File indexing completed on 2024-04-28 15:28:38
0001 // invalid regexp 0002 shouldThrow("/(/"); 0003 // should not crash 0004 shouldThrow("''.match('(')"); 0005 0006 shouldBe("(new RegExp()).source", "''"); 0007 shouldBe("Boolean(new RegExp())", "true"); 0008 shouldBeTrue("isNaN(Number(new RegExp()))"); 0009 0010 // RegExp constructor called as a function 0011 shouldBe("RegExp(/x/).source", "'x'"); 0012 //shouldBe("RegExp(/x/, 'g').source", "'/x/'"); // can't supply flags when constructing one RegExp from another, says mozilla 0013 shouldBe("RegExp('x', 'g').global", "true"); 0014 shouldBe("RegExp('x').source", "'x'"); 0015 0016 // RegExp constructor 0017 shouldBe("new RegExp('x').source", "'x'"); 0018 0019 var ri = /a/i; 0020 var rm = /a/m; 0021 var rg = /a/g; 0022 0023 shouldBeFalse("(/a/).global"); 0024 shouldBe("typeof (/a/).global", "'boolean'"); 0025 shouldBeTrue("rg.global"); 0026 shouldBeFalse("(/a/).ignoreCase"); 0027 shouldBeTrue("ri.ignoreCase"); 0028 shouldBeFalse("(/a/).multiline"); 0029 shouldBeTrue("rm.multiline"); 0030 shouldBe("rg.toString()", "'/a/g'"); 0031 shouldBe("ri.toString()", "'/a/i'"); 0032 shouldBe("rm.toString()", "'/a/m'"); 0033 0034 // check properety attributes 0035 rg.global = false; 0036 shouldBeTrue("rg.global"); 0037 ri.ignoreCase = false; 0038 shouldBeTrue("ri.ignoreCase"); 0039 rm.multiline = false; 0040 shouldBeTrue("rm.multiline"); 0041 0042 shouldBe("Boolean(/a/.test)", "true"); 0043 shouldBe("/(b)c/.exec('abcd').toString()", "\"bc,b\""); 0044 shouldBe("/(b)c/.exec('abcd').length", "2"); 0045 shouldBe("/(b)c/.exec('abcd').index", "1"); 0046 shouldBe("/(b)c/.exec('abcd').input", "'abcd'"); 0047 0048 var rs = /foo/; 0049 rs.source = "bar"; 0050 shouldBe("rs.source", "'foo'"); 0051 0052 shouldBe("var r = new RegExp(/x/); r.global=true; r.lastIndex = -1; typeof r.test('a')", "'boolean'"); 0053 0054 shouldBe("'abcdefghi'.match(/(abc)def(ghi)/).toString()","'abcdefghi,abc,ghi'"); 0055 shouldBe("/(abc)def(ghi)/.exec('abcdefghi').toString()","'abcdefghi,abc,ghi'"); 0056 shouldBe("RegExp.$1","'abc'"); 0057 shouldBe("with(RegExp) { $1 }","'abc'"); 0058 shouldBe("RegExp.$2","'ghi'"); 0059 shouldBe("RegExp.$3","''"); 0060 0061 shouldBe("'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/).toString()", "'abcdefghi,abcdefghi,bcdefgh,cdefg,def,e'"); 0062 shouldBe("RegExp.$1","'abcdefghi'"); 0063 shouldBe("RegExp.$2","'bcdefgh'"); 0064 shouldBe("RegExp.$3","'cdefg'"); 0065 shouldBe("RegExp.$4","'def'"); 0066 shouldBe("RegExp.$5","'e'"); 0067 shouldBe("RegExp.$6","''"); 0068 0069 shouldBe("'(100px 200px 150px 15px)'.match(/\\((\\d+)(px)* (\\d+)(px)* (\\d+)(px)* (\\d+)(px)*\\)/).toString()","'(100px 200px 150px 15px),100,px,200,px,150,px,15,px'"); 0070 shouldBe("RegExp.$1","'100'"); 0071 shouldBe("RegExp.$3","'200'"); 0072 shouldBe("RegExp.$5","'150'"); 0073 shouldBe("RegExp.$7","'15'"); 0074 shouldBe("''.match(/\((\\d+)(px)* (\\d+)(px)* (\\d+)(px)* (\\d+)(px)*\)/)","null"); 0075 shouldBe("RegExp.$1","''"); 0076 shouldBe("RegExp.$3","''"); 0077 shouldBe("RegExp.$5","''"); 0078 shouldBe("RegExp.$7","''"); 0079 0080 var invalidChars = /[^@\.\w]/g; // #47092 0081 shouldBe("'faure@kde.org'.match(invalidChars) == null", "true"); 0082 shouldBe("'faure-kde@kde.org'.match(invalidChars) == null", "false"); 0083 0084 shouldBe("'test1test2'.replace('test','X')","'X1test2'"); 0085 shouldBe("'test1test2'.replace(/\\d/,'X')","'testXtest2'"); 0086 shouldBe("'1test2test3'.replace(/\\d/,'')","'test2test3'"); 0087 shouldBe("'test1test2'.replace(/test/g,'X')","'X1X2'"); 0088 shouldBe("'1test2test3'.replace(/\\d/g,'')","'testtest'"); 0089 shouldBe("'1test2test3'.replace(/x/g,'')","'1test2test3'"); 0090 shouldBe("'test1test2'.replace(/(te)(st)/g,'$2$1')","'stte1stte2'"); 0091 shouldBe("'foo+bar'.replace(/\\+/g,'%2B')", "'foo%2Bbar'"); 0092 var caught = false; try { new RegExp("+"); } catch (e) { caught = true; } 0093 shouldBeTrue("caught"); // #40435 0094 var caught = false; try { new RegExp("]"); } catch (e) { caught = true; } 0095 shouldBeTrue("caught"); // test 89 of Acid3 0096 var caught = false; try { new RegExp("\\]"); } catch (e) { caught = true; } 0097 shouldBeFalse("caught"); 0098 shouldBe("'foo'.replace(/z?/g,'x')", "'xfxoxox'"); 0099 shouldBe("'test test'.replace(/\\s*/g,'')","'testtest'"); // #50985 0100 shouldBe("'abc$%@'.replace(/[^0-9a-z]*/gi,'')","'abc'"); // #50848 0101 shouldBe("'ab'.replace(/[^\\d\\.]*/gi,'')","''"); // #75292 0102 shouldBe("'1ab'.replace(/[^\\d\\.]*/gi,'')","'1'"); // #75292 0103 0104 // Acid3 showed a difference to the Perl regex behavior 0105 var x = /(\3)(\1)(a)/.exec('cat'); // the \3 matches the empty string, qv. ES3:15.10.2.9 0106 shouldBeTrue("!!x"); // or, "/(\\3)(\\1)(a)/ failed to match 'cat'"); 0107 shouldBe("x.length", "4"); // or, "/(\\3)(\\1)(a)/ failed to return four components"); 0108 shouldBe("x[0]", "'a'"); // or, "/(\\3)(\\1)(a)/ failed to find 'a' in 'cat'"); 0109 shouldBe("x[1]", "''"); // or, "/(\\3)(\\1)(a)/ failed to find '' in 'cat' as first part"); 0110 shouldBe("x[2]", "''"); // or, "/(\\3)(\\1)(a)/ failed to find '' in 'cat' as second part"); 0111 shouldBe("x[3]", "'a'"); // or, "/(\\3)(\\1)(a)/ failed to find 'a' in 'cat' as third part"); 0112 0113 // Empty character class matches nothing 0114 var ok = false; 0115 try { ok = (/[]/.exec('') == null); } catch (e) { } 0116 shouldBeTrue("ok"); 0117 0118 // [^] matches anything 0119 ok = false; 0120 try { ok = (/[^]/.exec('x') != null); } catch (e) { } 0121 shouldBeTrue("ok"); 0122 0123 shouldBe("'1test2test3blah'.split(/test/).toString()","'1,2,3blah'"); 0124 var reg = /(\d\d )/g; 0125 var str = new String('98 76 blah'); 0126 shouldBe("reg.exec(str).toString()","'98 ,98 '"); 0127 shouldBe("reg.lastIndex","3"); 0128 shouldBe("RegExp.$1","'98 '"); 0129 shouldBe("RegExp.$2","''"); 0130 0131 shouldBe("reg.exec(str).toString()","'76 ,76 '"); 0132 shouldBe("reg.lastIndex","6"); 0133 shouldBe("RegExp.$1","'76 '"); 0134 shouldBe("RegExp.$2","''"); 0135 0136 shouldBe("reg.exec(str)","null"); 0137 shouldBe("reg.lastIndex","0"); 0138 0139 // http://www.devguru.com/Technologies/ecmascript/quickref/regexp_lastindex.html 0140 // Looks IE-only though 0141 //shouldBe( "var re=/ships*\s/; re.exec('the hardships of traveling'); re.lastIndex", "14" ); 0142 //shouldBe( "var re=/ships*\s/; str='the hardships of traveling'; re.exec(str); re.exec(str); re.lastIndex", "0" ); 0143 0144 // http://devedge.netscape.com/library/manuals/2000/javascript/1.5/guide/regexp.html 0145 shouldBe( "myRe=/d(b+)d/g; myArray = myRe.exec('cdbbdbsbz'); myRe.lastIndex", "5" ); 0146 0147 reg = /^u/i; 0148 shouldBeTrue("reg.ignoreCase == true"); 0149 shouldBeTrue("reg.global === false"); 0150 shouldBeTrue("reg.multiline === false"); 0151 shouldBeTrue("reg.test('UGO')"); 0152 0153 // regexp are writable ? 0154 shouldBe("reg.x = 1; reg.x", "1"); 0155 // shared data ? 0156 shouldBe("var r2 = reg; r2.x = 2; reg.x", "2"); 0157 0158 var str = new String("For more information, see Chapter 3.4.5.1"); 0159 re = /(chapter \d+(\.\d)*)/i; 0160 // This returns the array containing Chapter 3.4.5.1,Chapter 3.4.5.1,.1 0161 // 'Chapter 3.4.5.1' is the first match and the first value remembered from (Chapter \d+(\.\d)*). 0162 // '.1' is the second value remembered from (\.\d) 0163 shouldBe("str.match(re).toString()","'Chapter 3.4.5.1,Chapter 3.4.5.1,.1'"); 0164 0165 str = "abcDdcba"; 0166 // The returned array contains D, d. 0167 shouldBe("str.match(/d/gi).toString()","'D,d'"); 0168 0169 // unicode escape sequence 0170 shouldBe("/\\u0061/.source", "'\\\\u0061'"); 0171 shouldBe("'abc'.match(/\\u0062/).toString()", "'b'"); 0172 0173 shouldBe("Object.prototype.toString.apply(RegExp.prototype)", 0174 "'[object RegExp]'"); 0175 0176 // not sure what this should return. most importantly 0177 // it doesn't throw an exception 0178 shouldBe("typeof RegExp.prototype.toString()", "'string'"); 0179 0180 0181 // Tests for unicode handling inside strings and regexps.. 0182 str = "\u304f"; 0183 shouldBe("str.replace(/o/ig,'aaa')", "str"); 0184 shouldBe("'PASS'.replace(/[\\u0100-\\uFFFF]/g, '?')", "'PASS'"); 0185 shouldBe("'\uDBFF\uDFFD'.replace(/\uDBFF/, 'A').replace(/\uDFFD/, 'B')", "'AB'"); 0186 shouldBe("'\uDBFF\uDFFD'.replace(/\\uDBFF/, 'A').replace(/\\uDFFD/, 'B')", "'AB'"); 0187 shouldBe("'\uDBFF\uDFFD'.replace(/\\W/, '*')", "'*\uDFFD'"); 0188 0189 myName = "\u041C\u0430\u043A\u0441\u0438\u043C\u0020\u041E"; // Maksim O in Cyrillic 0190 0191 //If one get rids of the 'im', should get 'Maks O' back 0192 nickName = myName.replace(/\u0438\u043C/, ''); 0193 shouldBe("nickName", "'\u041C\u0430\u043A\u0441\u0020\u041E'"); 0194 0195 //If one gets rid of the ' O', should get Maks back 0196 shouldBe("nickName.replace(/ \u041E/,'')", "'\u041C\u0430\u043A\u0441'"); 0197 0198 //Some checks for index handling with unicode-encoded stuff... 0199 multi = "\u0430\u0431\u0432\u0430\u0431\u0432\u0430\u0431\u0432"; //abv 3 times in Cyrillic 0200 matches = multi.match(/\u0430\u0431\u0432/g); //match abv... 0201 shouldBe("matches.length", "3"); 0202 shouldBe("matches[0]", "'\u0430\u0431\u0432'"); 0203 shouldBe("matches[1]", "'\u0430\u0431\u0432'"); 0204 shouldBe("matches[2]", "'\u0430\u0431\u0432'"); 0205 0206 // null bytes handled safely 0207 shouldBe("'a\\u0000b'.search(/\\u0000b/)", "1"); 0208 0209 // escaped pattern characters 0210 shouldBe("'abc'.search(/\\u005Ea/)", "-1"); // unlike /^a/ 0211 shouldBe("'abc'.search(/c\\u0024/)", "-1"); // unlike /c$/ 0212 shouldBe("'a\\\\bc'.search(/\\u005C/)", "1"); // Unlike /\/ 0213 shouldBe("'abc'.search(/b\\u002B/)", "-1"); // unlike /b+/ 0214 shouldBe("'abc'.search(/a\\u002Ec/)", "-1"); // unlike /a.c/ 0215 shouldBe("'abc'.search(/ax\\u002A/)", "-1"); // unlike /ax*/ 0216 shouldBe("'abc'.search(/ab\\u002B/)", "-1"); // unlike /ab+/ 0217 shouldBe("'abc'.search(/ax\\u003F/)", "-1"); // unlike /ax?/ 0218 shouldBe("'abc'.search(/b\\u007Cx/)", "-1"); // unlike /b|x/ 0219 0220 // incomplete, non-standard \u sequences we model the IE behavior here 0221 // which always treats e.g. \u9 as u9. Mozilla treats (\u9) as (u9) 0222 // but just \u9 like \u0009. 0223 shouldBe("'abc'.replace(/\\u0062/, 'x');", "'axc'"); 0224 shouldBe("'au062c'.replace(/\\u062/, 'x');", "'axc'"); 0225 shouldBe("'au62c'.replace(/\\u62/, 'x');", "'axc'"); 0226 shouldBe("'au2c'.replace(/\\u2/, 'x');", "'axc'"); 0227 shouldBe("'auc'.replace(/\\u/, 'x');", "'axc'"); 0228 shouldBe("'au62c'.replace(/[\\u62]+/, 'x');", "'axc'"); 0229 shouldBe("'au62wc'.search(/\\u62w/);", "1"); 0230 shouldBe("'au62c'.search(/(\\u62)/);", "1"); 0231 shouldBe("'au62c'.search(/(\\u62)/);", "1"); 0232 shouldBe("'au62bc'.search(/(\\u62|q)/);", "1"); 0233 0234 var s = "*"; 0235 while (s.length < 100000) 0236 s = s + s; 0237 var re = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/; 0238 0239 shouldThrow('("<scr" + s + "/scr>").match(re);'); // ... and not crash 0240 0241 // proper .lastIndex updating for .test 0242 var re = /x/g; 0243 var s = "x"; 0244 shouldBeFalse("re.test(s) && re.test(s)"); 0245 0246 // Crash test for reentrancy 0247 var re = 0; 0248 function callback(str) { 0249 return crashme("lorem"); 0250 } 0251 function crashme(txt) { 0252 if (!re) re = new RegExp('lorem (ipsum)',"gm"); 0253 return txt.replace(re, callback); 0254 } 0255 crashme("lorem ipsum"); 0256 0257 debug("Done.");