| // Copyright 2010 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. |
| |
| // Test the ToPrimitive internal function used by ToNumber/ToString. |
| // Does it [[Get]] and [[Call]] the object's toString and valueOf properties |
| // correctly. Specifically, does it call [[Get]] only once per property. |
| |
| var o1 = { toString: function() { return 42; }, |
| valueOf: function() { return "37"; } }; |
| var n1 = Number(o1); |
| var s1 = String(o1); |
| assertTrue(typeof n1 == "number"); |
| assertTrue(typeof s1 == "string"); |
| |
| var trace = []; |
| var valueOfValue = 42; |
| var toStringValue = "foo"; |
| function traceValueOf () { |
| trace.push("vo"); |
| return valueOfValue; |
| }; |
| function traceToString() { |
| trace.push("ts"); |
| return toStringValue; |
| }; |
| var valueOfFunc = traceValueOf; |
| var toStringFunc = traceToString; |
| |
| var ot = { get toString() { trace.push("gts"); |
| return toStringFunc; }, |
| get valueOf() { trace.push("gvo"); |
| return valueOfFunc; } |
| }; |
| |
| var nt = Number(ot); |
| assertEquals(42, nt); |
| assertEquals(["gvo","vo"], trace); |
| |
| trace = []; |
| var st = String(ot); |
| assertEquals("foo", st); |
| assertEquals(["gts","ts"], trace); |
| |
| trace = []; |
| valueOfValue = ["not primitive"]; |
| var nt = Number(ot); |
| assertEquals(Number("foo"), nt); |
| assertEquals(["gvo", "vo", "gts", "ts"], trace); |
| |
| trace = []; |
| valueOfValue = 42; |
| toStringValue = ["not primitive"]; |
| var st = String(ot); |
| assertEquals(String(42), st); |
| assertEquals(["gts", "ts", "gvo", "vo"], trace); |
| |
| trace = []; |
| valueOfValue = ["not primitive"]; |
| assertThrows("Number(ot)", TypeError); |
| assertEquals(["gvo", "vo", "gts", "ts"], trace); |
| |
| |
| toStringFunc = "not callable"; |
| trace = []; |
| valueOfValue = 42; |
| var st = String(ot); |
| assertEquals(String(42), st); |
| assertEquals(["gts", "gvo", "vo"], trace); |
| |
| valueOfFunc = "not callable"; |
| trace = []; |
| assertThrows("String(ot)", TypeError); |
| assertEquals(["gts", "gvo"], trace); |
| |
| toStringFunc = traceToString; |
| toStringValue = "87"; |
| trace = []; |
| var nt = Number(ot); |
| assertEquals(87, nt); |
| assertEquals(["gvo", "gts", "ts"], trace); |
| |
| assertThrows('Number(Symbol())', TypeError); |