;; String>>format: and printOn: tests. (set! st-test-pass 0) (set! st-test-fail 0) (set! st-test-fails (list)) (st-bootstrap-classes!) (define ev (fn (src) (smalltalk-eval src))) (define evp (fn (src) (smalltalk-eval-program src))) ;; ── 1. String>>format: ── (st-test "format: single placeholder" (ev "'Hello, {1}!' format: #('World')") "Hello, World!") (st-test "format: multiple placeholders" (ev "'{1} + {2} = {3}' format: #(1 2 3)") "1 + 2 = 3") (st-test "format: out-of-order" (ev "'{2} {1}' format: #('first' 'second')") "second first") (st-test "format: repeated index" (ev "'{1}-{1}-{1}' format: #(#a)") "a-a-a") (st-test "format: empty source" (ev "'' format: #()") "") (st-test "format: no placeholders" (ev "'plain text' format: #()") "plain text") (st-test "format: unmatched {" (ev "'open { brace' format: #('x')") "open { brace") (st-test "format: out-of-range index keeps literal" (ev "'{99}' format: #('hi')") "{99}") (st-test "format: numeric arg" (ev "'value: {1}' format: #(42)") "value: 42") (st-test "format: float arg" (ev "'pi ~ {1}' format: #(3.14)") "pi ~ 3.14") ;; ── 2. printOn: writes printString to stream ── (st-test "printOn: writes int via stream" (evp "| s | s := WriteStream on: (Array new: 0). 42 printOn: s. ^ s contents") (list "4" "2")) (st-test "printOn: writes string" (evp "| s | s := WriteStream on: (Array new: 0). 'hi' printOn: s. ^ s contents") (list "'" "h" "i" "'")) (st-test "printOn: returns receiver" (evp "| s | s := WriteStream on: (Array new: 0). ^ 99 printOn: s") 99) ;; ── 3. Universal printString fallback for user instances ── (st-class-define! "Cat" "Object" (list)) (st-class-define! "Animal" "Object" (list)) (st-test "printString of vowel-initial class" (evp "^ Animal new printString") "an Animal") (st-test "printString of consonant-initial class" (evp "^ Cat new printString") "a Cat") (st-test "user override of printString wins" (begin (st-class-add-method! "Cat" "printString" (st-parse-method "printString ^ #miaow asString")) (str (evp "^ Cat new printString"))) "miaow") ;; ── 4. printOn: on user instance with overridden printString ── (st-test "printOn: respects user-overridden printString" (evp "| s | s := WriteStream on: (Array new: 0). Cat new printOn: s. ^ s contents") (list "m" "i" "a" "o" "w")) ;; ── 5. printString for class-refs ── (st-test "Class printString is its name" (ev "Animal printString") "Animal") ;; ── 6. format: combined with printString ── (st-class-define! "Box" "Object" (list "n")) (st-class-add-method! "Box" "n:" (st-parse-method "n: v n := v. ^ self")) (st-class-add-method! "Box" "printString" (st-parse-method "printString ^ '<' , n printString , '>'")) (st-test "format: with custom printString in arg" (str (evp "| b | b := Box new n: 7. ^ '({1})' format: (Array with: b printString)")) "(<7>)") (st-class-add-class-method! "Array" "with:" (st-parse-method "with: x | a | a := Array new: 1. a at: 1 put: x. ^ a")) (list st-test-pass st-test-fail)