mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-31 03:34:08 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			256 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			256 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright 2008 the V8 project authors. All rights reserved.
 | |
| // Redistribution and use in source and binary forms, with or without
 | |
| // modification, are permitted provided that the following conditions are
 | |
| // met:
 | |
| //
 | |
| //     * Redistributions of source code must retain the above copyright
 | |
| //       notice, this list of conditions and the following disclaimer.
 | |
| //     * Redistributions in binary form must reproduce the above
 | |
| //       copyright notice, this list of conditions and the following
 | |
| //       disclaimer in the documentation and/or other materials provided
 | |
| //       with the distribution.
 | |
| //     * Neither the name of Google Inc. nor the names of its
 | |
| //       contributors may be used to endorse or promote products derived
 | |
| //       from this software without specific prior written permission.
 | |
| //
 | |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| 
 | |
| var s = "test";
 | |
| 
 | |
| function getTwoByteString() { return "\u1234t"; }
 | |
| function getCons() { return "testtesttesttest" + getTwoByteString() }
 | |
| 
 | |
| var slowIndex1 = { valueOf: function() { return 1; } };
 | |
| var slowIndex2 = { toString: function() { return "2"; } };
 | |
| var slowIndexOutOfRange = { valueOf: function() { return -1; } };
 | |
| 
 | |
| function basicTest(s, len) {
 | |
|   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(len));
 | |
|   assertEquals("", s().charAt(slowIndexOutOfRange));
 | |
|   assertEquals("", s().charAt(1/0));
 | |
|   assertEquals("", s().charAt(-1/0));
 | |
|   assertEquals("t", s().charAt(0));
 | |
|   assertEquals("t", s().charAt(-0.0));
 | |
|   assertEquals("t", s().charAt(-0.1));
 | |
|   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.1));
 | |
|   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(len)));
 | |
|   assertTrue(isNaN(s().charCodeAt(slowIndexOutOfRange)));
 | |
|   assertTrue(isNaN(s().charCodeAt(1/0)));
 | |
|   assertTrue(isNaN(s().charCodeAt(-1/0)));
 | |
| }
 | |
| basicTest(function() { return s; }, s.length);
 | |
| basicTest(getCons, getCons().length);
 | |
| 
 | |
| // Make sure enough of the one-char string cache is filled.
 | |
| var alpha = ['@'];
 | |
| for (var i = 1; i < 128; i++) {
 | |
|   var c = String.fromCharCode(i);
 | |
|   alpha[i] = c.charAt(0);
 | |
| }
 | |
| var alphaStr = alpha.join("");
 | |
| 
 | |
| // Now test chars.
 | |
| 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(function() { return s; }, s.length);
 | |
|   basicTest(getCons, getCons().length);
 | |
|   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();
 |