aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/flathsh_unit_test.c205
-rw-r--r--src/test/lvlhsh_unit_test.c206
-rw-r--r--src/test/njs_externals_test.c80
-rw-r--r--src/test/njs_unit_test.c126
4 files changed, 361 insertions, 256 deletions
diff --git a/src/test/flathsh_unit_test.c b/src/test/flathsh_unit_test.c
new file mode 100644
index 00000000..b2a76f30
--- /dev/null
+++ b/src/test/flathsh_unit_test.c
@@ -0,0 +1,205 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) NGINX, Inc.
+ */
+
+
+#include <njs_main.h>
+
+
+static njs_int_t
+flathsh_unit_test_key_test(njs_flathsh_query_t *fhq, void *data)
+{
+ if (*(uintptr_t *) fhq->key.start == *(uintptr_t *) data) {
+ return NJS_OK;
+ }
+
+ return NJS_DECLINED;
+}
+
+
+static void *
+flathsh_unit_test_pool_alloc(void *pool, size_t size)
+{
+ return njs_mp_align(pool, NJS_MAX_ALIGNMENT, size);
+}
+
+
+static void
+flathsh_unit_test_pool_free(void *pool, void *p, size_t size)
+{
+ njs_mp_free(pool, p);
+}
+
+
+static const njs_flathsh_proto_t flathsh_proto njs_aligned(64) = {
+ flathsh_unit_test_key_test,
+ flathsh_unit_test_pool_alloc,
+ flathsh_unit_test_pool_free,
+};
+
+
+static njs_int_t
+flathsh_unit_test_add(njs_flathsh_t *lh, const njs_flathsh_proto_t *proto,
+ void *pool, uintptr_t key)
+{
+ njs_flathsh_query_t fhq;
+
+ fhq.key_hash = key;
+ fhq.replace = 0;
+ fhq.key.length = sizeof(uintptr_t);
+ fhq.key.start = (u_char *) &key;
+ fhq.proto = proto;
+ fhq.pool = pool;
+
+ switch (njs_flathsh_insert(lh, &fhq)) {
+
+ case NJS_OK:
+ ((njs_flathsh_elt_t *) fhq.value)->value[0] = (void *) key;
+ return NJS_OK;
+
+ case NJS_DECLINED:
+ njs_printf("flathsh unit test failed: key %08Xl is already in hash\n",
+ (long) key);
+ /* Fall through. */
+
+ default:
+ return NJS_ERROR;
+ }
+}
+
+
+static njs_int_t
+flathsh_unit_test_get(njs_flathsh_t *lh, const njs_flathsh_proto_t *proto,
+ uintptr_t key)
+{
+ njs_flathsh_query_t fhq;
+
+ fhq.key_hash = key;
+ fhq.key.length = sizeof(uintptr_t);
+ fhq.key.start = (u_char *) &key;
+ fhq.proto = proto;
+
+ if (njs_flathsh_find(lh, &fhq) == NJS_OK) {
+
+ if (key == (uintptr_t) ((njs_flathsh_elt_t *) fhq.value)->value[0]) {
+ return NJS_OK;
+ }
+ }
+
+ njs_printf("flathsh unit test failed: key %08Xl not found in hash\n",
+ (long) key);
+
+ return NJS_ERROR;
+}
+
+
+static njs_int_t
+flathsh_unit_test_delete(njs_flathsh_t *lh, const njs_flathsh_proto_t *proto,
+ void *pool, uintptr_t key)
+{
+ njs_int_t ret;
+ njs_flathsh_query_t fhq;
+
+ fhq.key_hash = key;
+ fhq.key.length = sizeof(uintptr_t);
+ fhq.key.start = (u_char *) &key;
+ fhq.proto = proto;
+ fhq.pool = pool;
+
+ ret = njs_flathsh_delete(lh, &fhq);
+
+ if (ret != NJS_OK) {
+ njs_printf("flathsh unit test failed: key %08lX not found in hash\n",
+ (long) key);
+ }
+
+ return ret;
+}
+
+
+static njs_int_t
+flathsh_unit_test(njs_uint_t n)
+{
+ njs_mp_t *pool;
+ uint32_t key;
+ njs_uint_t i;
+ njs_flathsh_t lh;
+ njs_flathsh_each_t lhe;
+
+ const size_t min_chunk_size = 32;
+ const size_t page_size = 1024;
+ const size_t page_alignment = 128;
+ const size_t cluster_size = 4096;
+
+ pool = njs_mp_create(cluster_size, page_alignment, page_size,
+ min_chunk_size);
+ if (pool == NULL) {
+ return NJS_ERROR;
+ }
+
+ njs_printf("flathsh unit test started: %l items\n", (long) n);
+
+ njs_memzero(&lh, sizeof(njs_flathsh_t));
+
+ key = 0;
+ for (i = 0; i < n; i++) {
+ key = njs_murmur_hash2(&key, sizeof(uint32_t));
+
+ if (flathsh_unit_test_add(&lh, &flathsh_proto, pool, key) != NJS_OK) {
+ njs_printf("flathsh add unit test failed at %l\n", (long) i);
+ return NJS_ERROR;
+ }
+ }
+
+ key = 0;
+ for (i = 0; i < n; i++) {
+ key = njs_murmur_hash2(&key, sizeof(uint32_t));
+
+ if (flathsh_unit_test_get(&lh, &flathsh_proto, key) != NJS_OK) {
+ return NJS_ERROR;
+ }
+ }
+
+ njs_flathsh_each_init(&lhe, &flathsh_proto);
+
+ for (i = 0; i < n + 1; i++) {
+ if (njs_flathsh_each(&lh, &lhe) == NULL) {
+ break;
+ }
+ }
+
+ if (i != n) {
+ njs_printf("flathsh each unit test failed at %l of %l\n",
+ (long) i, (long) n);
+ return NJS_ERROR;
+ }
+
+ key = 0;
+ for (i = 0; i < n; i++) {
+ key = njs_murmur_hash2(&key, sizeof(uint32_t));
+
+ if (flathsh_unit_test_delete(&lh, &flathsh_proto, pool, key) != NJS_OK) {
+ return NJS_ERROR;
+ }
+ }
+
+ if (!njs_mp_is_empty(pool)) {
+ njs_printf("mem cache pool is not empty\n");
+ return NJS_ERROR;
+ }
+
+ njs_mp_destroy(pool);
+
+ njs_printf("flathsh unit test passed\n");
+
+ return NJS_OK;
+}
+
+
+int
+main(void)
+{
+ return flathsh_unit_test(1000 * 1000);
+}
diff --git a/src/test/lvlhsh_unit_test.c b/src/test/lvlhsh_unit_test.c
deleted file mode 100644
index 6172c1c7..00000000
--- a/src/test/lvlhsh_unit_test.c
+++ /dev/null
@@ -1,206 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) NGINX, Inc.
- */
-
-
-#include <njs_main.h>
-
-
-static njs_int_t
-lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data)
-{
- if (*(uintptr_t *) lhq->key.start == (uintptr_t) data) {
- return NJS_OK;
- }
-
- return NJS_DECLINED;
-}
-
-
-static void *
-lvlhsh_unit_test_pool_alloc(void *pool, size_t size)
-{
- return njs_mp_align(pool, NJS_MAX_ALIGNMENT, size);
-}
-
-
-static void
-lvlhsh_unit_test_pool_free(void *pool, void *p, size_t size)
-{
- njs_mp_free(pool, p);
-}
-
-
-static const njs_lvlhsh_proto_t lvlhsh_proto njs_aligned(64) = {
- NJS_LVLHSH_LARGE_SLAB,
- lvlhsh_unit_test_key_test,
- lvlhsh_unit_test_pool_alloc,
- lvlhsh_unit_test_pool_free,
-};
-
-
-static njs_int_t
-lvlhsh_unit_test_add(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto,
- void *pool, uintptr_t key)
-{
- njs_lvlhsh_query_t lhq;
-
- lhq.key_hash = key;
- lhq.replace = 0;
- lhq.key.length = sizeof(uintptr_t);
- lhq.key.start = (u_char *) &key;
- lhq.value = (void *) key;
- lhq.proto = proto;
- lhq.pool = pool;
-
- switch (njs_lvlhsh_insert(lh, &lhq)) {
-
- case NJS_OK:
- return NJS_OK;
-
- case NJS_DECLINED:
- njs_printf("lvlhsh unit test failed: key %08Xl is already in hash\n",
- (long) key);
- /* Fall through. */
-
- default:
- return NJS_ERROR;
- }
-}
-
-
-static njs_int_t
-lvlhsh_unit_test_get(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto,
- uintptr_t key)
-{
- njs_lvlhsh_query_t lhq;
-
- lhq.key_hash = key;
- lhq.key.length = sizeof(uintptr_t);
- lhq.key.start = (u_char *) &key;
- lhq.proto = proto;
-
- if (njs_lvlhsh_find(lh, &lhq) == NJS_OK) {
-
- if (key == (uintptr_t) lhq.value) {
- return NJS_OK;
- }
- }
-
- njs_printf("lvlhsh unit test failed: key %08Xl not found in hash\n",
- (long) key);
-
- return NJS_ERROR;
-}
-
-
-static njs_int_t
-lvlhsh_unit_test_delete(njs_lvlhsh_t *lh, const njs_lvlhsh_proto_t *proto,
- void *pool, uintptr_t key)
-{
- njs_int_t ret;
- njs_lvlhsh_query_t lhq;
-
- lhq.key_hash = key;
- lhq.key.length = sizeof(uintptr_t);
- lhq.key.start = (u_char *) &key;
- lhq.proto = proto;
- lhq.pool = pool;
-
- ret = njs_lvlhsh_delete(lh, &lhq);
-
- if (ret != NJS_OK) {
- njs_printf("lvlhsh unit test failed: key %08lX not found in hash\n",
- (long) key);
- }
-
- return ret;
-}
-
-
-static njs_int_t
-lvlhsh_unit_test(njs_uint_t n)
-{
- njs_mp_t *pool;
- uint32_t key;
- njs_uint_t i;
- njs_lvlhsh_t lh;
- njs_lvlhsh_each_t lhe;
-
- const size_t min_chunk_size = 32;
- const size_t page_size = 1024;
- const size_t page_alignment = 128;
- const size_t cluster_size = 4096;
-
- pool = njs_mp_create(cluster_size, page_alignment, page_size,
- min_chunk_size);
- if (pool == NULL) {
- return NJS_ERROR;
- }
-
- njs_printf("lvlhsh unit test started: %l items\n", (long) n);
-
- njs_memzero(&lh, sizeof(njs_lvlhsh_t));
-
- key = 0;
- for (i = 0; i < n; i++) {
- key = njs_murmur_hash2(&key, sizeof(uint32_t));
-
- if (lvlhsh_unit_test_add(&lh, &lvlhsh_proto, pool, key) != NJS_OK) {
- njs_printf("lvlhsh add unit test failed at %l\n", (long) i);
- return NJS_ERROR;
- }
- }
-
- key = 0;
- for (i = 0; i < n; i++) {
- key = njs_murmur_hash2(&key, sizeof(uint32_t));
-
- if (lvlhsh_unit_test_get(&lh, &lvlhsh_proto, key) != NJS_OK) {
- return NJS_ERROR;
- }
- }
-
- njs_lvlhsh_each_init(&lhe, &lvlhsh_proto);
-
- for (i = 0; i < n + 1; i++) {
- if (njs_lvlhsh_each(&lh, &lhe) == NULL) {
- break;
- }
- }
-
- if (i != n) {
- njs_printf("lvlhsh each unit test failed at %l of %l\n",
- (long) i, (long) n);
- return NJS_ERROR;
- }
-
- key = 0;
- for (i = 0; i < n; i++) {
- key = njs_murmur_hash2(&key, sizeof(uint32_t));
-
- if (lvlhsh_unit_test_delete(&lh, &lvlhsh_proto, pool, key) != NJS_OK) {
- return NJS_ERROR;
- }
- }
-
- if (!njs_mp_is_empty(pool)) {
- njs_printf("mem cache pool is not empty\n");
- return NJS_ERROR;
- }
-
- njs_mp_destroy(pool);
-
- njs_printf("lvlhsh unit test passed\n");
-
- return NJS_OK;
-}
-
-
-int
-main(void)
-{
- return lvlhsh_unit_test(1000 * 1000);
-}
diff --git a/src/test/njs_externals_test.c b/src/test/njs_externals_test.c
index 8d71aae7..d34ec1f2 100644
--- a/src/test/njs_externals_test.c
+++ b/src/test/njs_externals_test.c
@@ -13,7 +13,7 @@
typedef struct {
- njs_lvlhsh_t hash;
+ njs_flathsh_t hash;
uint32_t a;
uint32_t d;
@@ -56,19 +56,19 @@ njs_module_t njs_unit_test_external_module = {
static njs_int_t
-lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data)
+flathsh_unit_test_key_test(njs_flathsh_query_t *fhq, void *data)
{
njs_str_t name;
njs_unit_test_prop_t *prop;
- prop = data;
+ prop = *(njs_unit_test_prop_t **) data;
name = prop->name;
- if (name.length != lhq->key.length) {
+ if (name.length != fhq->key.length) {
return NJS_DECLINED;
}
- if (memcmp(name.start, lhq->key.start, lhq->key.length) == 0) {
+ if (memcmp(name.start, fhq->key.start, fhq->key.length) == 0) {
return NJS_OK;
}
@@ -77,29 +77,28 @@ lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data)
static void *
-lvlhsh_unit_test_pool_alloc(void *pool, size_t size)
+flathsh_unit_test_pool_alloc(void *pool, size_t size)
{
return njs_mp_align(pool, NJS_MAX_ALIGNMENT, size);
}
static void
-lvlhsh_unit_test_pool_free(void *pool, void *p, size_t size)
+flathsh_unit_test_pool_free(void *pool, void *p, size_t size)
{
njs_mp_free(pool, p);
}
-static const njs_lvlhsh_proto_t lvlhsh_proto njs_aligned(64) = {
- NJS_LVLHSH_LARGE_SLAB,
- lvlhsh_unit_test_key_test,
- lvlhsh_unit_test_pool_alloc,
- lvlhsh_unit_test_pool_free,
+static const njs_flathsh_proto_t flathsh_proto njs_aligned(64) = {
+ flathsh_unit_test_key_test,
+ flathsh_unit_test_pool_alloc,
+ flathsh_unit_test_pool_free,
};
static njs_unit_test_prop_t *
-lvlhsh_unit_test_alloc(njs_mp_t *pool, const njs_str_t *name,
+flathsh_unit_test_alloc(njs_mp_t *pool, const njs_str_t *name,
const njs_value_t *value)
{
njs_unit_test_prop_t *prop;
@@ -120,22 +119,21 @@ lvlhsh_unit_test_alloc(njs_mp_t *pool, const njs_str_t *name,
static njs_int_t
-lvlhsh_unit_test_add(njs_mp_t *pool, njs_unit_test_req_t *r,
+flathsh_unit_test_add(njs_mp_t *pool, njs_unit_test_req_t *r,
njs_unit_test_prop_t *prop)
{
- njs_lvlhsh_query_t lhq;
+ njs_flathsh_query_t fhq;
- lhq.key = prop->name;
- lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
+ fhq.key = prop->name;
+ fhq.key_hash = njs_djb_hash(fhq.key.start, fhq.key.length);
- lhq.replace = 1;
- lhq.value = (void *) prop;
- lhq.proto = &lvlhsh_proto;
- lhq.pool = pool;
-
- switch (njs_lvlhsh_insert(&r->hash, &lhq)) {
+ fhq.replace = 1;
+ fhq.proto = &flathsh_proto;
+ fhq.pool = pool;
+ switch (njs_flathsh_insert(&r->hash, &fhq)) {
case NJS_OK:
+ ((njs_flathsh_elt_t *) fhq.value)->value[0] = (void *) prop;
return NJS_OK;
case NJS_DECLINED:
@@ -237,7 +235,7 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id,
njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
{
njs_int_t ret;
- njs_lvlhsh_query_t lhq;
+ njs_flathsh_query_t fhq;
njs_unit_test_req_t *r;
njs_unit_test_prop_t *prop;
@@ -247,7 +245,7 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id,
return NJS_DECLINED;
}
- ret = njs_vm_prop_name(vm, atom_id, &lhq.key);
+ ret = njs_vm_prop_name(vm, atom_id, &fhq.key);
if (ret != NJS_OK) {
if (setval == NULL && retval != NULL) {
/* Get. */
@@ -260,7 +258,7 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id,
if (setval != NULL || retval == NULL) {
/* Set or Delete. */
- if (lhq.key.length == 5 && memcmp(lhq.key.start, "error", 5) == 0) {
+ if (fhq.key.length == 5 && memcmp(fhq.key.start, "error", 5) == 0) {
njs_vm_error(vm, "cannot %s \"error\" prop",
retval != NULL ? "set" : "delete");
return NJS_ERROR;
@@ -269,15 +267,15 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id,
if (setval != NULL) {
/* Set. */
- prop = lvlhsh_unit_test_alloc(njs_vm_memory_pool(vm), &lhq.key, setval);
+ prop = flathsh_unit_test_alloc(njs_vm_memory_pool(vm), &fhq.key, setval);
if (prop == NULL) {
njs_vm_memory_error(vm);
return NJS_ERROR;
}
- ret = lvlhsh_unit_test_add(njs_vm_memory_pool(vm), r, prop);
+ ret = flathsh_unit_test_add(njs_vm_memory_pool(vm), r, prop);
if (ret != NJS_OK) {
- njs_vm_error(vm, "lvlhsh_unit_test_add() failed");
+ njs_vm_error(vm, "flathsh_unit_test_add() failed");
return NJS_ERROR;
}
@@ -286,14 +284,14 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id,
/* Get or Delete. */
- lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
- lhq.proto = &lvlhsh_proto;
-
- ret = njs_lvlhsh_find(&r->hash, &lhq);
+ fhq.key_hash = njs_djb_hash(fhq.key.start, fhq.key.length);
+ fhq.proto = &flathsh_proto;
- prop = lhq.value;
+ ret = njs_flathsh_find(&r->hash, &fhq);
if (ret == NJS_OK) {
+ prop = ((njs_flathsh_elt_t *) fhq.value)->value[0];
+
if (retval == NULL) {
njs_value_invalid_set(njs_value_arg(&prop->value));
return NJS_OK;
@@ -1130,19 +1128,19 @@ njs_externals_init_internal(njs_vm_t *vm, njs_unit_test_req_init_t *init,
return NJS_ERROR;
}
- prop = lvlhsh_unit_test_alloc(njs_vm_memory_pool(vm),
- &init[i].props[j].name,
- njs_value_arg(&value));
+ prop = flathsh_unit_test_alloc(njs_vm_memory_pool(vm),
+ &init[i].props[j].name,
+ njs_value_arg(&value));
if (njs_slow_path(prop == NULL)) {
- njs_printf("lvlhsh_unit_test_alloc() failed\n");
+ njs_printf("flathsh_unit_test_alloc() failed\n");
return NJS_ERROR;
}
- ret = lvlhsh_unit_test_add(njs_vm_memory_pool(vm), &requests[i],
- prop);
+ ret = flathsh_unit_test_add(njs_vm_memory_pool(vm), &requests[i],
+ prop);
if (njs_slow_path(ret != NJS_OK)) {
- njs_printf("lvlhsh_unit_test_add() failed\n");
+ njs_printf("flathsh_unit_test_add() failed\n");
return NJS_ERROR;
}
}
diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c
index 2227c0a6..78e12197 100644
--- a/src/test/njs_unit_test.c
+++ b/src/test/njs_unit_test.c
@@ -3923,6 +3923,9 @@ static njs_unit_test_t njs_test[] =
{ njs_str("delete this !== true"),
njs_str("false") },
+ { njs_str("undefined[Symbol()]"),
+ njs_str("TypeError: cannot get property \"Symbol()\" of undefined") },
+
/* Object shorthand methods. */
{ njs_str("var o = {m(){}}; new o.m();"),
@@ -5906,6 +5909,12 @@ static njs_unit_test_t njs_test[] =
njs_str("true") },
{ njs_str(NJS_TYPED_ARRAY_LIST
+ ".every(v=>{Object.defineProperty(v.prototype, '0', {set(){ throw 'Oops' }});"
+ " var t = new v([0]); var r = Object.create(t);"
+ " r[0] = 1; return true})"),
+ njs_str("true") },
+
+ { njs_str(NJS_TYPED_ARRAY_LIST
".every(v=>{try {var a = new v([1,1]); Object.defineProperty(a, '1', {get(){return 22}})} "
" catch (e) { return e.message == 'Cannot redefine property: \"1\"'}})"),
njs_str("true") },
@@ -9553,6 +9562,9 @@ static njs_unit_test_t njs_test[] =
{ njs_str("/["),
njs_str("SyntaxError: Unterminated RegExp \"/[\" in 1") },
+ { njs_str("/[][a"),
+ njs_str("SyntaxError: Unterminated RegExp \"/[][a\" in 1") },
+
{ njs_str("/[\\"),
njs_str("SyntaxError: Unterminated RegExp \"/[\\\" in 1") },
@@ -9588,11 +9600,24 @@ static njs_unit_test_t njs_test[] =
njs_str("/\\]cd/") },
#endif
+ { njs_str("RegExp('[][a')"),
+ njs_str("SyntaxError: "
+ njs_pcre_var("pcre_compile2(\"(?!)[a\") failed: missing terminating ] for character class at \"\"",
+ "pcre_compile(\"[][a\") failed: missing terminating ] for character class")) },
+
+ { njs_str("RegExp('[][a][a')"),
+ njs_str("SyntaxError: "
+ njs_pcre_var("pcre_compile2(\"(?!)[a][a\") failed: missing terminating ] for character class at \"\"",
+ "pcre_compile(\"[][a][a\") failed: missing terminating ] for character class")) },
+
{ njs_str("RegExp('[\\\\')"),
njs_str("SyntaxError: "
njs_pcre_var("pcre_compile2(\"[\\\") failed: \\ at end of pattern at \"\"",
"pcre_compile(\"[\\\") failed: \\ at end of pattern")) },
+ { njs_str("RegExp('[][a]')"),
+ njs_str(njs_pcre_var("/(?!)[a]/", "/[][a]/")) },
+
{ njs_str("RegExp('\\\\0').source[1]"),
njs_str("0") },
@@ -10984,6 +11009,30 @@ static njs_unit_test_t njs_test[] =
"f.apply(123, {})"),
njs_str("123") },
+ { njs_str("'Hello'.concat(' ', 'World')"),
+ njs_str("Hello World") },
+
+ { njs_str("'Value: '.concat(42, ' and ', 3.14)"),
+ njs_str("Value: 42 and 3.14") },
+
+ { njs_str("'Flags: '.concat(true, ' and ', false)"),
+ njs_str("Flags: true and false") },
+
+ { njs_str("'Values: '.concat(null, ' and ', undefined)"),
+ njs_str("Values: null and undefined") },
+
+ { njs_str("'Mixed: '.concat(123, ' ', true, ' ', null, ' ', undefined)"),
+ njs_str("Mixed: 123 true null undefined") },
+
+ { njs_str("'Special: '.concat(NaN, ' ', Infinity, ' ', -Infinity)"),
+ njs_str("Special: NaN Infinity -Infinity") },
+
+ { njs_str("'Numbers: '.concat(1234567890, ' ', 0.123456789, ' ', 1.23e-10)"),
+ njs_str("Numbers: 1234567890 0.123456789 1.23e-10") },
+
+ { njs_str("'Zero: '.concat(0, ' ', -0)"),
+ njs_str("Zero: 0 0") },
+
{ njs_str("(function(index, ...rest){ return rest[index];})"
".apply({}, [1022].concat(Array(1023).fill(1).map((v,i)=>i.toString(16))))"),
njs_str("3fe") },
@@ -11033,6 +11082,15 @@ static njs_unit_test_t njs_test[] =
{ njs_str("''.concat.apply('a', [ 'b', 'c' ], 'd')"),
njs_str("abc") },
+ { njs_str("''.concat.apply('', Array(128).fill(1.23456789123e14)) == '123456789123000'.repeat(128)"),
+ njs_str("true") },
+
+ { njs_str("''.concat.apply('', Array(128).fill(0).map((v,i)=>Math.log2(i))).startsWith('-Infinity')"),
+ njs_str("true") },
+
+ { njs_str("''.concat.apply('', Array(256).fill(0).map((v,i)=> !(i % 2) ? Math.exp(i) : 'α'.repeat(Math.log2(i)))).endsWith('110ααααααα')"),
+ njs_str("true") },
+
{ njs_str("[].join.call([1,2,3])"),
njs_str("1,2,3") },
@@ -11966,6 +12024,48 @@ static njs_unit_test_t njs_test[] =
{ njs_str("/[]a/.test('a')"),
njs_str("false") },
+ { njs_str("/[#[]/.test('[')"),
+ njs_str("true") },
+
+ { njs_str("/[\\s[]/.test('[')"),
+ njs_str("true") },
+
+ { njs_str("/[#[^]/.test('[')"),
+ njs_str("true") },
+
+ { njs_str("/[#\\[]/.test('[')"),
+ njs_str("true") },
+
+ { njs_str("/[\\[^]/.test('[')"),
+ njs_str("true") },
+
+ { njs_str("/[^]abc]/.test('#abc]')"),
+ njs_str("true") },
+
+ { njs_str("/[[^]abc]/.test('[abc]')"),
+ njs_str("true") },
+
+ { njs_str("/[[^]abc]/.test('^abc]')"),
+ njs_str("true") },
+
+ { njs_str("/[]/.test('[]')"),
+ njs_str("false") },
+
+ { njs_str("/[[]/.test('[')"),
+ njs_str("true") },
+
+ { njs_str("/\\[]/.test('[]')"),
+ njs_str("true") },
+
+ { njs_str("/[]abc]/.test('abc]')"),
+ njs_str("false") },
+
+ { njs_str("/abc]/.test('abc]')"),
+ njs_str("true") },
+
+ { njs_str("/\\\\\\[]/.test('\\\\[]')"),
+ njs_str("true") },
+
#ifdef NJS_HAVE_PCRE2
{ njs_str("/[]*a/.test('a')"),
njs_str("true") },
@@ -14186,22 +14286,22 @@ static njs_unit_test_t njs_test[] =
njs_str("true") },
{ njs_str("new Function('('.repeat(2**13));"),
- njs_str("SyntaxError: Unexpected token \"}\" in runtime:1") },
+ njs_str("SyntaxError: Unexpected token \"}\" in runtime") },
{ njs_str("new Function('{'.repeat(2**13));"),
- njs_str("SyntaxError: Unexpected token \")\" in runtime:1") },
+ njs_str("SyntaxError: Unexpected token \")\" in runtime") },
{ njs_str("new Function('['.repeat(2**13));"),
- njs_str("SyntaxError: Unexpected token \"}\" in runtime:1") },
+ njs_str("SyntaxError: Unexpected token \"}\" in runtime") },
{ njs_str("new Function('`'.repeat(2**13));"),
njs_str("[object Function]") },
{ njs_str("new Function('{['.repeat(2**13));"),
- njs_str("SyntaxError: Unexpected token \"}\" in runtime:1") },
+ njs_str("SyntaxError: Unexpected token \"}\" in runtime") },
{ njs_str("new Function('{;'.repeat(2**13));"),
- njs_str("SyntaxError: Unexpected token \")\" in runtime:1") },
+ njs_str("SyntaxError: Unexpected token \")\" in runtime") },
{ njs_str("(new Function('1;'.repeat(2**13) + 'return 2'))()"),
njs_str("2") },
@@ -14213,7 +14313,7 @@ static njs_unit_test_t njs_test[] =
njs_str("-4") },
{ njs_str("new Function('new '.repeat(2**13));"),
- njs_str("SyntaxError: Unexpected token \"}\" in runtime:1") },
+ njs_str("SyntaxError: Unexpected token \"}\" in runtime") },
{ njs_str("(new Function('return ' + 'typeof '.repeat(2**13) + 'x'))()"),
njs_str("string") },
@@ -14279,7 +14379,13 @@ static njs_unit_test_t njs_test[] =
njs_str("ReferenceError: \"foo\" is not defined") },
{ njs_str("this.NN = {}; var f = Function('eval = 42;'); f()"),
- njs_str("SyntaxError: Identifier \"eval\" is forbidden as left-hand in assignment in runtime:1") },
+ njs_str("SyntaxError: Identifier \"eval\" is forbidden as left-hand in assignment in runtime") },
+
+ { njs_str("new Function('}); let a; a; function o(){}; //')"),
+ njs_str("SyntaxError: Unexpected token \"}\" in runtime") },
+
+ { njs_str("new Function('}); let a; a; function o(){}; ({')"),
+ njs_str("SyntaxError: single function literal required") },
{ njs_str("RegExp()"),
njs_str("/(?:)/") },
@@ -19808,7 +19914,7 @@ static njs_unit_test_t njs_test[] =
njs_str("[object AsyncFunction]") },
{ njs_str("let f = new Function('x', 'await 1; return x'); f(1)"),
- njs_str("SyntaxError: await is only valid in async functions in runtime:1") },
+ njs_str("SyntaxError: await is only valid in async functions in runtime") },
{ njs_str("new AsyncFunction()"),
njs_str("ReferenceError: \"AsyncFunction\" is not defined") },
@@ -21673,7 +21779,9 @@ done:
return NJS_ERROR;
}
- success = njs_strstr_eq(&expected->ret, &s);
+ success = expected->ret.length <= s.length
+ && (memcmp(expected->ret.start, s.start, expected->ret.length)
+ == 0);
if (!success) {
njs_stderror("njs(\"%V\")\nexpected: \"%V\"\n got: \"%V\"\n",
&expected->script, &expected->ret, &s);