Home | History | Annotate | Download | only in harmony
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Flags: --harmony-proxies --harmony-reflect
      6 
      7 (function testNonConstructable() {
      8   var proxy = new Proxy({},{});
      9   assertThrows(function(){ new proxy() }, TypeError);
     10 
     11   var proxy2 = new Proxy(proxy, {});
     12   assertThrows(function(){ proxy2() }, TypeError);
     13 })();
     14 
     15 (function testFailingConstructRevoked() {
     16   var pair = Proxy.revocable(Array, {});
     17   var instance = new pair.proxy();
     18   pair.revoke();
     19   assertThrows(function(){ new pair.proxy() }, TypeError);
     20 })();
     21 
     22 (function testFailingGetTrap() {
     23   var handler = {
     24     get() {
     25       throw TypeError();
     26     }
     27   }
     28   var proxy = new Proxy({},{});
     29   var proxy2 = new Proxy({}, proxy);
     30   assertThrows(function(){ new proxy2() }, TypeError);
     31 })();
     32 
     33 (function testConstructFallback() {
     34   var called = false;
     35   function Target() {
     36     called = true;
     37     this.property1 = 'value1';
     38   };
     39   Target.prototype = {};
     40   var proxy = new Proxy(Target, {});
     41 
     42   assertFalse(called);
     43   var instance = new proxy();
     44   assertTrue(called);
     45   assertEquals('value1', instance.property1);
     46   assertSame(Target.prototype, Reflect.getPrototypeOf(instance));
     47 
     48   var proxy2 = new Proxy(proxy, {});
     49   called = false;
     50   var instance2 = new proxy2();
     51   assertTrue(called);
     52   assertEquals('value1', instance2.property1);
     53   assertSame(Target.prototype, Reflect.getPrototypeOf(instance));
     54 })();
     55 
     56 (function testConstructTrapDirectReturn() {
     57   function Target(a, b) {
     58       this.sum = a + b;
     59   };
     60   var handler = {
     61       construct(t, c, args) {
     62           return { sum: 42 };
     63       }
     64   };
     65   var proxy = new Proxy(Target, handler);
     66   assertEquals(42, (new proxy(1, 2)).sum);
     67 })();
     68 
     69 (function testConstructTrap() {
     70   function Target(arg1, arg2) {
     71     this.arg1 = arg1;
     72     this.arg2 = arg2;
     73   }
     74   var seen_target, seen_arguments, seen_new_target;
     75   var handler = {
     76     construct(target, args, new_target) {
     77       seen_target = target;
     78       seen_arguments = args;
     79       seen_new_target = new_target;
     80       return Reflect.construct(target, args, new_target);
     81     }
     82   }
     83   var proxy = new Proxy(Target, handler);
     84   var instance = new proxy('a', 'b');
     85   assertEquals(Target, seen_target);
     86   assertEquals(['a','b'], seen_arguments);
     87   assertEquals(proxy, seen_new_target);
     88   assertEquals('a', instance.arg1);
     89   assertEquals('b', instance.arg2);
     90 
     91   var instance2 = Reflect.construct(proxy, ['a1', 'b1'], Array);
     92   assertEquals(Target, seen_target);
     93   assertEquals(['a1', 'b1'], seen_arguments);
     94   assertEquals(Array, seen_new_target);
     95   assertEquals('a1', instance2.arg1);
     96   assertEquals('b1', instance2.arg2);
     97 })();
     98 
     99 (function testConstructCrossRealm() {
    100   var realm1 = Realm.create();
    101   var handler = {
    102     construct(target, args, new_target) {
    103       return args;
    104     }
    105   };
    106   var OtherProxy = Realm.eval(realm1, "Proxy");
    107   var otherArrayPrototype = Realm.eval(realm1, 'Array.prototype');
    108 
    109   // Proxy and handler are from this realm.
    110   var proxy = new Proxy(Array, handler);
    111   var result = new proxy();
    112   assertSame(Array.prototype, Reflect.getPrototypeOf(result));
    113 
    114   // Proxy is from this realm, handler is from realm1.
    115   var otherProxy = new OtherProxy(Array, handler);
    116   var otherResult = new otherProxy();
    117   assertSame(Array.prototype, Reflect.getPrototypeOf(otherResult));
    118 
    119   // Proxy and handler are from realm1.
    120   var otherProxy2 = Realm.eval(realm1, 'new Proxy('+
    121         'Array, { construct(target, args, new_target) { return args }} )');
    122   var otherResult2 = new otherProxy2();
    123   assertSame(Array.prototype, Reflect.getPrototypeOf(otherResult2));
    124 })();
    125 
    126 (function testReflectConstructCrossReal() {
    127   var realm1 = Realm.create();
    128   var realm2 = Realm.create();
    129   var realm3 = Realm.create();
    130   var realm4 = Realm.create();
    131 
    132   var argsRealm1 = Realm.eval(realm1, '[]');
    133   var ProxyRealm2 = Realm.eval(realm2, 'Proxy');
    134   var constructorRealm3 = Realm.eval(realm3, '(function(){})');
    135   var handlerRealm4 = Realm.eval(realm4,
    136       '({ construct(target, args, new_target) {return args} })');
    137 
    138   var proxy = new ProxyRealm2(constructorRealm3, handlerRealm4);
    139 
    140   // Check that the arguments array returned by handlerRealm4 is created in the
    141   // realm of the Reflect.construct function.
    142   var result = Reflect.construct(proxy, argsRealm1);
    143   assertSame(Array.prototype, Reflect.getPrototypeOf(result));
    144 
    145   var ReflectConstructRealm1 = Realm.eval(realm1, 'Reflect.construct');
    146   var result2 = ReflectConstructRealm1(proxy, argsRealm1);
    147   assertSame(Realm.eval(realm1, 'Array.prototype'),
    148     Reflect.getPrototypeOf(result2));
    149 
    150   var result3 = ReflectConstructRealm1(proxy, []);
    151   assertSame(Realm.eval(realm1, 'Array.prototype'),
    152     Reflect.getPrototypeOf(result3));
    153 
    154   var ReflectConstructRealm2 = Realm.eval(realm2, 'Reflect.construct');
    155   var result4 = ReflectConstructRealm2(proxy, argsRealm1);
    156   assertSame(Realm.eval(realm2, 'Array.prototype'),
    157     Reflect.getPrototypeOf(result4));
    158 })();
    159