/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * File Name: String/split-002.js * ECMA Section: 15.6.4.9 * Description: Based on ECMA 2 Draft 7 February 1999 * * Author: christine@netscape.com * Date: 19 February 1999 */ /* * Since regular expressions have been part of JavaScript since 1.2, there * are already tests for regular expressions in the js1_2/regexp folder. * * These new tests try to supplement the existing tests, and verify that * our implementation of RegExp conforms to the ECMA specification, but * does not try to be as exhaustive as in previous tests. * * The [,limit] argument to String.split is new, and not covered in any * existing tests. * * String.split cases are covered in ecma/String/15.5.4.8-*.js. * String.split where separator is a RegExp are in * js1_2/regexp/string_split.js * */ var SECTION = "ecma_2/String/split-002.js"; var VERSION = "ECMA_2"; var TITLE = "String.prototype.split( regexp, [,limit] )"; startTest(); // the separator is not supplied // separator is undefined // separator is an empty string // AddSplitCases( "splitme", "", "''", ["s", "p", "l", "i", "t", "m", "e"] ); // AddSplitCases( "splitme", new RegExp(), "new RegExp()", ["s", "p", "l", "i", "t", "m", "e"] ); // separator is an empty regexp // separator is not supplied CompareSplit( "hello", "ll" ); CompareSplit( "hello", "l" ); CompareSplit( "hello", "x" ); CompareSplit( "hello", "h" ); CompareSplit( "hello", "o" ); CompareSplit( "hello", "hello" ); CompareSplit( "hello", undefined ); CompareSplit( "hello", ""); CompareSplit( "hello", "hellothere" ); CompareSplit( new String("hello" ) ); Number.prototype.split = String.prototype.split; CompareSplit( new Number(100111122133144155), 1 ); CompareSplitWithLimit(new Number(100111122133144155), 1, 1 ); CompareSplitWithLimit(new Number(100111122133144155), 1, 2 ); CompareSplitWithLimit(new Number(100111122133144155), 1, 0 ); CompareSplitWithLimit(new Number(100111122133144155), 1, 100 ); CompareSplitWithLimit(new Number(100111122133144155), 1, void 0 ); CompareSplitWithLimit(new Number(100111122133144155), 1, Math.pow(2,32)-1 ); CompareSplitWithLimit(new Number(100111122133144155), 1, "boo" ); CompareSplitWithLimit(new Number(100111122133144155), 1, -(Math.pow(2,32)-1) ); CompareSplitWithLimit( "hello", "l", NaN ); CompareSplitWithLimit( "hello", "l", 0 ); CompareSplitWithLimit( "hello", "l", 1 ); CompareSplitWithLimit( "hello", "l", 2 ); CompareSplitWithLimit( "hello", "l", 3 ); CompareSplitWithLimit( "hello", "l", 4 ); /* CompareSplitWithLimit( "hello", "ll", 0 ); CompareSplitWithLimit( "hello", "ll", 1 ); CompareSplitWithLimit( "hello", "ll", 2 ); CompareSplit( "", " " ); CompareSplit( "" ); */ // separartor is a regexp // separator regexp value global setting is set // string is an empty string // if separator is an empty string, split each by character // this is not a String object // limit is not a number // limit is undefined // limit is larger than 2^32-1 // limit is a negative number test(); function CompareSplit( string, separator ) { split_1 = string.split( separator ); split_2 = string_split( string, separator ); AddTestCase( "( " + string +".split(" + separator + ") ).length" , split_2.length, split_1.length ); var limit = split_1.length > split_2.length ? split_1.length : split_2.length; for ( var split_item = 0; split_item < limit; split_item++ ) { AddTestCase( string + ".split(" + separator + ")["+split_item+"]", split_2[split_item], split_1[split_item] ); } } function CompareSplitWithLimit( string, separator, splitlimit ) { split_1 = string.split( separator, splitlimit ); split_2 = string_split( string, separator, splitlimit ); AddTestCase( "( " + string +".split(" + separator + ", " + splitlimit+") ).length" , split_2.length, split_1.length ); var limit = split_1.length > split_2.length ? split_1.length : split_2.length; for ( var split_item = 0; split_item < limit; split_item++ ) { AddTestCase( string + ".split(" + separator + ", " + splitlimit+")["+split_item+"]", split_2[split_item], split_1[split_item] ); } } function string_split ( __this, separator, limit ) { var S = String(__this ); // 1 var A = new Array(); // 2 if ( limit == undefined ) { // 3 lim = Math.pow(2, 31 ) -1; } else { lim = ToUint32( limit ); } var s = S.length; // 4 var p = 0; // 5 if ( separator == undefined ) { // 8 A[0] = S; return A; } if ( separator.constructor == RegExp ) // 6 R = separator; else R = separator.toString(); if (lim == 0) return A; // 7 if ( separator == undefined ) { // 8 A[0] = S; return A; } if (s == 0) { // 9 z = SplitMatch(R, S, 0); if (z != false) return A; A[0] = S; return A; } var q = p; // 10 loop: while (true ) { if ( q == s ) break; // 11 z = SplitMatch(R, S, q); // 12 //print("Returned ", z); if (z != false) { // 13 e = z.endIndex; // 14 cap = z.captures; // 14 if (e != p) { // 15 //print("S = ", S, ", p = ", p, ", q = ", q); T = S.slice(p, q); // 16 //print("T = ", T); A[A.length] = T; // 17 if (A.length == lim) return A; // 18 p = e; // 19 i = 0; // 20 while (true) { // 25 if (i == cap.length) { // 21 q = p; // 10 continue loop; } i = i + 1; // 22 A[A.length] = cap[i] // 23 if (A.length == lim) return A; // 24 } } } q = q + 1; // 26 } T = S.slice(p, q); A[A.length] = T; return A; } function SplitMatch(R, S, q) { if (R.constructor == RegExp) { // 1 var reResult = R.match(S, q); // 8 if (reResult == undefined) return false; else { a = new Array(reResult.length - 1); for (var i = 1; i < reResult.length; i++) a[a.length] = reResult[i]; return { endIndex : reResult.index + reResult[0].length, captures : cap }; } } else { var r = R.length; // 2 s = S.length; // 3 if ((q + r) > s) return false; // 4 for (var i = 0; i < r; i++) { //print("S.charAt(", q + i, ") = ", S.charAt(q + i), ", R.charAt(", i, ") = ", R.charAt(i)); if (S.charAt(q + i) != R.charAt(i)) // 5 return false; } cap = new Array(); // 6 return { endIndex : q + r, captures : cap }; // 7 } } function ToUint32( n ) { n = Number( n ); var sign = ( n < 0 ) ? -1 : 1; if ( Math.abs( n ) == 0 || Math.abs( n ) == Number.POSITIVE_INFINITY || n != n) { return 0; } n = sign * Math.floor( Math.abs(n) ) n = n % Math.pow(2,32); if ( n < 0 ){ n += Math.pow(2,32); } return ( n ); }