1
0

Helios-SUnit.st 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. Smalltalk createPackage: 'Helios-SUnit'!
  2. HLToolListWidget subclass: #HLMultiSelectToolListWidget
  3. instanceVariableNames: ''
  4. package: 'Helios-SUnit'!
  5. !HLMultiSelectToolListWidget commentStamp!
  6. This is a list that handles multiple selection!
  7. !HLMultiSelectToolListWidget methodsFor: 'accessing'!
  8. activeItemCssClass
  9. ^'selector'
  10. !
  11. listCssClass
  12. ^'nav nav-multiselect nav-pills nav-stacked'
  13. !
  14. listCssClassForItem: anObject
  15. ^(super listCssClassForItem: anObject), ((self isSelected: anObject)
  16. ifTrue: [' active']
  17. ifFalse: ['']).
  18. ! !
  19. !HLMultiSelectToolListWidget methodsFor: 'actions'!
  20. select: anObject
  21. self subclassResponsibility
  22. !
  23. toggleListItem: aListItem
  24. | item |
  25. (aListItem get: 0) ifNil: [ ^ self ].
  26. "Find item"
  27. item := aListItem data: 'item'.
  28. self toggleSelection: item
  29. !
  30. toggleSelection: anObject
  31. (self isSelected: anObject)
  32. ifTrue: [ self unselect: anObject ]
  33. ifFalse: [self select: anObject ]
  34. !
  35. unselect: anObject
  36. self subclassResponsibility
  37. ! !
  38. !HLMultiSelectToolListWidget methodsFor: 'rendering'!
  39. reselectItem: anObject
  40. anObject ifNil: [^self].
  41. self toggleSelection: anObject
  42. ! !
  43. !HLMultiSelectToolListWidget methodsFor: 'testing'!
  44. isSelected: anObject
  45. self subclassResponsibility
  46. ! !
  47. HLMultiSelectToolListWidget subclass: #HLSUnitClassesListWidget
  48. instanceVariableNames: ''
  49. package: 'Helios-SUnit'!
  50. !HLSUnitClassesListWidget commentStamp!
  51. I display a list of classes (subclasses of `TestCase`).!
  52. !HLSUnitClassesListWidget methodsFor: 'accessing'!
  53. cssClassForItem: aClass
  54. ^ aClass theNonMetaClass heliosClass
  55. !
  56. items
  57. ^ items ifNil: [ self initializeItems ]
  58. !
  59. label
  60. ^ 'Classes'
  61. ! !
  62. !HLSUnitClassesListWidget methodsFor: 'actions'!
  63. observeModel
  64. self model announcer
  65. on: HLPackageSelected
  66. send: #onPackageSelected:
  67. to: self;
  68. on: HLPackageUnselected
  69. send: #onPackageUnselected:
  70. to: self;
  71. on: HLClassSelected
  72. send: #onClassSelected:
  73. to: self;
  74. on: HLClassUnselected
  75. send: #onClassUnselected:
  76. to: self
  77. !
  78. select: anObject
  79. model selectClass: anObject
  80. !
  81. unselect: anObject
  82. model unselectClass: anObject
  83. ! !
  84. !HLSUnitClassesListWidget methodsFor: 'initialization'!
  85. initializeItems
  86. ^items := model testClasses
  87. ! !
  88. !HLSUnitClassesListWidget methodsFor: 'reactions'!
  89. onClassSelected: anAnnouncement
  90. self refresh
  91. !
  92. onClassUnselected: anAnnouncement
  93. self refresh
  94. !
  95. onPackageSelected: anAnnouncement
  96. self initializeItems;
  97. refresh
  98. !
  99. onPackageUnselected: anAnnouncement
  100. self initializeItems;
  101. refresh
  102. ! !
  103. !HLSUnitClassesListWidget methodsFor: 'rendering'!
  104. renderItemLabel: aClass on: html
  105. html with: aClass name
  106. ! !
  107. !HLSUnitClassesListWidget methodsFor: 'testing'!
  108. isSelected: anObject
  109. ^model selectedClasses includes: anObject
  110. ! !
  111. HLMultiSelectToolListWidget subclass: #HLSUnitPackagesListWidget
  112. instanceVariableNames: ''
  113. package: 'Helios-SUnit'!
  114. !HLSUnitPackagesListWidget commentStamp!
  115. I display a list of packages for which unit tests are associated (packages containing subclasses of `TestCase`).!
  116. !HLSUnitPackagesListWidget methodsFor: 'accessing'!
  117. cssClassForItem: anItem
  118. ^ anItem isDirty
  119. ifTrue: [ 'package_dirty' ]
  120. ifFalse: [ 'package' ]
  121. !
  122. items
  123. ^ items ifNil: [ self initializeItems ]
  124. !
  125. label
  126. ^ 'Packages'
  127. ! !
  128. !HLSUnitPackagesListWidget methodsFor: 'actions'!
  129. observeModel
  130. self model announcer
  131. on: HLPackageSelected
  132. send: #onPackageSelected:
  133. to: self;
  134. on: HLPackageUnselected
  135. send: #onPackageUnselected:
  136. to: self
  137. !
  138. select: anObject
  139. model selectPackage: anObject
  140. !
  141. unselect: anObject
  142. model unselectPackage: anObject
  143. ! !
  144. !HLSUnitPackagesListWidget methodsFor: 'initialization'!
  145. initializeItems
  146. ^items := model testPackages
  147. sort: [:a :b | a name < b name]
  148. ! !
  149. !HLSUnitPackagesListWidget methodsFor: 'reactions'!
  150. onPackageSelected: anAnnouncement
  151. self refresh
  152. !
  153. onPackageUnselected: anAnnouncement
  154. self refresh
  155. ! !
  156. !HLSUnitPackagesListWidget methodsFor: 'rendering'!
  157. renderButtonsOn: html
  158. html button
  159. with: 'Run Tests';
  160. onClick: [ self model runTests ]
  161. !
  162. renderItemLabel: aPackage on: html
  163. html with: aPackage name
  164. ! !
  165. !HLSUnitPackagesListWidget methodsFor: 'testing'!
  166. isSelected: anObject
  167. ^model selectedPackages includes: anObject
  168. ! !
  169. HLWidget subclass: #HLSUnit
  170. <<<<<<< variant A
  171. instanceVariableNames: 'model packagesListWidget resultWidget'
  172. >>>>>>> variant B
  173. instanceVariableNames: 'model packagesListWidget classesListWidget resultWidget failuresWidget errorsWidget'
  174. ####### Ancestor
  175. instanceVariableNames: ''
  176. ======= end
  177. package: 'Helios-SUnit'!
  178. <<<<<<< variant A
  179. !HLSUnit commentStamp!
  180. I am the main widget for running unit tests in Helios.
  181. I provide the ability to select set of tests to run per package, and a detailed result log with passed tests, failed tests and errors.!
  182. !HLSUnit methodsFor: 'accessing'!
  183. model
  184. ^ model ifNil: [ model := HLSUnitModel new ]
  185. ! !
  186. !HLSUnit methodsFor: 'rendering'!
  187. renderContentOn: html
  188. html with: (HLVerticalSplitter
  189. with: self packagesListWidget
  190. with: self resultWidget).
  191. self packagesListWidget focus
  192. ! !
  193. !HLSUnit methodsFor: 'widgets'!
  194. packagesListWidget
  195. ^ packagesListWidget ifNil: [
  196. packagesListWidget := HLSUnitPackagesListWidget on: self model ]
  197. !
  198. resultWidget
  199. ^ resultWidget ifNil: [
  200. resultWidget := HLWidget new ]
  201. ! !
  202. >>>>>>> variant B
  203. !HLSUnit commentStamp!
  204. I am the main widget for running unit tests in Helios.
  205. I provide the ability to select set of tests to run per package, and a detailed result log with passed tests, failed tests and errors.!
  206. !HLSUnit methodsFor: 'accessing'!
  207. model
  208. ^ model ifNil: [ model := HLSUnitModel new ]
  209. ! !
  210. !HLSUnit methodsFor: 'keybindings'!
  211. registerBindingsOn: aBindingGroup
  212. HLToolCommand
  213. registerConcreteClassesOn: aBindingGroup
  214. for: self model
  215. ! !
  216. !HLSUnit methodsFor: 'rendering'!
  217. renderContentOn: html
  218. html with: (HLContainer with: (
  219. HLVerticalSplitter
  220. with: (HLVerticalSplitter
  221. with: self packagesListWidget
  222. with: self classesListWidget)
  223. with: (HLHorizontalSplitter
  224. with: self resultWidget
  225. with: (HLHorizontalSplitter
  226. with: self failuresWidget
  227. with: self errorsWidget)))).
  228. self packagesListWidget focus
  229. ! !
  230. !HLSUnit methodsFor: 'widgets'!
  231. classesListWidget
  232. ^ classesListWidget ifNil: [
  233. classesListWidget := HLSUnitClassesListWidget on: self model.
  234. classesListWidget next: self failuresWidget ]
  235. !
  236. errorsWidget
  237. ^ errorsWidget ifNil: [errorsWidget := HLSUnitErrorsListWidget on: self model]
  238. !
  239. failuresWidget
  240. ^ failuresWidget ifNil: [
  241. failuresWidget := HLSUnitFailuresListWidget on: self model.
  242. failuresWidget next: self errorsWidget]
  243. !
  244. packagesListWidget
  245. ^ packagesListWidget ifNil: [
  246. packagesListWidget := HLSUnitPackagesListWidget on: self model.
  247. packagesListWidget next: self classesListWidget]
  248. !
  249. resultWidget
  250. ^ resultWidget ifNil: [
  251. resultWidget := HLSUnitResults new
  252. model: self model;
  253. yourself]
  254. ! !
  255. ####### Ancestor
  256. ======= end
  257. !HLSUnit class methodsFor: 'accessing'!
  258. tabClass
  259. ^ 'sunit'
  260. !
  261. tabLabel
  262. ^ 'SUnit'
  263. !
  264. tabPriority
  265. ^ 1000
  266. ! !
  267. !HLSUnit class methodsFor: 'testing'!
  268. canBeOpenAsTab
  269. ^ true
  270. ! !
  271. <<<<<<< variant A
  272. HLModel subclass: #HLSUnitModel
  273. instanceVariableNames: 'selectedPackages'
  274. package: 'Helios-SUnit'!
  275. !HLSUnitModel methodsFor: 'accessing'!
  276. selectedPackages
  277. ^ selectedPackages ifNil: [ selectedPackages := Set new ]
  278. !
  279. testPackages
  280. "Answer all packages containing concrete subclasses of TestCase"
  281. ^ self environment packages
  282. select: [ :each | each isTestPackage ]
  283. ! !
  284. !HLSUnitModel methodsFor: 'actions'!
  285. selectPackage: aPackage
  286. self packages add: aPackage
  287. !
  288. unselectPackage: aPackage
  289. self packages remove: aPackage ifAbsent: []
  290. ! !
  291. HLWidget subclass: #HLSUnitPackagesListWidget
  292. instanceVariableNames: 'model'
  293. package: 'Helios-SUnit'!
  294. !HLSUnitPackagesListWidget commentStamp!
  295. I display a list of packages for which unit tests are associated (packages containing subclasses of `TestCase`).!
  296. !HLSUnitPackagesListWidget methodsFor: 'accessing'!
  297. model
  298. ^ model
  299. !
  300. model: anObject
  301. model := anObject
  302. ! !
  303. !HLSUnitPackagesListWidget class methodsFor: 'instance creation'!
  304. on: aSUnitModel
  305. ^ self new
  306. model: aSUnitModel;
  307. yourself
  308. ! !
  309. >>>>>>> variant B
  310. HLModel subclass: #HLSUnitModel
  311. instanceVariableNames: 'selectedPackages selectedClasses testResult currentSuite'
  312. package: 'Helios-SUnit'!
  313. !HLSUnitModel methodsFor: 'accessing'!
  314. currentSuite
  315. ^currentSuite
  316. !
  317. selectedClasses
  318. ^ (self privateSelectedClasses) select: [:each |
  319. self selectedPackages includes: each package]
  320. !
  321. selectedPackages
  322. ^ selectedPackages ifNil: [ selectedPackages := Set new ]
  323. !
  324. testCases
  325. | testCases |
  326. testCases := #().
  327. self selectedClasses
  328. do: [ :each | testCases addAll: each buildSuite ].
  329. ^ testCases
  330. !
  331. testClasses
  332. "Answer all concrete subclasses of TestCase in selected packages"
  333. | stream |
  334. stream := Array new writeStream.
  335. self selectedPackages do: [ :package |
  336. stream nextPutAll: (package classes select: [ :each |
  337. (each includesBehavior: TestCase) and: [
  338. each isAbstract not ] ] ) ].
  339. ^ stream contents
  340. !
  341. testPackages
  342. "Answer all packages containing concrete subclasses of TestCase"
  343. ^ self environment packages
  344. select: [ :each | each isTestPackage ]
  345. !
  346. testResult
  347. ^testResult ifNil: [testResult := TestResult new]
  348. ! !
  349. !HLSUnitModel methodsFor: 'actions'!
  350. runTests
  351. | worker |
  352. worker := TestSuiteRunner on: self testCases.
  353. testResult := worker result.
  354. self announcer announce: (HLRunTests on: worker).
  355. self subscribeToTestSuite: worker.
  356. worker run
  357. !
  358. selectAllPackages
  359. self testPackages do: [:each | self selectPackage: each]
  360. !
  361. selectClass: aClass
  362. self privateSelectedClasses add: aClass.
  363. self announcer announce: (HLClassSelected on: aClass).
  364. !
  365. selectPackage: aPackage
  366. self selectedPackages add: aPackage.
  367. self announcer announce: (HLPackageSelected on: aPackage).
  368. !
  369. subscribeToTestSuite: aTestSuiteRunner
  370. currentSuite ifNotNil: [ currentSuite announcer unsubscribe: self].
  371. currentSuite := aTestSuiteRunner.
  372. currentSuite announcer
  373. on: ResultAnnouncement
  374. send: #onResultAnnouncement:
  375. to: self
  376. !
  377. unselectClass: aClass
  378. self privateSelectedClasses remove: aClass ifAbsent: [^self].
  379. self announcer announce: (HLClassUnselected on: aClass).
  380. !
  381. unselectPackage: aPackage
  382. self selectedPackages remove: aPackage ifAbsent: [^self].
  383. self announcer announce: (HLPackageUnselected on: aPackage).
  384. ! !
  385. !HLSUnitModel methodsFor: 'private'!
  386. privateSelectedClasses
  387. ^ (selectedClasses ifNil: [ selectedClasses := Set new ])
  388. ! !
  389. !HLSUnitModel methodsFor: 'reacting'!
  390. onResultAnnouncement: announcement
  391. "Propogate announcement"
  392. self announcer announce: announcement.
  393. ! !
  394. HLToolListWidget subclass: #HLSUnitResultListWidget
  395. instanceVariableNames: ''
  396. package: 'Helios-SUnit'!
  397. !HLSUnitResultListWidget methodsFor: 'actions'!
  398. performFailure: aTestCase
  399. aTestCase runCase
  400. ! !
  401. !HLSUnitResultListWidget methodsFor: 'initialization'!
  402. observeModel
  403. self model announcer
  404. on: ResultAnnouncement
  405. send: #onResultAnnouncement:
  406. to: self
  407. ! !
  408. !HLSUnitResultListWidget methodsFor: 'reacting'!
  409. onResultAnnouncement: announcement
  410. self refresh.
  411. ! !
  412. !HLSUnitResultListWidget methodsFor: 'rendering'!
  413. renderItemLabel: anObject on: html
  414. html with: anObject class name, ' >> ', anObject selector
  415. !
  416. reselectItem: anObject
  417. self performFailure: anObject
  418. ! !
  419. HLSUnitResultListWidget subclass: #HLSUnitErrorsListWidget
  420. instanceVariableNames: ''
  421. package: 'Helios-SUnit'!
  422. !HLSUnitErrorsListWidget methodsFor: 'accessing'!
  423. items
  424. ^self model testResult errors
  425. !
  426. label
  427. ^'Errors'
  428. ! !
  429. HLSUnitResultListWidget subclass: #HLSUnitFailuresListWidget
  430. instanceVariableNames: ''
  431. package: 'Helios-SUnit'!
  432. !HLSUnitFailuresListWidget methodsFor: 'accessing'!
  433. label
  434. ^'Failures'
  435. ! !
  436. !HLSUnitFailuresListWidget methodsFor: 'as yet unclassified'!
  437. items
  438. ^self model testResult failures
  439. ! !
  440. HLWidget subclass: #HLSUnitResultStatus
  441. instanceVariableNames: 'model'
  442. package: 'Helios-SUnit'!
  443. !HLSUnitResultStatus methodsFor: 'accessing'!
  444. model
  445. ^ model ifNil: [model := TestResult new]
  446. !
  447. model: anObject
  448. model := anObject.
  449. self observeModel.
  450. !
  451. result
  452. ^ self model testResult
  453. !
  454. statusCssClass
  455. ^'sunit status ', self result status
  456. !
  457. statusInfo
  458. ^ self printTotal, self printPasses, self printErrors, self printFailures
  459. ! !
  460. !HLSUnitResultStatus methodsFor: 'initialization'!
  461. observeModel
  462. self model announcer
  463. on: ResultAnnouncement
  464. send: #onResultAnnouncement:
  465. to: self
  466. ! !
  467. !HLSUnitResultStatus methodsFor: 'printing'!
  468. printErrors
  469. ^ self result errors size asString , ' errors, '
  470. !
  471. printFailures
  472. ^ self result failures size asString, ' failures'
  473. !
  474. printPasses
  475. ^ (self result runs - self result errors size - self result failures size) asString , ' passes, '
  476. !
  477. printTotal
  478. ^ self result total asString, ' runs, '
  479. ! !
  480. !HLSUnitResultStatus methodsFor: 'reacting'!
  481. onResultAnnouncement: announcement
  482. self refresh.
  483. ! !
  484. !HLSUnitResultStatus methodsFor: 'rendering'!
  485. renderContentOn: html
  486. html div
  487. class: self statusCssClass;
  488. with: [ html span with: self statusInfo ]
  489. ! !
  490. HLWidget subclass: #HLSUnitResults
  491. instanceVariableNames: 'model progressBarWidget resultStatusWidget'
  492. package: 'Helios-SUnit'!
  493. !HLSUnitResults methodsFor: 'accessing'!
  494. model
  495. ^model
  496. !
  497. model: anObject
  498. model := anObject.
  499. self observeModel
  500. !
  501. progressBarWidget
  502. ^progressBarWidget ifNil: [progressBarWidget := HLProgressBarWidget new
  503. label: '';
  504. yourself]
  505. !
  506. resultStatusWidget
  507. ^resultStatusWidget ifNil: [resultStatusWidget := HLSUnitResultStatus new
  508. model: self model;
  509. yourself]
  510. ! !
  511. !HLSUnitResults methodsFor: 'initialization'!
  512. observeModel
  513. self model announcer
  514. on: HLRunTests
  515. send: #onRunTests:
  516. to: self;
  517. on: ResultAnnouncement
  518. send: #onResultAnnouncement:
  519. to: self
  520. ! !
  521. !HLSUnitResults methodsFor: 'reacting'!
  522. onResultAnnouncement: announcement
  523. [self progressBarWidget
  524. updateProgress: (self model testResult runs / self model testResult total * 100) rounded] valueWithTimeout: 10
  525. !
  526. onRunTests: announcement
  527. self progressBarWidget updateProgress: 0;
  528. refresh.
  529. ! !
  530. !HLSUnitResults methodsFor: 'rendering'!
  531. renderContentOn: html
  532. html with: self resultStatusWidget;
  533. with: self progressBarWidget
  534. ! !
  535. ####### Ancestor
  536. ======= end