Mirror of https://github.com/roostorg/coop github.com/roostorg/coop
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 557ff54b2b435e5f1e789c6a8a4e1bebf2d7deb6 71 lines 2.8 kB view raw
1// eslint-disable-next-line import/no-extraneous-dependencies 2import jestSnapshot from 'jest-snapshot'; 3// eslint-disable-next-line import/no-extraneous-dependencies 4import jsonPath from 'jsonpath'; 5import lodash from 'lodash'; 6 7const { toMatchSnapshot } = jestSnapshot; 8const { set } = lodash; 9 10interface CustomMatchers<R = unknown> { 11 /** 12 * This assertion works like `toMatchSnapshot`, except that it makes it 13 * easier to define many asymmetric property matchers at once, to better 14 * support cases where many keys in the snapshot have dynamic values. 15 * 16 * For example, the data being snapshotted might be a list of newly-created 17 * objects, each of which has a dynamically-generated id. In that case, you 18 * could use this assertion to easily require that every id is a string: 19 * 20 * `toMatchDynamicSnapshot({ '$[*].id': expect.any(String) })`. 21 * 22 * In the above, the `$[*].id` key is a jsonpath expression that matches the 23 * id property of every object in the root list. 24 */ 25 toMatchDynamicSnapshot(propertyMatchers: object, hint?: string): R; 26} 27 28declare global { 29 // eslint-disable-next-line @typescript-eslint/no-namespace 30 namespace jest { 31 // Normally, an empty interface in TS is pointless but, in this case, we're 32 // actually taking advantage of declaration merging (on Expect, Matchers, 33 // and InverseAsymmetricMatchers) to make those interfaces, which are defined 34 // elsewhere extend our CustomMatchers interface. 35 // eslint-disable-next-line @typescript-eslint/no-empty-object-type 36 interface Expect extends CustomMatchers {} 37 // eslint-disable-next-line @typescript-eslint/no-empty-object-type 38 interface Matchers<R> extends CustomMatchers<R> {} 39 // eslint-disable-next-line @typescript-eslint/no-empty-object-type 40 interface InverseAsymmetricMatchers extends CustomMatchers {} 41 } 42} 43 44expect.extend({ 45 toMatchDynamicSnapshot(received, propertyMatchers: object, hint?: string) { 46 // Treat property matcher keys as jsonpath queries 47 // if they start with a $ and contain a dot. 48 const isJsonPath = (it: string) => it[0] === '$' && it.includes('.'); 49 const generatedPropertyMatchers = { ...propertyMatchers }; 50 51 Object.keys(propertyMatchers).forEach((k) => { 52 const key = k as keyof typeof generatedPropertyMatchers & 53 keyof typeof propertyMatchers; 54 55 if (isJsonPath(k)) { 56 // eslint-disable-next-line @typescript-eslint/no-dynamic-delete 57 delete generatedPropertyMatchers[key]; 58 jsonPath.paths(received, k).forEach((path) => { 59 set(generatedPropertyMatchers, path.slice(1), propertyMatchers[key]); 60 }); 61 } 62 }); 63 64 return (toMatchSnapshot as any).call( 65 this, 66 received, 67 generatedPropertyMatchers, 68 hint, 69 ); 70 }, 71});