1c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Copyright 2011 the V8 project authors. All rights reserved. 2c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Redistribution and use in source and binary forms, with or without 3c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// modification, are permitted provided that the following conditions are 4c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// met: 5c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// 6c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// * Redistributions of source code must retain the above copyright 7c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// notice, this list of conditions and the following disclaimer. 8c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// * Redistributions in binary form must reproduce the above 9c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// copyright notice, this list of conditions and the following 10c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// disclaimer in the documentation and/or other materials provided 11c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// with the distribution. 12c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// * Neither the name of Google Inc. nor the names of its 13c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// contributors may be used to endorse or promote products derived 14c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// from this software without specific prior written permission. 15c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// 16c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 28c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Array's toString should call the object's own join method, if one exists and 29c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// is callable. Otherwise, just use the original Object.toString function. 30c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 31c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar success = "[test success]"; 32c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar expectedThis; 33c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comfunction testJoin() { 34c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com assertEquals(0, arguments.length); 35c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com assertSame(expectedThis, this); 36c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return success; 37c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 38c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 39c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 40c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// On an Array object. 41c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 42c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Default case. 43c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar a1 = [1, 2, 3]; 44c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals(a1.join(), a1.toString()); 45c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 46c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Non-standard "join" function is called correctly. 47c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar a2 = [1, 2, 3]; 48c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.coma2.join = testJoin; 49c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comexpectedThis = a2; 50c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals(success, a2.toString()); 51c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 52c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Non-callable join function is ignored and Object.prototype.toString is 53c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// used instead. 54c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar a3 = [1, 2, 3]; 55c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.coma3.join = "not callable"; 56c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals("[object Array]", a3.toString()); 57c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 58c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Non-existing join function is treated same as non-callable. 59c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar a4 = [1, 2, 3]; 60c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.coma4.__proto__ = { toString: Array.prototype.toString }; 61c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// No join on Array. 62c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals("[object Array]", a4.toString()); 63c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 64c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 65c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// On a non-Array object. 66c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 67c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Default looks-like-an-array case. 68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar o1 = {length: 3, 0: 1, 1: 2, 2: 3, 69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com toString: Array.prototype.toString, 70c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com join: Array.prototype.join}; 71c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals(o1.join(), o1.toString()); 72c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 74c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Non-standard join is called correctly. 75c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Check that we don't read, e.g., length before calling join. 76c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar o2 = {toString : Array.prototype.toString, 77c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com join: testJoin, 78c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com get length() { assertUnreachable(); }, 79c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com get 0() { assertUnreachable(); }}; 80c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comexpectedThis = o2; 81c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals(success, o2.toString()); 82c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 83c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Non-standard join is called even if it looks like an array. 84c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar o3 = {length: 3, 0: 1, 1: 2, 2: 3, 85c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com toString: Array.prototype.toString, 86c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com join: testJoin}; 87c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comexpectedThis = o3; 88c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals(success, o3.toString()); 89c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 90c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Non-callable join works same as for Array. 91c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar o4 = {length: 3, 0: 1, 1: 2, 2: 3, 92c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com toString: Array.prototype.toString, 93c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com join: "not callable"}; 94c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals("[object Object]", o4.toString()); 95c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 96c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 97c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Non-existing join works same as for Array. 98c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar o5 = {length: 3, 0: 1, 1: 2, 2: 3, 99c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com toString: Array.prototype.toString 100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com /* no join */}; 101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals("[object Object]", o5.toString()); 102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Test that ToObject is called before getting "join", so the instance 105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// that "join" is read from is the same one passed as receiver later. 106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar called_before = false; 107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comexpectedThis = null; 108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comObject.defineProperty(Number.prototype, "join", {get: function() { 109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com assertFalse(called_before); 110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com called_before = true; 111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com expectedThis = this; 112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return testJoin; 113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }}); 114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comNumber.prototype.arrayToString = Array.prototype.toString; 115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals(success, (42).arrayToString()); 116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// ---------------------------------------------------------- 118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Testing Array.prototype.toLocaleString 119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Ensure that it never uses Array.prototype.toString for anything. 121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comArray.prototype.toString = function() { assertUnreachable(); }; 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Default case. 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar la1 = [1, [2, 3], 4]; 125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals("1,2,3,4", la1.toLocaleString()); 126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Used on a string (which looks like an array of characters). 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comString.prototype.toLocaleString = Array.prototype.toLocaleString; 129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals("1,2,3,4", "1234".toLocaleString()); 130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// If toLocaleString of element is not callable, throw a TypeError. 132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar la2 = [1, {toLocaleString: "not callable"}, 3]; 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertThrows(function() { la2.toLocaleString(); }, TypeError); 134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// If toLocaleString of element is callable, call it. 136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar la3 = [1, {toLocaleString: function() { return "XX";}}, 3]; 137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals("1,XX,3", la3.toLocaleString()); 138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Omitted elements, as well as undefined and null, become empty string. 140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvar la4 = [1, null, 3, undefined, 5,, 7]; 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comassertEquals("1,,3,,5,,7", la4.toLocaleString()); 142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// ToObject is called first and the same object is being used for the 145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// rest of the operations. 146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comObject.defineProperty(Number.prototype, "length", { 147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com get: function() { 148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com exptectedThis = this; 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return 3; 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }}); 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comfor (var i = 0; i < 3; i++) { 152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object.defineProperty(Number.prototype, i, { 153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com get: function() { 154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com assertEquals(expectedThis, this); 155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return +this; 156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }}); 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comNumber.prototype.arrayToLocaleString = Array.prototype.toLocaleString; 159f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgassertEquals("42,42,42", (42).arrayToLocaleString()); 160