| Index: test/mjsunit/string-charat.js
|
| diff --git a/test/mjsunit/string-charat.js b/test/mjsunit/string-charat.js
|
| index d1989dfd731177e50c4bd3dcbdd585995901b16e..a14d51aa528d5101d2a8744592add488ddae04f7 100644
|
| --- a/test/mjsunit/string-charat.js
|
| +++ b/test/mjsunit/string-charat.js
|
| @@ -27,29 +27,48 @@
|
|
|
| var s = "test";
|
|
|
| -assertEquals("t", s.charAt());
|
| -assertEquals("t", s.charAt("string"));
|
| -assertEquals("t", s.charAt(null));
|
| -assertEquals("t", s.charAt(void 0));
|
| -assertEquals("t", s.charAt(false));
|
| -assertEquals("e", s.charAt(true));
|
| -assertEquals("", s.charAt(-1));
|
| -assertEquals("", s.charAt(4));
|
| -assertEquals("t", s.charAt(0));
|
| -assertEquals("t", s.charAt(3));
|
| -assertEquals("t", s.charAt(NaN));
|
| -
|
| -assertEquals(116, s.charCodeAt());
|
| -assertEquals(116, s.charCodeAt("string"));
|
| -assertEquals(116, s.charCodeAt(null));
|
| -assertEquals(116, s.charCodeAt(void 0));
|
| -assertEquals(116, s.charCodeAt(false));
|
| -assertEquals(101, s.charCodeAt(true));
|
| -assertEquals(116, s.charCodeAt(0));
|
| -assertEquals(116, s.charCodeAt(3));
|
| -assertEquals(116, s.charCodeAt(NaN));
|
| -assertTrue(isNaN(s.charCodeAt(-1)));
|
| -assertTrue(isNaN(s.charCodeAt(4)));
|
| +var slowIndex1 = { valueOf: function() { return 1; } };
|
| +var slowIndex2 = { toString: function() { return "2"; } };
|
| +var slowIndexOutOfRange = { valueOf: function() { return -1; } };
|
| +
|
| +function basicTest() {
|
| + assertEquals("t", s.charAt());
|
| + assertEquals("t", s.charAt("string"));
|
| + assertEquals("t", s.charAt(null));
|
| + assertEquals("t", s.charAt(void 0));
|
| + assertEquals("t", s.charAt(false));
|
| + assertEquals("e", s.charAt(true));
|
| + assertEquals("", s.charAt(-1));
|
| + assertEquals("", s.charAt(4));
|
| + assertEquals("", s.charAt(slowIndexOutOfRange));
|
| + assertEquals("t", s.charAt(0));
|
| + assertEquals("t", s.charAt(-0.0));
|
| + assertEquals("t", s.charAt(0.4));
|
| + assertEquals("e", s.charAt(slowIndex1));
|
| + assertEquals("s", s.charAt(slowIndex2));
|
| + assertEquals("t", s.charAt(3));
|
| + assertEquals("t", s.charAt(3.4));
|
| + assertEquals("t", s.charAt(NaN));
|
| +
|
| + assertEquals(116, s.charCodeAt());
|
| + assertEquals(116, s.charCodeAt("string"));
|
| + assertEquals(116, s.charCodeAt(null));
|
| + assertEquals(116, s.charCodeAt(void 0));
|
| + assertEquals(116, s.charCodeAt(false));
|
| + assertEquals(101, s.charCodeAt(true));
|
| + assertEquals(116, s.charCodeAt(0));
|
| + assertEquals(116, s.charCodeAt(-0.0));
|
| + assertEquals(116, s.charCodeAt(0.4));
|
| + assertEquals(101, s.charCodeAt(slowIndex1));
|
| + assertEquals(115, s.charCodeAt(slowIndex2));
|
| + assertEquals(116, s.charCodeAt(3));
|
| + assertEquals(116, s.charCodeAt(3.4));
|
| + assertEquals(116, s.charCodeAt(NaN));
|
| + assertTrue(isNaN(s.charCodeAt(-1)));
|
| + assertTrue(isNaN(s.charCodeAt(4)));
|
| + assertTrue(isNaN(s.charCodeAt(slowIndexOutOfRange)));
|
| +}
|
| +basicTest();
|
|
|
| // Make sure enough of the one-char string cache is filled.
|
| var alpha = ['@'];
|
| @@ -64,3 +83,162 @@ for (var i = 1; i < 128; i++) {
|
| assertEquals(alpha[i], alphaStr.charAt(i));
|
| assertEquals(String.fromCharCode(i), alphaStr.charAt(i));
|
| }
|
| +
|
| +// Test stealing String.prototype.{charAt,charCodeAt}.
|
| +var o = {
|
| + charAt: String.prototype.charAt,
|
| + charCodeAt: String.prototype.charCodeAt,
|
| + toString: function() { return "012"; },
|
| + valueOf: function() { return "should not be called"; }
|
| +};
|
| +
|
| +function stealTest() {
|
| + assertEquals("0", o.charAt(0));
|
| + assertEquals("1", o.charAt(1));
|
| + assertEquals("1", o.charAt(1.4));
|
| + assertEquals("1", o.charAt(slowIndex1));
|
| + assertEquals("2", o.charAt(2));
|
| + assertEquals("2", o.charAt(slowIndex2));
|
| + assertEquals(48, o.charCodeAt(0));
|
| + assertEquals(49, o.charCodeAt(1));
|
| + assertEquals(49, o.charCodeAt(1.4));
|
| + assertEquals(49, o.charCodeAt(slowIndex1));
|
| + assertEquals(50, o.charCodeAt(2));
|
| + assertEquals(50, o.charCodeAt(slowIndex2));
|
| + assertEquals("", o.charAt(-1));
|
| + assertEquals("", o.charAt(-1.4));
|
| + assertEquals("", o.charAt(10));
|
| + assertEquals("", o.charAt(slowIndexOutOfRange));
|
| + assertTrue(isNaN(o.charCodeAt(-1)));
|
| + assertTrue(isNaN(o.charCodeAt(-1.4)));
|
| + assertTrue(isNaN(o.charCodeAt(10)));
|
| + assertTrue(isNaN(o.charCodeAt(slowIndexOutOfRange)));
|
| +}
|
| +stealTest();
|
| +
|
| +// Test custom string IC-s.
|
| +for (var i = 0; i < 20; i++) {
|
| + basicTest();
|
| + stealTest();
|
| +}
|
| +
|
| +var badToString = function() { return []; };
|
| +
|
| +function testBadToString_charAt() {
|
| + var goodToString = o.toString;
|
| + var hasCaught = false;
|
| + var numCalls = 0;
|
| + var result;
|
| + try {
|
| + for (var i = 0; i < 20; i++) {
|
| + if (i == 10) o.toString = o.valueOf = badToString;
|
| + result = o.charAt(1);
|
| + numCalls++;
|
| + }
|
| + } catch (e) {
|
| + hasCaught = true;
|
| + } finally {
|
| + o.toString = goodToString;
|
| + }
|
| + assertTrue(hasCaught);
|
| + assertEquals("1", result);
|
| + assertEquals(10, numCalls);
|
| +}
|
| +testBadToString_charAt();
|
| +
|
| +function testBadToString_charCodeAt() {
|
| + var goodToString = o.toString;
|
| + var hasCaught = false;
|
| + var numCalls = 0;
|
| + var result;
|
| + try {
|
| + for (var i = 0; i < 20; i++) {
|
| + if (i == 10) o.toString = o.valueOf = badToString;
|
| + result = o.charCodeAt(1);
|
| + numCalls++;
|
| + }
|
| + } catch (e) {
|
| + hasCaught = true;
|
| + } finally {
|
| + o.toString = goodToString;
|
| + }
|
| + assertTrue(hasCaught);
|
| + assertEquals(49, result);
|
| + assertEquals(10, numCalls);
|
| +}
|
| +testBadToString_charCodeAt();
|
| +
|
| +var badIndex = {
|
| + toString: badToString,
|
| + valueOf: badToString
|
| +};
|
| +
|
| +function testBadIndex_charAt() {
|
| + var index = 1;
|
| + var hasCaught = false;
|
| + var numCalls = 0;
|
| + var result;
|
| + try {
|
| + for (var i = 0; i < 20; i++) {
|
| + if (i == 10) index = badIndex;
|
| + result = o.charAt(index);
|
| + numCalls++;
|
| + }
|
| + } catch (e) {
|
| + hasCaught = true;
|
| + }
|
| + assertTrue(hasCaught);
|
| + assertEquals("1", result);
|
| + assertEquals(10, numCalls);
|
| +}
|
| +testBadIndex_charAt();
|
| +
|
| +function testBadIndex_charCodeAt() {
|
| + var index = 1;
|
| + var hasCaught = false;
|
| + var numCalls = 0;
|
| + var result;
|
| + try {
|
| + for (var i = 0; i < 20; i++) {
|
| + if (i == 10) index = badIndex;
|
| + result = o.charCodeAt(index);
|
| + numCalls++;
|
| + }
|
| + } catch (e) {
|
| + hasCaught = true;
|
| + }
|
| + assertTrue(hasCaught);
|
| + assertEquals(49, result);
|
| + assertEquals(10, numCalls);
|
| +}
|
| +testBadIndex_charCodeAt();
|
| +
|
| +function testPrototypeChange_charAt() {
|
| + var result, oldResult;
|
| + for (var i = 0; i < 20; i++) {
|
| + if (i == 10) {
|
| + oldResult = result;
|
| + String.prototype.charAt = function() { return "%"; };
|
| + }
|
| + result = s.charAt(1);
|
| + }
|
| + assertEquals("%", result);
|
| + assertEquals("e", oldResult);
|
| + delete String.prototype.charAt; // Restore the default.
|
| +}
|
| +testPrototypeChange_charAt();
|
| +
|
| +function testPrototypeChange_charCodeAt() {
|
| + var result, oldResult;
|
| + for (var i = 0; i < 20; i++) {
|
| + if (i == 10) {
|
| + oldResult = result;
|
| + String.prototype.charCodeAt = function() { return 42; };
|
| + }
|
| + result = s.charCodeAt(1);
|
| + }
|
| + assertEquals(42, result);
|
| + assertEquals(101, oldResult);
|
| + delete String.prototype.charCodeAt; // Restore the default.
|
| +}
|
| +testPrototypeChange_charCodeAt();
|
|
|