-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(terminate): renames exit to terminate (it now works for any type…
…/reason) exit() was only intended for manual exit calls. terminate() has the same functionality but works for signal, exception, rejection, and exit equally. BREAKING CHANGE: exit() has been renamed to terminate(). it now takes two arguments, the first being the termination type, and the second its argument (previously, it only took one: the exit code number).
- Loading branch information
Showing
5 changed files
with
246 additions
and
65 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import handler from '~/utils/handler'; | ||
import store from '~/store'; | ||
import { TSignal } from '~/types'; | ||
|
||
export default terminate; | ||
|
||
function terminate(type: 'signal', arg: TSignal): Promise<void>; | ||
function terminate(type: 'exception' | 'rejection', arg: Error): Promise<void>; | ||
function terminate(type: 'exit', arg: number): Promise<void>; | ||
async function terminate( | ||
type: 'signal' | 'exception' | 'rejection' | 'exit', | ||
arg: any | ||
): Promise<void> { | ||
switch (type) { | ||
case 'signal': | ||
if (store.state.attached.signal) return handler('signal', arg); | ||
break; | ||
case 'exception': | ||
if (store.state.attached.exception) return handler('exception', arg); | ||
break; | ||
case 'rejection': | ||
if (store.state.attached.rejection) return handler('rejection', arg); | ||
break; | ||
case 'exit': | ||
if (store.state.attached.exit) return handler('exit', arg); | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
return store.options.resolver(type, arg); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
import { terminate } from '~/index'; | ||
import _handler from '~/utils/handler'; | ||
import resetStore from '../reset-store'; | ||
import store from '~/store'; | ||
|
||
const handler: any = _handler; | ||
jest.mock('~/utils/handler'); | ||
|
||
const resetHandler = (): void => { | ||
handler.mockReset(); | ||
handler.mockImplementation(() => Promise.resolve('foo')); | ||
}; | ||
|
||
describe(`signal`, () => { | ||
test(`calls handler with signal when attached to signal`, async () => { | ||
expect.assertions(6); | ||
resetStore(); | ||
store.state.attached.signal = true; | ||
|
||
resetHandler(); | ||
const res1 = await terminate('signal', 'SIGINT'); | ||
expect(res1).toBe('foo'); | ||
expect(handler).toBeCalledTimes(1); | ||
expect(handler).toBeCalledWith('signal', 'SIGINT'); | ||
|
||
resetHandler(); | ||
const res2 = await terminate('signal', 'SIGHUP'); | ||
expect(res2).toBe('foo'); | ||
expect(handler).toBeCalledTimes(1); | ||
expect(handler).toBeCalledWith('signal', 'SIGHUP'); | ||
}); | ||
test(`calls resolver when not attached to signal`, async () => { | ||
expect.assertions(8); | ||
resetHandler(); | ||
resetStore(); | ||
store.state.attached.signal = false; | ||
const called: any[] = []; | ||
store.options.resolver = (...args) => { | ||
called.push(args); | ||
return Promise.resolve('bar'); | ||
}; | ||
|
||
const res1 = await terminate('signal', 'SIGINT'); | ||
expect(handler).not.toBeCalled(); | ||
expect(res1).toBe('bar'); | ||
expect(called).toHaveLength(1); | ||
expect(called[0]).toEqual(['signal', 'SIGINT']); | ||
|
||
const res2 = await terminate('signal', 'SIGHUP'); | ||
expect(handler).not.toBeCalled(); | ||
expect(res2).toBe('bar'); | ||
expect(called).toHaveLength(2); | ||
expect(called[1]).toEqual(['signal', 'SIGHUP']); | ||
}); | ||
}); | ||
|
||
describe(`exception`, () => { | ||
test(`calls handler with error when attached to exception`, async () => { | ||
expect.assertions(3); | ||
resetStore(); | ||
store.state.attached.exception = true; | ||
|
||
resetHandler(); | ||
const err = Error(); | ||
const res = await terminate('exception', err); | ||
expect(res).toBe('foo'); | ||
expect(handler).toBeCalledTimes(1); | ||
expect(handler).toBeCalledWith('exception', err); | ||
}); | ||
test(`calls resolver when not attached to exception`, async () => { | ||
expect.assertions(4); | ||
resetHandler(); | ||
resetStore(); | ||
store.state.attached.exception = false; | ||
const called: any[] = []; | ||
store.options.resolver = (...args) => { | ||
called.push(args); | ||
return Promise.resolve('bar'); | ||
}; | ||
|
||
const err = Error(); | ||
const res = await terminate('exception', err); | ||
expect(handler).not.toBeCalled(); | ||
expect(res).toBe('bar'); | ||
expect(called).toHaveLength(1); | ||
expect(called[0]).toEqual(['exception', err]); | ||
}); | ||
}); | ||
|
||
describe(`rejection`, () => { | ||
test(`calls handler with error when attached to rejection`, async () => { | ||
expect.assertions(3); | ||
resetStore(); | ||
store.state.attached.rejection = true; | ||
|
||
resetHandler(); | ||
const err = Error(); | ||
const res = await terminate('rejection', err); | ||
expect(res).toBe('foo'); | ||
expect(handler).toBeCalledTimes(1); | ||
expect(handler).toBeCalledWith('rejection', err); | ||
}); | ||
test(`calls resolver when not attached to rejection`, async () => { | ||
expect.assertions(4); | ||
resetHandler(); | ||
resetStore(); | ||
store.state.attached.rejection = false; | ||
const called: any[] = []; | ||
store.options.resolver = (...args) => { | ||
called.push(args); | ||
return Promise.resolve('bar'); | ||
}; | ||
|
||
const err = Error(); | ||
const res = await terminate('rejection', err); | ||
expect(handler).not.toBeCalled(); | ||
expect(res).toBe('bar'); | ||
expect(called).toHaveLength(1); | ||
expect(called[0]).toEqual(['rejection', err]); | ||
}); | ||
}); | ||
|
||
describe(`exit`, () => { | ||
test(`calls handler with exit code when attached to exit`, async () => { | ||
expect.assertions(6); | ||
resetStore(); | ||
store.state.attached.exit = true; | ||
|
||
resetHandler(); | ||
const res1 = await terminate('exit', 0); | ||
expect(res1).toBe('foo'); | ||
expect(handler).toBeCalledTimes(1); | ||
expect(handler).toBeCalledWith('exit', 0); | ||
|
||
resetHandler(); | ||
const res2 = await terminate('exit', 1); | ||
expect(res2).toBe('foo'); | ||
expect(handler).toBeCalledTimes(1); | ||
expect(handler).toBeCalledWith('exit', 1); | ||
}); | ||
test(`calls resolver when not attached to exit`, async () => { | ||
expect.assertions(8); | ||
resetHandler(); | ||
resetStore(); | ||
store.state.attached.exit = false; | ||
const called: any[] = []; | ||
store.options.resolver = (...args) => { | ||
called.push(args); | ||
return Promise.resolve('bar'); | ||
}; | ||
|
||
const res1 = await terminate('exit', 0); | ||
expect(handler).not.toBeCalled(); | ||
expect(res1).toBe('bar'); | ||
expect(called).toHaveLength(1); | ||
expect(called[0]).toEqual(['exit', 0]); | ||
|
||
const res2 = await terminate('exit', 1); | ||
expect(handler).not.toBeCalled(); | ||
expect(res2).toBe('bar'); | ||
expect(called).toHaveLength(2); | ||
expect(called[1]).toEqual(['exit', 1]); | ||
}); | ||
}); | ||
|
||
describe(`unknown type`, () => { | ||
test(`calls resolver when not attached`, async () => { | ||
expect.assertions(4); | ||
resetHandler(); | ||
resetStore(); | ||
store.state.attached = { | ||
signal: false, | ||
exception: false, | ||
rejection: false, | ||
exit: false | ||
}; | ||
const called: any[] = []; | ||
store.options.resolver = (...args) => { | ||
called.push(args); | ||
return Promise.resolve('bar'); | ||
}; | ||
|
||
// @ts-ignore | ||
const res = await terminate('unknown_type', 0); | ||
expect(handler).not.toBeCalled(); | ||
expect(res).toBe('bar'); | ||
expect(called).toHaveLength(1); | ||
expect(called[0]).toEqual(['unknown_type', 0]); | ||
}); | ||
test(`calls resolver when attached`, async () => { | ||
expect.assertions(4); | ||
resetHandler(); | ||
resetStore(); | ||
store.state.attached = { | ||
signal: true, | ||
exception: true, | ||
rejection: true, | ||
exit: true | ||
}; | ||
const called: any[] = []; | ||
store.options.resolver = (...args) => { | ||
called.push(args); | ||
return Promise.resolve('bar'); | ||
}; | ||
|
||
// @ts-ignore | ||
const res = await terminate('unknown_type', 0); | ||
expect(handler).not.toBeCalled(); | ||
expect(res).toBe('bar'); | ||
expect(called).toHaveLength(1); | ||
expect(called[0]).toEqual(['unknown_type', 0]); | ||
}); | ||
}); |