usable package system
[clinton/parenscript.git] / t / ps-tests.lisp
1 (in-package :ps-test)
2 ;; Other tests not in the reference
3
4 (eval-when (:compile-toplevel :load-toplevel :execute)
5 (def-suite ps-tests))
6 (in-suite ps-tests)
7
8 (test-ps-js plus-is-not-commutative
9 (setf x (+ "before" x "after"))
10 "x = 'before' + x + 'after'")
11
12 (test-ps-js plus-works-if-first
13 (setf x (+ x "middle" "after"))
14 "x += 'middle' + 'after'")
15
16 (test-ps-js setf-side-effects
17 (progn
18 (let ((x 10))
19 (defun side-effect()
20 (setf x 4)
21 (return 3))
22 (setf x (+ 2 (side-effect) x 5))))
23 "
24 var x = 10;
25 function sideEffect() {
26 x = 4;
27 return 3;
28 };
29 x = 2 + sideEffect() + x + 5;")
30 ;; Parenscript used to optimize to much:
31 ;; var x = 10;
32 ;; function sideEffect() {
33 ;; x = 4;
34 ;; return 3;
35 ;; };
36 ;; x += 2 + sideEffect() + 5;
37 ;;
38 ;; Which is 20, not 14
39
40
41 (test-ps-js dot-notation-bug
42 (.match (+ "" x) "foo")
43 "('' + x).match('foo')")
44
45 (test-ps-js method-call-op-form (.to-string (+ "" x)) "('' + x).toString()")
46 (test-ps-js method-call-number (.to-string 10) "( 10 ).toString()")
47 (test-ps-js method-call-string (.to-string "hi") "'hi'.toString()")
48 (test-ps-js method-call-lit-object
49 (.to-string (create :to-string (lambda ()
50 (return "it works"))))
51 "( { toString : function () { return 'it works'; } } ).toString()")
52
53 (test-ps-js method-call-variable
54 (.to-string x)
55 "x.toString()")
56
57 (test-ps-js method-call-array
58 (.to-string (list 10 20))
59 "[ 10, 20 ].toString()")
60 (test-ps-js method-call-fn-call
61 (.to-string (foo))
62 "foo().toString()")
63 (test-ps-js method-call-lambda-fn
64 (.to-string (lambda () (alert 10)))
65 "( function () { alert(10); } ).toString()")
66 (test-ps-js method-call-lambda-call
67 (.to-string ((lambda (x) (return x)) 10))
68 "(function (x) { return x; }) (10).toString()")
69
70 (test no-whitespace-before-dot
71 (let* ((parenscript::*enable-package-system* nil)
72 (str (compile-script '(.to-string ((lambda (x) (return x)) 10))))
73 (dot-pos (position #\. str :test #'char=))
74 (char-before (elt str (1- dot-pos)))
75 (a-parenthesis #\)))
76 (is (char= char-before a-parenthesis))))
77
78 ;; A problem with long nested operator, when the statement spanned several rows
79 ;; the rows would not be joined together correctly.
80 (test-ps-js bug-dwim-join
81 (alert (html ((:div :id 777
82 :style (css-inline :border "1pxsssssssssss"
83 :font-size "x-small"
84 :height (* 2 200)
85 :width (* 2 300))))))
86 "alert
87 ('<div id=\"777\" style=\"'
88 + ('border:1pxsssssssssss;font-size:x-small;height:' + 2 * 200 + ';width:'
89 + 2 * 300)
90 + '\"></div>')") ;";This line should start with a plus character.
91
92
93 (test-ps-js simple-slot-value
94 (let ((foo (create :a 1)))
95 (alert (slot-value foo 'a)))
96 "{
97 var foo = { a : 1 };
98 alert(foo.a);
99 }")
100
101 (test-ps-js buggy-slot-value
102 (let ((foo (create :a 1))
103 (slot-name "a"))
104 (alert (slot-value foo slot-name)))
105 "{
106 var foo = { a : 1 };
107 var slotName = 'a';
108 alert(foo[slotName]);
109 }"); Last line was alert(foo.slotName) before bug-fix.
110
111 (test-ps-js buggy-slot-value-two
112 (slot-value foo (get-slot-name))
113 "foo[getSlotName()]")
114
115 (test-ps-js old-case-is-now-switch
116 ;; Switch was "case" before, but that was very non-lispish.
117 ;; For example, this code makes three messages and not one
118 ;; which may have been expected. This is because a switch
119 ;; statment must have a break statement for it to return
120 ;; after the alert. Otherwise it continues on the next
121 ;; clause.
122 (switch (aref blorg i)
123 (1 (alert "one"))
124 (2 (alert "two"))
125 (default (alert "default clause")))
126 "switch (blorg[i]) {
127 case 1: alert('one');
128 case 2: alert('two');
129 default: alert('default clause');
130 }")
131
132 (test-ps-js lisp-like-case
133 (case (aref blorg i)
134 (1 (alert "one"))
135 (2 (alert "two"))
136 (default (alert "default clause")))
137 "switch (blorg[i]) {
138 case 1:
139 alert('one');
140 break;
141 case 2:
142 alert('two');
143 break;
144 default: alert('default clause');
145 }")
146
147
148 (test-ps-js even-lispier-case
149 (case (aref blorg i)
150 ((1 2) (alert "Below three"))
151 (3 (alert "Three"))
152 (t (alert "Something else")))
153 "switch (blorg[i]) {
154 case 1: ;
155 case 2:
156 alert('Below three');
157 break;
158 case 3:
159 alert('Three');
160 break;
161 default: alert('Something else');
162 }")
163
164 (test-ps-js otherwise-case
165 (case (aref blorg i)
166 (1 (alert "one"))
167 (otherwise (alert "default clause")))
168 "switch (blorg[i]) {
169 case 1:
170 alert('one');
171 break;
172 default: alert('default clause');
173 }")
174
175 (test escape-sequences-in-string
176 (let ((parenscript::*enable-package-system* nil)
177 (escapes `((#\\ . #\\)
178 (#\b . #\Backspace)
179 (#\f . ,(code-char 12))
180 ("u000B" . ,(code-char #x000b));;Vertical tab, too uncommon to bother with
181 (#\n . #\Newline)
182 (#\r . #\Return)
183 (#\' . #\');;Double quote need not be quoted because parenscript strings are single quoted
184 (#\t . #\Tab)
185 ("u001F" . ,(code-char #x001f));; character below 32
186 ("u0080" . ,(code-char 128)) ;;Character over 127. Actually valid, parenscript escapes them to be sure.
187 ("uABCD" . ,(code-char #xabcd)))));; Really above ascii.
188 (loop for (js-escape . lisp-char) in escapes
189 for generated = (compile-script `(let ((x , (format nil "hello~ahi" lisp-char)))))
190 for wanted = (format nil "{
191 var x = 'hello\\~ahi';
192 }" js-escape)
193 do (is (string= generated wanted)))))
194
195 (test-ps-js complicated-symbol-name1
196 grid-rows[foo].bar
197 "gridRows[foo].bar")
198
199 (test-ps-js complicated-symbol-name2
200 *grid-rows*[foo].bar
201 "GRIDROWS[foo].bar")
202
203 (test-ps-js slot-value-setf
204 (setf (slot-value x 'y) (+ (+ a 3) 4))
205 "x.y = (a + 3) + 4")