JSlang.dev

JavaScript Deep Dives with Wolfram. Since 2015
Inclusive, Test-Driven, Spec-Focused, Collaborative.

October 17, 2024
TestsSource
#76 Proxy

Source Code

The source code we wrote during the event.

import assert from 'assert';

describe('Are you mutating the original object?', () => {
  it('when I proxy an objects property I can still read the value of the original object', () => {
    const obj = {x: 42};
    const proxy = new Proxy(obj, {});
    assert.strictEqual(proxy.x, obj.x);
  });
  it('a proxy with an empty handler mutates the original object', () => {
    const obj = {x: 42};
    const proxy = new Proxy(obj, {});
    proxy.x = 10;
    assert.strictEqual(obj.x, 10);
  });
  it('proxying an object with an non-empty handler does mutate the original', () => {
    const obj = {x: 42};
    const proxy = new Proxy(obj, {get() {return 25}});
    proxy.x = 10;
    assert.strictEqual(obj.x, 10);
  });
  it('proxying an object with an non-empty handler applies to all properties', () => {
    const obj = {x: 42, y: 23};
    const proxy = new Proxy(obj, {get() {return 25}});
    assert.deepEqual(proxy, {x: 25, y: 25});
  });
  it('proxying the getter also applies to non-initialized properties', () => {
    const obj = {};
    const proxy = new Proxy(obj, {get() {return 25}});
    assert.strictEqual(proxy.foo, 25);
  });
});

describe('Can a proxy setter/getter be async?', () => {
  it('a sync setter handler in a proxy just `return true` does not mutate the original object', () => {
    const obj = {x: 42};
    const proxy = new Proxy(obj, {
      set() {return true}
    });
    proxy.x = 23;
    assert.strictEqual(obj.x, 42);
  });
  it('a sync setter handler mutates the original object', () => {
    const obj = {};
    const proxy = new Proxy(obj, {
      set(target, prop, value) {
        target[prop] = value + 1;
        return true;
      }
    });
    proxy.x = 5;
    assert.strictEqual(obj.x, 6);
  });
  it('an async setter handler ????', async () => {
    const obj = {};
    const proxy = new Proxy(obj, {
      async set(target, prop, value) {
        const delayedValue = new Promise(
          (resolve) => setTimeout(() => resolve(42), 500)
        );
        target[prop] = value + await delayedValue;
        return true;
      }
    });
    proxy.x = 1;
    // assert.strictEqual(await obj.x, 42);
    
    await (new Promise(
      (resolve) => setTimeout(resolve, 600)));
    
    assert.strictEqual(await obj.x, 43);
  });
});