From ef34ea04aa66e69c3f8423172b52cd5505413e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20D=C3=ADaz?= Date: Wed, 6 Jun 2018 16:56:12 -0600 Subject: [PATCH] Adding basic tests to shared utilities. (#35) --- src/__tests__/requestCache.spec.js | 2 +- src/__tests__/shared.spec.js | 75 ++++++++++++++++++++++++++++++ src/requestCache.js | 8 ++-- src/shared.js | 11 ++--- 4 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 src/__tests__/shared.spec.js diff --git a/src/__tests__/requestCache.spec.js b/src/__tests__/requestCache.spec.js index ed6350b..7a3ab38 100644 --- a/src/__tests__/requestCache.spec.js +++ b/src/__tests__/requestCache.spec.js @@ -69,7 +69,7 @@ describe('Request Cache', () => { }); it('should return an object when given an undefined value', () => { - expect(Object.keys(cache.parse(undefined)).length).toBe(0); + expect(cache.parse(undefined)).toEqual({}); }); it('should parse any value other than undefined', () => { diff --git a/src/__tests__/shared.spec.js b/src/__tests__/shared.spec.js new file mode 100644 index 0000000..ae2c81d --- /dev/null +++ b/src/__tests__/shared.spec.js @@ -0,0 +1,75 @@ +const { + requestRegex, + replacementRegex, + dynamicValueRegex, + UpperCaseKeys, + removeOptionalKeys, + toKebabCase, + replaceInObject +} = require('../shared'); + +describe('Shared Utilities', () => { + describe('requestRegex', () => { + test.each([ + ['GET /hello', true], + ['HEAD /hello', true], + ['POST /hello', true], + ['PUT /hello', true], + ['DELETE /hello', true], + ['CONNECT /hello', true], + ['OPTIONS /hello', true], + ['TRACE /hello', true], + ['PATCH /hello', true] + ])('should match: %s', (example, expected) => { + expect(requestRegex.test(example)).toBe(expected); + }); + }); + + describe('replacementRegex', () => { + test.each([ + ['$a.b', ['$a.b']], + ['GET /hello/$a.name', ['$a.name']], + ['PUT /hi/$a.a/$a.b', ['$a.a', '$a.b']], + [`\\$value`, ['\\$value']] + ])('should match: %s', (example, expected) => { + expect(example.match(replacementRegex)).toEqual(expected); + }); + }); + + describe('dynamicValueRegex', () => { + test.each([ + ['$[test()]', ['$[test()]']], + ['$[test(1, 2, 3)]', ['$[test(1, 2, 3)]']], + [`$[test({ \n id: 1 \n })]`, ['$[test({ \n id: 1 \n })]']] + ])('should match: %s', (example, expected) => { + expect(example.match(dynamicValueRegex)).toEqual(expected); + }); + }); + + describe('UpperCaseKeys', () => { + it('should uppercase all first-level keys in an object', () => { + let a = { test: 1, Test2: 2 }; + expect(UpperCaseKeys(a)).toEqual({ TEST: 1, TEST2: 2 }); + }); + }); + + describe('removeOptionalKeys', () => { + it('should remove empty objects from an object', () => { + let a = { b: {}, c: 2, d: {} }; + expect(removeOptionalKeys(a, ['b', 'd'])).toEqual({ c: 2 }); + }); + }); + + describe('toKebabCase', () => { + it('should convert camel case to kebab case', () => { + expect(toKebabCase('helloWorld')).toBe('hello-world'); + }); + }); + + describe('replaceInObject', () => { + it('should replace every value in an object with the output of a function', () => { + let a = { b: 'b', c: 'c' }; + expect(replaceInObject(a, obj => 'a')).toEqual({ b: 'a', c: 'a' }); + }); + }); +}); diff --git a/src/requestCache.js b/src/requestCache.js index da10d4e..43b591d 100644 --- a/src/requestCache.js +++ b/src/requestCache.js @@ -31,15 +31,15 @@ class RequestCache { return null; } - return replaceInObject(item, item => { - return item.replace(replacementRegex, (match, key) => { + return replaceInObject(item, item => + item.replace(replacementRegex, (match, key) => { if (match.startsWith('\\')) { return match.replace('\\$', '$'); } return this.get(key); - }); - }); + }) + ); } } diff --git a/src/shared.js b/src/shared.js index 8a7e68b..4b0404d 100644 --- a/src/shared.js +++ b/src/shared.js @@ -20,15 +20,14 @@ const UpperCaseKeys = function(obj) { return result; }; +const isEmptyObject = obj => + Object.keys(obj).length === 0 && obj.constructor === Object; + const removeOptionalKeys = function(obj, optionalValues) { let result = {}; Object.keys(obj).forEach(key => { - if ( - optionalValues.includes(key) && - (Object.keys(obj[key]).length === 0 && - obj[key].constructor === Object) - ) { + if (optionalValues.includes(key) && isEmptyObject(obj[key])) { return; } @@ -42,7 +41,6 @@ const toKebabCase = function(str) { return str .trim() .replace(/([a-z])([A-Z])/g, '$1-$2') - .replace(/\s+/g, '-') .toLowerCase(); }; @@ -62,6 +60,7 @@ const replaceInObject = function(obj, fn) { } if (type === 'object') { + obj = Object.assign({}, obj); Object.keys(obj).forEach(k => (obj[k] = replaceInObject(obj[k], fn))); }