1 // Copyright 2008 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 var s = 'abcdefghijklmn'; 29 assertEquals(s, s.substr()); 30 assertEquals(s, s.substr(0)); 31 assertEquals(s, s.substr('0')); 32 assertEquals(s, s.substr(void 0)); 33 assertEquals(s, s.substr(null)); 34 assertEquals(s, s.substr(false)); 35 assertEquals(s, s.substr(0.9)); 36 assertEquals(s, s.substr({ valueOf: function() { return 0; } })); 37 assertEquals(s, s.substr({ toString: function() { return '0'; } })); 38 39 var s1 = s.substring(1); 40 assertEquals(s1, s.substr(1)); 41 assertEquals(s1, s.substr('1')); 42 assertEquals(s1, s.substr(true)); 43 assertEquals(s1, s.substr(1.1)); 44 assertEquals(s1, s.substr({ valueOf: function() { return 1; } })); 45 assertEquals(s1, s.substr({ toString: function() { return '1'; } })); 46 47 48 assertEquals(s.substring(s.length - 1), s.substr(-1)); 49 assertEquals(s.substring(s.length - 1), s.substr(-1.2)); 50 assertEquals(s.substring(s.length - 1), s.substr(-1.7)); 51 assertEquals(s.substring(s.length - 2), s.substr(-2)); 52 assertEquals(s.substring(s.length - 2), s.substr(-2.3)); 53 assertEquals(s.substring(s.length - 2, s.length - 1), s.substr(-2, 1)); 54 assertEquals(s, s.substr(-100)); 55 assertEquals('abc', s.substr(-100, 3)); 56 assertEquals(s1, s.substr(-s.length + 1)); 57 58 // assertEquals('', s.substr(0, void 0)); // smjs and rhino 59 assertEquals('abcdefghijklmn', s.substr(0, void 0)); // kjs and v8 60 assertEquals('', s.substr(0, null)); 61 assertEquals(s, s.substr(0, String(s.length))); 62 assertEquals('a', s.substr(0, true)); 63 64 65 // Test substrings of different lengths and alignments. 66 // First ASCII. 67 var x = "ASCII"; 68 for (var i = 0; i < 25; i++) { 69 x += (i >> 4).toString(16) + (i & 0x0f).toString(16); 70 } 71 /x/.exec(x); // Try to force a flatten. 72 for (var i = 5; i < 25; i++) { 73 for (var j = 0; j < 25; j++) { 74 var z = x.substring(i, i+j); 75 var w = Math.random() * 42; // Allocate something new in new-space. 76 assertEquals(j, z.length); 77 for (var k = 0; k < j; k++) { 78 assertEquals(x.charAt(i+k), z.charAt(k)); 79 } 80 } 81 } 82 83 84 // Then two-byte strings. 85 x = "UC16\u2028"; // Non-ascii char forces two-byte string. 86 for (var i = 0; i < 25; i++) { 87 x += (i >> 4).toString(16) + (i & 0x0f).toString(16); 88 } 89 /x/.exec(x); // Try to force a flatten. 90 for (var i = 5; i < 25; i++) { 91 for (var j = 0; j < 25; j++) { 92 var z = x.substring(i, i + j); 93 var w = Math.random() * 42; // Allocate something new in new-space. 94 assertEquals(j, z.length); 95 for (var k = 0; k < j; k++) { 96 assertEquals(x.charAt(i+k), z.charAt(k)); 97 } 98 } 99 } 100 101 102 // Keep creating strings to to force allocation failure on substring creation. 103 var x = "0123456789ABCDEF"; 104 x += x; // 2^5 105 x += x; 106 x += x; 107 x += x; 108 x += x; 109 x += x; // 2^10 110 x += x; 111 x += x; 112 var xl = x.length; 113 var cache = []; 114 for (var i = 0; i < 10000; i++) { 115 var z = x.substring(i % xl); 116 assertEquals(xl - (i % xl), z.length); 117 cache.push(z); 118 } 119 120 121 // Same with two-byte strings 122 var x = "\u2028123456789ABCDEF"; 123 x += x; // 2^5 124 x += x; 125 x += x; 126 x += x; 127 x += x; 128 x += x; // 2^10 129 x += x; 130 x += x; 131 var xl = x.length; 132 var cache = []; 133 for (var i = 0; i < 10000; i++) { 134 var z = x.substring(i % xl); 135 assertEquals(xl - (i % xl), z.length); 136 cache.push(z); 137 } 138 139 // Substring of substring. 140 var cache = []; 141 var last = x; 142 var offset = 0; 143 for (var i = 0; i < 64; i++) { 144 var z = last.substring(i); 145 last = z; 146 cache.push(z); 147 offset += i; 148 } 149 for (var i = 63; i >= 0; i--) { 150 var z = cache.pop(); 151 assertTrue(/\u2028123456789ABCDEF/.test(z)); 152 assertEquals(xl - offset, z.length); 153 offset -= i; 154 } 155