1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include <string.h> 17425bb815Sopenharmony_ci 18425bb815Sopenharmony_ci#include "jerryscript.h" 19425bb815Sopenharmony_ci#include "test-common.h" 20425bb815Sopenharmony_ci#include "jerryscript-ext/module.h" 21425bb815Sopenharmony_ci 22425bb815Sopenharmony_ci/* Load a module. */ 23425bb815Sopenharmony_ciconst char eval_string1[] = "require ('my_custom_module');"; 24425bb815Sopenharmony_ci 25425bb815Sopenharmony_ci/* Load a module using a different resolver. */ 26425bb815Sopenharmony_ciconst char eval_string2[] = "require ('differently-handled-module');"; 27425bb815Sopenharmony_ci 28425bb815Sopenharmony_ci/* Load a broken module using the built-in resolver. */ 29425bb815Sopenharmony_ciconst char eval_string3[] = 30425bb815Sopenharmony_ci"(function() {" 31425bb815Sopenharmony_ci" var theError;" 32425bb815Sopenharmony_ci" try {" 33425bb815Sopenharmony_ci" require ('my_broken_module');" 34425bb815Sopenharmony_ci" } catch (anError) {" 35425bb815Sopenharmony_ci" theError = anError;" 36425bb815Sopenharmony_ci" }" 37425bb815Sopenharmony_ci" return (((theError.message === 'Module on_resolve () must not be NULL') &&" 38425bb815Sopenharmony_ci" (theError.moduleName === 'my_broken_module') &&" 39425bb815Sopenharmony_ci" (theError instanceof TypeError)) ? 1 : 0);" 40425bb815Sopenharmony_ci"}) ();"; 41425bb815Sopenharmony_ci 42425bb815Sopenharmony_ci/* Load a non-existent module. */ 43425bb815Sopenharmony_ciconst char eval_string4[] = 44425bb815Sopenharmony_ci"(function() {" 45425bb815Sopenharmony_ci" var theError;" 46425bb815Sopenharmony_ci" try {" 47425bb815Sopenharmony_ci" require ('some_missing_module_xyzzy');" 48425bb815Sopenharmony_ci" } catch (anError) {" 49425bb815Sopenharmony_ci" theError = anError;" 50425bb815Sopenharmony_ci" }" 51425bb815Sopenharmony_ci" return (((theError.message === 'Module not found') &&" 52425bb815Sopenharmony_ci" (theError.moduleName === 'some_missing_module_xyzzy')) ? 1 : 0);" 53425bb815Sopenharmony_ci"}) ();"; 54425bb815Sopenharmony_ci 55425bb815Sopenharmony_ci/* Make sure the result of a module load is cached. */ 56425bb815Sopenharmony_ciconst char eval_string5[] = 57425bb815Sopenharmony_ci"(function() {" 58425bb815Sopenharmony_ci" var x = require('cache-check');" 59425bb815Sopenharmony_ci" var y = require('cache-check');" 60425bb815Sopenharmony_ci" return x === y ? 1 : 0;" 61425bb815Sopenharmony_ci"}) ();"; 62425bb815Sopenharmony_ci 63425bb815Sopenharmony_ci/* Make sure the result of a module load is removed from the cache. */ 64425bb815Sopenharmony_ciconst char eval_string6[] = 65425bb815Sopenharmony_ci"(function() {" 66425bb815Sopenharmony_ci" var x = require('cache-check');" 67425bb815Sopenharmony_ci" clear_require_cache('cache-check');" 68425bb815Sopenharmony_ci" var y = require('cache-check');" 69425bb815Sopenharmony_ci" return x !== y ? 1 : 0;" 70425bb815Sopenharmony_ci"}) ();"; 71425bb815Sopenharmony_ci 72425bb815Sopenharmony_ci/* Make sure the entire cache is cleared. */ 73425bb815Sopenharmony_ciconst char eval_string7[] = 74425bb815Sopenharmony_ci"(function() {" 75425bb815Sopenharmony_ci" var x = require('cache-check');" 76425bb815Sopenharmony_ci" clear_require_cache(undefined);" 77425bb815Sopenharmony_ci" var y = require('cache-check');" 78425bb815Sopenharmony_ci" return x !== y ? 1 : 0;" 79425bb815Sopenharmony_ci"}) ();"; 80425bb815Sopenharmony_ci 81425bb815Sopenharmony_ci/* 82425bb815Sopenharmony_ci * Define a resolver for a module named "differently-handled-module" to check that custom resolvers work. 83425bb815Sopenharmony_ci */ 84425bb815Sopenharmony_cistatic bool 85425bb815Sopenharmony_ciresolve_differently_handled_module (const jerry_value_t name, 86425bb815Sopenharmony_ci jerry_value_t *result) 87425bb815Sopenharmony_ci{ 88425bb815Sopenharmony_ci jerry_size_t name_size = jerry_get_utf8_string_size (name); 89425bb815Sopenharmony_ci JERRY_VLA (jerry_char_t, name_string, name_size); 90425bb815Sopenharmony_ci jerry_string_to_utf8_char_buffer (name, name_string, name_size); 91425bb815Sopenharmony_ci 92425bb815Sopenharmony_ci if (!strncmp ((char *) name_string, "differently-handled-module", name_size)) 93425bb815Sopenharmony_ci { 94425bb815Sopenharmony_ci (*result) = jerry_create_number (29); 95425bb815Sopenharmony_ci return true; 96425bb815Sopenharmony_ci } 97425bb815Sopenharmony_ci return false; 98425bb815Sopenharmony_ci} /* resolve_differently_handled_module */ 99425bb815Sopenharmony_ci 100425bb815Sopenharmony_cistatic jerryx_module_resolver_t differently_handled_module_resolver = 101425bb815Sopenharmony_ci{ 102425bb815Sopenharmony_ci NULL, 103425bb815Sopenharmony_ci resolve_differently_handled_module 104425bb815Sopenharmony_ci}; 105425bb815Sopenharmony_ci 106425bb815Sopenharmony_ci/* 107425bb815Sopenharmony_ci * Define module "cache-check" via its own resolver as an empty object. Since objects are accessible only via references 108425bb815Sopenharmony_ci * we can strictly compare the object returned on subsequent attempts at loading "cache-check" with the object returned 109425bb815Sopenharmony_ci * on the first attempt and establish that the two are in fact the same object - which in turn shows that caching works. 110425bb815Sopenharmony_ci */ 111425bb815Sopenharmony_cistatic bool 112425bb815Sopenharmony_cicache_check (const jerry_value_t name, 113425bb815Sopenharmony_ci jerry_value_t *result) 114425bb815Sopenharmony_ci{ 115425bb815Sopenharmony_ci jerry_size_t name_size = jerry_get_utf8_string_size (name); 116425bb815Sopenharmony_ci JERRY_VLA (jerry_char_t, name_string, name_size); 117425bb815Sopenharmony_ci jerry_string_to_utf8_char_buffer (name, name_string, name_size); 118425bb815Sopenharmony_ci 119425bb815Sopenharmony_ci if (!strncmp ((char *) name_string, "cache-check", name_size)) 120425bb815Sopenharmony_ci { 121425bb815Sopenharmony_ci (*result) = jerry_create_object (); 122425bb815Sopenharmony_ci return true; 123425bb815Sopenharmony_ci } 124425bb815Sopenharmony_ci return false; 125425bb815Sopenharmony_ci} /* cache_check */ 126425bb815Sopenharmony_ci 127425bb815Sopenharmony_cistatic jerryx_module_resolver_t cache_check_resolver = 128425bb815Sopenharmony_ci{ 129425bb815Sopenharmony_ci NULL, 130425bb815Sopenharmony_ci cache_check 131425bb815Sopenharmony_ci}; 132425bb815Sopenharmony_ci 133425bb815Sopenharmony_cistatic const jerryx_module_resolver_t *resolvers[3] = 134425bb815Sopenharmony_ci{ 135425bb815Sopenharmony_ci &jerryx_module_native_resolver, 136425bb815Sopenharmony_ci &differently_handled_module_resolver, 137425bb815Sopenharmony_ci &cache_check_resolver 138425bb815Sopenharmony_ci}; 139425bb815Sopenharmony_ci 140425bb815Sopenharmony_cistatic jerry_value_t 141425bb815Sopenharmony_cihandle_clear_require_cache (const jerry_value_t js_function, 142425bb815Sopenharmony_ci const jerry_value_t this_val, 143425bb815Sopenharmony_ci const jerry_value_t args_p[], 144425bb815Sopenharmony_ci const jerry_length_t args_count) 145425bb815Sopenharmony_ci{ 146425bb815Sopenharmony_ci (void) js_function; 147425bb815Sopenharmony_ci (void) this_val; 148425bb815Sopenharmony_ci (void) args_count; 149425bb815Sopenharmony_ci 150425bb815Sopenharmony_ci TEST_ASSERT (args_count == 1); 151425bb815Sopenharmony_ci jerryx_module_clear_cache (args_p[0], resolvers, 3); 152425bb815Sopenharmony_ci 153425bb815Sopenharmony_ci return 0; 154425bb815Sopenharmony_ci} /* handle_clear_require_cache */ 155425bb815Sopenharmony_ci 156425bb815Sopenharmony_cistatic jerry_value_t 157425bb815Sopenharmony_cihandle_require (const jerry_value_t js_function, 158425bb815Sopenharmony_ci const jerry_value_t this_val, 159425bb815Sopenharmony_ci const jerry_value_t args_p[], 160425bb815Sopenharmony_ci const jerry_length_t args_count) 161425bb815Sopenharmony_ci{ 162425bb815Sopenharmony_ci (void) js_function; 163425bb815Sopenharmony_ci (void) this_val; 164425bb815Sopenharmony_ci (void) args_count; 165425bb815Sopenharmony_ci 166425bb815Sopenharmony_ci jerry_value_t return_value = 0; 167425bb815Sopenharmony_ci 168425bb815Sopenharmony_ci TEST_ASSERT (args_count == 1); 169425bb815Sopenharmony_ci return_value = jerryx_module_resolve (args_p[0], resolvers, 3); 170425bb815Sopenharmony_ci 171425bb815Sopenharmony_ci return return_value; 172425bb815Sopenharmony_ci} /* handle_require */ 173425bb815Sopenharmony_ci 174425bb815Sopenharmony_cistatic void 175425bb815Sopenharmony_ciassert_number (jerry_value_t js_value, double expected_result) 176425bb815Sopenharmony_ci{ 177425bb815Sopenharmony_ci TEST_ASSERT (!jerry_value_is_error (js_value)); 178425bb815Sopenharmony_ci TEST_ASSERT (jerry_get_number_value (js_value) == expected_result); 179425bb815Sopenharmony_ci} /* assert_number */ 180425bb815Sopenharmony_ci 181425bb815Sopenharmony_cistatic void 182425bb815Sopenharmony_cieval_one (const char *the_string, double expected_result) 183425bb815Sopenharmony_ci{ 184425bb815Sopenharmony_ci jerry_value_t js_eval_result = jerry_eval ((const jerry_char_t *) the_string, 185425bb815Sopenharmony_ci strlen (the_string), 186425bb815Sopenharmony_ci JERRY_PARSE_STRICT_MODE); 187425bb815Sopenharmony_ci assert_number (js_eval_result, expected_result); 188425bb815Sopenharmony_ci jerry_release_value (js_eval_result); 189425bb815Sopenharmony_ci} /* eval_one */ 190425bb815Sopenharmony_ci 191425bb815Sopenharmony_ci#ifndef ENABLE_INIT_FINI 192425bb815Sopenharmony_ciextern void my_broken_module_register (void); 193425bb815Sopenharmony_ciextern void my_custom_module_register (void); 194425bb815Sopenharmony_ci#endif /* !ENABLE_INIT_FINI */ 195425bb815Sopenharmony_ci 196425bb815Sopenharmony_ciint 197425bb815Sopenharmony_cimain (int argc, char **argv) 198425bb815Sopenharmony_ci{ 199425bb815Sopenharmony_ci (void) argc; 200425bb815Sopenharmony_ci (void) argv; 201425bb815Sopenharmony_ci jerry_value_t js_global = 0, js_function = 0, js_property_name = 0; 202425bb815Sopenharmony_ci jerry_value_t res; 203425bb815Sopenharmony_ci 204425bb815Sopenharmony_ci#ifndef ENABLE_INIT_FINI 205425bb815Sopenharmony_ci my_broken_module_register (); 206425bb815Sopenharmony_ci my_custom_module_register (); 207425bb815Sopenharmony_ci#endif /* !ENABLE_INIT_FINI */ 208425bb815Sopenharmony_ci 209425bb815Sopenharmony_ci jerry_init (JERRY_INIT_EMPTY); 210425bb815Sopenharmony_ci 211425bb815Sopenharmony_ci js_global = jerry_get_global_object (); 212425bb815Sopenharmony_ci 213425bb815Sopenharmony_ci js_function = jerry_create_external_function (handle_require); 214425bb815Sopenharmony_ci js_property_name = jerry_create_string ((const jerry_char_t *) "require"); 215425bb815Sopenharmony_ci res = jerry_set_property (js_global, js_property_name, js_function); 216425bb815Sopenharmony_ci TEST_ASSERT (!jerry_value_is_error (res)); 217425bb815Sopenharmony_ci TEST_ASSERT (jerry_value_is_boolean (res) && jerry_get_boolean_value (res)); 218425bb815Sopenharmony_ci jerry_release_value (res); 219425bb815Sopenharmony_ci jerry_release_value (js_property_name); 220425bb815Sopenharmony_ci jerry_release_value (js_function); 221425bb815Sopenharmony_ci 222425bb815Sopenharmony_ci js_function = jerry_create_external_function (handle_clear_require_cache); 223425bb815Sopenharmony_ci js_property_name = jerry_create_string ((const jerry_char_t *) "clear_require_cache"); 224425bb815Sopenharmony_ci res = jerry_set_property (js_global, js_property_name, js_function); 225425bb815Sopenharmony_ci TEST_ASSERT (!jerry_value_is_error (res)); 226425bb815Sopenharmony_ci TEST_ASSERT (jerry_value_is_boolean (res) && jerry_get_boolean_value (res)); 227425bb815Sopenharmony_ci jerry_release_value (res); 228425bb815Sopenharmony_ci jerry_release_value (js_property_name); 229425bb815Sopenharmony_ci jerry_release_value (js_function); 230425bb815Sopenharmony_ci 231425bb815Sopenharmony_ci jerry_release_value (js_global); 232425bb815Sopenharmony_ci 233425bb815Sopenharmony_ci eval_one (eval_string1, 42); 234425bb815Sopenharmony_ci eval_one (eval_string2, 29); 235425bb815Sopenharmony_ci eval_one (eval_string3, 1); 236425bb815Sopenharmony_ci eval_one (eval_string4, 1); 237425bb815Sopenharmony_ci eval_one (eval_string5, 1); 238425bb815Sopenharmony_ci eval_one (eval_string6, 1); 239425bb815Sopenharmony_ci eval_one (eval_string7, 1); 240425bb815Sopenharmony_ci 241425bb815Sopenharmony_ci jerry_cleanup (); 242425bb815Sopenharmony_ci} /* main */ 243