Skip to content

Commit

Permalink
Feature/73 default json mapper response (#201)
Browse files Browse the repository at this point in the history
* feat: added customizable default value for jsonMapper

* reafactor: better typings and format
  • Loading branch information
maryiabydanova authored Dec 12, 2021
1 parent faebc52 commit 721e696
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 33 deletions.
38 changes: 30 additions & 8 deletions packages/xlsx-import/src/mappers/jsonMapper.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
type JsonMapper = <TJsonResult>(value: string) => TJsonResult | null;

export const jsonMapper: JsonMapper = <TJsonResult extends any>(value: string): TJsonResult | null => {
try {
return JSON.parse(value);
} catch (e) {
return null;
}
type JsonMapperSignature<TDefaultResult> = <TJsonResult>(value: string) => TJsonResult | TDefaultResult;

export type JsonMapper<TJsonResult> = JsonMapperSignature<TJsonResult> & {
default: <TDefaultResult>(value: TDefaultResult) => JsonMapper<TDefaultResult>;
};

interface IJsonMapperOptions<TDefaultResult> {
default: TDefaultResult;
}

const factory = <TDefaultResult>(options: Readonly<IJsonMapperOptions<TDefaultResult>>): JsonMapper<TDefaultResult> => {
const mapper: JsonMapper<TDefaultResult> = <TJsonResult>(json: string): TJsonResult | TDefaultResult => {
try {
return JSON.parse(json);
} catch (e) {
return options.default;
}
};

mapper.default = <TJSonResult>(defaultResult: TJSonResult) =>
factory<TJSonResult>({
...options,
default: defaultResult,
});

return mapper;
};

export const jsonMapper = factory({
default: null,
});
32 changes: 32 additions & 0 deletions packages/xlsx-import/tests/unit/mappers/jsonMapper.test.ts
Original file line number Diff line number Diff line change
@@ -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 });
});
});
});
26 changes: 1 addition & 25 deletions packages/xlsx-import/tests/unit/mappers/stringMapper.test.ts
Original file line number Diff line number Diff line change
@@ -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/', () => {
Expand Down Expand Up @@ -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 = [
Expand Down

0 comments on commit 721e696

Please sign in to comment.