Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
199 lines
5.1 KiB
Plaintext
199 lines
5.1 KiB
Plaintext
;; SUnit port tests. Loads `lib/smalltalk/sunit.sx` (which itself calls
|
|
;; smalltalk-load to install TestCase/TestSuite/TestResult/TestFailure)
|
|
;; and exercises the framework on small Smalltalk-defined cases.
|
|
|
|
(set! st-test-pass 0)
|
|
(set! st-test-fail 0)
|
|
(set! st-test-fails (list))
|
|
|
|
;; test.sh loads lib/smalltalk/sunit.sx for us BEFORE this file runs
|
|
;; (nested SX loads do not propagate top-level forms reliably, so the
|
|
;; bootstrap chain is concentrated in test.sh). The SUnit classes are
|
|
;; already present in the class table at this point.
|
|
|
|
(define ev (fn (src) (smalltalk-eval src)))
|
|
(define evp (fn (src) (smalltalk-eval-program src)))
|
|
|
|
;; ── 1. Classes installed ──
|
|
(st-test "TestCase exists" (st-class-exists? "TestCase") true)
|
|
(st-test "TestSuite exists" (st-class-exists? "TestSuite") true)
|
|
(st-test "TestResult exists" (st-class-exists? "TestResult") true)
|
|
(st-test "TestFailure < Error"
|
|
(st-class-inherits-from? "TestFailure" "Error") true)
|
|
|
|
;; ── 2. A subclass with one passing test runs cleanly ──
|
|
(smalltalk-load
|
|
"TestCase subclass: #PassingCase
|
|
instanceVariableNames: ''!
|
|
|
|
!PassingCase methodsFor: 'tests'!
|
|
testOnePlusOne self assert: 1 + 1 = 2! !")
|
|
|
|
(st-test "passing test runs and counts as pass"
|
|
(evp
|
|
"| suite r |
|
|
suite := PassingCase suiteForAll: #(#testOnePlusOne).
|
|
r := suite run.
|
|
^ r passCount")
|
|
1)
|
|
|
|
(st-test "passing test has no failures"
|
|
(evp
|
|
"| suite r |
|
|
suite := PassingCase suiteForAll: #(#testOnePlusOne).
|
|
r := suite run.
|
|
^ r failureCount")
|
|
0)
|
|
|
|
;; ── 3. A subclass with a failing assert: increments failures ──
|
|
(smalltalk-load
|
|
"TestCase subclass: #FailingCase
|
|
instanceVariableNames: ''!
|
|
|
|
!FailingCase methodsFor: 'tests'!
|
|
testFalse self assert: false!
|
|
testEquals self assert: 1 + 1 equals: 3! !")
|
|
|
|
(st-test "assert: false bumps failureCount"
|
|
(evp
|
|
"| suite r |
|
|
suite := FailingCase suiteForAll: #(#testFalse).
|
|
r := suite run.
|
|
^ r failureCount")
|
|
1)
|
|
|
|
(st-test "assert:equals: with mismatch fails"
|
|
(evp
|
|
"| suite r |
|
|
suite := FailingCase suiteForAll: #(#testEquals).
|
|
r := suite run.
|
|
^ r failureCount")
|
|
1)
|
|
|
|
(st-test "failure messageText captured"
|
|
(evp
|
|
"| suite r rec |
|
|
suite := FailingCase suiteForAll: #(#testEquals).
|
|
r := suite run.
|
|
rec := r failures at: 1.
|
|
^ rec at: 2")
|
|
"expected 3 but got 2")
|
|
|
|
;; ── 4. Mixed pass/fail counts add up ──
|
|
(smalltalk-load
|
|
"TestCase subclass: #MixedCase
|
|
instanceVariableNames: ''!
|
|
|
|
!MixedCase methodsFor: 'tests'!
|
|
testGood self assert: true!
|
|
testBad self assert: false!
|
|
testAlsoGood self assert: 2 > 1! !")
|
|
|
|
(st-test "mixed suite — totalCount"
|
|
(evp
|
|
"| s r |
|
|
s := MixedCase suiteForAll: #(#testGood #testBad #testAlsoGood).
|
|
r := s run.
|
|
^ r totalCount")
|
|
3)
|
|
|
|
(st-test "mixed suite — passCount"
|
|
(evp
|
|
"| s r |
|
|
s := MixedCase suiteForAll: #(#testGood #testBad #testAlsoGood).
|
|
r := s run.
|
|
^ r passCount")
|
|
2)
|
|
|
|
(st-test "mixed suite — failureCount"
|
|
(evp
|
|
"| s r |
|
|
s := MixedCase suiteForAll: #(#testGood #testBad #testAlsoGood).
|
|
r := s run.
|
|
^ r failureCount")
|
|
1)
|
|
|
|
(st-test "allPassed false on mix"
|
|
(evp
|
|
"| s r |
|
|
s := MixedCase suiteForAll: #(#testGood #testBad #testAlsoGood).
|
|
r := s run.
|
|
^ r allPassed")
|
|
false)
|
|
|
|
(st-test "allPassed true with only passes"
|
|
(evp
|
|
"| s r |
|
|
s := MixedCase suiteForAll: #(#testGood #testAlsoGood).
|
|
r := s run.
|
|
^ r allPassed")
|
|
true)
|
|
|
|
;; ── 5. setUp / tearDown ──
|
|
(smalltalk-load
|
|
"TestCase subclass: #FixtureCase
|
|
instanceVariableNames: 'value'!
|
|
|
|
!FixtureCase methodsFor: 'fixture'!
|
|
setUp value := 42. ^ self!
|
|
tearDown ^ self! !
|
|
|
|
!FixtureCase methodsFor: 'tests'!
|
|
testValueIs42 self assert: value = 42! !")
|
|
|
|
(st-test "setUp ran before test"
|
|
(evp
|
|
"| s r |
|
|
s := FixtureCase suiteForAll: #(#testValueIs42).
|
|
r := s run.
|
|
^ r passCount")
|
|
1)
|
|
|
|
;; ── 6. should:raise: and shouldnt:raise: ──
|
|
(smalltalk-load
|
|
"TestCase subclass: #RaiseCase
|
|
instanceVariableNames: ''!
|
|
|
|
!RaiseCase methodsFor: 'tests'!
|
|
testShouldRaise
|
|
self should: [Error signal: 'boom'] raise: Error!
|
|
|
|
testShouldRaiseFails
|
|
self should: [42] raise: Error!
|
|
|
|
testShouldntRaise
|
|
self shouldnt: [42] raise: Error! !")
|
|
|
|
(st-test "should:raise: catches matching"
|
|
(evp
|
|
"| r |
|
|
r := (RaiseCase suiteForAll: #(#testShouldRaise)) run.
|
|
^ r passCount") 1)
|
|
|
|
(st-test "should:raise: fails when no exception"
|
|
(evp
|
|
"| r |
|
|
r := (RaiseCase suiteForAll: #(#testShouldRaiseFails)) run.
|
|
^ r failureCount") 1)
|
|
|
|
(st-test "shouldnt:raise: passes when nothing thrown"
|
|
(evp
|
|
"| r |
|
|
r := (RaiseCase suiteForAll: #(#testShouldntRaise)) run.
|
|
^ r passCount") 1)
|
|
|
|
;; ── 7. summary string uses format: ──
|
|
(st-test "summary contains pass count"
|
|
(let
|
|
((s (evp
|
|
"| s r |
|
|
s := MixedCase suiteForAll: #(#testGood #testBad).
|
|
r := s run.
|
|
^ r summary")))
|
|
(cond
|
|
((not (string? s)) false)
|
|
(else (> (len s) 0))))
|
|
true)
|
|
|
|
(list st-test-pass st-test-fail)
|