1 /** 2 * File Name: String/split-002.js 3 * ECMA Section: 15.6.4.9 4 * Description: Based on ECMA 2 Draft 7 February 1999 5 * 6 * Author: christine (at) netscape.com 7 * Date: 19 February 1999 8 */ 9 10 /* 11 * Since regular expressions have been part of JavaScript since 1.2, there 12 * are already tests for regular expressions in the js1_2/regexp folder. 13 * 14 * These new tests try to supplement the existing tests, and verify that 15 * our implementation of RegExp conforms to the ECMA specification, but 16 * does not try to be as exhaustive as in previous tests. 17 * 18 * The [,limit] argument to String.split is new, and not covered in any 19 * existing tests. 20 * 21 * String.split cases are covered in ecma/String/15.5.4.8-*.js. 22 * String.split where separator is a RegExp are in 23 * js1_2/regexp/string_split.js 24 * 25 */ 26 27 var SECTION = "ecma_2/String/split-002.js"; 28 var VERSION = "ECMA_2"; 29 var TITLE = "String.prototype.split( regexp, [,limit] )"; 30 31 startTest(); 32 33 // the separator is not supplied 34 // separator is undefined 35 // separator is an empty string 36 37 // AddSplitCases( "splitme", "", "''", ["s", "p", "l", "i", "t", "m", "e"] ); 38 // AddSplitCases( "splitme", new RegExp(), "new RegExp()", ["s", "p", "l", "i", "t", "m", "e"] ); 39 40 // separator is an empty regexp 41 // separator is not supplied 42 43 CompareSplit( "hello", "ll" ); 44 45 CompareSplit( "hello", "l" ); 46 CompareSplit( "hello", "x" ); 47 CompareSplit( "hello", "h" ); 48 CompareSplit( "hello", "o" ); 49 CompareSplit( "hello", "hello" ); 50 CompareSplit( "hello", undefined ); 51 52 CompareSplit( "hello", ""); 53 CompareSplit( "hello", "hellothere" ); 54 55 CompareSplit( new String("hello" ) ); 56 57 58 Number.prototype.split = String.prototype.split; 59 60 CompareSplit( new Number(100111122133144155), 1 ); 61 CompareSplitWithLimit(new Number(100111122133144155), 1, 1 ); 62 63 CompareSplitWithLimit(new Number(100111122133144155), 1, 2 ); 64 CompareSplitWithLimit(new Number(100111122133144155), 1, 0 ); 65 CompareSplitWithLimit(new Number(100111122133144155), 1, 100 ); 66 CompareSplitWithLimit(new Number(100111122133144155), 1, void 0 ); 67 CompareSplitWithLimit(new Number(100111122133144155), 1, Math.pow(2,32)-1 ); 68 CompareSplitWithLimit(new Number(100111122133144155), 1, "boo" ); 69 CompareSplitWithLimit(new Number(100111122133144155), 1, -(Math.pow(2,32)-1) ); 70 CompareSplitWithLimit( "hello", "l", NaN ); 71 CompareSplitWithLimit( "hello", "l", 0 ); 72 CompareSplitWithLimit( "hello", "l", 1 ); 73 CompareSplitWithLimit( "hello", "l", 2 ); 74 CompareSplitWithLimit( "hello", "l", 3 ); 75 CompareSplitWithLimit( "hello", "l", 4 ); 76 77 78 /* 79 CompareSplitWithLimit( "hello", "ll", 0 ); 80 CompareSplitWithLimit( "hello", "ll", 1 ); 81 CompareSplitWithLimit( "hello", "ll", 2 ); 82 CompareSplit( "", " " ); 83 CompareSplit( "" ); 84 */ 85 86 // separartor is a regexp 87 // separator regexp value global setting is set 88 // string is an empty string 89 // if separator is an empty string, split each by character 90 91 // this is not a String object 92 93 // limit is not a number 94 // limit is undefined 95 // limit is larger than 2^32-1 96 // limit is a negative number 97 98 test(); 99 100 function CompareSplit( string, separator ) { 101 split_1 = string.split( separator ); 102 split_2 = string_split( string, separator ); 103 104 AddTestCase( 105 "( " + string +".split(" + separator + ") ).length" , 106 split_2.length, 107 split_1.length ); 108 109 var limit = split_1.length > split_2.length ? 110 split_1.length : split_2.length; 111 112 for ( var split_item = 0; split_item < limit; split_item++ ) { 113 AddTestCase( 114 string + ".split(" + separator + ")["+split_item+"]", 115 split_2[split_item], 116 split_1[split_item] ); 117 } 118 } 119 120 function CompareSplitWithLimit( string, separator, splitlimit ) { 121 split_1 = string.split( separator, splitlimit ); 122 split_2 = string_split( string, separator, splitlimit ); 123 124 AddTestCase( 125 "( " + string +".split(" + separator + ", " + splitlimit+") ).length" , 126 split_2.length, 127 split_1.length ); 128 129 var limit = split_1.length > split_2.length ? 130 split_1.length : split_2.length; 131 132 for ( var split_item = 0; split_item < limit; split_item++ ) { 133 AddTestCase( 134 string + ".split(" + separator + ", " + splitlimit+")["+split_item+"]", 135 split_2[split_item], 136 split_1[split_item] ); 137 } 138 } 139 140 function string_split ( __this, separator, limit ) { 141 var S = String(__this ); // 1 142 143 var A = new Array(); // 2 144 145 if ( limit == undefined ) { // 3 146 lim = Math.pow(2, 31 ) -1; 147 } else { 148 lim = ToUint32( limit ); 149 } 150 151 var s = S.length; // 4 152 var p = 0; // 5 153 154 if ( separator == undefined ) { // 8 155 A[0] = S; 156 return A; 157 } 158 159 if ( separator.constructor == RegExp ) // 6 160 R = separator; 161 else 162 R = separator.toString(); 163 164 if (lim == 0) return A; // 7 165 166 if ( separator == undefined ) { // 8 167 A[0] = S; 168 return A; 169 } 170 171 if (s == 0) { // 9 172 z = SplitMatch(R, S, 0); 173 if (z != false) return A; 174 A[0] = S; 175 return A; 176 } 177 178 var q = p; // 10 179 loop: 180 while (true ) { 181 182 if ( q == s ) break; // 11 183 184 z = SplitMatch(R, S, q); // 12 185 186 //print("Returned ", z); 187 188 if (z != false) { // 13 189 e = z.endIndex; // 14 190 cap = z.captures; // 14 191 if (e != p) { // 15 192 //print("S = ", S, ", p = ", p, ", q = ", q); 193 T = S.slice(p, q); // 16 194 //print("T = ", T); 195 A[A.length] = T; // 17 196 if (A.length == lim) return A; // 18 197 p = e; // 19 198 i = 0; // 20 199 while (true) { // 25 200 if (i == cap.length) { // 21 201 q = p; // 10 202 continue loop; 203 } 204 i = i + 1; // 22 205 A[A.length] = cap[i] // 23 206 if (A.length == lim) return A; // 24 207 } 208 } 209 } 210 211 q = q + 1; // 26 212 } 213 214 T = S.slice(p, q); 215 A[A.length] = T; 216 return A; 217 } 218 219 function SplitMatch(R, S, q) 220 { 221 if (R.constructor == RegExp) { // 1 222 var reResult = R.match(S, q); // 8 223 if (reResult == undefined) 224 return false; 225 else { 226 a = new Array(reResult.length - 1); 227 for (var i = 1; i < reResult.length; i++) 228 a[a.length] = reResult[i]; 229 return { endIndex : reResult.index + reResult[0].length, captures : cap }; 230 } 231 } 232 else { 233 var r = R.length; // 2 234 s = S.length; // 3 235 if ((q + r) > s) return false; // 4 236 for (var i = 0; i < r; i++) { 237 //print("S.charAt(", q + i, ") = ", S.charAt(q + i), ", R.charAt(", i, ") = ", R.charAt(i)); 238 if (S.charAt(q + i) != R.charAt(i)) // 5 239 return false; 240 } 241 cap = new Array(); // 6 242 return { endIndex : q + r, captures : cap }; // 7 243 } 244 } 245 246 function ToUint32( n ) { 247 n = Number( n ); 248 var sign = ( n < 0 ) ? -1 : 1; 249 250 if ( Math.abs( n ) == 0 251 || Math.abs( n ) == Number.POSITIVE_INFINITY 252 || n != n) { 253 return 0; 254 } 255 n = sign * Math.floor( Math.abs(n) ) 256 257 n = n % Math.pow(2,32); 258 259 if ( n < 0 ){ 260 n += Math.pow(2,32); 261 } 262 263 return ( n ); 264 } 265