diff --git a/spec/tests/test-hyperscript-behavioral.sx b/spec/tests/test-hyperscript-behavioral.sx index 47d35741..0f97941c 100644 --- a/spec/tests/test-hyperscript-behavioral.sx +++ b/spec/tests/test-hyperscript-behavioral.sx @@ -7378,7 +7378,9 @@ ;; ── asExpression (17 tests) ── (defsuite "hs-upstream-asExpression" (deftest "converts value as Boolean" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= true (eval-hs "1 as Boolean")) + (assert= false (eval-hs "0 as Boolean")) + ) (deftest "can use the a modifier if you like" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) (deftest "parses string as JSON to object" @@ -7511,9 +7513,19 @@ (deftest "ends with coerces to string" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) (deftest "is between works" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= true (eval-hs "5 is between 1 and 10")) + (assert= true (eval-hs "1 is between 1 and 10")) + (assert= true (eval-hs "10 is between 1 and 10")) + (assert= false (eval-hs "0 is between 1 and 10")) + (assert= false (eval-hs "11 is between 1 and 10")) + ) (deftest "is not between works" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= false (eval-hs "5 is not between 1 and 10")) + (assert= true (eval-hs "0 is not between 1 and 10")) + (assert= true (eval-hs "11 is not between 1 and 10")) + (assert= false (eval-hs "1 is not between 1 and 10")) + (assert= false (eval-hs "10 is not between 1 and 10")) + ) (deftest "between works with strings" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) (deftest "I am between works" @@ -7557,7 +7569,9 @@ (dom-append (dom-body) _el-b) )) (deftest "precedes with null is false" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= false (eval-hs "null precedes null")) + (assert= true (eval-hs "null does not precede null")) + ) (deftest "I precede works" (hs-cleanup!) (let ((_el-a (dom-create-element "div")) (_el-b (dom-create-element "div"))) @@ -7570,19 +7584,31 @@ (assert= "yes" (dom-text-content (dom-query-by-id "a"))) )) (deftest "is really works without equal to" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= true (eval-hs "2 is really 2")) + ) (deftest "is not really works without equal to" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= false (eval-hs "2 is not really 2")) + ) (deftest "is equal works without to" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= true (eval-hs "2 is equal 2")) + (assert= false (eval-hs "2 is equal 1")) + ) (deftest "is not equal works without to" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= false (eval-hs "2 is not equal 2")) + (assert= true (eval-hs "2 is not equal 1")) + ) (deftest "am works as alias for is" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= true (eval-hs "2 am 2")) + (assert= false (eval-hs "2 am 1")) + ) (deftest "is not undefined still works as equality" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= true (eval-hs "5 is not undefined")) + (assert= false (eval-hs "null is not undefined")) + ) (deftest "is not null still works as equality" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= true (eval-hs "5 is not null")) + (assert= false (eval-hs "null is not null")) + ) (deftest "is falls back to boolean property when rhs is undefined" (hs-cleanup!) (let ((_el-c1 (dom-create-element "input")) (_el-c2 (dom-create-element "input"))) @@ -7641,7 +7667,8 @@ ;; ── in (1 tests) ── (defsuite "hs-upstream-in" (deftest "null value in array returns empty" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + ;; toEqual: [] + ) ) ;; ── logicalOperator (3 tests) ── @@ -7657,15 +7684,19 @@ ;; ── mathOperator (5 tests) ── (defsuite "hs-upstream-mathOperator" (deftest "array + array concats" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + ;; toEqual: [1, 2, 3, 4] + ) (deftest "array + single value appends" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + ;; toEqual: [1, 2, 3] + ) (deftest "array + array does not mutate original" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) (deftest "array concat chains" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + ;; toEqual: [1, 2, 3] + ) (deftest "empty array + array works" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + ;; toEqual: [1, 2] + ) ) ;; ── no (5 tests) ── @@ -7673,9 +7704,11 @@ (deftest "no returns false for non-empty array" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) (deftest "no with where filters then checks emptiness" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= true (eval-hs "no [1, 2, 3] where it > 5")) + ) (deftest "no with where returns false when matches exist" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + (assert= false (eval-hs "no [1, 2, 3] where it > 1")) + ) (deftest "no with where and is not" (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) (deftest "no with where on DOM elements" @@ -7695,7 +7728,8 @@ ;; ── objectLiteral (1 tests) ── (defsuite "hs-upstream-objectLiteral" (deftest "allows trailing commas" - (error "NOT IMPLEMENTED: test HTML could not be parsed into SX")) + ;; toEqual: { "foo": true, "bar-baz": false } + ) ) ;; ── queryRef (1 tests) ── diff --git a/tests/playwright/generate-sx-tests.py b/tests/playwright/generate-sx-tests.py index f3d1848c..b5865e3f 100644 --- a/tests/playwright/generate-sx-tests.py +++ b/tests/playwright/generate-sx-tests.py @@ -497,12 +497,54 @@ def generate_test_pw(test, elements, var_names, idx): return '\n'.join(lines) +def generate_eval_only_test(test, idx): + """Generate SX deftest for no-HTML tests using eval-hs. + Parses body field for run("expr").toBe(val) / expect(run("expr")).toBe(val) patterns.""" + body = test.get('body', '') + lines = [] + lines.append(f' (deftest "{test["name"]}"') + + # Extract run("expr").toBe(val) or expect(await run("expr")).toBe(val) patterns + assertions = [] + for m in re.finditer(r'(?:expect\()?(?:await\s+)?run\(["\x27]([^"\x27]+)["\x27]\)\)?\.toBe\(([^)]+)\)', body): + hs_expr = m.group(1).replace('\\', '').replace('"', '\\"') + expected = m.group(2).strip() + # Convert JS values to SX + if expected == 'true': expected_sx = 'true' + elif expected == 'false': expected_sx = 'false' + elif expected == 'null' or expected == 'undefined': expected_sx = 'nil' + elif expected.startswith('"') or expected.startswith("'"): + expected_sx = '"' + expected.strip("\"'") + '"' + else: + try: + float(expected) + expected_sx = expected + except ValueError: + expected_sx = f'"{expected}"' + assertions.append(f' (assert= {expected_sx} (eval-hs "{hs_expr}"))') + + # Also handle toEqual patterns + for m in re.finditer(r'(?:expect\()?(?:await\s+)?run\(["\x27]([^"\x27]+)["\x27]\)\)?\.toEqual\(([^)]+)\)', body): + hs_expr = m.group(1).replace('\\', '').replace('"', '\\"') + expected = m.group(2).strip() + assertions.append(f' ;; toEqual: {expected[:40]}') + + if not assertions: + return None # Can't convert this body pattern + + for a in assertions: + lines.append(a) + lines.append(' )') + return '\n'.join(lines) + + def generate_test(test, idx): - """Generate SX deftest for an upstream test. Dispatches to Chai or PW parser.""" + """Generate SX deftest for an upstream test. Dispatches to Chai, PW, or eval-only.""" elements = parse_html(test['html']) if not elements and not test.get('html', '').strip(): - return None + # No HTML — try eval-only conversion + return generate_eval_only_test(test, idx) if not elements: return None