UNPKG

1.49 kBPlain TextView Raw
1import * as theredoc from 'theredoc'
2import _ from '../wrap/lodash'
3import log from '../log'
4import tdFunction from '../function'
5import store from '../store'
6
7export default function proxy<T> (name: string, { excludeMethods } : { excludeMethods?: string[] } = {}) : T {
8 ensureProxySupport(name)
9 return new Proxy({}, generateHandler(name, excludeMethods))
10}
11
12const ensureProxySupport = (name) => {
13 if (typeof Proxy === 'undefined') {
14 log.error('td.object', theredoc`\
15 The current runtime does not have Proxy support, which is what
16 testdouble.js depends on when a string name is passed to \`td.object()\`.
17
18 More details here:
19 https://github.com/testdouble/testdouble.js/blob/master/docs/4-creating-test-doubles.md#objectobjectname
20
21 Did you mean \`td.object(['${name}'])\`?
22 `)
23 }
24}
25
26const generateHandler = (internalName, excludeMethods) => ({
27 get (target, propKey) {
28 return generateGet(target, propKey, internalName, excludeMethods)
29 }
30})
31
32const generateGet = (target, propKey, internalName, excludeMethods) => {
33 if (!Object.prototype.hasOwnProperty.call(target, propKey) &&
34 !_.includes(excludeMethods, propKey)) {
35 const nameWithProp = `${internalName || ''}.${String(propKey)}`
36 const tdFunc = tdFunction(nameWithProp)
37 const tdFuncProxy = new Proxy(tdFunc, generateHandler(nameWithProp, excludeMethods))
38 store.registerAlias(tdFunc, tdFuncProxy)
39 target[propKey] = tdFuncProxy
40 }
41 return target[propKey]
42}