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 37typedef 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 45typedef struct 46{ 47 jerry_binary_operation_t op; 48 jerry_value_t lhs; 49 jerry_value_t rhs; 50} test_nan_entry_t; 51 52typedef test_nan_entry_t test_error_entry_t; 53class ApiBinaryOperationsArithmeticsTest : public testing::Test{ 54public: 55 static void SetUpTestCase() 56 { 57 GTEST_LOG_(INFO) << "ApiBinaryOperationsArithmeticsTest SetUpTestCase"; 58 } 59 60 static void TearDownTestCase() 61 { 62 GTEST_LOG_(INFO) << "ApiBinaryOperationsArithmeticsTest TearDownTestCase"; 63 } 64 65 void SetUp() override {} 66 void TearDown() override {} 67 68}; 69 70static constexpr size_t JERRY_SCRIPT_MEM_SIZE = 50 * 1024 * 1024; 71static 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} 77HWTEST_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