276 lines
7.2 KiB
JavaScript
276 lines
7.2 KiB
JavaScript
import executeSequentially from '../../src/utils/executeSequentially'
|
|
|
|
describe('executeSequentially', () => {
|
|
it('should resolve if the list is empty', () => {
|
|
// given
|
|
const list = []
|
|
|
|
// when
|
|
return executeSequentially(list).then(() => {
|
|
// then
|
|
// it should resolve
|
|
})
|
|
})
|
|
|
|
it('should execute all the functions in the list', () => {
|
|
// given
|
|
const list = [jest.fn().mockReturnValue(Promise.resolve())]
|
|
|
|
// when
|
|
return executeSequentially(list).then(() => {
|
|
// then
|
|
expect(list[0]).toHaveBeenCalledTimes(1)
|
|
})
|
|
})
|
|
|
|
it('should wait for function to finish', () => {
|
|
// given
|
|
let finished = 0
|
|
|
|
const list = [
|
|
buildMockFunction({ timeout: 100, before: () => finished++ }),
|
|
buildMockFunction({ timeout: 50, before: () => finished++ })
|
|
]
|
|
|
|
// when
|
|
return executeSequentially(list).then(() => {
|
|
// then
|
|
expect(list[0]).toHaveBeenCalledTimes(1)
|
|
expect(list[1]).toHaveBeenCalledTimes(1)
|
|
expect(finished).toBe(2)
|
|
})
|
|
})
|
|
|
|
it('should return index of the function that failed (last function fails)', () => {
|
|
// given
|
|
const list = [buildMockFunction(), buildMockFunction(), buildMockFunction({ shouldFail: true })]
|
|
|
|
// when
|
|
return executeSequentially(list).then(
|
|
() => {
|
|
throw new Error('should not resolve')
|
|
},
|
|
([err, index]) => {
|
|
expect(index).toBe(2)
|
|
}
|
|
)
|
|
})
|
|
|
|
it('should return index of the function that failed (first function rejects)', () => {
|
|
// given
|
|
const list = [buildMockFunction({ shouldFail: true }), buildMockFunction(), buildMockFunction()]
|
|
|
|
// when
|
|
return executeSequentially(list).then(
|
|
() => {
|
|
throw new Error('should not resolve')
|
|
},
|
|
([err, index]) => {
|
|
expect(index).toBe(0)
|
|
}
|
|
)
|
|
})
|
|
|
|
it('should return index of the function that failed (first function throws)', () => {
|
|
// given
|
|
const list = [buildMockFunction({ shouldFail: true }), buildMockFunction(), buildMockFunction()]
|
|
|
|
// when
|
|
return executeSequentially(list).then(
|
|
() => {
|
|
throw new Error('should not resolve')
|
|
},
|
|
([err, index]) => {
|
|
expect(index).toBe(0)
|
|
}
|
|
)
|
|
})
|
|
|
|
it('should not execute the functions after the function that failed', () => {
|
|
// given
|
|
let finished = 0
|
|
|
|
const list = [
|
|
buildMockFunction({ shouldFail: true, before: () => finished++ }),
|
|
buildMockFunction(),
|
|
buildMockFunction()
|
|
]
|
|
|
|
// when
|
|
return executeSequentially(list).then(
|
|
() => {
|
|
throw new Error('should not resolve')
|
|
},
|
|
([err, index]) => {
|
|
expect(index).toBe(0)
|
|
expect(finished).toBe(1)
|
|
expect(list[0]).toHaveBeenCalledTimes(1)
|
|
expect(list[1]).toHaveBeenCalledTimes(0)
|
|
expect(list[2]).toHaveBeenCalledTimes(0)
|
|
}
|
|
)
|
|
})
|
|
|
|
it('should reject with the error of the failed function', () => {
|
|
// given
|
|
let finished = 0
|
|
const ERR = 'FN FAILED'
|
|
|
|
const list = [
|
|
buildMockFunction({
|
|
shouldFail: true,
|
|
rejectWith: ERR,
|
|
before: () => {
|
|
finished++
|
|
}
|
|
}),
|
|
buildMockFunction(),
|
|
buildMockFunction()
|
|
]
|
|
|
|
// when
|
|
return executeSequentially(list).then(
|
|
() => {
|
|
throw new Error('should not resolve')
|
|
},
|
|
([err, index]) => {
|
|
expect(err).toBe(ERR)
|
|
|
|
expect(index).toBe(0)
|
|
expect(finished).toBe(1)
|
|
|
|
expect(list[0]).toHaveBeenCalledTimes(1)
|
|
expect(list[1]).toHaveBeenCalledTimes(0)
|
|
expect(list[2]).toHaveBeenCalledTimes(0)
|
|
}
|
|
)
|
|
})
|
|
|
|
it('should accept an index to set the start of the execution', () => {
|
|
// given
|
|
const list = [buildMockFunction(), buildMockFunction(), buildMockFunction()]
|
|
|
|
// when
|
|
return executeSequentially(list, 1).then(() => {
|
|
expect(list[0]).toHaveBeenCalledTimes(0)
|
|
expect(list[1]).toHaveBeenCalledTimes(1)
|
|
expect(list[2]).toHaveBeenCalledTimes(1)
|
|
})
|
|
})
|
|
|
|
it('should fail with the absolute index of the failed function', () => {
|
|
// given
|
|
const list = [
|
|
buildMockFunction(),
|
|
buildMockFunction(),
|
|
buildMockFunction(),
|
|
buildMockFunction({ shouldFail: true }),
|
|
buildMockFunction()
|
|
]
|
|
|
|
// when
|
|
return executeSequentially(list, 2).then(
|
|
() => {
|
|
throw new Error('should not resolve')
|
|
},
|
|
([err, index]) => {
|
|
expect(index).toBe(3)
|
|
expect(list[0]).toHaveBeenCalledTimes(0)
|
|
expect(list[1]).toHaveBeenCalledTimes(0)
|
|
expect(list[2]).toHaveBeenCalledTimes(1)
|
|
expect(list[3]).toHaveBeenCalledTimes(1)
|
|
expect(list[4]).toHaveBeenCalledTimes(0)
|
|
}
|
|
)
|
|
})
|
|
|
|
it('should accept a callback to execute after each successful execution', () => {
|
|
// given
|
|
const list = [buildMockFunction(), buildMockFunction(), buildMockFunction()]
|
|
|
|
// when
|
|
const before = jest.fn()
|
|
return executeSequentially(list, 0, before).then(() => {
|
|
// then
|
|
expect(list[0]).toHaveBeenCalledTimes(1)
|
|
expect(list[1]).toHaveBeenCalledTimes(1)
|
|
expect(list[2]).toHaveBeenCalledTimes(1)
|
|
expect(before).toHaveBeenCalledTimes(3)
|
|
expect(before).toHaveBeenCalledWith(0)
|
|
expect(before).toHaveBeenCalledWith(1)
|
|
expect(before).toHaveBeenCalledWith(2)
|
|
})
|
|
})
|
|
|
|
it(`should not execute 'before' callback after a failed function`, () => {
|
|
// given
|
|
const list = [buildMockFunction(), buildMockFunction({ shouldFail: true }), buildMockFunction()]
|
|
|
|
// when
|
|
const before = jest.fn()
|
|
return executeSequentially(list, 0, before).then(
|
|
() => {
|
|
throw new Error('should not resolve')
|
|
},
|
|
() => {
|
|
// then
|
|
expect(list[0]).toHaveBeenCalledTimes(1)
|
|
expect(list[1]).toHaveBeenCalledTimes(1)
|
|
expect(list[2]).toHaveBeenCalledTimes(0)
|
|
expect(before).toHaveBeenCalledTimes(2)
|
|
expect(before).toHaveBeenCalledWith(0)
|
|
expect(before).toHaveBeenCalledWith(1)
|
|
expect(before).not.toHaveBeenCalledWith(2)
|
|
}
|
|
)
|
|
})
|
|
|
|
it(`should call 'after' callback right before the failing function`, () => {
|
|
// Given
|
|
const list = [buildMockFunction(), buildMockFunction({ shouldFail: true }), buildMockFunction()]
|
|
|
|
// When
|
|
const before = jest.fn()
|
|
const after = jest.fn()
|
|
return executeSequentially(list, 0, before, after).then(
|
|
() => {
|
|
throw new Error('should not resolve')
|
|
},
|
|
() => {
|
|
// Then
|
|
expect(list[0]).toHaveBeenCalledTimes(1)
|
|
expect(list[1]).toHaveBeenCalledTimes(1)
|
|
expect(list[2]).toHaveBeenCalledTimes(0)
|
|
expect(after).toHaveBeenCalledTimes(1)
|
|
expect(after).toHaveBeenCalledWith(0)
|
|
expect(after).not.toHaveBeenCalledWith(1)
|
|
expect(after).not.toHaveBeenCalledWith(2)
|
|
}
|
|
)
|
|
})
|
|
})
|
|
|
|
function buildMockFunction({
|
|
timeout = 0,
|
|
shouldFail = false,
|
|
rejectWith = null,
|
|
before = () => {},
|
|
after = () => {}
|
|
} = {}) {
|
|
return jest.fn(
|
|
() =>
|
|
new Promise((resolve, reject) => {
|
|
setTimeout(() => {
|
|
before()
|
|
|
|
if (shouldFail) {
|
|
reject(rejectWith)
|
|
} else {
|
|
after()
|
|
resolve()
|
|
}
|
|
}, timeout)
|
|
})
|
|
)
|
|
}
|