diff --git a/harness/assert.js b/harness/assert.js index 35abaf8f6ddaf410c43d64f5472567facc6f3c40..9abf3e13cd02ab5b031b96792dda177b31ea0b33 100644 --- a/harness/assert.js +++ b/harness/assert.js @@ -51,24 +51,30 @@ assert.notSameValue = function (actual, unexpected, message) { $ERROR(message); }; -assert.throws = function (expectedErrorConstructor, func) { +assert.throws = function (expectedErrorConstructor, func, message) { if (func === undefined) { $ERROR('assert.throws requires two arguments: the error constructor and a function to run'); return; } + if (message === undefined) { + message = ''; + } else { + message += ' '; + } try { func(); } catch (thrown) { if (typeof thrown !== 'object' || thrown === null) { - $ERROR('Thrown value was not an object!'); - return; - } - if (thrown.constructor !== expectedErrorConstructor) { - $ERROR('Expected a ' + expectedErrorConstructor.name + ' but got a ' + thrown.constructor.name); + message += 'Thrown value was not an object!'; + $ERROR(message); + } else if (thrown.constructor !== expectedErrorConstructor) { + message += 'Expected a ' + expectedErrorConstructor.name + ' but got a ' + thrown.constructor.name; + $ERROR(message); } return; } - $ERROR('Expected a ' + expectedErrorConstructor.name + ' to be thrown but no exception was thrown at all'); + message += 'Expected a ' + expectedErrorConstructor.name + ' to be thrown but no exception was thrown at all'; + $ERROR(message); }; diff --git a/test/built-ins/RegExp/unicode_identity_escape.js b/test/built-ins/RegExp/unicode_identity_escape.js new file mode 100755 index 0000000000000000000000000000000000000000..67be1a0b3a63bba2703f03b7a712b09935b7ffe2 --- /dev/null +++ b/test/built-ins/RegExp/unicode_identity_escape.js @@ -0,0 +1,53 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: IdentityEscape for Unicode RegExp +info: > + IdentityEscape for Unicode RegExps is restricted to SyntaxCharacter and U+002F (SOLIDUS) +es6id: 21.1.2 +---*/ + +// 21.2.1 Patterns +// +// IdentityEscape[U] :: +// [+U] SyntaxCharacter +// [+U] / +// +// SyntaxCharacter :: one of +// ^ $ \ . * + ? ( ) [ ] { } | + +// IdentityEscape in AtomEscape +assert(/\^/u.test("^"), "IdentityEscape in AtomEscape: /\\^/"); +assert(/\$/u.test("$"), "IdentityEscape in AtomEscape: /\\$/"); +assert(/\\/u.test("\\"), "IdentityEscape in AtomEscape: /\\\\/"); +assert(/\./u.test("."), "IdentityEscape in AtomEscape: /\\./"); +assert(/\*/u.test("*"), "IdentityEscape in AtomEscape: /\\*/"); +assert(/\+/u.test("+"), "IdentityEscape in AtomEscape: /\\+/"); +assert(/\?/u.test("?"), "IdentityEscape in AtomEscape: /\\?/"); +assert(/\(/u.test("("), "IdentityEscape in AtomEscape: /\\(/"); +assert(/\)/u.test(")"), "IdentityEscape in AtomEscape: /\\)/"); +assert(/\[/u.test("["), "IdentityEscape in AtomEscape: /\\[/"); +assert(/\]/u.test("]"), "IdentityEscape in AtomEscape: /\\]/"); +assert(/\{/u.test("{"), "IdentityEscape in AtomEscape: /\\{/"); +assert(/\}/u.test("}"), "IdentityEscape in AtomEscape: /\\}/"); +assert(/\|/u.test("|"), "IdentityEscape in AtomEscape: /\\|/"); +assert(/\//u.test("/"), "IdentityEscape in AtomEscape: /\\//"); + + +// IdentityEscape in ClassEscape +assert(/[\^]/u.test("^"), "IdentityEscape in ClassEscape: /[\\^]/"); +assert(/[\$]/u.test("$"), "IdentityEscape in ClassEscape: /[\\$]/"); +assert(/[\\]/u.test("\\"), "IdentityEscape in ClassEscape: /[\\\\]/"); +assert(/[\.]/u.test("."), "IdentityEscape in ClassEscape: /[\\.]/"); +assert(/[\*]/u.test("*"), "IdentityEscape in ClassEscape: /[\\*]/"); +assert(/[\+]/u.test("+"), "IdentityEscape in ClassEscape: /[\\+]/"); +assert(/[\?]/u.test("?"), "IdentityEscape in ClassEscape: /[\\?]/"); +assert(/[\(]/u.test("("), "IdentityEscape in ClassEscape: /[\\(]/"); +assert(/[\)]/u.test(")"), "IdentityEscape in ClassEscape: /[\\)]/"); +assert(/[\[]/u.test("["), "IdentityEscape in ClassEscape: /[\\[]/"); +assert(/[\]]/u.test("]"), "IdentityEscape in ClassEscape: /[\\]]/"); +assert(/[\{]/u.test("{"), "IdentityEscape in ClassEscape: /[\\{]/"); +assert(/[\}]/u.test("}"), "IdentityEscape in ClassEscape: /[\\}]/"); +assert(/[\|]/u.test("|"), "IdentityEscape in ClassEscape: /[\\|]/"); +assert(/[\/]/u.test("/"), "IdentityEscape in ClassEscape: /[\\/]/"); diff --git a/test/built-ins/RegExp/unicode_restricted_brackets.js b/test/built-ins/RegExp/unicode_restricted_brackets.js new file mode 100755 index 0000000000000000000000000000000000000000..b02aab72e20bcdba9e95d6071c1826f480db4752 --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_brackets.js @@ -0,0 +1,31 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - Standalone brackets +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExp. + Tested extension: "Atom[U] :: PatternCharacter" +es6id: 21.1.2 +---*/ + +// Single parentheses and brackets. +assert.throws(SyntaxError, function() { + RegExp("(", "u"); +}, 'RegExp("(", "u"): '); +assert.throws(SyntaxError, function() { + RegExp(")", "u"); +}, 'RegExp(")", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[", "u"); +}, 'RegExp("[", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("]", "u"); +}, 'RegExp("]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("{", "u"); +}, 'RegExp("{", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("}", "u"); +}, 'RegExp("}", "u"): '); diff --git a/test/built-ins/RegExp/unicode_restricted_character_class_escape.js b/test/built-ins/RegExp/unicode_restricted_character_class_escape.js new file mode 100755 index 0000000000000000000000000000000000000000..5d2888ec3df6cae4dd714900c1488d957b7ca81a --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_character_class_escape.js @@ -0,0 +1,73 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - ClassEscape in range expression +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExp. + Tested extension: "ClassAtomNoDashInRange :: \ ClassEscape but only if ClassEscape evaluates to a CharSet with exactly one character" +es6id: 21.2.2.15.1 +---*/ + +// Leading CharacterClassEscape. +assert.throws(SyntaxError, function() { + RegExp("[\\d-a]", "u"); +}, 'RegExp("[\\d-a]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\D-a]", "u"); +}, 'RegExp("[\\D-a]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\s-a]", "u"); +}, 'RegExp("[\\s-a]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\S-a]", "u"); +}, 'RegExp("[\\S-a]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\w-a]", "u"); +}, 'RegExp("[\\w-a]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\W-a]", "u"); +}, 'RegExp("[\\W-a]", "u"): '); + + +// Trailing CharacterClassEscape. +assert.throws(SyntaxError, function() { + RegExp("[a-\\d]", "u"); +}, 'RegExp("[a-\\d]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[a-\\D]", "u"); +}, 'RegExp("[a-\\D]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[a-\\s]", "u"); +}, 'RegExp("[a-\\s]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[a-\\S]", "u"); +}, 'RegExp("[a-\\S]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[a-\\w]", "u"); +}, 'RegExp("[a-\\w]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[a-\\W]", "u"); +}, 'RegExp("[a-\\W]", "u"): '); + + +// Leading and trailing CharacterClassEscape. +assert.throws(SyntaxError, function() { + RegExp("[\\d-\\d]", "u"); +}, 'RegExp("[\\d-\\d]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\D-\\D]", "u"); +}, 'RegExp("[\\D-\\D]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\s-\\s]", "u"); +}, 'RegExp("[\\s-\\s]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\S-\\S]", "u"); +}, 'RegExp("[\\S-\\S]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\w-\\w]", "u"); +}, 'RegExp("[\\w-\\w]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\W-\\W]", "u"); +}, 'RegExp("[\\W-\\W]", "u"): '); diff --git a/test/built-ins/RegExp/unicode_restricted_identity_escape.js b/test/built-ins/RegExp/unicode_restricted_identity_escape.js new file mode 100755 index 0000000000000000000000000000000000000000..120d747a28f7a586c004b34cb784b5bd5882251d --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_identity_escape.js @@ -0,0 +1,65 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - Identity escape with basic latin characters +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExps. + Tested extension: "IdentityEscape[U] :: [~U] SourceCharacter but not c" +es6id: 21.1.2 +---*/ + +function isSyntaxCharacter(c) { + switch (c) { + case "^": + case "$": + case "\\": + case ".": + case "*": + case "+": + case "?": + case "(": + case ")": + case "[": + case "]": + case "{": + case "}": + case "|": + return true; + default: + return false; + } +} + +function isAlphaDigit(c) { + return ("0" <= c && c <= "9") || ("A" <= c && c <= "Z") || ("a" <= c && c <= "z"); +} + + +// IdentityEscape in AtomEscape. +// +// AtomEscape[U] :: CharacterEscape[?U] +// CharacterEscape[U] :: IdentityEscape[?U] +for (var cu = 0x00; cu <= 0x7f; ++cu) { + var s = String.fromCharCode(cu); + if (!isAlphaDigit(s) && !isSyntaxCharacter(s) && s !== "/") { + assert.throws(SyntaxError, function() { + RegExp("\\" + s, "u"); + }, "Invalid IdentityEscape in AtomEscape: '\\" + s + "'"); + } +} + + +// IdentityEscape in ClassEscape. +// +// ClassEscape[U] :: CharacterEscape[?U] +// CharacterEscape[U] :: IdentityEscape[?U] +for (var cu = 0x00; cu <= 0x7f; ++cu) { + var s = String.fromCharCode(cu); + if (!isAlphaDigit(s) && !isSyntaxCharacter(s) && s !== "/" && s !== "-") { + assert.throws(SyntaxError, function() { + RegExp("[\\" + s + "]", "u"); + }, "Invalid IdentityEscape in ClassEscape: '\\" + s + "'"); + } +} diff --git a/test/built-ins/RegExp/unicode_restricted_identity_escape_alpha.js b/test/built-ins/RegExp/unicode_restricted_identity_escape_alpha.js new file mode 100755 index 0000000000000000000000000000000000000000..e543cfdc8dbe0ff6a2f3c42e087da1716d4c174e --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_identity_escape_alpha.js @@ -0,0 +1,100 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - Identity escape with basic latin letters +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExps. + Tested extension: "IdentityEscape[U] :: [~U] SourceCharacter but not c" + + Forbidden extension (16.1): + The RegExp pattern grammars in 21.2.1 and B.1.4 must not be extended to recognize any of the + source characters A-Z or a-z as IdentityEscape[U] when the U grammar parameter is present. +es6id: 21.1.2 +---*/ + +function isValidAlphaEscapeInAtom(s) { + switch (s) { + // Assertion [U] :: \b + case "b": + // Assertion [U] :: \B + case "B": + // ControlEscape :: one of f n r t v + case "f": + case "n": + case "r": + case "t": + case "v": + // CharacterClassEscape :: one of d D s S w W + case "d": + case "D": + case "s": + case "S": + case "w": + case "W": + return true; + default: + return false; + } +} + +function isValidAlphaEscapeInClass(s) { + switch (s) { + // ClassEscape[U] :: b + case "b": + // ControlEscape :: one of f n r t v + case "f": + case "n": + case "r": + case "t": + case "v": + // CharacterClassEscape :: one of d D s S w W + case "d": + case "D": + case "s": + case "S": + case "w": + case "W": + return true; + default: + return false; + } +} + +// IdentityEscape in AtomEscape +for (var cu = 0x41 /* A */; cu <= 0x5a /* Z */; ++cu) { + var s = String.fromCharCode(cu); + if (!isValidAlphaEscapeInAtom(s)) { + assert.throws(SyntaxError, function() { + RegExp("\\" + s, "u"); + }, "IdentityEscape in AtomEscape: '" + s + "'"); + } +} +for (var cu = 0x61 /* a */; cu <= 0x7a /* z */; ++cu) { + var s = String.fromCharCode(cu); + if (!isValidAlphaEscapeInAtom(s)) { + assert.throws(SyntaxError, function() { + RegExp("\\" + s, "u"); + }, "IdentityEscape in AtomEscape: '" + s + "'"); + } +} + + +// IdentityEscape in ClassEscape +for (var cu = 0x41 /* A */; cu <= 0x5a /* Z */; ++cu) { + var s = String.fromCharCode(cu); + if (!isValidAlphaEscapeInClass(s)) { + assert.throws(SyntaxError, function() { + RegExp("[\\" + s + "]", "u"); + }, "IdentityEscape in ClassEscape: '" + s + "'"); + } +} +for (var cu = 0x61 /* a */; cu <= 0x7a /* z */; ++cu) { + var s = String.fromCharCode(cu); + if (!isValidAlphaEscapeInClass(s)) { + assert.throws(SyntaxError, function() { + RegExp("[\\" + s + "]", "u"); + }, "IdentityEscape in ClassEscape: '" + s + "'"); + } +} diff --git a/test/built-ins/RegExp/unicode_restricted_identity_escape_c.js b/test/built-ins/RegExp/unicode_restricted_identity_escape_c.js new file mode 100755 index 0000000000000000000000000000000000000000..65c643e4ce4aa7a13f6bdab88e13d31e924e848c --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_identity_escape_c.js @@ -0,0 +1,45 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - Invalid control escape sequences +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExp. + Tested extension: "IdentityEscape[U] :: [~U] SourceCharacter but not c" +es6id: 21.1.2 +---*/ + +function isAlpha(c) { + return ("A" <= c && c <= "Z") || ("a" <= c && c <= "z"); +} + + +// "c ControlLetter" sequence in AtomEscape. +// +// AtomEscape[U] :: CharacterEscape[?U] +// CharacterEscape[U] :: c ControlLetter +assert.throws(SyntaxError, function() { RegExp("\\c", "u"); }); +for (var cu = 0x00; cu <= 0x7f; ++cu) { + var s = String.fromCharCode(cu); + if (!isAlpha(s)) { + assert.throws(SyntaxError, function() { + RegExp("\\c" + s, "u"); + }, "ControlLetter escape in AtomEscape: '" + s + "'"); + } +} + + +// "c ControlLetter" sequence in ClassEscape. +// +// ClassEscape[U] :: CharacterEscape[?U] +// CharacterEscape[U] :: c ControlLetter +assert.throws(SyntaxError, function() { RegExp("[\\c]", "u"); }); +for (var cu = 0x00; cu <= 0x7f; ++cu) { + var s = String.fromCharCode(cu); + if (!isAlpha(s)) { + assert.throws(SyntaxError, function() { + RegExp("[\\c" + s + "]", "u"); + }, "ControlLetter escape in ClassEscape: '" + s + "'"); + } +} diff --git a/test/built-ins/RegExp/unicode_restricted_identity_escape_u.js b/test/built-ins/RegExp/unicode_restricted_identity_escape_u.js new file mode 100755 index 0000000000000000000000000000000000000000..dc8a870c203d5310d6cf6391c992c10206fa5a54 --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_identity_escape_u.js @@ -0,0 +1,76 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - Incomplete Unicode escape sequences +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExp. + Tested extension: "IdentityEscape[U] :: [~U] SourceCharacter but not c" +es6id: 21.1.2 +---*/ + +// Incomplete RegExpUnicodeEscapeSequence in AtomEscape not parsed as IdentityEscape. +// +// AtomEscape[U] :: CharacterEscape[?U] +// CharacterEscape[U] :: RegExpUnicodeEscapeSequence[?U] +assert.throws(SyntaxError, function() { + RegExp("\\u", "u"); +}, 'RegExp("\\u", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\u1", "u"); +}, 'RegExp("\\u1", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\u12", "u"); +}, 'RegExp("\\u12", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\u123", "u"); +}, 'RegExp("\\u123", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\u{", "u"); +}, 'RegExp("\\u{", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\u{}", "u"); +}, 'RegExp("\\u{}", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\u{1", "u"); +}, 'RegExp("\\u{1", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\u{12", "u"); +}, 'RegExp("\\u{12", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\u{123", "u"); +}, 'RegExp("\\u{123", "u"): '); + + +// Incomplete RegExpUnicodeEscapeSequence in ClassEscape not parsed as IdentityEscape. +// +// ClassEscape[U] :: CharacterEscape[?U] +// CharacterEscape[U] :: RegExpUnicodeEscapeSequence[?U] +assert.throws(SyntaxError, function() { + RegExp("[\\u]", "u"); +}, 'RegExp("[\\u]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\u1]", "u"); +}, 'RegExp("[\\u1]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\u12]", "u"); +}, 'RegExp("[\\u12]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\u123]", "u"); +}, 'RegExp("[\\u123]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\u{]", "u"); +}, 'RegExp("[\\u{]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\u{}]", "u"); +}, 'RegExp("[\\u{}]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\u{1]", "u"); +}, 'RegExp("[\\u{1]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\u{12]", "u"); +}, 'RegExp("[\\u{12]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\u{123]", "u"); +}, 'RegExp("[\\u{123]", "u"): '); diff --git a/test/built-ins/RegExp/unicode_restricted_identity_escape_x.js b/test/built-ins/RegExp/unicode_restricted_identity_escape_x.js new file mode 100755 index 0000000000000000000000000000000000000000..9e7e65f257ad12a5923bc3457bf8793bd6f32cff --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_identity_escape_x.js @@ -0,0 +1,34 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - Incomplete hexadecimal escape sequences +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExp. + Tested extension: "IdentityEscape[U] :: [~U] SourceCharacter but not c" +es6id: 21.1.2 +---*/ + +// Incomplete HexEscapeSequence in AtomEscape not parsed as IdentityEscape. +// +// AtomEscape[U] :: CharacterEscape[?U] +// CharacterEscape[U] :: HexEscapeSequence +assert.throws(SyntaxError, function() { + RegExp("\\x", "u"); +}, 'RegExp("\\x", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\x1", "u"); +}, 'RegExp("\\x1", "u"): '); + + +// Incomplete HexEscapeSequence in ClassEscape not parsed as IdentityEscape. +// +// ClassEscape[U] :: CharacterEscape[?U] +// CharacterEscape[U] :: HexEscapeSequence +assert.throws(SyntaxError, function() { + RegExp("[\\x]", "u"); +}, 'RegExp("[\\x]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\x1]", "u"); +}, 'RegExp("[\\x1]", "u"): '); diff --git a/test/built-ins/RegExp/unicode_restricted_incomple_quantifier.js b/test/built-ins/RegExp/unicode_restricted_incomple_quantifier.js new file mode 100755 index 0000000000000000000000000000000000000000..ce76163945b633ab6f9c5eea23911078a928618c --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_incomple_quantifier.js @@ -0,0 +1,40 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - Incomplete quantifiers +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExp. + Tested extension: "Atom[U] :: PatternCharacter" +es6id: 21.1.2 +---*/ + +// Incomplete quantifier with atom. +assert.throws(SyntaxError, function() { + RegExp("a{", "u"); +}, 'RegExp("a{", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("a{1", "u"); +}, 'RegExp("a{1", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("a{1,", "u"); +}, 'RegExp("a{1,", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("a{1,2", "u"); +}, 'RegExp("a{1,2", "u"): '); + + +// Incomplete quantifier without atom. +assert.throws(SyntaxError, function() { + RegExp("{", "u"); +}, 'RegExp("{", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("{1", "u"); +}, 'RegExp("{1", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("{1,", "u"); +}, 'RegExp("{1,", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("{1,2", "u"); +}, 'RegExp("{1,2", "u"): '); diff --git a/test/built-ins/RegExp/unicode_restricted_octal_escape.js b/test/built-ins/RegExp/unicode_restricted_octal_escape.js new file mode 100755 index 0000000000000000000000000000000000000000..4c51b2231154aa03151844e17fe0599c22e9c43e --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_octal_escape.js @@ -0,0 +1,148 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - Octal escape sequences +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExp. + Tested extension: "CharacterEscape[U] :: [~U] LegacyOctalEscapeSequence" +es6id: 21.1.2 +---*/ + +// DecimalEscape without leading 0 in AtomEscape. +// +// AtomEscape[U] :: DecimalEscape +// DecimalEscape :: DecimalIntegerLiteral [lookahead /= DecimalDigit] +assert.throws(SyntaxError, function() { + RegExp("\\1", "u"); +}, 'RegExp("\\1", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\2", "u"); +}, 'RegExp("\\2", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\3", "u"); +}, 'RegExp("\\3", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\4", "u"); +}, 'RegExp("\\4", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\5", "u"); +}, 'RegExp("\\5", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\6", "u"); +}, 'RegExp("\\6", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\7", "u"); +}, 'RegExp("\\7", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\8", "u"); +}, 'RegExp("\\8", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\9", "u"); +}, 'RegExp("\\9", "u"): '); + + +// DecimalEscape without leading 0 in ClassEscape. +// +// ClassEscape[U] :: DecimalEscape +// DecimalEscape :: DecimalIntegerLiteral [lookahead /= DecimalDigit] +assert.throws(SyntaxError, function() { + RegExp("[\\1]", "u"); +}, 'RegExp("[\\1]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\2]", "u"); +}, 'RegExp("[\\2]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\3]", "u"); +}, 'RegExp("[\\3]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\4]", "u"); +}, 'RegExp("[\\4]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\5]", "u"); +}, 'RegExp("[\\5]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\6]", "u"); +}, 'RegExp("[\\6]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\7]", "u"); +}, 'RegExp("[\\7]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\8]", "u"); +}, 'RegExp("[\\8]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\9]", "u"); +}, 'RegExp("[\\9]", "u"): '); + + +// DecimalEscape with leading 0 in AtomEscape. +// +// Atom[U] :: DecimalEscape +// DecimalEscape :: DecimalIntegerLiteral [lookahead /= DecimalDigit] +assert.throws(SyntaxError, function() { + RegExp("\\00", "u"); +}, 'RegExp("\\00", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\01", "u"); +}, 'RegExp("\\01", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\02", "u"); +}, 'RegExp("\\02", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\03", "u"); +}, 'RegExp("\\03", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\04", "u"); +}, 'RegExp("\\04", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\05", "u"); +}, 'RegExp("\\05", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\06", "u"); +}, 'RegExp("\\06", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\07", "u"); +}, 'RegExp("\\07", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\08", "u"); +}, 'RegExp("\\08", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("\\09", "u"); +}, 'RegExp("\\09", "u"): '); + + +// DecimalEscape with leading 0 in ClassEscape. +// +// ClassEscape[U] :: DecimalEscape +// DecimalEscape :: DecimalIntegerLiteral [lookahead /= DecimalDigit] +assert.throws(SyntaxError, function() { + RegExp("[\\00]", "u"); +}, 'RegExp("[\\00]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\01]", "u"); +}, 'RegExp("[\\01]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\02]", "u"); +}, 'RegExp("[\\02]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\03]", "u"); +}, 'RegExp("[\\03]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\04]", "u"); +}, 'RegExp("[\\04]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\05]", "u"); +}, 'RegExp("[\\05]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\06]", "u"); +}, 'RegExp("[\\06]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\07]", "u"); +}, 'RegExp("[\\07]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\08]", "u"); +}, 'RegExp("[\\08]", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("[\\09]", "u"); +}, 'RegExp("[\\09]", "u"): '); diff --git a/test/built-ins/RegExp/unicode_restricted_quantifiable_assertion.js b/test/built-ins/RegExp/unicode_restricted_quantifiable_assertion.js new file mode 100755 index 0000000000000000000000000000000000000000..2daab018fda1101808e4105a64fca3af631ade1f --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_quantifiable_assertion.js @@ -0,0 +1,94 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - Production 'QuantifiableAssertion Quantifier' +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExps. + Tested extension: "ExtendedTerm :: QuantifiableAssertion Quantifier" +es6id: 21.1.2 +---*/ + +// Positive lookahead with quantifier. +assert.throws(SyntaxError, function() { + RegExp("(?=.)*", "u"); +}, 'RegExp("(?=.)*", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?=.)+", "u"); +}, 'RegExp("(?=.)+", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?=.)?", "u"); +}, 'RegExp("(?=.)?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?=.){1}", "u"); +}, 'RegExp("(?=.){1}", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?=.){1,}", "u"); +}, 'RegExp("(?=.){1,}", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?=.){1,2}", "u"); +}, 'RegExp("(?=.){1,2}", "u"): '); + + +// Positive lookahead with reluctant quantifier. +assert.throws(SyntaxError, function() { + RegExp("(?=.)*?", "u"); +}, 'RegExp("(?=.)*?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?=.)+?", "u"); +}, 'RegExp("(?=.)+?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?=.)??", "u"); +}, 'RegExp("(?=.)??", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?=.){1}?", "u"); +}, 'RegExp("(?=.){1}?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?=.){1,}?", "u"); +}, 'RegExp("(?=.){1,}?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?=.){1,2}?", "u"); +}, 'RegExp("(?=.){1,2}?", "u"): '); + + +// Negative lookahead with quantifier. +assert.throws(SyntaxError, function() { + RegExp("(?!.)*", "u"); +}, 'RegExp("(?!.)*", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?!.)+", "u"); +}, 'RegExp("(?!.)+", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?!.)?", "u"); +}, 'RegExp("(?!.)?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?!.){1}", "u"); +}, 'RegExp("(?!.){1}", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?!.){1,}", "u"); +}, 'RegExp("(?!.){1,}", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?!.){1,2}", "u"); +}, 'RegExp("(?!.){1,2}", "u"): '); + + +// Negative lookahead with reluctant quantifier. +assert.throws(SyntaxError, function() { + RegExp("(?!.)*?", "u"); +}, 'RegExp("(?!.)*?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?!.)+?", "u"); +}, 'RegExp("(?!.)+?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?!.)??", "u"); +}, 'RegExp("(?!.)??", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?!.){1}?", "u"); +}, 'RegExp("(?!.){1}?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?!.){1,}?", "u"); +}, 'RegExp("(?!.){1,}?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("(?!.){1,2}?", "u"); +}, 'RegExp("(?!.){1,2}?", "u"): '); diff --git a/test/built-ins/RegExp/unicode_restricted_quantifier_without_atom.js b/test/built-ins/RegExp/unicode_restricted_quantifier_without_atom.js new file mode 100755 index 0000000000000000000000000000000000000000..856079bc297d3ef48a8d805b133d97d5c76fee06 --- /dev/null +++ b/test/built-ins/RegExp/unicode_restricted_quantifier_without_atom.js @@ -0,0 +1,52 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: B.1.4 is not applied for Unicode RegExp - Quantifier without matching Atom +info: > + The compatibility extensions defined in B.1.4 Regular Expressions Patterns + are not applied for Unicode RegExp. + Tested extension: "Atom[U] :: PatternCharacter" +es6id: 21.1.2 +---*/ + +// Quantifier without atom. +assert.throws(SyntaxError, function() { + RegExp("*", "u"); +}, 'RegExp("*", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("+", "u"); +}, 'RegExp("+", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("?", "u"); +}, 'RegExp("?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("{1}", "u"); +}, 'RegExp("{1}", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("{1,}", "u"); +}, 'RegExp("{1,}", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("{1,2}", "u"); +}, 'RegExp("{1,2}", "u"): '); + + +// Reluctant quantifier without atom. +assert.throws(SyntaxError, function() { + RegExp("*?", "u"); +}, 'RegExp("*?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("+?", "u"); +}, 'RegExp("+?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("??", "u"); +}, 'RegExp("??", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("{1}?", "u"); +}, 'RegExp("{1}?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("{1,}?", "u"); +}, 'RegExp("{1,}?", "u"): '); +assert.throws(SyntaxError, function() { + RegExp("{1,2}?", "u"); +}, 'RegExp("{1,2}?", "u"): ');