Added basic spy() and stub() functionality
This commit is contained in:
parent
084b751b5b
commit
5415f2ba95
3 changed files with 240 additions and 0 deletions
|
@ -1,7 +1,10 @@
|
|||
import Eltro from './lib/eltro.mjs'
|
||||
import assert from './lib/assert.mjs'
|
||||
import { spy, stub } from './lib/sinon.mjs'
|
||||
|
||||
export {
|
||||
Eltro,
|
||||
assert,
|
||||
spy,
|
||||
stub,
|
||||
}
|
||||
|
|
55
lib/sinon.mjs
Normal file
55
lib/sinon.mjs
Normal file
|
@ -0,0 +1,55 @@
|
|||
const indexMap = [
|
||||
'firstCall',
|
||||
'secondCall',
|
||||
'thirdCall',
|
||||
]
|
||||
|
||||
export function spy() {
|
||||
return stub()
|
||||
}
|
||||
|
||||
export function stub(returnFunc = null) {
|
||||
if (returnFunc && typeof(returnFunc) !== 'function') {
|
||||
throw new Error('stub() was called with non-function argument')
|
||||
}
|
||||
let returner = returnFunc ? returnFunc : null
|
||||
let calls = []
|
||||
let func = function(...args) {
|
||||
func.called = true
|
||||
calls.push(args)
|
||||
if (func.callCount < indexMap.length) {
|
||||
func[indexMap[func.callCount]] = args
|
||||
}
|
||||
func.callCount++
|
||||
if (returner) {
|
||||
return returner(...args)
|
||||
}
|
||||
}
|
||||
func.called = false
|
||||
func.callCount = 0
|
||||
func.onCall = function(i) {
|
||||
return calls[i]
|
||||
}
|
||||
func.returns = function(data) {
|
||||
returner = function() { return data }
|
||||
}
|
||||
func.returnWith = function(returnFunc) {
|
||||
if (typeof(returnFunc) !== 'function') {
|
||||
throw new Error('stub() was called with non-function argument')
|
||||
}
|
||||
returner = returnFunc
|
||||
}
|
||||
func.throws = function(data) {
|
||||
returner = function() { throw data }
|
||||
}
|
||||
func.resolves = function(data) {
|
||||
returner = function() { return Promise.resolve(data) }
|
||||
}
|
||||
func.rejects = function(data) {
|
||||
returner = function() { return Promise.reject(data) }
|
||||
}
|
||||
for (let i = 0; i < indexMap.length; i++) {
|
||||
func[indexMap[i]] = null
|
||||
}
|
||||
return func
|
||||
}
|
182
test/sinon.test.mjs
Normal file
182
test/sinon.test.mjs
Normal file
|
@ -0,0 +1,182 @@
|
|||
import assert from '../lib/assert.mjs'
|
||||
import t from '../lib/eltro.mjs'
|
||||
import { spy, stub } from '../index.mjs'
|
||||
|
||||
[spy, stub].forEach(function(tester, i) {
|
||||
t.describe(`#${i === 0 ? 'spy' : 'stub'}()`, function() {
|
||||
t.test('should keep track of call count', function() {
|
||||
let spyer = tester()
|
||||
assert.strictEqual(spyer.callCount, 0)
|
||||
assert.notOk(spyer.called)
|
||||
assert.strictEqual(spyer.firstCall, null)
|
||||
assert.strictEqual(spyer.secondCall, null)
|
||||
assert.strictEqual(spyer.thirdCall, null)
|
||||
|
||||
spyer()
|
||||
assert.strictEqual(spyer.callCount, 1)
|
||||
assert.ok(spyer.called)
|
||||
assert.deepStrictEqual(spyer.firstCall, [])
|
||||
assert.strictEqual(spyer.secondCall, null)
|
||||
assert.strictEqual(spyer.thirdCall, null)
|
||||
|
||||
spyer()
|
||||
assert.strictEqual(spyer.callCount, 2)
|
||||
assert.ok(spyer.called)
|
||||
assert.deepStrictEqual(spyer.firstCall, [])
|
||||
assert.deepStrictEqual(spyer.secondCall, [])
|
||||
assert.strictEqual(spyer.thirdCall, null)
|
||||
|
||||
spyer()
|
||||
assert.strictEqual(spyer.callCount, 3)
|
||||
assert.ok(spyer.called)
|
||||
assert.deepStrictEqual(spyer.firstCall, [])
|
||||
assert.deepStrictEqual(spyer.secondCall, [])
|
||||
assert.deepStrictEqual(spyer.thirdCall, [])
|
||||
|
||||
spyer()
|
||||
assert.strictEqual(spyer.callCount, 4)
|
||||
})
|
||||
|
||||
t.test('should keep track of arguments used to call', function() {
|
||||
const assertFirstArgs = 'asdf'
|
||||
const assertSecondArgs = { a: 1 }
|
||||
const assertThirdArgs = [{ b: 1 }, { c: 2 }]
|
||||
let spyer = tester()
|
||||
assert.notOk(spyer.called)
|
||||
|
||||
spyer(assertFirstArgs)
|
||||
spyer(assertSecondArgs)
|
||||
spyer(assertThirdArgs[0], assertThirdArgs[1])
|
||||
assert.strictEqual(spyer.callCount, 3)
|
||||
|
||||
assert.strictEqual(spyer.onCall(0)[0], assertFirstArgs)
|
||||
assert.strictEqual(spyer.onCall(1)[0], assertSecondArgs)
|
||||
assert.strictEqual(spyer.onCall(2)[0], assertThirdArgs[0])
|
||||
assert.strictEqual(spyer.onCall(2)[1], assertThirdArgs[1])
|
||||
|
||||
assert.strictEqual(spyer.firstCall[0], assertFirstArgs)
|
||||
assert.strictEqual(spyer.secondCall[0], assertSecondArgs)
|
||||
assert.strictEqual(spyer.thirdCall[0], assertThirdArgs[0])
|
||||
assert.strictEqual(spyer.thirdCall[1], assertThirdArgs[1])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
t.describe('#stub()', function() {
|
||||
t.test('should support returns', function() {
|
||||
const assertInput = { a : 1 }
|
||||
const assertReturns = { b: 3 }
|
||||
let s = stub()
|
||||
assert.strictEqual(s(), undefined)
|
||||
s.returns(assertReturns)
|
||||
assert.strictEqual(s(assertInput), assertReturns)
|
||||
assert.ok(s.called)
|
||||
assert.strictEqual(s.callCount, 2)
|
||||
assert.strictEqual(s.secondCall[0], assertInput)
|
||||
})
|
||||
|
||||
t.test('should support throws', function() {
|
||||
const assertInput = { a : 1 }
|
||||
const assertThrows = new Error('testety test')
|
||||
let s = stub()
|
||||
assert.strictEqual(s(), undefined)
|
||||
s.throws(assertThrows)
|
||||
assert.throws(function() {
|
||||
s(assertInput)
|
||||
}, assertThrows)
|
||||
assert.ok(s.called)
|
||||
assert.strictEqual(s.callCount, 2)
|
||||
assert.strictEqual(s.secondCall[0], assertInput)
|
||||
})
|
||||
|
||||
t.test('should support resolves', async function() {
|
||||
const assertInput = { a : 1 }
|
||||
const assertReturns = { b: 3 }
|
||||
let s = stub()
|
||||
assert.strictEqual(s(), undefined)
|
||||
s.resolves(assertReturns)
|
||||
let promiser = s(assertInput)
|
||||
assert.ok(promiser.then)
|
||||
assert.strictEqual(typeof(promiser.then), 'function')
|
||||
let output = await promiser
|
||||
assert.strictEqual(output, assertReturns)
|
||||
})
|
||||
|
||||
t.test('should support rejects', async function() {
|
||||
const assertInput = { a : 1 }
|
||||
const assertReturns = { b: 3 }
|
||||
let s = stub()
|
||||
assert.strictEqual(s(), undefined)
|
||||
s.rejects(assertReturns)
|
||||
let promiser = s(assertInput)
|
||||
assert.ok(promiser.then)
|
||||
assert.strictEqual(typeof(promiser.then), 'function')
|
||||
let output = await assert.isRejected(promiser)
|
||||
assert.strictEqual(output, assertReturns)
|
||||
})
|
||||
|
||||
t.test('should support custom function overwrite', async function() {
|
||||
const assertInput = { a : 1 }
|
||||
const assertReturns = { b: 3 }
|
||||
let ourCallCount = 50
|
||||
let s = stub(function(input) {
|
||||
ourCallCount++
|
||||
assert.strictEqual(input, assertInput)
|
||||
return assertReturns
|
||||
})
|
||||
assert.strictEqual(s(assertInput), assertReturns)
|
||||
assert.ok(s.called)
|
||||
assert.strictEqual(s.callCount, 1)
|
||||
assert.strictEqual(ourCallCount, 51)
|
||||
assert.strictEqual(s.firstCall[0], assertInput)
|
||||
|
||||
assert.throws(function() {
|
||||
s(null)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('should support custom function overwrite after the fact', async function() {
|
||||
const assertInput = { a : 1 }
|
||||
const assertReturns = { b: 3 }
|
||||
let ourCallCount = 0
|
||||
let s = stub()
|
||||
assert.strictEqual(s(null), undefined)
|
||||
s.returnWith(function(input) {
|
||||
ourCallCount++
|
||||
assert.strictEqual(input, assertInput)
|
||||
return assertReturns
|
||||
})
|
||||
assert.strictEqual(s(assertInput), assertReturns)
|
||||
assert.ok(s.called)
|
||||
assert.strictEqual(s.callCount, 2)
|
||||
assert.strictEqual(ourCallCount, 1)
|
||||
assert.strictEqual(s.secondCall[0], assertInput)
|
||||
|
||||
assert.throws(function() {
|
||||
s(null)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('should throw if parameter is something else than a function', function() {
|
||||
assert.ok(stub(null))
|
||||
assert.ok(stub(0))
|
||||
assert.ok(stub(''))
|
||||
assert.strictEqual(stub(null)(), undefined)
|
||||
assert.strictEqual(stub(0)(), undefined)
|
||||
assert.strictEqual(stub('')(), undefined)
|
||||
assert.throws(function() { stub([]) })
|
||||
assert.throws(function() { stub({}) })
|
||||
assert.throws(function() { stub(123) })
|
||||
assert.throws(function() { stub('asdf') })
|
||||
})
|
||||
|
||||
t.test('should throw if returnWith is called with something else than a function', function() {
|
||||
assert.throws(function() { stub().returnWith(0) })
|
||||
assert.throws(function() { stub().returnWith('') })
|
||||
assert.throws(function() { stub().returnWith(null) })
|
||||
assert.throws(function() { stub().returnWith([]) })
|
||||
assert.throws(function() { stub().returnWith({}) })
|
||||
assert.throws(function() { stub().returnWith(123) })
|
||||
assert.throws(function() { stub().returnWith('asdf') })
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue