1// Copyright 2014 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-reflect 6 7 8(function testReflectApplyArity() { 9 assertEquals(3, Reflect.apply.length); 10})(); 11 12 13(function testReflectApplyNonConstructor() { 14 assertThrows(function() { 15 new Reflect.apply(function(){}, null, []); 16 }, TypeError); 17})(); 18 19 20(function testAppliedReceiverSloppy() { 21 function returnThis() { return this; } 22 var receiver = {}; 23 24 assertSame(this, Reflect.apply(returnThis, void 0, [])); 25 assertSame(this, Reflect.apply(returnThis, null, [])); 26 assertSame(this, Reflect.apply(returnThis, this, [])); 27 assertSame(receiver, Reflect.apply(returnThis, receiver, [])); 28 29 // Wrap JS values 30 assertSame(String.prototype, 31 Object.getPrototypeOf(Reflect.apply(returnThis, "str", []))); 32 assertSame(Number.prototype, 33 Object.getPrototypeOf(Reflect.apply(returnThis, 123, []))); 34 assertSame(Boolean.prototype, 35 Object.getPrototypeOf(Reflect.apply(returnThis, true, []))); 36 assertSame(Symbol.prototype, 37 Object.getPrototypeOf( 38 Reflect.apply(returnThis, Symbol("test"), []))); 39})(); 40 41 42(function testAppliedReceiverStrict() { 43 function returnThis() { 'use strict'; return this; } 44 var receiver = {}; 45 46 assertSame(void 0, Reflect.apply(returnThis, void 0, [])); 47 assertSame(this, Reflect.apply(returnThis, this, [])); 48 assertSame(receiver, Reflect.apply(returnThis, receiver, [])); 49 50 // Don't wrap value types 51 var regexp = /123/; 52 var symbol = Symbol("test"); 53 assertSame("str", Reflect.apply(returnThis, "str", [])); 54 assertSame(123, Reflect.apply(returnThis, 123, [])); 55 assertSame(true, Reflect.apply(returnThis, true, [])); 56 assertSame(regexp, Reflect.apply(returnThis, regexp, [])); 57 assertSame(symbol, Reflect.apply(returnThis, symbol, [])); 58})(); 59 60 61(function testAppliedArgumentsLength() { 62 function returnLengthStrict() { 'use strict'; return arguments.length; } 63 function returnLengthSloppy() { return arguments.length; } 64 65 assertEquals(0, Reflect.apply(returnLengthStrict, this, [])); 66 assertEquals(0, Reflect.apply(returnLengthSloppy, this, [])); 67 assertEquals(0, Reflect.apply(returnLengthStrict, this, {})); 68 assertEquals(0, Reflect.apply(returnLengthSloppy, this, {})); 69 70 for (var i = 0; i < 256; ++i) { 71 assertEquals(i, Reflect.apply(returnLengthStrict, this, new Array(i))); 72 assertEquals(i, Reflect.apply(returnLengthSloppy, this, new Array(i))); 73 assertEquals(i, Reflect.apply(returnLengthStrict, this, { length: i })); 74 assertEquals(i, Reflect.apply(returnLengthSloppy, this, { length: i })); 75 } 76})(); 77 78 79(function testAppliedArgumentsLengthThrows() { 80 function noopStrict() { 'use strict'; } 81 function noopSloppy() { } 82 function MyError() {} 83 84 var argsList = {}; 85 Object.defineProperty(argsList, "length", { 86 get: function() { throw new MyError(); } 87 }); 88 89 assertThrows(function() { 90 Reflect.apply(noopStrict, this, argsList); 91 }, MyError); 92 93 assertThrows(function() { 94 Reflect.apply(noopSloppy, this, argsList); 95 }, MyError); 96})(); 97 98 99(function testAppliedArgumentsElementThrows() { 100 function noopStrict() { 'use strict'; } 101 function noopSloppy() { } 102 function MyError() {} 103 104 var argsList = { length: 1 }; 105 Object.defineProperty(argsList, "0", { 106 get: function() { throw new MyError(); } 107 }); 108 109 assertThrows(function() { 110 Reflect.apply(noopStrict, this, argsList); 111 }, MyError); 112 113 assertThrows(function() { 114 Reflect.apply(noopSloppy, this, argsList); 115 }, MyError); 116})(); 117 118 119(function testAppliedNonFunctionStrict() { 120 'use strict'; 121 assertThrows(function() { Reflect.apply(void 0); }, TypeError); 122 assertThrows(function() { Reflect.apply(null); }, TypeError); 123 assertThrows(function() { Reflect.apply(123); }, TypeError); 124 assertThrows(function() { Reflect.apply("str"); }, TypeError); 125 assertThrows(function() { Reflect.apply(Symbol("x")); }, TypeError); 126 assertThrows(function() { Reflect.apply(/123/); }, TypeError); 127 assertThrows(function() { Reflect.apply(NaN); }, TypeError); 128 assertThrows(function() { Reflect.apply({}); }, TypeError); 129 assertThrows(function() { Reflect.apply([]); }, TypeError); 130})(); 131 132 133(function testAppliedNonFunctionSloppy() { 134 assertThrows(function() { Reflect.apply(void 0); }, TypeError); 135 assertThrows(function() { Reflect.apply(null); }, TypeError); 136 assertThrows(function() { Reflect.apply(123); }, TypeError); 137 assertThrows(function() { Reflect.apply("str"); }, TypeError); 138 assertThrows(function() { Reflect.apply(Symbol("x")); }, TypeError); 139 assertThrows(function() { Reflect.apply(/123/); }, TypeError); 140 assertThrows(function() { Reflect.apply(NaN); }, TypeError); 141 assertThrows(function() { Reflect.apply({}); }, TypeError); 142 assertThrows(function() { Reflect.apply([]); }, TypeError); 143})(); 144 145 146(function testAppliedArgumentsNonList() { 147 function noopStrict() { 'use strict'; } 148 function noopSloppy() {} 149 var R = void 0; 150 assertThrows(function() { Reflect.apply(noopStrict, R, null); }, TypeError); 151 assertThrows(function() { Reflect.apply(noopSloppy, R, null); }, TypeError); 152 assertThrows(function() { Reflect.apply(noopStrict, R, 1); }, TypeError); 153 assertThrows(function() { Reflect.apply(noopSloppy, R, 1); }, TypeError); 154 assertThrows(function() { Reflect.apply(noopStrict, R, "BAD"); }, TypeError); 155 assertThrows(function() { Reflect.apply(noopSloppy, R, "BAD"); }, TypeError); 156 assertThrows(function() { Reflect.apply(noopStrict, R, true); }, TypeError); 157 assertThrows(function() { Reflect.apply(noopSloppy, R, true); }, TypeError); 158 var sym = Symbol("x"); 159 assertThrows(function() { Reflect.apply(noopStrict, R, sym); }, TypeError); 160 assertThrows(function() { Reflect.apply(noopSloppy, R, sym); }, TypeError); 161})(); 162 163 164(function testAppliedArgumentValue() { 165 function returnFirstStrict(a) { 'use strict'; return a; } 166 function returnFirstSloppy(a) { return a; } 167 function returnLastStrict(a) { 168 'use strict'; return arguments[arguments.length - 1]; } 169 function returnLastSloppy(a) { return arguments[arguments.length - 1]; } 170 function returnSumStrict() { 171 'use strict'; 172 var sum = arguments[0]; 173 for (var i = 1; i < arguments.length; ++i) { 174 sum += arguments[i]; 175 } 176 return sum; 177 } 178 function returnSumSloppy() { 179 var sum = arguments[0]; 180 for (var i = 1; i < arguments.length; ++i) { 181 sum += arguments[i]; 182 } 183 return sum; 184 } 185 186 assertEquals("OK!", Reflect.apply(returnFirstStrict, this, ["OK!"])); 187 assertEquals("OK!", Reflect.apply(returnFirstSloppy, this, ["OK!"])); 188 assertEquals("OK!", Reflect.apply(returnFirstStrict, this, 189 { 0: "OK!", length: 1 })); 190 assertEquals("OK!", Reflect.apply(returnFirstSloppy, this, 191 { 0: "OK!", length: 1 })); 192 assertEquals("OK!", Reflect.apply(returnLastStrict, this, 193 [0, 1, 2, 3, 4, 5, 6, 7, 8, "OK!"])); 194 assertEquals("OK!", Reflect.apply(returnLastSloppy, this, 195 [0, 1, 2, 3, 4, 5, 6, 7, 8, "OK!"])); 196 assertEquals("OK!", Reflect.apply(returnLastStrict, this, 197 { 9: "OK!", length: 10 })); 198 assertEquals("OK!", Reflect.apply(returnLastSloppy, this, 199 { 9: "OK!", length: 10 })); 200 assertEquals("TEST", Reflect.apply(returnSumStrict, this, 201 ["T", "E", "S", "T"])); 202 assertEquals("TEST!!", Reflect.apply(returnSumStrict, this, 203 ["T", "E", "S", "T", "!", "!"])); 204 assertEquals(10, Reflect.apply(returnSumStrict, this, 205 { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 })); 206 assertEquals("TEST", Reflect.apply(returnSumSloppy, this, 207 ["T", "E", "S", "T"])); 208 assertEquals("TEST!!", Reflect.apply(returnSumSloppy, this, 209 ["T", "E", "S", "T", "!", "!"])); 210 assertEquals(10, Reflect.apply(returnSumSloppy, this, 211 { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 })); 212})(); 213