mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-26 09:22:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			118 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| describe("[[Get]] trap normal behavior", () => {
 | |
|     test("forwarding when not defined in handler", () => {
 | |
|         expect(new Proxy({}, { get: undefined }).foo).toBeUndefined();
 | |
|         expect(new Proxy({}, { get: null }).foo).toBeUndefined();
 | |
|         expect(new Proxy({}, {}).foo).toBeUndefined();
 | |
|     });
 | |
| 
 | |
|     test("correct arguments supplied to trap", () => {
 | |
|         let o = {};
 | |
|         let p = new Proxy(o, {
 | |
|             get(target, property, receiver) {
 | |
|                 expect(target).toBe(o);
 | |
|                 expect(property).toBe("foo");
 | |
|                 expect(receiver).toBe(p);
 | |
|             },
 | |
|         });
 | |
| 
 | |
|         p.foo;
 | |
|     });
 | |
| 
 | |
|     test("correct arguments passed to trap even for number", () => {
 | |
|         let o = {};
 | |
|         let p = new Proxy(o, {
 | |
|             get(target, property, receiver) {
 | |
|                 expect(target).toBe(o);
 | |
|                 expect(property).toBe("1");
 | |
|                 expect(receiver).toBe(p);
 | |
|             },
 | |
|         });
 | |
| 
 | |
|         p[1];
 | |
|     });
 | |
| 
 | |
|     test("conditional return", () => {
 | |
|         let o = { foo: 1 };
 | |
|         let p = new Proxy(o, {
 | |
|             get(target, property, receiver) {
 | |
|                 if (property === "bar") {
 | |
|                     return 2;
 | |
|                 } else if (property === "baz") {
 | |
|                     return receiver.qux;
 | |
|                 } else if (property === "qux") {
 | |
|                     return 3;
 | |
|                 }
 | |
|                 return target[property];
 | |
|             },
 | |
|         });
 | |
| 
 | |
|         expect(p.foo).toBe(1);
 | |
|         expect(p.bar).toBe(2);
 | |
|         expect(p.baz).toBe(3);
 | |
|         expect(p.qux).toBe(3);
 | |
|         expect(p.test).toBeUndefined();
 | |
|         expect(p[Symbol.hasInstance]).toBeUndefined();
 | |
|     });
 | |
| 
 | |
|     test("custom receiver value", () => {
 | |
|         let p = new Proxy(
 | |
|             {},
 | |
|             {
 | |
|                 get(target, property, receiver) {
 | |
|                     return receiver;
 | |
|                 },
 | |
|             }
 | |
|         );
 | |
| 
 | |
|         expect(Reflect.get(p, "foo", 42)).toBe(42);
 | |
|     });
 | |
| });
 | |
| 
 | |
| describe("[[Get]] invariants", () => {
 | |
|     test("returned value must match the target property value if the property is non-configurable and non-writable", () => {
 | |
|         let o = {};
 | |
|         Object.defineProperty(o, "foo", { value: 5, configurable: false, writable: true });
 | |
|         Object.defineProperty(o, "bar", { value: 10, configurable: false, writable: false });
 | |
| 
 | |
|         let p = new Proxy(o, {
 | |
|             get() {
 | |
|                 return 8;
 | |
|             },
 | |
|         });
 | |
| 
 | |
|         expect(p.foo).toBe(8);
 | |
|         expect(() => {
 | |
|             p.bar;
 | |
|         }).toThrowWithMessage(
 | |
|             TypeError,
 | |
|             "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"
 | |
|         );
 | |
|     });
 | |
| 
 | |
|     test("returned value must be undefined if the property is a non-configurable accessor with no getter", () => {
 | |
|         let o = {};
 | |
|         Object.defineProperty(o, "foo", { configurable: false, set(_) {} });
 | |
| 
 | |
|         let p = new Proxy(o, {
 | |
|             get() {
 | |
|                 return 8;
 | |
|             },
 | |
|         });
 | |
| 
 | |
|         expect(() => {
 | |
|             p.foo;
 | |
|         }).toThrowWithMessage(
 | |
|             TypeError,
 | |
|             "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"
 | |
|         );
 | |
|     });
 | |
| });
 | |
| 
 | |
| test("Proxy handler that has the Proxy itself as its prototype", () => {
 | |
|     const handler = {};
 | |
|     const proxy = new Proxy({}, handler);
 | |
|     handler.__proto__ = proxy;
 | |
|     expect(() => {
 | |
|         proxy.foo;
 | |
|     }).toThrowWithMessage(InternalError, "Call stack size limit exceeded");
 | |
| });
 | 
