1d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Copyright 2009 the V8 project authors. All rights reserved. 2d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Redistribution and use in source and binary forms, with or without 3d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// modification, are permitted provided that the following conditions are 4d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// met: 5d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// 6d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// * Redistributions of source code must retain the above copyright 7d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// notice, this list of conditions and the following disclaimer. 8d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// * Redistributions in binary form must reproduce the above 9d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// copyright notice, this list of conditions and the following 10d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// disclaimer in the documentation and/or other materials provided 11d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// with the distribution. 12d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// * Neither the name of Google Inc. nor the names of its 13d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// contributors may be used to endorse or promote products derived 14d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// from this software without specific prior written permission. 15d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// 16d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 28d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Test Unicode character ranges in regexps. 29d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 30d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 31d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Cyrillic. 32d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvar cyrillic = { 33d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block FIRST: "\u0410", // A 34d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block first: "\u0430", // a 35d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block LAST: "\u042f", // YA 36d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block last: "\u044f", // ya 37d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block MIDDLE: "\u0427", // CHE 38d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block middle: "\u0447", // che 39d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Actually no characters are between the cases in Cyrillic. 40d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block BetweenCases: false}; 41d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 42d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvar SIGMA = "\u03a3"; 43d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvar sigma = "\u03c3"; 44d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvar alternative_sigma = "\u03c2"; 45d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 46d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Greek. 47d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvar greek = { 48d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block FIRST: "\u0391", // ALPHA 49d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block first: "\u03b1", // alpha 50d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block LAST: "\u03a9", // OMEGA 51d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block last: "\u03c9", // omega 52d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block MIDDLE: SIGMA, // SIGMA 53d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block middle: sigma, // sigma 54d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Epsilon acute is between ALPHA-OMEGA and alpha-omega, ie it 55d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // is between OMEGA and alpha. 56d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block BetweenCases: "\u03ad"}; 57d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 58d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 59d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockfunction Range(from, to, flags) { 60d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return new RegExp("[" + from + "-" + to + "]", flags); 61d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 62d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 63d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Test Cyrillic and Greek separately. 64d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockfor (var lang = 0; lang < 2; lang++) { 65d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var chars = (lang == 0) ? cyrillic : greek; 66d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 67d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block for (var i = 0; i < 2; i++) { 68d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var lc = (i == 0); // Lower case. 69d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var first = lc ? chars.first : chars.FIRST; 70d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var middle = lc ? chars.middle : chars.MIDDLE; 71d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var last = lc ? chars.last : chars.LAST; 72d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var first_other_case = lc ? chars.FIRST : chars.first; 73d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var middle_other_case = lc ? chars.MIDDLE : chars.middle; 74d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var last_other_case = lc ? chars.LAST : chars.last; 75d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 76d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(first, last).test(first), 1); 77d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(first, last).test(middle), 2); 78d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(first, last).test(last), 3); 79d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 80d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(Range(first, last).test(first_other_case), 4); 81d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(Range(first, last).test(middle_other_case), 5); 82d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(Range(first, last).test(last_other_case), 6); 83d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 84d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(first, last, "i").test(first), 7); 85d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(first, last, "i").test(middle), 8); 86d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(first, last, "i").test(last), 9); 87d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 88d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(first, last, "i").test(first_other_case), 10); 89d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(first, last, "i").test(middle_other_case), 11); 90d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(first, last, "i").test(last_other_case), 12); 91d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 92d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (chars.BetweenCases) { 93d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(Range(first, last).test(chars.BetweenCases), 13); 94d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(Range(first, last, "i").test(chars.BetweenCases), 14); 95d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 96d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 97d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (chars.BetweenCases) { 98d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(chars.FIRST, chars.last).test(chars.BetweenCases), 15); 99d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(chars.FIRST, chars.last, "i").test(chars.BetweenCases), 16); 100d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 101d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 102d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 103d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Test range that covers both greek and cyrillic characters. 104d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockfor (key in greek) { 105d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(greek.FIRST, cyrillic.last).test(greek[key]), 17 + key); 106d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (cyrillic[key]) { 107d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(greek.FIRST, cyrillic.last).test(cyrillic[key]), 18 + key); 108d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 109d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 110d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockfor (var i = 0; i < 2; i++) { 112d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var ignore_case = (i == 0); 113d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var flag = ignore_case ? "i" : ""; 114d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(greek.first, cyrillic.LAST, flag).test(greek.first), 19); 115d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(greek.first, cyrillic.LAST, flag).test(greek.middle), 20); 116d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(greek.first, cyrillic.LAST, flag).test(greek.last), 21); 117d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 118d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(greek.first, cyrillic.LAST, flag).test(cyrillic.FIRST), 22); 119d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(greek.first, cyrillic.LAST, flag).test(cyrillic.MIDDLE), 23); 120d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(Range(greek.first, cyrillic.LAST, flag).test(cyrillic.LAST), 24); 121d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 122d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // A range that covers the lower case greek letters and the upper case cyrillic 123d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // letters. 124d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertEquals(ignore_case, Range(greek.first, cyrillic.LAST, flag).test(greek.FIRST), 25); 125d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertEquals(ignore_case, Range(greek.first, cyrillic.LAST, flag).test(greek.MIDDLE), 26); 126d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertEquals(ignore_case, Range(greek.first, cyrillic.LAST, flag).test(greek.LAST), 27); 127d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 128d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertEquals(ignore_case, Range(greek.first, cyrillic.LAST, flag).test(cyrillic.first), 28); 129d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertEquals(ignore_case, Range(greek.first, cyrillic.LAST, flag).test(cyrillic.middle), 29); 130d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertEquals(ignore_case, Range(greek.first, cyrillic.LAST, flag).test(cyrillic.last), 30); 131d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 132d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 133d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 134d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Sigma is special because there are two lower case versions of the same upper 135d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// case character. JS requires that case independece means that you should 136d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// convert everything to upper case, so the two sigma variants are equal to each 137d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// other in a case independt comparison. 138d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockfor (var i = 0; i < 2; i++) { 139d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var simple = (i != 0); 140d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var name = simple ? "" : "[]"; 141d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var regex = simple ? SIGMA : "[" + SIGMA + "]"; 142d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 143d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(new RegExp(regex).test(sigma), 31 + name); 144d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(new RegExp(regex).test(alternative_sigma), 32 + name); 145d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex).test(SIGMA), 33 + name); 146d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 147d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex, "i").test(sigma), 34 + name); 148d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // JSC and Tracemonkey fail this one. 149d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex, "i").test(alternative_sigma), 35 + name); 150d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex, "i").test(SIGMA), 36 + name); 151d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 152d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block regex = simple ? sigma : "[" + sigma + "]"; 153d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 154d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex).test(sigma), 41 + name); 155d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(new RegExp(regex).test(alternative_sigma), 42 + name); 156d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(new RegExp(regex).test(SIGMA), 43 + name); 157d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 158d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex, "i").test(sigma), 44 + name); 159d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // JSC and Tracemonkey fail this one. 160d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex, "i").test(alternative_sigma), 45 + name); 161d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex, "i").test(SIGMA), 46 + name); 162d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 163d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block regex = simple ? alternative_sigma : "[" + alternative_sigma + "]"; 164d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 165d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(new RegExp(regex).test(sigma), 51 + name); 166d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex).test(alternative_sigma), 52 + name); 167d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertFalse(new RegExp(regex).test(SIGMA), 53 + name); 168d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 169d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // JSC and Tracemonkey fail this one. 170d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex, "i").test(sigma), 54 + name); 171d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex, "i").test(alternative_sigma), 55 + name); 172d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // JSC and Tracemonkey fail this one. 173d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(new RegExp(regex, "i").test(SIGMA), 56 + name); 174d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 175d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 176d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 177d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockfor (var add_non_ascii_character_to_subject = 0; 178d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block add_non_ascii_character_to_subject < 2; 179d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block add_non_ascii_character_to_subject++) { 180d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var suffix = add_non_ascii_character_to_subject ? "\ufffe" : ""; 181d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // A range that covers both ASCII and non-ASCII. 182d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block for (var i = 0; i < 2; i++) { 183d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var full = (i != 0); 184d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var mixed = full ? "[a-\uffff]" : "[a-" + cyrillic.LAST + "]"; 185d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var f = full ? "f" : "c"; 186d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block for (var j = 0; j < 2; j++) { 187d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var ignore_case = (j == 0); 188d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var flag = ignore_case ? "i" : ""; 189d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block var re = new RegExp(mixed, flag); 190257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch var expected = 191257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ignore_case || (full && !!add_non_ascii_character_to_subject); 192257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch assertEquals(expected, re.test("A" + suffix), 58 + flag + f); 193d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(re.test("a" + suffix), 59 + flag + f); 194d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(re.test("~" + suffix), 60 + flag + f); 195d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertTrue(re.test(cyrillic.MIDDLE), 61 + flag + f); 196d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block assertEquals(ignore_case || full, re.test(cyrillic.middle), 62 + flag + f); 197d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 198d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 199d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 200