proxytest9.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. function test0() {
  6. print('test0 : Object.keys with symbols');
  7. var sym = Symbol();
  8. var o = {};
  9. o[sym] = "blah";
  10. var p = new Proxy(o, {});
  11. WScript.Echo(Object.keys(p).length);
  12. }
  13. function test1() {
  14. print('test1: Object.prototype.propertyIsEnumerable');
  15. var sym = Symbol();
  16. var o = {};
  17. Object.defineProperty(o, sym, { value: 5, enumerable: true });
  18. print(o.propertyIsEnumerable(sym));
  19. }
  20. function test2() {
  21. print('test2: Object.getOwnPropertyDescriptor');
  22. var desc = { value: new Proxy({}, {}), writable: true, enumerable: true, configurable: true};
  23. var traps =
  24. {
  25. getOwnPropertyDescriptor: function () { WScript.Echo("getown"); return desc; }
  26. };
  27. var p = new Proxy({}, traps);
  28. WScript.Echo(Object.getOwnPropertyDescriptor(p).value);
  29. traps.getOwnPropertyDescriptor = function () {
  30. WScript.Echo("proxy getown");
  31. desc.get = function () { return 5; };
  32. return new Proxy(desc, { });
  33. }
  34. try {
  35. Object.getOwnPropertyDescriptor(p);
  36. print('Expected to throw TypeError');
  37. } catch (e) {
  38. if (e instanceof TypeError) {
  39. if (e.message !== "Invalid property descriptor: cannot both specify accessors and a 'value' attribute") {
  40. print('FAIL');
  41. }
  42. } else {
  43. print('FAIL');
  44. }
  45. }
  46. }
  47. function test3(){
  48. var traps = {
  49. has: function (target, prop) {
  50. print('has trap for prop :' + prop);
  51. return Reflect.has(target, prop);
  52. },
  53. getOwnPropertyDescriptor: function (target, prop) {
  54. print('getOwnPropertyDescriptor trap for prop: ' + prop);
  55. return new Proxy(desc, traps);
  56. }
  57. };
  58. var desc = { value: 1, writable: true, configurable : true };
  59. desc.a = 1;
  60. var p = new Proxy(desc, traps);
  61. Object.getOwnPropertyDescriptor(p,"a");
  62. }
  63. function test4() {
  64. var keys = ["a"];
  65. var traps =
  66. {
  67. ownKeys : function() { WScript.Echo("plain key trap!"); return keys; },
  68. getOwnPropertyDescriptor: function (target, prop) {
  69. WScript.Echo("getOwn");
  70. return { enumerable: true, configurable: true }
  71. }
  72. };
  73. var p = new Proxy({}, traps);
  74. WScript.Echo(Object.keys(p).length);
  75. traps.ownKeys = function (target, prop)
  76. {
  77. WScript.Echo("proxy key trap!");
  78. return new Proxy(keys, {});
  79. }
  80. WScript.Echo(Object.keys(p).length);
  81. }
  82. function test5() {
  83. var keys = ["a"];
  84. var traps =
  85. {
  86. ownKeys: function () { WScript.Echo("plain key trap!"); return keys; },
  87. getOwnPropertyDescriptor: function (target, prop) {
  88. WScript.Echo("getOwn :" + prop);
  89. return { enumerable: true, configurable: true }
  90. }
  91. };
  92. var p = new Proxy({}, traps);
  93. //WScript.Echo(Object.keys(p).length);
  94. traps.ownKeys = function (target, prop) {
  95. WScript.Echo("proxy key trap!");
  96. return { 0: "a", 2: "3", length : 2 }
  97. }
  98. WScript.Echo(Object.keys(p).length);
  99. }
  100. function test6() {
  101. var arr = [1, 2, 3];
  102. Math.max.apply(null, new Proxy(arr, {
  103. get: function (target, prop) {
  104. print('get trap : ' + prop);
  105. if (prop == 'length') {
  106. return target.length;
  107. }
  108. }
  109. }));
  110. }
  111. function test7() {
  112. var traps = {
  113. get: function (target, prop) {
  114. print('get trap :' + prop);
  115. return Reflect.get(target, prop);
  116. },
  117. ownKeys: function (target) {
  118. print('ownKeys trap : ');
  119. return Reflect.ownKeys(target);
  120. },
  121. getOwnPropertyDescriptor: function (target, prop) {
  122. print('getOwnPropertyDescriptor trap : ' + prop.toString());
  123. return Reflect.getOwnPropertyDescriptor(target, prop);
  124. }
  125. };
  126. var proto = { inherited: "blah" };
  127. var props = Object.create(proto);
  128. var sym1 = Symbol();
  129. Object.defineProperty(props, "a", { value: 5 });
  130. Object.defineProperty(props, "b", { value: 5 });
  131. Object.defineProperty(props, sym1, { value: 5 });
  132. var proxy_props = new Proxy(props, traps)
  133. var o1 = Object.create(proto, proxy_props);
  134. var o2 = Object.defineProperties({}, proxy_props);
  135. }
  136. function test8() {
  137. var test = function () { print('test') };
  138. var p = new Proxy(test, {
  139. has: function (target, prop) {
  140. print('has');
  141. },
  142. get: function (target, prop) {
  143. print('get : ' + prop);
  144. return Reflect.get(target, prop);
  145. }
  146. })
  147. p.bind({});
  148. }
  149. function test9() {
  150. var test = function () { print('test'); }
  151. var p = new Proxy(test, {
  152. apply: function (target) {
  153. print('apply');
  154. }
  155. });
  156. p.call();
  157. }
  158. // Function.bind with proxy
  159. function test10() {
  160. function test() { print('test called'); }
  161. var p = new Proxy(test, {});
  162. var x = p.bind({}, 1, 2);
  163. var proxy_x = new Proxy(x, {});
  164. print(x.name);
  165. print(proxy_x.name);
  166. print(p.name);
  167. p();
  168. x();
  169. proxy_x();
  170. }
  171. function test11() {
  172. var trap = {
  173. get: function (target, property) {
  174. print('get trap: ' + property);
  175. return Reflect.get(target, property);
  176. },
  177. getPrototypeOf: function (target) {
  178. print('getPrototypeOf trap');
  179. return { a: "a" };
  180. },
  181. getOwnPropertyDescriptor: function (target, property) {
  182. print('getOwnPropertyDescriptor trap: ' + property);
  183. return Reflect.getOwnPropertyDescriptor(target, property);
  184. }
  185. }
  186. function test(a, b) {
  187. }
  188. var t = test.bind({}, 1);
  189. var p = new Proxy(test, trap);
  190. var x = p.bind({}, 1);
  191. var proxy_x = new Proxy(x, {});
  192. print(Object.getPrototypeOf(proxy_x).a === "a");
  193. print(Object.getPrototypeOf(x).a === "a");
  194. }
  195. function test12() {
  196. var o = {};
  197. Object.defineProperty(o, "A", { get: function () { return 5; }, set: function (val) { } });
  198. var p = new Proxy(o, {
  199. getOwnPropertyDescriptor: function (target, property) {
  200. print('getOwnPropertyDescriptor trap :' + property);
  201. return Reflect.getOwnPropertyDescriptor(target, property);
  202. },
  203. get: function (target, property) {
  204. print('get trap :' + property);
  205. return Reflect.get(target, property);
  206. }
  207. })
  208. p.__lookupGetter__("A");
  209. p.__lookupSetter__("A");
  210. }
  211. function test13() {
  212. function Foo() { }
  213. Object.defineProperty(Foo, 'length', { value: 123, enumerable: true, configurable: false });
  214. print(Foo.length);
  215. var x = new Proxy(Foo, {
  216. ownKeys: function (target) {
  217. print("my proxy ownKeys");
  218. return Reflect.ownKeys(target);
  219. }
  220. });
  221. print(Object.keys(x));
  222. }
  223. function test14() {
  224. var x = function() {
  225. this.foo = "f1";
  226. this.bar = "f2";
  227. }
  228. var x1 = new Proxy(x, {
  229. construct: function (target, argumentList) {
  230. print('construct x');
  231. return Reflect.construct(target, argumentList);
  232. }
  233. });
  234. var p = new Proxy(x1, {
  235. construct: function (target, argumentList) {
  236. print('construct x1');
  237. return Reflect.construct(target, argumentList);
  238. }
  239. });
  240. var a = new p();
  241. print(a.foo + ":" + a.bar);
  242. }
  243. var handler =
  244. {
  245. get : function(target, property) {
  246. print('get trap ' + property);
  247. var x = Reflect.get(target, property);
  248. if(property == 'constructor')
  249. {
  250. x = new Proxy(x, handler);
  251. }
  252. return x;
  253. },
  254. construct: function(target, args) {
  255. print('constructor trap');
  256. return Reflect.construct(target, args);
  257. },
  258. apply : function(target, thisArg, argsList) {
  259. print('apply trap' );
  260. return Reflect.apply(target, thisArg, argsList)
  261. }
  262. };
  263. function test15()
  264. {
  265. var a = [1,2,3];
  266. var p = new Proxy(Array, handler);
  267. p.of = Array.of;
  268. print(p.of(1,2));
  269. }
  270. function test16()
  271. {
  272. var a = [1,2,3];
  273. var p = new Proxy(Array, handler);
  274. p.from = Array.from;
  275. print(p.from([1,2]));
  276. }
  277. function test17()
  278. {
  279. function foo() { this.x = 1};
  280. // proxy of foo
  281. var pFoo = new Proxy(foo, handler);
  282. // proxy of proxy of foo
  283. var proxyOfpFoo = new Proxy(pFoo, handler);
  284. // bind
  285. var x = proxyOfpFoo.bind(1);
  286. // proxy of bound function
  287. var y = new Proxy(x, handler);
  288. print((new y()).x == 1);
  289. }
  290. function test18()
  291. {
  292. var Obj = { a: 'foo', m: function () { } };
  293. var p = new Proxy(Obj, handler);
  294. p.m = Obj.m;
  295. // Here p.m should not be copy-prop'd from Obj.m
  296. p.m();
  297. }
  298. // Verify if targetFunction of bound function is a proxy to function
  299. function test19()
  300. {
  301. function foo(a) {
  302. this.abc = a;
  303. };
  304. var _ = new Proxy(foo, {});
  305. var p = _.bind();
  306. var x = new p('def');
  307. print(x.abc);
  308. }
  309. // Verify if targetFunction passed to Reflect.construct is a proxy to function
  310. function test20()
  311. {
  312. function foo(a) {this.abc = a;};
  313. var _ = new Proxy(foo, {});
  314. var p = _.bind();
  315. var x = Reflect.construct(p, ["ade"]);
  316. print(x.abc);
  317. }
  318. // Verify that constructor do return an object.
  319. function test21()
  320. {
  321. function foo() {
  322. this.a = "b";
  323. }
  324. var x = new Proxy(foo, {});
  325. var y = new x();
  326. print(y.a);
  327. }
  328. // some basic test262 test cases
  329. function test22(){
  330. //1. Proxy.length is configurable
  331. var x = Object.getOwnPropertyDescriptor(Proxy, 'length');
  332. print('value : ' + x.value);
  333. print('configurable : ' + x.configurable);
  334. print('writable : ' + x.writable);
  335. print('enumerable : ' + x.enumerable);
  336. var revocable = Proxy.revocable({}, {});
  337. var revokeFunction = revocable.revoke;
  338. //2. Revoke function's properties
  339. print(Object.prototype.hasOwnProperty.call(revokeFunction, "prototype"));
  340. print(Object.prototype.hasOwnProperty.call(revokeFunction, "name"));
  341. //3. Revoked proxy passed as target/handler
  342. revocable.revoke();
  343. try {
  344. var x = new Proxy({}, revocable.proxy);
  345. } catch(e) {
  346. print('expected :' + e.message);
  347. }
  348. try{
  349. var x = new Proxy(revocable.proxy,{});
  350. } catch(e) {
  351. print('expected :' + e.message);
  352. }
  353. //4. Proxy doesn't have prototype
  354. print('Proxy.prototype = ' + Object.hasOwnProperty.call(Proxy, 'prototype'));
  355. //5. Reflect.defineProperty should not throw if target already has a property
  356. Reflect.defineProperty(Object.defineProperty({},"x", {value:1}), "x", {value : 2});
  357. print('done test22');
  358. }
  359. // Verify that Object.setPrototype takes null as newPrototype value
  360. function test23()
  361. {
  362. var proxy = new Proxy(function() {}, {});
  363. Object.setPrototypeOf(proxy, null);
  364. print('test23 done.');
  365. }
  366. // Verifies ownPropertyNames, ownPropertySymbols
  367. function test24()
  368. {
  369. var o = {};
  370. var s1 = Symbol('b');
  371. var s2 = Symbol('c');
  372. Object.defineProperty(o, 'a', { value: 5, enumerable : true });
  373. Object.defineProperty(o, s1, { value: 5, enumerable: true });
  374. Object.defineProperty(o, s2, { value: 5, enumerable: false });
  375. var proxy = new Proxy(o, {});
  376. var propNames = Object.getOwnPropertyNames(proxy);
  377. var propSyms = Object.getOwnPropertySymbols(proxy);
  378. var propKeys = Reflect.ownKeys(proxy);
  379. print('*** ownPropertyNames');
  380. for (var p in propNames) {
  381. print(propNames[p].toString());
  382. }
  383. print('*** ownPropertySymbols');
  384. for (var p in propSyms) {
  385. print(propSyms[p].toString());
  386. }
  387. print('*** ownKeys');
  388. for (var p in propKeys) {
  389. print(propKeys[p].toString());
  390. }
  391. }
  392. function test25() {
  393. // CreateDynamicFunction -> GetPrototypeFromConstructor -> Get -> [[Get]]
  394. var get = [];
  395. var p = new Proxy(Function, { get: function(o, k) { get.push(k); return o[k]; }});
  396. new p;
  397. for (var x in get) {
  398. print(get[x].toString());
  399. }
  400. print(get.length);
  401. print(get);
  402. }
  403. function test26(){
  404. // SerializeJSONObject -> EnumerableOwnNames -> [[OwnPropertyKeys]]
  405. var ownKeysCalled = 0;
  406. var p = new Proxy({}, { ownKeys: function(o) { ownKeysCalled++; return Object.keys(o); }});
  407. JSON.stringify({ a: p, b: p });
  408. print(ownKeysCalled);
  409. print(ownKeysCalled === 2);
  410. }
  411. // has, deleteproperty, methodhelper
  412. function test27()
  413. {
  414. var handler = {
  415. get: function(target, property){
  416. print('getTrap, property : ' + property);
  417. if(property == 'foo123'){
  418. return function() {print('foo called'); return 23;}
  419. }
  420. return Reflect.get(target, property);
  421. },
  422. has: function(target, property){
  423. print('hasTrap, property : ' + property);
  424. return Reflect.has(target, property);
  425. },
  426. deleteProperty: function (target, property) {
  427. print('deleteTrap, property : ' + property);
  428. return Reflect.deleteProperty(target, property);
  429. }
  430. };
  431. // try to have different properties for below test cases
  432. var x = 'foo123';
  433. var y = 'bar123';
  434. var o = {};
  435. var p = new Proxy(o, handler);
  436. Reflect.has(p, 'p1');
  437. 'p2' in p;
  438. Reflect.deleteProperty(p, 'p3');
  439. typeof p[y];
  440. p[x]();
  441. }
  442. // Set property problem
  443. function test28(){
  444. var o2 = { p: 43 };
  445. var receiver = { p: 44 };
  446. var result = Reflect.set(o2, 'p', 42, receiver);
  447. print(o2.p);
  448. print(receiver.p);
  449. }
  450. function test29() {
  451. // CreateDynamicFunction -> GetPrototypeFromConstructor -> Get -> [[Get]]
  452. var get = [];
  453. var p = new Proxy(Function, {});
  454. var funcInstance = new p('b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', "return 1;");
  455. if (funcInstance.length != 9)
  456. {
  457. print('FAIL');
  458. }
  459. }
  460. function test30() {
  461. var o = Proxy.revocable([], {});
  462. o.revoke();
  463. try {
  464. Array.prototype.concat.call(o.proxy);
  465. } catch(e) {
  466. print('expected :' + e.message);
  467. }
  468. try {
  469. Array.prototype.join.call(o.proxy, o.proxy);
  470. } catch(e) {
  471. print('expected :' + e.message);
  472. }
  473. try {
  474. Object.prototype.toString.call(o.proxy);
  475. } catch(e) {
  476. print('expected :' + e.message);
  477. }
  478. try {
  479. function foo() {return this;}
  480. var p = Proxy.revocable(foo, {});
  481. p.revoke();
  482. var pp = new p.proxy();
  483. } catch(e) {
  484. print('expected :' + e.message);
  485. }
  486. }
  487. test0();
  488. test1();
  489. test2();
  490. test3();
  491. test4();
  492. test5();
  493. test6();
  494. test7();
  495. test8();
  496. test9();
  497. test10();
  498. test11();
  499. test12();
  500. test13();
  501. test14();
  502. test15();
  503. test16();
  504. test17();
  505. test18();
  506. test19();
  507. test20();
  508. test21();
  509. test22();
  510. test23();
  511. test24();
  512. test25();
  513. test26();
  514. test27();
  515. test28();
  516. test29();
  517. test30();