From 9960a1324a2a661b8f256597f84b1a1608e6d036 Mon Sep 17 00:00:00 2001 From: Arturo Riveron Borodovisina Date: Wed, 16 Mar 2022 15:12:03 +0100 Subject: [PATCH] test(utils): increase test coverage chunk 1 --- src/util.js | 2 +- test/tests/util/awaitKey.js | 28 +++++ test/tests/util/commons.js | 130 ++++++++++++++++++++++++ test/tests/util/deserializePrimitive.js | 38 +++++++ test/tests/util/dotify.js | 21 +++- test/tests/util/extend.js | 22 ++++ test/tests/util/get.js | 38 +++++++ test/tests/util/index.js | 11 ++ test/tests/util/match.js | 13 +++ test/tests/util/patch.js | 23 +++++ test/tests/util/promiseDebounce.js | 28 +++++ test/tests/util/safeInterval.js | 15 +++ test/tests/util/stringify.js | 13 +++ test/tests/util/stringifyError.js | 108 ++++++++++++++++++++ test/tests/util/values.js | 25 +++++ 15 files changed, 512 insertions(+), 3 deletions(-) create mode 100644 test/tests/util/awaitKey.js create mode 100644 test/tests/util/commons.js create mode 100644 test/tests/util/deserializePrimitive.js create mode 100644 test/tests/util/get.js create mode 100644 test/tests/util/match.js create mode 100644 test/tests/util/patch.js create mode 100644 test/tests/util/promiseDebounce.js create mode 100644 test/tests/util/safeInterval.js create mode 100644 test/tests/util/stringify.js create mode 100644 test/tests/util/stringifyError.js create mode 100644 test/tests/util/values.js diff --git a/src/util.js b/src/util.js index 30af21b4..a231b834 100644 --- a/src/util.js +++ b/src/util.js @@ -557,7 +557,7 @@ export function objFilter(obj : { [string] : T }, filter? : (T, ?string) = const result = {}; for (const key in obj) { - if (!obj.hasOwnProperty(key) || !filter(obj[key], key)) { + if (!obj.hasOwnProperty(key) || (filter && !filter(obj[key], key))) { continue; } diff --git a/test/tests/util/awaitKey.js b/test/tests/util/awaitKey.js new file mode 100644 index 00000000..ccd82121 --- /dev/null +++ b/test/tests/util/awaitKey.js @@ -0,0 +1,28 @@ +/* @flow */ + +import { awaitKey } from '../../../src'; + +describe('awaitKey cases', () => { + it('awaitKey should return the value when existing', () => { + const obj = { + custom: true + }; + const result = awaitKey(obj, 'custom'); + + if (!result) { + throw new Error(`should return "true", but got: ${ result }`); + } + }); + + it('awaitKey should return the configured value when does not exists', () => { + const obj = {}; + + awaitKey(obj, 'custom'); + obj.custom = 'result'; + const result = obj.custom; + + if (result !== 'result') { + throw new Error(`should return "result", but got: ${ result }`); + } + }); +}); diff --git a/test/tests/util/commons.js b/test/tests/util/commons.js new file mode 100644 index 00000000..00a33680 --- /dev/null +++ b/test/tests/util/commons.js @@ -0,0 +1,130 @@ +/* @flow */ + +import { + perc, min, max, roundUp, regexMap, svgToBase64, + objFilter, regexTokenize, camelToDasherize, dasherizeToCamel, + capitalizeFirstLetter, arrayFrom, isObject, isObjectObject +} from '../../../src/util'; + +describe('util cases', () => { + const sourceValues = [ 7, 30, 1 ]; + + it('perc', () => { + const result = perc(1000, 50); + + if (result !== 500) { + throw new Error(`should return the value "500", but got: ${ result }`); + } + }); + + it('min', () => { + const result = min(...sourceValues); + + if (result !== 1) { + throw new Error(`should return the minimum value "1", but got: ${ result }`); + } + }); + + it('max', () => { + const result = max(...sourceValues); + + if (result !== 30) { + throw new Error(`should return the maximum value "30", but got: ${ result }`); + } + }); + + it('roundUp', () => { + const result = roundUp(10, 5); + + if (result !== 10) { + throw new Error(`should return the roundUp value "10", but got: ${ result }`); + } + }); + + it('roundUp', () => { + const result = roundUp(10, 6); + + if (result !== 12) { + throw new Error(`should return the roundUp value "12", but got: ${ result }`); + } + }); + + it('regexMap', () => { + const expectedResult = 'test'; + // $FlowFixMe incompatible-call + const result = regexMap(expectedResult, /[a-z]*/); + + if (result[0] !== expectedResult) { + throw new Error(`should get the value "${ expectedResult }", but got: ${ String(result) }`); + } + }); + + it('svgToBase64', () => { + const expectedResult = 'data:image/svg+xml;base64,YQ'; + // $FlowFixMe incompatible-call + const result = svgToBase64('a'); + + if (result !== expectedResult) { + throw new Error(`should get the value "${ expectedResult }", but got: ${ String(result) }`); + } + }); + + it('objFilter', () => { + const result = objFilter({ value: true, value1: false }, value => value); + + if (!result.value) { + throw new Error(`should get the value "true" from key, but got: ${ String(result) }`); + } + }); + + it('regexTokenize', () => { + const expectedResult = 'test'; + const result = regexTokenize(expectedResult, /[a-z]+/); + + if (result[0] !== expectedResult) { + throw new Error(`should get the value "${ expectedResult }" from key, but got: ${ String(result) }`); + } + }); + + it('camelToDasherize and dasherizeToCamel', () => { + const dasherize = camelToDasherize('TestCase'); + const undasherize = dasherizeToCamel(dasherize); + + if (dasherize !== '-test-case' || undasherize !== 'TestCase') { + throw new Error(`should dasherize and undasherize values, but got dasherize: ${ String(dasherize) } and undasherize: ${ undasherize }`); + } + }); + + it('capitalizeFirstLetter', () => { + const expectedResult = 'Test'; + const result = capitalizeFirstLetter('test'); + + if (result !== expectedResult) { + throw new Error(`should return the value "${ expectedResult }", but got ${ String(result) }`); + } + }); + + it('arrayFrom', () => { + const result = arrayFrom([ 1, 2, 3 ]); + + if (result.length !== 3) { + throw new Error(`should return an array with length "3", but got ${ String(result) }`); + } + }); + + it('isObject', () => { + const result = isObject({}); + + if (!result) { + throw new Error(`should return the value "true", but got ${ String(result) }`); + } + }); + + it('isObjectObject', () => { + const result = isObjectObject({}); + + if (!result) { + throw new Error(`should return the value "true", but got ${ String(result) }`); + } + }); +}); diff --git a/test/tests/util/deserializePrimitive.js b/test/tests/util/deserializePrimitive.js new file mode 100644 index 00000000..08b12966 --- /dev/null +++ b/test/tests/util/deserializePrimitive.js @@ -0,0 +1,38 @@ +/* @flow */ + +import { deserializePrimitive } from '../../../src'; + +describe('deserializePrimitive cases', () => { + it('deserializePrimitive should return true', () => { + const result = deserializePrimitive('true'); + + if (result !== true) { + throw new Error(`should return "true", but got: ${ String(result) }`); + } + }); + + it('deserializePrimitive should return false', () => { + const result = deserializePrimitive('false'); + + if (result !== false) { + throw new Error(`should return "true", but got: ${ String(result) }`); + } + }); + + it('deserializePrimitive should return numeric value', () => { + const result = deserializePrimitive('10'); + + if (result !== 10) { + throw new Error(`should return "true", but got: ${ String(result) }`); + } + }); + + + it('deserializePrimitive should return float value', () => { + const result = deserializePrimitive('10.57'); + + if (result !== 10.57) { + throw new Error(`should return "true", but got: ${ String(result) }`); + } + }); +}); diff --git a/test/tests/util/dotify.js b/test/tests/util/dotify.js index d146e667..22281efb 100644 --- a/test/tests/util/dotify.js +++ b/test/tests/util/dotify.js @@ -5,7 +5,6 @@ import { dotify, undotify } from '../../../src'; describe('dotify cases', () => { it('should dotify and undotify to give the same result', () => { - const data = { foo: 'bar', baz: [ 1, 2, 3 ], @@ -18,7 +17,8 @@ describe('dotify cases', () => { }, zorg: 'zerg', berk: 'me,erk' - } + }, + func: () => true }; const dotified = dotify(data); @@ -28,4 +28,21 @@ describe('dotify cases', () => { throw new Error(`Does not match. Original data:\n\n${ JSON.stringify(data, null, 4) }\n\nDotified:\n\n${ JSON.stringify(dotified, null, 4) }\n\nUndotified:\n\n${ JSON.stringify(undotified, null, 4) }`); } }); + + it('undotify should throw an error', () => { + const expectedErrorMessage = 'Disallowed key: constructor'; + const data = { + 'test': Object.prototype, + 'constructor.part': 'error' + }; + + try { + // $FlowFixMe incompatible-type + undotify(data); + } catch (err) { + if (err.message !== expectedErrorMessage) { + throw new Error(`should throw the error message "${ expectedErrorMessage }", but got: ${ err.message }`); + } + } + }); }); diff --git a/test/tests/util/extend.js b/test/tests/util/extend.js index 28036e02..9e84e88e 100644 --- a/test/tests/util/extend.js +++ b/test/tests/util/extend.js @@ -4,6 +4,15 @@ import { extend } from '../../../src'; describe('extend cases', () => { + it('should return same object when second argument is empty', () => { + const result = extend({ a: true }); + const arrayResult = Object.entries(result).flat(); + + if (arrayResult[0] !== 'a' || !arrayResult[1]) { + throw new Error(`should return the exact same first argument object, but got: ${ String(result) }`); + } + }); + it('should add keys from one object to another', () => { const obj1 : Object = { 'foo': 1, @@ -31,4 +40,17 @@ describe('extend cases', () => { throw new Error(`Expected obj1.bloop to equal 6, got ${ obj1.bloop }`); } }); + + it('should return the extend object when Object.assign is not valid', () => { + const originalFunc = Object.assign; + Reflect.deleteProperty(Object, 'assign'); + const result = extend({ a: true }, { b: false }); + const arrayResult = Object.entries(result).flat(); + + if (arrayResult[0] !== 'a' || !arrayResult[1] || + arrayResult[2] !== 'b' || arrayResult[3]) { + throw new Error(`should return the extended object, but got: ${ String(result) }`); + } + Reflect.defineProperty(Object, 'assign', originalFunc); + }); }); diff --git a/test/tests/util/get.js b/test/tests/util/get.js new file mode 100644 index 00000000..717db33f --- /dev/null +++ b/test/tests/util/get.js @@ -0,0 +1,38 @@ +/* @flow */ + +import { get } from '../../../src'; + +describe('get cases', () => { + const expectedResult = 10; + it('get should return default value', () => { + const result = get({}, '', expectedResult); + + if (result !== expectedResult) { + throw new Error(`should return value "10", but got: ${ String(result) }`); + } + }); + + it('get should get deep keys', () => { + const result = get({ value: { result: expectedResult } }, 'value.result'); + + if (result !== expectedResult) { + throw new Error(`should return value "true", but got: ${ String(result) }`); + } + }); + + it('get should get deep keys', () => { + const result = get({ value: { result: expectedResult } }, 'value.result'); + + if (result !== expectedResult) { + throw new Error(`should return value "true", but got: ${ String(result) }`); + } + }); + + it('get should get deep keys with default value', () => { + const result = get({}, 'value.result', expectedResult); + + if (result !== expectedResult) { + throw new Error(`should return value "true", but got: ${ String(result) }`); + } + }); +}); diff --git a/test/tests/util/index.js b/test/tests/util/index.js index db9658a8..d28366da 100644 --- a/test/tests/util/index.js +++ b/test/tests/util/index.js @@ -7,7 +7,18 @@ import './extend'; import './serialize'; import './domainMatches'; import './identity'; +import './stringify'; +import './stringifyError'; import './stringifyErrorMessage'; import './isRegex'; import './isDefined'; import './base64encode'; +import './patch'; +import './match'; +import './awayKey'; +import './values'; +import './commons'; +import './promiseDebounce'; +import './safeInterval'; +import './deserializePrimitive'; +import './get'; diff --git a/test/tests/util/match.js b/test/tests/util/match.js new file mode 100644 index 00000000..4aeaa8fb --- /dev/null +++ b/test/tests/util/match.js @@ -0,0 +1,13 @@ +/* @flow */ + +import { match } from '../../../src'; + +describe('match cases', () => { + it('match should return original function', () => { + const result = match('letters', /(t[a-z]*)/i); + + if (result !== 'tters') { + throw new Error(`should return "tters", but got: ${ String(result) }`); + } + }); +}); diff --git a/test/tests/util/patch.js b/test/tests/util/patch.js new file mode 100644 index 00000000..a07ec47e --- /dev/null +++ b/test/tests/util/patch.js @@ -0,0 +1,23 @@ +/* @flow */ + +import { patchMethod } from '../../../src'; + +describe('patchMethod cases', () => { + it('patchMethod should return original function', () => { + const obj = { + custom() : string { + return 'first'; + } + }; + const handler = ({ callOriginal }) => { + return callOriginal(); + }; + + patchMethod(obj, 'custom', handler); + const result = obj.custom(); + + if (result !== 'first') { + throw new Error(`should return "first", but got: ${ result }`); + } + }); +}); diff --git a/test/tests/util/promiseDebounce.js b/test/tests/util/promiseDebounce.js new file mode 100644 index 00000000..8fff71fb --- /dev/null +++ b/test/tests/util/promiseDebounce.js @@ -0,0 +1,28 @@ +/* @flow */ + +import { promiseDebounce } from '../../../src'; + +describe('promiseDebounce cases', () => { + it('promiseDebounce should return original function', () => { + const debouncedFunc = promiseDebounce(() => true); + const result = debouncedFunc(); + + if (!debouncedFunc()) { + throw new Error(`should return the value "true", but got: ${ String(result) }`); + } + }); + + it('promiseDebounce should throw and error', () => { + const debouncedFunc = promiseDebounce(() => { + throw new Error('unexpected'); + }); + + debouncedFunc() + .catch(err => { + // $FlowFixMe incompatible-type + if (err.message !== 'unexpected') { + throw new Error(`should throw the error message "unexpected", but got: ${ err.message }`); + } + }); + }); +}); diff --git a/test/tests/util/safeInterval.js b/test/tests/util/safeInterval.js new file mode 100644 index 00000000..96bf6003 --- /dev/null +++ b/test/tests/util/safeInterval.js @@ -0,0 +1,15 @@ +/* @flow */ + +import { safeInterval } from '../../../src'; + +describe('safeInterval cases', () => { + it('safeInterval should safely debounce the function', () => { + safeInterval(() => true, 50); + }); + + it('safeInterval should cancel the debounced function', () => { + const result = safeInterval(() => true, 50); + + result.cancel(); + }); +}); diff --git a/test/tests/util/stringify.js b/test/tests/util/stringify.js new file mode 100644 index 00000000..d3b09a8f --- /dev/null +++ b/test/tests/util/stringify.js @@ -0,0 +1,13 @@ +/* @flow */ + +import { stringify } from '../../../src'; + +describe('stringify cases', () => { + it('stringify should return the exact same value when is a string value', () => { + const result = stringify('1'); + + if (result !== '1') { + throw new Error(`should return value "1", but got: ${ result }`); + } + }); +}); diff --git a/test/tests/util/stringifyError.js b/test/tests/util/stringifyError.js new file mode 100644 index 00000000..53f3dfd8 --- /dev/null +++ b/test/tests/util/stringifyError.js @@ -0,0 +1,108 @@ +/* @flow */ + +import { stringifyError } from '../../../src'; + +describe('stringifyError cases', () => { + it('stringifyError should return stack overflow error message', () => { + const expectedResult = 'stringifyError stack overflow'; + const result = stringifyError('custom error', 4); + + if (result !== expectedResult) { + throw new Error(`should throw the error message "${ expectedResult }", but got: ${ result }`); + } + }); + + it('stringifyError should return unknown error message', () => { + const expectedResult = ``; + const result = stringifyError(0, 1); + + if (result !== expectedResult) { + throw new Error(`should throw the error messagee "${ expectedResult }", but got: ${ result }`); + } + }); + + it('stringifyError should return the exact same error message when is a string type', () => { + const expectedResult = `my error`; + const result = stringifyError(expectedResult, 1); + + if (result !== expectedResult) { + throw new Error(`should throw the error message "${ expectedResult }", but got: ${ result }`); + } + }); + + it('stringifyError should return only the stack when is an Error instance', () => { + const expectedResult = `custom`; + const error = new Error(expectedResult); + const result = stringifyError(error, 1); + + if (!result.startsWith(`Error: ${ expectedResult }`)) { + throw new Error(`should throw the error message starting with "Error: ${ expectedResult }", but got: ${ result }`); + } + }); + + it('stringifyError should return the only the stack when is an Error instance with empty message', () => { + const expectedResult = `at Context.`; + const error = new Error('anything not important'); + + error.message = ''; + const result = stringifyError(error, 1); + + if (!result.includes(expectedResult)) { + throw new Error(`should throw the error message starting with "${ expectedResult }", but got: ${ result }`); + } + }); + + it('stringifyError should return the only the message when is an Error instance with empty stack', () => { + const expectedResult = `error instance`; + const error = new Error(expectedResult); + + error.stack = ''; + const result = stringifyError(error, 1); + + if (result !== expectedResult) { + throw new Error(`should throw the error message "${ expectedResult }", but got: ${ result }`); + } + }); + + it('stringifyError should return the message and stack when is and Error instance and message is not include in the stack', () => { + const expectedErrorMessage = 'Error: custom at line whatever'; + const error = new Error('custom'); + + error.message = 'message'; + error.stack = expectedErrorMessage; + const result = stringifyError(error, 1); + + if (!result.endsWith(expectedErrorMessage)) { + throw new Error(`should throw the error message ending with "${ expectedErrorMessage }", but got: ${ result }`); + } + }); + + it('stringifyError should return call toString when error message is an object', () => { + const expectedErrorMessage = '[object Object]'; + const result = stringifyError({}, 1); + + if (result !== expectedErrorMessage) { + throw new Error(`should throw the error message "${ expectedErrorMessage }", but got: ${ result }`); + } + }); + + it('stringifyError should return call toString from Object.prototype when error message is object', () => { + const expectedErrorMessage = '[object Object]'; + const result = stringifyError({ toString: null }, 1); + + if (result !== expectedErrorMessage) { + throw new Error(`should throw the error message "${ expectedErrorMessage }", but got: ${ result }`); + } + }); + + it('stringifyError should handle error when something when wrong', () => { + const expectedErrorMessage = 'Error while stringifying error'; + const result = stringifyError({ toString: () => { + throw new Error('unexpected error'); + } }, 2); + + if (!result.startsWith(expectedErrorMessage)) { + throw new Error(`should throw the error message starting wit "${ expectedErrorMessage }", but got: ${ result }`); + } + }); +}); diff --git a/test/tests/util/values.js b/test/tests/util/values.js new file mode 100644 index 00000000..238676a0 --- /dev/null +++ b/test/tests/util/values.js @@ -0,0 +1,25 @@ +/* @flow */ + +import { values } from '../../../src'; + +describe('values cases', () => { + + it('should return object values when Object.values is available', () => { + const result = values({ a: true }); + + if (!result[0]) { + throw new Error(`should return the value from the original object, but got: ${ String(result) }`); + } + }); + + it('should return object values when Object.values is unavailable', () => { + const originalFunc = Object.values; + Reflect.deleteProperty(Object, 'values'); + const result = values({ a: true }); + + if (!result[0]) { + throw new Error(`should return the value from the original object, but got: ${ String(result) }`); + } + Reflect.defineProperty(Object, 'values', originalFunc); + }); +});