1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 
8 #include "jsapi-tests/tests.h"
9 
10 using namespace JS;
11 
BEGIN_TEST(testForwardSetProperty)12 BEGIN_TEST(testForwardSetProperty) {
13   RootedValue v1(cx);
14   EVAL(
15       "var foundValue; \n"
16       "var obj1 = { set prop(val) { foundValue = this; } }; \n"
17       "obj1;",
18       &v1);
19 
20   RootedValue v2(cx);
21   EVAL(
22       "var obj2 = Object.create(obj1); \n"
23       "obj2;",
24       &v2);
25 
26   RootedValue v3(cx);
27   EVAL(
28       "var obj3 = {}; \n"
29       "obj3;",
30       &v3);
31 
32   RootedObject obj1(cx, &v1.toObject());
33   RootedObject obj2(cx, &v2.toObject());
34   RootedObject obj3(cx, &v3.toObject());
35 
36   RootedValue setval(cx, Int32Value(42));
37 
38   RootedValue propkey(cx);
39   EVAL("'prop';", &propkey);
40 
41   RootedId prop(cx);
42   CHECK(JS_ValueToId(cx, propkey, &prop));
43 
44   EXEC(
45       "function assertEq(a, b, msg) \n"
46       "{ \n"
47       "  if (!Object.is(a, b)) \n"
48       "    throw new Error('Assertion failure: ' + msg); \n"
49       "}");
50 
51   // Non-strict setter
52 
53   JS::ObjectOpResult result;
54   CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, v3, result));
55   CHECK(result);
56 
57   EXEC("assertEq(foundValue, obj3, 'wrong receiver passed to setter');");
58 
59   CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, setval, result));
60   CHECK(result);
61 
62   EXEC(
63       "assertEq(typeof foundValue === 'object', true, \n"
64       "         'passing 42 as receiver to non-strict setter ' + \n"
65       "         'must box');");
66 
67   EXEC(
68       "assertEq(foundValue instanceof Number, true, \n"
69       "         'passing 42 as receiver to non-strict setter ' + \n"
70       "         'must box to a Number');");
71 
72   EXEC(
73       "assertEq(foundValue.valueOf(), 42, \n"
74       "         'passing 42 as receiver to non-strict setter ' + \n"
75       "         'must box to new Number(42)');");
76 
77   // Strict setter
78 
79   RootedValue v4(cx);
80   EVAL("({ set prop(val) { 'use strict'; foundValue = this; } })", &v4);
81   RootedObject obj4(cx, &v4.toObject());
82 
83   CHECK(JS_ForwardSetPropertyTo(cx, obj4, prop, setval, v3, result));
84   CHECK(result);
85 
86   EXEC("assertEq(foundValue, obj3, 'wrong receiver passed to strict setter');");
87 
88   CHECK(JS_ForwardSetPropertyTo(cx, obj4, prop, setval, setval, result));
89   CHECK(result);
90 
91   EXEC(
92       "assertEq(foundValue, 42, \n"
93       "         '42 passed as receiver to strict setter was mangled');");
94 
95   return true;
96 }
97 END_TEST(testForwardSetProperty)
98