Tests+Meta: Reimport V8 regexp tests

This commit fixes assertEquals, assertThrows/assertDoesNotThrow in
compatibility shim - we were failing some tests purely because of a
bad shim.

Two test files are moved from XFAIL_TESTS to SKIP_FILES:
1. es6/regexp-tostring.js: checks for V8-specific error message wording
2. es6/unicode-regexp-ignore-case-noi18n.js: tests V8's non-i18n build
    behavior, it doesn't case-fold non-ASCII characters, but we do it
    correctly.

The regexp-unicode-sets.js test is now included and passes.

All files that were previously in XFAIL_TESTS and SKIP_TESTS are now
passing, so both lists are cleared.
This commit is contained in:
aplefull 2026-05-17 02:06:36 +02:00 committed by Jelle Raaijmakers
parent c0a8dd4536
commit b3bd8884ae
62 changed files with 985 additions and 1343 deletions

View file

@ -19,6 +19,9 @@ V8_COMPAT_SHIM = """\
function assertEquals(expected, actual, msg) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -43,11 +46,19 @@ function assertNotNull(val, msg) {
}
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {
@ -90,8 +101,11 @@ SKIP_FILES = {
# parse errors in other engines.
"regexp-14098.js",
"regexp-444637793.js",
# Uses regex literal syntax that triggers parse errors in our engine.
"regexp-unicode-sets.js",
# Tests V8-specific error message wording ("incompatible receiver"), we correctly throw but use different message.
"es6/regexp-tostring.js",
# Tests V8's non-i18n build behavior. Spec-compliant engines (including ours) behave differently - we correctly
# case-fold all cases.
"es6/unicode-regexp-ignore-case-noi18n.js",
# Multi-file dependency (lu-ui0..9 depend on testCodePointRange from lu-ui).
"harmony/regexp-property-lu-ui0.js",
"harmony/regexp-property-lu-ui1.js",
@ -106,37 +120,11 @@ SKIP_FILES = {
}
# Tests that crash or hang -- use test.skip() so they don't block the suite.
SKIP_TESTS = {
# Hangs: catastrophic backtracking tests that rely on V8-specific
# optimizations to terminate in reasonable time.
"regexp-capture-3",
# Crashes (SIGSEGV).
"regexp-capture",
}
SKIP_TESTS = {}
# Tests that fail but should be tracked -- use test.xfail() so we notice
# when they start passing.
XFAIL_TESTS = {
"es6/regexp-constructor",
"es6/regexp-tostring",
"es6/unicode-escapes-in-regexps",
"es6/unicode-regexp-backrefs",
"es6/unicode-regexp-ignore-case-noi18n",
"es6/unicode-regexp-restricted-syntax",
"es6/unicode-regexp-zero-length",
"regexp-duplicate-named-groups",
"regexp-lookahead",
"regexp-multiline",
"regexp-sort",
"regexp-UC16",
"harmony/regexp-property-binary",
"harmony/regexp-property-char-class",
"harmony/regexp-property-enumerated",
"harmony/regexp-property-exact-match",
"harmony/regexp-property-general-category",
"harmony/regexp-property-invalid",
"harmony/regexp-property-special",
}
XFAIL_TESTS = {}
def should_skip(content):

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,17 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -1,125 +0,0 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
expect(actual).toBe(expected);
}
}
function assertTrue(val, msg) {
expect(val).toBeTrue();
}
function assertFalse(val, msg) {
expect(val).toBeFalse();
}
function assertNull(val, msg) {
expect(val).toBeNull();
}
function assertNotNull(val, msg) {
expect(val).not.toBeNull();
}
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(fn).toThrow();
}
function assertDoesNotThrow(fn, msg) {
fn();
}
function assertInstanceof(val, type, msg) {
expect(val instanceof type).toBeTrue();
}
function assertUnreachable(msg) {
expect().fail("unreachable" + (msg ? ": " + msg : ""));
}
function assertEarlyError(code) {
assertThrows(() => new Function(code));
}
function assertThrowsAtRuntime(code, type_opt) {
const f = new Function(code);
assertThrows(f, type_opt);
}
function assertArrayEquals(expected, actual) {
expect(actual).toEqual(expected);
}
test.xfail("es6/regexp-tostring", () => {
var log = [];
var fake = {
get source() {
log.push("p");
return {
toString: function () {
log.push("ps");
return "pattern";
},
};
},
get flags() {
log.push("f");
return {
toString: function () {
log.push("fs");
return "flags";
},
};
},
};
function testThrows(x) {
try {
RegExp.prototype.toString.call(x);
} catch (e) {
assertTrue(/incompatible receiver/.test(e.message));
return;
}
assertUnreachable();
}
testThrows(1);
testThrows(null);
Number.prototype.source = "a";
Number.prototype.flags = "b";
testThrows(1);
assertEquals("/pattern/flags", RegExp.prototype.toString.call(fake));
assertEquals(["p", "ps", "f", "fs"], log);
// Monkey-patching is also possible on RegExp instances
let weird = /foo/;
Object.defineProperty(weird, "flags", { value: "bar" });
Object.defineProperty(weird, "source", { value: "baz" });
assertEquals("/baz/bar", weird.toString());
assertEquals("/(?:)/", RegExp.prototype.toString());
assertEquals("(?:)", RegExp.prototype.source);
assertEquals("", RegExp.prototype.flags);
});

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -1,137 +0,0 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
expect(actual).toBe(expected);
}
}
function assertTrue(val, msg) {
expect(val).toBeTrue();
}
function assertFalse(val, msg) {
expect(val).toBeFalse();
}
function assertNull(val, msg) {
expect(val).toBeNull();
}
function assertNotNull(val, msg) {
expect(val).not.toBeNull();
}
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(fn).toThrow();
}
function assertDoesNotThrow(fn, msg) {
fn();
}
function assertInstanceof(val, type, msg) {
expect(val instanceof type).toBeTrue();
}
function assertUnreachable(msg) {
expect().fail("unreachable" + (msg ? ": " + msg : ""));
}
function assertEarlyError(code) {
assertThrows(() => new Function(code));
}
function assertThrowsAtRuntime(code, type_opt) {
const f = new Function(code);
assertThrows(f, type_opt);
}
function assertArrayEquals(expected, actual) {
expect(actual).toEqual(expected);
}
test.xfail("es6/unicode-regexp-ignore-case-noi18n", () => {
assertTrue(/[a]/iu.test("\u{20a0}a"));
assertTrue(/[a]/iu.test("\u{20a0}A"));
assertTrue(/[A]/iu.test("\u{20a0}a"));
assertTrue(/[A]/iu.test("\u{20a0}A"));
// Non-unicode use toUpperCase mappings.
assertFalse(/[\u00e5]/i.test("\u212b"));
assertFalse(/[\u212b]/i.test("\u00e5\u1234"));
assertFalse(/[\u212b]/i.test("\u00e5"));
assertTrue("\u212b".toLowerCase() == "\u00e5");
assertTrue("\u00c5".toLowerCase() == "\u00e5");
assertTrue("\u00e5".toUpperCase() == "\u00c5");
// Unicode uses case folding mappings.
assertFalse(/\u00e5/iu.test("\u212b"));
assertTrue(/\u00e5/iu.test("\u00c5"));
assertTrue(/\u00e5/iu.test("\u00e5"));
assertFalse(/\u00e5/iu.test("\u212b"));
assertTrue(/\u00c5/iu.test("\u00e5"));
assertFalse(/\u00c5/iu.test("\u212b"));
assertTrue(/\u00c5/iu.test("\u00c5"));
assertFalse(/\u212b/iu.test("\u00c5"));
assertFalse(/\u212b/iu.test("\u00e5"));
assertTrue(/\u212b/iu.test("\u212b"));
// Non-BMP.
assertFalse(/\u{10400}/i.test("\u{10428}"));
assertFalse(/\u{10400}/iu.test("\u{10428}"));
assertFalse(/\ud801\udc00/iu.test("\u{10428}"));
assertFalse(/[\u{10428}]/iu.test("\u{10400}"));
assertFalse(/[\ud801\udc28]/iu.test("\u{10400}"));
assertEquals(["\uff21\u{10400}"], /[\uff40-\u{10428}]+/iu.exec("\uff21\u{10400}abc"));
// TODO(v8:10120): Investigate why these don't behave as expected.
{
// Should be:
// assertEquals(["abc"], /[^\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc\uff23"));
//
// But is:
assertEquals(["\u{ff21}"], /[^\uff40-\u{10428}]+/iu.exec("\uff21\u{10400}abc\uff23"));
}
assertEquals(["\uff53\u24bb"], /[\u24d5-\uff33]+/iu.exec("\uff54\uff53\u24bb\u24ba"));
// Full mappings are ignored.
assertFalse(/\u00df/iu.test("SS"));
assertFalse(/\u1f8d/iu.test("\u1f05\u03b9"));
// Simple mappings.
assertFalse(/\u1f8d/iu.test("\u1f85"));
// Common mappings.
assertTrue(/\u1f6b/iu.test("\u1f63"));
// Back references.
assertNull(/(.)\1\1/iu.exec("\u00e5\u212b\u00c5"));
assertNull(/(.)\1/iu.exec("\u{118aa}\u{118ca}"));
// Non-Latin1 maps to Latin1.
assertNull(/^\u017F/iu.exec("s"));
assertNull(/^\u017F/iu.exec("s\u1234"));
assertNull(/^a[\u017F]/iu.exec("as"));
assertNull(/^a[\u017F]/iu.exec("as\u1234"));
});

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {
@ -69,7 +70,7 @@ function assertArrayEquals(expected, actual) {
expect(actual).toEqual(expected);
}
test.xfail("harmony/regexp-property-enumerated", () => {
test("harmony/regexp-property-enumerated", () => {
assertThrows("/\\p{Bidi_Class=L}+/u");
assertThrows("/\\p{bc=Left_To_Right}+/u");
assertThrows("/\\p{bc=AL}+/u");

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {
@ -69,7 +70,7 @@ function assertArrayEquals(expected, actual) {
expect(actual).toEqual(expected);
}
test.xfail("harmony/regexp-property-exact-match", () => {
test("harmony/regexp-property-exact-match", () => {
assertThrows("/\\p{In CJK}/u");
assertThrows("/\\p{InCJKUnifiedIdeographs}/u");
assertThrows("/\\p{InCJK}/u");

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,17 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
fn = new Function(fn);
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {
@ -107,7 +93,7 @@ function assertArrayEquals(expected, actual) {
expect(actual).toEqual(expected);
}
test.skip("regexp-capture-3", () => {
test("regexp-capture-3", () => {
function oneMatch(re) {
"abcd".replace(re, function () {});
assertEquals("abcd", RegExp.input);

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {
@ -107,7 +93,7 @@ function assertArrayEquals(expected, actual) {
expect(actual).toEqual(expected);
}
test.skip("regexp-capture", () => {
test("regexp-capture", () => {
assertEquals(true, /(x)?\1y/.test("y"));
assertEquals(["y", undefined], /(x)?\1y/.exec("y"));
assertEquals(["y", undefined], /(x)?y/.exec("y"));

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -5,11 +5,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -35,32 +35,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -28,11 +28,11 @@
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (expected instanceof RegExp && actual instanceof RegExp) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
@ -58,32 +58,18 @@ function assertNotNull(val, msg) {
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
if (typeof fn === "string") {
try {
try {
fn = new Function(fn);
} catch (e) {
return;
}
} catch (e) {
return;
}
}
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {

View file

@ -0,0 +1,323 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// V8 assertion compatibility shim for Ladybird's test-js harness
function assertEquals(expected, actual, msg) {
if (Array.isArray(expected) && Array.isArray(actual)) {
expect(actual).toEqual(expected);
} else if (expected instanceof RegExp && actual instanceof RegExp) {
expect(actual.source).toBe(expected.source);
expect(actual.flags).toBe(expected.flags);
} else if (expected !== null && typeof expected === "object" && actual !== null && typeof actual === "object") {
expect(actual).toEqual(expected);
} else {
expect(actual).toBe(expected);
}
}
function assertTrue(val, msg) {
expect(val).toBeTrue();
}
function assertFalse(val, msg) {
expect(val).toBeFalse();
}
function assertNull(val, msg) {
expect(val).toBeNull();
}
function assertNotNull(val, msg) {
expect(val).not.toBeNull();
}
function assertThrows(fn, type_opt, msg_opt) {
if (typeof fn === "string") {
expect(() => eval(fn)).toThrow();
} else {
expect(fn).toThrow();
}
}
function assertDoesNotThrow(fn, msg) {
if (typeof fn === "string") {
eval(fn);
} else {
fn();
}
}
function assertInstanceof(val, type, msg) {
expect(val instanceof type).toBeTrue();
}
function assertUnreachable(msg) {
expect().fail("unreachable" + (msg ? ": " + msg : ""));
}
function assertEarlyError(code) {
assertThrows(() => new Function(code));
}
function assertThrowsAtRuntime(code, type_opt) {
const f = new Function(code);
assertThrows(f, type_opt);
}
function assertArrayEquals(expected, actual) {
expect(actual).toEqual(expected);
}
test("regexp-unicode-sets", () => {
assertEarlyError("/./uv");
assertThrowsAtRuntime("new RegExp('.','uv')", SyntaxError);
assertEquals("v", /./v.flags);
assertTrue(/./v.unicodeSets);
// Characters that require escaping within a character class in /v mode
assertEarlyError("/[(]/v");
assertEarlyError("/[)]/v");
assertEarlyError("/[[]/v");
assertEarlyError("/[]]/v");
assertEarlyError("/[{]/v");
assertEarlyError("/[}]/v");
assertEarlyError("/[/]/v");
assertEarlyError("/[-]/v");
// Need to escape the backslash, as assertEarlyError uses eval().
assertEarlyError("/[\\]/v");
assertEarlyError("/[|]/v");
assertEarlyError("/[&&]/v");
assertEarlyError("/[!!]/v");
assertEarlyError("/[##]/v");
assertEarlyError("/[$$]/v");
assertEarlyError("/[%%]/v");
assertEarlyError("/[**]/v");
assertEarlyError("/[++]/v");
assertEarlyError("/[,,]/v");
assertEarlyError("/[..]/v");
assertEarlyError("/[::]/v");
assertEarlyError("/[;;]/v");
assertEarlyError("/[<<]/v");
assertEarlyError("/[==]/v");
assertEarlyError("/[>>]/v");
assertEarlyError("/[??]/v");
assertEarlyError("/[@@]/v");
// The first ^ negates the class. The following two are not valid.
assertEarlyError("/[^^^]/v");
assertEarlyError("/[``]/v");
assertEarlyError("/[~~]/v");
assertEarlyError("/[a&&&]/v");
assertEarlyError("/[&&&a]/v");
// Unterminated string disjunction.
assertEarlyError("/[\\q{foo]/v");
assertEarlyError("/[\\q{foo|]/v");
// Negating classes containing strings is not allowed.
assertEarlyError("/[^\\q{foo}]/v");
assertEarlyError("/[^\\q{}]/v"); // Empty string counts as string.
assertEarlyError("/[^[\\q{foo}]]/v");
assertEarlyError("/[^[\\p{Basic_Emoji}]/v");
assertEarlyError("/[^\\q{foo}&&\\q{bar}]/v");
assertEarlyError("/[^\\q{foo}--\\q{bar}]/v");
// Exceptions when negating the class is allowed:
// The "string" contains only single characters.
/[^\q{a|b|c}]/v;
// Not all operands of an intersection contain strings.
/[^\q{foo}&&\q{bar}&&a]/v;
// The first operand of a subtraction doesn't contain strings.
/[^a--\q{foo}--\q{bar}]/v;
// Negated properties of strings are not allowed.
assertEarlyError("/\\P{Basic_Emoji}/v");
assertEarlyError("/\\P{Emoji_Keycap_Sequence}/v");
assertEarlyError("/\\P{RGI_Emoji_Modifier_Sequence}/v");
assertEarlyError("/\\P{RGI_Emoji_Flag_Sequence}/v");
assertEarlyError("/\\P{RGI_Emoji_Tag_Sequence}/v");
assertEarlyError("/\\P{RGI_Emoji_ZWJ_Sequence}/v");
assertEarlyError("/\\P{RGI_Emoji}/v");
// Invalid identity escape in string disjunction.
assertEarlyError("/[\\q{\\w}]/v");
const allAscii = Array.from({ length: 127 }, (v, i) => {
return String.fromCharCode(i);
});
function check(re, expectMatch, expectNoMatch = [], negationValid = true) {
if (expectNoMatch === undefined) {
const expectSet = new Set(
expectMatch.map(val => {
return typeof val == "number" ? String(val) : val;
})
);
expectNoMatch = allAscii.filter(val => !expectSet.has(val));
}
for (const match of expectMatch) {
assertTrue(re.test(match), `${re}.test(${match})`);
}
for (const noMatch of expectNoMatch) {
assertFalse(re.test(noMatch), `${re}.test(${noMatch})`);
}
if (!negationValid) {
// Negation of classes containing strings is an error.
const negated = `[^${re.source}]`;
assertThrows(
() => {
new RegExp(negated, `${re.flags}`);
},
SyntaxError,
`Invalid regular expression: /${negated}/${re.flags}: ` + `Negated character class may contain strings`
);
} else {
// Nest the current RegExp in a negated class and check expectations are
// inversed.
const inverted = new RegExp(`[^${re.source}]`, re.flags);
for (const match of expectMatch) {
assertFalse(inverted.test(match), `${inverted}.test(${match})`);
}
for (const noMatch of expectNoMatch) {
assertTrue(inverted.test(noMatch), `${inverted}.test(${noMatch})`);
}
}
}
// Union with nested class
check(/[\da-f[xy][^[^z]]]/v, Array.from("0123456789abcdefxyz"), Array.from("ghijklmnopqrstuv!?"));
// Intersections
check(/[\d&&[0-9]]/v, Array.from("0123456789"), []);
check(/[\d&&0]/v, [0], Array.from("123456789"));
check(/[\d&&9]/v, [9], Array.from("012345678"));
check(/[\d&&[02468]]/v, Array.from("02468"), Array.from("13579"));
check(/[\d&&[13579]]/v, Array.from("13579"), Array.from("02468"));
check(/[\w&&[^a-zA-Z_]]/v, Array.from("0123456789"), Array.from("abcdxyzABCDXYZ_!?"));
check(/[^\w&&[a-zA-Z_]]/v, Array.from("0123456789!?"), Array.from("abcdxyzABCDXYZ_"));
// Subtractions
check(/[\d--[!-%]]/v, Array.from("0123456789"));
check(/[\d--[A-Z]]/v, Array.from("0123456789"));
check(/[\d--[0-9]]/v, []);
check(/[\d--[\w]]/v, []);
check(/[\d--0]/v, Array.from("123456789"));
check(/[\d--9]/v, Array.from("012345678"));
check(/[[\d[a-c]]--9]/v, Array.from("012345678abc"));
check(/[\d--[02468]]/v, Array.from("13579"));
check(/[\d--[13579]]/v, Array.from("02468"));
check(/[[3-7]--[0-9]]/v, []);
check(/[[3-7]--[0-7]]/v, []);
check(/[[3-7]--[3-9]]/v, []);
check(/[[3-79]--[0-7]]/v, [9]);
check(/[[3-79]--[3-9]]/v, []);
check(/[[3-7]--[0-3]]/v, Array.from("4567"));
check(/[[3-7]--[0-5]]/v, Array.from("67"));
check(/[[3-7]--[7-9]]/v, Array.from("3456"));
check(/[[3-7]--[5-9]]/v, Array.from("34"));
check(/[[3-7a-c]--[0-3]]/v, Array.from("4567abc"));
check(/[[3-7a-c]--[0-5]]/v, Array.from("67abc"));
check(/[[3-7a-c]--[7-9]]/v, Array.from("3456abc"));
check(/[[3-7a-c]--[5-9]]/v, Array.from("34abc"));
check(/[[2-8]--[0-3]--5--[7-9]]/v, Array.from("46"));
check(/[[2-57-8]--[0-3]--[5-7]]/v, Array.from("48"));
check(/[[0-57-8]--[1-34]--[5-7]]/v, Array.from("08"));
check(/[\d--[^02468]]/v, Array.from("02468"));
check(/[\d--[^13579]]/v, Array.from("13579"));
check(/[[a-c]--\0]/v, Array.from("abc"));
// Ignore-Case
check(/[Ā-č]/v, Array.from("ĀāĂ㥹Ćć"), Array.from("abc"));
check(/[ĀĂĄĆ]/iv, Array.from("ĀāĂ㥹Ćć"), Array.from("abc"));
check(/[āăąć]/iv, Array.from("ĀāĂ㥹Ćć"), Array.from("abc"));
// Ignore-Case intersections
check(/[\w&&[^a-z_]]/iv, Array.from("0123456789"), Array.from("abcdxyzABCDXYZ_!?"));
check(/[^\w&&[a-z_]]/iv, Array.from("0123456789!?"), Array.from("abcdxyzABCDXYZ_"));
check(/[K&&]/iv, Array.from("Kk")); // K && U+212A (Kelvin Sign)
check(/[&&K]/iv, Array.from("Kk")); // U+212A (Kelvin Sign) && K
check(/[K&&\u{212A}]/iv, Array.from("Kk\u{212A}"));
check(/[\u{212A}&&K]/iv, Array.from("Kk\u{212A}"));
// Ignore-Case subtractions
check(/[\d--[A-Z]]/iv, Array.from("0123456789"), Array.from("abcdEFGH"));
check(/[[\d[a-c]]--9]/iv, Array.from("012345678abcABC"), Array.from("9xX"));
check(/[K--]/iv, [], Array.from("Kk")); // K -- U+212A (Kelvin Sign)
check(/[--k]/iv, [], Array.from("Kk")); // U+212A (Kelvin Sign) -- k
check(/[K--\u{212A}]/iv, [], Array.from("Kk"));
check(/[\u{212A}--k]/iv, [], Array.from("Kk"));
// String disjunctions
check(/[\q{foo|bar|0|5}]/v, ["foo", "bar", 0, 5], ["fo", "baz"], false);
check(/[\q{foo|bar}[05]]/v, ["foo", "bar", 0, 5], ["fo", "baz"], false);
check(/[\q{foo|bar|0|5}&&\q{bar}]/v, ["bar"], ["foo", 0, 5, "fo", "baz"], false);
// The second operand of the intersection doesn't contain strings, so the result
// will not contain strings and therefore negation is valid.
check(/[\q{foo|bar|0|5}&&\d]/v, [0, 5], ["foo", "bar", "fo", "baz"], true);
check(/[\q{foo|bar|0|5}--\q{foo}]/v, ["bar", 0, 5], ["foo", "fo", "baz"], false);
check(/[\q{foo|bar|0|5}--\d]/v, ["foo", "bar"], [0, 5, "fo", "baz"], false);
check(/[\q{foo|bar|3|2|0}--\d]/v, ["foo", "bar"], [0, 1, 2, 3, 4, 5, "fo", "baz"], false);
check(/[\q{foo|bar|0|5}&&\q{bAr}]/iv, ["bar", "bAr", "BAR"], ["foo", 0, 5, "fo", "baz"], false);
check(/[\q{foo|bar|0|5}--\q{FoO}]/iv, ["bar", "bAr", "BAR", 0, 5], ["foo", "FOO", "fo", "baz"], false);
check(/[\q{ĀĂĄĆ|AaAc}&&\q{āăąć}]/iv, ["ĀĂĄĆ", "āăąć"], ["AaAc"], false);
check(/[\q{ĀĂĄĆ|AaAc}--\q{āăąć}]/iv, ["AaAc", "aAaC"], ["ĀĂĄĆ", "āăąć"], false);
// Empty nested classes.
check(/[a-c\q{foo|bar}[]]/v, ["a", "b", "c", "foo", "bar"], [], false);
check(/[[a-c\q{foo|bar}]&&[]]/v, [], ["a", "b", "c", "foo", "bar"], true);
check(/[[a-c\q{foo|bar}]--[]]/v, ["a", "b", "c", "foo", "bar"], [], false);
check(/[[]&&[a-c\q{foo|bar}]]/v, [], ["a", "b", "c", "foo", "bar"], true);
check(/[[]--[a-c\q{foo|bar}]]/v, [], ["a", "b", "c", "foo", "bar"], true);
// Empty string disjunctions matches nothing, but succeeds.
let res = /[\q{}]/v.exec("foo");
assertNotNull(res);
assertEquals(1, res.length);
assertEquals("", res[0]);
// Ensure longest strings are matched first.
assertEquals(["xyz"], /[a-c\q{W|xy|xyz}]/v.exec("xyzabc"));
assertEquals(["xyz"], /[a-c\q{W|xyz|xy}]/v.exec("xyzabc"));
assertEquals(["xyz"], /[\q{W|xyz|xy}a-c]/v.exec("xyzabc"));
// Empty string is last.
assertEquals(["a"], /[\q{W|}a-c]/v.exec("abc"));
// Some more sophisticated tests taken from
// https://v8.dev/features/regexp-v-flag
assertTrue(/^\p{RGI_Emoji}$/v.test(""));
assertTrue(/^\p{RGI_Emoji}$/v.test("👨🏾"));
assertFalse(/[\p{Script_Extensions=Greek}--π]/v.test("π"));
assertFalse(/[\p{Script_Extensions=Greek}--[αβγ]]/v.test("α"));
assertFalse(/[\p{Script_Extensions=Greek}--[α-γ]]/v.test("β"));
assertTrue(/[\p{Decimal_Number}--[0-9]]/v.test("𑜹"));
assertFalse(/[\p{Decimal_Number}--[0-9]]/v.test("4"));
assertTrue(/^\p{RGI_Emoji_Tag_Sequence}$/v.test("🏴󠁧󠁢󠁳󠁣󠁴󠁿"));
assertFalse(/^[\p{RGI_Emoji_Tag_Sequence}--\q{🏴󠁧󠁢󠁳󠁣󠁴󠁿}]$/v.test("🏴󠁧󠁢󠁳󠁣󠁴󠁿"));
assertTrue(/[\p{Script_Extensions=Greek}&&\p{Letter}]/v.test("π"));
assertFalse(/[\p{Script_Extensions=Greek}&&\p{Letter}]/v.test("𐆊"));
assertTrue(/[\p{White_Space}&&\p{ASCII}]/v.test("\n"));
assertFalse(/[\p{White_Space}&&\p{ASCII}]/v.test("\u2028"));
assertTrue(/[\p{Script_Extensions=Mongolian}&&\p{Number}]/v.test(""));
assertFalse(/[\p{Script_Extensions=Mongolian}&&\p{Number}]/v.test(""));
assertTrue(/^[\p{Emoji_Keycap_Sequence}\p{ASCII}\q{🇧🇪|abc}xyz0-9]$/v.test("4"));
assertTrue(/^[\p{Emoji_Keycap_Sequence}\p{ASCII}\q{🇧🇪|abc}xyz0-9]$/v.test("_"));
assertTrue(/^[\p{Emoji_Keycap_Sequence}\p{ASCII}\q{🇧🇪|abc}xyz0-9]$/v.test("🇧🇪"));
assertTrue(/^[\p{Emoji_Keycap_Sequence}\p{ASCII}\q{🇧🇪|abc}xyz0-9]$/v.test("abc"));
assertTrue(/^[\p{Emoji_Keycap_Sequence}\p{ASCII}\q{🇧🇪|abc}xyz0-9]$/v.test("x"));
assertTrue(/^[\p{Emoji_Keycap_Sequence}\p{ASCII}\q{🇧🇪|abc}xyz0-9]$/v.test("4"));
assertTrue(/[\p{RGI_Emoji_Flag_Sequence}\p{RGI_Emoji_Tag_Sequence}]/v.test("🇧🇪"));
assertTrue(/[\p{RGI_Emoji_Flag_Sequence}\p{RGI_Emoji_Tag_Sequence}]/v.test("🏴󠁧󠁢󠁥󠁮󠁧󠁿"));
assertTrue(/[\p{RGI_Emoji_Flag_Sequence}\p{RGI_Emoji_Tag_Sequence}]/v.test("🇨🇭"));
assertTrue(/[\p{RGI_Emoji_Flag_Sequence}\p{RGI_Emoji_Tag_Sequence}]/v.test("🏴󠁧󠁢󠁷󠁬󠁳󠁿"));
// Check new case-folding semantics.
assertEquals("XXXXXX4#", "aAbBcC4#".replaceAll(/\p{Lowercase_Letter}/giv, "X"));
assertEquals("XXXXXX4#", "aAbBcC4#".replaceAll(/[^\P{Lowercase_Letter}]/giv, "X"));
assertFalse(/\P{ASCII}/iv.test("K"));
assertFalse(/^\P{Lowercase}/iv.test("A"));
});