aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/bun.js/oniguruma-regexp.test.ts282
1 files changed, 239 insertions, 43 deletions
diff --git a/test/bun.js/oniguruma-regexp.test.ts b/test/bun.js/oniguruma-regexp.test.ts
index 48906fb7d..372e8eb99 100644
--- a/test/bun.js/oniguruma-regexp.test.ts
+++ b/test/bun.js/oniguruma-regexp.test.ts
@@ -2,10 +2,186 @@ import { OnigurumaRegExp } from "bun";
import { expect, it, test } from "bun:test";
import { gc as gcTrace } from "./gc";
+it("repeated match and exec calls", () => {
+ for (let i = 0; i < 20000; i++) {
+ let r1 = new OnigurumaRegExp("//.+?/[^?]+", "sg");
+ let r2 = new RegExp("//.+?/[^?]+", "sg");
+ let s1 = "https://dylan-conway.com/profile";
+ expect(s1.match(r1)[0] === s1.match(r2)[0]).toBe(true);
+ expect(r1.exec(s1)[0] === r2.exec(s1)[0]).toBe(true);
+ }
+});
+
+it("repeated match and exec calls no global flag", () => {
+ for (let i = 0; i < 20000; i++) {
+ let r1 = new OnigurumaRegExp("//.+?/[^?]+", "s");
+ let r2 = new RegExp("//.+?/[^?]+", "s");
+ let s1 = "https://dylan-conway.com/profile";
+ expect(r1.exec(s1)[0] === r2.exec(s1)[0]).toBe(true);
+ expect(s1.match(r1)[0] === s1.match(r2)[0]).toBe(true);
+ }
+});
+
+const rb1 = new OnigurumaRegExp("//.+?/[^?]+", "s");
+const rb2 = new RegExp("//.+?/[^?]+", "s");
+it("repeated match calls with global regex without global flag", () => {
+ for (let i = 0; i < 20000; i++) {
+ let s1 = "https://dylan-conway.com/profile";
+ expect(rb1.exec(s1)[0] === rb2.exec(s1)[0]).toBe(true);
+ expect(s1.match(rb1)[0] === s1.match(rb2)[0]).toBe(true);
+ }
+});
+
it("escaped characters in character classes", () => {
+ expect(
+ new RegExp("[a-z]").exec("a")[0] ===
+ new OnigurumaRegExp("[a-z]").exec("a")[0]
+ ).toBe(true);
+
+ Bun.gc(true);
+
+ expect(
+ new RegExp("[a-z]").exec("b")[0] ===
+ new OnigurumaRegExp("[a-z]").exec("b")[0]
+ ).toBe(true);
+
+ Bun.gc(true);
+
+ expect(new RegExp("[a-zA-Z0-9_]+").exec("B9")[0]).toBe(
+ new OnigurumaRegExp("[a-zA-Z0-9_]+").exec("B9")[0]
+ );
+ Bun.gc(true);
+ expect(new RegExp("[a-z]").exec("-")).toBe(null);
+ Bun.gc(true);
+ expect(new OnigurumaRegExp("[a-z]").exec("-")).toBe(null);
+ Bun.gc(true);
+ expect(new RegExp("[a\\-z]").exec("-")[0]).toBe("-");
+ Bun.gc(true);
+ expect(new OnigurumaRegExp("[a\\-z]").exec("-")[0]).toBe("-");
+ Bun.gc(true);
+ expect(new RegExp("[a\\-z]").exec("a")[0]).toBe("a");
+ Bun.gc(true);
+ expect(new OnigurumaRegExp("[a\\-z]").exec("a")[0]).toBe("a");
+ Bun.gc(true);
+ expect(new RegExp("[a\\-z]").exec("z")[0]).toBe("z");
+ Bun.gc(true);
+ expect(new OnigurumaRegExp("[a\\-z]").exec("z")[0]).toBe("z");
+ Bun.gc(true);
+ expect(new RegExp("[a\\-z]").exec("b")).toBe(null);
+ Bun.gc(true);
+ expect(new OnigurumaRegExp("[a\\-z]").exec("b")).toBe(null);
+ Bun.gc(true);
+
+ expect(new RegExp("[^b-c]").exec("a")[0]).toBe(
+ new OnigurumaRegExp("[^b-c]").exec("a")[0]
+ );
+ Bun.gc(true);
+
+ expect(new RegExp("[\\^b-c]").exec("a")).toBe(null);
+ expect(new OnigurumaRegExp("[\\^b-c]").exec("a")).toBe(null);
+ Bun.gc(true);
+
+ expect(new RegExp("[\\^b-c]").exec("^c")[0]).toBe("^");
+ expect(new OnigurumaRegExp("[\\^b-c]").exec("^c")[0]).toBe("^");
+ Bun.gc(true);
+
+ expect(new RegExp("[a^b-c]").exec("a^")[0]).toBe("a");
+ expect(new OnigurumaRegExp("[a^b-c]").exec("a^")[0]).toBe("a");
+ Bun.gc(true);
+
+ expect(new RegExp("[\\\\]").exec("\\")[0]).toBe("\\");
+ expect(new OnigurumaRegExp("[\\\\]").exec("\\")[0]).toBe("\\");
+ Bun.gc(true);
+
+ let p = "//.+?[^?]+";
+ let s = "https://dylan-conway.com/profile";
+ const b1 = new RegExp(p, "gs");
+ const b2 = new OnigurumaRegExp(p, "gs");
+ Bun.gc(true);
+ expect(s.match(b1)[0] === s.match(b2)[0]).toBe(true);
+ Bun.gc(true);
+
+ const b3 = new RegExp("[\\^]");
+ const b4 = new OnigurumaRegExp("[\\^]");
+ Bun.gc(true);
+ expect(
+ "https://dylan-co^nway.com/profile".match(b3)[0] ===
+ "https://dylan-co^nway.com/profile".match(b4)[0]
+ ).toBe(true);
+ Bun.gc(true);
+
+ // prettier-ignore
+ p = "\/\/.+?\/[^?]+";
+ s = "https://dylan-conway.com/profile";
+ Bun.gc(true);
+ expect(s.match(new OnigurumaRegExp(p, "gs"))[0]).toBe(
+ new RegExp(p, "gs").exec(s)[0]
+ );
+ Bun.gc(true);
+
+ // middle no escape
+ p = "[.i^e]+";
+ s = "https://dylan-co^nway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
+ // middle with escape
+ p = "[.i\\^e]+";
+ s = "https://dylan-co^nway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
+ // end with escape
+ p = "[.ie\\^]+";
+ s = "https://dylan-co^nway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
+ // end no escape
+ p = "[.ie^]+";
+ s = "https://dylan-co^nway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
+ // start no escape
+ p = "[^.ie]+";
+ s = "https://dylan-co^nway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
+ // start with escape
+ p = "[\\^.ie]+";
+ s = "https://dylan-co^nway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
+ // middle with escape
+ p = "[.i\\-e]+";
+ s = "https://dylan-conway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
+ // end with escape
+ p = "[.ie\\-]+";
+ s = "https://dylan-conway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
+ // end no escape
+ p = "[.ie-]+";
+ s = "https://dylan-conway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
+ // start no escape
+ p = "[-.ie]+";
+ s = "https://dylan-conway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
+ // start with escape
+ p = "[\\-.ie]+";
+ s = "https://dylan-conway.com/profile";
+ expect(new OnigurumaRegExp(p).exec(s)[0]).toBe(new RegExp(p).exec(s)[0]);
+
let r1 = new RegExp("^([[(]-?[\\d]+)?,?(-?[\\d]+[\\])])?$").exec("(1,1]");
- let r2 = new OnigurumaRegExp("^([[(]-?[\\d]+)?,?(-?[\\d]+[\\])])?$").exec("(1,1]");
+ Bun.gc(true);
+ let r2 = new OnigurumaRegExp("^([[(]-?[\\d]+)?,?(-?[\\d]+[\\])])?$").exec(
+ "(1,1]"
+ );
+ Bun.gc(true);
expect(r1[0]).toBe(r2[0]);
+ Bun.gc(true);
let r3 = new RegExp("[\\d],[\\d]").exec("1,2");
let r4 = new OnigurumaRegExp("[\\d],[\\d]").exec("1,2");
@@ -54,15 +230,15 @@ it("escaped characters in character classes", () => {
let r31 = new RegExp("[[\\]][[\\]]").exec("]]");
let r32 = new OnigurumaRegExp("[[\\]][[\\]]").exec("]]");
expect(r31[0]).toBe(r32[0]);
-
+
let r33 = new RegExp("[\\]][\\]]").exec("]]");
let r34 = new OnigurumaRegExp("[\\]][\\]]").exec("]]");
expect(r33[0]).toBe(r34[0]);
-
+
let r35 = new RegExp("[a-z&&[^aeiou]").exec("a");
let r36 = new OnigurumaRegExp("[a-z&&[^aeiou]").exec("a");
expect(r35[0]).toBe(r36[0]);
-
+
let r37 = new RegExp("[a-z&&[^aeiou]]").exec("a]");
let r38 = new OnigurumaRegExp("[a-z&&[^aeiou]]").exec("a]");
expect(r37[0]).toBe(r38[0]);
@@ -107,9 +283,8 @@ test("OnigurumaRegExp.prototype.exec() 2", () => {
});
test("OnigurumaRegExp.prototype.exec() 3", () => {
-
let a22 = new OnigurumaRegExp("\\x9\\x5e", "gd");
- let a22_1 = a22.exec("table fox9\^otball, fox9\^osball");
+ let a22_1 = a22.exec("table fox9^otball, fox9^osball");
expect(a22_1[0]).toBe("x9^");
let a1 = new OnigurumaRegExp("x3\\x5e", "gd");
@@ -130,12 +305,12 @@ test("OnigurumaRegExp.prototype.exec() 3", () => {
test("OnigurumaRegExp.prototype.exec() 4", () => {
let a2 = new RegExp("\\x3\\x5e", "gd");
- let a2_1 = a2.exec("table fox3\^otball, fox3\^osball");
- a2_1 = a2.exec("table fox3\^otball, fox3\^osball");
+ let a2_1 = a2.exec("table fox3^otball, fox3^osball");
+ a2_1 = a2.exec("table fox3^otball, fox3^osball");
for (const RegExpConstructor of [OnigurumaRegExp, RegExp]) {
let a2 = new RegExpConstructor("\\x3\\x5e", "gd");
- let a2_1 = a2.exec("table fox3\^otball, fox3\^osball");
+ let a2_1 = a2.exec("table fox3^otball, fox3^osball");
expect(a2_1[0]).toBe("x3^");
expect(new RegExpConstructor("\\x3").source).toBe("\\x3");
@@ -144,22 +319,30 @@ test("OnigurumaRegExp.prototype.exec() 4", () => {
expect(new RegExpConstructor("j\\x3\\x2").source).toBe("j\\x3\\x2");
expect(new RegExpConstructor("\\x3\\x5\\j").source).toBe("\\x3\\x5\\j");
expect(new RegExpConstructor("\\x3\\x7\\xa").source).toBe("\\x3\\x7\\xa");
- expect(new RegExpConstructor("\\j323\\x7\\xa").source).toBe("\\j323\\x7\\xa");
+ expect(new RegExpConstructor("\\j323\\x7\\xa").source).toBe(
+ "\\j323\\x7\\xa"
+ );
expect(new RegExpConstructor("\\x56").test("V")).toBe(true);
}
});
test("OnigurumaRegExp.prototype.test()", () => {
- expect(new RegExp("\\\\(?![*+?^${}(|)[\\]])", "g").test('\\')).toBe(true);
- expect(new OnigurumaRegExp("\\\\(?![*+?^${}(|)[\\]])", "g").test('\\')).toBe(true);
+ expect(new RegExp("\\\\(?![*+?^${}(|)[\\]])", "g").test("\\")).toBe(true);
+ expect(new OnigurumaRegExp("\\\\(?![*+?^${}(|)[\\]])", "g").test("\\")).toBe(
+ true
+ );
expect(new RegExp("\\x56").test("V")).toBe(true);
expect(new OnigurumaRegExp("\\x56").test("V")).toBe(true);
- expect(new RegExp('//').compile('\\\\(?![*+?^${}(|)[\\]])', 'g').test('\\')).toBe(true);
- let r = new OnigurumaRegExp('//');
- expect(r.compile('\\\\(?![*+?^${}(|)[\\]])', 'g').test('\\')).toBe(true);
- expect(new OnigurumaRegExp('').compile('\\\\(?![*+?^${}(|)[\\]])', 'g').test('\\')).toBe(true);
+ expect(
+ new RegExp("//").compile("\\\\(?![*+?^${}(|)[\\]])", "g").test("\\")
+ ).toBe(true);
+ let r = new OnigurumaRegExp("//");
+ expect(r.compile("\\\\(?![*+?^${}(|)[\\]])", "g").test("\\")).toBe(true);
+ expect(
+ new OnigurumaRegExp("").compile("\\\\(?![*+?^${}(|)[\\]])", "g").test("\\")
+ ).toBe(true);
});
test("OnigurumaRegExp flag order", () => {
@@ -234,16 +417,15 @@ test("OnigurumaRegExp flags", () => {
expect(/a/g.toString()).toBe("/a/g");
expect(/a/y.toString()).toBe("/a/y");
expect(/a/m.toString()).toBe("/a/m");
- expect(/a/sg.toString()).toBe("/a/gs");
- expect(/a/ys.toString()).toBe("/a/sy");
+ expect(/a/gs.toString()).toBe("/a/gs");
+ expect(/a/sy.toString()).toBe("/a/sy");
expect(/a/gm.toString()).toBe("/a/gm");
- expect(/a/sgy.toString()).toBe("/a/gsy");
- expect(/a/sgm.toString()).toBe("/a/gms");
- expect(/a/ymg.toString()).toBe("/a/gmy");
+ expect(/a/gsy.toString()).toBe("/a/gsy");
+ expect(/a/gms.toString()).toBe("/a/gms");
+ expect(/a/gmy.toString()).toBe("/a/gmy");
// expect(/a/d.toString()).toBe("/a/d");
// expect(/a/dgimsuy.toString()).toBe("/a/dgimsuy");
-
// case insensitive option
for (const RegExpConstructor of [OnigurumaRegExp, RegExp]) {
expect(new RegExpConstructor("Is ThIs SqL?").test("IS THIS SQL?")).toBe(
@@ -526,31 +708,35 @@ it("String.prototype.split", () => {
it("escapes characters, unicode, and hex", () => {
for (const RegExpConstructor of [OnigurumaRegExp, RegExp]) {
- expect(new RegExpConstructor("[\\x00-\\x1F]").toString()).toBe("/[\\x00-\\x1F]/");
- expect(new RegExpConstructor("[\\u0000-\\u001F]").toString()).toBe("/[\\u0000-\\u001F]/");
- var s = /\\x{7HHHHHHH}(?=\\u{1233})/
- let a = new RegExpConstructor('\u{0001F46E}');
- expect(a.exec('👮')[0]).toBe('👮');
+ expect(new RegExpConstructor("[\\x00-\\x1F]").toString()).toBe(
+ "/[\\x00-\\x1F]/"
+ );
+ expect(new RegExpConstructor("[\\u0000-\\u001F]").toString()).toBe(
+ "/[\\u0000-\\u001F]/"
+ );
+ var s = /\\x{7HHHHHHH}(?=\\u{1233})/;
+ let a = new RegExpConstructor("\u{0001F46E}");
+ expect(a.exec("👮")[0]).toBe("👮");
}
- let y = new OnigurumaRegExp('[👮\\x7F](?<=👮)');
- expect(y.exec('👮\\x{7F}')[0]).toBe('👮');
+ let y = new OnigurumaRegExp("[👮\\x7F](?<=👮)");
+ expect(y.exec("👮\\x{7F}")[0]).toBe("👮");
- let by = new OnigurumaRegExp('[👮\\cx7f](?<=👮)');
- expect(y.exec('👮\\x{7F}')[0]).toBe('👮');
+ let by = new OnigurumaRegExp("[👮\\cx7f](?<=👮)");
+ expect(y.exec("👮\\x{7F}")[0]).toBe("👮");
- let bz = new OnigurumaRegExp('[👮\\x7](?<=👮)');
+ let bz = new OnigurumaRegExp("[👮\\x7](?<=👮)");
- let d = new OnigurumaRegExp('[\u{0001F46E}\x7F](?<=\u{0001F46E})');
- expect(d.exec('👮\x7F')[0]).toBe('👮');
+ let d = new OnigurumaRegExp("[\u{0001F46E}\x7F](?<=\u{0001F46E})");
+ expect(d.exec("👮\x7F")[0]).toBe("👮");
let y_2 = /[[👮\x7F](?<=👮)]/;
- expect(y_2.exec('👮\x7F')[0]).toBe('👮');
+ expect(y_2.exec("👮]")[0]).toBe("👮]");
let a1 = new OnigurumaRegExp("(f\xf3oo)", "gd");
let a1_1 = a1.exec("table f\xf3ootball, f\xf3oosball");
a1_1 = a1.exec("table f\xf3ootball, f\xf3oosball");
-
+
let a2 = new RegExp("(f\xf3oo)", "dg");
let a2_1 = a2.exec("table f\xf3ootball, f\xf3oosball");
a2_1 = a2.exec("table f\xf3ootball, f\xf3oosball");
@@ -580,17 +766,27 @@ it("lookbehinds", () => {
let small = /(?:)/;
expect(small instanceof OnigurumaRegExp).toBe(false);
- expect(/[\x00-\x1F\x27\x5C\x7F-\x9F]|[\uD800-\uDBFF]\(?<=[\uDC00-\uDFFF]\)|(?!.*[\uD800-\uDBFF][\uDC00-\uDFFF]).*[\uDC00-\uDFFF]/ instanceof RegExp).toBe(true);
- expect(/[\x00-\x1F\x27\x5C\x7F-\x9F]|[\uD800-\uDBFF](?<=[\uDC00-\uDFFF])|(?!.*[\uD800-\uDBFF][\uDC00-\uDFFF]).*[\uDC00-\uDFFF]/ instanceof OnigurumaRegExp).toBe(true);
+ expect(
+ /[\x00-\x1F\x27\x5C\x7F-\x9F]|[\uD800-\uDBFF]\(?<=[\uDC00-\uDFFF]\)|(?!.*[\uD800-\uDBFF][\uDC00-\uDFFF]).*[\uDC00-\uDFFF]/ instanceof
+ RegExp
+ ).toBe(true);
+ expect(
+ /[\x00-\x1F\x27\x5C\x7F-\x9F]|[\uD800-\uDBFF](?<=[\uDC00-\uDFFF])|(?!.*[\uD800-\uDBFF][\uDC00-\uDFFF]).*[\uDC00-\uDFFF]/ instanceof
+ OnigurumaRegExp
+ ).toBe(true);
expect(/(?<=\1d(o))/ instanceof OnigurumaRegExp).toBe(true);
expect(/\(?<=\1d(o)\)/ instanceof OnigurumaRegExp).toBe(false);
- expect(/(?!.*[\uD800-\uDBFF][\uDC00-\uDFFF]).*[\uDC00-\uDFFF]/ instanceof RegExp).toBe(true);
- expect(/\(?!.*[\uD800-\uDBFF][\uDC00-\uDFFF]\).*[\uDC00-\uDFFF]/ instanceof RegExp).toBe(true);
+ expect(
+ /(?!.*[\uD800-\uDBFF][\uDC00-\uDFFF]).*[\uDC00-\uDFFF]/ instanceof RegExp
+ ).toBe(true);
+ expect(
+ /\(?!.*[\uD800-\uDBFF][\uDC00-\uDFFF]\).*[\uDC00-\uDFFF]/ instanceof RegExp
+ ).toBe(true);
- let e = new OnigurumaRegExp('\(?<=\)');
- expect(e.source).toBe('(?<=)');
- expect(new OnigurumaRegExp('(?<=)').source).toBe('(?<=)');
+ let e = new OnigurumaRegExp("(?<=)");
+ expect(e.source).toBe("(?<=)");
+ expect(new OnigurumaRegExp("(?<=)").source).toBe("(?<=)");
expect(/\(?<=\)/.source).toBe("\\(?<=\\)");
expect(/(?<=)/.source).toBe("(?<=)");