spy-property-writes
v1.0.3
Published
Spy write operations on an object
Downloads
10
Readme
spy-property-writes
JavaScript offers various ways for an object to store another object. This library gives a uniform way to spy the various ways in which properties are passed to an object. This library also gives the power to change the values of these read operations. This library is not concerned by how the values are stored in the object but only how they are passed to it.
Usage
Spy property setters
const { spyPropertyWrites } = require('spy-property-writes')
const o = {}
const spyCallback = function(source, query, value, write) {
console.log({ query, value })
write(value)
}
const handler = spyPropertyWrites(spyCallback)
const spy = new Proxy(o, handler)
spy.a = 42
// console.log() => { query: 'set("a")', value: 42 }
Spy function arguments
const { spyPropertyWrites } = require('spy-property-writes')
const o = function() {}
const spyCallback = function(source, query, value, write) {
console.log({ query, value })
write(value)
}
const handler = spyPropertyWrites(spyCallback)
const spy = new Proxy(o, handler)
spy.bind({ foo: 'bar' })(42, 43)
// console.log() => { query: 'thisArgument(apply)', value: { foo: 'bar' } }
// console.log() => { query: 'argument1(apply)', 42 }
// console.log() => { query: 'argument2(apply)', 43 }
Spy constructor arguments
const { spyPropertyWrites } = require('spy-property-writes')
const o = function() {}
const spyCallback = function(source, query, value, write) {
console.log({ query, value })
write(value)
}
const handler = spyPropertyWrites(spyCallback)
const spy = new Proxy(o, handler)
new spy(42, 43)
// console.log() => { query: 'argument1(constructor)', value: 42 }
// console.log() => { query: 'argument2(constructor)', value: 43 }
DefineProperty
const { spyPropertyWrites } = require('spy-property-writes')
const o = function() {}
const spyCallback = function(source, query, value, write) {
console.log({ query, value })
write(value)
}
const handler = spyPropertyWrites(spyCallback)
const spy = new Proxy(o, handler)
Object.defineProperty(spy, 'a', { value: 42 })
// console.log() => { query: 'defineProperty("a").value', value: 42 }
Object.defineProperty(spy, 'b', { get() { return 42 } })
o.b
// console.log() => { query: 'defineProperty("a").get()', value: 42 }
getOwnPropertyDescriptor.set
const { spyPropertyWrites } = require('spy-property-writes')
const o = { set a() {} }
const spyCallback = function(source, query, value, write) {
console.log({ query, value })
write(value)
}
const handler = spyPropertyWrites(spyCallback)
const spy = new Proxy(o, handler)
Object.getOwnPropertyDescriptor(spy, 'a').set(42)
// console.log() => { query: 'getOwnPropertyDescriptor("a").set()', value: 42 }
SetPrototypeOf
const { spyPropertyWrites } = require('spy-property-writes')
const o = function() {}
const spyCallback = function(source, query, value, write) {
console.log({ query, value })
write(value)
}
const handler = spyPropertyWrites(spyCallback)
const spy = new Proxy(o, handler)
Object.setPrototypeOf(spy, { foo: 42 })
// console.log() => { query: 'setPrototypeOf()', value: { foo: 42 } }
Composing proxy handlers
The proxy handlers created by 'spy-property-writes' can wrap other proxy handlers. This allows composition of 'proxy enhancers' to create sophisticated proxy behavior.
const { spyPropertyWrites } = require('spy-property-reads')
const o = {}
// 1 - every property is doubled
const handler1 = { set: (target, prop, value, write) => target[prop] = value * 2 }
const spyCallback = function(source, query, value, write) {
console.log({ query, value })
write(value)
}
// 2 - spy on property reads
const handler2 = spyPropertyWrites(spyCallback, handler1)
// 3 - add un-spyable property
const handler3 = {
...handler2,
set: function(target, prop, value, write) {
if (prop === 'secret') { target[prop] = value }
else { return handler2.set(...arguments) }
}
}
const spy = new Proxy(o, handler3)
spy.a = 42
// console.log() => { query: 'set("a")', result: 42 }
spy.a // 84
spy.secret = 43
// No call to "console.log"