Skip to content

Commit

Permalink
Bug fix: interceptAnyObject used in monitorAPI (#259)
Browse files Browse the repository at this point in the history
* Bug fix: interceptAnyObject used in monitorAPI

* remove ts-ignore
  • Loading branch information
ShirShintel authored Oct 1, 2024
1 parent f75f355 commit 8b95cf2
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 23 deletions.
47 changes: 26 additions & 21 deletions src/interceptAnyObject.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,39 @@
import _ from 'lodash'

export type FunctionInterceptor = (name: string, original: Function) => Function
export type PropertyInterceptor = (name: string, original: any) => any

export interface AnyObject {
[key: string]: any
}
export type FunctionInterceptor = (name: string, original: Function) => Function
export type PropertyInterceptor = (name: string, original: any) => any
const isPlainObject = (value: any): value is AnyObject => _.isPlainObject(value)

export function interceptAnyObject<T extends AnyObject>(
export function interceptAnyObject<T>(
inner: T,
onFunction?: FunctionInterceptor,
onProperty?: PropertyInterceptor,
includeNestedLevels?: number
): T {
const result = _.mapValues(inner, (original, key) => {
if (typeof original === 'function' && typeof onFunction === 'function') {
return onFunction(key, original)
}
if (includeNestedLevels && _.isObjectLike(original)) {
return interceptAnyObject(
original,
onFunction ? (name, func) => onFunction(`${key}.${name}`, func) : undefined,
onProperty ? (name, value) => onProperty(`${key}.${name}`, value) : undefined,
includeNestedLevels - 1
)
}
if (typeof onProperty === 'function') {
return onProperty(key, original)
}
return original
}) as T
if (isPlainObject(inner)) {
const result = _.mapValues(inner, (original, key) => {
if (typeof original === 'function' && typeof onFunction === 'function') {
return onFunction(key, original)
}
if (includeNestedLevels && _.isPlainObject(original)) {
return interceptAnyObject(
original,
onFunction ? (name, func) => onFunction(`${key}.${name}`, func) : undefined,
onProperty ? (name, value) => onProperty(`${key}.${name}`, value) : undefined,
includeNestedLevels - 1
)
}
if (typeof onProperty === 'function') {
return onProperty(key, original)
}
return original
}) as T

return result
return result
}
return inner
}
2 changes: 1 addition & 1 deletion src/monitorAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function monitorAPI<TAPI>(
: () => true

return interceptAnyObject(
api as any,
api,
(funcName, originalFunc) => {
if (!shouldMonitor(funcName)) {
console.log('DISABLED MONITORING>', funcName)
Expand Down
32 changes: 31 additions & 1 deletion test/interceptAnyObject.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from 'lodash'
import { interceptAnyObject, FunctionInterceptor, PropertyInterceptor } from '../src/interceptAnyObject'
import { FunctionInterceptor, interceptAnyObject, PropertyInterceptor } from '../src/interceptAnyObject'

type LogSpy = jest.Mock<void, string[]>

Expand Down Expand Up @@ -184,4 +184,34 @@ describe('interceptAnyObject', () => {
])
expect(nestedFuncLevelTwoRetVal).toBe(12345)
})

it('should not intercept non object-like values - functions', () => {
const spy: LogSpy = jest.fn()
function real() {
return 'real'
}
const intercepted = interceptAnyObject(real, createFuncInterceptor(spy), createPropInterceptor(spy))
expect(intercepted()).toBe('real')
})

it('should not intercept non object-like values - primitives', () => {
const spy: LogSpy = jest.fn()
const real = 'real'
const intercepted = interceptAnyObject(real, createFuncInterceptor(spy), createPropInterceptor(spy))
expect(intercepted).toBe('real')
})

it('should not intercept non object-like values - arrays', () => {
const spy: LogSpy = jest.fn()
const real = ['real']
const intercepted = interceptAnyObject(real, createFuncInterceptor(spy), createPropInterceptor(spy))
expect(intercepted).toEqual(['real'])
})

it('should not intercept non object-like values - maps', () => {
const spy: LogSpy = jest.fn()
const real = new Map<string, string>([['key', 'value']])
const intercepted = interceptAnyObject(real, createFuncInterceptor(spy), createPropInterceptor(spy))
expect(intercepted.get('key')).toEqual('value')
})
})

0 comments on commit 8b95cf2

Please sign in to comment.