1 /* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "jerryscript.h"
17
18 #include "test-common.h"
19
20 #define T(op, lhs, rhs, res) \
21 { op, lhs, rhs, res }
22
23 #define T_NAN(op, lhs, rhs) \
24 { op, lhs, rhs }
25
26 #define T_ERR(op, lsh, rhs) \
27 T_NAN (op, lsh, rhs)
28
29 #define T_ARI(lhs, rhs) \
30 T_NAN (JERRY_BIN_OP_SUB, lhs, rhs), \
31 T_NAN (JERRY_BIN_OP_MUL, lhs, rhs), \
32 T_NAN (JERRY_BIN_OP_DIV, lhs, rhs), \
33 T_NAN (JERRY_BIN_OP_REM, lhs, rhs)
34
35 typedef struct
36 {
37 jerry_binary_operation_t op;
38 jerry_value_t lhs;
39 jerry_value_t rhs;
40 jerry_value_t expected;
41 } test_entry_t;
42
43 typedef struct
44 {
45 jerry_binary_operation_t op;
46 jerry_value_t lhs;
47 jerry_value_t rhs;
48 } test_nan_entry_t;
49
50 typedef test_nan_entry_t test_error_entry_t;
51
52 int
main(void)53 main (void)
54 {
55 TEST_INIT ();
56
57 jerry_init (JERRY_INIT_EMPTY);
58
59 jerry_value_t obj1 = jerry_eval ((const jerry_char_t *) "o={x:1};o", 9, JERRY_PARSE_NO_OPTS);
60 jerry_value_t obj2 = jerry_eval ((const jerry_char_t *) "o={x:1};o", 9, JERRY_PARSE_NO_OPTS);
61 jerry_value_t err1 = jerry_create_error (JERRY_ERROR_SYNTAX, (const jerry_char_t *) "error");
62
63 test_nan_entry_t test_nans[] =
64 {
65 /* Testing addition (+) */
66 T_NAN (JERRY_BIN_OP_ADD, jerry_create_number (3.1), jerry_create_undefined ()),
67 T_NAN (JERRY_BIN_OP_ADD, jerry_create_undefined (), jerry_create_undefined ()),
68 T_NAN (JERRY_BIN_OP_ADD, jerry_create_undefined (), jerry_create_null ()),
69
70 /* Testing subtraction (-), multiplication (*), division (/), remainder (%) */
71 T_ARI (jerry_create_number (3.1), jerry_create_undefined ()),
72 T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_string ((const jerry_char_t *) "bar")),
73 T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_undefined ()),
74 T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_null ()),
75 T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_number (5.0)),
76 T_ARI (jerry_create_undefined (), jerry_create_string ((const jerry_char_t *) "foo")),
77 T_ARI (jerry_create_null (), jerry_create_string ((const jerry_char_t *) "foo")),
78 T_ARI (jerry_create_number (5.0), jerry_create_string ((const jerry_char_t *) "foo")),
79 T_ARI (jerry_create_undefined (), jerry_create_undefined ()),
80 T_ARI (jerry_create_undefined (), jerry_create_null ()),
81 T_ARI (jerry_create_null (), jerry_create_undefined ()),
82 T_ARI (jerry_acquire_value (obj1), jerry_acquire_value (obj1)),
83 T_ARI (jerry_acquire_value (obj1), jerry_acquire_value (obj2)),
84 T_ARI (jerry_acquire_value (obj2), jerry_acquire_value (obj1)),
85 T_ARI (jerry_acquire_value (obj2), jerry_create_undefined ()),
86 T_ARI (jerry_acquire_value (obj1), jerry_create_string ((const jerry_char_t *) "foo")),
87 T_ARI (jerry_acquire_value (obj1), jerry_create_null ()),
88 T_ARI (jerry_acquire_value (obj1), jerry_create_boolean (true)),
89 T_ARI (jerry_acquire_value (obj1), jerry_create_boolean (false)),
90 T_ARI (jerry_acquire_value (obj1), jerry_create_number (5.0)),
91
92 /* Testing division (/) */
93 T_NAN (JERRY_BIN_OP_DIV, jerry_create_boolean (false), jerry_create_boolean (false)),
94 T_NAN (JERRY_BIN_OP_DIV, jerry_create_number (0.0), jerry_create_number (0.0)),
95 T_NAN (JERRY_BIN_OP_DIV, jerry_create_null (), jerry_create_null ()),
96
97 /* Testing remainder (%) */
98 T_NAN (JERRY_BIN_OP_REM, jerry_create_boolean (true), jerry_create_boolean (false)),
99 T_NAN (JERRY_BIN_OP_REM, jerry_create_boolean (false), jerry_create_boolean (false)),
100 T_NAN (JERRY_BIN_OP_REM, jerry_create_number (0.0), jerry_create_number (0.0)),
101 T_NAN (JERRY_BIN_OP_REM, jerry_create_null (), jerry_create_null ()),
102 };
103
104 for (uint32_t idx = 0; idx < sizeof (test_nans) / sizeof (test_nan_entry_t); idx++)
105 {
106 jerry_value_t result = jerry_binary_operation (test_nans[idx].op, test_nans[idx].lhs, test_nans[idx].rhs);
107 TEST_ASSERT (jerry_value_is_number (result));
108
109 double num = jerry_get_number_value (result);
110
111 TEST_ASSERT (num != num);
112
113 jerry_release_value (test_nans[idx].lhs);
114 jerry_release_value (test_nans[idx].rhs);
115 jerry_release_value (result);
116 }
117
118 test_entry_t tests[] =
119 {
120 /* Testing addition (+) */
121 T (JERRY_BIN_OP_ADD, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (10.0)),
122 T (JERRY_BIN_OP_ADD, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (13.1)),
123 T (JERRY_BIN_OP_ADD, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (4.1)),
124 T (JERRY_BIN_OP_ADD,
125 jerry_create_string ((const jerry_char_t *) "foo"),
126 jerry_create_string ((const jerry_char_t *) "bar"),
127 jerry_create_string ((const jerry_char_t *) "foobar")),
128 T (JERRY_BIN_OP_ADD,
129 jerry_create_string ((const jerry_char_t *) "foo"),
130 jerry_create_undefined (),
131 jerry_create_string ((const jerry_char_t *) "fooundefined")),
132 T (JERRY_BIN_OP_ADD,
133 jerry_create_string ((const jerry_char_t *) "foo"),
134 jerry_create_null (),
135 jerry_create_string ((const jerry_char_t *) "foonull")),
136 T (JERRY_BIN_OP_ADD,
137 jerry_create_string ((const jerry_char_t *) "foo"),
138 jerry_create_number (5.0),
139 jerry_create_string ((const jerry_char_t *) "foo5")),
140
141 T (JERRY_BIN_OP_ADD, jerry_create_null (), jerry_create_null (), jerry_create_number (0.0)),
142 T (JERRY_BIN_OP_ADD, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (2.0)),
143 T (JERRY_BIN_OP_ADD, jerry_create_boolean (true), jerry_create_boolean (false), jerry_create_number (1.0)),
144 T (JERRY_BIN_OP_ADD, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (1.0)),
145 T (JERRY_BIN_OP_ADD, jerry_create_boolean (false), jerry_create_boolean (false), jerry_create_number (0.0)),
146 T (JERRY_BIN_OP_ADD,
147 jerry_acquire_value (obj1),
148 jerry_acquire_value (obj1),
149 jerry_create_string ((const jerry_char_t *) "[object Object][object Object]")),
150 T (JERRY_BIN_OP_ADD,
151 jerry_acquire_value (obj1),
152 jerry_acquire_value (obj2),
153 jerry_create_string ((const jerry_char_t *) "[object Object][object Object]")),
154 T (JERRY_BIN_OP_ADD,
155 jerry_acquire_value (obj2),
156 jerry_acquire_value (obj1),
157 jerry_create_string ((const jerry_char_t *) "[object Object][object Object]")),
158 T (JERRY_BIN_OP_ADD,
159 jerry_acquire_value (obj1),
160 jerry_create_null (),
161 jerry_create_string ((const jerry_char_t *) "[object Object]null")),
162 T (JERRY_BIN_OP_ADD,
163 jerry_acquire_value (obj1),
164 jerry_create_undefined (),
165 jerry_create_string ((const jerry_char_t *) "[object Object]undefined")),
166 T (JERRY_BIN_OP_ADD,
167 jerry_acquire_value (obj1),
168 jerry_create_boolean (true),
169 jerry_create_string ((const jerry_char_t *) "[object Object]true")),
170 T (JERRY_BIN_OP_ADD,
171 jerry_acquire_value (obj1),
172 jerry_create_boolean (false),
173 jerry_create_string ((const jerry_char_t *) "[object Object]false")),
174 T (JERRY_BIN_OP_ADD,
175 jerry_acquire_value (obj1),
176 jerry_create_number (5.0),
177 jerry_create_string ((const jerry_char_t *) "[object Object]5")),
178 T (JERRY_BIN_OP_ADD,
179 jerry_acquire_value (obj1),
180 jerry_create_string ((const jerry_char_t *) "foo"),
181 jerry_create_string ((const jerry_char_t *) "[object Object]foo")),
182
183 /* Testing subtraction (-) */
184 T (JERRY_BIN_OP_SUB, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (0.0)),
185 T (JERRY_BIN_OP_SUB, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (-6.9)),
186 T (JERRY_BIN_OP_SUB, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (2.1)),
187 T (JERRY_BIN_OP_SUB, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (0.0)),
188 T (JERRY_BIN_OP_SUB, jerry_create_boolean (true), jerry_create_boolean (false), jerry_create_number (1.0)),
189 T (JERRY_BIN_OP_SUB, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (-1.0)),
190 T (JERRY_BIN_OP_SUB, jerry_create_boolean (false), jerry_create_boolean (false), jerry_create_number (0.0)),
191 T (JERRY_BIN_OP_SUB, jerry_create_null (), jerry_create_null (), jerry_create_number (-0.0)),
192
193 /* Testing multiplication (*) */
194 T (JERRY_BIN_OP_MUL, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (25.0)),
195 T (JERRY_BIN_OP_MUL, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (31)),
196 T (JERRY_BIN_OP_MUL, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (3.1)),
197 T (JERRY_BIN_OP_MUL, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (1.0)),
198 T (JERRY_BIN_OP_MUL, jerry_create_boolean (true), jerry_create_boolean (false), jerry_create_number (0.0)),
199 T (JERRY_BIN_OP_MUL, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (0.0)),
200 T (JERRY_BIN_OP_MUL, jerry_create_boolean (false), jerry_create_boolean (false), jerry_create_number (0.0)),
201 T (JERRY_BIN_OP_MUL, jerry_create_null (), jerry_create_null (), jerry_create_number (0.0)),
202
203 /* Testing division (/) */
204 T (JERRY_BIN_OP_DIV, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (1.0)),
205 T (JERRY_BIN_OP_DIV, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (0.31)),
206 T (JERRY_BIN_OP_DIV, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (3.1)),
207 T (JERRY_BIN_OP_DIV, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (1.0)),
208 T (JERRY_BIN_OP_DIV,
209 jerry_create_boolean (true),
210 jerry_create_boolean (false),
211 jerry_create_number_infinity (false)),
212 T (JERRY_BIN_OP_DIV, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (0.0)),
213
214 /* Testing remainder (%) */
215 T (JERRY_BIN_OP_REM, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (0.0)),
216 T (JERRY_BIN_OP_REM, jerry_create_number (5.0), jerry_create_number (2.0), jerry_create_number (1.0)),
217 T (JERRY_BIN_OP_REM, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (3.1)),
218 T (JERRY_BIN_OP_REM,
219 jerry_create_number (3.1),
220 jerry_create_boolean (true),
221 jerry_create_number (0.10000000000000009)),
222 T (JERRY_BIN_OP_REM, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (0.0)),
223 T (JERRY_BIN_OP_REM, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (0.0)),
224
225 };
226
227 for (uint32_t idx = 0; idx < sizeof (tests) / sizeof (test_entry_t); idx++)
228 {
229 jerry_value_t result = jerry_binary_operation (tests[idx].op, tests[idx].lhs, tests[idx].rhs);
230 TEST_ASSERT (!jerry_value_is_error (result));
231
232 jerry_value_t equals = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL, result, tests[idx].expected);
233 TEST_ASSERT (jerry_value_is_boolean (equals) && jerry_get_boolean_value (equals));
234 jerry_release_value (equals);
235
236 jerry_release_value (tests[idx].lhs);
237 jerry_release_value (tests[idx].rhs);
238 jerry_release_value (tests[idx].expected);
239 jerry_release_value (result);
240 }
241
242 jerry_value_t obj3 = jerry_eval ((const jerry_char_t *) "o={valueOf:function(){throw 5}};o", 33, JERRY_PARSE_NO_OPTS);
243
244 test_error_entry_t error_tests[] =
245 {
246 /* Testing addition (+) */
247 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (err1), jerry_acquire_value (err1)),
248 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (err1), jerry_create_undefined ()),
249 T_ERR (JERRY_BIN_OP_ADD, jerry_create_undefined (), jerry_acquire_value (err1)),
250
251 /* Testing subtraction (-), multiplication (*), division (/), remainder (%) */
252 T_ARI (jerry_acquire_value (err1), jerry_acquire_value (err1)),
253 T_ARI (jerry_acquire_value (err1), jerry_create_undefined ()),
254 T_ARI (jerry_create_undefined (), jerry_acquire_value (err1)),
255
256 /* Testing addition (+) */
257 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_undefined ()),
258 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_null ()),
259 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_boolean (true)),
260 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_boolean (false)),
261 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_acquire_value (obj2)),
262 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_string ((const jerry_char_t *) "foo")),
263
264 /* Testing subtraction (-), multiplication (*), division (/), remainder (%) */
265 T_ARI (jerry_acquire_value (obj3), jerry_create_undefined ()),
266 T_ARI (jerry_acquire_value (obj3), jerry_create_null ()),
267 T_ARI (jerry_acquire_value (obj3), jerry_create_boolean (true)),
268 T_ARI (jerry_acquire_value (obj3), jerry_create_boolean (false)),
269 T_ARI (jerry_acquire_value (obj3), jerry_acquire_value (obj2)),
270 T_ARI (jerry_acquire_value (obj3), jerry_create_string ((const jerry_char_t *) "foo")),
271 };
272
273 for (uint32_t idx = 0; idx < sizeof (error_tests) / sizeof (test_error_entry_t); idx++)
274 {
275 jerry_value_t result = jerry_binary_operation (tests[idx].op, error_tests[idx].lhs, error_tests[idx].rhs);
276 TEST_ASSERT (jerry_value_is_error (result));
277 jerry_release_value (error_tests[idx].lhs);
278 jerry_release_value (error_tests[idx].rhs);
279 jerry_release_value (result);
280 }
281
282 jerry_release_value (obj1);
283 jerry_release_value (obj2);
284 jerry_release_value (obj3);
285 jerry_release_value (err1);
286
287 jerry_cleanup ();
288
289 return 0;
290 } /* main */
291