UNPKG

chromogen

Version:

simple, interaction-driven Jest test generator for Recoil and React Hooks apps

218 lines (210 loc) 11.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.testSetters = exports.testSelectors = exports.initializeSelectorFamilies = exports.initializeSelectors = exports.returnSelectorFamily = exports.returnAtomFamily = exports.returnReadable = exports.returnWriteable = exports.selectorFamilyHook = exports.atomFamilyHook = exports.readableHook = exports.writeableHook = exports.importRecoilFamily = exports.importRecoilState = exports.assertState = exports.initializeAtoms = void 0; function initializeAtoms(state, current) { return state.reduce((initializers, { key, value, previous }) => `${initializers}\t\t\tresult.current.set${key}(${JSON.stringify(current ? value : previous)});\n\n`, ''); } exports.initializeAtoms = initializeAtoms; function assertState(updates) { return updates.reduce((assertions, { key, value }) => `${assertions}\t\texpect(result.current.${key}Value).toStrictEqual(${JSON.stringify(value)});\n\n`, ''); } exports.assertState = assertState; function importRecoilState(keyArray) { return keyArray.reduce((fullStr, key) => `${fullStr}\t${key},\n`, ''); } exports.importRecoilState = importRecoilState; function importRecoilFamily(familyObj) { return Object.keys(familyObj).reduce((importStr, familyName) => `${importStr}\t${familyName},\n`, ''); } exports.importRecoilFamily = importRecoilFamily; function writeableHook(keyArray) { return keyArray.reduce((fullStr, key) => `${fullStr}\tconst [${key}Value, set${key}] = useRecoilState(${key});\n`, ''); } exports.writeableHook = writeableHook; function readableHook(keyArray) { return keyArray.reduce((fullStr, key) => `${fullStr}\tconst ${key}Value = useRecoilValue(${key});\n`, ''); } exports.readableHook = readableHook; function atomFamilyHook(transactionArray) { const len = transactionArray.length; return len ? transactionArray[len - 1].atomFamilyState.reduce((str, atomState) => { const { family, key } = atomState; const params = key.substring(family.length + 2); const scrubbedParams = params.replace(/[^\w\s]/gi, ''); const parsedParams = JSON.parse(params); return `${str}\tconst [${`${family}__${scrubbedParams}__Value`}, ${`set${family}__${scrubbedParams}`}] = useRecoilState(${family}(${typeof parsedParams === 'string' ? `${params}` : `${parsedParams}`}));\n`; }, '') : ''; } exports.atomFamilyHook = atomFamilyHook; function selectorFamilyHook(selectorFamilyTracker, isSettable) { return Object.entries(selectorFamilyTracker) .filter((familyArr) => familyArr[1].isSettable === isSettable) .reduce((str, familyArr) => { const [familyName, { prevParams }] = familyArr; return `${str}${[...prevParams].reduce((innerStr, param) => { let scrubbedParams; if (typeof param === 'string') { scrubbedParams = param.replace(/[^\w\s]/gi, ''); } return isSettable ? `${innerStr}\tconst [${`${familyName}__${scrubbedParams !== undefined ? scrubbedParams : param}__Value`}, ${`set${familyName}__${scrubbedParams !== undefined ? scrubbedParams : param}`}] = useRecoilState(${familyName}(${typeof param === 'string' ? `"${param}"` : `${JSON.parse(param)}`}));\n` : `${innerStr}\tconst ${`${familyName}__${scrubbedParams !== undefined ? scrubbedParams : param}__Value`} = useRecoilValue(${familyName}(${typeof param === 'string' ? `"${param}"` : `${JSON.parse(param)}`}));\n`; }, '')}`; }, ''); } exports.selectorFamilyHook = selectorFamilyHook; function returnWriteable(keyArray) { return keyArray.reduce((fullStr, key) => `${fullStr}\t\t${key}Value,\n\t\tset${key},\n`, ''); } exports.returnWriteable = returnWriteable; function returnReadable(keyArray) { return keyArray.reduce((fullStr, key) => `${fullStr}\t\t${key}Value,\n`, ''); } exports.returnReadable = returnReadable; function returnAtomFamily(transactionArray) { const len = transactionArray.length; return len ? transactionArray[len - 1].atomFamilyState.reduce((value, atomState) => { const { family, key } = atomState; const params = key.substring(family.length + 2); const scrubbedParams = params.replace(/[^\w\s]/gi, ''); return `${value}\t\t${`${family}__${scrubbedParams}__Value`}, \t\t${`set${family}__${scrubbedParams}`},\n`; }, '') : ''; } exports.returnAtomFamily = returnAtomFamily; function returnSelectorFamily(selectorFamilyTracker, isSettable) { return Object.entries(selectorFamilyTracker) .filter((familyArr) => familyArr[1].isSettable === isSettable) .reduce((str, familyArr) => { const [familyName, { prevParams }] = familyArr; if (isSettable) { return `${str}${[...prevParams].reduce((innerStr, param) => { let scrubbedParams; if (typeof param === 'string') { scrubbedParams = param.replace(/[^\w\s]/gi, ''); } return `${innerStr}\t\t${`${familyName}__${scrubbedParams !== undefined ? scrubbedParams : param}__Value`}, ${`set${familyName}__${scrubbedParams !== undefined ? scrubbedParams : param}`},\n`; }, '')}`; } return `${str}${[...prevParams].reduce((innerStr, param) => { let scrubbedParams; if (typeof param === 'string') { scrubbedParams = param.replace(/[^\w\s]/gi, ''); } return `${innerStr}\t\t${`${familyName}__${scrubbedParams !== undefined ? scrubbedParams : param}__Value`},\n`; }, '')}`; }, ''); } exports.returnSelectorFamily = returnSelectorFamily; function initializeSelectors(initialRender) { return initialRender.reduce((fullStr, { key, value }) => `${fullStr}\tit('${key} should initialize correctly', () => { \t\texpect(result.current.${key}Value).toStrictEqual(${JSON.stringify(value)}); \t});\n\n`, ''); } exports.initializeSelectors = initializeSelectors; function initializeSelectorFamilies(initialRenderFamilies) { return initialRenderFamilies.reduce((initialTests, { key, params, value }) => { let scrubbedParams; if (typeof params === 'string') { scrubbedParams = params.replace(/[^\w\s]/gi, ''); } return `${initialTests}\tit('${key}__${scrubbedParams !== undefined ? scrubbedParams : JSON.stringify(params)} should initialize correctly', () => { \t\texpect(result.current.${key}__${scrubbedParams !== undefined ? scrubbedParams : JSON.stringify(params)}__Value).toStrictEqual(${JSON.stringify(value)}); \t});\n`; }, ''); } exports.initializeSelectorFamilies = initializeSelectorFamilies; function testSelectors(transactionArray) { return transactionArray.reduce((selectorTests, { state, updates, atomFamilyState, familyUpdates }) => { const allUpdatedAtoms = [ ...state.filter(({ updated }) => updated), ...atomFamilyState.filter(({ updated }) => updated), ]; const allUpdatedSelectors = [...updates, ...familyUpdates]; const atomLen = allUpdatedAtoms.length; const selectorLen = allUpdatedSelectors.length; return atomLen !== 0 && selectorLen !== 0 ? `${selectorTests}\tit('${selectorLen > 1 ? allUpdatedSelectors.reduce((list, selectorState, i) => { const { key } = selectorState; const isLastElement = i === selectorLen - 1; if ('params' in selectorState) { let scrubbedParams; if (typeof selectorState.params === 'string') { scrubbedParams = selectorState.params.replace(/[^\w\s]/gi, ''); } return `${list}${isLastElement ? 'and ' : ''}${key}__${scrubbedParams !== undefined ? scrubbedParams : selectorState.params}${isLastElement ? '' : ', '}`; } return `${list}${isLastElement ? 'and ' : ''}${key}${isLastElement ? '' : ', '}`; }, '') : `${allUpdatedSelectors[0].params !== undefined ? `${allUpdatedSelectors[0].key}__${typeof allUpdatedSelectors[0].params === 'string' ? allUpdatedSelectors[0].params.replace(/[^\w\s]/gi, '') : allUpdatedSelectors[0].params}` : allUpdatedSelectors[0].key}`} should properly derive state when ${atomLen > 1 ? allUpdatedAtoms.reduce((list, { key }, i) => { const isLastElement = i === atomLen - 1; const scrubbedKey = key.replace(/[^\w\s]/gi, ''); return `${list}${isLastElement ? 'and ' : ''}${scrubbedKey}${isLastElement ? ' update' : ', '}`; }, '') : `${allUpdatedAtoms[0].key.replace(/[^\w\s]/gi, '')} updates`}', () => { \t\tconst { result } = renderRecoilHook(useStoreHook); \t\tact(() => { ${state.reduce((initializers, { key, value }) => `${initializers}\t\t\tresult.current.set${key}(${JSON.stringify(value)});\n\n`, '')} ${atomFamilyState.reduce((initializers, { key, value }) => { const scrubbedKey = key.replace(/[^\w\s]/gi, ''); return `${initializers}\t\t\tresult.current.set${scrubbedKey}(${JSON.stringify(value)});\n\n`; }, '')} \t\t}); ${selectorLen !== 0 ? allUpdatedSelectors.reduce((assertions, selectorState) => { const { key, value } = selectorState; let scrubbedParams; if (typeof selectorState.params === 'string') { scrubbedParams = selectorState.params.replace(/[^\w\s]/gi, ''); } if (selectorState.params !== undefined) return `${assertions}\t\texpect(result.current.${key}__${scrubbedParams !== undefined ? scrubbedParams : selectorState.params}__Value).toStrictEqual(${JSON.stringify(value)});\n\n`; return `${assertions}\t\texpect(result.current.${key}Value).toStrictEqual(${JSON.stringify(value)});\n\n`; }, '') : ''}\t});\n\n` : selectorTests; }, ''); } exports.testSelectors = testSelectors; function testSetters(setTransactionArray) { return setTransactionArray.reduce((setterTests, { state, setter }) => { const updatedAtoms = state.filter(({ updated }) => updated); if (setter) { const { params } = setter; let scrubbedParams; if (typeof params === 'string') { scrubbedParams = params.replace(/[^\w\s]/gi, ''); } return params !== undefined ? `${setterTests}\tit('${setter.key}__${scrubbedParams !== undefined ? scrubbedParams : JSON.stringify(params)} should properly set state', () => { \t\tconst { result } = renderRecoilHook(useStoreHook); \t\tact(() => { ${initializeAtoms(state, false)}\t\t}); \t\tact(() => { \t\t\tresult.current.set${setter.key}__${scrubbedParams !== undefined ? scrubbedParams : JSON.stringify(params)}(${JSON.stringify(setter.newValue)}); \t\t}); ${assertState(updatedAtoms)}\t});\n\n` : `${setterTests}\tit('${setter.key} should properly set state', () => { \t\tconst { result } = renderRecoilHook(useStoreHook); \t\tact(() => { ${initializeAtoms(state, false)}\t\t}); \t\tact(() => { \t\t\tresult.current.set${setter.key}(${JSON.stringify(setter.newValue)}); \t\t}); ${assertState(updatedAtoms)}\t});\n\n`; } return setterTests; }, ''); } exports.testSetters = testSetters;