diff --git a/spec/tests/test-hyperscript-conformance-sandbox.sx b/spec/tests/test-hyperscript-conformance-sandbox.sx new file mode 100644 index 00000000..4819f44b --- /dev/null +++ b/spec/tests/test-hyperscript-conformance-sandbox.sx @@ -0,0 +1,271 @@ +;; _hyperscript conformance — 222 tests from v0.9.14 +;; +;; OCaml: loaded by run_tests.exe, uses eval-expr-cek +;; Sandbox: sx_playwright mode=sandbox stack=hs files=[this] +;; expr=(do (hs-conf-run-all) (hs-conf-report)) + +;; ── Counters ──────────────────────────────────────────────────── +(define hs-conf-pass 0) +(define hs-conf-fail 0) +(define hs-conf-fails (list)) + +;; ── eval-hs: sandbox version uses cek-eval ────────────────────── +(define eval-hs + (fn (src &rest opts) + (let ((sx (hs-to-sx (hs-compile src))) + (ctx (if (> (len opts) 0) (first opts) nil))) + (let ((bindings (list + (list (quote me) nil) + (list (quote it) nil) + (list (quote result) nil)))) + (do + (when ctx + (do + (when (get ctx "me") + (set! bindings (cons (list (quote me) (get ctx "me")) bindings))) + (when (get ctx "locals") + (for-each + (fn (k) (set! bindings (cons (list (make-symbol k) (get (get ctx "locals") k)) bindings))) + (keys (get ctx "locals")))))) + (cek-eval (list (quote let) bindings sx))))))) + +;; ── Fixture runner ────────────────────────────────────────────── +(define hs-conf-run-fixture + (fn (f) + (let ((src (get f "src")) + (expected (get f "expected")) + (ctx (if (or (get f "locals") (get f "me")) + {"locals" (get f "locals") "me" (get f "me")} nil))) + (let ((ok (try-call (fn () + (let ((result (if ctx (eval-hs src ctx) (eval-hs src)))) + (if (= result expected) + (set! hs-conf-pass (+ hs-conf-pass 1)) + (do (set! hs-conf-fail (+ hs-conf-fail 1)) + (append! hs-conf-fails (str src " => " result " exp " expected))))))))) + (when (not (get ok "ok")) + (do (set! hs-conf-fail (+ hs-conf-fail 1)) + (append! hs-conf-fails (str "ERR: " src)))))))) + +(define hs-conf-run-all + (fn () (for-each hs-conf-run-fixture hs-conf-all-fixtures))) + +(define hs-conf-report + (fn () (str hs-conf-pass "/" (+ hs-conf-pass hs-conf-fail) " pass, " hs-conf-fail " fail"))) + +;; ── Fixtures ──────────────────────────────────────────────────── +(define hs-conf-all-fixtures (list + {:src "[1, 2, 3]" :expected (list 1 2 3)} + {:src "[]" :expected (list)} + {:src "[true]" :expected (list true)} + {:src "[true, false]" :expected (list true false)} + {:src "10 as String" :expected "10"} + {:src "true as String" :expected "true"} + {:src "'10' as Int" :expected 10} + {:src "'10.4' as Int" :expected 10} + {:src "'10' as Float" :expected 10} + {:src "'10.4' as Float" :expected 10.4} + {:src "'10.4' as Fixed" :expected "10"} + {:src "'10.4899' as Fixed:2" :expected "10.49"} + {:src "'10' as Number" :expected 10} + {:src "'10.4' as Number" :expected 10.4} + {:src "{foo:'bar'} as JSON" :expected "{\"foo\":\"bar\"}"} + {:src "'{\"foo\":\"bar\"}' as Object" :expected "bar"} + {:src "'{\"foo\":\"bar\"}' as an Object" :expected "bar"} + {:src "x as Object" :expected "bar"} + {:src "x as Values" :expected "John"} + {:src "value as HTML" :expected "123"} + {:src "value as Fragment" :expected 1} + {:src "1 as Foo" :expected "foo1"} + {:src "1 as Foo:Bar" :expected "Bar1"} + {:src "\\\\-> true" :expected true} + {:src "\\\\ x -> x" :expected true} + {:src "\\\\ x, y -> y" :expected true} + {:src "['a', 'ab', 'abc'].map(\\\\ s -> s.length )" :expected (list 1 2 3)} + {:src "true" :expected true} + {:src "false" :expected false} + {:src ".badClassThatDoesNotHaveAnyElements" :expected 0} + {:src "1 < 2" :expected true} + {:src "2 < 1" :expected false} + {:src "2 < 2" :expected false} + {:src "1 <= 2" :expected true} + {:src "2 <= 1" :expected false} + {:src "2 <= 2" :expected true} + {:src "1 > 2" :expected false} + {:src "2 > 1" :expected true} + {:src "2 > 2" :expected false} + {:src "1 >= 2" :expected false} + {:src "2 >= 1" :expected true} + {:src "2 >= 2" :expected true} + {:src "1 == 2" :expected false} + {:src "2 == 1" :expected false} + {:src "2 == 2" :expected true} + {:src "1 === 2" :expected false} + {:src "2 === 1" :expected false} + {:src "2 === 2" :expected true} + {:src "1 != 2" :expected true} + {:src "2 != 1" :expected true} + {:src "2 != 2" :expected false} + {:src "1 !== 2" :expected true} + {:src "2 !== 1" :expected true} + {:src "2 !== 2" :expected false} + {:src "1 is 2" :expected false} + {:src "2 is 1" :expected false} + {:src "2 is 2" :expected true} + {:src "1 equals 2" :expected false} + {:src "2 equals 1" :expected false} + {:src "2 equals 2" :expected true} + {:src "1 is equal to 2" :expected false} + {:src "2 is equal to 1" :expected false} + {:src "2 is equal to 2" :expected true} + {:src "1 is really equal to 2" :expected false} + {:src "2 is really equal to 1" :expected false} + {:src "2 is really equal to '2'" :expected false} + {:src "2 is really equal to 2" :expected true} + {:src "1 really equals 2" :expected false} + {:src "2 really equals 1" :expected false} + {:src "2 really equals 2" :expected true} + {:src "1 is not 2" :expected true} + {:src "2 is not 1" :expected true} + {:src "2 is not 2" :expected false} + {:src "1 is not equal to 2" :expected true} + {:src "2 is not equal to 1" :expected true} + {:src "2 is not equal to 2" :expected false} + {:src "1 is not really equal to 2" :expected true} + {:src "2 is not really equal to 1" :expected true} + {:src "2 is not really equal to '2'" :expected true} + {:src "2 is not really equal to 2" :expected false} + {:src "1 is in [1, 2]" :expected true} + {:src "2 is in [1, 2]" :expected true} + {:src "3 is in [1, 2]" :expected false} + {:src "3 is in null" :expected false} + {:src "1 is not in [1, 2]" :expected false} + {:src "2 is not in [1, 2]" :expected false} + {:src "3 is not in [1, 2]" :expected true} + {:src "3 is not in null" :expected true} + {:src "I am in [1, 2]" :me 1 :expected true} + {:src "I am in [1, 2]" :me 2 :expected true} + {:src "I am in [1, 2]" :me 3 :expected false} + {:src "I am in null" :expected false} + {:src "I am not in [1, 2]" :me 1 :expected false} + {:src "I am not in [1, 2]" :me 2 :expected false} + {:src "I am not in [1, 2]" :me 3 :expected true} + {:src "I am not in null" :expected true} + {:src "'a' matches '.*'" :expected true} + {:src "'a' matches 'b'" :expected false} + {:src "'a' does not match '.*'" :expected false} + {:src "'a' does not match 'b'" :expected true} + {:src "undefined is empty" :expected true} + {:src "'' is empty" :expected true} + {:src "[] is empty" :expected true} + {:src "'not empty' is empty" :expected false} + {:src "1000 is empty" :expected false} + {:src "[1,2,3] is empty" :expected false} + {:src "undefined is not empty" :expected false} + {:src "'' is not empty" :expected false} + {:src "[] is not empty" :expected false} + {:src "'not empty' is not empty" :expected true} + {:src "1000 is not empty" :expected true} + {:src "[1,2,3] is not empty" :expected true} + {:src "null is a String" :expected true} + {:src "null is a String!" :expected false} + {:src "'' is a String!" :expected true} + {:src "null is not a String" :expected false} + {:src "null is not a String!" :expected true} + {:src "'' is not a String!" :expected false} + {:src "null is an String" :expected true} + {:src "null is an String!" :expected false} + {:src "'' is an String!" :expected true} + {:src "null is not an String" :expected false} + {:src "null is not an String!" :expected true} + {:src "'' is not an String!" :expected false} + {:src "1 is less than 2" :expected true} + {:src "2 is less than 1" :expected false} + {:src "2 is less than 2" :expected false} + {:src "1 is less than or equal to 2" :expected true} + {:src "2 is less than or equal to 1" :expected false} + {:src "2 is less than or equal to 2" :expected true} + {:src "1 is greater than 2" :expected false} + {:src "2 is greater than 1" :expected true} + {:src "2 is greater than 2" :expected false} + {:src "1 is greater than or equal to 2" :expected false} + {:src "2 is greater than or equal to 1" :expected true} + {:src "2 is greater than or equal to 2" :expected true} + {:src "undefined does not exist" :expected true} + {:src "null does not exist" :expected true} + {:src "cookies.foo" :expected "bar"} + {:src "set cookies.foo to 'bar'" :expected "bar"} + {:src "cookies.foo" :expected "bar"} + {:src "set cookies.foo to 'bar'" :expected "bar"} + {:src "cookies.foo" :expected "bar"} + {:src "set cookies.foo to 'doh'" :expected "doh"} + {:src "cookies.foo" :expected "doh"} + {:src "set cookies.foo to 'bar'" :expected true} + {:src "for x in cookies me.push(x.name) then you.push(x.value) end" :expected true} + {:src "1 in [1, 2, 3]" :expected (list 1)} + {:src "[1, 3] in [1, 2, 3]" :expected (list 1 3)} + {:src "[1, 3, 4] in [1, 2, 3]" :expected (list 1 3)} + {:src "[4, 5, 6] in [1, 2, 3]" :expected (list)} + {:src "func1() and func2()" :expected false} + {:src "func1() or func2()" :expected true} + {:src "1 + 1" :expected 2} + {:src "'a' + 'b'" :expected "ab"} + {:src "1 - 1" :expected 0} + {:src "1 * 2" :expected 2} + {:src "1 / 2" :expected 0.5} + {:src "3 mod 2" :expected 1} + {:src "1 + 2 + 3" :expected 6} + {:src "1 + (2 * 3)" :expected 7} + {:src "no null" :expected true} + {:src "no 'thing'" :expected false} + {:src "no ['thing']" :expected false} + {:src "no []" :expected true} + {:src "no .aClassThatDoesNotExist" :expected true} + {:src "not true" :expected false} + {:src "not false" :expected true} + {:src "not not true" :expected true} + {:src "-1" :expected -1} + {:src "1" :expected 1} + {:src "1.1" :expected 1.1} + {:src "1234567890.1234567890" :expected 1234570000} + {:src "{}" :expected {}} + {:src "{-foo:true, bar-baz:false}" :expected {:bar-baz false :-foo true}} + {:src "{foo:true, bar-baz:false,}" :expected {:bar-baz false :foo true}} + {:src "the first of [1, 2, 3]" :expected 1} + {:src "the last of [1, 2, 3]" :expected 3} + {:src "foo's foo" :expected "foo"} + {:src "its foo" :expected "foo"} + {:src "foo.foo" :expected "foo"} + {:src "foo of foo" :expected "foo"} + {:src "bar.doh of foo" :expected "foo"} + {:src "doh of foo.bar" :expected "foo"} + {:src "<.badClassThatDoesNotHaveAnyElements/>" :expected 0} + {:src "some null" :expected false} + {:src "some 'thing'" :expected true} + {:src "some []" :expected false} + {:src "some .aClassThatDoesNotExist" :expected false} + {:src "some " :expected true} + {:src "some ['thing']" :expected true} + {:src "1em" :expected "1em"} + {:src "1px" :expected "1px"} + {:src "-1px" :expected "-1px"} + {:src "100%" :expected "100%"} + {:src "1 em" :expected "1em"} + {:src "1 px" :expected "1px"} + {:src "100 %" :expected "100%"} + {:src "\"foo\"" :expected "foo"} + {:src "\"fo'o\"" :expected "fo'o"} + {:src "'foo'" :expected "foo"} + {:src "`$1`" :expected "1"} + {:src "`${1 + 2}`" :expected "3"} + {:src "` ${1 + 2} ${1 + 2} `" :expected " 3 3 "} + {:src "`${1 + 2} ${1 + 2} `" :expected "3 3 "} + {:src "`${1 + 2}${1 + 2} `" :expected "33 "} + {:src "`${1 + 2} ${1 + 2}`" :expected "3 3"} + {:src "`
${record.name}
`" :expected "
John Connor
"} + {:src "`https://${foo}`" :locals {:foo "bar"} :expected "https://bar"} + {:src "foo" :locals {:foo 42} :expected 42} + {:src "'foo' : String" :expected "foo"} + {:src "true : String" :expected 0} + {:src "'foo' : String!" :expected "foo"} + {:src "null : String!" :expected 0} +))