diff --git a/packages/xlsx-import/src/mappers/jsonMapper.ts b/packages/xlsx-import/src/mappers/jsonMapper.ts index 672cc3a..64c80f4 100644 --- a/packages/xlsx-import/src/mappers/jsonMapper.ts +++ b/packages/xlsx-import/src/mappers/jsonMapper.ts @@ -1,9 +1,31 @@ -type JsonMapper = (value: string) => TJsonResult | null; - -export const jsonMapper: JsonMapper = (value: string): TJsonResult | null => { - try { - return JSON.parse(value); - } catch (e) { - return null; - } +type JsonMapperSignature = (value: string) => TJsonResult | TDefaultResult; + +export type JsonMapper = JsonMapperSignature & { + default: (value: TDefaultResult) => JsonMapper; }; + +interface IJsonMapperOptions { + default: TDefaultResult; +} + +const factory = (options: Readonly>): JsonMapper => { + const mapper: JsonMapper = (json: string): TJsonResult | TDefaultResult => { + try { + return JSON.parse(json); + } catch (e) { + return options.default; + } + }; + + mapper.default = (defaultResult: TJSonResult) => + factory({ + ...options, + default: defaultResult, + }); + + return mapper; +}; + +export const jsonMapper = factory({ + default: null, +}); diff --git a/packages/xlsx-import/tests/unit/mappers/jsonMapper.test.ts b/packages/xlsx-import/tests/unit/mappers/jsonMapper.test.ts new file mode 100644 index 0000000..f363b85 --- /dev/null +++ b/packages/xlsx-import/tests/unit/mappers/jsonMapper.test.ts @@ -0,0 +1,32 @@ +import * as chai from 'chai'; +import { jsonMapper } from '../../../src/mappers/jsonMapper'; + +describe('UNIT TEST: src/mappers/', () => { + describe('jsonMapper', () => { + const dataProvider = [ + { inValue: '', expectedResult: null }, + { inValue: null, expectedResult: null }, + { inValue: ' ', expectedResult: null }, + { inValue: 'asd', expectedResult: null }, + { inValue: 'null', expectedResult: null }, + { inValue: 'false', expectedResult: false }, + { inValue: 'true', expectedResult: true }, + { inValue: '0', expectedResult: 0 }, + { inValue: '1', expectedResult: 1 }, + { inValue: '"string"', expectedResult: 'string' }, + { inValue: "'string'", expectedResult: null }, + { inValue: '{"a":1}', expectedResult: { a: 1 } }, + { inValue: '{"a":[1]}', expectedResult: { a: [1] } }, + ]; + dataProvider.forEach(({ inValue, expectedResult }) => { + it(`jsonMapper for input "${inValue}" SHOULD return "${JSON.stringify(expectedResult)}"`, () => { + chai.expect(jsonMapper(inValue as string)).is.eql(expectedResult); + }); + }); + + it('Should return default value on error', () => { + const mapper = jsonMapper.default({ a: 1 }); + chai.expect(mapper('invalid')).eql({ a: 1 }); + }); + }); +}); diff --git a/packages/xlsx-import/tests/unit/mappers/stringMapper.test.ts b/packages/xlsx-import/tests/unit/mappers/stringMapper.test.ts index be03831..68b159e 100644 --- a/packages/xlsx-import/tests/unit/mappers/stringMapper.test.ts +++ b/packages/xlsx-import/tests/unit/mappers/stringMapper.test.ts @@ -1,5 +1,5 @@ import * as chai from 'chai'; -import { isEmpty, isFilled, jsonMapper, lowerCaseMapper, upperCaseMapper } from '../../../src/mappers'; +import { isEmpty, isFilled, lowerCaseMapper, upperCaseMapper } from '../../../src/mappers'; import { stringMapper } from '../../../src/mappers/stringMapper'; describe('UNIT TEST: src/mappers/', () => { @@ -62,30 +62,6 @@ describe('UNIT TEST: src/mappers/', () => { }); }); - // todo move to jsonMapper.test.ts - describe('jsonMapper', () => { - const dataProvider = [ - { inValue: '', expectedResult: null }, - { inValue: null, expectedResult: null }, - { inValue: ' ', expectedResult: null }, - { inValue: 'asd', expectedResult: null }, - { inValue: 'null', expectedResult: null }, - { inValue: 'false', expectedResult: false }, - { inValue: 'true', expectedResult: true }, - { inValue: '0', expectedResult: 0 }, - { inValue: '1', expectedResult: 1 }, - { inValue: '"string"', expectedResult: 'string' }, - { inValue: "'string'", expectedResult: null }, - { inValue: '{"a":1}', expectedResult: { a: 1 } }, - { inValue: '{"a":[1]}', expectedResult: { a: [1] } }, - ]; - dataProvider.forEach(({ inValue, expectedResult }) => { - it(`jsonMapper for input "${inValue}" SHOULD return "${JSON.stringify(expectedResult)}"`, () => { - chai.expect(jsonMapper(inValue as string)).is.eql(expectedResult); - }); - }); - }); - // todo move to isEmpty.test.ts describe('isEmpty', () => { const dataProvider = [