metaltest/lib/mock.js

56 lines
1.1 KiB
JavaScript

const capture = (actions, name, fn) => async (...args) => {
const count = actions.reduce((count, curr) => {
if (curr.name === name) return count + 1
return count
}, 1)
try {
const result = await fn(...args, { count })
actions.push({ name, args, result })
return result
} catch (error) {
actions.push({ name, args, result: error })
throw error
}
}
const mock = async (mocks, fn) => {
const olds = {}
const actions = []
for (const mock of mocks) {
if (mock.package in olds === false) olds[mock.package] = {}
const old = olds[mock.package]
for (const name in mock.funcs) {
//Save
old[name] = mock.package[name]
//Capture
mock.package[name] = capture(actions, name, mock.funcs[name])
}
}
//Restore even when an error occurs
//Like with a failed assert
try {
await fn()
} catch (error) {
throw error
} finally {
for (const mock of mocks) {
const old = olds[mock.package]
for (const name in mock.funcs) {
//Restore
mock.package[name] = old[name]
}
}
}
return actions
}
export { mock }