Merge pull request #15 from pleshevskiy/bug-14

fix: filter undefined variable values
This commit is contained in:
Dmitriy Pleshevskiy 2020-11-06 03:48:05 +02:00
commit e303485f58
6 changed files with 5639 additions and 22 deletions

8
jest.config.js Normal file
View file

@ -0,0 +1,8 @@
module.exports = {
testRegex: 'tests/.*\\.spec\\.ts',
testEnvironment: 'jsdom',
preset: 'ts-jest',
moduleFileExtensions: ['ts', 'js', 'json'],
collectCoverage: true,
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.d.ts'],
};

5517
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,9 @@
"target" "target"
], ],
"scripts": { "scripts": {
"prepublishOnly": "tsc" "test": "jest",
"prepublishOnly": "tsc",
"report-coverage": "cat coverage/lcov.info | coveralls"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -34,6 +36,7 @@
"tiny-invariant": "^1.1.0" "tiny-invariant": "^1.1.0"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^26.0.15",
"@types/lodash.isequal": "^4.5.5", "@types/lodash.isequal": "^4.5.5",
"@types/react": "^16.9.55", "@types/react": "^16.9.55",
"@typescript-eslint/eslint-plugin": "^4.6.1", "@typescript-eslint/eslint-plugin": "^4.6.1",
@ -41,6 +44,8 @@
"eslint": "^7.12.1", "eslint": "^7.12.1",
"eslint-plugin-react": "^7.21.5", "eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-hooks": "^4.2.0",
"jest": "^26.6.3",
"ts-jest": "^26.4.3",
"typescript": "^4.0.5" "typescript": "^4.0.5"
} }
} }

View file

@ -5,29 +5,37 @@ export function isObject(val: any) {
export function formDataFromObject(obj: Record<string, any>) { export function formDataFromObject(obj: Record<string, any>) {
const formData = new FormData(); const formData = new FormData();
for (const [key, value] of Object.entries(obj)) { Object.entries(obj)
.filter(([_, value]) => value !== undefined)
.forEach(([key, value]) => {
if (Array.isArray(value)) { if (Array.isArray(value)) {
value.forEach(val => formData.append(key, val)); value
.filter(val => val !== undefined)
.forEach(val => formData.append(key, val));
} else if (isObject(value)) { } else if (isObject(value)) {
formData.set(key, JSON.stringify(value)); formData.set(key, JSON.stringify(value));
} else { } else {
formData.set(key, value); formData.set(key, value);
} }
} });
return formData; return formData;
} }
export function urlSearchParamsFromObject(obj: Record<string, any>) { export function urlSearchParamsFromObject(obj: Record<string, any>) {
const searchParams = new URLSearchParams(); const searchParams = new URLSearchParams();
for (const [key, value] of Object.entries(obj)) { Object.entries(obj)
.filter(([_, value]) => value !== undefined)
.forEach(([key, value]) => {
if (Array.isArray(value)) { if (Array.isArray(value)) {
const arrayKey = `${key}[]`; const arrayKey = `${key}[]`;
value.forEach(val => searchParams.append(arrayKey, val)); value
.filter(val => val !== undefined)
.forEach(val => searchParams.append(arrayKey, val));
} else { } else {
searchParams.set(key, value); searchParams.set(key, value);
} }
} });
return searchParams; return searchParams;
} }

81
tests/misc.spec.ts Normal file
View file

@ -0,0 +1,81 @@
import { formDataFromObject, isObject, urlSearchParamsFromObject } from '../src/misc';
describe('misc', () => {
describe('isObject', () => {
it('should return thruthy successfully', () => {
expect(isObject({})).toBeTruthy();
});
it('should return falsy', () => {
expect(isObject(1)).toBeFalsy();
expect(isObject(true)).toBeFalsy();
expect(isObject('')).toBeFalsy();
expect(isObject([])).toBeFalsy();
expect(isObject(function () { return null; })).toBeFalsy();
expect(isObject(null)).toBeFalsy();
expect(isObject(undefined)).toBeFalsy();
expect(isObject(NaN)).toBeFalsy();
expect(isObject(Infinity)).toBeFalsy();
});
});
describe('formDataFromObject', () => {
it('should convert object to form data successfully', () => {
const formData = formDataFromObject({
id: 1,
name: 'John',
status: ['ACTIVE', 'NOT_ACTIVE'],
user: {
name: 'John'
}
});
expect(formData).toBeInstanceOf(FormData);
expect(formData.get('id')).toBe('1');
expect(formData.get('name')).toBe('John');
expect(formData.getAll('status')).toEqual(['ACTIVE', 'NOT_ACTIVE']);
expect(formData.get('user')).toBe('{"name":"John"}');
});
it('should filter undefined values successfully', () => {
const formData = formDataFromObject({
id: undefined,
status: [undefined],
});
expect(formData.has('id')).toBeFalsy();
expect(formData.has('status')).toBeFalsy();
});
});
describe('urlSearchParamsFromObject', () => {
it('should convert object to search params successfully', () => {
const searchParams = urlSearchParamsFromObject({
id: 1,
name: 'John',
status: ['ACTIVE', 'NOT_ACTIVE']
});
expect(searchParams).toBeInstanceOf(URLSearchParams);
expect(searchParams.toString()).toBe('id=1&name=John&status%5B%5D=ACTIVE&status%5B%5D=NOT_ACTIVE');
});
it('should encode value as uri component successfully', () => {
const searchParams = urlSearchParamsFromObject({
name: '@',
});
expect(searchParams.toString()).toBe('name=%40');
});
it('should filter undefined values successfully', () => {
const searchParams = urlSearchParamsFromObject({
id: 1,
name: undefined,
status: ['ACTIVE', undefined],
});
expect(searchParams.toString()).toBe('id=1&status%5B%5D=ACTIVE');
});
});
});

View file

@ -14,9 +14,9 @@
"strict": true, "strict": true,
"strictNullChecks": true, "strictNullChecks": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"declaration": true, "declaration": true
}, },
"include": [ "include": [
"src" "src",
], ]
} }