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@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
100function 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
120function 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
140function 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
179loop:
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
219function 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
246function 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