import * as Sinon from 'sinon' import * as _ from 'lodash' export interface ClassStub extends Sinon.SinonStub { stubMethod(name: string): Sinon.SinonStub setProp(name: string, val: any) } export interface ClassMock extends Sinon.SinonMock { object: T } export interface ClassSpy extends Sinon.SinonSpy { spyMethod(name: string): Sinon.SinonSpy } export class SinonHelper implements Sinon.SinonSandbox { clock: Sinon.SinonFakeTimers requests: Sinon.SinonFakeXMLHttpRequest server: Sinon.SinonFakeServer spy: Sinon.SinonSpyStatic stub: Sinon.SinonStub mock: Sinon.SinonMockStatic useFakeTimers: Sinon.SinonFakeTimersStatic useFakeXMLHttpRequest: Sinon.SinonFakeXMLHttpRequestStatic useFakeServer: () => Sinon.SinonFakeServer restore: () => void stubClass(instanceClass: Function): T & ClassStub { let stubbed = this.stub(_.clone(instanceClass.prototype)) as T & ClassStub if (typeof stubbed.stubMethod === 'function') throw new Error('have function named stubMethod, conflicts!') if (typeof stubbed.setProp === 'function') throw new Error('have function named stubMethod, conflicts!') stubbed.setProp = function(name: string, val: any) { return stubbed[name] = val } stubbed.stubMethod = function(name: string): Sinon.SinonStub { return stubbed[name] as Sinon.SinonStub } return stubbed } mockClass(instanceClass: Function): ClassMock { let TmpCons = () => {} TmpCons.prototype = instanceClass.prototype let inst = new TmpCons let mocked = this.mock(inst) as ClassMock mocked.object = inst return mocked } spyClass(instanceClass: Function): ClassSpy { let spied = this.spy(_.clone(instanceClass.prototype)) as T & ClassSpy if (typeof spied.spyMethod === 'function') throw new Error('have function named spyMethod, conflicts!') spied.spyMethod = function(name: string): Sinon.SinonSpy { return spied[name] as Sinon.SinonSpy } return spied } } function newContext(): SinonHelper { let sandbox = Sinon.sandbox.create() let helper = new SinonHelper helper = _.extend(helper, sandbox) as SinonHelper after(function() { sandbox.restore() }) return helper } export default newContext