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 support reset', 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) assert.strictEqual(spyer.lastCall, null) spyer(1) spyer(2) spyer(3) spyer(4) spyer(5) assert.notStrictEqual(spyer.callCount, 0) assert.ok(spyer.called) assert.notStrictEqual(spyer.firstCall, null) assert.notStrictEqual(spyer.secondCall, null) assert.notStrictEqual(spyer.thirdCall, null) assert.notStrictEqual(spyer.lastCall, null) assert.strictEqual(spyer.lastCall[0], 5) spyer.reset() assert.strictEqual(spyer.callCount, 0) assert.notOk(spyer.called) assert.strictEqual(spyer.firstCall, null) assert.strictEqual(spyer.secondCall, null) assert.strictEqual(spyer.thirdCall, null) assert.strictEqual(spyer.lastCall, null) }) 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) assert.strictEqual(spyer.lastCall[0], assertFirstArgs) spyer(assertSecondArgs) assert.strictEqual(spyer.lastCall[0], assertSecondArgs) spyer(assertThirdArgs[0], assertThirdArgs[1]) assert.strictEqual(spyer.lastCall[0], assertThirdArgs[0]) assert.strictEqual(spyer.lastCall[1], assertThirdArgs[1]) assert.strictEqual(spyer.callCount, 3) assert.strictEqual(spyer.getCall(0)[0], assertFirstArgs) assert.strictEqual(spyer.getCall(1)[0], assertSecondArgs) assert.strictEqual(spyer.getCall(2)[0], assertThirdArgs[0]) assert.strictEqual(spyer.getCall(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.test('should support searching for a 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]) let call = spyer.findCall((args) => args[0] === assertSecondArgs) assert.strictEqual(spyer.secondCall, call) assert.strictEqual(call[0], assertSecondArgs) call = spyer.findCall((args) => args[0].b === assertThirdArgs[0].b) assert.strictEqual(spyer.thirdCall, call) assert.strictEqual(call[0], assertThirdArgs[0]) assert.strictEqual(call[1], assertThirdArgs[1]) call = spyer.findCall((args) => typeof args[0] === 'string') assert.strictEqual(spyer.firstCall, call) assert.strictEqual(call[0], assertFirstArgs) call = spyer.findCall(() => false) assert.strictEqual(call, null) }) }) }) 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') }) }) t.test('should support reset on returning', function() { let s = stub() assert.strictEqual(s.callCount, 0) assert.notOk(s.called) assert.strictEqual(s.firstCall, null) assert.strictEqual(s.secondCall, null) assert.strictEqual(s.thirdCall, null) assert.strictEqual(s(), undefined) s.returns('test') assert.strictEqual(s(1), 'test') assert.strictEqual(s(2), 'test') assert.strictEqual(s(3), 'test') assert.strictEqual(s(4), 'test') assert.strictEqual(s(5), 'test') assert.strictEqual(s.lastCall[0], 5) assert.notStrictEqual(s.callCount, 0) assert.ok(s.called) assert.notStrictEqual(s.firstCall, null) assert.notStrictEqual(s.secondCall, null) assert.notStrictEqual(s.thirdCall, null) s.reset() assert.strictEqual(s.callCount, 0) assert.notOk(s.called) assert.strictEqual(s.firstCall, null) assert.strictEqual(s.secondCall, null) assert.strictEqual(s.thirdCall, null) assert.strictEqual(s(), undefined) s.returnWith(function() { return 'yes' }) assert.strictEqual(s(), 'yes') s.reset() assert.strictEqual(s(), undefined) }) t.test('reset should default though to constructor returner', function() { let s = stub(function() { return 'success' }) assert.strictEqual(s.callCount, 0) assert.notOk(s.called) assert.strictEqual(s.firstCall, null) assert.strictEqual(s.secondCall, null) assert.strictEqual(s.thirdCall, null) assert.strictEqual(s(), 'success') s.returns('test') assert.strictEqual(s(1), 'test') assert.strictEqual(s(2), 'test') assert.strictEqual(s(3), 'test') assert.strictEqual(s(4), 'test') assert.strictEqual(s(5), 'test') assert.notStrictEqual(s.callCount, 0) assert.ok(s.called) assert.notStrictEqual(s.firstCall, null) assert.notStrictEqual(s.secondCall, null) assert.notStrictEqual(s.thirdCall, null) s.reset() assert.strictEqual(s.callCount, 0) assert.notOk(s.called) assert.strictEqual(s.firstCall, null) assert.strictEqual(s.secondCall, null) assert.strictEqual(s.thirdCall, null) assert.strictEqual(s(), 'success') s.returnWith(function() { return 'yes' }) assert.strictEqual(s(), 'yes') s.reset() assert.strictEqual(s(), 'success') }) t.test('should support chaining', function() { let s = stub() s.reset() .returnWith(function() {}) .resolves(null) .rejects(null) .throws(null) .returns(null) .reset() }) t.test('onCall should throw if not a number', function() { let s = stub() assert.throws(function() { s.onCall(undefined) }) assert.throws(function() { s.onCall([]) }) assert.throws(function() { s.onCall({}) }) assert.throws(function() { s.onCall('') }) assert.throws(function() { s.onCall('asdf') }) }) t.test('should support arbitrary call returns', function() { let s = stub() s.onCall(0).returns(1) .onCall(1).returns(2) assert.strictEqual(s(), 1) assert.strictEqual(s(), 2) s.reset() assert.strictEqual(s(), undefined) assert.strictEqual(s(), undefined) }) t.test('should send propert arguments in defined calls', function() { const assertInput = { a : 1 } const assertReturns = { b: 3 } let ourCallCount = 0 let s = stub() s.onCall(3).returnWith(function(input) { ourCallCount++ assert.strictEqual(input, assertInput) return assertReturns }) assert.strictEqual(s(null), undefined) assert.strictEqual(s(null), undefined) assert.strictEqual(s(null), undefined) assert.strictEqual(s(assertInput), assertReturns) assert.ok(s.called) assert.strictEqual(s.callCount, 4) assert.strictEqual(ourCallCount, 1) assert.strictEqual(s.getCall(3)[0], assertInput) assert.strictEqual(s(null), undefined) }) })