From 85ba858683c72b3bcccc027c4fe0f895bedef020 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Mon, 12 Feb 2018 14:54:24 +0300 Subject: [PATCH] Adding textual description for type converting exceptions. --- njs/njs_array.c | 13 +-- njs/njs_boolean.c | 6 +- njs/njs_date.c | 2 +- njs/njs_error.c | 2 +- njs/njs_function.c | 17 ++- njs/njs_number.c | 6 +- njs/njs_object.c | 49 ++++++--- njs/njs_regexp.c | 6 +- njs/njs_string.c | 12 ++- njs/njs_vm.c | 179 +++++++++++++++++++++++++++++--- njs/njs_vm.h | 2 + njs/test/njs_expect_test.exp | 7 +- njs/test/njs_interactive_test.c | 18 ++-- njs/test/njs_unit_test.c | 108 ++++++++++--------- 14 files changed, 306 insertions(+), 121 deletions(-) diff --git a/njs/njs_array.c b/njs/njs_array.c index 8b1d5597..25270ff3 100644 --- a/njs/njs_array.c +++ b/njs/njs_array.c @@ -1714,7 +1714,7 @@ njs_array_prototype_reduce(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, n = njs_array_iterator_index(array, iter); if (n == NJS_ARRAY_INVALID_INDEX) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "invalid index", NULL); return NXT_ERROR; } @@ -1775,7 +1775,7 @@ njs_array_iterator_args(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs) return NXT_OK; } - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "unexpected iterator arguments", NULL); return NXT_ERROR; } @@ -1849,7 +1849,9 @@ njs_array_prototype_reduce_right(njs_vm_t *vm, njs_value_t *args, n = njs_array_reduce_right_index(array, iter); if (n == NJS_ARRAY_INVALID_INDEX) { - goto type_error; + njs_exception_type_error(vm, "invalid index", NULL); + + return NXT_ERROR; } iter->retval = array->start[n]; @@ -1857,11 +1859,6 @@ njs_array_prototype_reduce_right(njs_vm_t *vm, njs_value_t *args, return njs_array_prototype_reduce_right_continuation(vm, args, nargs, unused); -type_error: - - njs_exception_type_error(vm, NULL, NULL); - - return NXT_ERROR; } diff --git a/njs/njs_boolean.c b/njs/njs_boolean.c index ee1cb51e..2b258f42 100644 --- a/njs/njs_boolean.c +++ b/njs/njs_boolean.c @@ -99,7 +99,8 @@ njs_boolean_prototype_value_of(njs_vm_t *vm, njs_value_t *args, value = &value->data.u.object_value->value; } else { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "unexpected value type:%s", + njs_type_string(value->type)); return NXT_ERROR; } } @@ -124,7 +125,8 @@ njs_boolean_prototype_to_string(njs_vm_t *vm, njs_value_t *args, value = &value->data.u.object_value->value; } else { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "unexpected value type:%s", + njs_type_string(value->type)); return NXT_ERROR; } } diff --git a/njs/njs_date.c b/njs/njs_date.c index b87b1f3a..64229af3 100644 --- a/njs/njs_date.c +++ b/njs/njs_date.c @@ -1911,7 +1911,7 @@ njs_date_prototype_to_json(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, } } - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "'this' argument is not an object", NULL); return NXT_ERROR; } diff --git a/njs/njs_error.c b/njs/njs_error.c index 5d9650e9..6d1e285f 100644 --- a/njs/njs_error.c +++ b/njs/njs_error.c @@ -612,7 +612,7 @@ njs_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, static const njs_value_t default_name = njs_string("Error"); if (nargs < 1 || !njs_is_object(&args[0])) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "'this' argument is not an object", NULL); return NXT_ERROR; } diff --git a/njs/njs_function.c b/njs/njs_function.c index 63ec876b..2f17e5d6 100644 --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -509,7 +509,7 @@ njs_function_prototype_call(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_function_t *function; if (!njs_is_function(&args[0])) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "'this' argument is not a function", NULL); return NXT_ERROR; } @@ -537,7 +537,8 @@ njs_function_prototype_apply(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_function_t *function; if (!njs_is_function(&args[0])) { - goto type_error; + njs_exception_type_error(vm, "'this' argument is not a function", NULL); + return NXT_ERROR; } function = args[0].data.u.function; @@ -545,7 +546,9 @@ njs_function_prototype_apply(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, if (nargs > 2) { if (!njs_is_array(&args[2])) { - goto type_error; + njs_exception_type_error(vm, "second argument is not an array", + NULL); + return NXT_ERROR; } array = args[2].data.u.array; @@ -561,12 +564,6 @@ njs_function_prototype_apply(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, } return njs_function_activate(vm, function, this, args, nargs, retval); - -type_error: - - njs_exception_type_error(vm, NULL, NULL); - - return NXT_ERROR; } @@ -622,7 +619,7 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_function_t *function; if (!njs_is_function(&args[0])) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "'this' argument is not a function", NULL); return NXT_ERROR; } diff --git a/njs/njs_number.c b/njs/njs_number.c index affc5461..3b648b7d 100644 --- a/njs/njs_number.c +++ b/njs/njs_number.c @@ -586,7 +586,8 @@ njs_number_prototype_value_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, value = &value->data.u.object_value->value; } else { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "unexpected value type:%s", + njs_type_string(value->type)); return NXT_ERROR; } } @@ -612,7 +613,8 @@ njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args, value = &value->data.u.object_value->value; } else { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "unexpected value type:%s", + njs_type_string(value->type)); return NXT_ERROR; } } diff --git a/njs/njs_object.c b/njs/njs_object.c index 29e392a9..68e262da 100644 --- a/njs/njs_object.c +++ b/njs/njs_object.c @@ -224,8 +224,6 @@ njs_object_property(njs_vm_t *vm, njs_object_t *object, nxt_lvlhsh_query_t *lhq) } while (object != NULL); - njs_exception_type_error(vm, NULL, NULL); - return NULL; } @@ -264,7 +262,8 @@ njs_object_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, type = njs_object_value_type(value->type); } else { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "unexpected constructor argument:%s", + njs_type_string(value->type)); return NXT_ERROR; } @@ -312,7 +311,7 @@ njs_object_create(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, } } - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "too few arguments", NULL); return NXT_ERROR; } @@ -325,7 +324,10 @@ njs_object_keys(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_array_t *keys; if (nargs < 2 || !njs_is_object(&args[1])) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "cannot convert %s argument to object", + (nargs >= 2) ? njs_type_string(args[1].type) + : "null"); + return NXT_ERROR; } @@ -426,15 +428,24 @@ static njs_ret_t njs_object_define_property(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - nxt_int_t ret; + nxt_int_t ret; + const char *type; if (nargs < 4 || !njs_is_object(&args[1]) || !njs_is_object(&args[3])) { - njs_exception_type_error(vm, NULL, NULL); + if (nargs < 2 || !njs_is_object(&args[1])) { + type = (nargs > 1) ? njs_type_string(args[1].type) : "null"; + njs_exception_type_error(vm, "cannot convert %s argument to object", + type); + + } else { + njs_exception_type_error(vm, "descriptor is not an object", NULL); + } + return NXT_ERROR; } if (!args[1].data.u.object->extensible) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "object is not extensible", NULL); return NXT_ERROR; } @@ -456,18 +467,27 @@ njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { nxt_int_t ret; + const char *type; nxt_lvlhsh_t *hash; njs_object_t *object; nxt_lvlhsh_each_t lhe; njs_object_prop_t *prop; if (nargs < 3 || !njs_is_object(&args[1]) || !njs_is_object(&args[2])) { - njs_exception_type_error(vm, NULL, NULL); + if (nargs < 2 || !njs_is_object(&args[1])) { + type = (nargs > 1) ? njs_type_string(args[1].type) : "null"; + njs_exception_type_error(vm, "cannot convert %s argument to object", + type); + + } else { + njs_exception_type_error(vm, "descriptor is not an object", NULL); + } + return NXT_ERROR; } if (!args[1].data.u.object->extensible) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "object is not extensible", NULL); return NXT_ERROR; } @@ -590,6 +610,7 @@ njs_object_get_own_property_descriptor(njs_vm_t *vm, njs_value_t *args, { uint32_t index; nxt_int_t ret; + const char *type; njs_array_t *array; njs_object_t *descriptor; njs_object_prop_t *pr, *prop, array_prop; @@ -597,7 +618,9 @@ njs_object_get_own_property_descriptor(njs_vm_t *vm, njs_value_t *args, nxt_lvlhsh_query_t lhq; if (nargs < 3 || !njs_is_object(&args[1])) { - njs_exception_type_error(vm, NULL, NULL); + type = (nargs > 1) ? njs_type_string(args[1].type) : "null"; + njs_exception_type_error(vm, "cannot convert %s argument to object", + type); return NXT_ERROR; } @@ -726,7 +749,9 @@ njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, return NXT_OK; } - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "cannot convert %s argument to object", + (nargs > 1) ? njs_type_string(args[1].type) + : "null"); return NXT_ERROR; } diff --git a/njs/njs_regexp.c b/njs/njs_regexp.c index 974a4225..21d21196 100644 --- a/njs/njs_regexp.c +++ b/njs/njs_regexp.c @@ -573,7 +573,7 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args, return njs_regexp_string_create(vm, &vm->retval, source, size, length); } - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "'this' argument is not a regexp", NULL); return NXT_ERROR; } @@ -591,7 +591,7 @@ njs_regexp_prototype_test(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_regexp_pattern_t *pattern; if (!njs_is_regexp(&args[0])) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "'this' argument is not a regexp", NULL); return NXT_ERROR; } @@ -641,7 +641,7 @@ njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, nxt_regex_match_data_t *match_data; if (!njs_is_regexp(&args[0])) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "'this' argument is not a regexp", NULL); return NXT_ERROR; } diff --git a/njs/njs_string.c b/njs/njs_string.c index cfd278d7..ced809c4 100644 --- a/njs/njs_string.c +++ b/njs/njs_string.c @@ -553,7 +553,8 @@ njs_string_prototype_value_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, value = &value->data.u.object_value->value; } else { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "unexpected value type:%s", + njs_type_string(value->type)); return NXT_ERROR; } } @@ -578,7 +579,8 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_string_prop_t string; if (njs_is_null_or_void(&args[0])) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "'this' argument is null or undefined", + NULL); return NXT_ERROR; } @@ -2539,7 +2541,8 @@ njs_string_replace_regexp_continuation(njs_vm_t *vm, njs_value_t *args, nxt_regex_match_data_free(r->match_data, vm->regex_context); - njs_exception_type_error(vm, NULL, NULL); + njs_exception_internal_error(vm, "unexpected continuation retval type:%s", + njs_type_string(r->retval.type)); return NXT_ERROR; } @@ -2651,7 +2654,8 @@ njs_string_replace_search_continuation(njs_vm_t *vm, njs_value_t *args, return njs_string_replace_join(vm, r); } - njs_exception_type_error(vm, NULL, NULL); + njs_exception_internal_error(vm, "unexpected continuation retval type:%s", + njs_type_string(r->retval.type)); return NXT_ERROR; } diff --git a/njs/njs_vm.c b/njs/njs_vm.c index c4de887a..194321ce 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -674,7 +674,8 @@ njs_vmcode_property_set(njs_vm_t *vm, njs_value_t *object, njs_vmcode_prop_set_t *code; if (njs_is_primitive(object)) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "property set on primitive %s type", + njs_type_string(object->type)); return NXT_ERROR; } @@ -794,7 +795,7 @@ njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *object, njs_value_t *property) case NJS_PRIMITIVE_VALUE: case NJS_STRING_VALUE: - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "property in on a primitive value", NULL); return NXT_ERROR; @@ -1039,7 +1040,23 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *object, break; default: /* NJS_VOID, NJS_NULL. */ - njs_exception_type_error(vm, NULL, NULL); + if (nxt_fast_path(njs_is_primitive(property))) { + + ret = njs_primitive_value_to_string(vm, &pq->value, property); + + if (nxt_fast_path(ret == NXT_OK)) { + njs_string_get(&pq->value, &pq->lhq.key); + njs_exception_type_error(vm, + "cannot get property '%.*s' of undefined", + (int) pq->lhq.key.length, + pq->lhq.key.start); + return NXT_ERROR; + } + } + + njs_exception_type_error(vm, + "cannot get property 'unknown' of undefined", NULL); + return NXT_ERROR; } @@ -1322,7 +1339,7 @@ njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object, nxt_lvlhsh_query_t lhq; if (!njs_is_function(constructor)) { - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "right argument is not a function", NULL); return NXT_ERROR; } @@ -2245,7 +2262,7 @@ njs_function_frame_create(njs_vm_t *vm, njs_value_t *value, } } - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "object is not callable", NULL); return NXT_ERROR; } @@ -2304,7 +2321,9 @@ njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object, njs_value_t *name) pq.query = NJS_PROPERTY_QUERY_GET; - switch (njs_property_query(vm, &pq, object, name)) { + ret = njs_property_query(vm, &pq, object, name); + + switch (ret) { case NXT_OK: prop = pq.lhq.value; @@ -2326,13 +2345,20 @@ njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object, njs_value_t *name) ret = nxt_lvlhsh_find(&ext->hash, &pq.lhq); if (nxt_slow_path(ret != NXT_OK)) { - goto type_error; + njs_exception_type_error(vm, + "cannot find property '%.*s' of an external object", + (int) pq.lhq.key.length, pq.lhq.key.start); + return NXT_ERROR; + } ext = pq.lhq.value; if (nxt_slow_path(ext->type != NJS_EXTERN_METHOD)) { - goto type_error; + njs_exception_type_error(vm, + "method '%.*s' of an external object is not callable", + (int) pq.lhq.key.length, pq.lhq.key.start); + return NXT_ERROR; } this.data.u.data = vm->external[ext->object]; @@ -2342,7 +2368,10 @@ njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object, njs_value_t *name) break; default: - goto type_error; + njs_exception_internal_error(vm, "method '%.*s' query failed:%d", + (int) pq.lhq.key.length, pq.lhq.key.start, + ret); + return NXT_ERROR; } if (nxt_fast_path(ret == NXT_OK)) { @@ -2350,12 +2379,6 @@ njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *object, njs_value_t *name) } return ret; - -type_error: - - njs_exception_type_error(vm, NULL, NULL); - - return NXT_ERROR; } @@ -2574,12 +2597,130 @@ trap: type_error: - njs_exception_type_error(vm, NULL, NULL); + njs_exception_type_error(vm, "cannot convert %s to %s", + njs_type_string(args->type), + njs_arg_type_string(*args_types)); return NXT_ERROR; } +const char * +njs_type_string(njs_value_type_t type) +{ + switch (type) { + case NJS_NULL: + return "null"; + + case NJS_VOID: + return "void"; + + case NJS_BOOLEAN: + return "boolean"; + + case NJS_NUMBER: + return "number"; + + case NJS_STRING: + return "string"; + + case NJS_EXTERNAL: + return "external"; + + case NJS_INVALID: + return "invalid"; + + case NJS_OBJECT: + return "object"; + + case NJS_ARRAY: + return "array"; + + case NJS_OBJECT_BOOLEAN: + return "object boolean"; + + case NJS_OBJECT_NUMBER: + return "object number"; + + case NJS_OBJECT_STRING: + return "object string"; + + case NJS_FUNCTION: + return "function"; + + case NJS_REGEXP: + return "regexp"; + + case NJS_DATE: + return "date"; + + case NJS_OBJECT_ERROR: + return "error"; + + case NJS_OBJECT_EVAL_ERROR: + return "eval error"; + + case NJS_OBJECT_INTERNAL_ERROR: + return "internal error"; + + case NJS_OBJECT_RANGE_ERROR: + return "range error"; + + case NJS_OBJECT_REF_ERROR: + return "reference error"; + + case NJS_OBJECT_SYNTAX_ERROR: + return "syntax error"; + + case NJS_OBJECT_TYPE_ERROR: + return "type error"; + + case NJS_OBJECT_URI_ERROR: + return "uri error"; + + default: + return NULL; + } +} + + +const char * +njs_arg_type_string(uint8_t arg) +{ + switch (arg) { + case NJS_SKIP_ARG: + return "skip"; + + case NJS_NUMBER_ARG: + return "number"; + + case NJS_INTEGER_ARG: + return "integer"; + + case NJS_STRING_ARG: + return "string"; + + case NJS_OBJECT_ARG: + return "object"; + + case NJS_STRING_OBJECT_ARG: + return "string object"; + + case NJS_FUNCTION_ARG: + return "function"; + + case NJS_REGEXP_ARG: + return "regexp"; + + case NJS_DATE_ARG: + return "regexp"; + + default: + return "unknown"; + } +} + + njs_ret_t njs_vmcode_return(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval) { @@ -3173,7 +3314,6 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint) if (!njs_is_primitive(retval)) { for ( ;; ) { - njs_exception_type_error(vm, NULL, NULL); ret = NXT_ERROR; if (njs_is_object(value) && vm->top_frame->trap_tries < 2) { @@ -3221,6 +3361,11 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint) } } + if (ret == NXT_ERROR) { + njs_exception_type_error(vm, "cannot evaluate an object's " + "value", NULL); + } + return ret; } } diff --git a/njs/njs_vm.h b/njs/njs_vm.h index bbd9442f..5ac28728 100644 --- a/njs/njs_vm.h +++ b/njs/njs_vm.h @@ -1152,6 +1152,8 @@ nxt_bool_t njs_values_strict_equal(const njs_value_t *val1, njs_ret_t njs_normalize_args(njs_vm_t *vm, njs_value_t *args, uint8_t *args_types, nxt_uint_t nargs); +const char *njs_type_string(njs_value_type_t type); +const char *njs_arg_type_string(uint8_t arg); njs_ret_t njs_native_function_arguments(njs_vm_t *vm, njs_value_t *args, uint8_t *args_types, nxt_uint_t nargs); diff --git a/njs/test/njs_expect_test.exp b/njs/test/njs_expect_test.exp index d6adec6b..2361f4f6 100644 --- a/njs/test/njs_expect_test.exp +++ b/njs/test/njs_expect_test.exp @@ -166,12 +166,17 @@ njs_test { "console.help()\r\nVM built-in objects:"} } +njs_test { + {"console.ll()\r\n" + "console.ll()\r\nTypeError: cannot find property 'll' of an external object"} +} + # Exception in njs_vm_retval() njs_test { {"var o = { toString: function() { return [1] } }\r\n" "undefined\r\n>> "} {"o\r\n" - "TypeError"} + "TypeError: cannot evaluate an object's value"} } # Backtraces are reset between invocations diff --git a/njs/test/njs_interactive_test.c b/njs/test/njs_interactive_test.c index 19a78c4a..d6e93f2f 100644 --- a/njs/test/njs_interactive_test.c +++ b/njs/test/njs_interactive_test.c @@ -120,7 +120,7 @@ static njs_interactive_test_t njs_test[] = { nxt_string("function ff(o) {return o.a.a}" ENTER "function f(o) {return ff(o)}" ENTER "f({})" ENTER), - nxt_string("TypeError\n" + nxt_string("TypeError: cannot get property 'a' of undefined\n" " at ff (:1)\n" " at f (:1)\n" " at main (native)\n") }, @@ -129,27 +129,27 @@ static njs_interactive_test_t njs_test[] = "function f(o) {try {return ff(o)} " "finally {return o.a.a}}" ENTER "f({})" ENTER), - nxt_string("TypeError\n" + nxt_string("TypeError: cannot get property 'a' of undefined\n" " at f (:1)\n" " at main (native)\n") }, { nxt_string("function f(ff, o) {return ff(o)}" ENTER "f(function (o) {return o.a.a}, {})" ENTER), - nxt_string("TypeError\n" + nxt_string("TypeError: cannot get property 'a' of undefined\n" " at anonymous (:1)\n" " at f (:1)\n" " at main (native)\n") }, { nxt_string("'str'.replace(/t/g," " function(m) {return m.a.a})" ENTER), - nxt_string("TypeError\n" + nxt_string("TypeError: cannot get property 'a' of undefined\n" " at anonymous (:1)\n" " at String.prototype.replace (native)\n" " at main (native)\n") }, { nxt_string("function f(o) {return Object.keys(o)}" ENTER "f()" ENTER), - nxt_string("TypeError\n" + nxt_string("TypeError: cannot convert void to object\n" " at Object.keys (native)\n" " at f (:1)\n" " at main (native)\n") }, @@ -160,20 +160,20 @@ static njs_interactive_test_t njs_test[] = " at main (native)\n") }, { nxt_string("Math.log({}.a.a)" ENTER), - nxt_string("TypeError\n" + nxt_string("TypeError: cannot get property 'a' of undefined\n" " at Math.log (native)\n" " at main (native)\n") }, { nxt_string("function f(o) {function f_in(o) {return o.a.a};" " return f_in(o)}; f({})" ENTER), - nxt_string("TypeError\n" + nxt_string("TypeError: cannot get property 'a' of undefined\n" " at f_in (:1)\n" " at f (:1)\n" " at main (native)\n") }, { nxt_string("function f(o) {var ff = function (o) {return o.a.a};" " return ff(o)}; f({})" ENTER), - nxt_string("TypeError\n" + nxt_string("TypeError: cannot get property 'a' of undefined\n" " at anonymous (:1)\n" " at f (:1)\n" " at main (native)\n") }, @@ -187,7 +187,7 @@ static njs_interactive_test_t njs_test[] = { nxt_string("var o = { toString: function() { return [1] } }" ENTER "o" ENTER), - nxt_string("TypeError\n" + nxt_string("TypeError: cannot evaluate an object's value\n" " at main (native)\n") }, }; diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 6b6084b1..2bd3a041 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -2309,10 +2309,10 @@ static njs_unit_test_t njs_test[] = nxt_string("undefined") }, { nxt_string("var a = {}; a.b.c"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot get property 'c' of undefined") }, { nxt_string("'a'.b = 1"), - nxt_string("TypeError") }, + nxt_string("TypeError: property set on primitive string type") }, { nxt_string("var a = {}; a.b = 1; a.b"), nxt_string("1") }, @@ -2342,16 +2342,16 @@ static njs_unit_test_t njs_test[] = nxt_string("3") }, { nxt_string("var a = undefined; a.b++; a.b"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot get property 'b' of undefined") }, { nxt_string("var a = null; a.b++; a.b"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot get property 'b' of undefined") }, { nxt_string("var a = true; a.b++; a.b"), - nxt_string("TypeError") }, + nxt_string("TypeError: property set on primitive boolean type") }, { nxt_string("var a = 1; a.b++; a.b"), - nxt_string("TypeError") }, + nxt_string("TypeError: property set on primitive number type") }, { nxt_string("var n = 1, o = { p: n += 1 }; o.p"), nxt_string("2") }, @@ -2369,7 +2369,7 @@ static njs_unit_test_t njs_test[] = nxt_string("2 1") }, { nxt_string("var a = 2; a.b = 1; var c = a.b++; a +' '+ a.b +' '+ c"), - nxt_string("TypeError") }, + nxt_string("TypeError: property set on primitive number type") }, { nxt_string("var x = { a: 1 }; x.a"), nxt_string("1") }, @@ -2408,7 +2408,7 @@ static njs_unit_test_t njs_test[] = nxt_string("SyntaxError: Unexpected token \";\" in 1") }, { nxt_string("var x = { a: 1, b: x.a }"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot get property 'a' of undefined") }, { nxt_string("var a = { b: 2 }; a.b += 1"), nxt_string("3") }, @@ -2481,10 +2481,10 @@ static njs_unit_test_t njs_test[] = nxt_string("false") }, { nxt_string("var a = 1; 1 in a"), - nxt_string("TypeError") }, + nxt_string("TypeError: property in on a primitive value") }, { nxt_string("var a = true; 1 in a"), - nxt_string("TypeError") }, + nxt_string("TypeError: property in on a primitive value") }, { nxt_string("var n = { toString: function() { return 'a' } };" "var o = { a: 5 }; o[n]"), @@ -3224,7 +3224,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [];" "a.reduce(function(p, v, i, a) { return p + v })"), - nxt_string("TypeError") }, + nxt_string("TypeError: invalid index") }, { nxt_string("var a = [];" "a.reduce(function(p, v, i, a) { return p + v }, 10)"), @@ -3232,7 +3232,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [,,];" "a.reduce(function(p, v, i, a) { return p + v })"), - nxt_string("TypeError") }, + nxt_string("TypeError: invalid index") }, { nxt_string("var a = [,,];" "a.reduce(function(p, v, i, a) { return p + v }, 10)"), @@ -3260,7 +3260,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [];" "a.reduceRight(function(p, v, i, a) { return p + v })"), - nxt_string("TypeError") }, + nxt_string("TypeError: invalid index") }, { nxt_string("var a = [];" "a.reduceRight(function(p, v, i, a) { return p + v }, 10)"), @@ -3268,7 +3268,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [,,];" "a.reduceRight(function(p, v, i, a) { return p + v })"), - nxt_string("TypeError") }, + nxt_string("TypeError: invalid index") }, { nxt_string("var a = [,,];" "a.reduceRight(function(p, v, i, a) { return p + v }, 10)"), @@ -3725,7 +3725,7 @@ static njs_unit_test_t njs_test[] = nxt_string("abc") }, { nxt_string("String.prototype.toString.call(1)"), - nxt_string("TypeError") }, + nxt_string("TypeError: unexpected value type:number") }, { nxt_string("'abc'.valueOf()"), nxt_string("abc") }, @@ -4131,7 +4131,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var r = { toString: function() { return /45/ } };" "'123456'.search(r)"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot evaluate an object's value") }, { nxt_string("var r = { toString: function() { return /34/ }," " valueOf: function() { return 45 } };" @@ -4265,7 +4265,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var r = { toString: function() { return /45/ } };" "'123456'.match(r)"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot evaluate an object's value") }, { nxt_string("var r = { toString: function() { return /34/ }," " valueOf: function() { return 45 } };" @@ -4509,10 +4509,10 @@ static njs_unit_test_t njs_test[] = nxt_string("OKundefined") }, { nxt_string("var a = 1; a()"), - nxt_string("TypeError") }, + nxt_string("TypeError: object is not callable") }, { nxt_string("var o = {a:1}; o.a()"), - nxt_string("TypeError") }, + nxt_string("TypeError: object is not callable") }, { nxt_string("(function(){})()"), nxt_string("undefined") }, @@ -4800,7 +4800,7 @@ static njs_unit_test_t njs_test[] = nxt_string("5") }, { nxt_string("var f = function(a) { return this + a }; f.apply(5, 1)"), - nxt_string("TypeError") }, + nxt_string("TypeError: second argument is not an array") }, { nxt_string("var f = function(a, b) { return this + a + b };" "f.apply(5, [1, 2])"), @@ -4814,7 +4814,7 @@ static njs_unit_test_t njs_test[] = nxt_string("[object Function]") }, { nxt_string("''.concat.call()"), - nxt_string("TypeError") }, + nxt_string("TypeError: 'this' argument is null or undefined") }, { nxt_string("''.concat.call('a', 'b', 'c')"), nxt_string("abc") }, @@ -4829,13 +4829,13 @@ static njs_unit_test_t njs_test[] = nxt_string("ab,cd") }, { nxt_string("''.concat.apply()"), - nxt_string("TypeError") }, + nxt_string("TypeError: 'this' argument is null or undefined") }, { nxt_string("''.concat.apply('a')"), nxt_string("a") }, { nxt_string("''.concat.apply('a', 'b')"), - nxt_string("TypeError") }, + nxt_string("TypeError: second argument is not an array") }, { nxt_string("''.concat.apply('a', [ 'b', 'c' ])"), nxt_string("abc") }, @@ -4853,10 +4853,10 @@ static njs_unit_test_t njs_test[] = nxt_string("1552553") }, { nxt_string("[].join.call()"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot convert void to object") }, { nxt_string("[].slice.call()"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot convert void to object") }, { nxt_string("function f(a) {} ; var a = f; var b = f; a === b"), nxt_string("true") }, @@ -4900,7 +4900,7 @@ static njs_unit_test_t njs_test[] = nxt_string("01") }, { nxt_string("var concat = ''.concat; concat(1,2,3)"), - nxt_string("TypeError") }, + nxt_string("TypeError: 'this' argument is null or undefined") }, { nxt_string("var concat = ''.concat; concat.call(1,2,3)"), nxt_string("123") }, @@ -4997,10 +4997,10 @@ static njs_unit_test_t njs_test[] = nxt_string("object") }, { nxt_string("new decodeURI('%00')"), - nxt_string("TypeError")}, + nxt_string("TypeError: object is not callable")}, { nxt_string("new ''.toString"), - nxt_string("TypeError")}, + nxt_string("TypeError: object is not callable")}, { nxt_string("function F() { return Number }" "var o = new (F())(5);" @@ -5214,7 +5214,7 @@ static njs_unit_test_t njs_test[] = nxt_string("true") }, { nxt_string("[0].map(RegExp().toString)"), - nxt_string("TypeError") }, + nxt_string("TypeError: 'this' argument is not a regexp") }, /* Non-standard ECMA-262 features. */ @@ -5565,10 +5565,10 @@ static njs_unit_test_t njs_test[] = nxt_string("o:OK") }, { nxt_string("var o = { toString: function() { return [1] } }; o"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot evaluate an object's value") }, { nxt_string("var o = { toString: function() { return [1] } }; 'o:' + o"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot evaluate an object's value") }, { nxt_string("var a = { valueOf: function() { return '3' } };" "var b = { toString: function() { return 10 - a + 'OK' } };" @@ -5620,7 +5620,7 @@ static njs_unit_test_t njs_test[] = nxt_string("true") }, { nxt_string("[] instanceof []"), - nxt_string("TypeError") }, + nxt_string("TypeError: right argument is not a function") }, { nxt_string("[] instanceof Array"), nxt_string("true") }, @@ -6202,6 +6202,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("var o = Object.create(null); '__proto__' in o"), nxt_string("false") }, + { nxt_string("Object.create()"), + nxt_string("TypeError: too few arguments") }, + { nxt_string("var o = {a:1, b:2, c:3};" "Object.keys(o)"), nxt_string("a,b,c") }, @@ -6215,11 +6218,14 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = [,6,,3]; a.one = 7; Object.keys(a)"), nxt_string("1,3,one") }, + { nxt_string("Object.keys()"), + nxt_string("TypeError: cannot convert null argument to object") }, + { nxt_string("Object.keys('a')"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot convert string argument to object") }, { nxt_string("Object.keys(1)"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot convert number argument to object") }, { nxt_string("var o = {}; Object.defineProperty(o, 'a', {}); o.a"), nxt_string("undefined") }, @@ -6274,10 +6280,10 @@ static njs_unit_test_t njs_test[] = nxt_string("2") }, { nxt_string("var o = {}; Object.defineProperty()"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot convert null argument to object") }, { nxt_string("var o = {}; Object.defineProperty(o)"), - nxt_string("TypeError") }, + nxt_string("TypeError: descriptor is not an object") }, { nxt_string("var o = Object.defineProperties({}, {a:{value:1}}); o.a"), nxt_string("1") }, @@ -6295,10 +6301,10 @@ static njs_unit_test_t njs_test[] = nxt_string("1") }, { nxt_string("Object.defineProperties(1, {})"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot convert number argument to object") }, { nxt_string("Object.defineProperties({}, 1)"), - nxt_string("TypeError") }, + nxt_string("TypeError: descriptor is not an object") }, { nxt_string("var o = {a:1}; o.hasOwnProperty('a')"), nxt_string("true") }, @@ -6361,10 +6367,10 @@ static njs_unit_test_t njs_test[] = nxt_string("true") }, { nxt_string("Object.getPrototypeOf(1)"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot convert number argument to object") }, { nxt_string("Object.getPrototypeOf('a')"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot convert string argument to object") }, { nxt_string("var p = {}; var o = Object.create(p);" "p.isPrototypeOf(o)"), @@ -6425,13 +6431,13 @@ static njs_unit_test_t njs_test[] = nxt_string("undefined") }, { nxt_string("Object.getOwnPropertyDescriptor(1, '0')"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot convert number argument to object") }, { nxt_string("Object.defineProperty(Object.freeze({}), 'b', {})"), - nxt_string("TypeError") }, + nxt_string("TypeError: object is not extensible") }, { nxt_string("Object.defineProperties(Object.freeze({}), {b:{}})"), - nxt_string("TypeError") }, + nxt_string("TypeError: object is not extensible") }, { nxt_string("Object.freeze()"), nxt_string("undefined") }, @@ -6456,7 +6462,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = Object.freeze([1,2]);" "Object.defineProperty(a, 'a', {value:1}).a"), - nxt_string("TypeError") }, + nxt_string("TypeError: object is not extensible") }, { nxt_string("var a = [1,2]; a.a = 1; Object.freeze(a);" "delete a.a; a.a"), @@ -6474,7 +6480,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var f = Object.freeze(function() {});" "Object.defineProperty(f, 'a', {value:1}).a"), - nxt_string("TypeError") }, + nxt_string("TypeError: object is not extensible") }, { nxt_string("var f = function() {}; f.a = 1; Object.freeze(f);" "delete f.a; f.a"), @@ -6492,7 +6498,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var d = Object.freeze(new Date(''));" "Object.defineProperty(d, 'a', {value:1}).a"), - nxt_string("TypeError") }, + nxt_string("TypeError: object is not extensible") }, { nxt_string("var d = new Date(''); d.a = 1; Object.freeze(d);" "delete d.a; d.a"), @@ -6510,7 +6516,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var r = Object.freeze(new RegExp(''));" "Object.defineProperty(r, 'a', {value:1}).a"), - nxt_string("TypeError") }, + nxt_string("TypeError: object is not extensible") }, { nxt_string("var r = new RegExp(''); r.a = 1; Object.freeze(r);" "delete r.a; r.a"), @@ -6657,11 +6663,11 @@ static njs_unit_test_t njs_test[] = { nxt_string("var o = Object.preventExtensions({a:1});" "Object.defineProperty(o, 'b', {value:1})"), - nxt_string("TypeError") }, + nxt_string("TypeError: object is not extensible") }, { nxt_string("var o = Object.preventExtensions({a:1});" "Object.defineProperties(o, {b:{value:1}})"), - nxt_string("TypeError") }, + nxt_string("TypeError: object is not extensible") }, { nxt_string("var o = Object.preventExtensions({a:1}); o.a = 2; o.a"), nxt_string("2") }, @@ -7079,7 +7085,7 @@ static njs_unit_test_t njs_test[] = nxt_string("true") }, { nxt_string("[0].map(new Date().getDate)"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot convert void to regexp") }, { nxt_string("new Date(eval)"), nxt_string("Invalid Date") }, @@ -8499,7 +8505,7 @@ static njs_unit_test_t njs_test[] = { nxt_string("var o = JSON.parse('{\"a\":1}', " " function(k, v) {return v.a.a;}); o"), - nxt_string("TypeError") }, + nxt_string("TypeError: cannot get property 'a' of undefined") }, /* JSON.stringify() */ -- 2.47.3