element-plus/packages/test-utils/define-getter.ts

46 lines
1.1 KiB
TypeScript
Raw Normal View History

2020-09-03 13:12:44 +08:00
import { isFunction, isUndefined } from 'lodash'
2020-09-02 17:44:14 +08:00
2020-09-03 13:12:44 +08:00
/**
*
* @param obj Object on which to add or modify the property.
* @param prop The property name
* @param value The value of `obj[prop]` or a getter
* @returns A restore function which can reset `obj[prop]`'s value or getter
*/
const defineGetter = (
obj: Record<string, any>,
prop: string,
value: any,
defaultValue?: any
) => {
2020-09-03 13:12:44 +08:00
let oldValue = defaultValue
const { get, configurable } = Object.getOwnPropertyDescriptor(obj, prop) || {}
if (isUndefined(defaultValue) && isUndefined(get)) {
try {
oldValue = obj[prop]
} catch {
throw new Error(
`TypeError: Illegal invocation. Cannot read ${prop} of '${obj}', '${obj}' might be a prototype, please specify default value instead.`
)
2020-09-03 13:12:44 +08:00
}
}
const oldGetter = get ?? (() => oldValue)
2020-09-02 17:44:14 +08:00
const getter = isFunction(value) ? value : () => value
2020-09-03 13:12:44 +08:00
Object.defineProperty(obj, prop, {
configurable: true,
get: getter,
})
return () => {
Object.defineProperty(obj, prop, {
configurable,
get: oldGetter,
})
}
2020-09-02 17:44:14 +08:00
}
export default defineGetter