js/src/tests/ecma_6/Proxy/proxy-isExtensible.js

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:20835ff7b31f
1 // Test ES6 Proxy trap compliance for Object.isExtensible() on exotic proxy
2 // objects.
3 var unsealed = {};
4 var sealed = Object.seal({});
5 var handler = {};
6
7 assertEq(Object.isExtensible(unsealed), true);
8 assertEq(Object.isExtensible(sealed), false);
9
10 var targetSealed = new Proxy(sealed, handler);
11 var targetUnsealed = new Proxy(unsealed, handler);
12
13 var handlerCalled = false;
14
15 // without traps, forward to the target
16 // First, make sure we get the obvious answer on a non-exotic target.
17 assertEq(Object.isExtensible(targetSealed), false, "Must forward to target without hook.");
18 assertEq(Object.isExtensible(targetUnsealed), true, "Must forward to target without hook.");
19
20 // Now, keep everyone honest. What if the target itself is a proxy?
21 function ensureCalled() { handlerCalled = true; return true; }
22 var proxyTarget = new Proxy({}, { isExtensible : ensureCalled });
23 assertEq(Object.isExtensible(new Proxy(proxyTarget, {})), true, "Must forward to target without hook.");
24 assertEq(handlerCalled, true, "Must forward to target without hook.");
25
26 // with traps, makes sure that the handler is called, and that we throw if the
27 // trap disagrees with the target
28 function testExtensible(obj, shouldThrow, expectedResult)
29 {
30 handlerCalled = false;
31 if (shouldThrow)
32 assertThrowsInstanceOf(function () { Object.isExtensible(obj); },
33 TypeError, "Must throw if handler and target disagree.");
34 else
35 assertEq(Object.isExtensible(obj), expectedResult, "Must return the correct value.");
36 assertEq(handlerCalled, true, "Must call handler trap if present");
37 }
38
39 // What if the trap says it's necessarily sealed?
40 function fakeSealed() { handlerCalled = true; return false; }
41 handler.isExtensible = fakeSealed;
42 testExtensible(targetSealed, false, false);
43 testExtensible(targetUnsealed, true);
44
45 // What if the trap says it's never sealed?
46 function fakeUnsealed() { handlerCalled = true; return true; }
47 handler.isExtensible = fakeUnsealed;
48 testExtensible(targetSealed, true);
49 testExtensible(targetUnsealed, false, true);
50
51 // make sure we are able to prevent further extensions mid-flight and throw if the
52 // hook tries to lie.
53 function makeSealedTruth(target) { handlerCalled = true; Object.preventExtensions(target); return false; }
54 function makeSealedLie(target) { handlerCalled = true; Object.preventExtensions(target); return true; }
55 handler.isExtensible = makeSealedTruth;
56 testExtensible(new Proxy({}, handler), false, false);
57 handler.isExtensible = makeSealedLie;
58 testExtensible(new Proxy({}, handler), true);
59
60 // What if the trap doesn't directly return a boolean?
61 function falseyNonBool() { handlerCalled = true; return undefined; }
62 handler.isExtensible = falseyNonBool;
63 testExtensible(targetSealed, false, false);
64 testExtensible(targetUnsealed, true);
65
66 function truthyNonBool() { handlerCalled = true; return {}; }
67 handler.isExtensible = truthyNonBool;
68 testExtensible(targetSealed, true);
69 testExtensible(targetUnsealed, false, true);
70
71 // What if the trap throws?
72 function ExtensibleError() { }
73 ExtensibleError.prototype = new Error();
74 ExtensibleError.prototype.constructor = ExtensibleError;
75 function throwFromTrap() { throw new ExtensibleError(); }
76 handler.isExtensible = throwFromTrap;
77
78 // exercise some other code paths and make sure that they invoke the trap and
79 // can handle the ensuing error.
80 assertThrowsInstanceOf(function () { Object.isExtensible(targetSealed); },
81 ExtensibleError, "Must throw if the trap does.");
82 assertThrowsInstanceOf(function () { Object.isFrozen(targetSealed); },
83 ExtensibleError, "Must throw if the trap does.");
84 assertThrowsInstanceOf(function () { Object.isSealed(targetSealed); },
85 ExtensibleError, "Must throw if the trap does.");
86
87
88 // What if the trap likes to re-ask old questions?
89 function recurse() { return Object.isExtensible(targetSealed); }
90 handler.isExtensible = recurse;
91 assertThrowsInstanceOf(function () { Object.isExtensible(targetSealed); },
92 InternalError, "Should allow and detect infinite recurison.");
93
94 reportCompare(0, 0, "OK");

mercurial