ProxyInProxy.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. // Verifies the order of getOwnPropertyDescriptor trap called for ownKeys
  6. function test1() {
  7. var obj = {};
  8. var proxy = new Proxy(obj, {
  9. getOwnPropertyDescriptor: function (target, property) {
  10. print('getOwnPropertyDescriptor on proxy : ' + property.toString());
  11. return { configurable: true, enumerable: true, value: 10 };
  12. },
  13. ownKeys: function (target) {
  14. print('ownKeys for proxy');
  15. return ["prop0", "prop1", Symbol("prop2"), Symbol("prop5")];
  16. }
  17. });
  18. var proxy2 = new Proxy(proxy, {
  19. getOwnPropertyDescriptor: function (target, property) {
  20. print('getOwnPropertyDescriptor on proxy2 : ' + property.toString());
  21. return { configurable: true, enumerable: true, value: 10 };
  22. },
  23. ownKeys: function (target) {
  24. print('ownKeys for proxy2');
  25. return ["prop2", "prop3", Symbol("prop4"), Symbol("prop5")];
  26. }
  27. });
  28. print('***Testing Object.getOwnPropertyNames()');
  29. print(Object.getOwnPropertyNames(proxy2));
  30. print('***Testing Object.keys()');
  31. print(Object.keys(proxy2));
  32. print('***Testing Object.getOwnPropertySymbols()');
  33. print(Object.getOwnPropertySymbols(proxy2).length);
  34. print('***Testing Object.freeze()');
  35. try{
  36. Object.freeze(proxy2);
  37. print('Object.freeze should fail because underlying OwnPropertyKeys should fail since target becomes non-extensible');
  38. } catch (e) {
  39. if (!(e instanceof TypeError)) {
  40. $ERROR('incorrect instanceof Error' + e);
  41. }
  42. }
  43. }
  44. // Verifies that we don't call GetPropertyDescriptor of target for Object.keys unnecessarily if we throw TypeERROR before
  45. function test2() {
  46. var obj = {};
  47. Object.defineProperty(obj, "a", { value: 5, configurable: false });
  48. var proxy = new Proxy(obj, {
  49. getOwnPropertyDescriptor: function (target, property) {
  50. print('getOwnPropertyDescriptor on proxy : ' + property.toString());
  51. return Object.getOwnPropertyDescriptor(target, property);
  52. },
  53. ownKeys: function (target) {
  54. print('ownKeys for proxy');
  55. return ["a", "prop0", "prop1", Symbol("prop2"), Symbol("prop5")];
  56. }
  57. });
  58. var proxy2 = new Proxy(proxy, {
  59. getOwnPropertyDescriptor: function (target, property) {
  60. print('getOwnPropertyDescriptor on proxy2 : ' + property.toString());
  61. return Object.getOwnPropertyDescriptor(target, property);
  62. },
  63. ownKeys: function (target) {
  64. print('ownKeys for proxy2');
  65. return ["prop2", "prop3", Symbol("prop4"), Symbol("prop5")];
  66. }
  67. });
  68. print('***Testing Object.keys()');
  69. try{
  70. print(Object.keys(proxy2));
  71. print('Should throw TypeError because ownKeys doesnt return non-configurable key.');
  72. } catch (e) {
  73. if (!(e instanceof TypeError)) {
  74. print('incorrect instanceof Error');
  75. }
  76. }
  77. }
  78. function test3() {
  79. var obj = {};
  80. var count = 0;
  81. var proxy = new Proxy(obj, {
  82. get: function (target, property, receiver) {
  83. print('get on proxy : ' + property.toString());
  84. return count++ * 5;
  85. },
  86. getOwnPropertyDescriptor: function (target, property) {
  87. print('getOwnPropertyDescriptor on proxy : ' + property.toString());
  88. return { configurable: true, enumerable: true, value: 10 };
  89. },
  90. ownKeys: function (target) {
  91. print('ownKeys for proxy');
  92. return ["prop0", "prop1", Symbol("prop2"), Symbol("prop5")];
  93. }
  94. });
  95. var proxy2 = new Proxy(proxy, {
  96. get: function (target, property, receiver) {
  97. print('get on proxy2 : ' + property.toString());
  98. return Reflect.get(target, property, receiver);
  99. },
  100. getOwnPropertyDescriptor: function (target, property) {
  101. print('getOwnPropertyDescriptor on proxy2 : ' + property.toString());
  102. return { configurable: true, enumerable: true, value: 10 };
  103. },
  104. ownKeys: function (target) {
  105. print('ownKeys for proxy2');
  106. return ["prop2", "prop3", Symbol("prop4"), Symbol("prop5")];
  107. }
  108. });
  109. print('***Testing Object.assign()');
  110. var answer = Object.assign(obj, null, proxy, proxy2);
  111. var symbols = Object.getOwnPropertySymbols(answer);
  112. var names = Object.getOwnPropertyNames(answer);
  113. print("PropertyNames returned : ");
  114. for (i = 0; i < names.length; i++)
  115. {
  116. print(names[i].toString())
  117. }
  118. print("PropertySymbols returned : ");
  119. for (i = 0; i < symbols.length; i++)
  120. {
  121. print(symbols[i].toString())
  122. }
  123. }
  124. function test4() {
  125. print("***Traps whose value is null are ignored");
  126. function getProxy(trap, result, obj) {
  127. const proxy = new Proxy(obj, {
  128. [trap]: () => {
  129. print(`"${trap}" called`);
  130. return result;
  131. }
  132. });
  133. return new Proxy(proxy, {
  134. [trap]: null
  135. });
  136. }
  137. Object.getPrototypeOf(getProxy("getPrototypeOf", {}, {}));
  138. Object.setPrototypeOf(getProxy("setPrototypeOf", true, {}), {});
  139. Object.isExtensible(getProxy("isExtensible", true, {}));
  140. Object.preventExtensions(getProxy("preventExtensions", false, {}));
  141. Object.getOwnPropertyDescriptor(getProxy("getOwnPropertyDescriptor", undefined, {}));
  142. Object.defineProperty(getProxy("defineProperty", true, {}), "prop", { value: 0 });
  143. "prop" in getProxy("has", true, {});
  144. getProxy("get", 0, {}).prop;
  145. getProxy("set", true, {}).prop = 0;
  146. delete getProxy("deleteProperty", true, {}).prop;
  147. Object.keys(getProxy("ownKeys", [], {}));
  148. getProxy("apply", 0, function () {})();
  149. new (getProxy("construct", {}, function () {}));
  150. }
  151. function test5() {
  152. print("***function wrapped in 2+ proxies");
  153. function a() {}
  154. const p1 = new Proxy(a, {})
  155. console.log(typeof p1) // "function"
  156. const p2 = new Proxy(p1, {})
  157. console.log(typeof p2) // "function"
  158. const p3 = new Proxy(p2, {})
  159. console.log(typeof p3) // "function"
  160. }
  161. function test6() {
  162. print("*** proxied function and Object.prototype.toString.call");
  163. console.log(Object.prototype.toString.call(new Proxy(function a() {}, {})));
  164. // "[object Function]"
  165. console.log(Object.prototype.toString.call(new Proxy(new Proxy(function a() {}, {}), {})));
  166. // "[object Function]"
  167. console.log(Object.prototype.toString.call(new Proxy([], {})));
  168. // "[object Array]"
  169. console.log(Object.prototype.toString.call(new Proxy(new Number(1), {})));
  170. // "[object Object]"
  171. console.log(Object.prototype.toString.call(new Proxy(new String(""), {})));
  172. // "[object Object]"
  173. console.log(Object.prototype.toString.call(new Proxy(new Boolean(true), {})));
  174. // "[object Object]"
  175. console.log(Object.prototype.toString.call(new Proxy(new Date, {})));
  176. // "[object Object]"
  177. }
  178. function test7() {
  179. print("*** proxied function and Function.prototype.toString.call");
  180. console.log(Function.prototype.toString.call(new Proxy(function a() { }, {})));
  181. // "function a() { }"
  182. console.log(Function.prototype.toString.call(new Proxy(new Proxy(function a() { }, {}), {})));
  183. // "function a() { }"
  184. }
  185. function test8() {
  186. print("*** deeply nested proxy and typeof");
  187. var nestedProxy = Proxy.revocable([], {}).proxy;
  188. for (let i = 0; i < 1e5; i++) {
  189. nestedProxy = new Proxy(nestedProxy, {});
  190. }
  191. (function () {
  192. if (nestedProxy != null && typeof nestedProxy == "object")
  193. {
  194. console.log("pass");
  195. }
  196. })();
  197. }
  198. test1();
  199. test2();
  200. test3();
  201. test4();
  202. test5();
  203. test6();
  204. test7();
  205. test8();