SUnit.st 4.1 KB

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