Proxy.handler-setPrototypeOf.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. load("test-common.js");
  2. try {
  3. const child = {};
  4. const childProto = { foo: "bar" };
  5. Object.setPrototypeOf(child, childProto);
  6. assert(child.foo === "bar");
  7. Object.setPrototypeOf(new Proxy(child, { setPrototypeOf: null }), childProto);
  8. Object.setPrototypeOf(new Proxy(child, { setPrototypeOf: undefined }), childProto);
  9. let o = {};
  10. let theNewProto = { foo: "bar" };
  11. let p = new Proxy(o, {
  12. setPrototypeOf(target, newProto) {
  13. assert(target === o);
  14. assert(newProto === theNewProto);
  15. return true;
  16. }
  17. });
  18. Object.setPrototypeOf(p, theNewProto);
  19. p = new Proxy(o, {
  20. setPrototypeOf(target, newProto) {
  21. if (target.shouldSet)
  22. Object.setPrototypeOf(target, newProto);
  23. return true;
  24. },
  25. });
  26. Object.setPrototypeOf(p, { foo: 1 });
  27. assert(Object.getPrototypeOf(p).foo === undefined);
  28. p.shouldSet = true;
  29. assert(o.shouldSet === true);
  30. Object.setPrototypeOf(p, { foo: 1 });
  31. assert(Object.getPrototypeOf(p).foo === 1);
  32. // Invariants
  33. assertThrowsError(() => {
  34. Object.setPrototypeOf(new Proxy(child, { setPrototypeOf: 1 }), {});
  35. }, {
  36. error: TypeError,
  37. message: "Proxy handler's setPrototypeOf trap wasn't undefined, null, or callable",
  38. });
  39. p = new Proxy(child, {
  40. setPrototypeOf(target, newProto) {
  41. assert(target === child);
  42. return false;
  43. },
  44. });
  45. assertThrowsError(() => {
  46. Object.setPrototypeOf(p, {});
  47. }, {
  48. error: TypeError,
  49. message: "Object's [[SetPrototypeOf]] method returned false",
  50. });
  51. assert(Object.getPrototypeOf(p) === childProto);
  52. p = new Proxy(child, {
  53. setPrototypeOf(target, newProto) {
  54. assert(target === child);
  55. return true;
  56. },
  57. });
  58. assert(Object.setPrototypeOf(p, {}) === p);
  59. assert(Object.getPrototypeOf(p) === childProto);
  60. Object.preventExtensions(child);
  61. p = new Proxy(child, {
  62. setPrototypeOf(target, newProto) {
  63. assert(target === child);
  64. return true;
  65. },
  66. });
  67. assert(Object.setPrototypeOf(p, childProto) === p);
  68. assert(Object.getPrototypeOf(p) === childProto);
  69. assertThrowsError(() => {
  70. Object.setPrototypeOf(p, {});
  71. }, {
  72. error: TypeError,
  73. message: "Proxy handler's setPrototypeOf trap violates invariant: the argument must match the prototype of the target if the target is non-extensible",
  74. });
  75. console.log("PASS");
  76. } catch (e) {
  77. console.log("FAIL: " + e);
  78. }