Files
js-maker/testing/jsmaker-regression.rkt
T
2026-05-27 17:00:11 +02:00

123 lines
7.3 KiB
Racket

#lang racket/base
(require racket/string
"../main.rkt"
"jsmaker-executors.rkt"
"jsmaker-test-framework.rkt")
(define direct-and (js/expression (and (> x 10) (< x 15))))
(unless (string=? direct-and "((x > 10) && (x < 15))")
(error 'jsmaker-regression "expected direct && generation, got: ~a" direct-and))
(define direct-or (js/expression (or (< x 10) (> x 20))))
(unless (string=? direct-or "((x < 10) || (x > 20))")
(error 'jsmaker-regression "expected direct || generation, got: ~a" direct-or))
(define direct-chain (js/expression (< x y 10)))
(unless (string=? direct-chain "((x < y) && (y < 10))")
(error 'jsmaker-regression "expected direct pairwise comparison, got: ~a" direct-chain))
(define effectful-chain (js/expression (< x (f y) 10)))
(unless (regexp-match? #rx"__cmp" effectful-chain)
(error 'jsmaker-regression "effectful chained comparison should use temporaries, got: ~a" effectful-chain))
(define simple-let-star
(js (let* ((x 10)
(y (+ x x)))
(return y))))
(define with-handlers-rest-lambda-program
(js (with-handlers ([exn? (λ args (displayln args))])
(/ 10 0))))
(unless (regexp-match? #rx"\\(function\\(\\.\\.\\.args\\)" with-handlers-rest-lambda-program)
(error 'jsmaker-regression
"with-handlers rest-lambda handler should be parenthesized in callee position, got: ~a"
with-handlers-rest-lambda-program))
(unless (not (regexp-match? #rx"catch[^{]*\\{\\n function\\(" with-handlers-rest-lambda-program))
(error 'jsmaker-regression
"with-handlers emitted a function declaration in statement position, got: ~a"
with-handlers-rest-lambda-program))
(unless (regexp-match? #rx"let x = 10;" simple-let-star)
(error 'jsmaker-regression "simple let* should emit direct let for x, got: ~a" simple-let-star))
(unless (regexp-match? #rx"let y = .*x.*x.*;" simple-let-star)
(error 'jsmaker-regression "simple let* should emit direct dependent let for y, got: ~a" simple-let-star))
(unless (not (regexp-match? #rx"__let_star_value" simple-let-star))
(error 'jsmaker-regression "simple let* should not use tempvars, got: ~a" simple-let-star))
(define tests
(list
(js-expression-test 'if-zero (js/expression (if 0 1 2)) "1")
(js-expression-test 'if-false (js/expression (if #f 1 2)) "2")
(js-expression-test 'and-false (js/expression (and #f 5)) "false")
(js-expression-test 'and-zero (js/expression (and 0 5)) "5")
(js-expression-test 'or-empty-string (js/expression (or "" 5)) "\"\"")
(js-expression-test 'direct-and-boolean (format "((x) => ~a)(12)" direct-and) "true")
(js-expression-test 'direct-or-boolean (format "((x) => ~a)(5)" direct-or) "true")
(js-expression-test 'chain-lt (js/expression (< 1 2 3)) "true")
(js-expression-test 'chain-lt-false (js/expression (< 1 3 2)) "false")
(js-expression-test 'let-expr (js/expression (let ([x 2] [y 3]) (+ x y))) "5")
(js-expression-test 'let-star-sequential-binding (js/expression (let* ([x 10] [y (+ x x)]) y)) "20")
(js-expression-test 'let-star-dependent-shadowing (js/expression (let ([x 4]) (let* ([x x] [y x]) (+ x y)))) "8")
(js-expression-test 'named-let (js/expression (let loop ([i 0] [s 0]) (if (< i 5) (loop (+ i 1) (+ s i)) s))) "10")
(js-expression-test 'for-list (js/expression (for/list ([x (in-range 5)] #:when (odd? x)) (* x x))) "[1,9]")
(js-expression-test 'for-fold (js/expression (for/fold ([s 0]) ([x (in-list (list 1 2 3))]) (+ x s))) "6")
(js-expression-test 'map-filter (js/expression (filter (lambda (x) (> x 2)) (map (lambda (x) (+ x 1)) (list 1 2 3)))) "[3,4]")
(js-expression-test 'hash-ref (js/expression (hash-ref (hash 'a 1 'b 2) 'b)) "2")
(js-expression-test 'compile-time-eval-number
(js/expression (eval (+ 1 2)))
"3")
(js-expression-test 'compile-time-eval-data
(js/expression (array (eval (list 1 2 3))
(eval (string-append "a" "b"))))
"[[1,2,3],\"ab\"]")
(let ([x 10]
[y 20])
(js-expression-test 'runtime-eval-lexical-let
(js/expression (let ([a (eval (* x y))]) (* a a)))
"40000"))
(js-expression-test 'substring (js/expression (substring "abcdef" 1 4)) "\"bcd\"")
(js-expression-test 'equal-list (js/expression (equal? (list 1 2) (list 1 2))) "true")
(js-expression-test 'cond-test-only (js/expression (cond [0] [else 2])) "0")
(js-expression-test 'cond-arrow (js/expression (cond [(+ 1 2) => (lambda (x) (+ x 10))] [else 0])) "13")
(js-expression-test 'cond-false-arrow (js/expression (cond [#f => (lambda (x) (+ x 10))] [else 7])) "7")
(js-expression-test 'rest-lambda (js/expression ((lambda xs (length xs)) 1 2 3)) "3")
(js-expression-test 'dotted-lambda (js/expression ((lambda (a . xs) (+ a (length xs))) 10 20 30)) "12")
(js-expression-test 'let-values-one (js/expression (let-values ([(x) 5]) (+ x 1))) "6")
(js-expression-test 'let-values-many (js/expression (let-values ([(x y) (values 2 3)]) (+ x y))) "5")
(js-expression-test 'let-tdz (js/expression (let ([x 4]) (let ([x x]) (+ x 1)))) "5")
(js-expression-test 'let-star-tdz (js/expression (let ([x 4]) (let* ([x x] [y x]) (+ x y)))) "8")
(js-expression-test 'division-normal
(js/expression (/ 20 2 2))
"5")
(js-expression-test 'with-handlers-division-by-zero
(js/expression (with-handlers ([exn? (lambda args (string-append "caught:" (exn-message (car args))))])
(/ 10 0)))
"\"caught:division by zero\"")
(js-expression-test 'with-handlers-generic-exn
(js/expression (with-handlers ([exn? (lambda (e) (string-append "caught:" (exn-message e)))])
(error "boom")))
"\"caught:boom\"")
(js-expression-test 'with-handlers-no-error
(js/expression (with-handlers ([exn? (lambda (e) 99)])
(+ 20 22)))
"42")
(js-expression-test 'gregor-prefix-date-string
(js/expression (date->string (foo:date 2026 5 25)))
"\"2026-05-25\"")
(js-expression-test 'gregor-prefix-time-string
(js/expression (time->string (bar:time 8 9 10)))
"\"08:09:10\"")
(js-expression-test 'gregor-prefix-moment-fields
(js/expression (list (baz:->year (baz:parse-moment "2026-05-25T08:09:10" "yyyy-MM-dd'T'HH:mm:ss"))
(baz:->month (baz:parse-moment "2026-05-25T08:09:10"))
(baz:->day (baz:parse-moment "2026-05-25T08:09:10"))))
"[2026,5,25]")
(js-expression-test 'gregor-js-date-conversion
(js/expression (list (q:->year (js-date->datetime (q:->js-date (q:date 2026 5 25))))
(q:date? (q:date 2026 5 25))
(q:moment? (q:moment 2026 5 25 8 9 10))))
"[2026,true,true]")))
(define engine (find-js-engine))
(run-jsmaker-regression 'jsmaker-core-regression tests "/tmp/jsmaker-core-regression.js" #:engine engine)