Home | History | Annotate | Download | only in String
      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