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 "config.h" 17#include "jerryscript.h" 18#include "jerryscript-port.h" 19#include "jerryscript-port-default.h" 20#include "test-common.h" 21#include <gtest/gtest.h> 22 23/** Test in Proxy on C side. Equivalent test code in JS: 24 25var demo = 0.0; 26 27var target = {}; 28var handler = { 29 get: function (target, name, recv) { 30 assert (typeof (target) === 'object'); 31 assert (name === 'value'); 32 assert (typeof (recv) === 'object'); 33 return demo++; 34 } 35 36 set: function (target, name, value, recv) { 37 assert (typeof (target) === 'object'); 38 assert (name === 'value'); 39 assert (typeof (recv) === 'object'); 40 demo = 55; 41 return demo; 42 } 43}; 44 45var pdemo = new Proxy(target, handler); 46 47assert (pdemo.value === 1.0); 48assert (pdemo.value === 1.0); 49assert (pdemo.value === 2.0); 50 51pdemo.value = 55; 52 53assert (pdemo.value === 56); 54 55pdemo.value = 12; 56 57assert (pdemo.value === 13); 58 */ 59 60static int demo_value = 0; 61 62static jerry_value_t 63handler_get (const jerry_value_t function_obj, /**< function object */ 64 const jerry_value_t this_val, /**< this arg */ 65 const jerry_value_t args_p[], /**< function arguments */ 66 const jerry_length_t args_count) /**< number of function arguments */ 67{ 68 JERRY_UNUSED (function_obj); 69 JERRY_UNUSED (this_val); 70 71 TEST_ASSERT (args_count == 3); 72 TEST_ASSERT (jerry_value_is_object (args_p[0])); /* target */ 73 TEST_ASSERT (jerry_value_is_string (args_p[1])); /* P */ 74 TEST_ASSERT (jerry_value_is_object (args_p[2])); /* receiver */ 75 76 const char expected[] = "value"; 77 char buffer[10]; 78 jerry_size_t copied = jerry_string_to_char_buffer (args_p[1], (jerry_char_t *) buffer, 10); 79 80 TEST_ASSERT (copied == 5); 81 TEST_ASSERT (strncmp (expected, buffer, 5) == 0); 82 83 demo_value++; 84 85 return jerry_create_number (demo_value); 86} /* handler_get */ 87 88static jerry_value_t 89handler_set (const jerry_value_t function_obj, /**< function object */ 90 const jerry_value_t this_val, /**< this arg */ 91 const jerry_value_t args_p[], /**< function arguments */ 92 const jerry_length_t args_count) /**< number of function arguments */ 93{ 94 JERRY_UNUSED (function_obj); 95 JERRY_UNUSED (this_val); 96 JERRY_UNUSED (args_p); 97 JERRY_UNUSED (args_count); 98 99 TEST_ASSERT (args_count == 4); 100 TEST_ASSERT (jerry_value_is_object (args_p[0])); /* target */ 101 TEST_ASSERT (jerry_value_is_string (args_p[1])); /* P */ 102 TEST_ASSERT (jerry_value_is_number (args_p[2])); /* V */ 103 TEST_ASSERT (jerry_value_is_object (args_p[3])); /* receiver */ 104 105 const char expected[] = "value"; 106 char buffer[10]; 107 jerry_size_t copied = jerry_string_to_char_buffer (args_p[1], (jerry_char_t *) buffer, 10); 108 109 TEST_ASSERT (copied == 5); 110 TEST_ASSERT (strncmp (expected, buffer, 5) == 0); 111 112 TEST_ASSERT (jerry_value_is_number (args_p[2])); 113 demo_value = (int) jerry_get_number_value (args_p[2]); 114 115 return jerry_create_number (demo_value); 116} /* handler_set */ 117 118static void 119set_property (jerry_value_t target, /**< target object */ 120 const char *name_p, /**< name of the property */ 121 jerry_value_t value) /**< value of the property */ 122{ 123 jerry_value_t name_val = jerry_create_string ((const jerry_char_t *) name_p); 124 jerry_value_t result_val = jerry_set_property (target, name_val, value); 125 126 TEST_ASSERT (jerry_value_is_boolean (result_val)); 127 TEST_ASSERT (jerry_get_boolean_value (result_val)); 128 jerry_release_value (name_val); 129} /* set_property */ 130 131static jerry_value_t 132get_property (jerry_value_t target, /**< target object */ 133 const char *name_p) /**< name of the property */ 134{ 135 jerry_value_t name_val = jerry_create_string ((const jerry_char_t *) name_p); 136 jerry_value_t result_val = jerry_get_property (target, name_val); 137 138 TEST_ASSERT (!jerry_value_is_error (result_val)); 139 jerry_release_value (name_val); 140 return result_val; 141} /* get_property */ 142 143static void 144set_function (jerry_value_t target, /**< target object */ 145 const char *name_p, /**< name of the function */ 146 jerry_external_handler_t handler_p) /**< function callback */ 147{ 148 jerry_value_t function_val = jerry_create_external_function (handler_p); 149 set_property (target, name_p, function_val); 150 jerry_release_value (function_val); 151} /* set_function */ 152 153class ProxyTest : public testing::Test{ 154public: 155 static void SetUpTestCase() 156 { 157 GTEST_LOG_(INFO) << "ProxyTest SetUpTestCase"; 158 } 159 160 static void TearDownTestCase() 161 { 162 GTEST_LOG_(INFO) << "ProxyTest TearDownTestCase"; 163 } 164 165 void SetUp() override {} 166 void TearDown() override {} 167 168}; 169static constexpr size_t JERRY_SCRIPT_MEM_SIZE = 50 * 1024 * 1024; 170static void* context_alloc_fn(size_t size, void* cb_data) 171{ 172 (void)cb_data; 173 size_t newSize = size > JERRY_SCRIPT_MEM_SIZE ? JERRY_SCRIPT_MEM_SIZE : size; 174 return malloc(newSize); 175} 176HWTEST_F(ProxyTest, Test001, testing::ext::TestSize.Level1) 177{ 178 TEST_INIT (); 179 180 if (!jerry_is_feature_enabled (JERRY_FEATURE_PROXY)) 181 { 182 printf ("Skipping test, Proxy not enabled\n"); 183 } 184 else{ 185 jerry_context_t *ctx_p = jerry_create_context (1024, context_alloc_fn, NULL); 186 jerry_port_default_set_current_context (ctx_p); 187 188 jerry_init (JERRY_INIT_EMPTY); 189 190 jerry_value_t handler = jerry_create_object (); 191 { 192 set_function (handler, "get", handler_get); 193 set_function (handler, "set", handler_set); 194 } 195 196 jerry_value_t target = jerry_create_object (); 197 jerry_value_t proxy = jerry_create_proxy (target, handler); 198 { 199 jerry_value_t global = jerry_get_global_object (); 200 set_property (global, "pdemo", proxy); 201 jerry_release_value (global); 202 } 203 204 const jerry_char_t get_value_src[] = TEST_STRING_LITERAL ("pdemo.value"); 205 jerry_value_t parsed_get_code_val = jerry_parse (NULL, 206 0, 207 get_value_src, 208 sizeof (get_value_src) - 1, 209 JERRY_PARSE_NO_OPTS); 210 TEST_ASSERT (!jerry_value_is_error (parsed_get_code_val)); 211 212 { 213 jerry_value_t res = jerry_run (parsed_get_code_val); 214 TEST_ASSERT (jerry_value_is_number (res)); 215 TEST_ASSERT (jerry_get_number_value (res) == 1.0); 216 jerry_release_value (res); 217 } 218 219 { 220 jerry_value_t res = get_property (proxy, "value"); 221 TEST_ASSERT (jerry_value_is_number (res)); 222 TEST_ASSERT (jerry_get_number_value (res) == 2.0); 223 jerry_release_value (res); 224 } 225 226 { 227 jerry_value_t res = jerry_run (parsed_get_code_val); 228 TEST_ASSERT (jerry_value_is_number (res)); 229 TEST_ASSERT (jerry_get_number_value (res) == 3.0); 230 jerry_release_value (res); 231 } 232 233 const jerry_char_t set_value_src[] = TEST_STRING_LITERAL ("pdemo.value = 55"); 234 jerry_value_t parsed_set_code_val = jerry_parse (NULL, 235 0, 236 set_value_src, 237 sizeof (set_value_src) - 1, 238 JERRY_PARSE_NO_OPTS); 239 TEST_ASSERT (!jerry_value_is_error (parsed_set_code_val)); 240 241 { 242 jerry_value_t res = jerry_run (parsed_set_code_val); 243 TEST_ASSERT (jerry_value_is_number (res)); 244 TEST_ASSERT (jerry_get_number_value (res) == 55); 245 jerry_release_value (res); 246 } 247 248 { 249 jerry_value_t res = jerry_run (parsed_get_code_val); 250 TEST_ASSERT (jerry_value_is_number (res)); 251 TEST_ASSERT (jerry_get_number_value (res) == 56); 252 jerry_release_value (res); 253 } 254 255 { 256 jerry_value_t new_value = jerry_create_number (12); 257 set_property (proxy, "value", new_value); 258 jerry_release_value (new_value); 259 } 260 261 { 262 jerry_value_t res = get_property (proxy, "value"); 263 TEST_ASSERT (jerry_value_is_number (res)); 264 TEST_ASSERT (jerry_get_number_value (res) == 13.0); 265 jerry_release_value (res); 266 } 267 268 jerry_release_value (parsed_set_code_val); 269 jerry_release_value (parsed_get_code_val); 270 jerry_release_value (proxy); 271 jerry_release_value (target); 272 jerry_release_value (handler); 273 274 jerry_cleanup (); 275 free (ctx_p); 276 } 277} 278