Fixed bug in keyword argument handling (patch thanks to Red Daly).
[clinton/parenscript.git] / t / ps-tests.lisp
index 710b49b..6d4ab8a 100644 (file)
@@ -44,7 +44,7 @@ x = 2 + sideEffect() + x + 5;")
 
 (test-ps-js method-call-op-form-args
   ((@ (+ "" x) to-string) 1 2 :baz 3)
-  "('' + x).toString(1, 2, { baz : 3 })")
+  "('' + x).toString(1, 2, 'baz', 3)")
 
 (test-ps-js method-call-number
   ((@ 10 to-string))
@@ -211,42 +211,39 @@ x = 2 + sideEffect() + x + 5;")
 (test script-star-eval2
   (is (string= "x = 1;" (normalize-js-code (ps* '(setf x 1))))))
 
-(test-ps-js slot-value-null1
-  (slot-value foo nil)
-  "foo")
-
-(test-ps-js slot-value-null2
-  (slot-value foo 'nil)
-  "foo")
-
 (test-ps-js unquoted-nil
   nil
   "null")
 
 (test-ps-js list-with-single-nil
-  (array 'nil)
+  (array nil)
   "[null]")
 
-(test-ps-js quoted-nil
+(test-ps-js quoted-nil-is-array
   'nil
-  "null")
-
-(test defsetf1
-  (ps (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval)))
-  (is (string= "var _js2 = 1; var _js3 = 2; var _js1 = 3; setBaz(_js2, _js3, _js1);"
-               (normalize-js-code (let* ((ps:*ps-gensym-counter* 0))
-                                    (ps (setf (baz 1 2) 3)))))))
-
-(test defsetf-short
-  (ps (defsetf baz set-baz "blah"))
-  (is (string= "setBaz(1, 2, 3, 'foo');" (normalize-js-code (ps (setf (baz 1 2 3) "foo"))))))
+  "[]")
 
-(test defun-setf1
-  (is (and (string= (normalize-js-code (ps:ps (defun (setf some-thing) (new-val i1 i2)
-                                                (setf (aref *some-thing* i1 i2) new-val))))
-               "function __setf_someThing(newVal, i1, i2) { SOMETHING[i1][i2] = newVal; };")
-           (string= (normalize-js-code (ps:ps-doc (setf (some-thing 1 2) "foo")))
-                    "var _js2 = 1; var _js3 = 2; var _js1 = 'foo'; __setf_someThing(_js1, _js2, _js3);"))))
+(test-ps-js defsetf1
+  (progn (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval))
+         (setf (baz 1 2) 3))
+  "var _js2 = 1; var _js3 = 2; var _js1 = 3; setBaz(_js2, _js3, _js1);")
+
+(test-ps-js defsetf-short
+  (progn (defsetf baz set-baz "docstring")
+         (setf (baz 1 2 3) "foo"))
+  "setBaz(1, 2, 3, 'foo');")
+
+(test-ps-js defun-setf1
+  (progn (defun (setf some-thing) (new-val i1 i2)
+           (setf (aref *some-thing* i1 i2) new-val))
+         (setf (some-thing 1 2) "foo"))
+"function __setf_someThing(newVal, i1, i2) {
+    SOMETHING[i1][i2] = newVal;
+};
+var _js2 = 1;
+var _js3 = 2;
+var _js1 = 'foo';
+__setf_someThing(_js1, _js2, _js3);")
 
 (test-ps-js defun-optional1
   (defun test-opt (&optional x) (return (if x "yes" "no")))
@@ -367,8 +364,8 @@ x = 2 + sideEffect() + x + 5;")
   (defun foo (&rest bar) (alert bar[1]))
   "function foo() {
     var bar = [];
-    for (var i2 = 0; i2 < arguments.length - 0; i2 += 1) {
-        bar[i2] = arguments[i2 + 0];
+    for (var i1 = 0; i1 < arguments.length - 0; i1 += 1) {
+        bar[i1] = arguments[i1 + 0];
     };
     alert(bar[1]);
 }")
@@ -377,53 +374,109 @@ x = 2 + sideEffect() + x + 5;")
   (defun foo (baz &rest bar) (return (+ baz (aref bar 1))))
   "function foo(baz) {
     var bar = [];
-    for (var i2 = 0; i2 < arguments.length - 1; i2 += 1) {
-        bar[i2] = arguments[i2 + 1];
+    for (var i1 = 0; i1 < arguments.length - 1; i1 += 1) {
+        bar[i1] = arguments[i1 + 1];
     };
     return baz + bar[1];
 }")
 
 (test-ps-js defun-keyword1
   (defun zoo (foo bar &key baz) (return (+ foo bar baz)))
-  "function zoo(foo, bar, _js1) {
-    if (_js1 === undefined) {
-        _js1 = {  };
+"function zoo(foo, bar) {
+    var baz;
+    var _js3 = arguments.length;
+    for (var n1 = 2; n1 < _js3; n1 += 2) {
+        switch (arguments[n1]) {
+        case 'baz':
+            {
+                baz = arguments[n1 + 1];
+            };
+        };
     };
-    return foo + bar + _js1.baz;
+    if (baz === undefined) {
+        baz = null;
+    };
+    return foo + bar + baz;
 }")
 
 (test-ps-js defun-keyword2
   (defun zoo (&key baz) (return (* baz baz)))
-  "function zoo(_js1) {
-    if (_js1 === undefined) {
-        _js1 = {  };
+  "function zoo() {
+    var baz;
+    var _js3 = arguments.length;
+    for (var n1 = 0; n1 < _js3; n1 += 2) {
+        switch (arguments[n1]) {
+        case 'baz':
+            {
+                baz = arguments[n1 + 1];
+            };
+        };
+    };
+    if (baz === undefined) {
+        baz = null;
     };
-    return _js1.baz * _js1.baz;
+    return baz * baz;
 }")
 
 (test-ps-js defun-keyword3
   (defun zoo (&key baz (bar 4)) (return (* baz bar)))
-  "function zoo(_js1) {
-    if (_js1 === undefined) {
-        _js1 = {  };
+  "function zoo() {
+    var baz;
+    var bar;
+    var _js3 = arguments.length;
+    for (var n1 = 0; n1 < _js3; n1 += 2) {
+        switch (arguments[n1]) {
+        case 'baz':
+            {
+                baz = arguments[n1 + 1];
+            };
+            break;
+        case 'bar':
+            {
+                bar = arguments[n1 + 1];
+            };
+        };
+    };
+    if (baz === undefined) {
+        baz = null;
+    };
+    if (bar === undefined) {
+        bar = 4;
+    };
+    return baz * bar;
+}")
+
+(test-ps-js defun-keyword4
+  (defun hello-world (&key ((:my-name-key my-name) 1))
+    my-name)
+  "function helloWorld() {
+    var myName;
+    var _js3 = arguments.length;
+    for (var n1 = 0; n1 < _js3; n1 += 2) {
+        switch (arguments[n1]) {
+        case 'my-name-key':
+            {
+                myName = arguments[n1 + 1];
+            };
+        };
     };
-    if (_js1.bar === undefined) {
-        _js1.bar = 4;
+    if (myName === undefined) {
+        myName = 1;
     };
-    return _js1.baz * _js1.bar;
+    myName;
 }")
 
 (test-ps-js keyword-funcall1
   (func :baz 1)
-  "func({ baz : 1 })")
+  "func('baz', 1)")
 
 (test-ps-js keyword-funcall2
   (func :baz 1 :bar foo)
-  "func({ baz : 1, bar : foo })")
+  "func('baz', 1, 'bar', foo)")
 
 (test-ps-js keyword-funcall3
   (fun a b :baz c)
-  "fun(a, b, { baz : c })")
+  "fun(a, b, 'baz', c)")
   
 (test-ps-js cond1
   (cond ((= x 1) 1))
@@ -432,7 +485,8 @@ x = 2 + sideEffect() + x + 5;")
 }")
 
 (test-ps-js cond2
-  (cond ((= x 1) 2) ((= y (* x 4)) (foo "blah") (* x y)))
+  (cond ((= x 1) 2)
+        ((= y (* x 4)) (foo "blah") (* x y)))
   "if (x == 1) {
     2;
 } else if (y == x * 4) {
@@ -479,7 +533,7 @@ x = 2 + sideEffect() + x + 5;")
                      :onclick (ps-inline (transport)))
                  img))
        img))
-  "document.write(LINKORNOT == 1 ? '<A HREF=\"#\" ONCLICK=\"' + ('javascript:' + 'transport()') + '\">' + img + '</A>' : img)")
+  "document.write(LINKORNOT == 1 ? '<A HREF=\"#\" ONCLICK=\"' + ('javascript:' + 'transport' + '(' + ')') + '\">' + img + '</A>' : img)")
 
 (test-ps-js negate-number-literal ;; ok, this was broken and fixed before, but no one bothered to add the test!
   (- 1)
@@ -640,10 +694,6 @@ try {
   (instanceof (or a b) (if x y z))
   "((a || b) instanceof (x ? y : z))")
 
-(test-ps-js op-p6
-  (doeach (x (or a b)))
-  "for (var x in (a || b)) { };")
-
 (test-ps-js op-p7
   (or x (if (= x 0) "zero" "empty"))
   "x || (x == 0 ? 'zero' : 'empty')")
@@ -691,3 +741,81 @@ try {
 (test-ps-js slot-value-lambda
   (slot-value (lambda ()) 'prototype)
   "(function () { }).prototype")
+
+(test-ps-js who-html1
+  (who-ps-html (:span :class "ticker-symbol"
+                      :ticker-symbol symbol
+                      (:a :href "http://foo.com"
+                          symbol)
+                      (:span :class "ticker-symbol-popup")))
+  "'<SPAN CLASS=\"ticker-symbol\" TICKER-SYMBOL=\"' + symbol + '\"><A HREF=\"http://foo.com\">' + symbol + '</A><SPAN CLASS=\"ticker-symbol-popup\"></SPAN></SPAN>'")
+
+(test-ps-js flet1
+  ((lambda () (flet ((foo (x) (return (1+ x)))) (return (foo 1)))))
+  "(function () {
+    var foo = function (x) {
+        return x + 1;
+    };
+    return foo(1);
+})()")
+
+(test-ps-js labels1
+  ((lambda () (labels ((foo (x) 
+                         (return (if (=== 0 x)
+                                     0
+                                     (+ x (foo (1- x)))))))
+                (return (foo 3)))))
+  "(function () {
+    var foo = function foo(x) {
+        return 0 === x ? 0 : x + foo(x - 1);
+    };
+    return foo(3);
+})()")
+
+(test-ps-js for-loop-var-init-exp
+  ((lambda (x)
+     (return (do* ((y (if x 0 1) (1+ y))
+                   (z 0 (1+ z)))
+                  ((= y 3) z))))
+   true)
+  "(function (x) {
+    return (function () {
+        for (var y = x ? 0 : 1, z = 0; y != 3; y += 1, z += 1) {
+        };
+        return z;
+    })();
+})(true)")
+
+(test-ps-js math-pi
+  pi
+  "Math.PI")
+
+(test-ps-js literal-array
+  '(1 2 3)
+  "[1, 2, 3]")
+
+(test-ps-js literal-array-1
+  '(1 foo 3)
+  "[1, 'foo', 3]")
+
+(test ps-lisp-expands-in-lexical-environment
+  (is (string= "5;" (let ((x 5)) (ps (lisp x))))))
+
+(test ps*-lisp-expands-in-null-lexical-environment
+  (signals error (let ((x 5)) (declare (ignore x)) (ps* '(lisp x)))))
+
+(test ps*-lisp-expands-in-dynamic-environment
+  (is (string= "1 + 2;" (let ((*print-level* 2)) (ps* '(+ 1 (lisp *print-level*)))))))
+
+(test ps-lisp-dynamic-environment
+  (is (string= "1 + 2;" (let ((*print-level* 2)) (ps (+ 1 (lisp *print-level*)))))))
+
+(test-ps-js ps-js-target-version-keyword-test1
+  (defun foo (x y &key bar baz))
+  "function foo(x, y) {
+    var x1 = Array.prototype.indexOf.call(arguments, 'bar', 2);
+    var bar = -1 == x1 ? null : arguments[x1 + 1];
+    var x2 = Array.prototype.indexOf.call(arguments, 'baz', 2);
+    var baz = -1 == x2 ? null : arguments[x2 + 1];
+}"
+  :js-target-version 1.6)