Home | History | Annotate | Download | only in webkit
      1 // Copyright 2013 the V8 project authors. All rights reserved.
      2 // Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions
      6 // are met:
      7 // 1.  Redistributions of source code must retain the above copyright
      8 //     notice, this list of conditions and the following disclaimer.
      9 // 2.  Redistributions in binary form must reproduce the above copyright
     10 //     notice, this list of conditions and the following disclaimer in the
     11 //     documentation and/or other materials provided with the distribution.
     12 //
     13 // THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
     14 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     15 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     16 // DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     17 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     18 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     19 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     20 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     21 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     22 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23 
     24 description(
     25 'Test regular expression processing with alternatives that match consuming no characters'
     26 );
     27 
     28 var emptyStr = "";
     29 var s1 = "xxxx";
     30 var s2 = "aaaa";
     31 var s3 = "aax";
     32 var s4 = "abab";
     33 var s5 = "ab";
     34 var s6 = "xabx";
     35 var s7 = "g0";
     36 
     37 // Non-capturing empty first alternative greedy '*'
     38 var re1 = new RegExp(/(?:|a|z)*/);
     39 shouldBe('emptyStr.match(re1)', '[""]');
     40 shouldBe('s1.match(re1)', '[""]');
     41 shouldBe('s2.match(re1)', '["aaaa"]');
     42 shouldBe('s3.match(re1)', '["aa"]');
     43 
     44 // Non-capturing empty middle alternative greedy '*'
     45 var re2 = new RegExp(/(?:a||z)*/);
     46 shouldBe('emptyStr.match(re2)', '[""]');
     47 shouldBe('s1.match(re2)', '[""]');
     48 shouldBe('s2.match(re2)', '["aaaa"]');
     49 shouldBe('s3.match(re2)', '["aa"]');
     50 
     51 // Non-capturing empty last alternative greedy '*'
     52 var re3 = new RegExp(/(?:a|z|)*/);
     53 shouldBe('emptyStr.match(re3)', '[""]');
     54 shouldBe('s1.match(re3)', '[""]');
     55 shouldBe('s2.match(re3)', '["aaaa"]');
     56 shouldBe('s3.match(re3)', '["aa"]');
     57 
     58 // Capturing empty first alternative greedy '*'
     59 var re4 = new RegExp(/(|a|z)*/);
     60 shouldBe('emptyStr.match(re4)', '["", undefined]');
     61 shouldBe('s1.match(re4)', '["", undefined]');
     62 shouldBe('s2.match(re4)', '["aaaa", "a"]');
     63 shouldBe('s3.match(re4)', '["aa", "a"]');
     64 
     65 // Capturing empty middle alternative greedy '*'
     66 var re5 = new RegExp(/(a||z)*/);
     67 shouldBe('emptyStr.match(re5)', '["", undefined]');
     68 shouldBe('s1.match(re5)', '["", undefined]');
     69 shouldBe('s2.match(re5)', '["aaaa", "a"]');
     70 shouldBe('s3.match(re5)', '["aa", "a"]');
     71 
     72 // Capturing empty last alternative greedy '*'
     73 var re6 = new RegExp(/(a|z|)*/);
     74 shouldBe('emptyStr.match(re6)', '["", undefined]');
     75 shouldBe('s1.match(re6)', '["", undefined]');
     76 shouldBe('s2.match(re6)', '["aaaa", "a"]');
     77 shouldBe('s3.match(re6)', '["aa", "a"]');
     78 
     79 // Non-capturing empty first alternative fixed-count
     80 var re7 = new RegExp(/(?:|a|z){2,5}/);
     81 shouldBe('emptyStr.match(re7)', '[""]');
     82 shouldBe('s1.match(re7)', '[""]');
     83 shouldBe('s2.match(re7)', '["aaa"]');
     84 shouldBe('s3.match(re7)', '["aa"]');
     85 
     86 // Non-capturing empty middle alternative fixed-count
     87 var re8 = new RegExp(/(?:a||z){2,5}/);
     88 shouldBe('emptyStr.match(re8)', '[""]');
     89 shouldBe('s1.match(re8)', '[""]');
     90 shouldBe('s2.match(re8)', '["aaaa"]');
     91 shouldBe('s3.match(re8)', '["aa"]');
     92 
     93 // Non-capturing empty last alternative fixed-count
     94 var re9 = new RegExp(/(?:a|z|){2,5}/);
     95 shouldBe('emptyStr.match(re9)', '[""]');
     96 shouldBe('s1.match(re9)', '[""]');
     97 shouldBe('s2.match(re9)', '["aaaa"]');
     98 shouldBe('s3.match(re9)', '["aa"]');
     99 
    100 // Non-capturing empty first alternative non-greedy '*'
    101 var re10 = new RegExp(/(?:|a|z)*?/);
    102 shouldBe('emptyStr.match(re10)', '[""]');
    103 shouldBe('s1.match(re10)', '[""]');
    104 shouldBe('s2.match(re10)', '[""]');
    105 shouldBe('s3.match(re10)', '[""]');
    106 
    107 // Non-capturing empty middle alternative non-greedy '*'
    108 var re11 = new RegExp(/(?:a||z)*?/);
    109 shouldBe('emptyStr.match(re11)', '[""]');
    110 shouldBe('s1.match(re11)', '[""]');
    111 shouldBe('s2.match(re11)', '[""]');
    112 shouldBe('s3.match(re11)', '[""]');
    113 
    114 // Non-capturing empty last alternative non-greedy '*'
    115 var re12 = new RegExp(/(?:a|z|)*?/);
    116 shouldBe('emptyStr.match(re12)', '[""]');
    117 shouldBe('s1.match(re12)', '[""]');
    118 shouldBe('s2.match(re12)', '[""]');
    119 shouldBe('s3.match(re12)', '[""]');
    120 
    121 // Capturing empty first alternative non-greedy '*'
    122 var re13 = new RegExp(/(|a|z)*?/);
    123 shouldBe('emptyStr.match(re13)', '["", undefined]');
    124 shouldBe('s1.match(re13)', '["", undefined]');
    125 shouldBe('s2.match(re13)', '["", undefined]');
    126 shouldBe('s3.match(re13)', '["", undefined]');
    127 
    128 // Capturing empty middle alternative non-greedy '*'
    129 var re14 = new RegExp(/(a||z)*?/);
    130 shouldBe('emptyStr.match(re14)', '["", undefined]');
    131 shouldBe('s1.match(re14)', '["", undefined]');
    132 shouldBe('s2.match(re14)', '["", undefined]');
    133 shouldBe('s3.match(re14)', '["", undefined]');
    134 
    135 // Capturing empty last alternative non-greedy '*'
    136 var re15 = new RegExp(/(a|z|)*?/);
    137 shouldBe('emptyStr.match(re15)', '["", undefined]');
    138 shouldBe('s1.match(re15)', '["", undefined]');
    139 shouldBe('s2.match(re15)', '["", undefined]');
    140 shouldBe('s3.match(re15)', '["", undefined]');
    141 
    142 // Non-capturing empty first alternative greedy '?'
    143 var re16 = new RegExp(/(?:|a|z)?/);
    144 shouldBe('emptyStr.match(re16)', '[""]');
    145 shouldBe('s1.match(re16)', '[""]');
    146 shouldBe('s2.match(re16)', '["a"]');
    147 shouldBe('s3.match(re16)', '["a"]');
    148 
    149 // Non-capturing empty middle alternative greedy '?'
    150 var re17 = new RegExp(/(?:a||z)?/);
    151 shouldBe('emptyStr.match(re17)', '[""]');
    152 shouldBe('s1.match(re17)', '[""]');
    153 shouldBe('s2.match(re17)', '["a"]');
    154 shouldBe('s3.match(re17)', '["a"]');
    155 
    156 // Non-capturing empty last alternative greedy '?'
    157 var re18 = new RegExp(/(?:a|z|)?/);
    158 shouldBe('emptyStr.match(re18)', '[""]');
    159 shouldBe('s1.match(re18)', '[""]');
    160 shouldBe('s2.match(re18)', '["a"]');
    161 shouldBe('s3.match(re18)', '["a"]');
    162 
    163 // Capturing empty first alternative greedy '?'
    164 var re19 = new RegExp(/(|a|z)?/);
    165 shouldBe('emptyStr.match(re19)', '["", undefined]');
    166 shouldBe('s1.match(re19)', '["", undefined]');
    167 shouldBe('s2.match(re19)', '["a", "a"]');
    168 shouldBe('s3.match(re19)', '["a", "a"]');
    169 
    170 // Capturing empty middle alternative greedy '?'
    171 var re20 = new RegExp(/(a||z)?/);
    172 shouldBe('emptyStr.match(re20)', '["", undefined]');
    173 shouldBe('s1.match(re20)', '["", undefined]');
    174 shouldBe('s2.match(re20)', '["a", "a"]');
    175 shouldBe('s3.match(re20)', '["a", "a"]');
    176 
    177 // Capturing empty last alternative greedy '?'
    178 var re21 = new RegExp(/(a|z|)?/);
    179 shouldBe('emptyStr.match(re21)', '["", undefined]');
    180 shouldBe('s1.match(re21)', '["", undefined]');
    181 shouldBe('s2.match(re21)', '["a", "a"]');
    182 shouldBe('s3.match(re21)', '["a", "a"]');
    183 
    184 // Non-capturing empty first alternative non-greedy '?'
    185 var re22 = new RegExp(/(?:|a|z)??/);
    186 shouldBe('emptyStr.match(re22)', '[""]');
    187 shouldBe('s1.match(re22)', '[""]');
    188 shouldBe('s2.match(re22)', '[""]');
    189 shouldBe('s3.match(re22)', '[""]');
    190 
    191 // Non-capturing empty middle alternative non-greedy '?'
    192 var re23 = new RegExp(/(?:a||z)??/);
    193 shouldBe('emptyStr.match(re23)', '[""]');
    194 shouldBe('s1.match(re23)', '[""]');
    195 shouldBe('s2.match(re23)', '[""]');
    196 shouldBe('s3.match(re23)', '[""]');
    197 
    198 // Non-capturing empty last alternative non-greedy '?'
    199 var re24 = new RegExp(/(?:a|z|)??/);
    200 shouldBe('emptyStr.match(re24)', '[""]');
    201 shouldBe('s1.match(re24)', '[""]');
    202 shouldBe('s2.match(re24)', '[""]');
    203 shouldBe('s3.match(re24)', '[""]');
    204 
    205 // Capturing empty first alternative non-greedy '?'
    206 var re25 = new RegExp(/(|a|z)??/);
    207 shouldBe('emptyStr.match(re25)', '["", undefined]');
    208 shouldBe('s1.match(re25)', '["", undefined]');
    209 shouldBe('s2.match(re25)', '["", undefined]');
    210 shouldBe('s3.match(re25)', '["", undefined]');
    211 
    212 // Capturing empty middle alternative non-greedy '?'
    213 var re26 = new RegExp(/(a||z)??/);
    214 shouldBe('emptyStr.match(re26)', '["", undefined]');
    215 shouldBe('s1.match(re26)', '["", undefined]');
    216 shouldBe('s2.match(re26)', '["", undefined]');
    217 shouldBe('s3.match(re26)', '["", undefined]');
    218 
    219 // Capturing empty last alternative non-greedy '?'
    220 var re27 = new RegExp(/(a|z|)??/);
    221 shouldBe('emptyStr.match(re27)', '["", undefined]');
    222 shouldBe('s1.match(re27)', '["", undefined]');
    223 shouldBe('s2.match(re27)', '["", undefined]');
    224 shouldBe('s3.match(re27)', '["", undefined]');
    225 
    226 // Non-capturing empty first alternative greedy '*' non-terminal
    227 var re28 = new RegExp(/(?:|a|z)*x/);
    228 shouldBe('emptyStr.match(re28)', 'null');
    229 shouldBe('s1.match(re28)', '["x"]');
    230 shouldBe('s2.match(re28)', 'null');
    231 shouldBe('s3.match(re28)', '["aax"]');
    232 
    233 // Non-capturing empty middle alternative greedy '*' non-terminal
    234 var re29 = new RegExp(/(?:a||z)*x/);
    235 shouldBe('emptyStr.match(re29)', 'null');
    236 shouldBe('s1.match(re29)', '["x"]');
    237 shouldBe('s2.match(re29)', 'null');
    238 shouldBe('s3.match(re29)', '["aax"]');
    239 
    240 // Non-capturing empty last alternative greedy '*' non-terminal
    241 var re30 = new RegExp(/(?:a|z|)*x/);
    242 shouldBe('emptyStr.match(re30)', 'null');
    243 shouldBe('s1.match(re30)', '["x"]');
    244 shouldBe('s2.match(re30)', 'null');
    245 shouldBe('s3.match(re30)', '["aax"]');
    246 
    247 // Non-capturing two possibly empty alternatives greedy '*'
    248 var re31 = new RegExp(/(?:a*|b*)*/);
    249 shouldBe('emptyStr.match(re31)', '[""]');
    250 shouldBe('s1.match(re31)', '[""]');
    251 shouldBe('s3.match(re31)', '["aa"]');
    252 shouldBe('s4.match(re31)', '["abab"]');
    253 
    254 // Non-capturing two possibly empty non-greedy alternatives non-greedy '*'
    255 var re32 = new RegExp(/(?:a*?|b*?)*/);
    256 shouldBe('emptyStr.match(re32)', '[""]');
    257 shouldBe('s1.match(re32)', '[""]');
    258 shouldBe('s2.match(re32)', '["aaaa"]');
    259 shouldBe('s4.match(re32)', '["abab"]');
    260 shouldBe('s5.match(re32)', '["ab"]');
    261 shouldBe('s6.match(re32)', '[""]');
    262 
    263 // Three possibly empty alternatives with greedy +
    264 var re33 = new RegExp(/(?:(?:(?!))|g?|0*\*?)+/);
    265 shouldBe('emptyStr.match(re33)', '[""]');
    266 shouldBe('s1.match(re33)', '[""]');
    267 shouldBe('s7.match(re33)', '["g0"]');
    268 
    269 // first alternative zero length fixed count
    270 var re34 = new RegExp(/(?:|a)/);
    271 shouldBe('emptyStr.match(re34)', '[""]');
    272 shouldBe('s1.match(re34)', '[""]');
    273 shouldBe('s2.match(re34)', '[""]');
    274 shouldBe('s3.match(re34)', '[""]');
    275