diff options
Diffstat (limited to 'deps/v8/test/mjsunit/es6/unicode-escapes-in-regexps.js')
-rw-r--r-- | deps/v8/test/mjsunit/es6/unicode-escapes-in-regexps.js | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/deps/v8/test/mjsunit/es6/unicode-escapes-in-regexps.js b/deps/v8/test/mjsunit/es6/unicode-escapes-in-regexps.js new file mode 100644 index 0000000000..2d2d11825d --- /dev/null +++ b/deps/v8/test/mjsunit/es6/unicode-escapes-in-regexps.js @@ -0,0 +1,285 @@ +// Copyright 2014 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. + +// ES6 extends the \uxxxx escape and also allows \u{xxxxx}. + +function testRegexpHelper(r) { + assertTrue(r.test("foo")); + assertTrue(r.test("boo")); + assertFalse(r.test("moo")); +} + + +(function TestUnicodeEscapes() { + testRegexpHelper(/(\u0066|\u0062)oo/); + testRegexpHelper(/(\u0066|\u0062)oo/u); + testRegexpHelper(/(\u{0066}|\u{0062})oo/u); + testRegexpHelper(/(\u{66}|\u{000062})oo/u); + + // Note that we need \\ inside a string, otherwise it's interpreted as a + // unicode escape inside a string. + testRegexpHelper(new RegExp("(\\u0066|\\u0062)oo")); + testRegexpHelper(new RegExp("(\\u0066|\\u0062)oo", "u")); + testRegexpHelper(new RegExp("(\\u{0066}|\\u{0062})oo", "u")); + testRegexpHelper(new RegExp("(\\u{66}|\\u{000062})oo", "u")); + + // Though, unicode escapes via strings should work too. + testRegexpHelper(new RegExp("(\u0066|\u0062)oo")); + testRegexpHelper(new RegExp("(\u0066|\u0062)oo", "u")); + testRegexpHelper(new RegExp("(\u{0066}|\u{0062})oo", "u")); + testRegexpHelper(new RegExp("(\u{66}|\u{000062})oo", "u")); +})(); + + +(function TestUnicodeEscapesInCharacterClasses() { + testRegexpHelper(/[\u0062-\u0066]oo/); + testRegexpHelper(/[\u0062-\u0066]oo/u); + testRegexpHelper(/[\u{0062}-\u{0066}]oo/u); + testRegexpHelper(/[\u{62}-\u{00000066}]oo/u); + + // Note that we need \\ inside a string, otherwise it's interpreted as a + // unicode escape inside a string. + testRegexpHelper(new RegExp("[\\u0062-\\u0066]oo")); + testRegexpHelper(new RegExp("[\\u0062-\\u0066]oo", "u")); + testRegexpHelper(new RegExp("[\\u{0062}-\\u{0066}]oo", "u")); + testRegexpHelper(new RegExp("[\\u{62}-\\u{00000066}]oo", "u")); + + // Though, unicode escapes via strings should work too. + testRegexpHelper(new RegExp("[\u0062-\u0066]oo")); + testRegexpHelper(new RegExp("[\u0062-\u0066]oo", "u")); + testRegexpHelper(new RegExp("[\u{0062}-\u{0066}]oo", "u")); + testRegexpHelper(new RegExp("[\u{62}-\u{00000066}]oo", "u")); +})(); + + +(function TestBraceEscapesWithoutUnicodeFlag() { + // \u followed by illegal escape will be parsed as u. {x} will be the + // character count. + function helper1(r) { + assertFalse(r.test("fbar")); + assertFalse(r.test("fubar")); + assertTrue(r.test("fuubar")); + assertFalse(r.test("fuuubar")); + } + helper1(/f\u{2}bar/); + helper1(new RegExp("f\\u{2}bar")); + + function helper2(r) { + assertFalse(r.test("fbar")); + assertTrue(r.test("fubar")); + assertTrue(r.test("fuubar")); + assertFalse(r.test("fuuubar")); + } + + helper2(/f\u{1,2}bar/); + helper2(new RegExp("f\\u{1,2}bar")); + + function helper3(r) { + assertTrue(r.test("u")); + assertTrue(r.test("{")); + assertTrue(r.test("2")); + assertTrue(r.test("}")); + assertFalse(r.test("q")); + assertFalse(r.test("(")); + assertFalse(r.test(")")); + } + helper3(/[\u{2}]/); + helper3(new RegExp("[\\u{2}]")); +})(); + + +(function TestInvalidEscapes() { + // Without the u flag, invalid unicode escapes and other invalid escapes are + // treated as identity escapes. + function helper1(r) { + assertTrue(r.test("firstuxz89second")); + } + helper1(/first\u\x\z\8\9second/); + helper1(new RegExp("first\\u\\x\\z\\8\\9second")); + + function helper2(r) { + assertTrue(r.test("u")); + assertTrue(r.test("x")); + assertTrue(r.test("z")); + assertTrue(r.test("8")); + assertTrue(r.test("9")); + assertFalse(r.test("q")); + assertFalse(r.test("7")); + } + helper2(/[\u\x\z\8\9]/); + helper2(new RegExp("[\\u\\x\\z\\8\\9]")); + + // However, with the u flag, these are treated as invalid escapes. + assertThrows("/\\u/u", SyntaxError); + assertThrows("/\\u12/u", SyntaxError); + assertThrows("/\\ufoo/u", SyntaxError); + assertThrows("/\\x/u", SyntaxError); + assertThrows("/\\xfoo/u", SyntaxError); + assertThrows("/\\z/u", SyntaxError); + assertThrows("/\\8/u", SyntaxError); + assertThrows("/\\9/u", SyntaxError); + + assertThrows("new RegExp('\\\\u', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\u12', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\ufoo', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\x', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\xfoo', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\z', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\8', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\9', 'u')", SyntaxError); +})(); + + +(function TestTooBigHexEscape() { + // The hex number inside \u{} has a maximum value. + /\u{10ffff}/u + new RegExp("\\u{10ffff}", "u") + assertThrows("/\\u{110000}/u", SyntaxError); + assertThrows("new RegExp('\\\\u{110000}', 'u')", SyntaxError); + + // Without the u flag, they're of course fine ({x} is the count). + /\u{110000}/ + new RegExp("\\u{110000}") +})(); + + +(function TestSyntaxEscapes() { + // Syntax escapes work the same with or without the u flag. + function helper(r) { + assertTrue(r.test("foo[bar")); + assertFalse(r.test("foo]bar")); + } + helper(/foo\[bar/); + helper(new RegExp("foo\\[bar")); + helper(/foo\[bar/u); + helper(new RegExp("foo\\[bar", "u")); +})(); + + +(function TestUnicodeSurrogates() { + // U+10E6D corresponds to the surrogate pair [U+D803, U+DE6D]. + function helper(r) { + assertTrue(r.test("foo\u{10e6d}bar")); + } + helper(/foo\ud803\ude6dbar/u); + helper(new RegExp("foo\\ud803\\ude6dbar", "u")); +})(); + + +(function AllFlags() { + // Test that we can pass all possible regexp flags and they work properly. + function helper1(r) { + assertTrue(r.global); + assertTrue(r.ignoreCase); + assertTrue(r.multiline); + assertTrue(r.sticky); + assertTrue(r.unicode); + } + + helper1(/foo/gimyu); + helper1(new RegExp("foo", "gimyu")); + + function helper2(r) { + assertFalse(r.global); + assertFalse(r.ignoreCase); + assertFalse(r.multiline); + assertFalse(r.sticky); + assertFalse(r.unicode); + } + + helper2(/foo/); + helper2(new RegExp("foo")); +})(); + + +(function DuplicatedFlags() { + // Test that duplicating the u flag is not allowed. + assertThrows("/foo/ugu"); + assertThrows("new RegExp('foo', 'ugu')"); +})(); + + +(function ToString() { + // Test that the u flag is included in the string representation of regexps. + function helper(r) { + assertEquals(r.toString(), "/foo/u"); + } + helper(/foo/u); + helper(new RegExp("foo", "u")); +})(); + +// Non-BMP patterns. +// Single character atom. +assertTrue(new RegExp("\u{12345}", "u").test("\u{12345}")); +assertTrue(/\u{12345}/u.test("\u{12345}")); +assertTrue(new RegExp("\u{12345}", "u").test("\ud808\udf45")); +assertTrue(/\u{12345}/u.test("\ud808\udf45")); +assertFalse(new RegExp("\u{12345}", "u").test("\udf45")); +assertFalse(/\u{12345}/u.test("\udf45")); + +// Multi-character atom. +assertTrue(new RegExp("\u{12345}\u{23456}", "u").test("a\u{12345}\u{23456}b")); +assertTrue(/\u{12345}\u{23456}/u.test("b\u{12345}\u{23456}c")); +assertFalse(new RegExp("\u{12345}\u{23456}", "u").test("a\udf45\u{23456}b")); +assertFalse(/\u{12345}\u{23456}/u.test("b\udf45\u{23456}c")); + +// Disjunction. +assertTrue(new RegExp("\u{12345}(?:\u{23456})", "u").test( + "a\u{12345}\u{23456}b")); +assertTrue(/\u{12345}(?:\u{23456})/u.test("b\u{12345}\u{23456}c")); +assertFalse(new RegExp("\u{12345}(?:\u{23456})", "u").test( + "a\udf45\u{23456}b")); +assertFalse(/\u{12345}(?:\u{23456})/u.test("b\udf45\u{23456}c")); + +// Alternative. +assertTrue(new RegExp("\u{12345}|\u{23456}", "u").test("a\u{12345}b")); +assertTrue(/\u{12345}|\u{23456}/u.test("b\u{23456}c")); +assertFalse(new RegExp("\u{12345}|\u{23456}", "u").test("a\udf45\ud84db")); +assertFalse(/\u{12345}|\u{23456}/u.test("b\udf45\ud808c")); + +// Capture. +assertTrue(new RegExp("(\u{12345}|\u{23456}).\\1", "u").test( + "\u{12345}b\u{12345}")); +assertTrue(/(\u{12345}|\u{23456}).\1/u.test("\u{12345}b\u{12345}")); +assertFalse(new RegExp("(\u{12345}|\u{23456}).\\1", "u").test( + "\u{12345}b\u{23456}")); +assertFalse(/(\u{12345}|\u{23456}).\1/u.test("\u{12345}b\u{23456}")); + +// Quantifier. +assertTrue(new RegExp("\u{12345}{3}", "u").test("\u{12345}\u{12345}\u{12345}")); +assertTrue(/\u{12345}{3}/u.test("\u{12345}\u{12345}\u{12345}")); +assertTrue(new RegExp("\u{12345}{3}").test("\u{12345}\udf45\udf45")); +assertFalse(/\ud808\udf45{3}/u.test("\u{12345}\udf45\udf45")); +assertTrue(/\ud808\udf45{3}/u.test("\u{12345}\u{12345}\u{12345}")); +assertFalse(new RegExp("\u{12345}{3}", "u").test("\u{12345}\udf45\udf45")); +assertFalse(/\u{12345}{3}/u.test("\u{12345}\udf45\udf45")); + +// Literal surrogates. +assertEquals(["\u{10000}\u{10000}"], + new RegExp("\ud800\udc00+", "u").exec("\u{10000}\u{10000}")); +assertEquals(["\u{10000}\u{10000}"], + new RegExp("\\ud800\\udc00+", "u").exec("\u{10000}\u{10000}")); + +assertEquals(["\u{10003}\u{50001}"], + new RegExp("[\\ud800\\udc03-\\ud900\\udc01\]+", "u").exec( + "\u{10003}\u{50001}")); +assertEquals(["\u{10003}\u{50001}"], + new RegExp("[\ud800\udc03-\u{50001}\]+", "u").exec( + "\u{10003}\u{50001}")); + +// Unicode escape sequences to represent a non-BMP character cannot have +// mixed notation, and must follow the rules for RegExpUnicodeEscapeSequence. +assertThrows(() => new RegExp("[\\ud800\udc03-\ud900\\udc01\]+", "u")); +assertThrows(() => new RegExp("[\\ud800\udc03-\ud900\\udc01\]+", "u")); +assertNull(new RegExp("\\ud800\udc00+", "u").exec("\u{10000}\u{10000}")); +assertNull(new RegExp("\ud800\\udc00+", "u").exec("\u{10000}\u{10000}")); + +assertNull(new RegExp("[\\ud800\udc00]", "u").exec("\u{10000}")); +assertNull(new RegExp("[\\{ud800}\udc00]", "u").exec("\u{10000}")); +assertNull(new RegExp("[\ud800\\udc00]", "u").exec("\u{10000}")); +assertNull(new RegExp("[\ud800\\{udc00}]", "u").exec("\u{10000}")); + +assertNull(/\u{d800}\u{dc00}+/u.exec("\ud800\udc00\udc00")); +assertNull(/\ud800\u{dc00}+/u.exec("\ud800\udc00\udc00")); +assertNull(/\u{d800}\udc00+/u.exec("\ud800\udc00\udc00")); |