/*=== basic test string 1 a string 1 b string 1 c string 1 A string 1 B string 1 C string 1 U+0000 string 1 f string 1 o string 1 o string 1 U+0081 string 1 b string 1 a string 1 r string 1 U+07FF string 1 q string 1 u string 1 u string 1 x string 1 U+1234 string 1 b string 1 a string 1 z string 1 U+FEDC string 1 x string 1 y string 1 z string 1 U+FFFF ===*/ print('basic test'); function charAtTest() { var str = new String('abcABC\u0000foo\u0081bar\u07ffquux\u1234baz\ufedcxyz\uffff'); var i; // we want to print out ascii but don't want to rely on charCodeAt(). // use a hashmap to "stringify" the non-ascii chars var map = { '\u0000': 'U+0000', '\u0081': 'U+0081', '\u07ff': 'U+07FF', '\u1234': 'U+1234', '\ufedc': 'U+FEDC', '\uffff': 'U+FFFF', } function pc(c) { print(typeof c, c.length, (c >= ' ' && c <= '~' ? c : map[c])); } // print in order for (i = 0; i < str.length; i++) { pc(str.charAt(i)); } } try { charAtTest(); } catch (e) { print(e); } /*=== oob test -3 0 -2 0 -1 0 0 1 b 1 1 a 2 1 r 3 0 4 0 5 0 -Infinity 0 Infinity 0 NaN 1 b ===*/ print('oob test'); function outOfBoundsTest() { var str = new String('bar'); var i; function pc(idx) { var c = str.charAt(idx); print(idx, c.length, c); } for (i = -3; i < 6; i++) { pc(i); } pc(Number.NEGATIVE_INFINITY), pc(Number.POSITIVE_INFINITY), // ToInteger(NaN) coerces to 0 -> 'b' pc(Number.NaN); } try { outOfBoundsTest(); } catch (e) { print(e); } /*=== random access test random access test done ===*/ /* Random access test for a large string. The purpose of this test is to * stress the stringcache. Note that the test is not deterministic. */ print('random access test'); function randomAccessTest() { var tmp = []; var str; var i; var idx, c1, c2; for (i = 0; i < 65536; i++) { tmp.push(String.fromCharCode(i)); } str = new String(tmp.join('')); for (i = 0; i < 100000; i++) { idx = Math.floor(Math.random() * 65536); c1 = str.charAt(idx); c2 = String.fromCharCode(idx); // XXX: unfortunately we depend on this too if (c1 !== c2) { print('random access test failed for index', idx); } } print('random access test done'); } try { randomAccessTest(); } catch (e) { print(e); } /*=== coercion testing undefined TypeError testing null TypeError testing true 0 string t 1 string r 2 string u 3 string e testing false 0 string f 1 string a 2 string l 3 string s 4 string e testing 123 0 string 1 1 string 2 2 string 3 testing foo 0 string f 1 string o 2 string o testing 1,2 0 string 1 1 string , 2 string 2 testing [object Object] 0 string [ 1 string o 2 string b 3 string j 4 string e 5 string c 6 string t 7 string 8 string O 9 string b 10 string j 11 string e 12 string c 13 string t 14 string ] ===*/ /* charAt() is generic, check 'this' coercion */ print('coercion'); function thisCoercionTest() { function test(x) { var c; var i; print('testing', x); try { for (i = 0; ; i++) { c = String.prototype.charAt.call(x, i); if (c === '') { break; } print(i, typeof c, c); } } catch (e) { print(e.name); } } // undefined and null cause TypeError from CheckObjectCoercible test(undefined); test(null); test(true); test(false); test(123); test('foo'); test([1,2]); test({ foo: 1, bar: 2 }); } try { thisCoercionTest(); } catch (e) { print(e); }