getOwnPropertyDescriptors.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. if (this.WScript && this.WScript.LoadScriptFile) { // Check for running in ch
  6. this.WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
  7. }
  8. function verifyObjectDescriptors(descriptors, allTruePropName, allFalsePropName) {
  9. var allProperties = Object.getOwnPropertyNames(descriptors).concat(Object.getOwnPropertySymbols(descriptors));
  10. assert.areEqual([allTruePropName, allFalsePropName], allProperties, "Result should have one descriptor for each own property");
  11. assert.isTrue(descriptors.hasOwnProperty(allTruePropName), "Result should contain all own properties");
  12. assert.isTrue(descriptors.hasOwnProperty(allFalsePropName), "Result should contain all own properties");
  13. assert.areEqual(descriptors[allTruePropName].value, "fooAllTrue", "Result value attribute should match the value set by defineProperties");
  14. assert.areEqual(descriptors[allFalsePropName].value, "fooAllFalse", "Result value attribute should match the value set by defineProperties");
  15. var expectedProps = ['configurable', 'writable', 'enumerable'];
  16. for (var i in expectedProps) {
  17. assert.isTrue(descriptors[allTruePropName][expectedProps[i]], "Result value attribute should match the value set by defineProperties");
  18. assert.isFalse(descriptors[allFalsePropName][expectedProps[i]], "Result value attribute should match the value set by defineProperties");
  19. }
  20. }
  21. var tests = [
  22. {
  23. name: "Object has getOwnPropertyDescriptors method",
  24. body: function() {
  25. assert.isTrue(Object.hasOwnProperty("getOwnPropertyDescriptors"), 'Object should have getOwnPropertyDescriptors method');
  26. assert.isFalse(Object.hasOwnProperty({}, "getOwnPropertyDescriptors"), 'New objects should have a property getOwnPropertyDescriptors');
  27. assert.isUndefined(Object.getOwnPropertyDescriptor({}, "getOwnPropertyDescriptors"), 'Object.getOwnPropertyDescriptor({}, "getOwnPropertyDescriptors") should be undefined');
  28. for (var p in {}) {
  29. assert.isTrue(p != "getOwnPropertyDescriptors", "getOwnPropertyDescriptors should not be enumerable on new objects");
  30. }
  31. assert.areEqual(1, Object.getOwnPropertyDescriptors.length, "Object.getOwnPropertyDescriptors requires exactly one parameter.");
  32. }
  33. },
  34. {
  35. name: "Correctly handles bad parameters.",
  36. body: function() {
  37. assert.throws(function() {
  38. Object.getOwnPropertyDescriptors();
  39. }, TypeError, "Missing first parameter should cause a TypeError.", "Object expected");
  40. assert.throws(function() {
  41. Object.getOwnPropertyDescriptors(null);
  42. }, TypeError, "Null first parameter should cause a TypeError", "Object expected");
  43. }
  44. },
  45. {
  46. name: "The resulting get and set are identical with the original get and set.",
  47. body: function() {
  48. // This test is adapted from https://github.com/tc39/proposal-object-getownpropertydescriptors/blob/master/test/built-ins/Object/getOwnPropertyDescriptors/has-accessors.js
  49. var a = {
  50. get a() {},
  51. set a(value) {}
  52. };
  53. var b = Object.getOwnPropertyDescriptors(a);
  54. assert.isTrue(b.a.get === Object.getOwnPropertyDescriptor(a, 'a').get);
  55. assert.isTrue(b.a.set === Object.getOwnPropertyDescriptor(a, 'a').set);
  56. }
  57. },
  58. {
  59. name: "For properties with string names, the list of property descriptors includes all own properties with correct descriptors",
  60. body: function() {
  61. var foo = {}
  62. Object.defineProperties(foo, {
  63. "fooAllTrue": {
  64. configurable: true,
  65. enumerable: true,
  66. value: "fooAllTrue",
  67. writable: true
  68. },
  69. "fooAllFalse": {
  70. configurable: false,
  71. enumerable: false,
  72. value: "fooAllFalse",
  73. writable: false
  74. }
  75. });
  76. var desc = Object.getOwnPropertyDescriptors(foo);
  77. assert.isTrue(desc instanceof Object, "Result must be an object");
  78. verifyObjectDescriptors(desc, "fooAllTrue", "fooAllFalse");
  79. }
  80. },
  81. {
  82. name: "For properties with number names, the list of property descriptors includes all own properties with correct descriptors",
  83. body: function() {
  84. var foo = {}
  85. var allTrueNum = 1234;
  86. var allFalseNum = 5678;
  87. Object.defineProperties(foo, {
  88. [allTrueNum]: {
  89. configurable: true,
  90. enumerable: true,
  91. value: "fooAllTrue",
  92. writable: true
  93. },
  94. [allFalseNum]: {
  95. configurable: false,
  96. enumerable: false,
  97. value: "fooAllFalse",
  98. writable: false
  99. }
  100. });
  101. var desc = Object.getOwnPropertyDescriptors(foo);
  102. assert.isTrue(desc instanceof Object, "Result must be an object");
  103. verifyObjectDescriptors(desc, allTrueNum.toString(), allFalseNum.toString());
  104. // Also verify that the properties are accessible as numbers
  105. assert.areEqual(desc[allTrueNum].value, "fooAllTrue", "For properties with number names, resulting properties should be accessible with numeric names.")
  106. assert.areEqual(desc[allFalseNum].value, "fooAllFalse", "For properties with number names, resulting properties should be accessible with numeric names.")
  107. }
  108. },
  109. {
  110. name: "For properties with symbol names, the list of property descriptors includes all own properties with correct descriptors",
  111. body: function() {
  112. var foo = {}
  113. var allTrueSymbol = Symbol("allTrue");
  114. var allFalseSymbol = Symbol("allFalse");
  115. Object.defineProperties(foo, {
  116. [allTrueSymbol]: {
  117. configurable: true,
  118. enumerable: true,
  119. value: "fooAllTrue",
  120. writable: true
  121. },
  122. [allFalseSymbol]: {
  123. configurable: false,
  124. enumerable: false,
  125. value: "fooAllFalse",
  126. writable: false
  127. }
  128. });
  129. var desc = Object.getOwnPropertyDescriptors(foo);
  130. assert.isTrue(desc instanceof Object, "Result must be an object");
  131. verifyObjectDescriptors(desc, allTrueSymbol, allFalseSymbol);
  132. }
  133. },
  134. {
  135. name:"For any property, if getOwnPropertyDescriptor(property) is undefined, that property should not be present on the result.",
  136. body: function() {
  137. // Adapted from: https://github.com/ljharb/test262/blob/c2eaa30b08fb1e041b7297e415b6bad8461f50dc/test/built-ins/Object/getOwnPropertyDescriptors/proxy-undefined-descriptor.js
  138. var proxyHandler = {
  139. getOwnPropertyDescriptor: function () {},
  140. };
  141. var key = "a";
  142. var obj = {};
  143. obj[key] = "value";
  144. var proxy = new Proxy(obj, proxyHandler);
  145. var descriptor = Object.getOwnPropertyDescriptor(proxy, key);
  146. assert.areEqual(undefined, descriptor, "Descriptor matches result of [[GetOwnPropertyDescriptor]] trap");
  147. var result = Object.getOwnPropertyDescriptors(proxy);
  148. assert.isFalse(result.hasOwnProperty(key), "key should not be present in result");
  149. }
  150. },
  151. ]
  152. testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });