tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Object-toSource.js (10635B)


      1 // |reftest| skip-if(!Object.prototype.toSource)
      2 
      3 var BUGNUMBER = 1317400;
      4 var summary = "Function string representation in Object.prototype.toSource";
      5 
      6 print(BUGNUMBER + ": " + summary);
      7 
      8 // Methods.
      9 
     10 assertEq(({ foo(){} }).toSource(),
     11         "({foo(){}})");
     12 assertEq(({ *foo(){} }).toSource(),
     13         "({*foo(){}})");
     14 assertEq(({ async foo(){} }).toSource(),
     15         "({async foo(){}})");
     16 
     17 assertEq(({ 1(){} }).toSource(),
     18         "({1(){}})");
     19 
     20 // Methods with more spacing.
     21 // Spacing is kept.
     22 
     23 assertEq(({ foo (){} }).toSource(),
     24         "({foo (){}})");
     25 assertEq(({ foo () {} }).toSource(),
     26         "({foo () {}})");
     27 
     28 // Methods with computed name.
     29 // Method syntax is composed.
     30 
     31 let name = "foo";
     32 assertEq(({ [name](){} }).toSource(),
     33         "({foo(){}})");
     34 assertEq(({ *[name](){} }).toSource(),
     35         "({*foo(){}})");
     36 assertEq(({ async [name](){} }).toSource(),
     37         "({async foo(){}})");
     38 
     39 assertEq(({ [ Symbol.iterator ](){} }).toSource(),
     40         "({[Symbol.iterator](){}})");
     41 
     42 // Accessors.
     43 
     44 assertEq(({ get foo(){} }).toSource(),
     45         "({get foo(){}})");
     46 assertEq(({ set foo(v){} }).toSource(),
     47         "({set foo(v){}})");
     48 
     49 // Accessors with computed name.
     50 // Method syntax is composed.
     51 
     52 assertEq(({ get [name](){} }).toSource(),
     53         "({get foo(){}})");
     54 assertEq(({ set [name](v){} }).toSource(),
     55         "({set foo(v){}})");
     56 
     57 assertEq(({ get [ Symbol.iterator ](){} }).toSource(),
     58         "({get [Symbol.iterator](){}})");
     59 assertEq(({ set [ Symbol.iterator ](v){} }).toSource(),
     60         "({set [Symbol.iterator](v){}})");
     61 
     62 // Getter and setter with same name.
     63 // Getter always comes before setter.
     64 
     65 assertEq(({ get foo(){}, set foo(v){} }).toSource(),
     66         "({get foo(){}, set foo(v){}})");
     67 assertEq(({ set foo(v){}, get foo(){} }).toSource(),
     68         "({get foo(){}, set foo(v){}})");
     69 
     70 // Normal properties.
     71 
     72 assertEq(({ foo: function(){} }).toSource(),
     73         "({foo:(function(){})})");
     74 assertEq(({ foo: function bar(){} }).toSource(),
     75         "({foo:(function bar(){})})");
     76 assertEq(({ foo: function*(){} }).toSource(),
     77         "({foo:(function*(){})})");
     78 assertEq(({ foo: async function(){} }).toSource(),
     79         "({foo:(async function(){})})");
     80 
     81 // Normal properties with computed name.
     82 
     83 assertEq(({ [ Symbol.iterator ]: function(){} }).toSource(),
     84         "({[Symbol.iterator]:(function(){})})");
     85 
     86 // Dynamically defined properties with function expression.
     87 // Never become a method syntax.
     88 
     89 let obj = {};
     90 obj.foo = function() {};
     91 assertEq(obj.toSource(),
     92         "({foo:(function() {})})");
     93 
     94 obj = {};
     95 Object.defineProperty(obj, "foo", {value: function() {}});
     96 assertEq(obj.toSource(),
     97         "({})");
     98 
     99 obj = {};
    100 Object.defineProperty(obj, "foo", {value: function() {}, enumerable: true});
    101 assertEq(obj.toSource(),
    102         "({foo:(function() {})})");
    103 
    104 obj = {};
    105 Object.defineProperty(obj, "foo", {value: function bar() {}, enumerable: true});
    106 assertEq(obj.toSource(),
    107         "({foo:(function bar() {})})");
    108 
    109 obj = {};
    110 Object.defineProperty(obj, Symbol.iterator, {value: function() {}, enumerable: true});
    111 assertEq(obj.toSource(),
    112         "({[Symbol.iterator]:(function() {})})");
    113 
    114 // Dynamically defined property with other object's method.
    115 // Method syntax is composed.
    116 
    117 let method = ({foo() {}}).foo;
    118 
    119 obj = {};
    120 Object.defineProperty(obj, "foo", {value: method, enumerable: true});
    121 assertEq(obj.toSource(),
    122         "({foo() {}})");
    123 
    124 obj = {};
    125 Object.defineProperty(obj, "bar", {value: method, enumerable: true});
    126 assertEq(obj.toSource(),
    127         "({bar() {}})");
    128 
    129 method = ({*foo() {}}).foo;
    130 
    131 obj = {};
    132 Object.defineProperty(obj, "bar", {value: method, enumerable: true});
    133 assertEq(obj.toSource(),
    134         "({*bar() {}})");
    135 
    136 method = ({async foo() {}}).foo;
    137 
    138 obj = {};
    139 Object.defineProperty(obj, "bar", {value: method, enumerable: true});
    140 assertEq(obj.toSource(),
    141         "({async bar() {}})");
    142 
    143 // Dynamically defined accessors.
    144 // Accessor syntax is composed.
    145 
    146 obj = {};
    147 Object.defineProperty(obj, "foo", {get: function() {}, enumerable: true});
    148 assertEq(obj.toSource(),
    149         "({get foo() {}})");
    150 
    151 obj = {};
    152 Object.defineProperty(obj, "foo", {set: function() {}, enumerable: true});
    153 assertEq(obj.toSource(),
    154         "({set foo() {}})");
    155 
    156 obj = {};
    157 Object.defineProperty(obj, Symbol.iterator, {get: function() {}, enumerable: true});
    158 assertEq(obj.toSource(),
    159         "({get [Symbol.iterator]() {}})");
    160 
    161 obj = {};
    162 Object.defineProperty(obj, Symbol.iterator, {set: function() {}, enumerable: true});
    163 assertEq(obj.toSource(),
    164         "({set [Symbol.iterator]() {}})");
    165 
    166 // Dynamically defined accessors with other object's accessors.
    167 // Accessor syntax is composed.
    168 
    169 let accessor = Object.getOwnPropertyDescriptor({ get foo() {} }, "foo").get;
    170 obj = {};
    171 Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
    172 assertEq(obj.toSource(),
    173         "({get foo() {}})");
    174 
    175 accessor = Object.getOwnPropertyDescriptor({ get bar() {} }, "bar").get;
    176 obj = {};
    177 Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
    178 assertEq(obj.toSource(),
    179         "({get foo() {}})");
    180 
    181 accessor = Object.getOwnPropertyDescriptor({ set foo(v) {} }, "foo").set;
    182 obj = {};
    183 Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
    184 assertEq(obj.toSource(),
    185         "({get foo(v) {}})");
    186 
    187 accessor = Object.getOwnPropertyDescriptor({ set bar(v) {} }, "bar").set;
    188 obj = {};
    189 Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
    190 assertEq(obj.toSource(),
    191         "({get foo(v) {}})");
    192 
    193 accessor = Object.getOwnPropertyDescriptor({ get foo() {} }, "foo").get;
    194 obj = {};
    195 Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
    196 assertEq(obj.toSource(),
    197         "({set foo() {}})");
    198 
    199 accessor = Object.getOwnPropertyDescriptor({ get bar() {} }, "bar").get;
    200 obj = {};
    201 Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
    202 assertEq(obj.toSource(),
    203         "({set foo() {}})");
    204 
    205 accessor = Object.getOwnPropertyDescriptor({ set foo(v) {} }, "foo").set;
    206 obj = {};
    207 Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
    208 assertEq(obj.toSource(),
    209         "({set foo(v) {}})");
    210 
    211 accessor = Object.getOwnPropertyDescriptor({ set bar(v) {} }, "bar").set;
    212 obj = {};
    213 Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
    214 assertEq(obj.toSource(),
    215         "({set foo(v) {}})");
    216 
    217 // Methods with proxy.
    218 // Treated as normal property.
    219 
    220 method = ({foo() {}}).foo;
    221 let handler = {
    222  get(that, name) {
    223    if (name == "toSource") {
    224      return function() {
    225        return that.toSource();
    226      };
    227    }
    228    return that[name];
    229  }
    230 };
    231 let proxy = new Proxy(method, handler);
    232 
    233 obj = {};
    234 Object.defineProperty(obj, "foo", {value: proxy, enumerable: true});
    235 assertEq(obj.toSource(),
    236         "({foo:foo() {}})");
    237 
    238 // Accessors with proxy.
    239 // Accessor syntax is composed.
    240 
    241 accessor = Object.getOwnPropertyDescriptor({ get foo() {} }, "foo").get;
    242 proxy = new Proxy(accessor, handler);
    243 
    244 obj = {};
    245 Object.defineProperty(obj, "foo", {get: proxy, enumerable: true});
    246 assertEq(obj.toSource(),
    247         "({get foo() {}})");
    248 
    249 obj = {};
    250 Object.defineProperty(obj, "foo", {set: proxy, enumerable: true});
    251 assertEq(obj.toSource(),
    252         "({set foo() {}})");
    253 
    254 // Methods from other global.
    255 // Treated as normal property in the cross-compartment case.
    256 
    257 let g = newGlobal();
    258 
    259 method = g.eval("({ foo() {} }).foo");
    260 
    261 obj = {};
    262 Object.defineProperty(obj, "foo", {value: method, enumerable: true});
    263 assertEq((obj.toSource() === "({foo:foo() {}})" ||
    264          obj.toSource() === "({foo() {}})"),
    265         true);
    266 
    267 // Accessors from other global.
    268 // Accessor syntax is composed.
    269 
    270 accessor = g.eval("Object.getOwnPropertyDescriptor({ get foo() {} }, 'foo').get");
    271 
    272 obj = {};
    273 Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
    274 assertEq(obj.toSource(),
    275         "({get foo() {}})");
    276 
    277 accessor = g.eval("Object.getOwnPropertyDescriptor({ get bar() {} }, 'bar').get");
    278 
    279 obj = {};
    280 Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
    281 assertEq(obj.toSource(),
    282         "({get foo() {}})");
    283 
    284 accessor = g.eval("Object.getOwnPropertyDescriptor({ set foo(v) {} }, 'foo').set");
    285 
    286 obj = {};
    287 Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
    288 assertEq(obj.toSource(),
    289         "({get foo(v) {}})");
    290 
    291 accessor = g.eval("Object.getOwnPropertyDescriptor({ set bar(v) {} }, 'bar').set");
    292 
    293 obj = {};
    294 Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
    295 assertEq(obj.toSource(),
    296         "({get foo(v) {}})");
    297 
    298 accessor = g.eval("Object.getOwnPropertyDescriptor({ get foo() {} }, 'foo').get");
    299 
    300 obj = {};
    301 Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
    302 assertEq(obj.toSource(),
    303         "({set foo() {}})");
    304 
    305 accessor = g.eval("Object.getOwnPropertyDescriptor({ get bar() {} }, 'bar').get");
    306 
    307 obj = {};
    308 Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
    309 assertEq(obj.toSource(),
    310         "({set foo() {}})");
    311 
    312 accessor = g.eval("Object.getOwnPropertyDescriptor({ set foo(v) {} }, 'foo').set");
    313 
    314 obj = {};
    315 Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
    316 assertEq(obj.toSource(),
    317         "({set foo(v) {}})");
    318 
    319 accessor = g.eval("Object.getOwnPropertyDescriptor({ set bar(v) {} }, 'bar').set");
    320 
    321 obj = {};
    322 Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
    323 assertEq(obj.toSource(),
    324         "({set foo(v) {}})");
    325 
    326 // **** Some weird cases ****
    327 
    328 // Accessors with generator or async.
    329 
    330 obj = {};
    331 Object.defineProperty(obj, "foo", {get: function*() {}, enumerable: true});
    332 assertEq(obj.toSource(),
    333         "({get foo() {}})");
    334 
    335 obj = {};
    336 Object.defineProperty(obj, "foo", {set: async function() {}, enumerable: true});
    337 assertEq(obj.toSource(),
    338         "({set foo() {}})");
    339 
    340 // Modified toSource.
    341 
    342 obj = { foo() {} };
    343 obj.foo.toSource = () => "hello";
    344 assertEq(obj.toSource(),
    345         "({hello})");
    346 
    347 obj = { foo() {} };
    348 obj.foo.toSource = () => "bar() {}";
    349 assertEq(obj.toSource(),
    350         "({bar() {}})");
    351 
    352 // Modified toSource with different method name.
    353 
    354 obj = {};
    355 Object.defineProperty(obj, "foo", {value: function bar() {}, enumerable: true});
    356 obj.foo.toSource = () => "hello";
    357 assertEq(obj.toSource(),
    358         "({foo:hello})");
    359 
    360 obj = {};
    361 Object.defineProperty(obj, "foo", {value: function* bar() {}, enumerable: true});
    362 obj.foo.toSource = () => "hello";
    363 assertEq(obj.toSource(),
    364         "({foo:hello})");
    365 
    366 obj = {};
    367 Object.defineProperty(obj, "foo", {value: async function bar() {}, enumerable: true});
    368 obj.foo.toSource = () => "hello";
    369 assertEq(obj.toSource(),
    370         "({foo:hello})");
    371 
    372 if (typeof reportCompare === "function")
    373    reportCompare(true, true);