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 #include "jerryscript-port.h"
18 #include "jerryscript-port-default.h"
19 #include "test-common.h"
20 #include <gtest/gtest.h>
21
22 #define T(op, lhs, rhs, res) \
23 { op, lhs, rhs, res }
24
25 #define T_NAN(op, lhs, rhs) \
26 { op, lhs, rhs }
27
28 #define T_ERR(op, lsh, rhs) \
29 T_NAN (op, lsh, rhs)
30
31 #define T_ARI(lhs, rhs) \
32 T_NAN (JERRY_BIN_OP_SUB, lhs, rhs), \
33 T_NAN (JERRY_BIN_OP_MUL, lhs, rhs), \
34 T_NAN (JERRY_BIN_OP_DIV, lhs, rhs), \
35 T_NAN (JERRY_BIN_OP_REM, lhs, rhs)
36
37 typedef struct
38 {
39 jerry_binary_operation_t op;
40 jerry_value_t lhs;
41 jerry_value_t rhs;
42 jerry_value_t expected;
43 } test_entry_t;
44
45 typedef struct
46 {
47 jerry_binary_operation_t op;
48 jerry_value_t lhs;
49 jerry_value_t rhs;
50 } test_nan_entry_t;
51
52 typedef test_nan_entry_t test_error_entry_t;
53 class ApiBinaryOperationsArithmeticsTest : public testing::Test{
54 public:
SetUpTestCase()55 static void SetUpTestCase()
56 {
57 GTEST_LOG_(INFO) << "ApiBinaryOperationsArithmeticsTest SetUpTestCase";
58 }
59
TearDownTestCase()60 static void TearDownTestCase()
61 {
62 GTEST_LOG_(INFO) << "ApiBinaryOperationsArithmeticsTest TearDownTestCase";
63 }
64
SetUp()65 void SetUp() override {}
TearDown()66 void TearDown() override {}
67
68 };
69
70 static constexpr size_t JERRY_SCRIPT_MEM_SIZE = 50 * 1024 * 1024;
context_alloc_fn(size_t size,void * cb_data)71 static void* context_alloc_fn(size_t size, void* cb_data)
72 {
73 (void)cb_data;
74 size_t newSize = size > JERRY_SCRIPT_MEM_SIZE ? JERRY_SCRIPT_MEM_SIZE : size;
75 return malloc(newSize);
76 }
77 HWTEST_F(ApiBinaryOperationsArithmeticsTest, Test001, testing::ext::TestSize.Level1)
78 {
79 jerry_context_t* ctx_p = jerry_create_context(1024 * 1024 * 50, context_alloc_fn, NULL);
80 jerry_port_default_set_current_context(ctx_p);
81 TEST_INIT ();
82
83 jerry_init (JERRY_INIT_EMPTY);
84
85 jerry_value_t obj1 = jerry_eval ((const jerry_char_t *) "o={x:1};o", 9, JERRY_PARSE_NO_OPTS);
86 jerry_value_t obj2 = jerry_eval ((const jerry_char_t *) "o={x:1};o", 9, JERRY_PARSE_NO_OPTS);
87 jerry_value_t err1 = jerry_create_error (JERRY_ERROR_SYNTAX, (const jerry_char_t *) "error");
88
89 test_nan_entry_t test_nans[] =
90 {
91 /* Testing addition (+) */
92 T_NAN (JERRY_BIN_OP_ADD, jerry_create_number (3.1), jerry_create_undefined ()),
93 T_NAN (JERRY_BIN_OP_ADD, jerry_create_undefined (), jerry_create_undefined ()),
94 T_NAN (JERRY_BIN_OP_ADD, jerry_create_undefined (), jerry_create_null ()),
95
96 /* Testing subtraction (-), multiplication (*), division (/), remainder (%) */
97 T_ARI (jerry_create_number (3.1), jerry_create_undefined ()),
98 T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_string ((const jerry_char_t *) "bar")),
99 T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_undefined ()),
100 T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_null ()),
101 T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_number (5.0)),
102 T_ARI (jerry_create_undefined (), jerry_create_string ((const jerry_char_t *) "foo")),
103 T_ARI (jerry_create_null (), jerry_create_string ((const jerry_char_t *) "foo")),
104 T_ARI (jerry_create_number (5.0), jerry_create_string ((const jerry_char_t *) "foo")),
105 T_ARI (jerry_create_undefined (), jerry_create_undefined ()),
106 T_ARI (jerry_create_undefined (), jerry_create_null ()),
107 T_ARI (jerry_create_null (), jerry_create_undefined ()),
108 T_ARI (jerry_acquire_value (obj1), jerry_acquire_value (obj1)),
109 T_ARI (jerry_acquire_value (obj1), jerry_acquire_value (obj2)),
110 T_ARI (jerry_acquire_value (obj2), jerry_acquire_value (obj1)),
111 T_ARI (jerry_acquire_value (obj2), jerry_create_undefined ()),
112 T_ARI (jerry_acquire_value (obj1), jerry_create_string ((const jerry_char_t *) "foo")),
113 T_ARI (jerry_acquire_value (obj1), jerry_create_null ()),
114 T_ARI (jerry_acquire_value (obj1), jerry_create_boolean (true)),
115 T_ARI (jerry_acquire_value (obj1), jerry_create_boolean (false)),
116 T_ARI (jerry_acquire_value (obj1), jerry_create_number (5.0)),
117
118 /* Testing division (/) */
119 T_NAN (JERRY_BIN_OP_DIV, jerry_create_boolean (false), jerry_create_boolean (false)),
120 T_NAN (JERRY_BIN_OP_DIV, jerry_create_number (0.0), jerry_create_number (0.0)),
121 T_NAN (JERRY_BIN_OP_DIV, jerry_create_null (), jerry_create_null ()),
122
123 /* Testing remainder (%) */
124 T_NAN (JERRY_BIN_OP_REM, jerry_create_boolean (true), jerry_create_boolean (false)),
125 T_NAN (JERRY_BIN_OP_REM, jerry_create_boolean (false), jerry_create_boolean (false)),
126 T_NAN (JERRY_BIN_OP_REM, jerry_create_number (0.0), jerry_create_number (0.0)),
127 T_NAN (JERRY_BIN_OP_REM, jerry_create_null (), jerry_create_null ()),
128 };
129
130 for (uint32_t idx = 0; idx < sizeof (test_nans) / sizeof (test_nan_entry_t); idx++)
131 {
132 jerry_value_t result = jerry_binary_operation (test_nans[idx].op, test_nans[idx].lhs, test_nans[idx].rhs);
133 TEST_ASSERT (jerry_value_is_number (result));
134
135 double num = jerry_get_number_value (result);
136
137 TEST_ASSERT (num != num);
138
139 jerry_release_value (test_nans[idx].lhs);
140 jerry_release_value (test_nans[idx].rhs);
141 jerry_release_value (result);
142 }
143
144 test_entry_t tests[] =
145 {
146 /* Testing addition (+) */
147 T (JERRY_BIN_OP_ADD, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (10.0)),
148 T (JERRY_BIN_OP_ADD, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (13.1)),
149 T (JERRY_BIN_OP_ADD, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (4.1)),
150 T (JERRY_BIN_OP_ADD,
151 jerry_create_string ((const jerry_char_t *) "foo"),
152 jerry_create_string ((const jerry_char_t *) "bar"),
153 jerry_create_string ((const jerry_char_t *) "foobar")),
154 T (JERRY_BIN_OP_ADD,
155 jerry_create_string ((const jerry_char_t *) "foo"),
156 jerry_create_undefined (),
157 jerry_create_string ((const jerry_char_t *) "fooundefined")),
158 T (JERRY_BIN_OP_ADD,
159 jerry_create_string ((const jerry_char_t *) "foo"),
160 jerry_create_null (),
161 jerry_create_string ((const jerry_char_t *) "foonull")),
162 T (JERRY_BIN_OP_ADD,
163 jerry_create_string ((const jerry_char_t *) "foo"),
164 jerry_create_number (5.0),
165 jerry_create_string ((const jerry_char_t *) "foo5")),
166
167 T (JERRY_BIN_OP_ADD, jerry_create_null (), jerry_create_null (), jerry_create_number (0.0)),
168 T (JERRY_BIN_OP_ADD, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (2.0)),
169 T (JERRY_BIN_OP_ADD, jerry_create_boolean (true), jerry_create_boolean (false), jerry_create_number (1.0)),
170 T (JERRY_BIN_OP_ADD, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (1.0)),
171 T (JERRY_BIN_OP_ADD, jerry_create_boolean (false), jerry_create_boolean (false), jerry_create_number (0.0)),
172 T (JERRY_BIN_OP_ADD,
173 jerry_acquire_value (obj1),
174 jerry_acquire_value (obj1),
175 jerry_create_string ((const jerry_char_t *) "[object Object][object Object]")),
176 T (JERRY_BIN_OP_ADD,
177 jerry_acquire_value (obj1),
178 jerry_acquire_value (obj2),
179 jerry_create_string ((const jerry_char_t *) "[object Object][object Object]")),
180 T (JERRY_BIN_OP_ADD,
181 jerry_acquire_value (obj2),
182 jerry_acquire_value (obj1),
183 jerry_create_string ((const jerry_char_t *) "[object Object][object Object]")),
184 T (JERRY_BIN_OP_ADD,
185 jerry_acquire_value (obj1),
186 jerry_create_null (),
187 jerry_create_string ((const jerry_char_t *) "[object Object]null")),
188 T (JERRY_BIN_OP_ADD,
189 jerry_acquire_value (obj1),
190 jerry_create_undefined (),
191 jerry_create_string ((const jerry_char_t *) "[object Object]undefined")),
192 T (JERRY_BIN_OP_ADD,
193 jerry_acquire_value (obj1),
194 jerry_create_boolean (true),
195 jerry_create_string ((const jerry_char_t *) "[object Object]true")),
196 T (JERRY_BIN_OP_ADD,
197 jerry_acquire_value (obj1),
198 jerry_create_boolean (false),
199 jerry_create_string ((const jerry_char_t *) "[object Object]false")),
200 T (JERRY_BIN_OP_ADD,
201 jerry_acquire_value (obj1),
202 jerry_create_number (5.0),
203 jerry_create_string ((const jerry_char_t *) "[object Object]5")),
204 T (JERRY_BIN_OP_ADD,
205 jerry_acquire_value (obj1),
206 jerry_create_string ((const jerry_char_t *) "foo"),
207 jerry_create_string ((const jerry_char_t *) "[object Object]foo")),
208
209 /* Testing subtraction (-) */
210 T (JERRY_BIN_OP_SUB, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (0.0)),
211 T (JERRY_BIN_OP_SUB, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (-6.9)),
212 T (JERRY_BIN_OP_SUB, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (2.1)),
213 T (JERRY_BIN_OP_SUB, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (0.0)),
214 T (JERRY_BIN_OP_SUB, jerry_create_boolean (true), jerry_create_boolean (false), jerry_create_number (1.0)),
215 T (JERRY_BIN_OP_SUB, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (-1.0)),
216 T (JERRY_BIN_OP_SUB, jerry_create_boolean (false), jerry_create_boolean (false), jerry_create_number (0.0)),
217 T (JERRY_BIN_OP_SUB, jerry_create_null (), jerry_create_null (), jerry_create_number (-0.0)),
218
219 /* Testing multiplication (*) */
220 T (JERRY_BIN_OP_MUL, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (25.0)),
221 T (JERRY_BIN_OP_MUL, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (31)),
222 T (JERRY_BIN_OP_MUL, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (3.1)),
223 T (JERRY_BIN_OP_MUL, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (1.0)),
224 T (JERRY_BIN_OP_MUL, jerry_create_boolean (true), jerry_create_boolean (false), jerry_create_number (0.0)),
225 T (JERRY_BIN_OP_MUL, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (0.0)),
226 T (JERRY_BIN_OP_MUL, jerry_create_boolean (false), jerry_create_boolean (false), jerry_create_number (0.0)),
227 T (JERRY_BIN_OP_MUL, jerry_create_null (), jerry_create_null (), jerry_create_number (0.0)),
228
229 /* Testing division (/) */
230 T (JERRY_BIN_OP_DIV, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (1.0)),
231 T (JERRY_BIN_OP_DIV, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (0.31)),
232 T (JERRY_BIN_OP_DIV, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (3.1)),
233 T (JERRY_BIN_OP_DIV, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (1.0)),
234 T (JERRY_BIN_OP_DIV,
235 jerry_create_boolean (true),
236 jerry_create_boolean (false),
237 jerry_create_number_infinity (false)),
238 T (JERRY_BIN_OP_DIV, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (0.0)),
239
240 /* Testing remainder (%) */
241 T (JERRY_BIN_OP_REM, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (0.0)),
242 T (JERRY_BIN_OP_REM, jerry_create_number (5.0), jerry_create_number (2.0), jerry_create_number (1.0)),
243 T (JERRY_BIN_OP_REM, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (3.1)),
244 T (JERRY_BIN_OP_REM,
245 jerry_create_number (3.1),
246 jerry_create_boolean (true),
247 jerry_create_number (0.10000000000000009)),
248 T (JERRY_BIN_OP_REM, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (0.0)),
249 T (JERRY_BIN_OP_REM, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (0.0)),
250
251 };
252
253 for (uint32_t idx = 0; idx < sizeof (tests) / sizeof (test_entry_t); idx++)
254 {
255 jerry_value_t result = jerry_binary_operation (tests[idx].op, tests[idx].lhs, tests[idx].rhs);
256 TEST_ASSERT (!jerry_value_is_error (result));
257
258 jerry_value_t equals = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL, result, tests[idx].expected);
259 TEST_ASSERT (jerry_value_is_boolean (equals) && jerry_get_boolean_value (equals));
260 jerry_release_value (equals);
261
262 jerry_release_value (tests[idx].lhs);
263 jerry_release_value (tests[idx].rhs);
264 jerry_release_value (tests[idx].expected);
265 jerry_release_value (result);
266 }
267
268 jerry_value_t obj3 = jerry_eval ((const jerry_char_t *) "o={valueOf:function(){throw 5}};o", 33, JERRY_PARSE_NO_OPTS);
269
270 test_error_entry_t error_tests[] =
271 {
272 /* Testing addition (+) */
273 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (err1), jerry_acquire_value (err1)),
274 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (err1), jerry_create_undefined ()),
275 T_ERR (JERRY_BIN_OP_ADD, jerry_create_undefined (), jerry_acquire_value (err1)),
276
277 /* Testing subtraction (-), multiplication (*), division (/), remainder (%) */
278 T_ARI (jerry_acquire_value (err1), jerry_acquire_value (err1)),
279 T_ARI (jerry_acquire_value (err1), jerry_create_undefined ()),
280 T_ARI (jerry_create_undefined (), jerry_acquire_value (err1)),
281
282 /* Testing addition (+) */
283 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_undefined ()),
284 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_null ()),
285 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_boolean (true)),
286 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_boolean (false)),
287 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_acquire_value (obj2)),
288 T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_string ((const jerry_char_t *) "foo")),
289
290 /* Testing subtraction (-), multiplication (*), division (/), remainder (%) */
291 T_ARI (jerry_acquire_value (obj3), jerry_create_undefined ()),
292 T_ARI (jerry_acquire_value (obj3), jerry_create_null ()),
293 T_ARI (jerry_acquire_value (obj3), jerry_create_boolean (true)),
294 T_ARI (jerry_acquire_value (obj3), jerry_create_boolean (false)),
295 T_ARI (jerry_acquire_value (obj3), jerry_acquire_value (obj2)),
296 T_ARI (jerry_acquire_value (obj3), jerry_create_string ((const jerry_char_t *) "foo")),
297 };
298
299 for (uint32_t idx = 0; idx < sizeof (error_tests) / sizeof (test_error_entry_t); idx++)
300 {
301 jerry_value_t result = jerry_binary_operation (tests[idx].op, error_tests[idx].lhs, error_tests[idx].rhs);
302 TEST_ASSERT (jerry_value_is_error (result));
303 jerry_release_value (error_tests[idx].lhs);
304 jerry_release_value (error_tests[idx].rhs);
305 jerry_release_value (result);
306 }
307
308 jerry_release_value (obj1);
309 jerry_release_value (obj2);
310 jerry_release_value (obj3);
311 jerry_release_value (err1);
312
313 jerry_cleanup ();
314 free (ctx_p);
315 }
316