Proxy.handler-get.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. describe("[[Get]] trap normal behavior", () => {
  2. test("forwarding when not defined in handler", () => {
  3. expect(new Proxy({}, { get: undefined }).foo).toBeUndefined();
  4. expect(new Proxy({}, { get: null }).foo).toBeUndefined();
  5. expect(new Proxy({}, {}).foo).toBeUndefined();
  6. });
  7. test("correct arguments supplied to trap", () => {
  8. let o = {};
  9. let p = new Proxy(o, {
  10. get(target, property, receiver) {
  11. expect(target).toBe(o);
  12. expect(property).toBe("foo");
  13. expect(receiver).toBe(p);
  14. },
  15. });
  16. p.foo;
  17. });
  18. test("correct arguments passed to trap even for number", () => {
  19. let o = {};
  20. let p = new Proxy(o, {
  21. get(target, property, receiver) {
  22. expect(target).toBe(o);
  23. expect(property).toBe("1");
  24. expect(receiver).toBe(p);
  25. },
  26. });
  27. p[1];
  28. });
  29. test("conditional return", () => {
  30. let o = { foo: 1 };
  31. let p = new Proxy(o, {
  32. get(target, property, receiver) {
  33. if (property === "bar") {
  34. return 2;
  35. } else if (property === "baz") {
  36. return receiver.qux;
  37. } else if (property === "qux") {
  38. return 3;
  39. }
  40. return target[property];
  41. },
  42. });
  43. expect(p.foo).toBe(1);
  44. expect(p.bar).toBe(2);
  45. expect(p.baz).toBe(3);
  46. expect(p.qux).toBe(3);
  47. expect(p.test).toBeUndefined();
  48. expect(p[Symbol.hasInstance]).toBeUndefined();
  49. });
  50. test("custom receiver value", () => {
  51. let p = new Proxy(
  52. {},
  53. {
  54. get(target, property, receiver) {
  55. return receiver;
  56. },
  57. }
  58. );
  59. expect(Reflect.get(p, "foo", 42)).toBe(42);
  60. });
  61. });
  62. describe("[[Get]] invariants", () => {
  63. test("returned value must match the target property value if the property is non-configurable and non-writable", () => {
  64. let o = {};
  65. Object.defineProperty(o, "foo", { value: 5, configurable: false, writable: true });
  66. Object.defineProperty(o, "bar", { value: 10, configurable: false, writable: false });
  67. let p = new Proxy(o, {
  68. get() {
  69. return 8;
  70. },
  71. });
  72. expect(p.foo).toBe(8);
  73. expect(() => {
  74. p.bar;
  75. }).toThrowWithMessage(
  76. TypeError,
  77. "Proxy handler's get trap violates invariant: the returned value must match the value on the target if the property exists on the target as a non-writable, non-configurable own data property"
  78. );
  79. });
  80. test("returned value must be undefined if the property is a non-configurable accessor with no getter", () => {
  81. let o = {};
  82. Object.defineProperty(o, "foo", { configurable: false, set(_) {} });
  83. let p = new Proxy(o, {
  84. get() {
  85. return 8;
  86. },
  87. });
  88. expect(() => {
  89. p.foo;
  90. }).toThrowWithMessage(
  91. TypeError,
  92. "Proxy handler's get trap violates invariant: the returned value must be undefined if the property exists on the target as a non-configurable accessor property with an undefined get attribute"
  93. );
  94. });
  95. });