smalltalk: SUnit port (TestCase/TestSuite/TestResult/TestFailure) + 19 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
This commit is contained in:
153
lib/smalltalk/sunit.sx
Normal file
153
lib/smalltalk/sunit.sx
Normal file
@@ -0,0 +1,153 @@
|
||||
;; SUnit — minimal port written in SX-Smalltalk, run by smalltalk-load.
|
||||
;;
|
||||
;; Provides:
|
||||
;; TestCase — base class. Subclass it, add `testSomething` methods.
|
||||
;; TestSuite — a collection of TestCase instances; runs them all.
|
||||
;; TestResult — passes / failures / errors counts and lists.
|
||||
;; TestFailure — Error subclass raised by `assert:` and friends.
|
||||
;;
|
||||
;; Conventions:
|
||||
;; - Test methods are run in a fresh instance per test.
|
||||
;; - `setUp` is sent before each test; `tearDown` after.
|
||||
;; - Failures are signalled by TestFailure; runner catches and records.
|
||||
|
||||
(define
|
||||
st-sunit-source
|
||||
"Error subclass: #TestFailure
|
||||
instanceVariableNames: ''!
|
||||
|
||||
Object subclass: #TestCase
|
||||
instanceVariableNames: 'testSelector'!
|
||||
|
||||
!TestCase methodsFor: 'access'!
|
||||
testSelector ^ testSelector!
|
||||
testSelector: aSym testSelector := aSym. ^ self! !
|
||||
|
||||
!TestCase methodsFor: 'fixture'!
|
||||
setUp ^ self!
|
||||
tearDown ^ self! !
|
||||
|
||||
!TestCase methodsFor: 'asserts'!
|
||||
assert: aBoolean
|
||||
aBoolean ifFalse: [TestFailure signal: 'assertion failed'].
|
||||
^ self!
|
||||
|
||||
assert: aBoolean description: aString
|
||||
aBoolean ifFalse: [TestFailure signal: aString].
|
||||
^ self!
|
||||
|
||||
assert: actual equals: expected
|
||||
actual = expected ifFalse: [
|
||||
TestFailure signal: 'expected ' , expected printString
|
||||
, ' but got ' , actual printString].
|
||||
^ self!
|
||||
|
||||
deny: aBoolean
|
||||
aBoolean ifTrue: [TestFailure signal: 'denial failed'].
|
||||
^ self!
|
||||
|
||||
should: aBlock raise: anExceptionClass
|
||||
| raised |
|
||||
raised := false.
|
||||
[aBlock value] on: anExceptionClass do: [:e | raised := true].
|
||||
raised ifFalse: [
|
||||
TestFailure signal: 'expected exception ' , anExceptionClass name
|
||||
, ' was not raised'].
|
||||
^ self!
|
||||
|
||||
shouldnt: aBlock raise: anExceptionClass
|
||||
| raised |
|
||||
raised := false.
|
||||
[aBlock value] on: anExceptionClass do: [:e | raised := true].
|
||||
raised ifTrue: [
|
||||
TestFailure signal: 'unexpected exception ' , anExceptionClass name].
|
||||
^ self! !
|
||||
|
||||
!TestCase methodsFor: 'running'!
|
||||
runCase
|
||||
self setUp.
|
||||
self perform: testSelector.
|
||||
self tearDown.
|
||||
^ self! !
|
||||
|
||||
!TestCase class methodsFor: 'instantiation'!
|
||||
selector: aSym ^ self new testSelector: aSym!
|
||||
|
||||
suiteForAll: aSelectorArray
|
||||
| suite |
|
||||
suite := TestSuite new init.
|
||||
suite name: self name.
|
||||
aSelectorArray do: [:s | suite addTest: (self selector: s)].
|
||||
^ suite! !
|
||||
|
||||
Object subclass: #TestResult
|
||||
instanceVariableNames: 'passes failures errors'!
|
||||
|
||||
!TestResult methodsFor: 'init'!
|
||||
init
|
||||
passes := Array new: 0.
|
||||
failures := Array new: 0.
|
||||
errors := Array new: 0.
|
||||
^ self! !
|
||||
|
||||
!TestResult methodsFor: 'access'!
|
||||
passes ^ passes!
|
||||
failures ^ failures!
|
||||
errors ^ errors!
|
||||
passCount ^ passes size!
|
||||
failureCount ^ failures size!
|
||||
errorCount ^ errors size!
|
||||
totalCount ^ passes size + failures size + errors size!
|
||||
|
||||
addPass: aTest passes add: aTest. ^ self!
|
||||
addFailure: aTest message: aMsg
|
||||
| rec |
|
||||
rec := Array new: 2.
|
||||
rec at: 1 put: aTest. rec at: 2 put: aMsg.
|
||||
failures add: rec.
|
||||
^ self!
|
||||
addError: aTest message: aMsg
|
||||
| rec |
|
||||
rec := Array new: 2.
|
||||
rec at: 1 put: aTest. rec at: 2 put: aMsg.
|
||||
errors add: rec.
|
||||
^ self!
|
||||
|
||||
isEmpty ^ self totalCount = 0!
|
||||
allPassed ^ (failures size + errors size) = 0!
|
||||
|
||||
summary
|
||||
^ 'Tests: {1} Passed: {2} Failed: {3} Errors: {4}'
|
||||
format: (Array
|
||||
with: self totalCount printString
|
||||
with: passes size printString
|
||||
with: failures size printString
|
||||
with: errors size printString)! !
|
||||
|
||||
Object subclass: #TestSuite
|
||||
instanceVariableNames: 'tests name'!
|
||||
|
||||
!TestSuite methodsFor: 'init'!
|
||||
init tests := Array new: 0. name := 'Suite'. ^ self!
|
||||
name ^ name!
|
||||
name: aString name := aString. ^ self! !
|
||||
|
||||
!TestSuite methodsFor: 'tests'!
|
||||
tests ^ tests!
|
||||
addTest: aTest tests add: aTest. ^ self!
|
||||
addAll: aCollection aCollection do: [:t | self addTest: t]. ^ self!
|
||||
size ^ tests size! !
|
||||
|
||||
!TestSuite methodsFor: 'running'!
|
||||
run
|
||||
| result |
|
||||
result := TestResult new init.
|
||||
tests do: [:t | self runTest: t result: result].
|
||||
^ result!
|
||||
|
||||
runTest: aTest result: aResult
|
||||
[aTest runCase. aResult addPass: aTest]
|
||||
on: TestFailure do: [:e | aResult addFailure: aTest message: e messageText].
|
||||
^ self! !")
|
||||
|
||||
(smalltalk-load st-sunit-source)
|
||||
Reference in New Issue
Block a user