#lang scheme/base
(require srfi/26/cut
         "../test-base.ss"
         (prefix-in js: "lang.ss")
         "struct.ss")
(define syms
  '(a b c))
(define ids
  (map (cut make-Identifier #f <>)
       syms))
(define numbers
  '(1 2 3))
(define numeric-lits 
  (map (cut make-NumericLiteral #f <>)
       numbers))
(define lang-tests
  (test-suite "lang.ss"
    
    (test-case "js:var"
      (check-exn exn:fail:contract? js:var "no args")
      (check-equal? (apply js:var syms)
                    (make-VariableDeclaration #f (map (cut make-VariableInitializer #f <> <>) ids '(#f #f #f)))
                    "no initializers")
      (check-equal? (apply js:var (map js:init syms numbers))
                    (make-VariableDeclaration #f (map (cut make-VariableInitializer #f <> <>) ids numeric-lits))
                    "initializers"))
    
    (test-case "js:begin"
      (check-equal? (js:begin)
                    (make-BeginStatement #f (list))
                    "no args")
      (check-equal? (js:begin 1 2 3)
                    (make-BeginStatement #f (map (cut make-ExpressionStatement #f <>) numeric-lits))
                    "multiple args"))
    
    (test-case "js:block"
      (check-equal? (js:block)
                    (make-BlockStatement #f null)
                    "no args")
      (check-equal? (js:block 1 2 3)
                    (make-BlockStatement #f (map (cut make-ExpressionStatement #f <>) numeric-lits))
                    "args"))
    
    (test-case "js:if"
      (check-equal? (apply js:if numbers)
                    (make-IfStatement #f
                                      (make-NumericLiteral #f 1) 
                                      (make-ExpressionStatement #f (make-NumericLiteral #f 2))
                                      (make-ExpressionStatement #f (make-NumericLiteral #f 3)))))
    
    (test-case "js:do"
      (check-equal? (js:do 1 #:while 2)
                    (make-DoWhileStatement #f
                                           (make-ExpressionStatement #f (make-NumericLiteral #f 1))
                                           (make-NumericLiteral #f 2))))
    
    (test-case "js:while"
      (check-equal? (js:while 1 2)
                    (make-WhileStatement #f
                                         (make-NumericLiteral #f 1)
                                         (make-ExpressionStatement #f (make-NumericLiteral #f 2)))))
    
    (test-case "js:for-in"
      (check-not-exn
        (lambda ()
          (js:for-in (js:var 'key) 
                     (js:object (js:field 'a 1)
                                (js:field 'b 2)
                                (js:field 'c 3))
                     (js:call 'alert (js:id 'key))))
        "single iterator variable")
      (check-exn exn:fail:contract?
        (lambda ()
          (js:for-in (js:var 'key 'val)
                     (js:object (js:field 'a 1)
                                (js:field 'b 2)
                                (js:field 'c 3))
                     (js:call 'alert (js:id 'key))))
        "multiple iterator variables"))
    
    
    ))
(provide lang-tests)