1 ;;; Copyright 2005-2006 Henrik Hjelte
2 ;;; Copyright 2007-2012 Vladimir Sedach
4 ;;; SPDX-License-Identifier: BSD-3-Clause
6 ;;; Redistribution and use in source and binary forms, with or
7 ;;; without modification, are permitted provided that the following
8 ;;; conditions are met:
10 ;;; 1. Redistributions of source code must retain the above copyright
11 ;;; notice, this list of conditions and the following disclaimer.
13 ;;; 2. Redistributions in binary form must reproduce the above
14 ;;; copyright notice, this list of conditions and the following
15 ;;; disclaimer in the documentation and/or other materials provided
16 ;;; with the distribution.
18 ;;; 3. Neither the name of the copyright holder nor the names of its
19 ;;; contributors may be used to endorse or promote products derived
20 ;;; from this software without specific prior written permission.
22 ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 ;;; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 ;;; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 ;;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 ;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
27 ;;; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 ;;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 ;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 ;;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 ;;; ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 ;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 ;;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 ;;; POSSIBILITY OF SUCH DAMAGE.
36 (in-package #:parenscript.tests
)
37 (named-readtables:in-readtable
:parenscript
)
39 (fiveam:in-suite output-tests
)
41 (test-ps-js statements-and-expressions-1
45 (test-ps-js statements-and-expressions-2
53 (test-ps-js symbol-conversion-1
55 "bangwhathashatpercent;")
57 (test-ps-js symbol-conversion-2
61 (test-ps-js symbol-conversion-3
65 (test-ps-js symbol-conversion-4
69 (test-ps-js symbol-conversion-5
71 "encodeURIComponent;")
73 (test-ps-js symbol-conversion-6
77 (test-ps-js number-literals-1
81 (test-ps-js number-literals-2
85 (test-ps-js number-literals-3
89 (test-ps-js string-literals-1
93 (test-ps-js string-literals-2
97 (test-ps-js string-literals-3
101 (test-ps-js array-literals-1
105 (test-ps-js array-literals-2
109 (test-ps-js array-literals-3
111 (array "foobar" "bratzel bub"))
112 "[[2, 3], ['foobar', 'bratzel bub']];")
114 (test-ps-js array-literals-4
118 (test-ps-js array-literals-5
120 "new Array(1, 2, 3);")
122 (test-ps-js array-literals-6
125 (make-array "foobar" "bratzel bub"))
126 "new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));")
128 (test-ps-js array-init-1
129 (make-array 2 :initial-contents
'(10 20))
131 var arr1 = new Array(2);
132 var init2 = [10, 20];
133 for (var i4 = 0; i4 < Math.min(arr1.length, init2.length); i4 += 1) {
134 arr1[i4] = init2[i4];
140 (test-ps-js array-init-2
141 (make-array 5 :initial-element
10)
143 var arr1 = new Array(5);
145 for (var i4 = 0; i4 < arr1.length; i4 += 1) {
152 (test-ps-js object-literals-1
153 (create foo
"bar" :blorg
1)
154 "{ foo : 'bar', 'blorg' : 1 };")
156 (test-ps-js object-literals-2
159 another-object
(create :schtrunz
1))
162 anotherObject : { 'schtrunz' : 1 } };")
164 (test-ps-js object-literals-3
165 (getprop an-object
'foo
)
168 (test-ps-js object-literals-4
169 (@ an-object foo bar
)
172 (test-ps-js object-literals-5
173 (with-slots (a b c
) this
175 "this.a + this.b + this.c;")
177 (test-ps-js with-slots-single-eval
178 (lambda () (with-slots (a b
) (foo) (+ a b
)))
182 return object1.a + object1.b;
185 (test-ps-js object-literal-quoted-symbols
186 (create 'test
"bang" 'symbol-saved-my-life
"parenscript")
187 "{ 'test' : 'bang', 'symbolSavedMyLife' : 'parenscript' };")
189 (test-ps-js object-literal-property-accessors
193 (set x v
) (setf x v
))))
202 :js-target-version
"1.8.5")
204 (test-ps-js object-method-apply-1
205 (apply (@ an-object foo
) nil
)
206 "anObject.foo.apply(anObject, null);")
208 (test-ps-js object-method-apply-2
209 (apply (getprop (make-an-object) foo
'bar
) nil
)
211 var _js1 = makeAnObject()[foo];
214 return _js2.apply(_js1, null);
217 (test-ps-js object-method-apply-3
218 (apply (@ (make-an-object) foo
) (bar))
220 var _js1 = makeAnObject();
223 return _js2.apply(_js1, bar());
226 (test-ps-js regular-expression-literals-1
230 (test-ps-js regular-expression-literals-2
234 (test-ps-js literal-symbols-1
238 (test-ps-js literal-symbols-2
242 (test-ps-js literal-symbols-3
246 (test-ps-js literal-symbols-4
252 (test-ps-js literal-symbols-5
256 (test-ps-js literal-symbols-6
260 (test-ps-js variables-1
264 (test-ps-js variables-2
268 (test-ps-js variables-3
272 (test-ps-js function-calls-and-method-calls-1
276 (test-ps-js function-calls-and-method-calls-2
277 (foobar (blorg 1 2) (blabla 3 4) (array 2 3 4))
278 "foobar(blorg(1, 2), blabla(3, 4), [2, 3, 4]);")
280 (test-ps-js function-calls-and-method-calls-3
281 ((getprop this
'blorg
) 1 2)
284 (test-ps-js function-calls-and-method-calls-4
288 (test-ps-js function-calls-and-method-calls-5
289 ((getprop (aref foobar
1) 'blorg
) nil t
)
290 "foobar[1].blorg(null, true);")
292 (test-ps-js operator-expressions-1
296 (test-ps-js operator-expressions-2
300 (test-ps-js operator-expressions-3
301 (* 1 (+ 2 3 4) 4 (/ 6 7))
302 "1 * (2 + 3 + 4) * 4 * (6 / 7);")
304 (test-ps-js operator-expressions-4
308 (test-ps-js operator-expressions-5
312 (test-ps-js operator-expressions-6
316 (test-ps-js operator-expressions-7
320 (test-ps-js operator-expressions-8
324 (test-ps-js body-forms-1
325 (progn (blorg i
) (blafoo i
))
329 (test-ps-js body-forms-2
330 (+ i
(progn (blorg i
) (blafoo i
)))
331 "i + (blorg(i), blafoo(i));")
333 (test-ps-js function-definition-1
334 (defun a-function (a b
)
336 "function aFunction(a, b) {
340 (test-ps-js lambda-definition-2
341 (lambda (a b
) (+ a b
))
346 (test-ps-js assignment-1
350 (test-ps-js assignment-2
351 (setf a
2 b
3 c
4 x
(+ a b c
))
357 (test-ps-js assignment-3
358 (setf a
(+ a
2 3 4 a
))
359 "a = a + 2 + 3 + 4 + a;")
361 (test-ps-js assignment-4
365 (test-ps-js assignment-5
377 (test-ps-js assignment-6
381 (test-ps-js assignment-8
383 (defun (setf color
) (new-color el
)
384 (setf (getprop (getprop el
'style
) 'color
) new-color
))
385 (setf (color some-div
) (+ 23 "em")))
386 "function __setf_color(newColor, el) {
387 return el.style.color = newColor;
389 __setf_color(23 + 'em', someDiv);")
391 (test-ps-js assignment-10
393 (defsetf left
(el) (offset)
394 `(setf (getprop (getprop ,el
'style
) 'left
) ,offset
))
395 (setf (left some-div
) (+ 123 "px")))
398 var _js1 = 123 + 'px';
399 return _js2.style.left = _js1;
402 (test-ps-js assignment-12
403 (macrolet ((left (el)
404 `(getprop ,el
'offset-left
)))
406 "someDiv.offsetLeft;")
408 (test-ps-js nil-block-return-1
409 (block nil
(return) 1)
415 (test-ps-js single-argument-statements-2
419 (test-ps-js single-argument-expression-1
420 (delete (new (*foobar
2 3 4)))
421 "delete new Foobar(2, 3, 4);")
423 (test-ps-js single-argument-expression-2
424 (if (= (typeof blorg
) *string
)
425 (alert (+ "blorg is a string: " blorg
))
426 (alert "blorg is not a string"))
427 "if (typeof blorg === String) {
428 alert('blorg is a string: ' + blorg);
430 alert('blorg is not a string');
433 (test-ps-js conditional-statements-1
435 (if ((@ blorg is-correct
))
436 (progn (carry-on) (return-from foo i
))
437 (alert "blorg is not correct!")))
439 if (blorg.isCorrect()) {
445 return alert('blorg is not correct!');
449 (test-ps-js conditional-statements-2
450 (+ i
(if ((@ blorg add-one
)) 1 2))
451 "i + (blorg.addOne() ? 1 : 2);")
453 (test-ps-js conditional-statements-3
455 (when ((@ blorg is-correct
))
457 (return-from foo i
)))
459 if (blorg.isCorrect()) {
466 (test-ps-js conditional-statements-4
467 (unless ((@ blorg is-correct
))
468 (alert "blorg is not correct!"))
469 "if (!blorg.isCorrect()) {
470 alert('blorg is not correct!');
473 (test-ps-js variable-declaration-1
474 (defvar *a
* (array 1 2 3))
475 "if ('undefined' === typeof A) { var A = [1, 2, 3]; };")
477 (test-ps-js variable-declaration-2
478 (progn (defvar *a
* 4)
484 "if ('undefined' === typeof A) { var A = 4; };
499 (test-ps-js variable-declaration-3
503 (test-ps-js variable-declaration-4
504 (progn (defparameter *a
* 4)
525 (test-ps-js variable-declaration-5
529 (test-ps-js iteration-constructs-1
530 (do* ((a) b
(c (array "a" "b" "c" "d" "e"))
532 (e (aref c d
) (aref c d
)))
533 ((or (= d
(@ c length
)) (string= e
"x")))
535 (funcall (@ document write
) (+ "a: " a
" b: " b
"<br/>")))
537 for (var a = null, b = null, c = ['a', 'b', 'c', 'd', 'e'], d = 0, e = c[d];
538 !(d === c.length || e === 'x'); d += 1, e = c[d]) {
541 document.write('a: ' + a + ' b: ' + b + '<br/>');
545 (test-ps-js iteration-constructs-2
547 (s 0 (+ s i
(1+ i
))))
549 (funcall (@ document write
) (+ "i: " i
" s: " s
"<br/>")))
554 document.write('i: ' + i + ' s: ' + s + '<br/>');
556 var _js2 = s + i + (i + 1);
562 (test-ps-js iteration-constructs-3
564 (s 0 (+ s i
(1- i
))))
566 ((@ document write
) (+ "i: " i
" s: " s
"<br/>")))
568 for (var i = 0, s = 0; i <= 10; i += 1, s = s + i + (i - 1)) {
569 document.write('i: ' + i + ' s: ' + s + '<br/>');
573 (test-ps-js iteration-constructs-4
574 (let ((arr (array "a" "b" "c" "d" "e")))
575 (dotimes (i (@ arr length
))
576 ((@ document write
) (+ "i: " i
" arr[i]: " (aref arr i
) "<br/>"))))
578 var arr = ['a', 'b', 'c', 'd', 'e'];
579 for (var i = 0; i < arr.length; i += 1) {
580 document.write('i: ' + i + ' arr[i]: ' + arr[i] + '<br/>');
584 (test-ps-js iteration-constructs-5
586 (alert (+ "Summation to 10 is "
588 (incf res
(1+ i
))))))
592 return alert('Summation to 10 is ' + (function () {
593 for (var i = 0; i < 10; i += 1) {
601 (test-ps-js iteration-constructs-6
602 (let ((l (list 1 2 4 8 16 32)))
604 ((@ document write
) (+ "c: " c
"<br/>"))))
606 var l = [1, 2, 4, 8, 16, 32];
607 for (var c = null, _js_idx2 = 0; _js_idx2 < l.length; _js_idx2 += 1) {
609 document.write('c: ' + c + '<br/>');
613 (test-ps-js iteration-constructs-7
614 (let ((l '(1 2 4 8 16 32))
616 (alert (+ "Sum of " l
" is: "
620 var l = [1, 2, 4, 8, 16, 32];
623 return alert('Sum of ' + l + ' is: ' + (function () {
624 for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) {
633 (test-ps-js iteration-constructs-8
634 (let ((obj (create a
1 b
2 c
3)))
636 ((@ document write
) (+ i
": " (aref obj i
) "<br/>"))))
638 var obj = { a : 1, b : 2, c : 3 };
640 document.write(i + ': ' + obj[i] + '<br/>');
644 (test-ps-js iteration-constructs-9
645 (loop while
(funcall (@ film is-not-finished
)) do
646 (funcall (@ this eat
) (new *popcorn
)))
648 while (film.isNotFinished()) {
649 this.eat(new Popcorn);
653 (test-ps-js loop-for-bindings
654 (loop :for
((a b
) (:c
:d
)) :in arr
:do
(foo a b c d
))
656 var _js2 = arr.length;
657 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
658 var _db4 = arr[_js1];
669 (test-ps-js loop-for-on
670 (loop :for
(k v
) :on plist
:by
2 :do
(foo k v
))
672 for (var _js1 = plist; _js1.length > 0; _js1 = _js1['slice'](2)) {
679 (test-ps-js loop-for-keys-of
680 (loop :for k
:of obj
:do
(foo k
))
687 (test-ps-js loop-for-key-val-pairs-of
688 (loop :for
(k v
) :of obj
:do
(foo k v
))
696 (test-ps-js loop-for-key-val-pairs-of-with-bindings
697 (loop :for
(k (a b
)) :of obj
:do
(foo k a b
))
707 (test-ps-js loop-for-just-vals-of
708 (loop :for
(nil v
) :of obj
:do
(foo k v
))
710 for (var _js1 in obj) {
716 (test-ps-js loop-map-to
717 (loop :for str
:in strs
:map str
:to
(length str
))
719 var _js2 = strs.length;
721 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
722 var str = strs[_js1];
723 map3[str] = str.length;
728 (test-ps-js loop-for-of-map-to
729 (loop :for k
:of obj
:map k
:to
(foo k
))
739 (test-ps-js loop-for-of-when
740 (loop :for k
:of obj
:when
(foo k
) :map k
:to
(bar k
))
752 (test-ps-js loop-for-in-until-when
753 (loop :for a
:in b
:until
(> a
100) :when
(< a
50) :do
(foo a
))
756 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
767 (test-ps-js loop-with-for-when
768 (loop :with c
= c1
:for d
:from c1
:below c2
769 :when
(foo c d
) :do
(setf c d
)
773 for (var d = c1; d < c2; d += 1) {
781 (test-ps-js loop-for-then-for-in-while
783 (loop :for a
= (foo) :then
(bar) :for b
:in c
:while b
:do
(foo a b c
)))
787 for (var a = foo(); true; a = bar()) {
788 var _js1 = FIRST3 ? 0 : _js1 + 1;
801 (test-ps-js loop-while-when
802 (loop :for a
= (pop stack
) :while a
:for
(b c
) = (foo a
) :when b
:do
(bar c
))
804 for (var a = pop(stack); a; a = pop(stack)) {
814 (test-ps-js loop-for-of-for-in
816 (loop :for k
:of obj
:for a
:in b
:do
(foo k a
)))
817 "function blah(obj, b) {
821 var _js1 = FIRST3 ? 0 : _js1 + 1;
831 (test-ps-js loop-for-dot
832 (loop :for
(op . args
) :in expr
:do
(foo op args
))
834 var _js2 = expr.length;
835 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
836 var _db3 = expr[_js1];
838 var args = _db3.length > 1 ? _db3.slice(1) : [];
843 (test-ps-js loop-for-rest
844 (loop :for
(op &rest args
) :in expr
:do
(foo op args
))
846 var _js2 = expr.length;
847 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
848 var _db3 = expr[_js1];
850 var args = _db3.length > 1 ? _db3.slice(1) : [];
855 (test-ps-js loop-collect
856 (setf x
(loop :for a
:in b
:collect
(foo a
)))
860 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
862 collect3.push(foo(a));
868 (test-ps-js loop-append
869 (loop :for a
:in b
:append a
)
873 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
875 append3 = append3.concat(a);
881 (test-ps-js the-case-statement-1
883 ((1 "one") (alert "one"))
885 (t (alert "default clause")))
895 alert('default clause');
898 (test-ps-js the-case-statement-2
899 (switch (aref blorg i
)
900 (1 (alert "If I get here"))
901 (2 (alert "I also get here"))
902 (default (alert "I always get here")))
904 case 1: alert('If I get here');
905 case 2: alert('I also get here');
906 default: alert('I always get here');
909 (test-ps-js the-try-statement-1
912 (alert (+ "an error happened: " error
)))
914 (alert "Leaving the try form")))
918 alert('an error happened: ' + error);
920 alert('Leaving the try form');
923 (test-ps-js the-html-generator-1
924 (ps-html ((:a
:href
"foobar") "blorg"))
925 "'<a href=\\\"foobar\\\">blorg</a>';")
927 (test-ps-js the-html-generator-2
928 (ps-html ((:a
:href
(generate-a-link)) "blorg"))
929 "['<a href=\\\"', generateALink(), '\\\">blorg</a>'].join('');")
931 (test-ps-js the-html-generator-3
932 (funcall (getprop document
'write
)
933 (ps-html ((:a
:href
"#"
934 :onclick
(ps-inline (transport))) "link")))
935 "document.write(['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">link</a>'].join(''));")
937 (test-ps-js the-html-generator-4
940 (setf (getprop element
'inner-h-t-m-l
)
941 (ps-html ((:textarea
(or disabled
(not authorized
)) :disabled
"disabled")
945 var authorized = true;
946 return element.innerHTML = ['<textarea', disabled || !authorized ? [' disabled=\\\"', 'disabled', '\\\"'].join('') : '', '>Edit me</textarea>'].join('');
949 (test-ps-js plus-is-not-commutative
950 (setf x
(+ "before" x
"after"))
951 "x = 'before' + x + 'after';")
953 (test-ps-js plus-works-if-first
954 (setf x
(+ x
"middle" "after"))
955 "x = x + 'middle' + 'after';")
957 (test-ps-js method-call-op-form
958 (funcall (getprop (+ "" x
) 'to-string
))
959 "('' + x).toString();")
961 (test-ps-js method-call-op-form-args
962 (funcall (getprop (+ "" x
) 'foo
) 1 2 :baz
3)
963 "('' + x).foo(1, 2, 'baz', 3);")
965 (test-ps-js method-call-string
966 ((getprop "hi" 'to-string
))
969 (test-ps-js method-call-conditional
973 (test-ps-js method-call-variable
977 (test-ps-js method-call-array
978 ((@ (list 10 20) to-string
))
979 "[10, 20].toString();")
981 (test-ps-js method-call-lambda-call
982 (funcall (getprop (funcall (lambda (x) x
) 10) 'to-string
))
983 "(function (x) { return x; })(10).toString();")
985 (fiveam:test no-whitespace-before-dot
986 (let ((str (ps* '((@ ((lambda (x) x
) 10) to-string
)))))
987 (fiveam:is
(char= #\
) (elt str
(1- (position #\. str
)))))))
989 (test-ps-js simple-getprop
990 (let ((foo (create a
1)))
991 (alert (getprop foo
'a
)))
998 (test-ps-js buggy-getprop
999 (getprop foo slot-name
)
1002 (test-ps-js buggy-getprop-two
1003 (getprop foo
(get-slot-name))
1004 "foo[getSlotName()];")
1006 (test-ps-js old-case-is-now-switch
1007 ;; Switch was "case" before, but that was very non-lispish.
1008 ;; For example, this code makes three messages and not one
1009 ;; which may have been expected. This is because a switch
1010 ;; statment must have a break statement for it to return
1011 ;; after the alert. Otherwise it continues on the next
1013 (switch (aref blorg i
)
1016 (default (alert "default clause")))
1017 "switch (blorg[i]) {
1018 case 1: alert('one');
1019 case 2: alert('two');
1020 default: alert('default clause');
1023 (test-ps-js lisp-like-case
1024 (case (aref blorg i
)
1027 (t (alert "default clause")))
1028 "switch (blorg[i]) {
1035 default: alert('default clause');
1039 (test-ps-js even-lispier-case
1040 (case (aref blorg i
)
1041 ((1 2) (alert "Below three"))
1043 (t (alert "Something else")))
1044 "switch (blorg[i]) {
1047 alert('Below three');
1052 default: alert('Something else');
1055 (test-ps-js otherwise-case
1056 (case (aref blorg i
)
1058 (otherwise (alert "default clause")))
1059 "switch (blorg[i]) {
1063 default: alert('default clause');
1066 (fiveam:test escape-sequences-in-string
1070 (#\f .
,(code-char 12))
1071 ("u000B" .
,(code-char #xB
)) ; vertical tab
1077 ("u001F" .
,(code-char #x1F
)) ; character below 32
1078 ("u0080" .
,(code-char 128)) ; character over 127
1079 ("u00A0" .
,(code-char 160)) ; non-breaking space
1080 ("u00AD" .
,(code-char 173)) ; soft hyphen
1081 ("u200B" .
,(code-char #x200B
)) ; zero-width space
1082 ("u200C" .
,(code-char #x200C
)) ; zero-width non-joiner
1084 (loop for
(js-escape . lisp-char
) in escapes
1085 for generated
= (ps-doc* (format nil
"hello~ahi" lisp-char
))
1086 for wanted
= (format nil
"'hello\\~ahi';" js-escape
)
1087 do
(fiveam:is
(string= generated wanted
)))))
1089 (fiveam:test escape-doublequotes
1090 (let ((*js-string-delimiter
* #\"))
1091 (fiveam:is
(string= (ps-doc* "hello\"hi") "\"hello\\\"\hi\";"))))
1093 (test-ps-js getprop-setf
1094 (setf (getprop x
'y
) (+ (+ a
3) 4))
1095 "x.y = (a + 3) + 4;")
1097 (test-ps-js getprop-conditional1
1098 (getprop (if zoo foo bar
) 'x
)
1099 "(zoo ? foo : bar).x;")
1101 (test-ps-js getprop-conditional2
1102 (getprop (if (not zoo
) foo bar
) 'x
)
1103 "(!zoo ? foo : bar).x;")
1105 (fiveam:test script-star-eval1
1107 (normalize-js-output (ps* '(setf x
1) '(setf y
2)))
1110 (fiveam:test script-star-eval2
1112 (normalize-js-output (ps* '(setf x
1)))
1115 (test-ps-js list-with-single-nil
1119 (test-ps-js quoted-nil-is-array
1123 (test-ps-js quoted-nil-is-array1
1127 (test-ps-js literal-nil
1131 (test-ps-js quoted-quoted-nil
1135 (test-ps-js quoted-quoted-nil1
1139 (test-ps-js defsetf1
1140 (progn (defsetf baz
(x y
) (newval) `(set-baz ,x
,y
,newval
))
1147 return setBaz(_js2, _js3, _js1);
1150 (test-ps-js setf-macroexpands1
1151 (macrolet ((bar (x y
)
1153 (setf (bar foo
2) 3))
1156 (test-ps-js defsetf-short
1157 (progn (defsetf baz set-baz
"docstring")
1158 (setf (baz 1 2 3) "foo"))
1159 "setBaz(1, 2, 3, 'foo');")
1161 (test-ps-js defun-setf1
1162 (progn (defun (setf some-thing
) (new-val i1 i2
)
1163 (setf (aref *some-thing
* i1 i2
) new-val
))
1164 (setf (some-thing 1 2) "foo"))
1165 "function __setf_someThing(newVal, i1, i2) {
1166 return SOMETHING[i1][i2] = newVal;
1168 __setf_someThing('foo', 1, 2);")
1170 (test-ps-js defun-optional1
1171 (defun test-opt (&optional x
)
1173 "function testOpt(x) {
1174 return x ? 'yes' : 'no';
1177 (test-ps-js defun-optional2
1178 (defun foo (x &optional y
)
1180 "function foo(x, y) {
1184 (test-ps-js defun-optional3
1185 (defun blah (&optional
(x 0))
1188 if (x === undefined) {
1194 (test-ps-js arglist-optional4
1195 (lambda (&optional
(x 0 supplied?
))
1198 var suppliedwhat = x !== undefined;
1199 if (!suppliedwhat) {
1205 (test-ps-js return-nothing
1206 (defun foo () (return-from foo
))
1211 (test-ps-js return-values
1213 (return-from foo
(values 1 2 3)))
1216 __PS_MV_REG = [2, 3];
1220 (test-ps-js set-timeout
1221 (set-timeout (lambda () (alert "foo")) 10)
1222 "setTimeout(function () { __PS_MV_REG = []; return alert('foo'); }, 10);")
1224 (test-ps-js operator-precedence
1228 (test-ps-js operators-1
1248 (test-ps-js setf-conditional
1249 (setf foo
(if x
1 2))
1252 (test-ps-js obj-literal-numbers
1256 (test-ps-js obj-literal-strings
1260 (test-ps-js getprop-string
1264 (test-ps-js getprop-string1
1265 (getprop "bar" 'length
)
1268 (test-ps-js getprop-progn
1269 (getprop (progn (some-fun "abc") "123") "length")
1270 "(someFun('abc'), '123')['length'];")
1272 (test-ps-js getprop-multi1
1273 (getprop foo
1 "two" three
'bar
1 2)
1274 "foo[1]['two'][three].bar[1][2];")
1276 (test-ps-js method-call-block
1277 ((@ (progn (some-fun "abc") "123") to-string
))
1278 "(someFun('abc'), '123').toString();")
1280 (test-ps-js create-blank
1284 (test-ps-js blank-object-literal
1288 (test-ps-js array-literal1
1292 (test-ps-js array-literal2
1296 (test-ps-js array-literal3
1300 (test-ps-js array-literal4
1304 (test-ps-js array-literal5
1305 ([] (1 2) ("a" "b"))
1306 "[[1, 2], ['a', 'b']];")
1308 (test-ps-js defun-rest1
1309 (defun foo (&rest bar
)
1310 (alert (aref bar
1)))
1312 var bar = Array.prototype.slice.call(arguments, 0);
1314 return alert(bar[1]);
1317 (test-ps-js defun-rest2
1318 (defun foo (baz &rest bar
) (+ baz
(aref bar
1)))
1319 "function foo(baz) {
1320 var bar = Array.prototype.slice.call(arguments, 1);
1322 return baz + bar[1];
1325 (test-ps-js defun-keyword1
1326 (defun zoo (foo bar
&key baz
) (+ foo bar baz
))
1327 "function zoo(foo, bar) {
1328 var _js2 = arguments.length;
1329 for (var n1 = 2; n1 < _js2; n1 += 2) {
1330 switch (arguments[n1]) {
1332 baz = arguments[n1 + 1];
1336 return foo + bar + baz;
1339 (test-ps-js defun-keyword2
1340 (defun zoo (&key baz
) (* baz baz
))
1342 var _js2 = arguments.length;
1343 for (var n1 = 0; n1 < _js2; n1 += 2) {
1344 switch (arguments[n1]) {
1346 baz = arguments[n1 + 1];
1353 (test-ps-js defun-keyword3
1354 (defun zoo (&key baz
(bar 4)) (* baz bar
))
1356 var _js2 = arguments.length;
1357 for (var n1 = 0; n1 < _js2; n1 += 2) {
1358 switch (arguments[n1]) {
1360 baz = arguments[n1 + 1];
1363 bar = arguments[n1 + 1];
1367 var bar = 'undefined' === typeof bar ? 4 : bar;
1371 (test-ps-js defun-keyword4
1372 (defun hello-world (&key
((:my-name-key my-name
) 1))
1374 "function helloWorld() {
1375 var _js2 = arguments.length;
1376 for (var n1 = 0; n1 < _js2; n1 += 2) {
1377 switch (arguments[n1]) {
1379 myName = arguments[n1 + 1];
1382 var myName = 'undefined' === typeof myName ? 1 : myName;
1386 (test-ps-js arglist-keyword-supplied
1387 (lambda (&key
(foo 1 supplied?
))
1390 var _js2 = arguments.length;
1391 for (var n1 = 0; n1 < _js2; n1 += 2) {
1392 switch (arguments[n1]) {
1394 foo = arguments[n1 + 1];
1395 suppliedwhat = true;
1399 var foo = 'undefined' === typeof foo ? 1 : foo;
1403 (test-ps-js keyword-funcall1
1407 (test-ps-js keyword-funcall2
1408 (func :baz
1 :bar foo
)
1409 "func('baz', 1, 'bar', foo);")
1411 (test-ps-js keyword-funcall3
1413 "fun(a, b, 'baz', c);")
1423 ((= y
(* x
4)) (foo "blah") (* x y
)))
1426 } else if (y === x * 4) {
1431 (test-ps-js if-exp-without-else-return
1432 (defun foo () (return-from foo
(if x
1)))
1434 return x ? 1 : null;
1437 (test-ps-js progn-expression-single-statement
1438 (defun foo () (return-from foo
(progn (* x y
))))
1443 (test-ps-js cond-expression1
1445 (cond ((< 1 2) (bar "foo") (* 4 5))))
1454 (test-ps-js cond-expression2
1456 (cond ((< 2 1) "foo")
1461 } else if (7 === 7) {
1466 (test-ps-js cond-expression-final-t-clause
1468 (cond ((< 1 2) (bar "foo") (* 4 5))
1480 } else if (a === b) {
1483 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1492 (test-ps-js cond-expression-middle-t-clause
;; should this signal a warning?
1505 (test-ps-js funcall-if-expression
1506 (funcall (getprop document
'write
)
1507 (if (= *linkornot
* 1)
1508 (ps-html ((:a
:href
"#"
1509 :onclick
(ps-inline (transport)))
1512 "document.write(LINKORNOT === 1 ? ['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">', img, '</a>'].join('') : img);")
1514 (test-ps-js negate-number-literal
1518 (fiveam:test macro-environment1
1521 (normalize-js-output
1522 (let* ((macroname (gensym)))
1523 (ps* `(defmacro ,macroname
(x) `(+ ,x
123))
1525 (macrolet ((,macroname
(x) `(aref data
,x
)))
1526 (when (,macroname x
)
1527 (setf (,macroname x
) 123)))))))
1528 (normalize-js-output
1530 return data[x] ? (data[x] = 123) : null;
1533 (fiveam:test macro-environment2
1536 (let ((outer-lexical-variable 1))
1537 (defpsmacro macro-environment2-macro
(x)
1538 `(+ ,outer-lexical-variable
,x
))
1539 (ps* '(macro-environment2-macro 2)))
1542 (test-ps-js ampersand-whole-1
1543 (macrolet ((foo (&whole foo bar baz
)
1544 (declare (ignore bar baz
))
1545 (with-standard-io-syntax
1546 (let ((*print-case
* :downcase
))
1547 (format nil
"~a" foo
)))))
1551 (test-ps-js ampersand-whole-2
1552 (macrolet ((foo (&whole foo bar baz
)
1557 (test-ps-js keyword-consistent
1561 (test-ps-js simple-symbol-macrolet
1562 (symbol-macrolet ((x 1)) x
)
1565 (test-ps-js compound-symbol-macrolet
1566 (symbol-macrolet ((x 123)
1571 (test-ps-js define-symbol-macro
1572 (progn (define-symbol-macro tst-sym-macro
2)
1576 (test-ps-js define-symbol-macro1
1577 (progn (define-symbol-macro tst-sym-macro1
2)
1578 (foo tst-sym-macro1
))
1581 (test-ps-js define-symbol-macro2
1582 (progn (define-symbol-macro tst-sym-macro2
3)
1583 (list tst-sym-macro2
))
1586 (test-ps-js define-symbol-macro3
1587 (progn (define-symbol-macro tst-sym-macro3
4)
1588 (setq foo
(create tst-sym-macro3 tst-sym-macro3
)))
1589 "foo = { tstSymMacro3 : 4 };")
1591 (test-ps-js define-symbol-macro4
1592 (progn (define-symbol-macro tst-sym-macro4
5)
1593 (setq foo
(if (baz) tst-sym-macro4 bar
)))
1594 "foo = baz() ? 5 : bar;")
1596 (test-ps-js expression-progn
1597 (1+ (progn (foo) (if x
1 2)))
1598 "(foo(), x ? 1 : 2) + 1;")
1600 (test-ps-js let-decl-in-expression
1602 (if x
1 (let* ((foo x
)) foo
)))
1612 (test-ps-js special-var1
1613 (progn (defvar *foo
*)
1620 FOO_TMPSTACK1 = FOO;
1624 FOO = FOO_TMPSTACK1;
1628 (test-ps-js special-var2
1629 (progn (defparameter *foo
*)
1638 FOO_TMPSTACK1 = FOO;
1640 return FOO * 2 * BAZ;
1642 FOO = FOO_TMPSTACK1;
1646 (test-ps-js literal1
1650 (test-ps-js literal2
1654 (test-ps-js setf-dec1
1658 (test-ps-js setf-dec2
1662 (test-ps-js special-char-equals
1666 (test-ps-js setf-operator-priority
1668 (or (getprop cache id
)
1669 (setf (getprop cache id
) ((@ document get-element-by-id
) id
))))
1672 return cache[id] || (cache[id] = document.getElementById(id));
1675 (test-ps-js aref-operator-priority
1676 (aref (if (and x
(> (length x
) 0))
1680 "(x && x.length > 0 ? x[0] : y)[z];")
1682 (test-ps-js aref-operator-priority1
1683 (aref (or (getprop x
'y
)
1688 (test-ps-js aref-operator-priority2
1692 (test-ps-js negate-operator-priority
1701 (delete (if a
(or b c
) d
))
1702 "delete (a ? b || c : d);")
1705 (not (if (or x
(not y
)) z
))
1706 "!(x || !y ? z : null);")
1713 (instanceof (or a b
) (if x y z
))
1714 "((a || b) instanceof (x ? y : z));")
1717 (or x
(if (= x
0) "zero" "empty"))
1718 "x || (x === 0 ? 'zero' : 'empty');")
1720 (test-ps-js named-op-expression
1724 (test-ps-js named-op-expression1
1728 (test-ps-js aref-array-expression
1730 "(a || b || c)[0];")
1732 (test-ps-js getprop-operator
1733 (getprop (or a b c
) 'd
)
1736 (test-ps-js getprop-parens
1737 (getprop (getprop foo
'bar
) 'baz
)
1740 (test-ps-js funcall-funcall
1744 (test-ps-js expression-funcall
1745 ((or (@ window eval
) eval
) foo nil
)
1746 "(window.eval || eval)(foo, null);")
1748 (test-ps-js expression-funcall1
1749 (((or (@ window eval
) eval
) foo nil
))
1750 "(window.eval || eval)(foo, null)();")
1752 (test-ps-js expression-funcall2
1753 (((or (@ window eval
) eval
)) foo nil
)
1754 "(window.eval || eval)()(foo, null);")
1756 (test-ps-js who-html1
1757 (who-ps-html (:span
:class
"ticker-symbol"
1758 :ticker-symbol symbol
1759 (:a
:href
"http://foo.com"
1761 (:span
:class
"ticker-symbol-popup")))
1762 "['<span class=\\\"ticker-symbol\\\" ticker-symbol=\\\"', symbol, '\\\"><a href=\\\"http://foo.com\\\">', symbol, '</a><span class=\\\"ticker-symbol-popup\\\"></span></span>'].join('');")
1764 (test-ps-js who-html2
1765 (who-ps-html (:p
"t0" (:span
"t1")))
1766 "'<p>t0<span>t1</span></p>';")
1769 ((lambda () (flet ((foo (x)
1773 var foo = function (x) {
1781 (flet ((foo (x) (1+ x
))
1785 var foo = function (x) {
1788 var bar = function (y) {
1796 (flet ((foo (x) (+ 2 x
)))
1797 (flet ((foo (x) (1+ x
))
1798 (bar (y) (+ 2 (foo y
))))
1801 var foo = function (x) {
1804 var foo1 = function (x) {
1807 var bar = function (y) {
1812 return bar(foo1(1));
1816 ((lambda () (labels ((foo (x)
1819 (+ x
(foo (1- x
))))))
1822 var foo = function (x) {
1824 return 0 === x ? 0 : x + foo(x - 1);
1831 (labels ((foo (x) (1+ (bar x
)))
1832 (bar (y) (+ 2 (foo y
))))
1835 var foo = function (x) {
1839 var bar = function (y) {
1848 (labels ((foo (x) (1+ x
))
1849 (bar (y) (+ 2 (foo y
))))
1852 var foo = function (x) {
1855 var bar = function (y) {
1863 (test-ps-js labels-lambda-list
1864 (labels ((foo (x &optional
(y 0))
1868 var foo = function (x, y) {
1869 if (y === undefined) {
1878 (test-ps-js for-loop-var-init-exp
1880 (do* ((y (if x
0 1) (1+ y
))
1885 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1894 (test-ps-js literal-array
1898 (test-ps-js literal-array-1
1902 (test-ps-js literal-array-literal
1906 (test-ps-js literal-array-literal1
1910 (fiveam:test ps-lisp-expands-in-lexical-environment
1911 (fiveam:is
(string= (let ((x 5)) (ps (lisp x
)))
1914 (fiveam:test ps-lisp-expands-in-lexical-environment1
1915 (fiveam:is
(string= (let ((x 5)) (ps (+ 1 (lisp x
))))
1918 (fiveam:test ps-lisp-expands-in-lexical-environment2
1919 (fiveam:is
(string= (let ((x 2)) (ps (+ 1 (lisp x
) 3)))
1922 (fiveam:test ps
*-lisp-expands-in-null-lexical-environment
1923 (fiveam:signals unbound-variable
1925 (declare (ignore x
))
1928 (fiveam:test ps
*-lisp-expands-in-dynamic-environment
1931 (declare (special foo
))
1932 (ps* '(+ 1 (lisp (locally (declare (special foo
))
1936 (fiveam:test ps-lisp-dynamic-environment
1939 (declare (special foo
))
1940 (ps (+ 1 (lisp foo
))))
1943 (test-ps-js nested-if-expressions1
1945 (return-from foo
(if (if x y z
) a b
)))
1954 (test-ps-js nested-if-expressions2
1956 (if x y
(if z a b
)))
1965 (test-ps-js nested-if-expressions3
1966 (foo (if (if x y z
) a b
)
1967 (if x y
(if z a b
)))
1968 "foo((x ? y : z) ? a : b, x ? y : (z ? a : b));")
2040 (test-ps-js let-exp1
2091 (test-ps-js symbol-macrolet-var
2092 (symbol-macrolet ((x y
))
2096 (test-ps-js setf-conditional1
2097 (setf x
(unless (null a
) (1+ a
)))
2098 "x = a != null ? a + 1 : null;")
2100 (test-ps-js setf-let1
2101 (setf x
(let ((a 1)) a
))
2107 (test-ps-js setf-let2
2108 (setf x
(let ((a (foo)))
2114 return a != null ? a + 1 : null;
2117 (test-ps-js symbol-macro-env1
2118 (symbol-macrolet ((bar 1))
2119 (macrolet ((bar (x y
) `(+ ,x
,y
)))
2123 (test-ps-js symbol-macrolet-fun1
2124 (symbol-macrolet ((baz +))
2128 (test-ps-js lisp2-namespaces1
2130 (setf list
(list 1 2 3)))
2133 return list = [1, 2, 3];
2136 (test-ps-js let-shadows-symbol-macrolet
2137 (symbol-macrolet ((x y
))
2147 (test-ps-js let-rename-optimization1
2155 (test-ps-js let-rename-optimization2
2164 (test-ps-js symbol-macro-array
2165 (symbol-macrolet ((x 1))
2169 (test-ps-js symbol-macro-obj
2170 (symbol-macrolet ((x (+ 1 2)))
2174 (test-ps-js symbol-macro-obj1
2175 (symbol-macrolet ((x (+ 1 2)))
2179 (test-ps-js symbol-macro-getprop1
2180 (symbol-macrolet ((x (+ 1 2)))
2184 (test-ps-js symbol-macro-getprop1
2185 (symbol-macrolet ((x (+ 1 2)))
2189 (test-ps-js let-let-create
2199 (test-ps-js symbol-macro-conditional1
2200 (symbol-macrolet ((x y
))
2208 (test-ps-js symbol-macro-conditional2
2209 (symbol-macrolet ((x y
))
2213 (test-ps-js preserve-this
2215 (let ((y (block nil
(bar this
))))
2218 var y = (function () {
2226 (test-ps-js flet-apply
2227 (flet ((foo () 'bar
))
2228 (apply (function foo
) nil
))
2230 var foo = function () {
2233 return foo.apply(this, null);
2236 (test-ps-js let-apply
2237 (let ((foo (lambda () 1)))
2238 (let ((foo (lambda () 2)))
2241 var foo = function () {
2244 var foo1 = function () {
2247 return foo1.apply(this, null);
2250 (test-ps-js flet-let
2251 (flet ((x (x) (1+ x
)))
2255 var x = function (x) {
2263 (test-ps-js let-flet
2265 (flet ((x (x) (1+ x
)))
2269 var x1 = function (x) {
2276 (test-ps-js labels-let
2277 (labels ((x (x) (1+ x
)))
2281 var x = function (x) {
2289 (test-ps-js let-labels
2291 (labels ((x (x) (1+ x
)))
2295 var x1 = function (x) {
2302 (test-ps-js macrolet-let-inteference
2303 (macrolet ((a (n) `(+ ,n
5)))
2305 (let ((b (a (- a
4))))
2309 var b = (a - 4) + 5;
2313 (test-ps-js let-subtract-add
2329 (test-ps-js create-reserved-word
2331 "{ 'default' : 1 };")
2333 (test-ps-js getprop-reserved-word
2334 (getprop foo
:default
)
2337 (test-ps-js getprop-reserved-word1
2338 (getprop foo
'default
)
2341 (test-ps-js eval-when-ps-side
2342 (eval-when (:execute
)
2346 (defvar *lisp-output
* nil
)
2348 (fiveam:test eval-when-lisp-side
()
2349 (setf *lisp-output
* 'original-value
)
2351 (normalize-js-output
2352 (ps-doc* `(eval-when (:compile-toplevel
)
2353 (setf *lisp-output
* 'it-works
))))))
2354 (fiveam:is
(eql 'it-works
*lisp-output
*))
2355 (fiveam:is
(string= "" js-output
))))
2357 (defpsmacro my-in-package
(package-name)
2358 `(eval-when (:compile-toplevel
)
2359 (setf *lisp-output
* ,package-name
)))
2361 (fiveam:test eval-when-macro-expansion
()
2362 (setf *lisp-output
* 'original-value
)
2364 (normalize-js-output
2366 (my-in-package :cl-user
)
2368 (declare (ignore js-output
))
2369 (fiveam:is
(eql :cl-user
*lisp-output
*))))
2371 (fiveam:test eval-when-macrolet-expansion
()
2372 (setf *lisp-output
* 'original-value
)
2374 (normalize-js-output
2376 `(macrolet ((my-in-package2 (package-name)
2377 `(eval-when (:compile-toplevel
)
2378 (setf *lisp-output
* ,package-name
))))
2379 (my-in-package2 :cl-user
)
2381 (declare (ignore js-output
))
2382 (fiveam:is
(eql :cl-user
*lisp-output
*))))
2384 (test-ps-js getprop-keyword
2388 (test-ps-js nary-comparison1
2389 (lambda () (< 1 2 3))
2392 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
2395 (test-ps-js chain-getprop1
2396 (chain ($
"foo") (bar x z
) frob
(baz 5))
2397 "$('foo').bar(x, z).frob.baz(5);")
2399 (test-ps-js chain-getprop2
2400 (chain ($
"foo") bar baz
)
2401 "$('foo').bar.baz;")
2403 (test-ps-js chain-getprop3
2404 (chain ($
"foo") bar
(x y
) baz
)
2405 "$('foo').bar.x(y).baz;")
2407 (test-ps-js flet-expression
2408 (1+ (flet ((foo (x) (1+ x
)))
2411 var foo = function (x) {
2418 (test-ps-js flet-lambda-list
2419 (flet ((foo (x &key
(y 0))
2423 var foo = function (x) {
2424 var _js2 = arguments.length;
2425 for (var n1 = 1; n1 < _js2; n1 += 2) {
2426 switch (arguments[n1]) {
2428 y = arguments[n1 + 1];
2431 var y = 'undefined' === typeof y ? 0 : y;
2435 return foo(1, 'y', 2);
2438 (test-ps-js return-case-break-elimination
2452 (test-ps-js aplusplus
2456 (test-ps-js astarstar
2460 (test-ps-js switch-return-fallthrough
2479 (test-ps-js return-last-case
2493 (test-ps-js return-macrolet
2495 (macrolet ((x () 1))
2508 (test-ps-js mv-bind1
2509 (multiple-value-bind (a b
)
2519 var b = __PS_MV_REG[0];
2525 (test-ps-js mv-bind2
2526 (multiple-value-bind (a b
)
2537 var b = __PS_MV_REG[0];
2543 (test-ps-js multiple-value-bind-simple
2544 (multiple-value-bind (a b
) (blah)
2549 var b = __PS_MV_REG[0];
2555 (lambda () (values))
2561 (lambda () (values x
))
2567 (lambda () (values x y
))
2575 (lambda () (values x y z
))
2578 __PS_MV_REG = [y, z];
2582 (test-ps-js values-return
2584 (return-from foo
(values (* x x
) y
)))
2585 "function foo(x, y) {
2591 (test-ps-js return-macrolet1
2593 (symbol-macrolet ((x 2))
2601 (test-ps-js return-cond
2604 (cond ((foo? x
) (loop for y in x do
(foo y
)))
2609 var _js2 = x.length;
2610 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2614 } else if (barwhat(x)) {
2623 (test-ps-js return-case
2627 (1 (loop for y in x do
(foo y
)))
2633 var _js2 = x.length;
2634 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2649 (test-ps-js return-case1
2667 (test-ps-js lambda-loop-if-return
2670 (loop for y in x do
(foo y
))
2674 var _js4 = x.length;
2675 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2685 (test-ps-js lambda-loop-if-return1
2689 (progn (loop for y in x do
(foo y
))
2695 return foo(function () {
2697 var _js4 = x.length;
2698 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2703 throw { '__ps_block_tag' : 'baz',
2704 '__ps_value' : null };
2710 } catch (_ps_err5) {
2711 if (_ps_err5 && 'baz' === _ps_err5['__ps_block_tag']) {
2712 return _ps_err5['__ps_value'];
2719 (test-ps-js switch-loop
2722 (1 (dolist (a b
)))))
2726 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2733 (test-ps-js switch-folds-blocks
2736 (1 (loop repeat
3 do
(alert "foo")))
2741 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2752 (test-ps-js setf-places-before-macros
2754 (defsetf left
(el) (offset)
2755 `(setf (@ ,el style left
) ,offset
))
2756 (macrolet ((left (el)
2757 `(@ ,el offset-left
)))
2763 _js2.style.left = _js1;
2764 return x.offsetLeft;
2767 (test-ps-js for-return
2768 (lambda () (dolist (arg args
) (foo arg
)))
2770 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2771 arg = args[_js_idx1];
2776 (test-ps-js try-catch-return
2796 (let ((x (ps:try
(+ 1 2)
2800 var x = (function () {
2811 (test-ps-js try-finally-return-from
2814 (ps:try
(when (blah) 4)
2820 return blah() ? 4 : null;
2825 return dontCallMe();
2828 (test-ps-js defun-setf-optional
2829 (defun (setf foo
) (new-value b
&optional c
)
2830 (setf (aref b
(or c
0)) new-value
))
2831 "function __setf_foo(newValue, b, c) {
2832 return b[c || 0] = newValue;
2835 (test-ps-js defun-setf-rest
2836 (progn (defun (setf foo
) (new-value b
&rest foo
)
2837 (do-something b foo new-value
))
2838 (setf (foo x
1 2 3 4) 5))
2839 "function __setf_foo(newValue, b) {
2840 var foo = Array.prototype.slice.call(arguments, 2);
2842 return doSomething(b, foo, newValue);
2844 __setf_foo(5, x, 1, 2, 3, 4);")
2846 (test-ps-js return-null
2847 (defun foo () (return-from foo nil
))
2852 (test-ps-js implicit-return-null
2859 (test-ps-js implicit-return-null
2866 (test-ps-js return-conditional-nested
2867 (defun blep (ss x y
)
2871 (destructuring-bind (a b
) pair
2872 (unless (or (null a
) (null b
))
2873 (let ((val (baz a b
)))
2878 "function blep(ss, x, y) {
2884 if (!(a == null || b == null)) {
2885 var val = baz(a, b);
2889 return !blee() ? true : null;
2897 (test-ps-js return-when-returns-broken-return
2899 (return-from foo
(when x
1))
2902 return x ? 1 : null;
2906 (test-ps-js return-case-conditional
2910 (123 (when (bar) t
))
2916 return bar() ? true : null;
2923 (test-ps-js return-try-conditional
2931 return x ? 1 : null;
2939 (test-ps-js function-declare-special
2941 (declare (special *foo
*))
2947 FOO_TMPSTACK1 = FOO;
2951 FOO = FOO_TMPSTACK1;
2955 (test-ps-js declare-special-let
2957 (declare (special *foo
*))
2962 FOO_TMPSTACK1 = FOO;
2967 FOO = FOO_TMPSTACK1;
2971 (test-ps-js declare-special-let-scope
2974 (declare (special *foo
*))
2981 FOO_TMPSTACK1 = FOO;
2985 FOO = FOO_TMPSTACK1;
2992 (test-ps-js declare-special-let
*
2993 (let* ((*foo
* 123) (*bar
* (+ *foo
* *bar
*)))
2994 (declare (special *foo
* *bar
*))
2999 FOO_TMPSTACK1 = FOO;
3003 BAR_TMPSTACK2 = BAR;
3008 BAR = BAR_TMPSTACK2;
3011 FOO = FOO_TMPSTACK1;
3015 (test-ps-js defun-multiple-declarations-around-docstring
3017 (declare (ignorable x y
))
3018 (declare (integer x
) (float y
))
3019 "Fooes X while barring Y."
3020 (declare (special *foo
*) (special *bar
*))
3021 (let ((*bar
* (bar y
)))
3023 "/** Fooes X while barring Y. */
3024 function foo(x, y) {
3027 BAR_TMPSTACK1 = BAR;
3032 BAR = BAR_TMPSTACK1;
3036 (test-ps-js macro-null-toplevel
3038 (defmacro macro-null-toplevel
()
3040 (macro-null-toplevel))
3043 (test-ps-js define-symbol-macro-let
3045 (define-symbol-macro test-symbol-macro
1)
3046 (let ((test-symbol-macro 2))
3047 (1+ test-symbol-macro
))
3048 (1+ test-symbol-macro
))
3050 var testSymbolMacro1 = 2;
3051 return testSymbolMacro1 + 1;
3055 (test-ps-js define-symbol-macro-flet
3057 (define-symbol-macro test-symbol-macro1
1)
3058 (flet ((test-symbol-macro1 () 2))
3059 (foo test-symbol-macro1
)
3060 (test-symbol-macro1))
3061 (bar test-symbol-macro1
))
3063 var testSymbolMacro1_1 = function () {
3068 return testSymbolMacro1_1();
3072 (fiveam:test compile-stream-nulls
3075 (with-input-from-string (s "
3076 (defmacro macro-null-toplevel ()
3078 (macro-null-toplevel)")
3079 (ps-compile-stream s
))
3082 (fiveam:test compile-stream1
3085 (with-input-from-string (s "
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)")
3091 (ps::with-blank-compilation-environment
3092 (ps-compile-stream s
)))
3094 var testSymbolMacro1_1 = function () {
3099 return testSymbolMacro1_1();
3104 (test-ps-js equality-nary1
3105 (let ((x 10) (y 10) (z 10))
3112 return (_cmp1 = y, x === _cmp1 && _cmp1 === z);
3115 (test-ps-js equality1
3126 (test-ps-js getprop-quote-reserved
3127 (getprop foo
':break
)
3130 (test-ps-js defun-block-return-from
3143 (test-ps-js block-return-from
3147 (return-from scope
))
3159 (test-ps-js block-return-from0
3164 (return-from scope
))
3176 (test-ps-js block-return-from01
3181 (return-from scope
))
3197 (test-ps-js block-return-from02
3202 (return-from scope
(foobar)))
3219 (test-ps-js block-return-from1
3224 (return-from scope
))
3240 (test-ps-js block-return-from2
3246 (return-from scope
6))
3259 (test-ps-js let-funcall
3273 (test-ps-js symbol-macrolet-funcall
3274 (symbol-macrolet ((foo bar
))
3275 (funcall foo
1 2 3))
3278 (test-ps-js times-assign
3282 (test-ps-js vector-literal
3286 (test-ps-js vector-literal1
3288 "[1, 2, ['a', 'b'], 3];")
3291 (+ 1 (rem 2 (+ 3 4)))
3294 (test-ps-js non-associative
3295 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
3296 "1 / (2 / 3) + (1 - (2 - 3));")
3298 (test-ps-js lambda-apply
3300 (apply (lambda (y) (bar (1+ y
))) x
))
3302 return (function (y) {
3308 (test-ps-js operator-expressions-nested-let
3309 (let ((x (let ((y 1))
3318 (test-ps-js operator-expressions-array-nested-let
3319 (list (let ((y 1)) y
) 2)
3325 (test-ps-js add-subtract-precedence
3329 (test-ps-js ps-inline-toplevel
3331 "'javascript:' + 'foo()';")
3333 (test-ps-js no-clause-progn-exp
3337 (test-ps-js no-clause-progn-return
3339 (return-from foo
(progn)))
3344 (test-ps-js empty-cond-clause
3345 (setf x
(cond ((foo))))
3347 var testResult1 = foo();
3349 return testResult1 ? testResult1 : null;
3352 (test-ps-js empty-cond-clause1
3353 (setf x
(cond ((foo) 123)
3358 var testResult1 = bar();
3370 (test-ps-js let-no-body
3372 (return-from foo
(let ((foo bar
)))))
3378 (test-ps-js rename-lexical-dupes
3380 (list (let ((foo 12)) (* foo
2))
3381 (let ((foo 13)) (* foo
3))))
3385 return [(foo = 12, foo * 2), (foo1 = 13, foo1 * 3)];
3388 (test-ps-js defun-comment1
3390 "BARBAR is a revolutionary new foobar.
3394 * BARBAR is a revolutionary new foobar.
3401 (test-ps-js var-comment
3406 (test-ps-js case-return-break-broken-return
3409 ("bar" (if y
(return-from foo t
) nil
))
3424 (test-ps-js case-return-break1-broken-return
3427 ("bar" (if y
(return-from foo t
)))
3442 (test-ps-js setf-progn
3443 (setf foo
(progn (bar) (baz) 3))
3448 (test-ps-js var-progn
3449 (var x
(progn (foo) (bar)))
3453 (test-ps-js implicit-return-loop
3457 (loop :repeat
100 :do
(bar))
3463 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
3471 (test-ps-js loop-closures
3472 (dotimes (i 10) (lambda () (+ i
1)))
3474 for (var i = 0; i < 10; i += 1) {
3481 (test-ps-js loop-closures-let
3484 (lambda () (+ i x
))))
3486 for (var i = 0; i < 10; i += 1) {
3489 return function () {
3496 (test-ps-js loop-closures-flet
3498 (flet ((foo (x) (+ i x
)))
3499 (lambda () (foo i
))))
3501 for (var i = 0; i < 10; i += 1) {
3503 var foo = function (x) {
3506 return function () {
3514 (test-ps-js while-closures-let
3515 (loop while
(foo) do
3517 (lambda () (+ 1 abc
))))
3523 return function () {
3530 (test-ps-js dotted-list-form
3533 (destructuring-bind (b . c
)
3539 var c = bar.length > 1 ? bar.slice(1) : [];
3545 (test-ps-js explicit-nil-block
3548 (block nil
(return (foo 2)) (+ 1 2))
3562 (test-ps-js dynamic-extent-function-return
3565 (return-from foo
6))))
3569 return (function () {
3571 throw { '__ps_block_tag' : 'foo', '__ps_value' : 6 };
3573 } catch (_ps_err1) {
3574 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3575 return _ps_err1['__ps_value'];
3582 (test-ps-js dynamic-extent-function-return-nothing
3585 (return-from foo
))))
3589 return (function () {
3591 throw { '__ps_block_tag' : 'foo', '__ps_value' : null };
3593 } catch (_ps_err1) {
3594 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3595 return _ps_err1['__ps_value'];
3602 (test-ps-js dynamic-extent-function-return-values
3605 (return-from foo
(values 1 2 3)))))
3609 return (function () {
3611 __PS_MV_REG = [2, 3];
3612 throw { '__ps_block_tag' : 'foo',
3613 '__ps_value' : val1 };
3615 } catch (_ps_err2) {
3616 if (_ps_err2 && 'foo' === _ps_err2['__ps_block_tag']) {
3617 return _ps_err2['__ps_value'];
3624 (test-ps-js dynamic-extent-function-return-funcall
3627 (return-from foo
(if baz
6 5)))))
3631 return (function () {
3633 throw { '__ps_block_tag' : 'foo', '__ps_value' : baz ? 6 : 5 };
3635 } catch (_ps_err1) {
3636 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3637 return _ps_err1['__ps_value'];
3644 (test-ps-js block-dynamic-return
3645 (defvar foo
((lambda ()
3647 ((lambda () (return 6)))
3649 "if ('undefined' === typeof foo) {
3650 var foo = (function () {
3654 throw { '__ps_block_tag' : 'nilBlock', '__ps_value' : 6 };
3658 } catch (_ps_err1) {
3659 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
3660 return _ps_err1['__ps_value'];
3667 (test-ps-js iteration-lambda-capture-no-need
3669 (lambda (x) (1+ x
)))
3671 for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
3679 (test-ps-js case-invert1
3680 (encodeURIComponent fooBar
)
3681 "encodeURIComponent(fooBar);")
3683 (test-ps-js simple-ash
3684 (+ (ash 4 1) (ash 4 -
1))
3685 "(4 << 1) + (4 >> 1);")
3687 (test-ps-js progn-nil-expression
3688 (bar (progn (foo) nil
))
3689 "bar((foo(), null));")
3691 (test-ps-js other-progn-nil-exp
3693 (or (foo) (progn (bar) nil
)))
3696 return foo() || (bar(), null);
3699 (test-ps-js lambda-nil-return
3712 (test-ps-js lambda-nil-return-implicit-nested2
3718 (return-from foo i
)))
3724 for (var i = 0; i < 4; i += 1) {
3731 (test-ps-js throw-is-a-statement
3733 (let ((result (foo)))
3734 (unless (null result
)
3738 if (result != null) {
3743 (test-ps-js expressify1
3745 (when (some-condition)
3750 if (someCondition()) {
3758 (test-ps-js case-when-return
3761 ("a" (when (foo) (return-from blah
111)))
3779 (test-ps-js flet-return-from
3782 (return-from foo
123)))
3785 var foo = function () {
3792 (test-ps-js flet-return-from1
3794 (return-from foo
123)))
3797 var foo = function () {
3804 (test-ps-js lambda-docstring-declarations
3806 "This is a docstring"
3807 (declare (ignore x
))
3813 (test-ps-js setf-let-exp
3814 (setf foo
(let ((x (+ 1 2)))
3816 "foo = (function () {
3818 return x ? 123 : 456;
3821 (test-ps-js create-let-exp
3822 (create :abc
(let ((x (+ 1 2)))
3824 "{ 'abc' : (function () {
3826 return x ? 123 : 456;
3829 (test-ps-js eql-eql-eql-precedence
3830 (unless (equal (= 3 3) (= 3 4))
3831 (chain console
(log 1)))
3832 "if ((3 === 3) != (3 === 4)) {
3836 (test-ps-js case-cond-breaks
3842 (return-from blah nil
))
3870 (test-ps-js cond-double-t
3883 (test-ps-js let-let-funcall-lambda
3886 (funcall (lambda (x) (+ x
9)) x
)))
3890 return (function (x) {
3895 (test-ps-js let-let-lambda
3898 (lambda (x) (+ x
9))))
3902 return function (x) {
3907 (test-ps-js let-lambda
3909 (lambda (x) (+ x
9)))
3912 return function (x) {
3917 (test-ps-js symbol-macrolet-no-shadow-lambda
3918 (symbol-macrolet ((x y
))
3919 (lambda (x) (+ x x
)))
3924 (test-ps-js divide-one-arg-reciprocal
3928 (test-ps-js division-not-associative
3932 (test-ps-js divide-expressions
3936 (test-ps-js divide-expressions1
3938 "Math.floor((x - 1) / y);")
3940 (test-ps-js lexical-funargs-shadow1
3952 (test-ps-js times-rem
3956 (test-ps-js rem-divide
3960 (test-ps-js case-break-return
3961 (lambda () (case x
(:foo
) (:bar
1)))
3971 (test-ps-js trivial-expression-switch
3972 (foobar (case x
(1 2)))
3973 "foobar((function () {
3980 (test-ps-js trivial-expression-while
3981 (foobar (loop while
(< 0 x
) do
(decf x
)))
3982 "foobar((function () {
3988 (test-ps-js funcall-block-expression-loop-lambda
3989 (foobar (loop for i from
0 to
10 do
(1+ i
)))
3990 "foobar((function () {
3991 for (var i = 0; i <= 10; i += 1) {
3996 (test-ps-js plus-block-expression-loop-lambda
3997 (1+ (loop for i from
0 to
10 do
(1+ i
)))
3999 for (var i = 0; i <= 10; i += 1) {
4004 (test-ps-js let-closures-rename
4006 (let ((x 1)) (lambda () (1+ x
)))
4007 (let ((x 2)) (lambda () (1+ x
))))
4014 return function () {
4019 (test-ps-js let-closures-rename1
4023 (lambda () (+ x y
))))
4026 (lambda () (+ x y
)))))
4035 return function () {
4040 (test-ps-js let-closures-rename2
4041 (defun make-closures ()
4043 (let ((x 1)) (lambda () (1+ x
)))
4044 (let ((x 2)) (lambda () (1+ x
)))))
4045 "function makeClosures() {
4048 return [(x = 1, function () {
4050 }), (x1 = 2, function () {
4056 (test-ps-js conditional-not-used-up
4068 (test-ps-js toplevel-local-scope
4069 (create "fn" (let ((x 5)) (lambda () x
)))
4070 "{ 'fn' : (function () {
4072 return function () {
4077 (test-ps-js toplevel-local-scope1
4078 (defparameter foo
(create "fn" (let ((x 5)) (lambda () x
))))
4079 "var foo = { 'fn' : (function () {
4081 return function () {
4086 (test-ps-js block-let
4089 (return-from foobar x
)
4097 (test-ps-js expressionize-if-macroexpand-error
4098 (progn (defmacro xbaz
() `(blah))
4104 "function foo(xbaz) {
4116 (test-ps-js toplevel-defun-macroexpand
4117 (progn (defmacro defun-js
(name lambda-list
&body body
)
4118 `(defun ,name
,lambda-list
,@body
))
4121 (defun-js bar
() (1+ foo
))
4127 if ('undefined' === typeof baz) { var baz = 2; };")
4129 (test-ps-js js-ir-package-unique-symbols
4130 (loop :for i
:from
0 :below
5 :do
4131 (let ((block (elt blocks i
)))
4135 for (var i = 0; i < 5; i += 1) {
4136 var block = blocks[i];
4144 (test-ps-js broken-quote-expansion1
4149 return p.x < 0 ? p.y : p.x;
4152 (test-ps-js broken-quote-expansion2
4154 (define-symbol-macro foo123
(ps:@ a foo123
))
4155 (lambda () (when (> foo123
1) 2)))
4157 return a.foo123 > 1 ? 2 : null;
4160 (test-ps-js unused-named-block-not-printed1
4167 (test-ps-js unused-named-block-not-printed2
4175 (test-ps-js unused-named-block-not-printed3
4183 (test-ps-js unused-named-block-not-printed4
4192 (test-ps-js trig-no-bind1
4194 "(Math.exp(3.14) + Math.exp(-3.14)) / 2;")
4196 (test-ps-js trig-bind1
4199 var x1 = blah(3.14);
4201 return 2 * Math.log(Math.sqrt((x1 + 1) / 2) + Math.sqrt((x1 - 1) / 2));
4204 (test-ps-js double-negation
4205 (or (not foo
) (not (not foo
)) (not (not (not foo
))))
4206 "!foo || foo || !foo;")
4208 (test-ps-js empty-let
4217 (test-ps-js empty-let
*
4226 (test-ps-js defun-no-body-declare
4227 (defun foo () (declare (ignore x
)))
4232 (test-ps-js defun-no-body-let-declare
4233 (defun foo () (let () (declare (ignore x
))))
4238 (test-ps-js empty-defun-docstring-declare
4241 (declare (ignore x
)))
4247 (test-ps-js defun-docstring-string
4256 (test-ps-js return-object
4258 (ps:create
:abc
(let ((x (ps:getprop obj
"blah")))
4260 "function foo(obj) {
4262 return { 'abc' : (x = obj['blah'], x ? 123 : 456) };
4265 (test-ps-js unicode-strings
4269 (test-ps-js expressionize-return
4270 (defun next-page (self)
4271 (with-slots (limit offset count
)
4273 (when (and count
(< (* limit offset
) count
))
4274 (set-state self
(create x
(+ offset
1))))))
4275 "function nextPage(self) {
4276 var object1 = self.state;
4278 return object1.count && object1.limit * object1.offset < object1.count ? setState(self, { x : object1.offset + 1 }) : null;
4281 (test-ps-js let-defun-toplevel
4282 (progn (let ((foo 0))
4291 (test-ps-js let-defvar-toplevel
4292 (progn (let ((foo 0))
4293 (defvar bar
(1+ foo
)))
4296 if ('undefined' === typeof bar) { var bar = foo + 1; };
4299 (test-ps-js setf-side-effects
4301 (defun side-effect()
4304 (setf x
(+ 2 (side-effect) x
5)))
4306 function sideEffect() {
4310 x = 2 + sideEffect() + x + 5;")
4312 (test-ps-js stupid-lisp-trick
4316 (write-string "[1,2,3]" ps
::*psw-stream
*)
4320 (test-ps-js maybe-once-only-symbol-macrolet
4321 (symbol-macrolet ((x (call-me-once)))
4325 var x1 = callMeOnce();
4327 return (Math.exp(x1) - Math.exp(-x1)) / 2;
4330 (test-ps-js maybe-once-only-symbol-macro
4332 (define-symbol-macro maybe-once-only-symbol-macro
(call-me-once))
4333 (tanh maybe-once-only-symbol-macro
))
4336 var x1 = callMeOnce();
4338 return (Math.exp(x1) - Math.exp(-x1)) / (Math.exp(x1) + Math.exp(-x1));
4341 (test-ps-js maybe-once-only-evaluation-order
4344 (maybe-once-only (x y
)
4351 return x1 + x1 + y2 + y2;
4354 (test-ps-js maybe-once-only-macroexpansion
4357 (ps:maybe-once-only
(x y
)
4364 (test-ps-js lambda-block-wrap-for-dynamic-return
4378 throw { '__ps_block_tag' : 'X', '__ps_value' : 1 };
4383 } catch (_ps_err1) {
4384 if (_ps_err1 && 'X' === _ps_err1['__ps_block_tag']) {
4385 _ps_err1['__ps_value'];
4396 (test-ps-js lambda-progn-block
4401 (return-from X
1)))))
4404 return function () {
4406 throw { '__ps_block_tag' : 'X', '__ps_value' : 1 };
4408 } catch (_ps_err1) {
4409 if (_ps_err1 && 'X' === _ps_err1['__ps_block_tag']) {
4410 return _ps_err1['__ps_value'];
4417 (test-ps-js defun-when-if-return
4420 (loop if
(foo) return
10)))
4421 "function foobar() {
4432 (test-ps-js block-block-return-from-toplevel
4435 (return-from foo
10)))
4440 ;;; Stuff to fix. Not necessarily wrong, but redundant/could be better
4442 (test-ps-js block-dynamic-return1-redundant
4446 ((lambda () (return 6)))
4449 ;;; FIXME. Not wrong, but redundant
4450 "var foo = (function () {
4455 throw { '__ps_block_tag' : 'nilBlock', '__ps_value' : 6 };
4458 } catch (_ps_err1) {
4459 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
4460 _ps_err1['__ps_value'];
4471 (test-ps-js block-gratuitous-dynamic-return
4475 (return-from bar
10)))
4481 throw { '__ps_block_tag' : 'bar', '__ps_value' : 10 };
4482 } catch (_ps_err1) {
4483 if (_ps_err1 && 'bar' === _ps_err1['__ps_block_tag']) {
4484 _ps_err1['__ps_value'];
4495 (test-ps-js for-loop-var-init-let
4498 ((x (let ((x0 (foo y
)))
4504 for (var x = (x0 = foo(y), bar(x0)); ; ) {