1 ;;;; -*- encoding:utf-8 -*-
3 ;;; Copyright 2005-2006 Henrik Hjelte
4 ;;; Copyright 2007-2012, 2018, 2020 Vladimir Sedach
5 ;;; Copyright 2019 Jason Miller
7 ;;; SPDX-License-Identifier: BSD-3-Clause
9 ;;; Redistribution and use in source and binary forms, with or
10 ;;; without modification, are permitted provided that the following
11 ;;; conditions are met:
13 ;;; 1. Redistributions of source code must retain the above copyright
14 ;;; notice, this list of conditions and the following disclaimer.
16 ;;; 2. Redistributions in binary form must reproduce the above
17 ;;; copyright notice, this list of conditions and the following
18 ;;; disclaimer in the documentation and/or other materials provided
19 ;;; with the distribution.
21 ;;; 3. Neither the name of the copyright holder nor the names of its
22 ;;; contributors may be used to endorse or promote products derived
23 ;;; from this software without specific prior written permission.
25 ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
26 ;;; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
27 ;;; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28 ;;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 ;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
30 ;;; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 ;;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
32 ;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 ;;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
34 ;;; ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35 ;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 ;;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 ;;; POSSIBILITY OF SUCH DAMAGE.
39 (in-package #:parenscript.tests
)
40 (named-readtables:in-readtable
:parenscript
)
42 (fiveam:in-suite output-tests
)
44 (test-ps-js statements-and-expressions-1
48 (test-ps-js statements-and-expressions-2
56 (test-ps-js symbol-conversion-1
58 "bangwhathashatpercent;")
60 (test-ps-js symbol-conversion-2
64 (test-ps-js symbol-conversion-3
68 (test-ps-js symbol-conversion-4
72 (test-ps-js symbol-conversion-5
74 "encodeURIComponent;")
76 (test-ps-js symbol-conversion-6
80 (test-ps-js number-literals-1
84 (test-ps-js number-literals-2
88 (test-ps-js number-literals-3
92 (test-ps-js string-literals-1
96 (test-ps-js string-literals-2
100 (test-ps-js string-literals-3
104 (test-ps-js array-literals-1
108 (test-ps-js array-literals-2
112 (test-ps-js array-literals-3
114 (array "foobar" "bratzel bub"))
115 "[[2, 3], ['foobar', 'bratzel bub']];")
117 (test-ps-js array-literals-4
121 (test-ps-js array-literals-5
123 "new Array(1, 2, 3);")
125 (test-ps-js array-literals-6
128 (make-array "foobar" "bratzel bub"))
129 "new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));")
131 (test-ps-js array-init-1
132 (make-array 2 :initial-contents
'(10 20))
134 var arr1 = new Array(2);
135 var init2 = [10, 20];
136 for (var i4 = 0; i4 < Math.min(arr1.length, init2.length); i4 += 1) {
137 arr1[i4] = init2[i4];
143 (test-ps-js array-init-2
144 (make-array 5 :initial-element
10)
146 var arr1 = new Array(5);
148 for (var i4 = 0; i4 < arr1.length; i4 += 1) {
155 (test-ps-js object-literals-1
156 (create foo
"bar" :blorg
1)
157 "{ foo : 'bar', 'blorg' : 1 };")
159 (test-ps-js object-literals-2
162 another-object
(create :schtrunz
1))
165 anotherObject : { 'schtrunz' : 1 } };")
167 (test-ps-js object-literals-3
168 (getprop an-object
'foo
)
171 (test-ps-js object-literals-4
172 (@ an-object foo bar
)
175 (test-ps-js object-literals-5
176 (with-slots (a b c
) this
178 "this.a + this.b + this.c;")
180 (test-ps-js with-slots-single-eval
181 (lambda () (with-slots (a b
) (foo) (+ a b
)))
185 return object1.a + object1.b;
188 (test-ps-js object-literal-quoted-symbols
189 (create 'test
"bang" 'symbol-saved-my-life
"parenscript")
190 "{ 'test' : 'bang', 'symbolSavedMyLife' : 'parenscript' };")
192 (test-ps-js object-literal-property-accessors
196 (set x v
) (setf x v
))))
205 :js-target-version
"1.8.5")
207 (test-ps-js object-method-apply-1
208 (apply (@ an-object foo
) nil
)
209 "anObject.foo.apply(anObject, null);")
211 (test-ps-js object-method-apply-2
212 (apply (getprop (make-an-object) foo
'bar
) nil
)
214 var _js1 = makeAnObject()[foo];
217 return _js2.apply(_js1, null);
220 (test-ps-js object-method-apply-3
221 (apply (@ (make-an-object) foo
) (bar))
223 var _js1 = makeAnObject();
226 return _js2.apply(_js1, bar());
229 (test-ps-js regular-expression-literals-1
233 (test-ps-js regular-expression-literals-2
237 (test-ps-js literal-symbols-1
241 (test-ps-js literal-symbols-2
245 (test-ps-js literal-symbols-3
249 (test-ps-js literal-symbols-4
255 (test-ps-js literal-symbols-5
259 (test-ps-js literal-symbols-6
263 (test-ps-js variables-1
267 (test-ps-js variables-2
271 (test-ps-js variables-3
275 (test-ps-js function-calls-and-method-calls-1
279 (test-ps-js function-calls-and-method-calls-2
280 (foobar (blorg 1 2) (blabla 3 4) (array 2 3 4))
281 "foobar(blorg(1, 2), blabla(3, 4), [2, 3, 4]);")
283 (test-ps-js function-calls-and-method-calls-3
284 ((getprop this
'blorg
) 1 2)
287 (test-ps-js function-calls-and-method-calls-4
291 (test-ps-js function-calls-and-method-calls-5
292 ((getprop (aref foobar
1) 'blorg
) nil t
)
293 "foobar[1].blorg(null, true);")
295 (test-ps-js operator-expressions-1
299 (test-ps-js operator-expressions-2
303 (test-ps-js operator-expressions-3
304 (* 1 (+ 2 3 4) 4 (/ 6 7))
305 "1 * (2 + 3 + 4) * 4 * (6 / 7);")
307 (test-ps-js operator-expressions-4
311 (test-ps-js operator-expressions-5
315 (test-ps-js operator-expressions-6
319 (test-ps-js operator-expressions-7
323 (test-ps-js operator-expressions-8
327 (test-ps-js body-forms-1
328 (progn (blorg i
) (blafoo i
))
332 (test-ps-js body-forms-2
333 (+ i
(progn (blorg i
) (blafoo i
)))
334 "i + (blorg(i), blafoo(i));")
336 (test-ps-js function-definition-1
337 (defun a-function (a b
)
339 "function aFunction(a, b) {
343 (test-ps-js lambda-definition-2
344 (lambda (a b
) (+ a b
))
349 (test-ps-js assignment-1
353 (test-ps-js assignment-2
354 (setf a
2 b
3 c
4 x
(+ a b c
))
360 (test-ps-js assignment-3
361 (setf a
(+ a
2 3 4 a
))
362 "a = a + 2 + 3 + 4 + a;")
364 (test-ps-js assignment-4
368 (test-ps-js assignment-5
380 (test-ps-js assignment-6
384 (test-ps-js assignment-8
386 (defun (setf color
) (new-color el
)
387 (setf (getprop (getprop el
'style
) 'color
) new-color
))
388 (setf (color some-div
) (+ 23 "em")))
389 "function __setf_color(newColor, el) {
390 return el.style.color = newColor;
392 __setf_color(23 + 'em', someDiv);")
394 (test-ps-js assignment-10
396 (defsetf left
(el) (offset)
397 `(setf (getprop (getprop ,el
'style
) 'left
) ,offset
))
398 (setf (left some-div
) (+ 123 "px")))
401 var _js1 = 123 + 'px';
402 return _js2.style.left = _js1;
405 (test-ps-js assignment-12
406 (macrolet ((left (el)
407 `(getprop ,el
'offset-left
)))
409 "someDiv.offsetLeft;")
411 (test-ps-js nil-block-return-1
412 (block nil
(return) 1)
418 (test-ps-js single-argument-statements-2
422 (test-ps-js single-argument-expression-1
423 (delete (new (*foobar
2 3 4)))
424 "delete new Foobar(2, 3, 4);")
426 (test-ps-js single-argument-expression-2
427 (if (= (typeof blorg
) *string
)
428 (alert (+ "blorg is a string: " blorg
))
429 (alert "blorg is not a string"))
430 "if (typeof blorg === String) {
431 alert('blorg is a string: ' + blorg);
433 alert('blorg is not a string');
436 (test-ps-js conditional-statements-1
438 (if ((@ blorg is-correct
))
439 (progn (carry-on) (return-from foo i
))
440 (alert "blorg is not correct!")))
442 if (blorg.isCorrect()) {
448 return alert('blorg is not correct!');
452 (test-ps-js conditional-statements-2
453 (+ i
(if ((@ blorg add-one
)) 1 2))
454 "i + (blorg.addOne() ? 1 : 2);")
456 (test-ps-js conditional-statements-3
458 (when ((@ blorg is-correct
))
460 (return-from foo i
)))
462 if (blorg.isCorrect()) {
469 (test-ps-js conditional-statements-4
470 (unless ((@ blorg is-correct
))
471 (alert "blorg is not correct!"))
472 "if (!blorg.isCorrect()) {
473 alert('blorg is not correct!');
476 (test-ps-js variable-declaration-1
477 (defvar *a
* (array 1 2 3))
478 "if ('undefined' === typeof A) { var A = [1, 2, 3]; };")
480 (test-ps-js variable-declaration-2
481 (progn (defvar *a
* 4)
487 "if ('undefined' === typeof A) { var A = 4; };
502 (test-ps-js variable-declaration-3
506 (test-ps-js variable-declaration-4
507 (progn (defparameter *a
* 4)
528 (test-ps-js variable-declaration-5
532 (test-ps-js iteration-constructs-1
533 (do* ((a) b
(c (array "a" "b" "c" "d" "e"))
535 (e (aref c d
) (aref c d
)))
536 ((or (= d
(@ c length
)) (string= e
"x")))
538 (funcall (@ document write
) (+ "a: " a
" b: " b
"<br/>")))
540 for (var a = null, b = null, c = ['a', 'b', 'c', 'd', 'e'], d = 0, e = c[d];
541 !(d === c.length || e === 'x'); d += 1, e = c[d]) {
544 document.write('a: ' + a + ' b: ' + b + '<br/>');
548 (test-ps-js iteration-constructs-2
550 (s 0 (+ s i
(1+ i
))))
552 (funcall (@ document write
) (+ "i: " i
" s: " s
"<br/>")))
557 document.write('i: ' + i + ' s: ' + s + '<br/>');
559 var _js2 = s + i + (i + 1);
565 (test-ps-js iteration-constructs-3
567 (s 0 (+ s i
(1- i
))))
569 ((@ document write
) (+ "i: " i
" s: " s
"<br/>")))
571 for (var i = 0, s = 0; i <= 10; i += 1, s = s + i + (i - 1)) {
572 document.write('i: ' + i + ' s: ' + s + '<br/>');
576 (test-ps-js iteration-constructs-4
577 (let ((arr (array "a" "b" "c" "d" "e")))
578 (dotimes (i (@ arr length
))
579 ((@ document write
) (+ "i: " i
" arr[i]: " (aref arr i
) "<br/>"))))
581 var arr = ['a', 'b', 'c', 'd', 'e'];
582 for (var i = 0; i < arr.length; i += 1) {
583 document.write('i: ' + i + ' arr[i]: ' + arr[i] + '<br/>');
587 (test-ps-js iteration-constructs-5
589 (alert (+ "Summation to 10 is "
591 (incf res
(1+ i
))))))
595 return alert('Summation to 10 is ' + (function () {
596 for (var i = 0; i < 10; i += 1) {
604 (test-ps-js iteration-constructs-6
605 (let ((l (list 1 2 4 8 16 32)))
607 ((@ document write
) (+ "c: " c
"<br/>"))))
609 var l = [1, 2, 4, 8, 16, 32];
610 for (var c = null, _js_idx2 = 0; _js_idx2 < l.length; _js_idx2 += 1) {
612 document.write('c: ' + c + '<br/>');
616 (test-ps-js iteration-constructs-7
617 (let ((l '(1 2 4 8 16 32))
619 (alert (+ "Sum of " l
" is: "
623 var l = [1, 2, 4, 8, 16, 32];
626 return alert('Sum of ' + l + ' is: ' + (function () {
627 for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) {
636 (test-ps-js iteration-constructs-8
637 (let ((obj (create a
1 b
2 c
3)))
639 ((@ document write
) (+ i
": " (aref obj i
) "<br/>"))))
641 var obj = { a : 1, b : 2, c : 3 };
643 document.write(i + ': ' + obj[i] + '<br/>');
647 (test-ps-js iteration-constructs-9
648 (loop while
(funcall (@ film is-not-finished
)) do
649 (funcall (@ this eat
) (new *popcorn
)))
651 while (film.isNotFinished()) {
652 this.eat(new Popcorn);
656 (test-ps-js iteration-constructs-10
657 (loop for i from
1 while
(foo))
659 for (var i = 1; foo(); i += 1) {
663 (test-ps-js iteration-constructs-11
666 for (var i = 1; true; i += 1) {
670 (test-ps-js loop-for-bindings
671 (loop :for
((a b
) (:c
:d
)) :in arr
:do
(foo a b c d
))
673 var _js2 = arr.length;
674 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
675 var _db4 = arr[_js1];
686 (test-ps-js loop-for-on
687 (loop :for
(k v
) :on plist
:by
2 :do
(foo k v
))
689 for (var _js1 = plist; _js1.length > 0; _js1 = _js1['slice'](2)) {
696 (test-ps-js loop-for-keys-of
697 (loop :for k
:of obj
:do
(foo k
))
704 (test-ps-js loop-for-key-val-pairs-of
705 (loop :for
(k v
) :of obj
:do
(foo k v
))
713 (test-ps-js loop-for-key-val-pairs-of-with-bindings
714 (loop :for
(k (a b
)) :of obj
:do
(foo k a b
))
724 (test-ps-js loop-for-just-vals-of
725 (loop :for
(nil v
) :of obj
:do
(foo k v
))
727 for (var _js1 in obj) {
733 (test-ps-js loop-map-to
734 (loop :for str
:in strs
:map str
:to
(length str
))
736 var _js2 = strs.length;
738 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
739 var str = strs[_js1];
740 map3[str] = str.length;
745 (test-ps-js loop-for-of-map-to
746 (loop :for k
:of obj
:map k
:to
(foo k
))
756 (test-ps-js loop-for-of-when
757 (loop :for k
:of obj
:when
(foo k
) :map k
:to
(bar k
))
769 (test-ps-js loop-for-in-until-when
770 (loop :for a
:in b
:until
(> a
100) :when
(< a
50) :do
(foo a
))
773 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
784 (test-ps-js loop-with-for-when
785 (loop :with c
= c1
:for d
:from c1
:below c2
786 :when
(foo c d
) :do
(setf c d
)
790 for (var d = c1; d < c2; d += 1) {
798 (test-ps-js loop-for-then-for-in-while
800 (loop :for a
= (foo) :then
(bar) :for b
:in c
:while b
:do
(foo a b c
)))
804 for (var a = foo(); true; a = bar()) {
805 var _js1 = FIRST3 ? 0 : _js1 + 1;
818 (test-ps-js loop-while-when
819 (loop :for a
= (pop stack
) :while a
:for
(b c
) = (foo a
) :when b
:do
(bar c
))
821 for (var a = pop(stack); a; a = pop(stack)) {
831 (test-ps-js loop-for-of-for-in
833 (loop :for k
:of obj
:for a
:in b
:do
(foo k a
)))
834 "function blah(obj, b) {
838 var _js1 = FIRST3 ? 0 : _js1 + 1;
848 (test-ps-js loop-for-dot
849 (loop :for
(op . args
) :in expr
:do
(foo op args
))
851 var _js2 = expr.length;
852 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
853 var _db3 = expr[_js1];
855 var args = _db3.length > 1 ? _db3.slice(1) : [];
860 (test-ps-js loop-for-rest
861 (loop :for
(op &rest args
) :in expr
:do
(foo op args
))
863 var _js2 = expr.length;
864 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
865 var _db3 = expr[_js1];
867 var args = _db3.length > 1 ? _db3.slice(1) : [];
872 (test-ps-js loop-collect
873 (setf x
(loop :for a
:in b
:collect
(foo a
)))
877 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
879 collect3.push(foo(a));
885 (test-ps-js loop-collect-twice
886 (loop collect x collect
(1+ x
))
891 collect1.push(x + 1);
897 (test-ps-js loop-append
898 (loop :for a
:in b
:append a
)
902 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
904 append3 = append3.concat(a);
910 (test-ps-js the-case-statement-1
912 ((1 "one") (alert "one"))
914 (t (alert "default clause")))
924 alert('default clause');
927 (test-ps-js the-case-statement-2
928 (switch (aref blorg i
)
929 (1 (alert "If I get here"))
930 (2 (alert "I also get here"))
931 (default (alert "I always get here")))
933 case 1: alert('If I get here');
934 case 2: alert('I also get here');
935 default: alert('I always get here');
938 (test-ps-js the-try-statement-1
941 (alert (+ "an error happened: " error
)))
943 (alert "Leaving the try form")))
947 alert('an error happened: ' + error);
949 alert('Leaving the try form');
952 (test-ps-js the-html-generator-1
953 (ps-html ((:a
:href
"foobar") "blorg"))
954 "'<a href=\\\"foobar\\\">blorg</a>';")
956 (test-ps-js the-html-generator-2
957 (ps-html ((:a
:href
(generate-a-link)) "blorg"))
958 "['<a href=\\\"', generateALink(), '\\\">blorg</a>'].join('');")
960 (test-ps-js the-html-generator-3
961 (funcall (getprop document
'write
)
962 (ps-html ((:a
:href
"#"
963 :onclick
(ps-inline (transport))) "link")))
964 "document.write(['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">link</a>'].join(''));")
966 (test-ps-js the-html-generator-4
969 (setf (getprop element
'inner-h-t-m-l
)
970 (ps-html ((:textarea
(or disabled
(not authorized
)) :disabled
"disabled")
974 var authorized = true;
975 return element.innerHTML = ['<textarea', disabled || !authorized ? [' disabled=\\\"', 'disabled', '\\\"'].join('') : '', '>Edit me</textarea>'].join('');
978 (test-ps-js plus-is-not-commutative
979 (setf x
(+ "before" x
"after"))
980 "x = 'before' + x + 'after';")
982 (test-ps-js plus-works-if-first
983 (setf x
(+ x
"middle" "after"))
984 "x = x + 'middle' + 'after';")
986 (test-ps-js method-call-op-form
987 (funcall (getprop (+ "" x
) 'to-string
))
988 "('' + x).toString();")
990 (test-ps-js method-call-op-form-args
991 (funcall (getprop (+ "" x
) 'foo
) 1 2 :baz
3)
992 "('' + x).foo(1, 2, 'baz', 3);")
994 (test-ps-js method-call-string
995 ((getprop "hi" 'to-string
))
998 (test-ps-js method-call-conditional
1002 (test-ps-js method-call-variable
1006 (test-ps-js method-call-array
1007 ((@ (list 10 20) to-string
))
1008 "[10, 20].toString();")
1010 (test-ps-js method-call-lambda-call
1011 (funcall (getprop (funcall (lambda (x) x
) 10) 'to-string
))
1012 "(function (x) { return x; })(10).toString();")
1014 (fiveam:test no-whitespace-before-dot
1015 (let ((str (ps* '((@ ((lambda (x) x
) 10) to-string
)))))
1016 (fiveam:is
(char= #\
) (elt str
(1- (position #\. str
)))))))
1018 (test-ps-js simple-getprop
1019 (let ((foo (create a
1)))
1020 (alert (getprop foo
'a
)))
1022 var foo = { a : 1 };
1024 return alert(foo.a);
1027 (test-ps-js buggy-getprop
1028 (getprop foo slot-name
)
1031 (test-ps-js buggy-getprop-two
1032 (getprop foo
(get-slot-name))
1033 "foo[getSlotName()];")
1035 (test-ps-js old-case-is-now-switch
1036 ;; Switch was "case" before, but that was very non-lispish.
1037 ;; For example, this code makes three messages and not one
1038 ;; which may have been expected. This is because a switch
1039 ;; statment must have a break statement for it to return
1040 ;; after the alert. Otherwise it continues on the next
1042 (switch (aref blorg i
)
1045 (default (alert "default clause")))
1046 "switch (blorg[i]) {
1047 case 1: alert('one');
1048 case 2: alert('two');
1049 default: alert('default clause');
1052 (test-ps-js lisp-like-case
1053 (case (aref blorg i
)
1056 (t (alert "default clause")))
1057 "switch (blorg[i]) {
1064 default: alert('default clause');
1068 (test-ps-js even-lispier-case
1069 (case (aref blorg i
)
1070 ((1 2) (alert "Below three"))
1072 (t (alert "Something else")))
1073 "switch (blorg[i]) {
1076 alert('Below three');
1081 default: alert('Something else');
1084 (test-ps-js otherwise-case
1085 (case (aref blorg i
)
1087 (otherwise (alert "default clause")))
1088 "switch (blorg[i]) {
1092 default: alert('default clause');
1095 (fiveam:test escape-sequences-in-string
1099 (#\f .
,(code-char 12))
1100 ("u000B" .
,(code-char #xB
)) ; vertical tab
1106 ("u001F" .
,(code-char #x1F
)) ; character below 32
1107 ("u0080" .
,(code-char 128)) ; character over 127
1108 ("u00A0" .
,(code-char 160)) ; non-breaking space
1109 ("u00AD" .
,(code-char 173)) ; soft hyphen
1110 ("u200B" .
,(code-char #x200B
)) ; zero-width space
1111 ("u200C" .
,(code-char #x200C
)) ; zero-width non-joiner
1113 (loop for
(js-escape . lisp-char
) in escapes
1114 for generated
= (ps-doc* (format nil
"hello~ahi" lisp-char
))
1115 for wanted
= (format nil
"'hello\\~ahi';" js-escape
)
1116 do
(fiveam:is
(string= generated wanted
)))))
1118 (fiveam:test escape-doublequotes
1119 (let ((*js-string-delimiter
* #\"))
1120 (fiveam:is
(string= (ps-doc* "hello\"hi") "\"hello\\\"\hi\";"))))
1122 (test-ps-js getprop-setf
1123 (setf (getprop x
'y
) (+ (+ a
3) 4))
1124 "x.y = (a + 3) + 4;")
1126 (test-ps-js getprop-conditional1
1127 (getprop (if zoo foo bar
) 'x
)
1128 "(zoo ? foo : bar).x;")
1130 (test-ps-js getprop-conditional2
1131 (getprop (if (not zoo
) foo bar
) 'x
)
1132 "(!zoo ? foo : bar).x;")
1134 (fiveam:test script-star-eval1
1136 (normalize-js-output (ps* '(setf x
1) '(setf y
2)))
1139 (fiveam:test script-star-eval2
1141 (normalize-js-output (ps* '(setf x
1)))
1144 (test-ps-js list-with-single-nil
1148 (test-ps-js quoted-nil-is-array
1152 (test-ps-js quoted-nil-is-array1
1156 (test-ps-js literal-nil
1160 (test-ps-js quoted-quoted-nil
1164 (test-ps-js quoted-quoted-nil1
1168 (test-ps-js defsetf1
1169 (progn (defsetf baz
(x y
) (newval) `(set-baz ,x
,y
,newval
))
1176 return setBaz(_js2, _js3, _js1);
1179 (test-ps-js setf-macroexpands1
1180 (macrolet ((bar (x y
)
1182 (setf (bar foo
2) 3))
1185 (test-ps-js defsetf-short
1186 (progn (defsetf baz set-baz
"docstring")
1187 (setf (baz 1 2 3) "foo"))
1188 "setBaz(1, 2, 3, 'foo');")
1190 (test-ps-js defun-setf1
1191 (progn (defun (setf some-thing
) (new-val i1 i2
)
1192 (setf (aref *some-thing
* i1 i2
) new-val
))
1193 (setf (some-thing 1 2) "foo"))
1194 "function __setf_someThing(newVal, i1, i2) {
1195 return SOMETHING[i1][i2] = newVal;
1197 __setf_someThing('foo', 1, 2);")
1199 (test-ps-js defun-optional1
1200 (defun test-opt (&optional x
)
1202 "function testOpt(x) {
1203 return x ? 'yes' : 'no';
1206 (test-ps-js defun-optional2
1207 (defun foo (x &optional y
)
1209 "function foo(x, y) {
1213 (test-ps-js defun-optional3
1214 (defun blah (&optional
(x 0))
1217 if (x === undefined) {
1223 (test-ps-js arglist-optional4
1224 (lambda (&optional
(x 0 supplied?
))
1227 var suppliedwhat = x !== undefined;
1228 if (!suppliedwhat) {
1234 (test-ps-js return-nothing
1235 (defun foo () (return-from foo
))
1240 (test-ps-js return-values
1242 (return-from foo
(values 1 2 3)))
1245 __PS_MV_REG = [2, 3];
1249 (test-ps-js set-timeout
1250 (set-timeout (lambda () (alert "foo")) 10)
1251 "setTimeout(function () { __PS_MV_REG = []; return alert('foo'); }, 10);")
1253 (test-ps-js operator-precedence
1257 (test-ps-js operators-1
1277 (test-ps-js setf-conditional
1278 (setf foo
(if x
1 2))
1281 (test-ps-js obj-literal-numbers
1285 (test-ps-js obj-literal-strings
1289 (test-ps-js getprop-string
1293 (test-ps-js getprop-string1
1294 (getprop "bar" 'length
)
1297 (test-ps-js getprop-progn
1298 (getprop (progn (some-fun "abc") "123") "length")
1299 "(someFun('abc'), '123')['length'];")
1301 (test-ps-js getprop-multi1
1302 (getprop foo
1 "two" three
'bar
1 2)
1303 "foo[1]['two'][three].bar[1][2];")
1305 (test-ps-js method-call-block
1306 ((@ (progn (some-fun "abc") "123") to-string
))
1307 "(someFun('abc'), '123').toString();")
1309 (test-ps-js create-blank
1313 (test-ps-js blank-object-literal
1317 (test-ps-js array-literal1
1321 (test-ps-js array-literal2
1325 (test-ps-js array-literal3
1329 (test-ps-js array-literal4
1333 (test-ps-js array-literal5
1334 ([] (1 2) ("a" "b"))
1335 "[[1, 2], ['a', 'b']];")
1337 (test-ps-js defun-rest1
1338 (defun foo (&rest bar
)
1339 (alert (aref bar
1)))
1341 var bar = Array.prototype.slice.call(arguments, 0);
1343 return alert(bar[1]);
1346 (test-ps-js defun-rest2
1347 (defun foo (baz &rest bar
) (+ baz
(aref bar
1)))
1348 "function foo(baz) {
1349 var bar = Array.prototype.slice.call(arguments, 1);
1351 return baz + bar[1];
1354 (test-ps-js defun-keyword1
1355 (defun zoo (foo bar
&key baz
) (+ foo bar baz
))
1356 "function zoo(foo, bar) {
1357 var _js2 = arguments.length;
1358 for (var n1 = 2; n1 < _js2; n1 += 2) {
1359 switch (arguments[n1]) {
1361 baz = arguments[n1 + 1];
1365 return foo + bar + baz;
1368 (test-ps-js defun-keyword2
1369 (defun zoo (&key baz
) (* baz baz
))
1371 var _js2 = arguments.length;
1372 for (var n1 = 0; n1 < _js2; n1 += 2) {
1373 switch (arguments[n1]) {
1375 baz = arguments[n1 + 1];
1382 (test-ps-js defun-keyword3
1383 (defun zoo (&key baz
(bar 4)) (* baz bar
))
1385 var _js2 = arguments.length;
1386 for (var n1 = 0; n1 < _js2; n1 += 2) {
1387 switch (arguments[n1]) {
1389 baz = arguments[n1 + 1];
1392 bar = arguments[n1 + 1];
1396 var bar = 'undefined' === typeof bar ? 4 : bar;
1400 (test-ps-js defun-keyword4
1401 (defun hello-world (&key
((:my-name-key my-name
) 1))
1403 "function helloWorld() {
1404 var _js2 = arguments.length;
1405 for (var n1 = 0; n1 < _js2; n1 += 2) {
1406 switch (arguments[n1]) {
1408 myName = arguments[n1 + 1];
1411 var myName = 'undefined' === typeof myName ? 1 : myName;
1415 (test-ps-js arglist-keyword-supplied
1416 (lambda (&key
(foo 1 supplied?
))
1419 var _js2 = arguments.length;
1420 for (var n1 = 0; n1 < _js2; n1 += 2) {
1421 switch (arguments[n1]) {
1423 foo = arguments[n1 + 1];
1424 suppliedwhat = true;
1428 var foo = 'undefined' === typeof foo ? 1 : foo;
1432 (test-ps-js keyword-funcall1
1436 (test-ps-js keyword-funcall2
1437 (func :baz
1 :bar foo
)
1438 "func('baz', 1, 'bar', foo);")
1440 (test-ps-js keyword-funcall3
1442 "fun(a, b, 'baz', c);")
1452 ((= y
(* x
4)) (foo "blah") (* x y
)))
1455 } else if (y === x * 4) {
1460 (test-ps-js if-exp-without-else-return
1461 (defun foo () (return-from foo
(if x
1)))
1463 return x ? 1 : null;
1466 (test-ps-js progn-expression-single-statement
1467 (defun foo () (return-from foo
(progn (* x y
))))
1472 (test-ps-js cond-expression1
1474 (cond ((< 1 2) (bar "foo") (* 4 5))))
1483 (test-ps-js cond-expression2
1485 (cond ((< 2 1) "foo")
1490 } else if (7 === 7) {
1495 (test-ps-js cond-expression-final-t-clause
1497 (cond ((< 1 2) (bar "foo") (* 4 5))
1509 } else if (a === b) {
1512 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1521 (test-ps-js cond-expression-middle-t-clause
;; should this signal a warning?
1534 (test-ps-js funcall-if-expression
1535 (funcall (getprop document
'write
)
1536 (if (= *linkornot
* 1)
1537 (ps-html ((:a
:href
"#"
1538 :onclick
(ps-inline (transport)))
1541 "document.write(LINKORNOT === 1 ? ['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">', img, '</a>'].join('') : img);")
1543 (test-ps-js negate-number-literal
1547 (fiveam:test macro-environment1
1550 (normalize-js-output
1551 (let* ((macroname (gensym)))
1552 (ps* `(defmacro ,macroname
(x) `(+ ,x
123))
1554 (macrolet ((,macroname
(x) `(aref data
,x
)))
1555 (when (,macroname x
)
1556 (setf (,macroname x
) 123)))))))
1557 (normalize-js-output
1559 return data[x] ? (data[x] = 123) : null;
1562 (fiveam:test macro-environment2
1565 (let ((outer-lexical-variable 1))
1566 (defpsmacro macro-environment2-macro
(x)
1567 `(+ ,outer-lexical-variable
,x
))
1568 (ps* '(macro-environment2-macro 2)))
1571 (test-ps-js ampersand-whole-1
1572 (macrolet ((foo (&whole foo bar baz
)
1573 (declare (ignore bar baz
))
1574 (with-standard-io-syntax
1575 (let ((*print-case
* :downcase
))
1576 (format nil
"~a" foo
)))))
1580 (test-ps-js ampersand-whole-2
1581 (macrolet ((foo (&whole foo bar baz
)
1586 (test-ps-js keyword-consistent
1590 (test-ps-js simple-symbol-macrolet
1591 (symbol-macrolet ((x 1)) x
)
1594 (test-ps-js compound-symbol-macrolet
1595 (symbol-macrolet ((x 123)
1600 (test-ps-js define-symbol-macro
1601 (progn (define-symbol-macro tst-sym-macro
2)
1605 (test-ps-js define-symbol-macro1
1606 (progn (define-symbol-macro tst-sym-macro1
2)
1607 (foo tst-sym-macro1
))
1610 (test-ps-js define-symbol-macro2
1611 (progn (define-symbol-macro tst-sym-macro2
3)
1612 (list tst-sym-macro2
))
1615 (test-ps-js define-symbol-macro3
1616 (progn (define-symbol-macro tst-sym-macro3
4)
1617 (setq foo
(create tst-sym-macro3 tst-sym-macro3
)))
1618 "foo = { tstSymMacro3 : 4 };")
1620 (test-ps-js define-symbol-macro4
1621 (progn (define-symbol-macro tst-sym-macro4
5)
1622 (setq foo
(if (baz) tst-sym-macro4 bar
)))
1623 "foo = baz() ? 5 : bar;")
1625 (test-ps-js expression-progn
1626 (1+ (progn (foo) (if x
1 2)))
1627 "(foo(), x ? 1 : 2) + 1;")
1629 (test-ps-js let-decl-in-expression
1631 (if x
1 (let* ((foo x
)) foo
)))
1641 (test-ps-js special-var1
1642 (progn (defvar *foo
*)
1649 FOO_TMPSTACK1 = FOO;
1653 FOO = FOO_TMPSTACK1;
1657 (test-ps-js special-var2
1658 (progn (defparameter *foo
*)
1667 FOO_TMPSTACK1 = FOO;
1669 return FOO * 2 * BAZ;
1671 FOO = FOO_TMPSTACK1;
1675 (test-ps-js literal1
1679 (test-ps-js literal2
1683 (test-ps-js setf-dec1
1687 (test-ps-js setf-dec2
1691 (test-ps-js special-char-equals
1695 (test-ps-js setf-operator-priority
1697 (or (getprop cache id
)
1698 (setf (getprop cache id
) ((@ document get-element-by-id
) id
))))
1701 return cache[id] || (cache[id] = document.getElementById(id));
1704 (test-ps-js aref-operator-priority
1705 (aref (if (and x
(> (length x
) 0))
1709 "(x && x.length > 0 ? x[0] : y)[z];")
1711 (test-ps-js aref-operator-priority1
1712 (aref (or (getprop x
'y
)
1717 (test-ps-js aref-operator-priority2
1721 (test-ps-js negate-operator-priority
1730 (delete (if a
(or b c
) d
))
1731 "delete (a ? b || c : d);")
1734 (not (if (or x
(not y
)) z
))
1735 "!(x || !y ? z : null);")
1742 (instanceof (or a b
) (if x y z
))
1743 "((a || b) instanceof (x ? y : z));")
1746 (or x
(if (= x
0) "zero" "empty"))
1747 "x || (x === 0 ? 'zero' : 'empty');")
1749 (test-ps-js named-op-expression
1753 (test-ps-js named-op-expression1
1757 (test-ps-js aref-array-expression
1759 "(a || b || c)[0];")
1761 (test-ps-js getprop-operator
1762 (getprop (or a b c
) 'd
)
1765 (test-ps-js getprop-parens
1766 (getprop (getprop foo
'bar
) 'baz
)
1769 (test-ps-js funcall-funcall
1773 (test-ps-js expression-funcall
1774 ((or (@ window eval
) eval
) foo nil
)
1775 "(window.eval || eval)(foo, null);")
1777 (test-ps-js expression-funcall1
1778 (((or (@ window eval
) eval
) foo nil
))
1779 "(window.eval || eval)(foo, null)();")
1781 (test-ps-js expression-funcall2
1782 (((or (@ window eval
) eval
)) foo nil
)
1783 "(window.eval || eval)()(foo, null);")
1785 (test-ps-js who-html1
1786 (who-ps-html (:span
:class
"ticker-symbol"
1787 :ticker-symbol symbol
1788 (:a
:href
"http://foo.com"
1790 (:span
:class
"ticker-symbol-popup")))
1791 "['<span class=\\\"ticker-symbol\\\" ticker-symbol=\\\"', symbol, '\\\"><a href=\\\"http://foo.com\\\">', symbol, '</a><span class=\\\"ticker-symbol-popup\\\"></span></span>'].join('');")
1793 (test-ps-js who-html2
1794 (who-ps-html (:p
"t0" (:span
"t1")))
1795 "'<p>t0<span>t1</span></p>';")
1798 ((lambda () (flet ((foo (x)
1802 var foo = function (x) {
1810 (flet ((foo (x) (1+ x
))
1814 var foo = function (x) {
1817 var bar = function (y) {
1825 (flet ((foo (x) (+ 2 x
)))
1826 (flet ((foo (x) (1+ x
))
1827 (bar (y) (+ 2 (foo y
))))
1830 var foo = function (x) {
1833 var foo1 = function (x) {
1836 var bar = function (y) {
1841 return bar(foo1(1));
1845 ((lambda () (labels ((foo (x)
1848 (+ x
(foo (1- x
))))))
1851 var foo = function (x) {
1853 return 0 === x ? 0 : x + foo(x - 1);
1860 (labels ((foo (x) (1+ (bar x
)))
1861 (bar (y) (+ 2 (foo y
))))
1864 var foo = function (x) {
1868 var bar = function (y) {
1877 (labels ((foo (x) (1+ x
))
1878 (bar (y) (+ 2 (foo y
))))
1881 var foo = function (x) {
1884 var bar = function (y) {
1892 (test-ps-js labels-lambda-list
1893 (labels ((foo (x &optional
(y 0))
1897 var foo = function (x, y) {
1898 if (y === undefined) {
1907 (test-ps-js for-loop-var-init-exp
1909 (do* ((y (if x
0 1) (1+ y
))
1914 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1923 (test-ps-js literal-array
1927 (test-ps-js literal-array-1
1931 (test-ps-js literal-array-literal
1935 (test-ps-js literal-array-literal1
1939 (fiveam:test ps-lisp-expands-in-lexical-environment
1940 (fiveam:is
(string= (let ((x 5)) (ps (lisp x
)))
1943 (fiveam:test ps-lisp-expands-in-lexical-environment1
1944 (fiveam:is
(string= (let ((x 5)) (ps (+ 1 (lisp x
))))
1947 (fiveam:test ps-lisp-expands-in-lexical-environment2
1948 (fiveam:is
(string= (let ((x 2)) (ps (+ 1 (lisp x
) 3)))
1951 (fiveam:test ps
*-lisp-expands-in-null-lexical-environment
1952 (fiveam:signals unbound-variable
1954 (declare (ignore x
))
1957 (fiveam:test ps
*-lisp-expands-in-dynamic-environment
1960 (declare (special foo
))
1961 (ps* '(+ 1 (lisp (locally (declare (special foo
))
1965 (fiveam:test ps-lisp-dynamic-environment
1968 (declare (special foo
))
1969 (ps (+ 1 (lisp foo
))))
1972 (test-ps-js nested-if-expressions1
1974 (return-from foo
(if (if x y z
) a b
)))
1983 (test-ps-js nested-if-expressions2
1985 (if x y
(if z a b
)))
1994 (test-ps-js nested-if-expressions3
1995 (foo (if (if x y z
) a b
)
1996 (if x y
(if z a b
)))
1997 "foo((x ? y : z) ? a : b, x ? y : (z ? a : b));")
2069 (test-ps-js let-exp1
2120 (test-ps-js symbol-macrolet-var
2121 (symbol-macrolet ((x y
))
2125 (test-ps-js setf-conditional1
2126 (setf x
(unless (null a
) (1+ a
)))
2127 "x = a != null ? a + 1 : null;")
2129 (test-ps-js setf-let1
2130 (setf x
(let ((a 1)) a
))
2136 (test-ps-js setf-let2
2137 (setf x
(let ((a (foo)))
2143 return a != null ? a + 1 : null;
2146 (test-ps-js symbol-macro-env1
2147 (symbol-macrolet ((bar 1))
2148 (macrolet ((bar (x y
) `(+ ,x
,y
)))
2152 (test-ps-js symbol-macrolet-fun1
2153 (symbol-macrolet ((baz +))
2157 (test-ps-js lisp2-namespaces1
2159 (setf list
(list 1 2 3)))
2162 return list = [1, 2, 3];
2165 (test-ps-js let-shadows-symbol-macrolet
2166 (symbol-macrolet ((x y
))
2176 (test-ps-js let-rename-optimization1
2184 (test-ps-js let-rename-optimization2
2193 (test-ps-js symbol-macro-array
2194 (symbol-macrolet ((x 1))
2198 (test-ps-js symbol-macro-obj
2199 (symbol-macrolet ((x (+ 1 2)))
2203 (test-ps-js symbol-macro-obj1
2204 (symbol-macrolet ((x (+ 1 2)))
2208 (test-ps-js symbol-macro-getprop1
2209 (symbol-macrolet ((x (+ 1 2)))
2213 (test-ps-js symbol-macro-getprop1
2214 (symbol-macrolet ((x (+ 1 2)))
2218 (test-ps-js let-let-create
2228 (test-ps-js symbol-macro-conditional1
2229 (symbol-macrolet ((x y
))
2237 (test-ps-js symbol-macro-conditional2
2238 (symbol-macrolet ((x y
))
2242 (test-ps-js preserve-this
2244 (let ((y (block nil
(bar this
))))
2247 var y = (function () {
2255 (test-ps-js flet-apply
2256 (flet ((foo () 'bar
))
2257 (apply (function foo
) nil
))
2259 var foo = function () {
2262 return foo.apply(this, null);
2265 (test-ps-js let-apply
2266 (let ((foo (lambda () 1)))
2267 (let ((foo (lambda () 2)))
2270 var foo = function () {
2273 var foo1 = function () {
2276 return foo1.apply(this, null);
2279 (test-ps-js flet-let
2280 (flet ((x (x) (1+ x
)))
2284 var x = function (x) {
2292 (test-ps-js let-flet
2294 (flet ((x (x) (1+ x
)))
2298 var x1 = function (x) {
2305 (test-ps-js labels-let
2306 (labels ((x (x) (1+ x
)))
2310 var x = function (x) {
2318 (test-ps-js let-labels
2320 (labels ((x (x) (1+ x
)))
2324 var x1 = function (x) {
2331 (test-ps-js macrolet-let-inteference
2332 (macrolet ((a (n) `(+ ,n
5)))
2334 (let ((b (a (- a
4))))
2338 var b = (a - 4) + 5;
2342 (test-ps-js let-subtract-add
2358 (test-ps-js create-reserved-word
2360 "{ 'default' : 1 };")
2362 (test-ps-js getprop-reserved-word
2363 (getprop foo
:default
)
2366 (test-ps-js getprop-reserved-word1
2367 (getprop foo
'default
)
2370 (test-ps-js eval-when-ps-side
2371 (eval-when (:execute
)
2375 (defvar *lisp-output
* nil
)
2377 (fiveam:test eval-when-lisp-side
()
2378 (setf *lisp-output
* 'original-value
)
2380 (normalize-js-output
2381 (ps-doc* `(eval-when (:compile-toplevel
)
2382 (setf *lisp-output
* 'it-works
))))))
2383 (fiveam:is
(eql 'it-works
*lisp-output
*))
2384 (fiveam:is
(string= "" js-output
))))
2386 (defpsmacro my-in-package
(package-name)
2387 `(eval-when (:compile-toplevel
)
2388 (setf *lisp-output
* ,package-name
)))
2390 (fiveam:test eval-when-macro-expansion
()
2391 (setf *lisp-output
* 'original-value
)
2393 (normalize-js-output
2395 (my-in-package :cl-user
)
2397 (declare (ignore js-output
))
2398 (fiveam:is
(eql :cl-user
*lisp-output
*))))
2400 (fiveam:test eval-when-macrolet-expansion
()
2401 (setf *lisp-output
* 'original-value
)
2403 (normalize-js-output
2405 `(macrolet ((my-in-package2 (package-name)
2406 `(eval-when (:compile-toplevel
)
2407 (setf *lisp-output
* ,package-name
))))
2408 (my-in-package2 :cl-user
)
2410 (declare (ignore js-output
))
2411 (fiveam:is
(eql :cl-user
*lisp-output
*))))
2413 (test-ps-js getprop-keyword
2417 (test-ps-js nary-comparison1
2418 (lambda () (< 1 2 3))
2421 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
2424 (test-ps-js chain-getprop1
2425 (chain ($
"foo") (bar x z
) frob
(baz 5))
2426 "$('foo').bar(x, z).frob.baz(5);")
2428 (test-ps-js chain-getprop2
2429 (chain ($
"foo") bar baz
)
2430 "$('foo').bar.baz;")
2432 (test-ps-js chain-getprop3
2433 (chain ($
"foo") bar
(x y
) baz
)
2434 "$('foo').bar.x(y).baz;")
2436 (test-ps-js flet-expression
2437 (1+ (flet ((foo (x) (1+ x
)))
2440 var foo = function (x) {
2447 (test-ps-js flet-lambda-list
2448 (flet ((foo (x &key
(y 0))
2452 var foo = function (x) {
2453 var _js2 = arguments.length;
2454 for (var n1 = 1; n1 < _js2; n1 += 2) {
2455 switch (arguments[n1]) {
2457 y = arguments[n1 + 1];
2460 var y = 'undefined' === typeof y ? 0 : y;
2464 return foo(1, 'y', 2);
2467 (test-ps-js return-case-break-elimination
2481 (test-ps-js aplusplus
2485 (test-ps-js astarstar
2489 (test-ps-js switch-return-fallthrough
2508 (test-ps-js return-last-case
2522 (test-ps-js return-macrolet
2524 (macrolet ((x () 1))
2537 (test-ps-js mv-bind1
2538 (multiple-value-bind (a b
)
2548 var b = __PS_MV_REG[0];
2554 (test-ps-js mv-bind2
2555 (multiple-value-bind (a b
)
2566 var b = __PS_MV_REG[0];
2572 (test-ps-js multiple-value-bind-simple
2573 (multiple-value-bind (a b
) (blah)
2578 var b = __PS_MV_REG[0];
2584 (lambda () (values))
2590 (lambda () (values x
))
2596 (lambda () (values x y
))
2604 (lambda () (values x y z
))
2607 __PS_MV_REG = [y, z];
2611 (test-ps-js values-return
2613 (return-from foo
(values (* x x
) y
)))
2614 "function foo(x, y) {
2620 (test-ps-js return-macrolet1
2622 (symbol-macrolet ((x 2))
2630 (test-ps-js return-cond
2633 (cond ((foo? x
) (loop for y in x do
(foo y
)))
2638 var _js2 = x.length;
2639 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2643 } else if (barwhat(x)) {
2652 (test-ps-js return-case
2656 (1 (loop for y in x do
(foo y
)))
2662 var _js2 = x.length;
2663 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2678 (test-ps-js return-case1
2696 (test-ps-js lambda-loop-if-return
2699 (loop for y in x do
(foo y
))
2703 var _js4 = x.length;
2704 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2714 (test-ps-js lambda-loop-if-return1
2718 (progn (loop for y in x do
(foo y
))
2724 return foo(function () {
2726 var _js4 = x.length;
2727 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2732 throw { '__ps_block_tag' : 'baz',
2733 '__ps_value' : null };
2739 } catch (_ps_err5) {
2740 if (_ps_err5 && 'baz' === _ps_err5['__ps_block_tag']) {
2741 return _ps_err5['__ps_value'];
2748 (test-ps-js switch-loop
2751 (1 (dolist (a b
)))))
2755 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2762 (test-ps-js switch-folds-blocks
2765 (1 (loop repeat
3 do
(alert "foo")))
2770 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2781 (test-ps-js setf-places-before-macros
2783 (defsetf left
(el) (offset)
2784 `(setf (@ ,el style left
) ,offset
))
2785 (macrolet ((left (el)
2786 `(@ ,el offset-left
)))
2792 _js2.style.left = _js1;
2793 return x.offsetLeft;
2796 (test-ps-js for-return
2797 (lambda () (dolist (arg args
) (foo arg
)))
2799 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2800 arg = args[_js_idx1];
2805 (test-ps-js try-catch-return
2825 (let ((x (ps:try
(+ 1 2)
2829 var x = (function () {
2840 (test-ps-js try-finally-return-from
2843 (ps:try
(when (blah) 4)
2849 return blah() ? 4 : null;
2854 return dontCallMe();
2857 (test-ps-js defun-setf-optional
2858 (defun (setf foo
) (new-value b
&optional c
)
2859 (setf (aref b
(or c
0)) new-value
))
2860 "function __setf_foo(newValue, b, c) {
2861 return b[c || 0] = newValue;
2864 (test-ps-js defun-setf-rest
2865 (progn (defun (setf foo
) (new-value b
&rest foo
)
2866 (do-something b foo new-value
))
2867 (setf (foo x
1 2 3 4) 5))
2868 "function __setf_foo(newValue, b) {
2869 var foo = Array.prototype.slice.call(arguments, 2);
2871 return doSomething(b, foo, newValue);
2873 __setf_foo(5, x, 1, 2, 3, 4);")
2875 (test-ps-js return-null
2876 (defun foo () (return-from foo nil
))
2881 (test-ps-js implicit-return-null
2888 (test-ps-js implicit-return-null
2895 (test-ps-js return-conditional-nested
2896 (defun blep (ss x y
)
2900 (destructuring-bind (a b
) pair
2901 (unless (or (null a
) (null b
))
2902 (let ((val (baz a b
)))
2907 "function blep(ss, x, y) {
2913 if (!(a == null || b == null)) {
2914 var val = baz(a, b);
2918 return !blee() ? true : null;
2926 (test-ps-js return-when-returns-broken-return
2928 (return-from foo
(when x
1))
2931 return x ? 1 : null;
2935 (test-ps-js return-case-conditional
2939 (123 (when (bar) t
))
2945 return bar() ? true : null;
2952 (test-ps-js return-try-conditional
2960 return x ? 1 : null;
2968 (test-ps-js function-declare-special
2970 (declare (special *foo
*))
2976 FOO_TMPSTACK1 = FOO;
2980 FOO = FOO_TMPSTACK1;
2984 (test-ps-js declare-special-let
2986 (declare (special *foo
*))
2991 FOO_TMPSTACK1 = FOO;
2996 FOO = FOO_TMPSTACK1;
3000 (test-ps-js declare-special-let-scope
3003 (declare (special *foo
*))
3010 FOO_TMPSTACK1 = FOO;
3014 FOO = FOO_TMPSTACK1;
3021 (test-ps-js declare-special-let
*
3022 (let* ((*foo
* 123) (*bar
* (+ *foo
* *bar
*)))
3023 (declare (special *foo
* *bar
*))
3028 FOO_TMPSTACK1 = FOO;
3032 BAR_TMPSTACK2 = BAR;
3037 BAR = BAR_TMPSTACK2;
3040 FOO = FOO_TMPSTACK1;
3044 (test-ps-js defun-multiple-declarations-around-docstring
3046 (declare (ignorable x y
))
3047 (declare (integer x
) (float y
))
3048 "Fooes X while barring Y."
3049 (declare (special *foo
*) (special *bar
*))
3050 (let ((*bar
* (bar y
)))
3052 "/** Fooes X while barring Y. */
3053 function foo(x, y) {
3056 BAR_TMPSTACK1 = BAR;
3061 BAR = BAR_TMPSTACK1;
3065 (test-ps-js macro-null-toplevel
3067 (defmacro macro-null-toplevel
()
3069 (macro-null-toplevel))
3072 (test-ps-js define-symbol-macro-let
3074 (define-symbol-macro test-symbol-macro
1)
3075 (let ((test-symbol-macro 2))
3076 (1+ test-symbol-macro
))
3077 (1+ test-symbol-macro
))
3079 var testSymbolMacro1 = 2;
3080 return testSymbolMacro1 + 1;
3084 (test-ps-js define-symbol-macro-flet
3086 (define-symbol-macro test-symbol-macro1
1)
3087 (flet ((test-symbol-macro1 () 2))
3088 (foo test-symbol-macro1
)
3089 (test-symbol-macro1))
3090 (bar test-symbol-macro1
))
3092 var testSymbolMacro1_1 = function () {
3097 return testSymbolMacro1_1();
3101 (fiveam:test compile-stream-nulls
3104 (with-input-from-string (s "
3105 (defmacro macro-null-toplevel ()
3107 (macro-null-toplevel)")
3108 (ps-compile-stream s
))
3111 (fiveam:test compile-stream1
3114 (with-input-from-string (s "
3115 (define-symbol-macro test-symbol-macro1 1)
3116 (flet ((test-symbol-macro1 () 2))
3117 (foo test-symbol-macro1)
3118 (test-symbol-macro1))
3119 (bar test-symbol-macro1)")
3120 (ps::with-blank-compilation-environment
3121 (ps-compile-stream s
)))
3123 var testSymbolMacro1_1 = function () {
3128 return testSymbolMacro1_1();
3133 (test-ps-js equality-nary1
3134 (let ((x 10) (y 10) (z 10))
3141 return (_cmp1 = y, x === _cmp1 && _cmp1 === z);
3144 (test-ps-js equality1
3155 (test-ps-js getprop-quote-reserved
3156 (getprop foo
':break
)
3159 (test-ps-js defun-block-return-from
3172 (test-ps-js block-return-from
3176 (return-from scope
))
3188 (test-ps-js block-return-from0
3193 (return-from scope
))
3205 (test-ps-js block-return-from01
3210 (return-from scope
))
3226 (test-ps-js block-return-from02
3231 (return-from scope
(foobar)))
3248 (test-ps-js block-return-from1
3253 (return-from scope
))
3269 (test-ps-js block-return-from2
3275 (return-from scope
6))
3288 (test-ps-js let-funcall
3302 (test-ps-js symbol-macrolet-funcall
3303 (symbol-macrolet ((foo bar
))
3304 (funcall foo
1 2 3))
3307 (test-ps-js times-assign
3311 (test-ps-js vector-literal
3315 (test-ps-js vector-literal1
3317 "[1, 2, ['a', 'b'], 3];")
3320 (+ 1 (rem 2 (+ 3 4)))
3323 (test-ps-js non-associative
3324 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
3325 "1 / (2 / 3) + (1 - (2 - 3));")
3327 (test-ps-js lambda-apply
3329 (apply (lambda (y) (bar (1+ y
))) x
))
3331 return (function (y) {
3337 (test-ps-js operator-expressions-nested-let
3338 (let ((x (let ((y 1))
3347 (test-ps-js operator-expressions-array-nested-let
3348 (list (let ((y 1)) y
) 2)
3354 (test-ps-js add-subtract-precedence
3358 (test-ps-js ps-inline-toplevel
3360 "'javascript:' + 'foo()';")
3362 (test-ps-js no-clause-progn-exp
3366 (test-ps-js no-clause-progn-return
3368 (return-from foo
(progn)))
3373 (test-ps-js empty-cond-clause
3374 (setf x
(cond ((foo))))
3376 var testResult1 = foo();
3378 return testResult1 ? testResult1 : null;
3381 (test-ps-js empty-cond-clause1
3382 (setf x
(cond ((foo) 123)
3387 var testResult1 = bar();
3399 (test-ps-js let-no-body
3401 (return-from foo
(let ((foo bar
)))))
3407 (test-ps-js rename-lexical-dupes
3409 (list (let ((foo 12)) (* foo
2))
3410 (let ((foo 13)) (* foo
3))))
3414 return [(foo = 12, foo * 2), (foo1 = 13, foo1 * 3)];
3417 (test-ps-js defun-comment1
3419 "BARBAR is a revolutionary new foobar.
3423 * BARBAR is a revolutionary new foobar.
3430 (test-ps-js var-comment
3435 (test-ps-js case-return-break-broken-return
3438 ("bar" (if y
(return-from foo t
) nil
))
3453 (test-ps-js case-return-break1-broken-return
3456 ("bar" (if y
(return-from foo t
)))
3471 (test-ps-js setf-progn
3472 (setf foo
(progn (bar) (baz) 3))
3477 (test-ps-js var-progn
3478 (var x
(progn (foo) (bar)))
3482 (test-ps-js implicit-return-loop
3486 (loop :repeat
100 :do
(bar))
3492 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
3500 (test-ps-js loop-closures
3501 (dotimes (i 10) (lambda () (+ i
1)))
3503 for (var i = 0; i < 10; i += 1) {
3510 (test-ps-js loop-closures-let
3513 (lambda () (+ i x
))))
3515 for (var i = 0; i < 10; i += 1) {
3518 return function () {
3525 (test-ps-js loop-closures-flet
3527 (flet ((foo (x) (+ i x
)))
3528 (lambda () (foo i
))))
3530 for (var i = 0; i < 10; i += 1) {
3532 var foo = function (x) {
3535 return function () {
3543 (test-ps-js while-closures-let
3544 (loop while
(foo) do
3546 (lambda () (+ 1 abc
))))
3552 return function () {
3559 (test-ps-js dotted-list-form
3562 (destructuring-bind (b . c
)
3568 var c = bar.length > 1 ? bar.slice(1) : [];
3574 (test-ps-js explicit-nil-block
3577 (block nil
(return (foo 2)) (+ 1 2))
3591 (test-ps-js dynamic-extent-function-return
3594 (return-from foo
6))))
3598 return (function () {
3600 throw { '__ps_block_tag' : 'foo', '__ps_value' : 6 };
3602 } catch (_ps_err1) {
3603 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3604 return _ps_err1['__ps_value'];
3611 (test-ps-js dynamic-extent-function-return-nothing
3614 (return-from foo
))))
3618 return (function () {
3620 throw { '__ps_block_tag' : 'foo', '__ps_value' : null };
3622 } catch (_ps_err1) {
3623 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3624 return _ps_err1['__ps_value'];
3631 (test-ps-js dynamic-extent-function-return-values
3634 (return-from foo
(values 1 2 3)))))
3638 return (function () {
3640 __PS_MV_REG = [2, 3];
3641 throw { '__ps_block_tag' : 'foo',
3642 '__ps_value' : val1 };
3644 } catch (_ps_err2) {
3645 if (_ps_err2 && 'foo' === _ps_err2['__ps_block_tag']) {
3646 return _ps_err2['__ps_value'];
3653 (test-ps-js dynamic-extent-function-return-funcall
3656 (return-from foo
(if baz
6 5)))))
3660 return (function () {
3662 throw { '__ps_block_tag' : 'foo', '__ps_value' : baz ? 6 : 5 };
3664 } catch (_ps_err1) {
3665 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3666 return _ps_err1['__ps_value'];
3673 (test-ps-js block-dynamic-return
3674 (defvar foo
((lambda ()
3676 ((lambda () (return 6)))
3678 "if ('undefined' === typeof foo) {
3679 var foo = (function () {
3683 throw { '__ps_block_tag' : 'nilBlock', '__ps_value' : 6 };
3687 } catch (_ps_err1) {
3688 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
3689 return _ps_err1['__ps_value'];
3696 (test-ps-js iteration-lambda-capture-no-need
3698 (lambda (x) (1+ x
)))
3700 for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
3708 (test-ps-js case-invert1
3709 (encodeURIComponent fooBar
)
3710 "encodeURIComponent(fooBar);")
3712 (test-ps-js simple-ash
3713 (+ (ash 4 1) (ash 4 -
1))
3714 "(4 << 1) + (4 >> 1);")
3716 (test-ps-js progn-nil-expression
3717 (bar (progn (foo) nil
))
3718 "bar((foo(), null));")
3720 (test-ps-js other-progn-nil-exp
3722 (or (foo) (progn (bar) nil
)))
3725 return foo() || (bar(), null);
3728 (test-ps-js lambda-nil-return
3741 (test-ps-js lambda-nil-return-implicit-nested2
3747 (return-from foo i
)))
3753 for (var i = 0; i < 4; i += 1) {
3760 (test-ps-js throw-is-a-statement
3762 (let ((result (foo)))
3763 (unless (null result
)
3767 if (result != null) {
3772 (test-ps-js expressify1
3774 (when (some-condition)
3779 if (someCondition()) {
3787 (test-ps-js case-when-return
3790 ("a" (when (foo) (return-from blah
111)))
3808 (test-ps-js flet-return-from
3811 (return-from foo
123)))
3814 var foo = function () {
3821 (test-ps-js flet-return-from1
3823 (return-from foo
123)))
3826 var foo = function () {
3833 (test-ps-js lambda-docstring-declarations
3835 "This is a docstring"
3836 (declare (ignore x
))
3842 (test-ps-js setf-let-exp
3843 (setf foo
(let ((x (+ 1 2)))
3845 "foo = (function () {
3847 return x ? 123 : 456;
3850 (test-ps-js create-let-exp
3851 (create :abc
(let ((x (+ 1 2)))
3853 "{ 'abc' : (function () {
3855 return x ? 123 : 456;
3858 (test-ps-js eql-eql-eql-precedence
3859 (unless (equal (= 3 3) (= 3 4))
3860 (chain console
(log 1)))
3861 "if ((3 === 3) != (3 === 4)) {
3865 (test-ps-js case-cond-breaks
3871 (return-from blah nil
))
3899 (test-ps-js cond-double-t
3912 (test-ps-js let-let-funcall-lambda
3915 (funcall (lambda (x) (+ x
9)) x
)))
3919 return (function (x) {
3924 (test-ps-js let-let-lambda
3927 (lambda (x) (+ x
9))))
3931 return function (x) {
3936 (test-ps-js let-lambda
3938 (lambda (x) (+ x
9)))
3941 return function (x) {
3946 (test-ps-js symbol-macrolet-no-shadow-lambda
3947 (symbol-macrolet ((x y
))
3948 (lambda (x) (+ x x
)))
3953 (test-ps-js divide-one-arg-reciprocal
3957 (test-ps-js division-not-associative
3961 (test-ps-js divide-expressions
3965 (test-ps-js divide-expressions1
3967 "Math.floor((x - 1) / y);")
3969 (test-ps-js lexical-funargs-shadow1
3981 (test-ps-js times-rem
3985 (test-ps-js rem-divide
3989 (test-ps-js case-break-return
3990 (lambda () (case x
(:foo
) (:bar
1)))
4000 (test-ps-js trivial-expression-switch
4001 (foobar (case x
(1 2)))
4002 "foobar((function () {
4009 (test-ps-js trivial-expression-while
4010 (foobar (loop while
(< 0 x
) do
(decf x
)))
4011 "foobar((function () {
4017 (test-ps-js funcall-block-expression-loop-lambda
4018 (foobar (loop for i from
0 to
10 do
(1+ i
)))
4019 "foobar((function () {
4020 for (var i = 0; i <= 10; i += 1) {
4025 (test-ps-js plus-block-expression-loop-lambda
4026 (1+ (loop for i from
0 to
10 do
(1+ i
)))
4028 for (var i = 0; i <= 10; i += 1) {
4033 (test-ps-js let-closures-rename
4035 (let ((x 1)) (lambda () (1+ x
)))
4036 (let ((x 2)) (lambda () (1+ x
))))
4043 return function () {
4048 (test-ps-js let-closures-rename1
4052 (lambda () (+ x y
))))
4055 (lambda () (+ x y
)))))
4064 return function () {
4069 (test-ps-js let-closures-rename2
4070 (defun make-closures ()
4072 (let ((x 1)) (lambda () (1+ x
)))
4073 (let ((x 2)) (lambda () (1+ x
)))))
4074 "function makeClosures() {
4077 return [(x = 1, function () {
4079 }), (x1 = 2, function () {
4085 (test-ps-js conditional-not-used-up
4097 (test-ps-js toplevel-local-scope
4098 (create "fn" (let ((x 5)) (lambda () x
)))
4099 "{ 'fn' : (function () {
4101 return function () {
4106 (test-ps-js toplevel-local-scope1
4107 (defparameter foo
(create "fn" (let ((x 5)) (lambda () x
))))
4108 "var foo = { 'fn' : (function () {
4110 return function () {
4115 (test-ps-js block-let
4118 (return-from foobar x
)
4126 (test-ps-js expressionize-if-macroexpand-error
4127 (progn (defmacro xbaz
() `(blah))
4133 "function foo(xbaz) {
4145 (test-ps-js toplevel-defun-macroexpand
4146 (progn (defmacro defun-js
(name lambda-list
&body body
)
4147 `(defun ,name
,lambda-list
,@body
))
4150 (defun-js bar
() (1+ foo
))
4156 if ('undefined' === typeof baz) { var baz = 2; };")
4158 (test-ps-js js-ir-package-unique-symbols
4159 (loop :for i
:from
0 :below
5 :do
4160 (let ((block (elt blocks i
)))
4164 for (var i = 0; i < 5; i += 1) {
4165 var block = blocks[i];
4173 (test-ps-js broken-quote-expansion1
4178 return p.x < 0 ? p.y : p.x;
4181 (test-ps-js broken-quote-expansion2
4183 (define-symbol-macro foo123
(ps:@ a foo123
))
4184 (lambda () (when (> foo123
1) 2)))
4186 return a.foo123 > 1 ? 2 : null;
4189 (test-ps-js unused-named-block-not-printed1
4196 (test-ps-js unused-named-block-not-printed2
4204 (test-ps-js unused-named-block-not-printed3
4212 (test-ps-js unused-named-block-not-printed4
4221 (test-ps-js trig-no-bind1
4223 "(Math.exp(3.14) + Math.exp(-3.14)) / 2;")
4225 (test-ps-js trig-bind1
4228 var x1 = blah(3.14);
4230 return 2 * Math.log(Math.sqrt((x1 + 1) / 2) + Math.sqrt((x1 - 1) / 2));
4233 (test-ps-js double-negation
4234 (or (not foo
) (not (not foo
)) (not (not (not foo
))))
4235 "!foo || foo || !foo;")
4237 (test-ps-js empty-let
4246 (test-ps-js empty-let
*
4255 (test-ps-js defun-no-body-declare
4256 (defun foo () (declare (ignore x
)))
4261 (test-ps-js defun-no-body-let-declare
4262 (defun foo () (let () (declare (ignore x
))))
4267 (test-ps-js empty-defun-docstring-declare
4270 (declare (ignore x
)))
4276 (test-ps-js defun-docstring-string
4285 (test-ps-js return-object
4287 (ps:create
:abc
(let ((x (ps:getprop obj
"blah")))
4289 "function foo(obj) {
4291 return { 'abc' : (x = obj['blah'], x ? 123 : 456) };
4294 (test-ps-js unicode-strings
4298 (test-ps-js expressionize-return
4299 (defun next-page (self)
4300 (with-slots (limit offset count
)
4302 (when (and count
(< (* limit offset
) count
))
4303 (set-state self
(create x
(+ offset
1))))))
4304 "function nextPage(self) {
4305 var object1 = self.state;
4307 return object1.count && object1.limit * object1.offset < object1.count ? setState(self, { x : object1.offset + 1 }) : null;
4310 (test-ps-js let-defun-toplevel
4311 (progn (let ((foo 0))
4320 (test-ps-js let-defvar-toplevel
4321 (progn (let ((foo 0))
4322 (defvar bar
(1+ foo
)))
4325 if ('undefined' === typeof bar) { var bar = foo + 1; };
4328 (test-ps-js setf-side-effects
4330 (defun side-effect()
4333 (setf x
(+ 2 (side-effect) x
5)))
4335 function sideEffect() {
4339 x = 2 + sideEffect() + x + 5;")
4341 (test-ps-js stupid-lisp-trick
4345 (write-string "[1,2,3]" ps
::*psw-stream
*)
4349 (test-ps-js maybe-once-only-symbol-macrolet
4350 (symbol-macrolet ((x (call-me-once)))
4354 var x1 = callMeOnce();
4356 return (Math.exp(x1) - Math.exp(-x1)) / 2;
4359 (test-ps-js maybe-once-only-symbol-macro
4361 (define-symbol-macro maybe-once-only-symbol-macro
(call-me-once))
4362 (tanh maybe-once-only-symbol-macro
))
4365 var x1 = callMeOnce();
4367 return (Math.exp(x1) - Math.exp(-x1)) / (Math.exp(x1) + Math.exp(-x1));
4370 (test-ps-js maybe-once-only-evaluation-order
4373 (maybe-once-only (x y
)
4380 return x1 + x1 + y2 + y2;
4383 (test-ps-js maybe-once-only-macroexpansion
4386 (ps:maybe-once-only
(x y
)
4393 (test-ps-js lambda-block-wrap-for-dynamic-return
4407 throw { '__ps_block_tag' : 'X', '__ps_value' : 1 };
4412 } catch (_ps_err1) {
4413 if (_ps_err1 && 'X' === _ps_err1['__ps_block_tag']) {
4414 _ps_err1['__ps_value'];
4425 (test-ps-js lambda-progn-block
4430 (return-from X
1)))))
4433 return function () {
4435 throw { '__ps_block_tag' : 'X', '__ps_value' : 1 };
4437 } catch (_ps_err1) {
4438 if (_ps_err1 && 'X' === _ps_err1['__ps_block_tag']) {
4439 return _ps_err1['__ps_value'];
4446 (test-ps-js defun-when-if-return
4449 (loop if
(foo) return
10)))
4450 "function foobar() {
4461 (test-ps-js block-block-return-from-toplevel
4464 (return-from foo
10)))
4469 ;;; Stuff to fix. Not necessarily wrong, but redundant/could be better
4471 (test-ps-js block-dynamic-return1-redundant
4475 ((lambda () (return 6)))
4478 ;;; FIXME. Not wrong, but redundant
4479 "var foo = (function () {
4484 throw { '__ps_block_tag' : 'nilBlock', '__ps_value' : 6 };
4487 } catch (_ps_err1) {
4488 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
4489 _ps_err1['__ps_value'];
4500 (test-ps-js block-gratuitous-dynamic-return
4504 (return-from bar
10)))
4510 throw { '__ps_block_tag' : 'bar', '__ps_value' : 10 };
4511 } catch (_ps_err1) {
4512 if (_ps_err1 && 'bar' === _ps_err1['__ps_block_tag']) {
4513 _ps_err1['__ps_value'];
4524 (test-ps-js for-loop-var-init-let
4527 ((x (let ((x0 (foo y
)))
4533 for (var x = (x0 = foo(y), bar(x0)); ; ) {