mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-25 17:53:53 +02:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			286 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			286 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // 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"));
 |