Last active
February 19, 2022 20:23
-
-
Save jfhector/883b03b2886645d6596d77f734330db7 to your computer and use it in GitHub Desktop.
wrapInSynchronousTryCatch
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
Feature: wrapInSynchronousTryCatch | |
Scenario: The function returned by wrapInSynchronousTryCatch calls the function provided to wrapInSynchronousTryCatch with the same arguments | |
Given wrapInSynchronousTryCatch is called with a synchronous function that does not throw | |
When the function returned by wrapInSynchronousTryCatch is called with some arguments | |
Then the function provided to wrapInSynchronousTryCatch gets called with the same arguments | |
And the function returned by wrapInSynchronousTryCatch returns the same thing as the provided function | |
Scenario: It catches any error that the provided function throws | |
Given wrapInSynchronousTryCatch is called with a synchronous function that throws when called with some arguments | |
When the function returned by wrapInSynchronousTryCatch is called with the same arguments | |
Then the error gets logged to the console | |
And the function returned by wrapInSynchronousTryCatch does not throw |
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
/* eslint-disable no-console */ | |
type WrapInSynchronousTryCatch = { | |
<Args extends any[], ReturnType>(fn: (...args: Args) => ReturnType): ( | |
...args: Args | |
) => ReturnType | undefined; | |
}; | |
/** | |
* Use this if you have a function that may throw an error, and you want that error handled so it doesn't propagate further. | |
* | |
* Important note: If the function you're providing is asynchronous (or returns a promise), use `wrapInAsyncTryCatch` instead. | |
* | |
* @param syncFnToWrapInTryCatch a synchronous function that you want called inside a try/catch block | |
* @returns a synchronous function which, when called, calls `fn` with the arguments it's given. `fn` will be called inside `try { ... } catch(err) { logs the err and returns }` | |
*/ | |
const wrapInSynchronousTryCatch: WrapInSynchronousTryCatch = syncFnToWrapInTryCatch => { | |
return function todoName(...args) { | |
try { | |
return syncFnToWrapInTryCatch(...args); | |
} catch (err) { | |
console.error(err); | |
return; | |
} | |
}; | |
}; | |
export { wrapInSynchronousTryCatch }; |
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
/* eslint-disable @typescript-eslint/no-empty-function */ | |
/* eslint-disable @typescript-eslint/no-unused-vars */ | |
/* eslint-disable no-console */ | |
import { defineFeature, loadFeature } from 'jest-cucumber'; | |
import { wrapInSynchronousTryCatch } from '..'; | |
// Syncing with .feature Cucumber file | |
const feature = loadFeature('../definition.feature', { | |
loadRelativePath: true, | |
}); | |
defineFeature(feature, test => { | |
afterEach(() => { | |
jest.clearAllMocks(); | |
}); | |
test('The function returned by wrapInSynchronousTryCatch calls the function provided to wrapInSynchronousTryCatch with the same arguments', ({ | |
given, | |
when, | |
then, | |
and, | |
}) => { | |
const functionToProvideToWithErrorBoundary = jest | |
.fn() | |
.mockImplementation((a, b) => a + ' ' + b); | |
let functionReturnedByWithErrorBoundary: any; | |
let valueReturnedByTheFunctionReturnedByWithErrorBoundary: any; | |
given( | |
'wrapInSynchronousTryCatch is called with a synchronous function that does not throw', | |
() => { | |
functionReturnedByWithErrorBoundary = wrapInSynchronousTryCatch( | |
functionToProvideToWithErrorBoundary | |
); | |
} | |
); | |
when( | |
'the function returned by wrapInSynchronousTryCatch is called with some arguments', | |
() => { | |
valueReturnedByTheFunctionReturnedByWithErrorBoundary = functionReturnedByWithErrorBoundary( | |
'Hello', | |
'World' | |
); | |
} | |
); | |
then( | |
'the function provided to wrapInSynchronousTryCatch gets called with the same arguments', | |
() => { | |
expect(functionToProvideToWithErrorBoundary).toHaveBeenCalledWith( | |
'Hello', | |
'World' | |
); | |
} | |
); | |
and( | |
'the function returned by wrapInSynchronousTryCatch returns the same thing as the provided function', | |
() => { | |
expect(valueReturnedByTheFunctionReturnedByWithErrorBoundary).toBe( | |
functionToProvideToWithErrorBoundary('Hello', 'World') | |
); | |
} | |
); | |
}); | |
test('It catches any error that the provided function throws', ({ | |
given, | |
when, | |
then, | |
and, | |
}) => { | |
const MOCK_ERROR = new Error('mock error'); | |
const functionToProvideToWithErrorBoundary = jest | |
.fn() | |
.mockImplementation(() => { | |
throw MOCK_ERROR; | |
}); | |
let functionReturnedByWithErrorBoundary: any; | |
const consoleErrorSpy = jest.spyOn(console, 'error'); | |
given( | |
'wrapInSynchronousTryCatch is called with a synchronous function that throws when called with some arguments', | |
() => { | |
functionReturnedByWithErrorBoundary = wrapInSynchronousTryCatch( | |
functionToProvideToWithErrorBoundary | |
); | |
} | |
); | |
when( | |
'the function returned by wrapInSynchronousTryCatch is called with the same arguments', | |
() => { | |
functionReturnedByWithErrorBoundary(); | |
} | |
); | |
then('the error gets logged to the console', () => { | |
expect(consoleErrorSpy).toHaveBeenCalledWith(MOCK_ERROR); | |
}); | |
and( | |
'the function returned by wrapInSynchronousTryCatch does not throw', | |
() => { | |
console.log( | |
'If this gets executed, it means there has been no unhandled exception, and this test is successful' | |
); | |
} | |
); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment