Skip to content

Instantly share code, notes, and snippets.

@aeinbu
Created May 8, 2020 07:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aeinbu/b4626b8999b6b55cddb0cd7defeda708 to your computer and use it in GitHub Desktop.
Save aeinbu/b4626b8999b6b55cddb0cd7defeda708 to your computer and use it in GitHub Desktop.
Makes new object that guards against executing methods and changing properties when not in debug mode
import { wrapInDisablerProxyFactory } from "./wrapInDebugModeProxy"
describe("Enable/disable functions", () => {
const obj = {
flipTheFlag(target) {
target.flag = true
},
inner: {
anotherFlipTheFlag(target) {
target.flag = true
}
}
}
test("Turns off any functions when not in debug mode", () => {
const wrapInDebugModeProxy = wrapInDisablerProxyFactory(() => false)
const debug = wrapInDebugModeProxy(obj)
const target = { flag: false }
debug.flipTheFlag(target)
expect(target.flag).toBe(false)
})
test("Turns on any functions when in debug mode", () => {
const wrapInDebugModeProxy = wrapInDisablerProxyFactory(() => true)
const debug = wrapInDebugModeProxy(obj)
const target = { flag: false }
debug.flipTheFlag(target)
expect(target.flag).toBe(true)
})
test("Turns off any functions inside nested objects when not in debug mode", () => {
const wrapInDebugModeProxy = wrapInDisablerProxyFactory(() => false)
const debug = wrapInDebugModeProxy(obj)
const target = { flag: false }
debug.inner.anotherFlipTheFlag(target)
expect(target.flag).toBe(false)
})
test("Turns on any functions inside nested objects when in debug mode", () => {
const wrapInDebugModeProxy = wrapInDisablerProxyFactory(() => true)
const debug = wrapInDebugModeProxy(obj)
const target = { flag: false }
debug.inner.anotherFlipTheFlag(target)
expect(target.flag).toBe(true)
})
})
describe("Enable/disable setting properties", () => {
test("Changing a property is not possible when in debug mode", () => {
const wrapInDebugModeProxy = wrapInDisablerProxyFactory(() => false)
const obj = { flag: false }
const debug = wrapInDebugModeProxy(obj)
debug.flag = true
expect(debug.flag).toBe(false)
expect(obj.flag).toBe(false)
})
test("Changing a property is possible when in debug mode", () => {
const wrapInDebugModeProxy = wrapInDisablerProxyFactory(() => true)
const obj = { flag: false }
const debug = wrapInDebugModeProxy(obj)
debug.flag = true
expect(debug.flag).toBe(true)
expect(obj.flag).toBe(true)
})
})
import { getIsDebugMode } from "src/infrastructure/frames/DebugContext"
const noop = () => { }
/**
* wrapInDisablerProxyFactory is a testable abstraction for wrapInDebuggerModeProxy
* Makes new object that guards against executing methods and changing properties when `predicate()` returns false
* @param enableWhenTruePredicate method to determine wether calling functions and setting properties is enabled (Ie. when debug mode is on or off)
*/
export const wrapInDisablerProxyFactory = (
enableWhenTruePredicate: () => boolean
) => <T extends object>(
orig: T
): T => {
if (typeof orig !== "object") {
return orig
}
return new Proxy(orig, {
get(target: any, property: string) {
const isDebug = enableWhenTruePredicate()
if (property in target) {
if (typeof target[property] === "function") {
return isDebug ? target[property] : noop
}
return wrapInDisablerProxyFactory(enableWhenTruePredicate)(target[property])
}
return undefined
},
set(target: any, property: string, value: any) {
const isDebug = enableWhenTruePredicate()
if (property in target && isDebug) {
target[property] = value
}
return true
}
}) as T
}
/**
* Makes new object that guards against executing methods and changing properties when not in debug mode
* Example use:
* ```
* const debug = wrapInDebugModeProxy(console)
* debug.log("any functions from console are available on debug, but they are disabled if debugging is turned of")
* ```
* @param orig the original object to be wrapped
*/
export const wrapInDebugModeProxy = wrapInDisablerProxyFactory(getIsDebugMode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment