1// Copyright 2013 the V8 project authors. All rights reserved. 2// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions 6// are met: 7// 1. Redistributions of source code must retain the above copyright 8// notice, this list of conditions and the following disclaimer. 9// 2. Redistributions in binary form must reproduce the above copyright 10// notice, this list of conditions and the following disclaimer in the 11// documentation and/or other materials provided with the distribution. 12// 13// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 24description( 25"This performs a number of different tests on JavaScript getters and setters." 26); 27 28debug("the get set object declaration syntax"); 29var o1 = { 'a':7, get b() { return this.a + 1 }, set b(x) { this.a = x } } 30shouldBe("o1.b", "8"); 31o1.b = 10; 32shouldBe("o1.b", "11"); 33 34debug("__defineGetter__ and __defineSetter__"); 35var o2 = new Object() 36o2.a = 7; 37o2.__defineGetter__('b', function getB() { return this.a + 1} ) 38o2.__defineSetter__('b', function setB(x) { this.a = x}) 39shouldBe("o2.b", "8"); 40o2.b = 10; 41shouldBe("o2.b", "11"); 42 43debug("Setting a value without having a setter"); 44var o3 = { get x() { return 42; } } 45shouldBe("o3.x = 10; o3.x", "42"); 46 47debug("Getting a value without having a getter"); 48var o4 = { set x(y) { }} 49shouldBeUndefined("o4.x"); 50 51debug("__lookupGetter__ and __lookupSetter__"); 52var o4 = new Object() 53function getB() { return this.a } 54function setB(x) { this.a = x } 55o4.__defineGetter__('b', getB) 56o4.__defineSetter__('b', setB) 57 58shouldBe("o4.__lookupGetter__('b')", "getB"); 59shouldBe("o4.__lookupSetter__('b')", "setB"); 60 61debug("__defineGetter__ and __defineSetter__ with various invalid arguments"); 62var numExceptions = 0; 63var o5 = new Object(); 64shouldThrow("o5.__defineSetter__('a', null)"); 65shouldThrow("o5.__defineSetter__('a', o5)"); 66shouldThrow("o5.__defineGetter__('a', null)"); 67shouldThrow("o5.__defineGetter__('a', o5)"); 68 69debug("setters and getters with exceptions"); 70var o6 = { get x() { throw 'Exception in get'}, set x(f) { throw 'Exception in set'}} 71var x = 0; 72var numExceptions = 0; 73shouldThrow("x = o6.x"); 74shouldBe("x", "0"); 75shouldThrow("o6.x = 42"); 76 77debug("Defining a setter should also define a getter for the same property which returns undefined. Thus, a getter defined on the prototype should not be called."); 78o7 = { 'a':7, set x(b) { this.a = b; }} 79o7.prototype = { get x() { return 42; }} 80shouldBeUndefined("o7.x") 81 82debug("If an object has a property and its prototype has a setter function for that property, then setting the property should set the property directly and not call the setter function."); 83var o8 = new Object() 84o8.numSets = 0; 85o8.x = 10; 86o8.__proto__.__defineSetter__('x', function() { this.numSets++; }) 87o8.x = 20; 88shouldBe("o8.numSets", "0"); 89 90({getter:"foo", b:"bar"}); 91testObj=({get getter(){return 'getter was called.'}, b: 'bar'}) 92shouldBe("typeof testObj.getter", "'string'"); 93 94debug("the get set with string property name"); 95var o9 = { 'a':7, get 'b'() { return this.a + 1 }, set 'b'(x) { this.a = x } } 96shouldBe("o9.b", "8"); 97o9.b = 10; 98shouldBe("o9.b", "11"); 99 100debug("the get set with numeric property name"); 101var o10 = { 'a':7, get 42() { return this.a + 1 }, set 42(x) { this.a = x } } 102shouldBe("o10[42]", "8"); 103o10[42] = 10; 104shouldBe("o10[42]", "11"); 105