Browse Source

string and global object testcases

pull/1/head
Sami Vaarala 12 years ago
parent
commit
fba8d983b2
  1. 219
      testcases/test-builtin-global-unescape.js
  2. 336
      testcases/test-builtin-string-proto-indexof.js
  3. 336
      testcases/test-builtin-string-proto-lastindexof.js
  4. 258
      testcases/test-builtin-string-proto-localecompare.js
  5. 28
      testcases/test-builtin-string-proto-slice-comp.js
  6. 1024
      testcases/test-builtin-string-proto-slice.js

219
testcases/test-builtin-global-unescape.js

@ -0,0 +1,219 @@
// FIXME: util
/* Trivial string checksum used to summarize brute force output lines
* (minimizes test case size).
*/
function checkSumString(x) {
var i, n;
var res = 0;
var mult = [ 1, 3, 5, 7, 11, 13, 17, 19, 23 ];
n = x.length;
for (i = 0; i < n; i++) {
res += x.charCodeAt(i) * mult[i % mult.length];
res = res >>> 0; // coerce to 32 bits
}
return res;
}
// FIXME: util
function getCodePoints(x) {
var res = [];
var i, n;
n = x.length;
for (i = 0; i < n; i++) {
res.push(x.charCodeAt(i));
}
return res.join(' ');
}
// indirect eval -> this is bound to the global object, E5 Section 10.4.2, step 1.a.
var g = (function () { var e = eval; return e('this'); } )();
var ucnybbles = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ];
var lcnybbles = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' ];
/*===
basic
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
37 117 49 50 51
37 117 49 50 51 103
37 117 49 50 51 71
37 85 49 50 51 52
4671
4671
37 49
37 49 103
37 49 71
31
31
%x escapes
%u escapes
===*/
print('basic');
function basicTest() {
var i;
var tmp;
// simple test of the 8-bit range
tmp = [];
for (i = 0; i < 256; i++) {
tmp.push(String.fromCharCode(i));
}
tmp = tmp.join('');
print(getCodePoints(g.unescape(tmp)));
// % must be followed by 'u' and 4 hex digits to make a unicode escape
print(getCodePoints(g.unescape('%u123')));
print(getCodePoints(g.unescape('%u123g')));
print(getCodePoints(g.unescape('%u123G')));
print(getCodePoints(g.unescape('%U1234'))); // uppercase 'u' not accepted
print(getCodePoints(g.unescape('%u123f'))); // valid
print(getCodePoints(g.unescape('%u123F'))); // valid
// % must be followed by 'x' and 2 hex digits to make a short escape
print(getCodePoints(g.unescape('%1')));
print(getCodePoints(g.unescape('%1g')));
print(getCodePoints(g.unescape('%1G')));
print(getCodePoints(g.unescape('%1f'))); // valid
print(getCodePoints(g.unescape('%1F'))); // valid
// check that all 2-byte escapes work
print('%x escapes');
for (i = 0; i < 256; i++) {
tmp = '%' + ucnybbles[i >> 4] + ucnybbles[i & 0x0f];
res = g.unescape(tmp);
if (res.length !== 1 || res.charCodeAt(0) !== i) {
print('unescape error for %xx at index i:', i);
}
tmp = '%' + lcnybbles[i >> 4] + lcnybbles[i & 0x0f];
res = g.unescape(tmp);
if (res.length !== 1 || res.charCodeAt(0) !== i) {
print('unescape error for %xx at index i:', i);
}
}
// check that all 4-byte escapes work
print('%u escapes');
for (i = 0; i < 65536; i++) {
tmp = '%u' + ucnybbles[(i >> 12) & 0x0f] + ucnybbles[(i >> 8) & 0x0f] +
ucnybbles[(i >> 4) & 0x0f] + ucnybbles[i & 0x0f];
res = g.unescape(tmp);
if (res.length !== 1 || res.charCodeAt(0) !== i) {
print('unescape error for %uxxxx at index i:', i);
}
tmp = '%u' + lcnybbles[(i >> 12) & 0x0f] + lcnybbles[(i >> 8) & 0x0f] +
lcnybbles[(i >> 4) & 0x0f] + lcnybbles[i & 0x0f];
res = g.unescape(tmp);
if (res.length !== 1 || res.charCodeAt(0) !== i) {
print('unescape error for %uxxxx at index i:', i);
}
}
}
try {
basicTest();
} catch (e) {
print(e);
}
/*===
bruteforce
0 5759968
1024 17273824
2048 28787680
3072 40301536
4096 51815392
5120 63329248
6144 74843104
7168 86356960
8192 97870816
9216 109384672
10240 120898528
11264 132412384
12288 143926240
13312 155440096
14336 166953952
15360 178467808
16384 189981664
17408 201495520
18432 213009376
19456 224523232
20480 236037088
21504 247550944
22528 259064800
23552 270578656
24576 282092512
25600 293606368
26624 305120224
27648 316634080
28672 328147936
29696 339661792
30720 351175648
31744 362689504
32768 374203360
33792 385717216
34816 397231072
35840 408744928
36864 420258784
37888 431772640
38912 443286496
39936 454800352
40960 466314208
41984 477828064
43008 489341920
44032 500855776
45056 512369632
46080 523883488
47104 535397344
48128 546911200
49152 558425056
50176 569938912
51200 581452768
52224 592966624
53248 604480480
54272 615994336
55296 627508192
56320 639022048
57344 650535904
58368 662049760
59392 673563616
60416 685077472
61440 696591328
62464 708105184
63488 719619040
64512 731132896
===*/
print('bruteforce');
function bruteForceTest() {
var i;
var tmp;
// decode every character (including '%', because the characters
// following it won't make a valid escape, it will decode as itself)
for (i = 0; i < 65536; i += 1024) {
tmp = [];
for (j = 0; j < 1024; j++) {
tmp.push(String.fromCharCode(i + j));
}
tmp = tmp.join('');
print(i, checkSumString(g.unescape(tmp)));
}
}
try {
bruteForceTest();
} catch (e) {
print(e.name);
}

