isolated_execution_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. package convey
  2. import (
  3. "strconv"
  4. "testing"
  5. "time"
  6. )
  7. func TestSingleScope(t *testing.T) {
  8. output := prepare()
  9. Convey("hi", t, func() {
  10. output += "done"
  11. })
  12. expectEqual(t, "done", output)
  13. }
  14. func TestSingleScopeWithMultipleConveys(t *testing.T) {
  15. output := prepare()
  16. Convey("1", t, func() {
  17. output += "1"
  18. })
  19. Convey("2", t, func() {
  20. output += "2"
  21. })
  22. expectEqual(t, "12", output)
  23. }
  24. func TestNestedScopes(t *testing.T) {
  25. output := prepare()
  26. Convey("a", t, func() {
  27. output += "a "
  28. Convey("bb", func() {
  29. output += "bb "
  30. Convey("ccc", func() {
  31. output += "ccc | "
  32. })
  33. })
  34. })
  35. expectEqual(t, "a bb ccc | ", output)
  36. }
  37. func TestNestedScopesWithIsolatedExecution(t *testing.T) {
  38. output := prepare()
  39. Convey("a", t, func() {
  40. output += "a "
  41. Convey("aa", func() {
  42. output += "aa "
  43. Convey("aaa", func() {
  44. output += "aaa | "
  45. })
  46. Convey("aaa1", func() {
  47. output += "aaa1 | "
  48. })
  49. })
  50. Convey("ab", func() {
  51. output += "ab "
  52. Convey("abb", func() {
  53. output += "abb | "
  54. })
  55. })
  56. })
  57. expectEqual(t, "a aa aaa | a aa aaa1 | a ab abb | ", output)
  58. }
  59. func TestSingleScopeWithConveyAndNestedReset(t *testing.T) {
  60. output := prepare()
  61. Convey("1", t, func() {
  62. output += "1"
  63. Reset(func() {
  64. output += "a"
  65. })
  66. })
  67. expectEqual(t, "1a", output)
  68. }
  69. func TestPanicingReset(t *testing.T) {
  70. output := prepare()
  71. Convey("1", t, func() {
  72. output += "1"
  73. Reset(func() {
  74. panic("nooo")
  75. })
  76. Convey("runs since the reset hasn't yet", func() {
  77. output += "a"
  78. })
  79. Convey("but this doesnt", func() {
  80. output += "nope"
  81. })
  82. })
  83. expectEqual(t, "1a", output)
  84. }
  85. func TestSingleScopeWithMultipleRegistrationsAndReset(t *testing.T) {
  86. output := prepare()
  87. Convey("reset after each nested convey", t, func() {
  88. Convey("first output", func() {
  89. output += "1"
  90. })
  91. Convey("second output", func() {
  92. output += "2"
  93. })
  94. Reset(func() {
  95. output += "a"
  96. })
  97. })
  98. expectEqual(t, "1a2a", output)
  99. }
  100. func TestSingleScopeWithMultipleRegistrationsAndMultipleResets(t *testing.T) {
  101. output := prepare()
  102. Convey("each reset is run at end of each nested convey", t, func() {
  103. Convey("1", func() {
  104. output += "1"
  105. })
  106. Convey("2", func() {
  107. output += "2"
  108. })
  109. Reset(func() {
  110. output += "a"
  111. })
  112. Reset(func() {
  113. output += "b"
  114. })
  115. })
  116. expectEqual(t, "1ab2ab", output)
  117. }
  118. func Test_Failure_AtHigherLevelScopePreventsChildScopesFromRunning(t *testing.T) {
  119. output := prepare()
  120. Convey("This step fails", t, func() {
  121. So(1, ShouldEqual, 2)
  122. Convey("this should NOT be executed", func() {
  123. output += "a"
  124. })
  125. })
  126. expectEqual(t, "", output)
  127. }
  128. func Test_Panic_AtHigherLevelScopePreventsChildScopesFromRunning(t *testing.T) {
  129. output := prepare()
  130. Convey("This step panics", t, func() {
  131. Convey("this happens, because the panic didn't happen yet", func() {
  132. output += "1"
  133. })
  134. output += "a"
  135. Convey("this should NOT be executed", func() {
  136. output += "2"
  137. })
  138. output += "b"
  139. panic("Hi")
  140. output += "nope"
  141. })
  142. expectEqual(t, "1ab", output)
  143. }
  144. func Test_Panic_InChildScopeDoes_NOT_PreventExecutionOfSiblingScopes(t *testing.T) {
  145. output := prepare()
  146. Convey("This is the parent", t, func() {
  147. Convey("This step panics", func() {
  148. panic("Hi")
  149. output += "1"
  150. })
  151. Convey("This sibling should execute", func() {
  152. output += "2"
  153. })
  154. })
  155. expectEqual(t, "2", output)
  156. }
  157. func Test_Failure_InChildScopeDoes_NOT_PreventExecutionOfSiblingScopes(t *testing.T) {
  158. output := prepare()
  159. Convey("This is the parent", t, func() {
  160. Convey("This step fails", func() {
  161. So(1, ShouldEqual, 2)
  162. output += "1"
  163. })
  164. Convey("This sibling should execute", func() {
  165. output += "2"
  166. })
  167. })
  168. expectEqual(t, "2", output)
  169. }
  170. func TestResetsAreAlwaysExecutedAfterScope_Panics(t *testing.T) {
  171. output := prepare()
  172. Convey("This is the parent", t, func() {
  173. Convey("This step panics", func() {
  174. panic("Hi")
  175. output += "1"
  176. })
  177. Convey("This sibling step does not panic", func() {
  178. output += "a"
  179. Reset(func() {
  180. output += "b"
  181. })
  182. })
  183. Reset(func() {
  184. output += "2"
  185. })
  186. })
  187. expectEqual(t, "2ab2", output)
  188. }
  189. func TestResetsAreAlwaysExecutedAfterScope_Failures(t *testing.T) {
  190. output := prepare()
  191. Convey("This is the parent", t, func() {
  192. Convey("This step fails", func() {
  193. So(1, ShouldEqual, 2)
  194. output += "1"
  195. })
  196. Convey("This sibling step does not fail", func() {
  197. output += "a"
  198. Reset(func() {
  199. output += "b"
  200. })
  201. })
  202. Reset(func() {
  203. output += "2"
  204. })
  205. })
  206. expectEqual(t, "2ab2", output)
  207. }
  208. func TestSkipTopLevel(t *testing.T) {
  209. output := prepare()
  210. SkipConvey("hi", t, func() {
  211. output += "This shouldn't be executed!"
  212. })
  213. expectEqual(t, "", output)
  214. }
  215. func TestSkipNestedLevel(t *testing.T) {
  216. output := prepare()
  217. Convey("hi", t, func() {
  218. output += "yes"
  219. SkipConvey("bye", func() {
  220. output += "no"
  221. })
  222. })
  223. expectEqual(t, "yes", output)
  224. }
  225. func TestSkipNestedLevelSkipsAllChildLevels(t *testing.T) {
  226. output := prepare()
  227. Convey("hi", t, func() {
  228. output += "yes"
  229. SkipConvey("bye", func() {
  230. output += "no"
  231. Convey("byebye", func() {
  232. output += "no-no"
  233. })
  234. })
  235. })
  236. expectEqual(t, "yes", output)
  237. }
  238. func TestIterativeConveys(t *testing.T) {
  239. output := prepare()
  240. Convey("Test", t, func() {
  241. for x := 0; x < 10; x++ {
  242. y := strconv.Itoa(x)
  243. Convey(y, func() {
  244. output += y
  245. })
  246. }
  247. })
  248. expectEqual(t, "0123456789", output)
  249. }
  250. func TestClosureVariables(t *testing.T) {
  251. output := prepare()
  252. i := 0
  253. Convey("A", t, func() {
  254. i = i + 1
  255. j := i
  256. output += "A" + strconv.Itoa(i) + " "
  257. Convey("B", func() {
  258. k := j
  259. j = j + 1
  260. output += "B" + strconv.Itoa(k) + " "
  261. Convey("C", func() {
  262. output += "C" + strconv.Itoa(k) + strconv.Itoa(j) + " "
  263. })
  264. Convey("D", func() {
  265. output += "D" + strconv.Itoa(k) + strconv.Itoa(j) + " "
  266. })
  267. })
  268. Convey("C", func() {
  269. output += "C" + strconv.Itoa(j) + " "
  270. })
  271. })
  272. output += "D" + strconv.Itoa(i) + " "
  273. expectEqual(t, "A1 B1 C12 A2 B2 D23 A3 C3 D3 ", output)
  274. }
  275. func TestClosureVariablesWithReset(t *testing.T) {
  276. output := prepare()
  277. i := 0
  278. Convey("A", t, func() {
  279. i = i + 1
  280. j := i
  281. output += "A" + strconv.Itoa(i) + " "
  282. Reset(func() {
  283. output += "R" + strconv.Itoa(i) + strconv.Itoa(j) + " "
  284. })
  285. Convey("B", func() {
  286. output += "B" + strconv.Itoa(j) + " "
  287. })
  288. Convey("C", func() {
  289. output += "C" + strconv.Itoa(j) + " "
  290. })
  291. })
  292. output += "D" + strconv.Itoa(i) + " "
  293. expectEqual(t, "A1 B1 R11 A2 C2 R22 D2 ", output)
  294. }
  295. func TestWrappedSimple(t *testing.T) {
  296. prepare()
  297. output := resetTestString{""}
  298. Convey("A", t, func() {
  299. func() {
  300. output.output += "A "
  301. Convey("B", func() {
  302. output.output += "B "
  303. Convey("C", func() {
  304. output.output += "C "
  305. })
  306. })
  307. Convey("D", func() {
  308. output.output += "D "
  309. })
  310. }()
  311. })
  312. expectEqual(t, "A B C A D ", output.output)
  313. }
  314. type resetTestString struct {
  315. output string
  316. }
  317. func addReset(o *resetTestString, f func()) func() {
  318. return func() {
  319. Reset(func() {
  320. o.output += "R "
  321. })
  322. f()
  323. }
  324. }
  325. func TestWrappedReset(t *testing.T) {
  326. prepare()
  327. output := resetTestString{""}
  328. Convey("A", t, addReset(&output, func() {
  329. output.output += "A "
  330. Convey("B", func() {
  331. output.output += "B "
  332. })
  333. Convey("C", func() {
  334. output.output += "C "
  335. })
  336. }))
  337. expectEqual(t, "A B R A C R ", output.output)
  338. }
  339. func TestWrappedReset2(t *testing.T) {
  340. prepare()
  341. output := resetTestString{""}
  342. Convey("A", t, func() {
  343. Reset(func() {
  344. output.output += "R "
  345. })
  346. func() {
  347. output.output += "A "
  348. Convey("B", func() {
  349. output.output += "B "
  350. Convey("C", func() {
  351. output.output += "C "
  352. })
  353. })
  354. Convey("D", func() {
  355. output.output += "D "
  356. })
  357. }()
  358. })
  359. expectEqual(t, "A B C R A D R ", output.output)
  360. }
  361. func TestInfiniteLoopWithTrailingFail(t *testing.T) {
  362. done := make(chan int)
  363. go func() {
  364. Convey("This fails", t, func() {
  365. Convey("and this is run", func() {
  366. So(true, ShouldEqual, true)
  367. })
  368. /* And this prevents the whole block to be marked as run */
  369. So(false, ShouldEqual, true)
  370. })
  371. done <- 1
  372. }()
  373. select {
  374. case <-done:
  375. return
  376. case <-time.After(1 * time.Millisecond):
  377. t.Fail()
  378. }
  379. }
  380. func TestOutermostResetInvokedForGrandchildren(t *testing.T) {
  381. output := prepare()
  382. Convey("A", t, func() {
  383. output += "A "
  384. Reset(func() {
  385. output += "rA "
  386. })
  387. Convey("B", func() {
  388. output += "B "
  389. Reset(func() {
  390. output += "rB "
  391. })
  392. Convey("C", func() {
  393. output += "C "
  394. Reset(func() {
  395. output += "rC "
  396. })
  397. })
  398. Convey("D", func() {
  399. output += "D "
  400. Reset(func() {
  401. output += "rD "
  402. })
  403. })
  404. })
  405. })
  406. expectEqual(t, "A B C rC rB rA A B D rD rB rA ", output)
  407. }
  408. func TestFailureOption(t *testing.T) {
  409. output := prepare()
  410. Convey("A", t, FailureHalts, func() {
  411. output += "A "
  412. So(true, ShouldEqual, true)
  413. output += "B "
  414. So(false, ShouldEqual, true)
  415. output += "C "
  416. })
  417. expectEqual(t, "A B ", output)
  418. }
  419. func TestFailureOption2(t *testing.T) {
  420. output := prepare()
  421. Convey("A", t, func() {
  422. output += "A "
  423. So(true, ShouldEqual, true)
  424. output += "B "
  425. So(false, ShouldEqual, true)
  426. output += "C "
  427. })
  428. expectEqual(t, "A B ", output)
  429. }
  430. func TestFailureOption3(t *testing.T) {
  431. output := prepare()
  432. Convey("A", t, FailureContinues, func() {
  433. output += "A "
  434. So(true, ShouldEqual, true)
  435. output += "B "
  436. So(false, ShouldEqual, true)
  437. output += "C "
  438. })
  439. expectEqual(t, "A B C ", output)
  440. }
  441. func TestFailureOptionInherit(t *testing.T) {
  442. output := prepare()
  443. Convey("A", t, FailureContinues, func() {
  444. output += "A1 "
  445. So(false, ShouldEqual, true)
  446. output += "A2 "
  447. Convey("B", func() {
  448. output += "B1 "
  449. So(true, ShouldEqual, true)
  450. output += "B2 "
  451. So(false, ShouldEqual, true)
  452. output += "B3 "
  453. })
  454. })
  455. expectEqual(t, "A1 A2 B1 B2 B3 ", output)
  456. }
  457. func TestFailureOptionInherit2(t *testing.T) {
  458. output := prepare()
  459. Convey("A", t, FailureHalts, func() {
  460. output += "A1 "
  461. So(false, ShouldEqual, true)
  462. output += "A2 "
  463. Convey("B", func() {
  464. output += "A1 "
  465. So(true, ShouldEqual, true)
  466. output += "A2 "
  467. So(false, ShouldEqual, true)
  468. output += "A3 "
  469. })
  470. })
  471. expectEqual(t, "A1 ", output)
  472. }
  473. func TestFailureOptionInherit3(t *testing.T) {
  474. output := prepare()
  475. Convey("A", t, FailureHalts, func() {
  476. output += "A1 "
  477. So(true, ShouldEqual, true)
  478. output += "A2 "
  479. Convey("B", func() {
  480. output += "B1 "
  481. So(true, ShouldEqual, true)
  482. output += "B2 "
  483. So(false, ShouldEqual, true)
  484. output += "B3 "
  485. })
  486. })
  487. expectEqual(t, "A1 A2 B1 B2 ", output)
  488. }
  489. func TestFailureOptionNestedOverride(t *testing.T) {
  490. output := prepare()
  491. Convey("A", t, FailureContinues, func() {
  492. output += "A "
  493. So(false, ShouldEqual, true)
  494. output += "B "
  495. Convey("C", FailureHalts, func() {
  496. output += "C "
  497. So(true, ShouldEqual, true)
  498. output += "D "
  499. So(false, ShouldEqual, true)
  500. output += "E "
  501. })
  502. })
  503. expectEqual(t, "A B C D ", output)
  504. }
  505. func TestFailureOptionNestedOverride2(t *testing.T) {
  506. output := prepare()
  507. Convey("A", t, FailureHalts, func() {
  508. output += "A "
  509. So(true, ShouldEqual, true)
  510. output += "B "
  511. Convey("C", FailureContinues, func() {
  512. output += "C "
  513. So(true, ShouldEqual, true)
  514. output += "D "
  515. So(false, ShouldEqual, true)
  516. output += "E "
  517. })
  518. })
  519. expectEqual(t, "A B C D E ", output)
  520. }
  521. func TestMultipleInvocationInheritance(t *testing.T) {
  522. output := prepare()
  523. Convey("A", t, FailureHalts, func() {
  524. output += "A1 "
  525. So(true, ShouldEqual, true)
  526. output += "A2 "
  527. Convey("B", FailureContinues, func() {
  528. output += "B1 "
  529. So(true, ShouldEqual, true)
  530. output += "B2 "
  531. So(false, ShouldEqual, true)
  532. output += "B3 "
  533. })
  534. Convey("C", func() {
  535. output += "C1 "
  536. So(true, ShouldEqual, true)
  537. output += "C2 "
  538. So(false, ShouldEqual, true)
  539. output += "C3 "
  540. })
  541. })
  542. expectEqual(t, "A1 A2 B1 B2 B3 A1 A2 C1 C2 ", output)
  543. }
  544. func TestMultipleInvocationInheritance2(t *testing.T) {
  545. output := prepare()
  546. Convey("A", t, FailureContinues, func() {
  547. output += "A1 "
  548. So(true, ShouldEqual, true)
  549. output += "A2 "
  550. So(false, ShouldEqual, true)
  551. output += "A3 "
  552. Convey("B", FailureHalts, func() {
  553. output += "B1 "
  554. So(true, ShouldEqual, true)
  555. output += "B2 "
  556. So(false, ShouldEqual, true)
  557. output += "B3 "
  558. })
  559. Convey("C", func() {
  560. output += "C1 "
  561. So(true, ShouldEqual, true)
  562. output += "C2 "
  563. So(false, ShouldEqual, true)
  564. output += "C3 "
  565. })
  566. })
  567. expectEqual(t, "A1 A2 A3 B1 B2 A1 A2 A3 C1 C2 C3 ", output)
  568. }
  569. func TestSetDefaultFailureMode(t *testing.T) {
  570. output := prepare()
  571. SetDefaultFailureMode(FailureContinues) // the default is normally FailureHalts
  572. defer SetDefaultFailureMode(FailureHalts)
  573. Convey("A", t, func() {
  574. output += "A1 "
  575. So(true, ShouldBeFalse)
  576. output += "A2 "
  577. })
  578. expectEqual(t, "A1 A2 ", output)
  579. }
  580. func prepare() string {
  581. testReporter = newNilReporter()
  582. return ""
  583. }