improved testing

This commit is contained in:
Josh Guyette 2023-07-18 17:55:45 -05:00
parent 48440fccb0
commit d9517c319a
3 changed files with 83 additions and 40 deletions

3
.gitignore vendored
View File

@ -15,6 +15,9 @@ node_modules/
# Build folder # Build folder
dist dist
# Jest coverage report
coverage
# Lock files # Lock files
yarn.lock yarn.lock
package-lock.json package-lock.json

View File

@ -12,11 +12,13 @@
"build": "tsc", "build": "tsc",
"pretest": "tsc", "pretest": "tsc",
"test": "./node_modules/.bin/jest --verbose", "test": "./node_modules/.bin/jest --verbose",
"coverage": "./node_modules/.bin/jest --coverage",
"prepublish": "tsc && npm run test" "prepublish": "tsc && npm run test"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.3", "@types/jest": "^29.5.3",
"@types/node": "^18.11.18", "@types/node": "^18.11.18",
"@types/rewire": "^2.5.28",
"jest": "^29.6.1", "jest": "^29.6.1",
"typescript": "^5.1.6" "typescript": "^5.1.6"
} }

View File

@ -1,21 +1,21 @@
// @ts-ignore - TS doesn't know this is allowed
import { startTimeout, startInterval, TimeInMS } from './Scheduler' import { startTimeout, startInterval, TimeInMS } from './Scheduler'
describe('setTimeout Tests', () => { beforeEach(() => {
beforeEach(() => {
jest.useFakeTimers() jest.useFakeTimers()
}) })
afterEach(() => { afterEach(() => {
jest.clearAllTimers() jest.clearAllTimers()
}) })
test('startTimeout, should start and stop properly', () => { describe('startTimeout Tests', () => {
test('should start and stop properly', () => {
const callback = jest.fn() const callback = jest.fn()
const stop = startTimeout(callback, { ms: 5000 }) const stop = startTimeout(callback, { ms: 5000 })
// Advance timers by less than the delay and check if callback has not been called // Advance timers by less than the delay and check if callback has not been called
jest.advanceTimersByTime(2000) jest.advanceTimersByTime(TimeInMS.SECOND * 2)
expect(callback).not.toBeCalled() expect(callback).not.toBeCalled()
// Advance timers to exactly the delay and check if callback has been called // Advance timers to exactly the delay and check if callback has been called
@ -26,46 +26,61 @@ describe('setTimeout Tests', () => {
stop() stop()
}) })
test('startTimeout, should not call the function if stop function is called', () => { test('should not call immediately', () => {
const fn = jest.fn() const callback = jest.fn()
const stop = startTimeout(fn, { ms: TimeInMS.SECOND }) const stop = startTimeout(callback, { ms: 5000 })
expect(fn).not.toBeCalled() // Should not be called immediately
expect(callback).not.toBeCalled()
// Cleanup
stop() stop()
jest.advanceTimersByTime(TimeInMS.SECOND)
expect(fn).not.toBeCalled()
}) })
test('startTimeout, should still call the function if stop function is called and canceled', () => { test('should not call the function if stop function is called', () => {
const fn = jest.fn() const callback = jest.fn()
const stop = startTimeout(fn, { ms: TimeInMS.SECOND }) const stop = startTimeout(callback, { ms: TimeInMS.SECOND })
expect(fn).not.toBeCalled() // Stop the timeout
stop()
// Advance timers by less than the delay and check if callback has not been called
jest.advanceTimersByTime(TimeInMS.SECOND)
expect(callback).not.toBeCalled()
// Advance timers by less than the delay and check if callback has not been called
jest.advanceTimersByTime(TimeInMS.SECOND)
expect(callback).not.toBeCalled()
})
test('should still call the function if stop function is called with a delay then canceled', () => {
const callback = jest.fn()
const stop = startTimeout(callback, { ms: TimeInMS.SECOND * 5 })
// Cancel the timeout, in 5 seconds
const stopCancel = stop({ const stopCancel = stop({
ms: TimeInMS.SECOND * 5, ms: TimeInMS.SECOND * 5,
})! })!
jest.advanceTimersByTime(TimeInMS.SECOND)
// Abort that cancel
stopCancel() stopCancel()
expect(fn).toBeCalled()
// Finish timer
jest.advanceTimersByTime(TimeInMS.SECOND * 5)
expect(callback).toBeCalled()
}) })
}) })
describe('setInterval Tests', () => { describe('startInterval Tests', () => {
beforeEach(() => { test('should correctly start and repeat interval', () => {
jest.useFakeTimers()
})
afterEach(() => {
jest.clearAllTimers()
})
test('startInterval, should correctly start and repeat interval', () => {
const callback = jest.fn() const callback = jest.fn()
const stop = startInterval(callback, TimeInMS.SECOND * 2, { ms: 5000 })
const stop = startInterval(callback, 2000, { ms: 5000 }) // Doesn't call the function right away
expect(callback).not.toBeCalled()
// Advance timers by less than the initial delay and check if callback has not been called // Advance timers by less than the initial delay and check if callback has not been called
jest.advanceTimersByTime(2000) jest.advanceTimersByTime(TimeInMS.SECOND * 2)
expect(callback).not.toBeCalled() expect(callback).not.toBeCalled()
// Advance timers to exactly the delay and check if callback has been called // Advance timers to exactly the delay and check if callback has been called
@ -73,20 +88,43 @@ describe('setInterval Tests', () => {
expect(callback).toBeCalledTimes(1) expect(callback).toBeCalledTimes(1)
// Advance timers by the interval and check if callback has been called again // Advance timers by the interval and check if callback has been called again
jest.advanceTimersByTime(2000) jest.advanceTimersByTime(TimeInMS.SECOND * 2)
expect(callback).toBeCalledTimes(2) expect(callback).toBeCalledTimes(2)
// Cleanup // Cleanup
stop() stop()
}) })
test('startInterval, should not call the function if stop function is called', () => { test('should not call the function if stop function is called', () => {
const fn = jest.fn() const callback = jest.fn()
const stop = startInterval(fn, 2000, { ms: TimeInMS.SECOND }) const stop = startInterval(callback, TimeInMS.SECOND * 2, {
ms: TimeInMS.SECOND,
})
expect(callback).not.toBeCalled()
expect(fn).not.toBeCalled()
stop() stop()
jest.advanceTimersByTime(TimeInMS.SECOND) jest.advanceTimersByTime(TimeInMS.SECOND)
expect(fn).not.toBeCalled() expect(callback).not.toBeCalled()
})
test('should still call the function if the stop function is called (with a delay), and the stopCancel function is called before the delay expires', () => {
const callback = jest.fn()
const stop = startInterval(callback, TimeInMS.SECOND * 2)
jest.advanceTimersByTime(TimeInMS.SECOND * 2)
expect(callback).toBeCalled()
const stopCancel = stop({
ms: TimeInMS.SECOND * 5,
})
stopCancel?.()
jest.advanceTimersByTime(TimeInMS.SECOND * 2)
expect(callback).toBeCalledTimes(2)
// cleanup
stop()
}) })
}) })