| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
| * vim: set ts=8 sts=4 et sw=4 tw=99: |
| */ |
| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| #include "jsapi-tests/tests.h" |
| |
| BEGIN_TEST(testForwardSetProperty) |
| { |
| JS::RootedValue v1(cx); |
| EVAL("var foundValue; \n" |
| "var obj1 = { set prop(val) { foundValue = this; } }; \n" |
| "obj1;", |
| &v1); |
| |
| JS::RootedValue v2(cx); |
| EVAL("var obj2 = Object.create(obj1); \n" |
| "obj2;", |
| &v2); |
| |
| JS::RootedValue v3(cx); |
| EVAL("var obj3 = {}; \n" |
| "obj3;", |
| &v3); |
| |
| JS::RootedObject obj1(cx, &v1.toObject()); |
| JS::RootedObject obj2(cx, &v2.toObject()); |
| JS::RootedObject obj3(cx, &v3.toObject()); |
| |
| JS::RootedValue setval(cx, JS::Int32Value(42)); |
| |
| JS::RootedValue propkey(cx); |
| EVAL("'prop';", &propkey); |
| |
| JS::RootedId prop(cx); |
| CHECK(JS_ValueToId(cx, propkey, &prop)); |
| |
| EXEC("function assertEq(a, b, msg) \n" |
| "{ \n" |
| " if (!Object.is(a, b)) \n" |
| " throw new Error('Assertion failure: ' + msg); \n" |
| "}"); |
| |
| // Non-strict setter |
| |
| JS::ObjectOpResult result; |
| CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, v3, result)); |
| CHECK(result); |
| |
| EXEC("assertEq(foundValue, obj3, 'wrong receiver passed to setter');"); |
| |
| CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, setval, result)); |
| CHECK(result); |
| |
| EXEC("assertEq(typeof foundValue === 'object', true, \n" |
| " 'passing 42 as receiver to non-strict setter ' + \n" |
| " 'must box');"); |
| |
| EXEC("assertEq(foundValue instanceof Number, true, \n" |
| " 'passing 42 as receiver to non-strict setter ' + \n" |
| " 'must box to a Number');"); |
| |
| EXEC("assertEq(foundValue.valueOf(), 42, \n" |
| " 'passing 42 as receiver to non-strict setter ' + \n" |
| " 'must box to new Number(42)');"); |
| |
| // Strict setter |
| |
| EVAL("obj1 = { set prop(val) { 'use strict'; foundValue = this; } }; \n" |
| "obj1;", |
| &v1); |
| |
| CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, v3, result)); |
| CHECK(result); |
| |
| EXEC("assertEq(foundValue, obj3, 'wrong receiver passed to strict setter');"); |
| |
| CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, setval, result)); |
| CHECK(result); |
| |
| JS::RootedValue strictSetSupported(cx); |
| EVAL("var strictSetSupported = false; \n" |
| "Object.defineProperty(Object.prototype, \n" |
| " 'strictSetter', \n" |
| " { \n" |
| " set(v) { \n" |
| " 'use strict'; \n" |
| " strictSetSupported = \n" |
| " typeof this === 'number'; \n" |
| " } \n" |
| " }); \n" |
| "17..strictSetter = 42; \n" |
| "strictSetSupported;", |
| &strictSetSupported); |
| CHECK(strictSetSupported.isBoolean()); |
| |
| if (strictSetSupported.toBoolean()) { |
| // XXX Bug 603201 will fix this. |
| MOZ_ASSERT(false, |
| "remove the support-testing check when bug 603201 is fixt"); |
| EXEC("assertEq(foundValue, 42, \n" |
| " '42 passed as receiver to strict setter ' + \n" |
| " 'was mangled');"); |
| } |
| |
| return true; |
| } |
| END_TEST(testForwardSetProperty) |