336
testcases/test-builtin-string-proto-indexof.js

@ -0,0 +1,336 @@
/*===
basic
number 0
number 3
number 6
number 9
number -1
number 9
number -1
number -1
===*/
print('basic');
function basicTest() {
var str = new String('foobarfoobar');
function p(x) {
print(typeof x, x);
}
p(str.indexOf('foo'));
p(str.indexOf('bar'));
p(str.indexOf('foo', 1));
p(str.indexOf('bar', 5));
p(str.indexOf('foo', 8));
p(str.indexOf('bar', 9)); // still found
p(str.indexOf('bar', 10)); // not found
p(str.indexOf('quux'));
}
try {
basicTest();
} catch (e) {
print(e);
}
/*===
empty
number 0
number 0
number 0
number 0
number 0
number 1
number 2
number 3
number 4
number 5
number 6
number 6
number 6
number 6
number 0
number 6
number 0
===*/
/* An empty search string is always found immediately at the starting
* position. Thus, the return value is the input position, clamped to
* to range [0,len(str)].
*
* There is some variance among implementations. V8 will return a value
* in the range [0,6] for the test below, whereas Rhino will return a 0
* for any negative position, but -1 (not found) for initial position 7
* or above.
*/
print('empty');
function emptyTest() {
var str = new String('foobar');
var i;
function p(x) {
print(typeof x, x);
}
p(str.indexOf(''));
for (i = -3; i < 10; i++) {
p(str.indexOf('', i));
}
p(str.indexOf('', Number.NEGATIVE_INFINITY));
p(str.indexOf('', Number.POSITIVE_INFINITY));
p(str.indexOf('', Number.NaN)); // coerces to 0
}
try {
emptyTest();
} catch (e) {
print(e);
}
/*===
position
number 0
number 0
number 0
number 0
number 0
number 0
number 0
number 0
number 1
number 2
number 3
number 4
number 5
number -1
number -1
number -1
number -1
number -1
number 0
number 3
number 3
number 3
number 3
number 0
number 0
number 0
number 0
number -1
number -1
===*/
/* Position handling. The position is coerced with ToInteger(), then
* clamped to the range [0, len(str)]. ToInteger(NaN) is 0.
*/
print('position');
function positionTest() {
// test string, 'x' always found if index < 6
var str = 'xxxxxx';
function p(x) {
print(typeof x, x);
}
p(str.indexOf('x'));
p(str.indexOf('x', Number.NEGATIVE_INFINITY));
p(str.indexOf('x', -123));
p(str.indexOf('x', -3));
p(str.indexOf('x', -2));
p(str.indexOf('x', -1));
p(str.indexOf('x', -0));
p(str.indexOf('x', 0));
p(str.indexOf('x', 1));
p(str.indexOf('x', 2));
p(str.indexOf('x', 3));
p(str.indexOf('x', 4));
p(str.indexOf('x', 5));
p(str.indexOf('x', 6));
p(str.indexOf('x', 7));
p(str.indexOf('x', 8));
p(str.indexOf('x', 123));
p(str.indexOf('x', Number.POSITIVE_INFINITY));
p(str.indexOf('x', Number.NaN));
// fractions
p(str.indexOf('x', 3.0));
p(str.indexOf('x', 3.1));
p(str.indexOf('x', 3.5));
p(str.indexOf('x', 3.9));
p(str.indexOf('x', -3.0));
p(str.indexOf('x', -3.1));
p(str.indexOf('x', -3.5));
p(str.indexOf('x', -3.9));
// if string is empty, even zero/NaN will yield -1 (not found)
str = new String('');
p(str.indexOf('x', 0));
p(str.indexOf('x', Number.NaN));
}
try {
positionTest();
} catch (e) {
print(e);
}
/*===
argument coercion
number 7
number 7
number 17
number 22
number 27
number 33
number 37
number 41
number 45
toString()
number 37
toString()
valueOf()
number 33
===*/
/* Argument coercion. Argument is coerced with ToString. */
print('argument coercion');
function argumentTest() {
var str = new String('foobar undefined null true false 123 baz 1,2 [object Object]');
function p(x) {
print(typeof x, x);
}
p(str.indexOf()); // argument not given
p(str.indexOf(undefined));
p(str.indexOf(null));
p(str.indexOf(true));
p(str.indexOf(false));
p(str.indexOf(123));
p(str.indexOf('baz'));
p(str.indexOf([1,2]));
p(str.indexOf({ foo: 1, bar: 2 }));
// coercion side effect
p(str.indexOf({
toString: function() { print('toString()'); return 'baz'; },
valueOf: function() { print('valueOf()'); return '123'; }
}));
// ToString() coercion falls back from toString() to valueOf() if toString()
// returns a non-primitive value
p(str.indexOf({
toString: function() { print('toString()'); return []; },
valueOf: function() { print('valueOf()'); return '123'; }
}));
}
try {
argumentTest();
} catch (e) {
print(e);
}
/*===
this coercion
TypeError
TypeError
number 0
number 2
number 1
number 1
number 1
number 8
toString() this
toString() arg
number 5
===*/
/* This coercion, the method is generic. */
print('this coercion');
function thisCoercionTest() {
function test(x,y) {
var t;
try {
t = String.prototype.indexOf.call(x, y);
print(typeof t, t);
} catch (e) {
print(e.name);
}
}
test(undefined, 'undefined'); // TypeError
test(null, 'null'); // TypeError
test(true, 'true');
test(false, 'lse');
test(123, '23');
test('quux', 'uux');
test([1,2], ',2');
test({ foo: 1, bar: 2 }, 'Object');
// coercion order if both this and searchString are coerced
test({
toString: function() { print('toString() this'); return 'test string'; },
valueOf: function() { print('valueOf() this'); return 'another value'; }
}, {
toString: function() { print('toString() arg'); return 'stri'; },
valueOf: function() { print('valueOf() arg'); return 'foo'; }
});
}
try {
thisCoercionTest();
} catch (e) {
print(e);
}
/*===
non-bmp
number 0
number 3
number 7
number 7
number -1
number 7
===*/
/* Because search happens internally using a byte search, a few simple tests
* with Unicode characters of varying length.
*/
print('non-bmp');
function nonBmpTest() {
var str = new String('foo\u1234bar\udeadquux\ubeefbaz');
function p(x) {
print(typeof x, x);
}
p(str.indexOf('foo'));
p(str.indexOf('\u1234'));
p(str.indexOf('\udead'));
p(str.indexOf('\udead', 7)); // found
p(str.indexOf('\udead', 8)); // not found
p(str.indexOf('\udead', 6)); // found
}
try {
nonBmpTest();
} catch (e) {
print(e);
}

