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