oke.
This commit is contained in:
@@ -1,25 +1,12 @@
|
||||
#lang racket/base
|
||||
|
||||
(require rackunit
|
||||
"../main.rkt"
|
||||
(require "../demo/dom-exercises.rkt"
|
||||
"jsmaker-test-framework.rkt")
|
||||
|
||||
(provide dom-tests)
|
||||
(check-contains 'dom-query-selector "document.querySelector(\"p\")" exercise01)
|
||||
(check-contains 'dom-inner-html "p.innerHTML" exercise01)
|
||||
(check-contains 'dom-insert-adjacent-html "insertAdjacentHTML" exercise02)
|
||||
(check-contains 'dom-text-content "textContent" exercise03)
|
||||
|
||||
(define dom-snippet
|
||||
(js
|
||||
(define title (send document getElementById "title"))
|
||||
(set! (js-dot title innerHTML) "Hello")
|
||||
(send title addEventListener "click" (lambda (evt) (return #t)))))
|
||||
|
||||
(define dom-tests
|
||||
(test-suite
|
||||
"DOM-like JavaScript generation"
|
||||
(test-case "send and js-dot generate method calls and property assignment"
|
||||
(check-js-contains? dom-snippet "document.getElementById(\"title\")")
|
||||
(check-js-contains? dom-snippet "title.innerHTML = \"Hello\";")
|
||||
(check-js-contains? dom-snippet "title.addEventListener"))))
|
||||
|
||||
(module+ test
|
||||
(require rackunit/text-ui)
|
||||
(run-tests dom-tests))
|
||||
(module+ main
|
||||
(test-summary 'jsmaker-dom-exercises))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#lang racket/base
|
||||
|
||||
(require "jsmaker-test-framework.rkt")
|
||||
(provide node-available? run-js/trimmed)
|
||||
;; Kept as a compatibility source file for the package layout. js-maker 3 uses
|
||||
;; the small optional Node runner in jsmaker-test-framework.rkt.
|
||||
(provide)
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
#lang racket/base
|
||||
|
||||
(require rackunit
|
||||
"../main.rkt"
|
||||
"jsmaker-test-framework.rkt")
|
||||
|
||||
(provide object-tests)
|
||||
|
||||
(define object-tests
|
||||
(test-suite
|
||||
"object construction regression tests"
|
||||
(test-case "new and method calls"
|
||||
(check-js-equal? (js (new Date)) "new Date();\n")
|
||||
(check-js-equal? (js (send console log "ok")) "console.log(\"ok\");\n"))))
|
||||
|
||||
(module+ test
|
||||
(require rackunit/text-ui)
|
||||
(run-tests object-tests))
|
||||
;; The old js-maker 2 hash tests covered a runtime library that is intentionally
|
||||
;; not part of the compact js-maker 3 restart. See README.md for the retained
|
||||
;; and removed test categories.
|
||||
(provide)
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
#lang racket/base
|
||||
|
||||
(require rackunit
|
||||
"../main.rkt"
|
||||
(require "../main.rkt"
|
||||
"jsmaker-test-framework.rkt")
|
||||
|
||||
(provide list-tests)
|
||||
(define list-program
|
||||
(string-append
|
||||
(js (define (makeList) (return (list 1 2 3))))
|
||||
"\nconsole.log(JSON.stringify(makeList()));\n"))
|
||||
(run-js-if-available 'list-runtime list-program "[1,2,3]")
|
||||
|
||||
(define list-tests
|
||||
(test-suite
|
||||
"list and quoted datum generation"
|
||||
(test-case "list and cons"
|
||||
(check-js-equal? (js (list 1 2 3)) "[1, 2, 3];\n")
|
||||
(check-js-equal? (js (cons 1 (list 2 3))) "[1].concat([2, 3]);\n"))
|
||||
(test-case "quoted data"
|
||||
(check-js-equal? (js (quote alpha)) "\"alpha\";\n")
|
||||
(check-js-equal? (js (quote (1 2 x))) "[1, 2, \"x\"];\n"))))
|
||||
(define cons-program
|
||||
(string-append
|
||||
(js (define (prepend xs) (return (cons 1 xs))))
|
||||
"\nconsole.log(JSON.stringify(prepend([2,3])));\n"))
|
||||
(run-js-if-available 'cons-runtime cons-program "[1,2,3]")
|
||||
|
||||
(module+ test
|
||||
(require rackunit/text-ui)
|
||||
(run-tests list-tests))
|
||||
(module+ main
|
||||
(test-summary 'jsmaker-list-regression))
|
||||
|
||||
@@ -1,51 +1,62 @@
|
||||
#lang racket/base
|
||||
|
||||
(require rackunit
|
||||
"../main.rkt"
|
||||
(require "../main.rkt"
|
||||
"jsmaker-test-framework.rkt")
|
||||
|
||||
(provide program-tests)
|
||||
|
||||
(define ordinary-let-program
|
||||
(string-append
|
||||
(js (define (ordinary-let x)
|
||||
(js (define (ordinaryLet x)
|
||||
(let ([x 1] [y x])
|
||||
(return y))))
|
||||
"console.log(ordinary_let(99));\n"))
|
||||
"\nconsole.log(JSON.stringify(ordinaryLet(99)));\n"))
|
||||
(run-js-if-available 'ordinary-let-runtime ordinary-let-program "99")
|
||||
|
||||
(define sequential-let-program
|
||||
(define let-star-program
|
||||
(string-append
|
||||
(js (define (sequential-let x)
|
||||
(js (define (sequentialLet x)
|
||||
(let* ([x 1] [y x])
|
||||
(return y))))
|
||||
"console.log(sequential_let(99));\n"))
|
||||
"\nconsole.log(JSON.stringify(sequentialLet(99)));\n"))
|
||||
(run-js-if-available 'let-star-runtime let-star-program "1")
|
||||
|
||||
(define named-let-program
|
||||
(string-append
|
||||
(js (define (sum-to n)
|
||||
(js (define (sumTo n)
|
||||
(let loop ([i 0] [acc 0])
|
||||
(if (> i n)
|
||||
(return acc)
|
||||
(loop (+ i 1) (+ acc i))))))
|
||||
"console.log(sum_to(10));\n"))
|
||||
"\nconsole.log(JSON.stringify(sumTo(10)));\n"))
|
||||
(run-js-if-available 'named-let-runtime named-let-program "55")
|
||||
|
||||
(define program-tests
|
||||
(test-suite
|
||||
"generated JavaScript program behavior"
|
||||
(test-case "ordinary let uses parallel Racket binding semantics"
|
||||
(check-js-contains? ordinary-let-program "const")
|
||||
(check-js-contains? ordinary-let-program "let x")
|
||||
(when (node-available?)
|
||||
(check-equal? (run-js/trimmed ordinary-let-program) "99")))
|
||||
(test-case "let* uses sequential binding semantics"
|
||||
(when (node-available?)
|
||||
(check-equal? (run-js/trimmed sequential-let-program) "1")))
|
||||
(test-case "named let compiles to a while loop with parallel updates"
|
||||
(check-js-contains? named-let-program "while (true)")
|
||||
(check-js-contains? named-let-program "continue;")
|
||||
(when (node-available?)
|
||||
(check-equal? (run-js/trimmed named-let-program) "55")))))
|
||||
(define ref-program
|
||||
(string-append
|
||||
(js (define (at xs i)
|
||||
(return (js-ref xs i))))
|
||||
"\nconsole.log(JSON.stringify(at([10,20,30],1)));\n"))
|
||||
(run-js-if-available 'ref-runtime ref-program "20")
|
||||
|
||||
(module+ test
|
||||
(require rackunit/text-ui)
|
||||
(run-tests program-tests))
|
||||
(define ref-set-program
|
||||
(string-append
|
||||
(js (define (put xs i value)
|
||||
(set! (js-ref xs i) value)
|
||||
(return xs)))
|
||||
"\nconsole.log(JSON.stringify(put([1,2,3],1,9)));\n"))
|
||||
(run-js-if-available 'ref-set-runtime ref-set-program "[1,9,3]")
|
||||
|
||||
(define ref-string-key-program
|
||||
(string-append
|
||||
(js (define (nameOf obj)
|
||||
(return (js-ref obj "name"))))
|
||||
"\nconsole.log(JSON.stringify(nameOf({name:\"Ada\"})));\n"))
|
||||
(run-js-if-available 'ref-string-key-runtime ref-string-key-program "\"Ada\"")
|
||||
|
||||
(define lambda-program
|
||||
(string-append
|
||||
(js (define (makeAdder x)
|
||||
(return (lambda (y) (return (+ x y))))))
|
||||
"\nconsole.log(JSON.stringify(makeAdder(2)(3)));\n"))
|
||||
(run-js-if-available 'lambda-runtime lambda-program "5")
|
||||
|
||||
(module+ main
|
||||
(test-summary 'jsmaker-program-regression))
|
||||
|
||||
@@ -1,19 +1,6 @@
|
||||
#lang racket/base
|
||||
|
||||
(require rackunit
|
||||
"../main.rkt"
|
||||
"jsmaker-test-framework.rkt")
|
||||
|
||||
(provide regexp-tests)
|
||||
|
||||
(define regexp-tests
|
||||
(test-suite
|
||||
"string escaping regression tests"
|
||||
(test-case "strings are JavaScript escaped"
|
||||
(check-js-equal? (js "a\"b") "\"a\\\"b\";\n")
|
||||
(check-js-equal? (js "a\\b") "\"a\\\\b\";\n")
|
||||
(check-js-equal? (js "a\nb") "\"a\\nb\";\n"))))
|
||||
|
||||
(module+ test
|
||||
(require rackunit/text-ui)
|
||||
(run-tests regexp-tests))
|
||||
;; The old regexp tests depended on a JavaScript regexp runtime shim. The new
|
||||
;; js-maker 3 core does not include that shim. See README.md for the retained
|
||||
;; and removed test categories.
|
||||
(provide)
|
||||
|
||||
@@ -1,35 +1,78 @@
|
||||
#lang racket/base
|
||||
|
||||
(require rackunit
|
||||
racket/runtime-path
|
||||
"../main.rkt"
|
||||
(require "../main.rkt"
|
||||
"jsmaker-test-framework.rkt")
|
||||
|
||||
(provide regression-tests)
|
||||
(check-public-api)
|
||||
|
||||
(define-runtime-path main-module "../main.rkt")
|
||||
(define simple-function
|
||||
(js (define (add1 x) (return (+ x 1)))))
|
||||
(check-contains 'simple-function "function add1(x)" simple-function)
|
||||
(check-contains 'simple-function-return "return x + 1;" simple-function)
|
||||
|
||||
(define regression-tests
|
||||
(test-suite
|
||||
"core js macro output"
|
||||
(test-case "the public API exports js only"
|
||||
(check-exn exn:fail? (lambda () (dynamic-require main-module 'js1)))
|
||||
(check-exn exn:fail? (lambda () (dynamic-require main-module 'js/expression))))
|
||||
(test-case "arithmetic and boolean expressions can be emitted as statements"
|
||||
(check-js-equal? (js (+ 1 2)) "1 + 2;\n")
|
||||
(check-js-equal? (js (and a b)) "a && b;\n")
|
||||
(check-js-equal? (js (not ready)) "!(ready);\n"))
|
||||
(test-case "value and function definitions"
|
||||
(check-js-equal? (js (define answer 42)) "let answer = 42;\n")
|
||||
(check-js-contains?
|
||||
(js (define (square x) (return (* x x))))
|
||||
"function square(x)"))
|
||||
(test-case "conditionals and begin blocks"
|
||||
(define out (js (if (> x 0) (return x) (return 0))))
|
||||
(check-js-contains? out "if (x > 0)")
|
||||
(check-js-contains? out "return x;")
|
||||
(check-js-contains? (js (begin (set! x 1) (return x))) "x = 1;"))))
|
||||
(define escaped-string
|
||||
(js (define (message) (return "regel 1\nregel 2 \"ok\""))))
|
||||
(check-contains 'string-newline "regel 1\\nregel 2" escaped-string)
|
||||
(check-contains 'string-quote "\\\"ok\\\"" escaped-string)
|
||||
|
||||
(module+ test
|
||||
(require rackunit/text-ui)
|
||||
(run-tests regression-tests))
|
||||
(define list-program
|
||||
(js (define (values) (return (list 1 "a" #t #f)))))
|
||||
(check-contains 'list-literal "return [1, \"a\", true, false];" list-program)
|
||||
|
||||
(define cons-program
|
||||
(js (define (prepend xs) (return (cons 1 xs)))))
|
||||
(check-contains 'cons-generation "[1].concat(xs)" cons-program)
|
||||
|
||||
(define send-program
|
||||
(js (define (unique xs) (return (send Array from (new Set xs))))))
|
||||
(check-contains 'send-generation "Array.from(new Set(xs))" send-program)
|
||||
|
||||
(define dot-set-program
|
||||
(js (define (setHtml el html) (set! (js-dot el innerHTML) html) (return (js-dot el innerHTML)))))
|
||||
(check-contains 'dot-set "el.innerHTML = html;" dot-set-program)
|
||||
(check-contains 'dot-return "return el.innerHTML;" dot-set-program)
|
||||
|
||||
(define ref-program
|
||||
(js (define (at xs i) (return (js-ref xs i)))))
|
||||
(check-contains 'ref-variable-index "return xs[i];" ref-program)
|
||||
|
||||
(define ref-string-key-program
|
||||
(js (define (nameOf obj) (return (js-ref obj "name")))))
|
||||
(check-contains 'ref-string-key "return obj[\"name\"];" ref-string-key-program)
|
||||
|
||||
(define ref-set-program
|
||||
(js (define (put xs i value) (set! (js-ref xs i) value) (return xs))))
|
||||
(check-contains 'ref-set "xs[i] = value;" ref-set-program)
|
||||
|
||||
(define ref-nested-program
|
||||
(js (define (nested matrix r c) (return (js-ref matrix r c)))))
|
||||
(check-contains 'ref-nested "return matrix[r][c];" ref-nested-program)
|
||||
|
||||
(define ordinary-let
|
||||
(js (define (ordinaryLet x)
|
||||
(let ([x 1] [y x])
|
||||
(return y)))))
|
||||
(check-matches 'ordinary-let-temp #rx"const .* = 1;" ordinary-let)
|
||||
(check-contains 'ordinary-let-inner "{\nlet x =" ordinary-let)
|
||||
(check-contains 'ordinary-let-inner-y "\nlet y =" ordinary-let)
|
||||
(check-contains 'ordinary-let-return "return y;" ordinary-let)
|
||||
|
||||
(define let-star
|
||||
(js (define (sequentialLet x)
|
||||
(let* ([x 1] [y x])
|
||||
(return y)))))
|
||||
(check-contains 'let-star-x "let x = 1;" let-star)
|
||||
(check-contains 'let-star-y "let y = x;" let-star)
|
||||
|
||||
(define named-let
|
||||
(js (define (sumTo n)
|
||||
(let loop ([i 0] [acc 0])
|
||||
(if (> i n)
|
||||
(return acc)
|
||||
(loop (+ i 1) (+ acc i)))))))
|
||||
(check-contains 'named-let-while "while (true)" named-let)
|
||||
(check-contains 'named-let-continue "continue;" named-let)
|
||||
(check-matches 'named-let-parallel-update #rx"const .* = i \\+ 1;" named-let)
|
||||
|
||||
(module+ main
|
||||
(test-summary 'jsmaker-regression))
|
||||
|
||||
@@ -1,28 +1,14 @@
|
||||
#lang racket/base
|
||||
|
||||
(require rackunit
|
||||
rackunit/text-ui
|
||||
(require "jsmaker-test-framework.rkt"
|
||||
"jsmaker-regression.rkt"
|
||||
"jsmaker-program-regression.rkt"
|
||||
"jsmaker-dom-exercises.rkt"
|
||||
"jsmaker-list-regression.rkt"
|
||||
"jsmaker-hash-regression.rkt"
|
||||
"jsmaker-regexp-regression.rkt"
|
||||
"jsmaker-usecases.rkt"
|
||||
"jsmaker-hash-regression.rkt")
|
||||
|
||||
(define all-tests
|
||||
(test-suite
|
||||
"js-maker 3 regression suite"
|
||||
regression-tests
|
||||
program-tests
|
||||
dom-tests
|
||||
list-tests
|
||||
regexp-tests
|
||||
usecase-tests
|
||||
object-tests))
|
||||
"jsmaker-dom-exercises.rkt"
|
||||
"jsmaker-usecases.rkt")
|
||||
|
||||
(module+ main
|
||||
(void (run-tests all-tests)))
|
||||
|
||||
(module+ test
|
||||
(void (run-tests all-tests)))
|
||||
(test-summary 'jsmaker-regressions)
|
||||
(displayln "js-maker regression suite completed."))
|
||||
|
||||
@@ -1,57 +1,115 @@
|
||||
#lang racket/base
|
||||
|
||||
(require rackunit
|
||||
racket/string
|
||||
racket/file
|
||||
racket/system)
|
||||
(require racket/file
|
||||
racket/format
|
||||
racket/list
|
||||
racket/port
|
||||
racket/runtime-path
|
||||
racket/string)
|
||||
|
||||
(provide check-js-equal?
|
||||
check-js-contains?
|
||||
check-js-matches?
|
||||
node-available?
|
||||
run-js/trimmed)
|
||||
(provide check-true
|
||||
check-equal
|
||||
check-matches
|
||||
check-not-matches
|
||||
check-contains
|
||||
check-not-contains
|
||||
check-public-api
|
||||
run-js-if-available
|
||||
note-dropped
|
||||
test-summary)
|
||||
|
||||
(define-check (check-js-equal? actual expected)
|
||||
(check-equal? actual expected))
|
||||
(define checks-run 0)
|
||||
(define checks-skipped 0)
|
||||
|
||||
(define-check (check-js-contains? actual needle)
|
||||
(check-true (string-contains? actual needle)
|
||||
(format "expected generated JavaScript to contain ~s, got:\n~a" needle actual)))
|
||||
(define (bump!) (set! checks-run (add1 checks-run)))
|
||||
(define (skip!) (set! checks-skipped (add1 checks-skipped)))
|
||||
|
||||
(define-check (check-js-matches? actual pattern)
|
||||
(check-true (regexp-match? pattern actual)
|
||||
(format "expected generated JavaScript to match ~s, got:\n~a" pattern actual)))
|
||||
(define (fail name fmt . args)
|
||||
(error name (apply format fmt args)))
|
||||
|
||||
(define (node-available?)
|
||||
(and (find-executable-path "node") #t))
|
||||
(define (check-true name value)
|
||||
(bump!)
|
||||
(unless value (fail name "check failed")))
|
||||
|
||||
(define (run-js/trimmed program)
|
||||
(define node (find-executable-path "node"))
|
||||
(unless node
|
||||
(error 'run-js/trimmed "node is not available"))
|
||||
(define source-path (make-temporary-file "js-maker-test-~a.js"))
|
||||
(define out-path (make-temporary-file "js-maker-test-out-~a.txt"))
|
||||
(define err-path (make-temporary-file "js-maker-test-err-~a.txt"))
|
||||
(dynamic-wind
|
||||
void
|
||||
(lambda ()
|
||||
(call-with-output-file source-path #:exists 'truncate
|
||||
(lambda (out) (display program out)))
|
||||
(define exit-code
|
||||
(call-with-output-file out-path #:exists 'truncate
|
||||
(lambda (out)
|
||||
(call-with-output-file err-path #:exists 'truncate
|
||||
(lambda (err)
|
||||
(parameterize ([current-output-port out]
|
||||
[current-error-port err])
|
||||
(system*/exit-code node source-path)))))))
|
||||
(define stdout (file->string out-path))
|
||||
(define stderr (file->string err-path))
|
||||
(unless (zero? exit-code)
|
||||
(error 'run-js/trimmed
|
||||
"node failed with exit code ~a\nstdout:\n~a\nstderr:\n~a\nprogram:\n~a"
|
||||
exit-code stdout stderr program))
|
||||
(string-trim stdout))
|
||||
(lambda ()
|
||||
(for ([path (list source-path out-path err-path)])
|
||||
(with-handlers ([exn:fail? void]) (delete-file path))))))
|
||||
(define (check-equal name actual expected)
|
||||
(bump!)
|
||||
(unless (equal? actual expected)
|
||||
(fail name "expected ~s, got ~s" expected actual)))
|
||||
|
||||
(define (check-matches name rx text)
|
||||
(bump!)
|
||||
(unless (regexp-match? rx text)
|
||||
(fail name "expected generated text to match ~s, got:\n~a" rx text)))
|
||||
|
||||
(define (check-not-matches name rx text)
|
||||
(bump!)
|
||||
(when (regexp-match? rx text)
|
||||
(fail name "expected generated text not to match ~s, got:\n~a" rx text)))
|
||||
|
||||
(define (check-contains name needle text)
|
||||
(bump!)
|
||||
(unless (string-contains? text needle)
|
||||
(fail name "expected generated text to contain ~s, got:\n~a" needle text)))
|
||||
|
||||
(define (check-not-contains name needle text)
|
||||
(bump!)
|
||||
(when (string-contains? text needle)
|
||||
(fail name "expected generated text not to contain ~s, got:\n~a" needle text)))
|
||||
|
||||
(define-runtime-path main-path "../main.rkt")
|
||||
|
||||
(define (all-symbols v)
|
||||
(cond [(symbol? v) (list v)]
|
||||
[(pair? v) (append (all-symbols (car v)) (all-symbols (cdr v)))]
|
||||
[else null]))
|
||||
|
||||
(define (check-public-api)
|
||||
(define mp `(file ,(path->string main-path)))
|
||||
(dynamic-require mp #f)
|
||||
(define-values (value-exports syntax-exports) (module->exports mp))
|
||||
(define exports (remove-duplicates (append (all-symbols value-exports)
|
||||
(all-symbols syntax-exports))))
|
||||
(check-true 'public-api-js (memq 'js exports))
|
||||
(check-true 'public-api-no-js1 (not (memq 'js1 exports)))
|
||||
(check-true 'public-api-no-js-ref (not (memq 'js-ref exports)))
|
||||
(check-true 'public-api-no-js/expression (not (memq 'js/expression exports))))
|
||||
|
||||
(define (candidate-node)
|
||||
(define env-node (getenv "JSMAKER_NODE"))
|
||||
(cond [(and env-node (not (string=? env-node ""))) env-node]
|
||||
[else (find-executable-path "node")]))
|
||||
|
||||
(define (subprocess-output executable file)
|
||||
(define-values (proc stdout stdin stderr)
|
||||
(subprocess #f #f #f executable file))
|
||||
(close-output-port stdin)
|
||||
(define out (port->string stdout))
|
||||
(define err (port->string stderr))
|
||||
(subprocess-wait proc)
|
||||
(values (subprocess-status proc) out err))
|
||||
|
||||
(define (run-js-if-available name program expected-stdout)
|
||||
(define node (candidate-node))
|
||||
(cond
|
||||
[node
|
||||
(bump!)
|
||||
(define file (make-temporary-file "jsmaker-~a.js"))
|
||||
(call-with-output-file file #:exists 'replace
|
||||
(lambda (out) (display program out)))
|
||||
(define-values (status stdout stderr) (subprocess-output node file))
|
||||
(delete-file file)
|
||||
(unless (and (zero? status) (string=? (string-trim stdout) expected-stdout))
|
||||
(fail name "JavaScript execution failed; status=~a stdout=~s stderr=~s program:\n~a"
|
||||
status stdout stderr program))]
|
||||
[else
|
||||
(skip!)
|
||||
(printf "NOTE: ~a skipped because node was not found.\n" name)]))
|
||||
|
||||
(define (note-dropped topic reason)
|
||||
(printf "NOTE: dropped old ~a tests: ~a\n" topic reason))
|
||||
|
||||
(define (test-summary who)
|
||||
(printf "~a: ~a checks passed" who checks-run)
|
||||
(unless (zero? checks-skipped)
|
||||
(printf ", ~a JavaScript execution checks skipped" checks-skipped))
|
||||
(newline))
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
#lang racket/base
|
||||
(require "jsmaker-regressions.rkt")
|
||||
|
||||
;; Kept as a compatibility source file for the package layout. Tests are run
|
||||
;; through testing/jsmaker-regressions.rkt.
|
||||
(provide)
|
||||
|
||||
@@ -1,32 +1,13 @@
|
||||
#lang racket/base
|
||||
|
||||
(require rackunit
|
||||
"../main.rkt"
|
||||
(require "../demo/js-usecases.rkt"
|
||||
"jsmaker-test-framework.rkt")
|
||||
|
||||
(provide usecase-tests)
|
||||
(check-contains 'usecase-random "Math.floor" usecase-random-number)
|
||||
(check-contains 'usecase-unique "new Set" usecase-unique-values)
|
||||
(check-contains 'usecase-array-at "return xs[i];" usecase-array-at)
|
||||
(check-contains 'usecase-named-let "while (true)" usecase-sum-to)
|
||||
(check-contains 'usecase-dom "getElementById" usecase-set-html)
|
||||
|
||||
(define counter-program
|
||||
(string-append
|
||||
(js (define (make-counter start)
|
||||
(let ([value start])
|
||||
(return (lambda ()
|
||||
(begin
|
||||
(set! value (+ value 1))
|
||||
(return value)))))))
|
||||
"const c = make_counter(5);\n"
|
||||
"console.log(c());\n"
|
||||
"console.log(c());\n"))
|
||||
|
||||
(define usecase-tests
|
||||
(test-suite
|
||||
"small use cases"
|
||||
(test-case "closures and set!"
|
||||
(check-js-contains? counter-program "function make_counter(start)")
|
||||
(check-js-contains? counter-program "value = value + 1;")
|
||||
(when (node-available?)
|
||||
(check-equal? (run-js/trimmed counter-program) "6\n7")))))
|
||||
|
||||
(module+ test
|
||||
(require rackunit/text-ui)
|
||||
(run-tests usecase-tests))
|
||||
(module+ main
|
||||
(test-summary 'jsmaker-usecases))
|
||||
|
||||
Reference in New Issue
Block a user