Proxy.handler-getOwnPropertyDescriptor.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. describe("[Call][GetOwnProperty]] trap normal behavior", () => {
  2. test("forwarding when not defined in handler", () => {
  3. expect(Object.getOwnPropertyDescriptor(new Proxy({}, { getOwnPropertyDescriptor: null }), "a")).toBeUndefined();
  4. expect(Object.getOwnPropertyDescriptor(new Proxy({}, { getOwnPropertyDescriptor: undefined }), "a")).toBeUndefined();
  5. expect(Object.getOwnPropertyDescriptor(new Proxy({}, {}), "a")).toBeUndefined();
  6. });
  7. test("correct arguments supplied to trap", () => {
  8. let o = {};
  9. let p = new Proxy(o, {
  10. getOwnPropertyDescriptor(target, property) {
  11. expect(target).toBe(o);
  12. expect(property).toBe("foo");
  13. }
  14. });
  15. Object.getOwnPropertyDescriptor(p, "foo");
  16. });
  17. test("conditional returned descriptor", () => {
  18. let o = { foo: "bar" };
  19. Object.defineProperty(o, "baz", { value: "qux", enumerable: false, configurable: true, writable: false });
  20. let p = new Proxy(o, {
  21. getOwnPropertyDescriptor(target, property) {
  22. if (property === "baz")
  23. return Object.getOwnPropertyDescriptor(target, "baz");
  24. return { value: target[property], enumerable: false, configurable: true, writable: true };
  25. }
  26. });
  27. let d = Object.getOwnPropertyDescriptor(p, "baz");
  28. expect(d.configurable).toBe(true);
  29. expect(d.enumerable).toBe(false);
  30. expect(d.writable).toBe(false);
  31. expect(d.value).toBe("qux");
  32. expect(d.get).toBeUndefined();
  33. expect(d.set).toBeUndefined();
  34. d = Object.getOwnPropertyDescriptor(p, "foo");
  35. expect(d.configurable).toBe(true);
  36. expect(d.enumerable).toBe(false);
  37. expect(d.writable).toBe(true);
  38. expect(d.value).toBe("bar");
  39. expect(d.get).toBeUndefined();
  40. expect(d.set).toBeUndefined();
  41. });
  42. });
  43. describe("[[GetOwnProperty]] invariants", () => {
  44. test("must return an object or undefined", () => {
  45. expect(() => {
  46. Object.getOwnPropertyDescriptor(new Proxy({}, {
  47. getOwnPropertyDescriptor() {
  48. return 1;
  49. },
  50. }));
  51. }).toThrowWithMessage(TypeError, "Proxy handler's getOwnPropertyDescriptor trap violates invariant: must return an object or undefined");
  52. });
  53. test("cannot return undefined for a non-configurable property", () => {
  54. let o = {};
  55. Object.defineProperty(o, "foo", { value: 10, configurable: false });
  56. let p = new Proxy(o, {
  57. getOwnPropertyDescriptor() {
  58. return undefined;
  59. },
  60. });
  61. expect(Object.getOwnPropertyDescriptor(p, "bar")).toBeUndefined();
  62. expect(() => {
  63. Object.getOwnPropertyDescriptor(p, "foo");
  64. }).toThrowWithMessage(TypeError, "Proxy handler's getOwnPropertyDescriptor trap violates invariant: cannot return undefined for a property on the target which is a non-configurable property");
  65. });
  66. test("cannot return undefined for an existing property if the target is non-extensible", () => {
  67. let o = {};
  68. Object.defineProperty(o, "baz", { value: 20, configurable: true, writable: true, enumerable: true });
  69. Object.preventExtensions(o);
  70. let p = new Proxy(o, {
  71. getOwnPropertyDescriptor() {
  72. return undefined;
  73. },
  74. });
  75. expect(() => {
  76. Object.getOwnPropertyDescriptor(p, "baz");
  77. }).toThrowWithMessage(TypeError, "Proxy handler's getOwnPropertyDescriptor trap violates invariant: cannot report a property as being undefined if it exists as an own property of the target and the target is non-extensible");
  78. });
  79. test("invalid property descriptors", () => {
  80. let o = {};
  81. Object.defineProperty(o, "v1", { value: 10, configurable: false });
  82. Object.defineProperty(o, "v2", { value: 10, configurable: false, enumerable: true });
  83. Object.defineProperty(o, "v3", { configurable: false, get() { return 1; } });
  84. Object.defineProperty(o, "v4", { value: 10, configurable: false, writable: false, enumerable: true });
  85. expect(() => {
  86. Object.getOwnPropertyDescriptor(new Proxy(o, {
  87. getOwnPropertyDescriptor() {
  88. return { configurable: true };
  89. },
  90. }), "v1");
  91. }).toThrowWithMessage(TypeError, "Proxy handler's getOwnPropertyDescriptor trap violates invariant: invalid property descriptor for existing property on the target");
  92. expect(() => {
  93. Object.getOwnPropertyDescriptor(new Proxy(o, {
  94. getOwnPropertyDescriptor() {
  95. return { enumerable: false };
  96. },
  97. }), "v2");
  98. }).toThrowWithMessage(TypeError, "Proxy handler's getOwnPropertyDescriptor trap violates invariant: invalid property descriptor for existing property on the target");
  99. expect(() => {
  100. Object.getOwnPropertyDescriptor(new Proxy(o, {
  101. getOwnPropertyDescriptor() {
  102. return { value: 10 };
  103. },
  104. }), "v3");
  105. }).toThrowWithMessage(TypeError, "Proxy handler's getOwnPropertyDescriptor trap violates invariant: invalid property descriptor for existing property on the target");
  106. expect(() => {
  107. Object.getOwnPropertyDescriptor(new Proxy(o, {
  108. getOwnPropertyDescriptor() {
  109. return { value: 10, writable: true };
  110. },
  111. }), "v4");
  112. }).toThrowWithMessage(TypeError, "Proxy handler's getOwnPropertyDescriptor trap violates invariant: invalid property descriptor for existing property on the target");
  113. });
  114. test("cannot report a property as non-configurable if it does not exist or is non-configurable", () => {
  115. let o = {};
  116. Object.defineProperty(o, "v", { configurable: true });
  117. expect(() => {
  118. Object.getOwnPropertyDescriptor(new Proxy(o, {
  119. getOwnPropertyDescriptor() {
  120. return { configurable: false };
  121. },
  122. }), "v");
  123. }).toThrowWithMessage(TypeError, "Proxy handler's getOwnPropertyDescriptor trap violates invariant: cannot report target's property as non-configurable if the property does not exist, or if it is configurable");
  124. });
  125. });