From af07a2141ad3951e146691a87fce25702a954c08 Mon Sep 17 00:00:00 2001 From: Zidong Jiang <zidong.jiang@intel.com> Date: Tue, 2 May 2017 14:19:17 +0800 Subject: [PATCH] Add promise C API related issue: 1794 JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang zidong.jiang@intel.com --- docs/02.API-REFERENCE.md | 138 ++++++++++++++- .../builtin-objects/ecma-builtin-promise.c | 2 +- jerry-core/ecma/operations/ecma-jobqueue.c | 15 +- .../ecma/operations/ecma-promise-object.c | 31 +++- .../ecma/operations/ecma-promise-object.h | 15 +- jerry-core/jerry.c | 78 +++++++++ jerry-core/jerryscript.h | 7 + jerry-core/lit/lit-magic-strings.h | 2 + tests/unit-core/CMakeLists.txt | 4 +- tests/unit-core/test-promise.c | 162 ++++++++++++++++++ tools/run-tests.py | 4 +- 11 files changed, 435 insertions(+), 23 deletions(-) create mode 100644 tests/unit-core/test-promise.c diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md index 8cf416e2c0..06b2a2e58f 100644 --- a/docs/02.API-REFERENCE.md +++ b/docs/02.API-REFERENCE.md @@ -1072,6 +1072,47 @@ jerry_value_is_object (const jerry_value_t value) - [jerry_release_value](#jerry_release_value) +## jerry_value_is_promise + +**Summary** + +Returns whether the given `jerry_value_t` is a promise value. + +*Note*: This API depends on the ES2015-subset profile. + +**Prototype** + +```c +bool +jerry_value_is_promise (const jerry_value_t value) +``` + +- `value` - api value +- return value + - true, if the given `jerry_value_t` is a promise + - false, otherwise + +**Example** + +```c +{ + jerry_value_t value; + ... // create or acquire value + + if (jerry_value_is_promise (value)) + { + ... + } + + jerry_release_value (value); +} +``` + +**See also** + +- [jerry_release_value](#jerry_release_value) + + ## jerry_value_is_string **Summary** @@ -1980,6 +2021,64 @@ jerry_value_to_string (const jerry_value_t value); - [jerry_value_to_primitive](#jerry_value_to_primitive) +# Functions for promise objects + +These APIs all depends on the ES2015-subset profile. + +## jerry_resolve_or_reject_promise + +**Summary** + +Resolve or reject the promise with an argument. + +**Prototype** + +```c +jerry_value_t +jerry_resolve_or_reject_promise (jerry_value_t promise, + jerry_value_t argument, + bool is_resolve) +``` + +- `promise` - the promise value +- `argument` - the argument for resolve or reject +- `is_resolve` - whether the promise should be resolved or rejected +- return value + - undefined jerry value - resolve or reject successed + - jerry value with error flag - otherwise + +**Example** + +```c +{ + jerry_value_t promise = ... // acquire/create a promise object. + + ... + + bool is_resolve = ... // whether the promise should be resolved or rejected + jerry_value_t argument = ... // prepare the argumnent for the resolve or reject. + + jerry_value_t is_ok = jerry_resolve_or_reject_promise (promise, + argument, + is_resolve); + + if (jerry_value_has_error_flag (is_ok)) + { + // handle the error. + } + + jerry_release_value (is_ok); + jerry_release_value (argument); + jerry_release_value (promise); +} +``` + +**See also** + +- [jerry_release_value](#jerry_release_value) +- [jerry_value_has_error_flag](#jerry_value_has_error_flag) + + # Acquire and release API values ## jerry_acquire_value @@ -2425,6 +2524,41 @@ jerry_create_object (void); - [jerry_release_value](#jerry_release_value) +## jerry_create_promise + +**Summary** + +Create an empty promise object which can be resolved or rejected later +by calling jerry_resolve_or_reject_promise. + +*Note*: This API depends on the ES2015-subset profile. + +**Prototype** + +```c +jerry_value_t +jerry_create_promise (void) +``` + +- return value - value of the newly created promise + +**Example** + +```c +{ + jerry_value_t p = jerry_create_promise (); + + ...// usage of the promise + + jerry_release_value (p); +} + +**See also** + +- [jerry_resolve_or_reject_promise](#jerry_resolve_or_reject_promise) +- [jerry_release_value](#jerry_release_value) + + ## jerry_create_string **Summary** @@ -3528,7 +3662,7 @@ static const jerry_object_native_info_t native_obj_type_info = { // The type of this's native pointer matches what is expected. // Only now is it safe to cast to native_obj_t * and dereference the - // pointer: + // pointer: native_obj_t *native_obj = native_p; native_obj->bar = ...; // Safe to access now! } @@ -3582,7 +3716,7 @@ jerry_set_object_native_pointer (const jerry_value_t obj_val, **Example** See [jerry_get_object_native_pointer](#jerry_get_object_native_pointer) for a -best-practice example. +best-practice example. **See also** diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c b/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c index 24cb4de001..f8e4ca4ed3 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c @@ -683,7 +683,7 @@ ecma_builtin_promise_dispatch_construct (const ecma_value_t *arguments_list_p, / return ecma_raise_type_error (ECMA_ERR_MSG ("First parameter must be callable.")); } - return ecma_op_create_promise_object (arguments_list_p[0], true); + return ecma_op_create_promise_object (arguments_list_p[0], ECMA_PROMISE_EXECUTOR_FUNCTION); } /* ecma_builtin_promise_dispatch_construct */ /** diff --git a/jerry-core/ecma/operations/ecma-jobqueue.c b/jerry-core/ecma/operations/ecma-jobqueue.c index afe8dcb61e..1fc69fa3bc 100644 --- a/jerry-core/ecma/operations/ecma-jobqueue.c +++ b/jerry-core/ecma/operations/ecma-jobqueue.c @@ -223,10 +223,14 @@ ecma_process_promise_resolve_thenable_job (void *obj_p) /**< the job to be opera { ecma_job_promise_resolve_thenable_t *job_p = (ecma_job_promise_resolve_thenable_t *) obj_p; ecma_object_t *promise_p = ecma_get_object_from_value (job_p->promise); - ecma_promise_resolving_functions_t *funcs; - funcs = ecma_promise_create_resolving_functions (promise_p); + ecma_string_t str_resolve, str_reject; + ecma_init_ecma_magic_string (&str_resolve, LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION); + ecma_init_ecma_magic_string (&str_reject, LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION); - ecma_value_t argv[] = { funcs->resolve, funcs->reject }; + ecma_value_t resolve = ecma_op_object_get (promise_p, &str_resolve); + ecma_value_t reject = ecma_op_object_get (promise_p, &str_reject); + + ecma_value_t argv[] = { resolve, reject }; ecma_value_t ret; ecma_value_t then_call_result = ecma_op_function_call (ecma_get_object_from_value (job_p->then), job_p->thenable, @@ -237,7 +241,7 @@ ecma_process_promise_resolve_thenable_job (void *obj_p) /**< the job to be opera if (ECMA_IS_VALUE_ERROR (then_call_result)) { - ret = ecma_op_function_call (ecma_get_object_from_value (funcs->reject), + ret = ecma_op_function_call (ecma_get_object_from_value (reject), ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), &then_call_result, 1); @@ -245,7 +249,8 @@ ecma_process_promise_resolve_thenable_job (void *obj_p) /**< the job to be opera ecma_free_value (then_call_result); } - ecma_promise_free_resolving_functions (funcs); + ecma_free_value (resolve); + ecma_free_value (reject); ecma_free_promise_resolve_thenable_job (job_p); return ret; diff --git a/jerry-core/ecma/operations/ecma-promise-object.c b/jerry-core/ecma/operations/ecma-promise-object.c index 0dc43ca270..321e351d8d 100644 --- a/jerry-core/ecma/operations/ecma-promise-object.c +++ b/jerry-core/ecma/operations/ecma-promise-object.c @@ -404,7 +404,7 @@ ecma_call_builtin_executor (ecma_object_t *executor_p, /**< the executor object * * @return pointer to the resolving functions */ -ecma_promise_resolving_functions_t * +static ecma_promise_resolving_functions_t * ecma_promise_create_resolving_functions (ecma_object_t *object_p) /**< the promise object */ { /* 1. */ @@ -455,7 +455,7 @@ ecma_promise_create_resolving_functions (ecma_object_t *object_p) /**< the promi /** * Free the heap and the member of the resolving functions. */ -void +static void ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs) /**< points to the functions */ { ecma_free_value (funcs->resolve); @@ -473,7 +473,7 @@ ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs */ ecma_value_t ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function or object */ - bool is_func) /**< indicates whether executor is a function */ + ecma_promise_executor_type_t type) /**< indicates the type of executor */ { /* 3. */ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE_PROTOTYPE); @@ -496,10 +496,22 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function /* 8. */ ecma_promise_resolving_functions_t *funcs = ecma_promise_create_resolving_functions (object_p); + ecma_string_t str_resolve, str_reject; + ecma_init_ecma_magic_string (&str_resolve, LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION); + ecma_init_ecma_magic_string (&str_reject, LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION); + ecma_op_object_put (object_p, + &str_resolve, + funcs->resolve, + false); + ecma_op_object_put (object_p, + &str_reject, + funcs->reject, + false); + /* 9. */ - ecma_value_t completion; + ecma_value_t completion = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); - if (is_func) + if (type == ECMA_PROMISE_EXECUTOR_FUNCTION) { JERRY_ASSERT (ecma_op_is_callable (executor)); @@ -509,7 +521,7 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function argv, 2); } - else + else if (type == ECMA_PROMISE_EXECUTOR_OBJECT) { JERRY_ASSERT (ecma_is_value_object (executor)); @@ -517,6 +529,11 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function funcs->resolve, funcs->reject); } + else + { + JERRY_ASSERT (type == ECMA_PROMISE_EXECUTOR_EMPTY); + JERRY_UNUSED (executor); + } ecma_value_t status = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); @@ -572,7 +589,7 @@ ecma_promise_new_capability (void) false); /* 6. */ - ecma_value_t promise = ecma_op_create_promise_object (executor, false); + ecma_value_t promise = ecma_op_create_promise_object (executor, ECMA_PROMISE_EXECUTOR_OBJECT); /* 10. */ ecma_op_object_put (capability_p, diff --git a/jerry-core/ecma/operations/ecma-promise-object.h b/jerry-core/ecma/operations/ecma-promise-object.h index 9873f26571..c4422bd571 100644 --- a/jerry-core/ecma/operations/ecma-promise-object.h +++ b/jerry-core/ecma/operations/ecma-promise-object.h @@ -37,6 +37,16 @@ typedef enum ECMA_PROMISE_STATE__COUNT /**< number of states */ } ecma_promise_state_t; +/** + * Indicates the type of the executor in promise construct. + */ +typedef enum +{ + ECMA_PROMISE_EXECUTOR_FUNCTION, /**< the executor is a function, it is for the usual constructor */ + ECMA_PROMISE_EXECUTOR_OBJECT, /**< the executor is an object, it is for the `then` routine */ + ECMA_PROMISE_EXECUTOR_EMPTY /**< the executor is empty, it is for external C API */ +} ecma_promise_executor_type_t; + /** * Description of the promise resolving functions. */ @@ -81,10 +91,7 @@ void ecma_promise_set_result (ecma_object_t *obj_p, ecma_value_t result); uint8_t ecma_promise_get_state (ecma_object_t *obj_p); void ecma_promise_set_state (ecma_object_t *obj_p, uint8_t state); ecma_value_t -ecma_op_create_promise_object (ecma_value_t executor, bool is_func); -ecma_promise_resolving_functions_t * -ecma_promise_create_resolving_functions (ecma_object_t *obj_p); -void ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs); +ecma_op_create_promise_object (ecma_value_t executor, ecma_promise_executor_type_t type); ecma_value_t ecma_promise_new_capability (void); ecma_value_t ecma_promise_then (ecma_value_t promise, diff --git a/jerry-core/jerry.c b/jerry-core/jerry.c index fcca46bfd2..43fcc16d61 100644 --- a/jerry-core/jerry.c +++ b/jerry-core/jerry.c @@ -29,6 +29,7 @@ #include "ecma-literal-storage.h" #include "ecma-objects.h" #include "ecma-objects-general.h" +#include "ecma-promise-object.h" #include "jcontext.h" #include "jerryscript.h" #include "jerry-debugger.h" @@ -2175,6 +2176,83 @@ jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, /**< per #endif /* JERRY_VM_EXEC_STOP */ } /* jerry_set_vm_exec_stop_callback */ +#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN + +/** + * Check if the specified value is promise. + * + * @return true - if the specified value is promise, + * false - otherwise + */ +bool +jerry_value_is_promise (const jerry_value_t value) /**< api value */ +{ + jerry_assert_api_available (); + + return (ecma_is_value_object (value) + && ecma_is_promise (ecma_get_object_from_value (value))); +} /* jerry_value_is_promise */ + +/** + * Create an empty Promise object which can be resolve/reject later + * by calling jerry_resolve_or_reject_promise. + * + * Note: + * returned value must be freed with jerry_release_value, when it is no longer needed. + * + * @return value of the created object + */ +jerry_value_t +jerry_create_promise (void) +{ + jerry_assert_api_available (); + + return ecma_op_create_promise_object (ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY), ECMA_PROMISE_EXECUTOR_EMPTY); +} /* jerry_create_promise */ + +/** + * Resolve or reject the promise with an argument. + * + * @return undefined value - if success + * value marked with error flag - otherwise + */ +jerry_value_t +jerry_resolve_or_reject_promise (jerry_value_t promise, /**< the promise value */ + jerry_value_t argument, /**< the argument */ + bool is_resolve) /**< whether the promise should be resolved or rejected */ +{ + jerry_assert_api_available (); + + if (!ecma_is_value_object (promise) || !ecma_is_promise (ecma_get_object_from_value (promise))) + { + return ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)); + } + + ecma_string_t str; + + if (is_resolve) + { + ecma_init_ecma_magic_string (&str, LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION); + } + else + { + ecma_init_ecma_magic_string (&str, LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION); + } + + ecma_value_t function = ecma_op_object_get (ecma_get_object_from_value (promise), &str); + + ecma_value_t ret = ecma_op_function_call (ecma_get_object_from_value (function), + ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), + &argument, + 1); + + ecma_free_value (function); + + return ret; +} /* jerry_resolve_or_reject_promise */ + +#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */ + /** * @} */ diff --git a/jerry-core/jerryscript.h b/jerry-core/jerryscript.h index be9d4a53e3..f4a9fbc26d 100644 --- a/jerry-core/jerryscript.h +++ b/jerry-core/jerryscript.h @@ -251,6 +251,7 @@ bool jerry_value_is_function (const jerry_value_t value); bool jerry_value_is_number (const jerry_value_t value); bool jerry_value_is_null (const jerry_value_t value); bool jerry_value_is_object (const jerry_value_t value); +bool jerry_value_is_promise (const jerry_value_t value); bool jerry_value_is_string (const jerry_value_t value); bool jerry_value_is_undefined (const jerry_value_t value); @@ -332,6 +333,7 @@ jerry_value_t jerry_create_number_infinity (bool sign); jerry_value_t jerry_create_number_nan (void); jerry_value_t jerry_create_null (void); jerry_value_t jerry_create_object (void); +jerry_value_t jerry_create_promise (void); jerry_value_t jerry_create_string_from_utf8 (const jerry_char_t *str_p); jerry_value_t jerry_create_string_sz_from_utf8 (const jerry_char_t *str_p, jerry_size_t str_size); jerry_value_t jerry_create_string (const jerry_char_t *str_p); @@ -387,6 +389,11 @@ void jerry_set_object_native_pointer (const jerry_value_t obj_val, bool jerry_foreach_object_property (const jerry_value_t obj_val, jerry_object_property_foreach_t foreach_p, void *user_data_p); +/** + * Promise resolve/reject functions. + */ +jerry_value_t jerry_resolve_or_reject_promise (jerry_value_t promise, jerry_value_t argument, bool is_resolve); + /** * Input validator functions. */ diff --git a/jerry-core/lit/lit-magic-strings.h b/jerry-core/lit/lit-magic-strings.h index fc1752c329..940330e1d5 100644 --- a/jerry-core/lit/lit-magic-strings.h +++ b/jerry-core/lit/lit-magic-strings.h @@ -38,6 +38,8 @@ typedef enum LIT_INTERNAL_MAGIC_STRING_PROMISE = LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**< [[Promise]] of promise * reject or resolve functions */ LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED, /**< [[AlreadyResolved]] of promise reject or resolve functions */ + LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION, /**< the resolve funtion of the promise object */ + LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION, /**< the reject function of the promise object */ LIT_NEED_MARK_MAGIC_STRING__COUNT, /**< number of internal magic strings which will be used as properties' names, * and the properties need to be marked during gc. */ LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE = LIT_NEED_MARK_MAGIC_STRING__COUNT, /**< native handle package diff --git a/tests/unit-core/CMakeLists.txt b/tests/unit-core/CMakeLists.txt index 3ffaaa394a..60053486ee 100644 --- a/tests/unit-core/CMakeLists.txt +++ b/tests/unit-core/CMakeLists.txt @@ -19,8 +19,8 @@ if (NOT IS_ABSOLUTE ${FEATURE_PROFILE}) set(FEATURE_PROFILE "${CMAKE_SOURCE_DIR}/jerry-core/profiles/${FEATURE_PROFILE}.profile") endif() -if(NOT ${FEATURE_PROFILE} STREQUAL "${CMAKE_SOURCE_DIR}/jerry-core/profiles/es5.1.profile") - message(FATAL_ERROR "FEATURE_PROFILE='${FEATURE_PROFILE}' isn't supported with UNITTESTS=ON") +if(${FEATURE_PROFILE} STREQUAL "${CMAKE_SOURCE_DIR}/jerry-core/profiles/minimal.profile") + message(FATAL_ERROR "minimal profile isn't supported in unit-core") endif() # Unit tests main modules diff --git a/tests/unit-core/test-promise.c b/tests/unit-core/test-promise.c new file mode 100644 index 0000000000..117ec1416a --- /dev/null +++ b/tests/unit-core/test-promise.c @@ -0,0 +1,162 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "jerryscript.h" +#include "jerryscript-port.h" +#include "jerryscript-port-default.h" +#include "test-common.h" + +#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN + +const char *test_source = ( + "var p1 = create_promise1();" + "var p2 = create_promise2();" + "p1.then(function(x) { " + " assert(x==='resolved'); " + "}); " + "p2.catch(function(x) { " + " assert(x==='rejected'); " + "}); " + ); + +static int count_in_assert = 0; +static jerry_value_t my_promise1; +static jerry_value_t my_promise2; +const jerry_char_t s1[] = "resolved"; +const jerry_char_t s2[] = "rejected"; + +static jerry_value_t +create_promise1_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */ + const jerry_value_t this_val __attribute__((unused)), /**< this value */ + const jerry_value_t args_p[] __attribute__((unused)), /**< arguments list */ + const jerry_length_t args_cnt __attribute__((unused))) /**< arguments length */ +{ + jerry_value_t ret = jerry_create_promise (); + my_promise1 = jerry_acquire_value (ret); + + return ret; +} /* create_promise1_handler */ + +static jerry_value_t +create_promise2_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */ + const jerry_value_t this_val __attribute__((unused)), /**< this value */ + const jerry_value_t args_p[] __attribute__((unused)), /**< arguments list */ + const jerry_length_t args_cnt __attribute__((unused))) /**< arguments length */ +{ + jerry_value_t ret = jerry_create_promise (); + my_promise2 = jerry_acquire_value (ret); + + return ret; +} /* create_promise2_handler */ + +static jerry_value_t +assert_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */ + const jerry_value_t this_p __attribute__((unused)), /**< this arg */ + const jerry_value_t args_p[], /**< function arguments */ + const jerry_length_t args_cnt) /**< number of function arguments */ +{ + count_in_assert++; + + if (args_cnt == 1 + && jerry_value_is_boolean (args_p[0]) + && jerry_get_boolean_value (args_p[0])) + { + return jerry_create_boolean (true); + } + else + { + TEST_ASSERT (false); + } +} /* assert_handler */ + +/** + * Register a JavaScript function in the global object. + */ +static void +register_js_function (const char *name_p, /**< name of the function */ + jerry_external_handler_t handler_p) /**< function callback */ +{ + jerry_value_t global_obj_val = jerry_get_global_object (); + + jerry_value_t function_val = jerry_create_external_function (handler_p); + jerry_value_t function_name_val = jerry_create_string ((const jerry_char_t *) name_p); + jerry_value_t result_val = jerry_set_property (global_obj_val, function_name_val, function_val); + + jerry_release_value (function_name_val); + jerry_release_value (function_val); + jerry_release_value (global_obj_val); + + jerry_release_value (result_val); +} /* register_js_function */ + +int +main (void) +{ + jerry_port_default_jobqueue_init (); + jerry_init (JERRY_INIT_EMPTY); + + register_js_function ("create_promise1", create_promise1_handler); + register_js_function ("create_promise2", create_promise2_handler); + register_js_function ("assert", assert_handler); + + jerry_value_t parsed_code_val = jerry_parse ((jerry_char_t *) test_source, strlen (test_source), false); + TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val)); + + jerry_value_t res = jerry_run (parsed_code_val); + TEST_ASSERT (!jerry_value_has_error_flag (res)); + + jerry_release_value (res); + jerry_release_value (parsed_code_val); + + /* Test jerry_create_promise and jerry_value_is_promise. */ + TEST_ASSERT (jerry_value_is_promise (my_promise1)); + TEST_ASSERT (jerry_value_is_promise (my_promise2)); + + TEST_ASSERT (count_in_assert == 0); + + /* Test jerry_resolve_or_reject_promise. */ + jerry_value_t str_resolve = jerry_create_string (s1); + jerry_value_t str_reject = jerry_create_string (s2); + + jerry_resolve_or_reject_promise (my_promise1, str_resolve, true); + jerry_resolve_or_reject_promise (my_promise2, str_reject, false); + + /* The resolve/reject function should be invalid after the promise has the result. */ + jerry_resolve_or_reject_promise (my_promise2, str_resolve, true); + jerry_resolve_or_reject_promise (my_promise1, str_reject, false); + + /* Run the jobqueue. */ + res = jerry_port_default_jobqueue_run (); + + TEST_ASSERT (!jerry_value_has_error_flag (res)); + TEST_ASSERT (count_in_assert == 2); + + jerry_release_value (my_promise1); + jerry_release_value (my_promise2); + jerry_release_value (str_resolve); + jerry_release_value (str_reject); + + jerry_cleanup (); +} /* main */ + +#else /* CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */ + +int +main (void) +{ + return 0; +} /* main */ + +#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */ diff --git a/tools/run-tests.py b/tools/run-tests.py index 2ff6fe0c28..d7790d9e56 100755 --- a/tools/run-tests.py +++ b/tools/run-tests.py @@ -42,9 +42,9 @@ def get_binary_path(bin_dir_path): # Test options for unittests JERRY_UNITTESTS_OPTIONS = [ Options('unittests', - ['--unittests', '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on']), + ['--unittests', '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on', '--profile=es2015-subset']), Options('unittests-debug', - ['--unittests', '--debug', '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on']) + ['--unittests', '--debug', '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on', '--profile=es2015-subset']) ] # Test options for jerry-tests