• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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