SUnit.st 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. Smalltalk current createPackage: 'SUnit' properties: #{}!
  2. Object subclass: #ResultAnnouncement
  3. instanceVariableNames: 'result'
  4. package: 'SUnit'!
  5. !ResultAnnouncement methodsFor: 'accessing'!
  6. result
  7. ^result
  8. !
  9. result: aTestResult
  10. result := aTestResult
  11. ! !
  12. Object subclass: #RunningTestContext
  13. instanceVariableNames: 'finished testCase result'
  14. package: 'SUnit'!
  15. !RunningTestContext methodsFor: 'accessing'!
  16. finished: aBlock
  17. finished := aBlock
  18. !
  19. result: aTestResult
  20. result := aTestResult
  21. !
  22. testCase: aTestCase
  23. testCase := aTestCase
  24. ! !
  25. !RunningTestContext methodsFor: 'running'!
  26. execute: aBlock
  27. [[[ aBlock
  28. ensure: [ result increaseRuns. testCase tearDown ]]
  29. on: TestFailure do: [:ex | result addFailure: testCase]]
  30. on: Error do: [:ex | result addError: testCase]]
  31. ensure: finished
  32. !
  33. start
  34. self execute: [ testCase setUp. testCase performTest ]
  35. ! !
  36. !RunningTestContext class methodsFor: 'instance creation'!
  37. testCase: aTestCase result: aTestResult finished: aBlock
  38. ^self new
  39. testCase: aTestCase;
  40. result: aTestResult;
  41. finished: aBlock;
  42. yourself
  43. ! !
  44. Object subclass: #TestCase
  45. instanceVariableNames: 'testSelector'
  46. package: 'SUnit'!
  47. !TestCase methodsFor: 'accessing'!
  48. selector
  49. ^testSelector
  50. !
  51. setTestSelector: aSelector
  52. testSelector := aSelector
  53. ! !
  54. !TestCase methodsFor: 'private'!
  55. signalFailure: aString
  56. TestFailure new
  57. messageText: aString;
  58. signal
  59. ! !
  60. !TestCase methodsFor: 'running'!
  61. performTest
  62. self perform: self selector
  63. !
  64. runCase
  65. [ self setUp.
  66. self performTest ] ensure: [
  67. self tearDown ]
  68. !
  69. setUp
  70. !
  71. tearDown
  72. ! !
  73. !TestCase methodsFor: 'testing'!
  74. assert: aBoolean
  75. self assert: aBoolean description: 'Assertion failed'
  76. !
  77. assert: aBoolean description: aString
  78. aBoolean ifFalse: [self signalFailure: aString]
  79. !
  80. assert: expected equals: actual
  81. ^ self assert: (expected = actual) description: 'Expected: ', expected asString, ' but was: ', actual asString
  82. !
  83. deny: aBoolean
  84. self assert: aBoolean not
  85. !
  86. should: aBlock
  87. self assert: aBlock value
  88. !
  89. should: aBlock raise: anExceptionClass
  90. self assert: ([aBlock value. false]
  91. on: anExceptionClass
  92. do: [:ex | true])
  93. !
  94. shouldnt: aBlock raise: anExceptionClass
  95. self assert: ([aBlock value. true]
  96. on: anExceptionClass
  97. do: [:ex | false])
  98. ! !
  99. !TestCase class methodsFor: 'accessing'!
  100. allTestSelectors
  101. | selectors |
  102. selectors := self testSelectors.
  103. self shouldInheritSelectors ifTrue: [
  104. selectors addAll: self superclass allTestSelectors].
  105. ^selectors
  106. !
  107. buildSuite
  108. ^self allTestSelectors collect: [:each | self selector: each]
  109. !
  110. lookupHierarchyRoot
  111. ^TestCase
  112. !
  113. selector: aSelector
  114. ^self new
  115. setTestSelector: aSelector;
  116. yourself
  117. !
  118. testSelectors
  119. ^self methodDictionary keys select: [:each | each match: '^test']
  120. ! !
  121. !TestCase class methodsFor: 'testing'!
  122. isAbstract
  123. ^ self name = 'TestCase'
  124. !
  125. shouldInheritSelectors
  126. ^self ~= self lookupHierarchyRoot
  127. ! !
  128. Error subclass: #TestFailure
  129. instanceVariableNames: ''
  130. package: 'SUnit'!
  131. Object subclass: #TestResult
  132. instanceVariableNames: 'timestamp runs errors failures total'
  133. package: 'SUnit'!
  134. !TestResult methodsFor: 'accessing'!
  135. addError: anError
  136. self errors add: anError
  137. !
  138. addFailure: aFailure
  139. self failures add: aFailure
  140. !
  141. errors
  142. ^errors
  143. !
  144. failures
  145. ^failures
  146. !
  147. increaseRuns
  148. runs := runs + 1
  149. !
  150. runs
  151. ^runs
  152. !
  153. status
  154. ^self errors isEmpty
  155. ifTrue: [
  156. self failures isEmpty
  157. ifTrue: ['success']
  158. ifFalse: ['failure']]
  159. ifFalse: ['error']
  160. !
  161. timestamp
  162. ^timestamp
  163. !
  164. total
  165. ^total
  166. !
  167. total: aNumber
  168. total := aNumber
  169. ! !
  170. !TestResult methodsFor: 'initialization'!
  171. initialize
  172. super initialize.
  173. timestamp := Date now.
  174. runs := 0.
  175. errors := Array new.
  176. failures := Array new.
  177. total := 0
  178. ! !
  179. !TestResult methodsFor: 'running'!
  180. nextRunDo: aBlock
  181. "Runs aBlock with index of next run
  182. or does nothing if no more runs"
  183. ^self runs == self total
  184. ifFalse: [ aBlock value: self runs + 1 ]
  185. ! !
  186. Object subclass: #TestSuiteRunner
  187. instanceVariableNames: 'suite result announcer runNextTest'
  188. package: 'SUnit'!
  189. !TestSuiteRunner methodsFor: 'accessing'!
  190. announcer
  191. ^announcer
  192. !
  193. result
  194. ^result
  195. !
  196. suite: aCollection
  197. suite := aCollection
  198. ! !
  199. !TestSuiteRunner methodsFor: 'actions'!
  200. resume
  201. runNextTest fork.
  202. announcer announce: (ResultAnnouncement new result: result)
  203. !
  204. run
  205. result total: suite size.
  206. self resume
  207. ! !
  208. !TestSuiteRunner methodsFor: 'initialization'!
  209. initialize
  210. super initialize.
  211. announcer := Announcer new.
  212. result := TestResult new.
  213. runNextTest := [ result nextRunDo: [ :index |
  214. (RunningTestContext testCase: (suite at: index) result: result finished: [ self resume ]) start ]].
  215. ! !
  216. !TestSuiteRunner class methodsFor: 'instance creation'!
  217. new
  218. self shouldNotImplement
  219. !
  220. on: aCollection
  221. ^super new suite: aCollection
  222. ! !