1.0.3 • Published 3 years ago

spy-property-reads v1.0.3

Weekly downloads
-
License
ISC
Repository
github
Last release
3 years ago

Spy-property-reads

JavaScript offers various ways for an object to store another object. This library give a uniform way to trap the various ways in which properties are extracted from an object.

Usage

Spy property getters

const { spyPropertyReads } = require('spy-property-reads')

const o = { a: 42, b: 42 }

const spyCallback = function(source, query, getResult) {
  const result = getResult()
  console.log({ query, result })
  return result
}

const handler = spyPropertyReads(spyCallback)
const spy = new Proxy(o, handler)

// accessing 42 using the property 'a'
spy.a
// => 42
//  console.log() => { query: 'get("a")', result: 42 } 

spy.b
// => 42
//  console.log() => { query: 'get("b")', result: 42 } 

Spy functions return values

const { spyPropertyReads } = require('spy-property-reads')

const o = function() { return 42 }

const spyCallback = function(source, query,  getResult) {
  const result = getResult()
  console.log({ query, result })
  return result
}

const handler = spyPropertyReads(spyCallback)
const spy = new Proxy(o, handler)

// accessing 42 by calling the function
spy()
// => 42
//  console.log() => { query: 'apply()', result: 42 } 

Spy property descriptors

const { spyPropertyReads } = require('spy-property-reads')

const o = {
  a: 42,
  get b() { return 10 }
}

const spyCallback = function(source, query,  getResult) {
  const result = getResult()
  console.log({ query, result })
  return result
}

const handler = spyPropertyReads(spyCallback)
const spy = new Proxy(o, handler)

Object.getOwnPropertyDescriptor(spy, 'a').value
// => 42
//  console.log() => { query: 'getOwnPropertyDescriptor("a").value', result: 42 } 

Object.getOwnPropertyDescriptor(spy, 'b').get()
// => 10
//  console.log() => { query: 'getOwnPropertyDescriptor("b").get()', result: 10 } 

Spy access to the prototype

const { spyPropertyReads } = require('spy-property-reads')

const o = Object.create({ foo: 'bar' })

const spyCallback = function(source, query,  getResult) {
  const result = getResult()
  console.log({ query, result })
  return result
}

const handler = spyPropertyReads(spyCallback)
const spy = new Proxy(o, handler)

Object.getPrototypeOf(spy)
// => { foo: 'bar' }
//  console.log() => { query: 'getPrototypeOf()', result: { foo: 'bar' } } 

Composing proxy handlers

The proxy handlers created by 'spy-property-reads' can wrap other proxy handlers. This allows composition of 'proxy enhancers' to create sophisticated proxy behavior.

const { spyPropertyReads } = require('spy-property-reads')

const o = {}
// 1 - every property return 42
const handler1 = { get: () => 42 }

const spyCallback = function(source, query, getResult) {
  const result = getResult()
  console.log({ query, result })
  return result
}
// 2 - spy on property reads
const handler2 = spyPropertyReads(spyCallback, handler1)

// 3 - add un-spyable property
const handler3 = {
  ...handler2,
  get: function(target, prop) {
    if (prop === 'secret') { return 'foo' }
    else { return handler2.get(...arguments) }
  }
}

const spy = new Proxy(o, handler3)

spy.a
// => 42
//  console.log() => { query: 'get("a")', result: 42 } 
spy.b
// => 42
//  console.log() => { query: 'get("b")', result: 42 } 
spy.c
// => 42
//  console.log() => { query: 'get("c")', result: 42 } 
spy.secret
// => foo
// No call to "console.log"

API

spyPropertyReads(callback, handler)

callback

A function which takes 3 arguments and returns the property querried.

Arguments:

1 - source: the object being spied 2 - query: a string representation of the function which triggered the callback 3 - getResult: a function which returns the property querried.

The reading operation on the spied object will return the value returned by the callback. To keep the return value unchanged, return the value returned by getResult(). Aternatively, we can modify the value, substitute it, or not call getResult at all and return something totally different.

handler (optional)

A proxy handler which will be wrapped. This permits to create sophisticated proxy behaviors by composing simple handlers together.

Return value

This function returns a proxy handler. A proxy can be instanciated with this handler or with another handler which wraps it to adds more features.