import { expect } from 'chai'
import * as sinon from 'sinon'
import { withTimeout } from '../../../lib'

const timeoutPromise = (timeout: number) => new Promise(res => {
    setTimeout(res, timeout)
})

describe('util -> support -> timeout -> withTimeout', () => {
    it('should call the on-time subscriber when promise resolves', async () => {
        const onTimeSpy = sinon.spy()
        const lateSpy = sinon.spy()
        const timeoutSpy = sinon.spy()
        await withTimeout(100, timeoutPromise(50))
            .onTime(onTimeSpy)
            .late(lateSpy)
            .timeout(timeoutSpy)
            .run()

        await timeoutPromise(100)

        expect(onTimeSpy.callCount).to.equal(1)
        expect(timeoutSpy.callCount).to.equal(0)
        expect(lateSpy.callCount).to.equal(0)
    })

    it('should call the late and timeout subscribers when promise resolves late', async () => {
        const onTimeSpy = sinon.spy()
        const lateSpy = sinon.spy()
        const timeoutSpy = sinon.spy()
        await withTimeout(50, timeoutPromise(100))
            .onTime(onTimeSpy)
            .late(lateSpy)
            .timeout(timeoutSpy)
            .run()

        await timeoutPromise(100)

        expect(onTimeSpy.callCount).to.equal(0)
        expect(timeoutSpy.callCount).to.equal(1)
        expect(lateSpy.callCount).to.equal(1)
    })

    it('should resolve the run() promise when the promise completes', async () => {
        const runSpy = sinon.spy()
        await withTimeout(50, timeoutPromise(10))
            .run()
            .then(runSpy)

        await timeoutPromise(100)

        expect(runSpy.callCount).to.be.equal(1)
    })
})