Last active
June 30, 2020 22:24
-
-
Save mayank23/4a5ac7a7cbb745aefc995777519338f5 to your computer and use it in GitHub Desktop.
Jest user defined asymmetric matchers
This file contains hidden or 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
import * as actionTypes from './action-types.js'; | |
class ActionTypeMatching extends AsymmetricMatcher { | |
constructor(expected){ | |
this.$$typeof = Symbol.for('jest.asymmetricMatcher'); | |
this.expected = expected; | |
} | |
asymmetricMatch(other) { | |
return (other === expected && actionTypes.hasOwnProperty(other)) | |
} | |
toString() { | |
return 'ActionTypeMatching'; | |
} | |
getExpectedType() { | |
return 'String' | |
} | |
toAsymmetricMatcher() { | |
// to be printed in diff string. | |
return `ActionTypeMatching(${this.expected})`; | |
} | |
} | |
// patch expect | |
expect.actionTypeMatching = (expected) => (new ActionTypeMatching(expected)); |
This file contains hidden or 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
export const SOME_ACTION = 'SOME_ACTION' |
This file contains hidden or 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
{ | |
"helloWorld" : "hello world" | |
} |
This file contains hidden or 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
class GreaterThan extends AsymmetricMatcher { | |
constructor(expected){ | |
this.$$typeof = Symbol.for('jest.asymmetricMatcher'); | |
this.expected = expected; | |
} | |
asymmetricMatch(other) { | |
return other > this.expected; | |
} | |
toString() { | |
return 'GreaterThan'; | |
} | |
getExpectedType() { | |
return 'Number' | |
} | |
toAsymmetricMatcher() { | |
// to be printed in diff string. | |
return `GreaterThan(${this.expected})`; | |
} | |
} | |
// patch expect | |
expect.greaterThan = (expected) => (new GreaterThan(expected)); |
This file contains hidden or 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
// patch expect by importing these files | |
import from './GreaterThan' | |
import from './ActionTypeMatching' | |
import from './TranslationKeyMatching' |
This file contains hidden or 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
describe('custom asymmetric matchers', () => { | |
describe('numeric limits', () => { | |
/* a bit contrived but a possible use case */ | |
it('PASS: has x> 9 && y > 19', () => { | |
const obj = { | |
x: 10, | |
y: 20 | |
} | |
expect(obj).toEqual({ | |
x: expect.greaterThan(9), | |
y: expect.greaterThan(19) | |
}) | |
}); | |
it('FAIL: has x>9 && y >19', () => { | |
const obj = { | |
x: 9, | |
y: 19 | |
} | |
expect(obj).toEqual({ | |
x: expect.greaterThan(9), | |
y: expect.greaterThan(19) | |
}) | |
}); | |
}); | |
describe('redux example', () => { | |
/* | |
Assume for example, we have a `actionTypes.js` file, which lists all | |
constants for all the various redux action types in our application. | |
e.g) | |
// constants.js | |
export const SOME_ACTION = 'SOME_ACTION'; | |
... | |
// end file | |
Basically, the asymmetric matcher, `actionTypeMatching`, | |
would test that the action type equals the `expected` value: | |
'some-action-type' and also exists in our `actionTypes.js` file. | |
*/ | |
/* | |
The `someActionCreator` function returns our redux action which is a plain object: | |
{ | |
type: 'SOME_ACTION', | |
} | |
*/ | |
it('PASS: returns valid action type', () => { | |
const actionObj = someActionCreator(); | |
expect(actionObj).toEqual({ | |
type: expect.actionTypeMatching('SOME_ACTION') | |
}); | |
}); | |
it('FAIL: returns valid action type', () => { | |
const actionObj = someActionCreator(); | |
expect(actionObj).toEqual({ | |
type: expect.actionTypeMatching('SOME_ACTION-TYPO') | |
}); | |
}); | |
}); | |
describe('internationalization (i18n) example', () => { | |
/* | |
Assume for example, we have an internationalized application which uses | |
translation keys for showing the correct message based on the locale. | |
e.g) | |
// en-us.json | |
{ | |
"helloWorld": "hello world" | |
} | |
... | |
// end file | |
Basically, the asymmetric matcher, `translationKeyMatching`, | |
would test that the translation key matched the `expected` value: | |
'helloWorld' and also exists in our `en-us.json` translations file. | |
(note: simple example, since just checking en-us) | |
*/ | |
it('PASS: has a valid translation key', () => { | |
/* let's say we have an object that will have a property that needs to be a translation key*/ | |
const objWithTranslationKey = { | |
messageId: 'helloWorld', | |
} | |
expect(objWithTranslationKey).toEqual({ | |
messageId: expect.translationKeyMatching('helloWorld') | |
}); | |
}); | |
it('FAIL: has a valid translation key', () => { | |
/* let's say we have an object that will have a property that needs to be a translation key*/ | |
const objWithTranslationKey = { | |
messageId: 'helloWorld-typo', | |
} | |
expect(objWithTranslationKey).toEqual({ | |
messageId: expect.translationKeyMatching('helloWorld') | |
}); | |
}); | |
}); | |
}); |
This file contains hidden or 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
import translations from './en-us.json'; | |
class TranslationKeyMatching extends AsymmetricMatcher { | |
constructor(expected){ | |
this.$$typeof = Symbol.for('jest.asymmetricMatcher'); | |
this.expected = expected; | |
} | |
asymmetricMatch(other) { | |
return (other === expected && translations.hasOwnProperty(other)) | |
} | |
toString() { | |
return 'TranslationKeyMatching'; | |
} | |
getExpectedType() { | |
return 'String' | |
} | |
toAsymmetricMatcher() { | |
// to be printed in diff string. | |
return `TranslationKey(${this.expected})`; | |
} | |
} | |
// patch expect | |
expect.translationKeyMatching = (expected) => (new TranslationKeyMatching(expected)); |
We would remove extends AsymmetricMatcher
?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks ❤️