336
testcases/test-builtin-string-proto-lastindexof.js

@ -0,0 +1,336 @@
/*===
basic
number 6
number 9
number 6
number 9
number 0
number 3
number -1
number -1
===*/
print('basic');
function basicTest() {
var str = new String('foobarfoobar');
function p(x) {
print(typeof x, x);
}
p(str.lastIndexOf('foo'));
p(str.lastIndexOf('bar'));
p(str.lastIndexOf('foo', 6)); // last foo
p(str.lastIndexOf('bar', 9)); // last bar
p(str.lastIndexOf('foo', 5)); // first foo
p(str.lastIndexOf('bar', 8)); // first bar
p(str.lastIndexOf('bar', 2)); // not found
p(str.lastIndexOf('quux'));
}
try {
basicTest();
} catch (e) {
print(e);
}
/*===
empty
number 6
number 0
number 0
number 0
number 0
number 1
number 2
number 3
number 4
number 5
number 6
number 6
number 6
number 6
number 0
number 6
number 6
===*/
/* An empty search string is always found immediately at the starting
* position. Thus, the return value is the input position, clamped to
* to range [0,len(str)].
*
* There is some variance among implementations. Rhino will always
* return a value in the range [0,6] for the test below, but for
* indexOf() it will return -1 (not found) if initial position is 7
* or above.
*/
print('empty');
function emptyTest() {
var str = new String('foobar');
var i;
function p(x) {
print(typeof x, x);
}
p(str.lastIndexOf(''));
for (i = -3; i < 10; i++) {
p(str.lastIndexOf('', i));
}
p(str.lastIndexOf('', Number.NEGATIVE_INFINITY));
p(str.lastIndexOf('', Number.POSITIVE_INFINITY));
p(str.lastIndexOf('', Number.NaN)); // coerces to 0
}
try {
emptyTest();
} catch (e) {
print(e);
}
/*===
position
number 5
number 0
number 0
number 0
number 0
number 0
number 0
number 0
number 1
number 2
number 3
number 4
number 5
number 5
number 5
number 5
number 5
number 5
number 5
number 3
number 3
number 3
number 3
number 0
number 0
number 0
number 0
number -1
number -1
===*/
/* Position handling. The position is coerced with ToInteger(), then
* clamped to the range [0, len(str)]. ToInteger(NaN) is 0.
*/
print('position');
function positionTest() {
// test string, 'x' always found if index < 6
var str = 'xxxxxx';
function p(x) {
print(typeof x, x);
}
p(str.lastIndexOf('x'));
p(str.lastIndexOf('x', Number.NEGATIVE_INFINITY));
p(str.lastIndexOf('x', -123));
p(str.lastIndexOf('x', -3));
p(str.lastIndexOf('x', -2));
p(str.lastIndexOf('x', -1));
p(str.lastIndexOf('x', -0));
p(str.lastIndexOf('x', 0));
p(str.lastIndexOf('x', 1));
p(str.lastIndexOf('x', 2));
p(str.lastIndexOf('x', 3));
p(str.lastIndexOf('x', 4));
p(str.lastIndexOf('x', 5));
p(str.lastIndexOf('x', 6));
p(str.lastIndexOf('x', 7));
p(str.lastIndexOf('x', 8));
p(str.lastIndexOf('x', 123));
p(str.lastIndexOf('x', Number.POSITIVE_INFINITY));
p(str.lastIndexOf('x', Number.NaN));
// fractions
p(str.lastIndexOf('x', 3.0));
p(str.lastIndexOf('x', 3.1));
p(str.lastIndexOf('x', 3.5));
p(str.lastIndexOf('x', 3.9));
p(str.lastIndexOf('x', -3.0));
p(str.lastIndexOf('x', -3.1));
p(str.lastIndexOf('x', -3.5));
p(str.lastIndexOf('x', -3.9));
// if string is empty, even zero/NaN will yield -1 (not found)
str = new String('');
p(str.lastIndexOf('x', 0));
p(str.lastIndexOf('x', Number.NaN));
}
try {
positionTest();
} catch (e) {
print(e);
}
/*===
argument coercion
number 7
number 7
number 17
number 22
number 27
number 33
number 37
number 41
number 45
toString()
number 37
toString()
valueOf()
number 33
===*/
/* Argument coercion. Argument is coerced with ToString. */
print('argument coercion');
function argumentTest() {
var str = new String('foobar undefined null true false 123 baz 1,2 [object Object]');
function p(x) {
print(typeof x, x);
}
p(str.lastIndexOf()); // argument not given
p(str.lastIndexOf(undefined));
p(str.lastIndexOf(null));
p(str.lastIndexOf(true));
p(str.lastIndexOf(false));
p(str.lastIndexOf(123));
p(str.lastIndexOf('baz'));
p(str.lastIndexOf([1,2]));
p(str.lastIndexOf({ foo: 1, bar: 2 }));
// coercion side effect
p(str.lastIndexOf({
toString: function() { print('toString()'); return 'baz'; },
valueOf: function() { print('valueOf()'); return '123'; }
}));
// ToString() coercion falls back from toString() to valueOf() if toString()
// returns a non-primitive value
p(str.lastIndexOf({
toString: function() { print('toString()'); return []; },
valueOf: function() { print('valueOf()'); return '123'; }
}));
}
try {
argumentTest();
} catch (e) {
print(e);
}
/*===
this coercion
TypeError
TypeError
number 0
number 2
number 1
number 1
number 1
number 8
toString() this
toString() arg
number 5
===*/
/* This coercion, the method is generic. */
print('this coercion');
function thisCoercionTest() {
function test(x,y) {
var t;
try {
t = String.prototype.lastIndexOf.call(x, y);
print(typeof t, t);
} catch (e) {
print(e.name);
}
}
test(undefined, 'undefined'); // TypeError
test(null, 'null'); // TypeError
test(true, 'true');
test(false, 'lse');
test(123, '23');
test('quux', 'uux');
test([1,2], ',2');
test({ foo: 1, bar: 2 }, 'Object');
// coercion order if both this and searchString are coerced
test({
toString: function() { print('toString() this'); return 'test string'; },
valueOf: function() { print('valueOf() this'); return 'another value'; }
}, {
toString: function() { print('toString() arg'); return 'stri'; },
valueOf: function() { print('valueOf() arg'); return 'foo'; }
});
}
try {
thisCoercionTest();
} catch (e) {
print(e);
}
/*===
non-bmp
number 0
number 3
number 7
number 7
number 7
number -1
===*/
/* Because search happens internally using a byte search, a few simple tests
* with Unicode characters of varying length.
*/
print('non-bmp');
function nonBmpTest() {
var str = new String('foo\u1234bar\udeadquux\ubeefbaz');
function p(x) {
print(typeof x, x);
}
p(str.lastIndexOf('foo'));
p(str.lastIndexOf('\u1234'));
p(str.lastIndexOf('\udead'));
p(str.lastIndexOf('\udead', 7)); // found
p(str.lastIndexOf('\udead', 8)); // found
p(str.lastIndexOf('\udead', 6)); // not found
}
try {
nonBmpTest();
} catch (e) {
print(e);
}

258
testcases/test-builtin-string-proto-localecompare.js

@ -0,0 +1,258 @@
/*
* This is necessarily a custom test, because behavior is implementation
* dependent. Technically the coercion behavior could be verified in an
* implemented independent manner, but that's not very useful.
*
* The current implementation has no special localeCompare(), but will
* just use UTF-8 comparison.
*
* Other implementations seem to vary. Rhino returns a value from {-1,0,1}
* while V8 apparently returns a different of codepoints (e.g. -11094).
*/
/*===
basic
number 1
number 0
number -1
number -1
number -1
number 0
number 1
number -1
number 1
number 1
number 0
number -1
number -1
===*/
/*---
{
"custom": true
}
---*/
print('basic');
function basicTest() {
function test(x,y) {
var s1 = new String(x);
var s2 = new String(y);
var t = s1.localeCompare(s2);
print(typeof t, t);
}
// ascii baseline
test('foo', 'bar');
test('foo', 'foo');
test('foo', 'quux');
// unicode
test('foo\u1234bar\u0300', 'foo\u1234bar\u003f');
test('foo\u1234bar\u0300', 'foo\u1234bar\u02ff');
test('foo\u1234bar\u0300', 'foo\u1234bar\u0300');
test('foo\u1234bar\u0300', 'foo\u1234bar\u0301');
test('foo\u1234bar\u0300', 'foo\u1234bar\u3456');
test('foo\u1234bar\u0900', 'foo\u1234bar\u003f');
test('foo\u1234bar\u0900', 'foo\u1234bar\u08ff');
test('foo\u1234bar\u0900', 'foo\u1234bar\u0900');
test('foo\u1234bar\u0900', 'foo\u1234bar\u0901');
test('foo\u1234bar\u0900', 'foo\u1234bar\u3456');
}
try {
basicTest();
} catch (e) {
print(e);
}
/*===
coercion
this
TypeError
TypeError
TypeError
TypeError
TypeError
TypeError
number 0
number 1
number -1
number 0
number 1
number -1
number 0
number 1
number -1
number 0
number 1
number -1
number 0
number 1
number -1
number 0
number -1
number 1
argument
number 0
number -1
number 1
number 0
number -1
number 1
number 0
number -1
number 1
number 0
number -1
number 1
number 0
number -1
number 1
number 0
number -1
number 1
number 0
number -1
number 1
number 0
number 1
number -1
===*/
/* Argument and this coercion */
print('coercion');
function coercionTest() {
function test(x,y) {
var t;
try {
t = String.prototype.localeCompare.call(x, y);
print(typeof t, t);
} catch (e) {
print(e.name);
}
}
print('this');
test(undefined, 'undefined');
test(undefined, 'undefinec');
test(undefined, 'undefinee');
test(null, 'null');
test(null, 'nulk');
test(null, 'nulm');
test(true, 'true');
test(true, 'trud');
test(true, 'truf');
test(false, 'false');
test(false, 'falsd');
test(false, 'falsf');
test(123, '123');
test(123, '122');
test(123, '124');
test('foo', 'foo');
test('foo', 'fon');
test('foo', 'fop');
test([1,2], '1,2');
test([1,2], '1,1');
test([1,2], '1,3');
/*
>>> ord(']')
93
>>> chr(92)
'\\'
>>> chr(94)
'^'
*/
test({ foo: 1, bar: 2 }, '[object Object]');
test({ foo: 1, bar: 2 }, '[object Object\u005c');
test({ foo: 1, bar: 2 }, '[object Object\u005e');
print('argument');
test('undefined', undefined);
test('undefinec', undefined);
test('undefinee', undefined);
test('null', null);
test('nulk', null);
test('nulm', null);
test('true', true);
test('trud', true);
test('truf', true);
test('false', false);
test('falsd', false);
test('falsf', false);
test('123', 123);
test('122', 123);
test('124', 123);
test('foo', 'foo');
test('fon', 'foo');
test('fop', 'foo');
test('1,2', [1,2]);
test('1,1', [1,2]);
test('1,3', [1,2]);
test('[object Object]', { foo: 1, bar: 2 });
test('[object Object\u005c', { foo: 1, bar: 2 });
test('[object Object\u005e', { foo: 1, bar: 2 });
}
try {
coercionTest();
} catch (e) {
print(e);
}
/*===
no that
number 0
number -1
number 1
===*/
/* If no 'that' is given, should behave like undefined, i.e. coerce
* to the string 'undefined'.
*
* This seems to vary with the implementation. Rhino will produce
* an 'undefined' and compare as expected. V8 will return 0 for all
* comparisons (i.e. all strings "match" an undefined match string).
*/
print('no that');
function noThatTest() {
function test(x) {
var t = String.prototype.localeCompare.call(x);
print(typeof t, t);
}
test('undefined');
test('undefinec');
test('undefinee');
}
try {
noThatTest();
} catch (e) {
print(e);
}

28
testcases/test-builtin-string-proto-slice-comp.js

@ -0,0 +1,28 @@
/*
* Compare slice() against substr() and substring().
*/
var str = new String('abcdefghij');
/*===
10
de
de de
defgh fgh
===*/
try {
print(str.length);
// slice won't swap arguments like substring()
print(str.slice(3, 5), str.slice(5, 3));
print(str.substring(3, 5), str.substring(5, 3));
// substring() takes a start and end offset as arguments, but
// substr() takes a start offset and *length*
print(str.substr(3, 5), str.substr(5, 3));
} catch (e) {
print(e);
}

1024
testcases/test-builtin-string-proto-slice.js

File diff suppressed because it is too large
Loading…
Cancel
Save