- Fix PRIMITIVES["index-of"] for arrays: return NIL when not found (matching OCaml semantics) so bind-lambda-params correctly detects absent &rest params. Previously String(array).indexOf() returned -1, which passed number? check and mis-fired the &rest branch, leaving non-&rest params unbound. - Declare var _lastErrorKont_ and var hostError in IIFE scope (strict mode fix) - Add PRIMITIVES["host-error"], ["try-catch"], ["without-io-hook"] - Add env["test-allowed?"] stub in run_tests.js - Add spec/tests/test-vectors.sx: 42 tests for all vector primitives - Rebuild sx-browser.js: 1847 standard / 2362 full tests pass (up from 5) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
208 lines
6.3 KiB
Plaintext
208 lines
6.3 KiB
Plaintext
;; test-vectors.sx — Tests for vector primitives
|
|
|
|
(defsuite
|
|
"vectors"
|
|
(deftest
|
|
"make-vector default fill is nil"
|
|
(let
|
|
((v (make-vector 3)))
|
|
(assert (vector? v))
|
|
(assert-equal 3 (vector-length v))
|
|
(assert-equal nil (vector-ref v 0))
|
|
(assert-equal nil (vector-ref v 1))
|
|
(assert-equal nil (vector-ref v 2))))
|
|
(deftest
|
|
"make-vector with fill value"
|
|
(let
|
|
((v (make-vector 4 99)))
|
|
(assert-equal 4 (vector-length v))
|
|
(assert-equal 99 (vector-ref v 0))
|
|
(assert-equal 99 (vector-ref v 1))
|
|
(assert-equal 99 (vector-ref v 2))
|
|
(assert-equal 99 (vector-ref v 3))))
|
|
(deftest
|
|
"make-vector size zero"
|
|
(let ((v (make-vector 0))) (assert-equal 0 (vector-length v))))
|
|
(deftest
|
|
"make-vector size one"
|
|
(let
|
|
((v (make-vector 1 "x")))
|
|
(assert-equal 1 (vector-length v))
|
|
(assert-equal "x" (vector-ref v 0))))
|
|
(deftest
|
|
"vector constructor no args"
|
|
(let ((v (vector))) (assert-equal 0 (vector-length v))))
|
|
(deftest
|
|
"vector constructor with args"
|
|
(let
|
|
((v (vector 10 20 30)))
|
|
(assert-equal 3 (vector-length v))
|
|
(assert-equal 10 (vector-ref v 0))
|
|
(assert-equal 20 (vector-ref v 1))
|
|
(assert-equal 30 (vector-ref v 2))))
|
|
(deftest
|
|
"vector constructor strings"
|
|
(let
|
|
((v (vector "a" "b" "c")))
|
|
(assert-equal "a" (vector-ref v 0))
|
|
(assert-equal "b" (vector-ref v 1))
|
|
(assert-equal "c" (vector-ref v 2))))
|
|
(deftest "vector? true for vector" (assert (vector? (make-vector 3))))
|
|
(deftest "vector? false for list" (assert (not (vector? (list 1 2 3)))))
|
|
(deftest "vector? false for number" (assert (not (vector? 42))))
|
|
(deftest "vector? false for nil" (assert (not (vector? nil))))
|
|
(deftest "vector? false for string" (assert (not (vector? "hello"))))
|
|
(deftest "vector-length zero" (assert-equal 0 (vector-length (vector))))
|
|
(deftest
|
|
"vector-length three"
|
|
(assert-equal 3 (vector-length (vector 1 2 3))))
|
|
(deftest
|
|
"vector-length after make-vector"
|
|
(assert-equal 7 (vector-length (make-vector 7 0))))
|
|
(deftest
|
|
"vector-ref first element"
|
|
(assert-equal 1 (vector-ref (vector 1 2 3) 0)))
|
|
(deftest
|
|
"vector-ref last element"
|
|
(assert-equal 3 (vector-ref (vector 1 2 3) 2)))
|
|
(deftest
|
|
"vector-ref middle element"
|
|
(assert-equal 2 (vector-ref (vector 1 2 3) 1)))
|
|
(deftest
|
|
"vector-set! mutates in place"
|
|
(let
|
|
((v (vector 1 2 3)))
|
|
(vector-set! v 1 99)
|
|
(assert-equal 99 (vector-ref v 1))
|
|
(assert-equal 1 (vector-ref v 0))
|
|
(assert-equal 3 (vector-ref v 2))))
|
|
(deftest
|
|
"vector-set! first slot"
|
|
(let
|
|
((v (make-vector 3 0)))
|
|
(vector-set! v 0 42)
|
|
(assert-equal 42 (vector-ref v 0))))
|
|
(deftest
|
|
"vector-set! last slot"
|
|
(let
|
|
((v (make-vector 3 0)))
|
|
(vector-set! v 2 77)
|
|
(assert-equal 77 (vector-ref v 2))))
|
|
(deftest
|
|
"vector-set! returns nil"
|
|
(let ((v (make-vector 3 0))) (assert-equal nil (vector-set! v 0 1))))
|
|
(deftest
|
|
"vector->list empty"
|
|
(assert-equal (list) (vector->list (vector))))
|
|
(deftest
|
|
"vector->list numbers"
|
|
(assert-equal (list 1 2 3) (vector->list (vector 1 2 3))))
|
|
(deftest
|
|
"vector->list strings"
|
|
(assert-equal (list "a" "b") (vector->list (vector "a" "b"))))
|
|
(deftest
|
|
"list->vector empty"
|
|
(let ((v (list->vector (list)))) (assert-equal 0 (vector-length v))))
|
|
(deftest
|
|
"list->vector numbers"
|
|
(let
|
|
((v (list->vector (list 10 20 30))))
|
|
(assert-equal 3 (vector-length v))
|
|
(assert-equal 10 (vector-ref v 0))
|
|
(assert-equal 20 (vector-ref v 1))
|
|
(assert-equal 30 (vector-ref v 2))))
|
|
(deftest
|
|
"vector-fill! sets all elements"
|
|
(let
|
|
((v (vector 1 2 3)))
|
|
(vector-fill! v 0)
|
|
(assert-equal 0 (vector-ref v 0))
|
|
(assert-equal 0 (vector-ref v 1))
|
|
(assert-equal 0 (vector-ref v 2))))
|
|
(deftest
|
|
"vector-fill! returns nil"
|
|
(assert-equal nil (vector-fill! (make-vector 2 0) 7)))
|
|
(deftest
|
|
"vector-fill! string fill"
|
|
(let
|
|
((v (make-vector 3 "")))
|
|
(vector-fill! v "x")
|
|
(assert-equal "x" (vector-ref v 0))
|
|
(assert-equal "x" (vector-ref v 2))))
|
|
(deftest
|
|
"vector-copy full copy"
|
|
(let
|
|
((v1 (vector 1 2 3)) (v2 (vector-copy (vector 1 2 3))))
|
|
(assert-equal 3 (vector-length v2))
|
|
(assert-equal 1 (vector-ref v2 0))
|
|
(assert-equal 2 (vector-ref v2 1))
|
|
(assert-equal 3 (vector-ref v2 2))))
|
|
(deftest
|
|
"vector-copy is independent"
|
|
(let
|
|
((v1 (vector 1 2 3)))
|
|
(let
|
|
((v2 (vector-copy v1)))
|
|
(vector-set! v1 0 99)
|
|
(assert-equal 1 (vector-ref v2 0)))))
|
|
(deftest
|
|
"vector-copy with start"
|
|
(let
|
|
((v (vector-copy (vector 10 20 30 40) 1)))
|
|
(assert-equal 3 (vector-length v))
|
|
(assert-equal 20 (vector-ref v 0))
|
|
(assert-equal 30 (vector-ref v 1))
|
|
(assert-equal 40 (vector-ref v 2))))
|
|
(deftest
|
|
"vector-copy with start and end"
|
|
(let
|
|
((v (vector-copy (vector 10 20 30 40) 1 3)))
|
|
(assert-equal 2 (vector-length v))
|
|
(assert-equal 20 (vector-ref v 0))
|
|
(assert-equal 30 (vector-ref v 1))))
|
|
(deftest
|
|
"vector-copy empty slice"
|
|
(let
|
|
((v (vector-copy (vector 1 2 3) 1 1)))
|
|
(assert-equal 0 (vector-length v))))
|
|
(deftest
|
|
"vector-ref out of bounds raises"
|
|
(let
|
|
((ok false))
|
|
(guard (exn (else (set! ok true))) (vector-ref (vector 1 2 3) 5))
|
|
(assert ok)))
|
|
(deftest
|
|
"vector-ref negative index raises"
|
|
(let
|
|
((ok false))
|
|
(guard (exn (else (set! ok true))) (vector-ref (vector 1 2 3) -1))
|
|
(assert ok)))
|
|
(deftest
|
|
"vector-set! out of bounds raises"
|
|
(let
|
|
((ok false))
|
|
(guard
|
|
(exn (else (set! ok true)))
|
|
(vector-set! (vector 1 2 3) 10 99))
|
|
(assert ok)))
|
|
(deftest
|
|
"vector list round-trip"
|
|
(let
|
|
((lst (list 5 10 15 20)))
|
|
(assert-equal lst (vector->list (list->vector lst)))))
|
|
(deftest
|
|
"vector mutation does not affect copy"
|
|
(let
|
|
((v1 (vector 1 2 3)))
|
|
(let
|
|
((v2 (vector-copy v1)))
|
|
(vector-set! v2 0 100)
|
|
(assert-equal 1 (vector-ref v1 0))
|
|
(assert-equal 100 (vector-ref v2 0)))))
|
|
(deftest
|
|
"vector-length after fill"
|
|
(let
|
|
((v (make-vector 5 0)))
|
|
(vector-fill! v 1)
|
|
(assert-equal 5 (vector-length v)))))
|