1 ;;; Copyright 2011-2012 Vladimir Sedach
3 ;;; SPDX-License-Identifier: BSD-3-Clause
5 ;;; Redistribution and use in source and binary forms, with or
6 ;;; without modification, are permitted provided that the following
7 ;;; conditions are met:
9 ;;; 1. Redistributions of source code must retain the above copyright
10 ;;; notice, this list of conditions and the following disclaimer.
12 ;;; 2. Redistributions in binary form must reproduce the above
13 ;;; copyright notice, this list of conditions and the following
14 ;;; disclaimer in the documentation and/or other materials provided
15 ;;; with the distribution.
17 ;;; 3. Neither the name of the copyright holder nor the names of its
18 ;;; contributors may be used to endorse or promote products derived
19 ;;; from this software without specific prior written permission.
21 ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
22 ;;; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
23 ;;; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 ;;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 ;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
26 ;;; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 ;;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28 ;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 ;;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 ;;; ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 ;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 ;;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 ;;; POSSIBILITY OF SUCH DAMAGE.
35 (in-package #:parenscript.eval-tests
)
36 (named-readtables:in-readtable
:parenscript
)
38 #+sbcl
(declaim (sb-ext:muffle-conditions sb-ext
:compiler-note
))
40 (fiveam:in-suite parenscript.tests
::eval-tests
)
47 (< 123.12 123.123 123.124)
54 (test-js-eval statements-and-expressions-2
55 ((lambda () (if 1 2 3)))
58 (test-js-eval statements-and-expressions-1
59 ((lambda () (+ 2 (if 1 2 3))))
62 (test-js-eval empty-array
66 (test-js-eval funargs-let1
74 (test-js-eval times-rem
78 (test-js-eval divide-rem
82 (test-js-eval rem-divide
86 (test-js-eval rem-multiply
90 (test-js-eval case-return-break-null
97 (test-js-eval defun-return1
98 (progn (defun bar (x) (1+ x
))
102 (test-js-eval defun-return2
103 (progn (defun bar (fn)
107 (bar (lambda () (return-from foo
123))))
113 (progn (defvar foo
1)
117 (test-js-eval block-dynamic-lambda
118 ((lambda () (block nil
(return 4) (+ 1 2))))
121 (test-js-eval block-dynamic-lambda1
122 ((lambda () (block nil
(return 4) (+ 1 2)) 5))
125 (test-js-eval loop-sum
126 (+ 1 (loop for i from
0 to
10 sum i
))
129 (test-js-eval loop-funcall-sum
130 ((lambda (x) (1+ x
)) (loop for i from
0 to
10 sum i
))
133 (test-js-eval loop-funcall-if-sum
134 (progn (defun one-plus (x)
137 (one-plus (if false
1 (loop for i from
0 to
10 sum i
))))
140 (test-js-eval case-return-break1-broken-return
141 (progn (defun foo (x y
)
143 ("bar" (if y
(return-from foo
1)))
145 (list (foo "bar" t
) (foo "bar" nil
) (foo "baz" nil
)))
148 (test-js-eval funcall-loop-doing
150 (loop for i from
0 to
10 do
(1+ i
)))
153 (test-js-eval block-dynamic-lambda2
154 ((lambda () (1+ (block nil
(return 4) (+ 1 2)))))
157 (test-js-eval block-dynamic-setf
158 (progn (defvar foo
(block nil
(return 4) (+ 1 2)))
162 (test-js-eval block-dynamic-return1
163 (progn (defvar foo
((lambda ()
165 ((lambda () (return 6)))
170 (test-js-eval block-lambda-dynamic-setf
171 (progn (defvar foo
(block nil
((lambda () (return 4))) (+ 1 2)))
175 (test-js-eval block-lambda-dynamic-lambda
176 ((lambda () (block nil
((lambda () (return 4))) (+ 1 2))))
179 (test-js-eval return-from-flet
181 (flet ((bar () (return-from foo
42)))
186 (test-js-eval plus-block
187 (1+ (block nil
(return 4) (+ 1 2)))
190 (test-js-eval let-closures-rename
191 (progn (defun make-closures ()
193 (let ((x 1)) (lambda () (1+ x
)))
194 (let ((x 2)) (lambda () (1+ x
)))))
196 (defvar foo
(make-closures))
198 (list (funcall (aref foo
0))
199 (funcall (aref foo
1))))
202 (test-js-eval labels-return
206 (return-from bar
"even"))
211 (test-js-eval labels-return1
215 (return-from foo
"even"))
222 (test-js-eval labels-return2
226 (when (evenp (+ x y
))
227 (return-from bar
"even"))))
235 (test-js-eval labels-return3
239 (when (evenp (+ x y
))
240 (return-from foo
"even"))))
249 (test-js-eval toplevel-local-scope
250 (progn (defvar foo
(create "fn" (let ((x 5)) (lambda () x
))))
251 (funcall (getprop foo
"fn")))
254 (test-js-eval special-var2
255 (progn (defvar *foo
*)
261 (test-js-eval special-var3
262 (progn (defvar *foo
* 1)
263 (+ *foo
* (let* ((*baz
* 3)
274 (test-js-eval operator-expressions-array-nested-let
275 (list (let ((y 1)) y
) 2)
278 (test-js-eval block-return-plus
279 (+ 1 (block foobar
(return-from foobar
2) 1))
282 (test-js-eval block-return-plus1
283 (+ 1 (block foobar
(+ 4 ((lambda (x) (return-from foobar x
)) 2)) 1))
286 (test-js-eval block-let
289 (return-from foobar x
)
293 (test-js-eval block-dynamic-return
294 (block nil
(return 4) (+ 1 2))
297 (test-js-eval block-lambda-dynamic-return
298 (block nil
((lambda () (return 4))) (+ 1 2))
301 (test-js-eval nil-block-return-1
302 (block nil
(return 1) 2)
305 (test-js-eval dolist-return
310 (test-js-eval let-defun-toplevel
311 (progn (let ((foo 0))
316 (test-js-eval let-defvar-toplevel
317 (progn (let ((foo 0))
318 (defvar bar
(1+ foo
)))
322 (test-js-eval values-not-returned
324 (setf x
(+ x
(values 2 (incf x
))))
328 (test-js-eval equality-nary1
329 (let ((x 10) (y 10) (z 10))
333 (test-js-eval values-not-returned1
335 (incf x
(+ x
(values 1 (incf x
))))
339 (test-js-eval incf-incf
345 (test-js-eval incf-setf
351 (test-js-eval values0
352 ((lambda () (values)))
355 (test-js-eval mv-return1
358 (multiple-value-bind (a b c
) (foo)
362 (test-js-eval dynamic-extent-function-return-values
365 (return-from foo
(values 1 2 3)))))
366 (multiple-value-bind (a b c
) (foo)
370 (test-js-eval plus-not-associative
376 (test-js-eval loop-return
378 (* 10 (loop for i from
0 below
10 do
384 (test-js-eval for-arr-place-in
385 (loop :for
(a b
) :in
'((2 3) (4 5)) :sum
(+ a b
))
388 (test-js-eval for-obj-place-in
389 (loop :for
(:a
:b
) :in
(list (create :a
2 :b
3)
394 (test-js-eval for-arr-place-
=
395 (flet ((foo () '(2 3)))
396 (loop :repeat
3 :for
(a b
) = (foo) :sum
(+ a b
)))
399 (test-js-eval for-obj-place-
=
400 (flet ((foo () (create :a
2 :b
3)))
401 (loop :repeat
3 :for
(:a
:b
) = (foo) :sum
(+ a b
)))
404 (test-js-eval loop-until1
406 (loop :doing
(incf x
) :until t
)
410 (test-js-eval loop-until2
411 (let ((b nil
) (c nil
))
412 (loop :for a
:in
'(4 9 10) :do
(setf b a
) :until
(> a
5))
413 (loop :for a
:in
'(4 9 10) :until
(> a
5) :do
(setf c a
))
417 (test-js-eval loop-until3
419 (loop :do
(incf x
) :until
(= x
5)
420 :do
(incf y
) :until
(= y
3))
424 (test-js-eval loop-with-clause
425 (loop for i
:from
0 :to
5
428 do
(return (setf x i
)))
431 (test-js-eval loop-append
432 (loop :for i
:from
0 :below
10 :by
3 :append
(list i
(* i
100)))
433 '(0 0 3 300 6 600 9 900))
435 (test-js-eval loop-appending
436 (loop :for i
:from
0 :below
10 :by
3 :appending
(list i
(* i
100)))
437 '(0 0 3 300 6 600 9 900))
439 (test-js-eval loop-maximize
440 (loop :for i
:in
(list 1 5 3 2) :maximize i
)
443 (test-js-eval loop-maximizing
444 (loop :for i
:in
(list 1 5 3 7) :maximizing i
)
447 (test-js-eval loop-minimize
448 (loop :for i
:in
(list 1 5 3 2) :minimize i
)
451 (test-js-eval loop-minimizing
452 (loop :for i
:in
(list 3 5 3 2) :minimizing i
)
455 (test-js-eval loop-for-on
456 (loop :for
(a b
) :on
'(10 20 30 40 50 60) :by
2 :collect
(list b a
))
457 '((20 10) (40 30) (60 50)))
459 (test-js-eval loop-parallel-clauses-with-return
460 (loop :for i
:from
0 :below
10 :for x
= (* i
10)
461 :when
(> i
5) :do
(return x
)
465 (test-js-eval loop-extended-conditional-clauses
466 (loop for i
:from
0 :to
5
475 '(1 2 2 1 3 4 4 2 5 6 6 3))
477 (test-js-eval loop-extended-conditional-clauses1
479 (bar (loop for i
:from
0 :to
5
488 and do
(incf foo x
))))
489 (funcall (@ bar push
) foo
)
491 '(1 2 2 1 3 4 4 2 5 6 6 3 21))
493 (test-js-eval for-loop-downfrom-to
494 (loop for i
:downfrom
5 :to
0
498 (test-js-eval for-loop-downfrom-above
499 (loop for i
:downfrom
5 :above
0
503 (test-js-eval loop-conditional-return-works
506 (if (< 10 i
) (return i
)))
510 (test-js-eval return-from-loop
519 (test-js-eval for-loop-var-init-exp
521 (do* ((y (if x
0 1) (1+ y
))
527 (test-js-eval dolist-return1
532 (test-js-eval lambda-nil-return-implicit-nested
533 (progn (defun foo (x)
541 (list (foo t
) (foo nil
)))
544 (test-js-eval case-clauses0
553 (test-js-eval case-clauses-false
561 (test-js-eval case-clauses-false-nil
569 (test-js-eval case-clauses-true
576 ;;; needs MV pass-through to work
577 ;; (test-js-eval multiple-value-call-twice
579 ;; (defun foo (x &optional y z)
588 ;; (multiple-value-bind (a b c) (bar)
590 ;; '(4 5 :undefined))
592 (test-js-eval recursive-values
604 (multiple-value-bind (a b c d
) (bar)
606 '(23 :undefined
:undefined
:undefined
))
608 (test-js-eval recursive-values1
622 (multiple-value-bind (a b c d
) (bar)
624 '(23 :undefined
:undefined
:undefined
))
626 (test-js-eval values-nonlocal-return
640 (multiple-value-bind (a b c
) (bar)
642 '(27 :undefined
:undefined
))
644 (test-js-eval values-nonlocal-return1
661 (multiple-value-bind (a b c
) (bar 1)
663 '(27 :undefined
:undefined
))
665 (test-js-eval values-nonlocal-return2
678 (multiple-value-bind (a b c
) (foo 1)
680 '(27 :undefined
:undefined
))
682 (test-js-eval case-symbol-macro-key
683 (symbol-macrolet ((x 1))
691 (test-js-eval case-symbol
699 (test-js-eval symbol-macro-funcall
700 (symbol-macrolet ((bar (getprop Math
'min
)))
704 (test-js-eval negative-mod
708 (test-js-eval negative-mod1
709 (mod -
12 (funcall (@ Math floor
) 7.5))
712 (test-js-eval negative-mod2
716 (test-js-eval negative-rem
720 (test-js-eval negative-rem1
721 (rem -
12 (funcall (@ Math floor
) 7.5))
724 (test-js-eval-epsilon trig1
728 (test-js-eval-epsilon trig2
732 (test-js-eval-epsilon trig3
736 (test-js-eval-epsilon trig4
740 (test-js-eval-epsilon trig5
744 (test-js-eval-epsilon trig6
748 (test-js-eval-epsilon trig7
752 (test-js-eval-epsilon trig8
756 (test-js-eval-epsilon trig7
760 (test-js-eval-epsilon trig8
764 (test-js-eval-epsilon trig7
768 (test-js-eval-epsilon trig8
769 (atanh (expt -
0.71 3))
772 (test-js-eval let-let
773 (let ((x (let ((y 12))
779 (test-js-eval let-let1
780 (let ((x (let ((y 12))
787 (test-js-eval array-init-1
788 (make-array 2 :initial-contents
'(10 20))
791 (test-js-eval array-init-2
792 (make-array 5 :initial-element
10)
795 (test-js-eval dotimes-block-return
796 (1+ (dotimes (x 3) (if (= x
2) (return (+ x x
)))))
799 (test-js-eval labels-factorial
805 (f (- n
1) (* n a
)))))
810 (test-js-eval destructuring-bind1
813 (destructuring-bind (b . c
)
819 (test-js-eval defun-not-a-docstring
826 (test-js-eval lambda-not-a-docstring
830 (test-js-eval loop-variable-capture1
831 (let ((x (make-array 10)))
832 (dotimes (i 10) (setf (aref x i
) (lambda () i
)))
833 (loop for x across x sum
(funcall x
)))
836 (test-js-eval loop-variable-capture2
837 (let ((x (make-array 10)))
840 (setf (aref x i
) (lambda () y
))))
841 (loop for x across x sum
(funcall x
)))
844 (test-js-eval loop-variable-capture3
845 (let ((x (make-array 10)))
848 (setf (aref x i
) (lambda () i
))))
849 (loop for x across x sum
(funcall x
)))
852 (test-js-eval nested-let
853 (let ((x (let ((y 94))
858 (test-js-eval lambda-apply
860 (apply (lambda (y) (1+ y
))
865 (test-js-eval subtract-associative
870 (test-js-eval logand1
872 (setf x
(logand x
947))
876 (test-js-eval cons-cdr-clause-empty
877 ((lambda () (cond (923))))
880 (test-js-eval labels-return-from
883 (return-from bar
"even"))
888 (test-js-eval random-float-const
889 (< 0 (rem (random 123.456) 1) 1)
892 (test-js-eval random-int-const
896 (test-js-eval random-float-fun-once-only
903 (< 0 (rem (random (foo)) 1) 1)))
906 (test-js-eval let-setf-side-effects
911 (setf x
(+ 2 (side-effect) x
5)))
914 (test-js-eval dolist-result-bind-nil
915 (dolist (i '(1 2 3) (list i
9))
919 (test-js-eval dotimes-result-bind-nil
920 (dotimes (i '(1 2 3) (list 9 i
))