From 351a563b3cfae16db62a95d5c2011544ddad7295 Mon Sep 17 00:00:00 2001 From: Erik Rasmussen Date: Tue, 18 Apr 2017 10:33:19 +0200 Subject: [PATCH 1/2] Upgraded deps, fixed build, added code cov --- .eslintrc | 11 +- .travis.yml | 15 +- LICENSE | 2 +- package.json | 31 ++-- src/__tests__/deepEquals.spec.js | 110 +++++++++++++ src/__tests__/memoize.spec.js | 180 +++++++++++++++++++++ src/deepEquals.js | 50 +++--- src/index.js | 4 +- src/lruCache.js | 20 +-- src/memoize.js | 48 +++--- src/singletonCache.js | 9 +- test/deepEquals.spec.js | 171 -------------------- test/memoize.js | 264 ------------------------------- webpack.config.base.js | 10 -- 14 files changed, 388 insertions(+), 537 deletions(-) create mode 100644 src/__tests__/deepEquals.spec.js create mode 100644 src/__tests__/memoize.spec.js delete mode 100644 test/deepEquals.spec.js delete mode 100644 test/memoize.js diff --git a/.eslintrc b/.eslintrc index c0645a3..5e603ec 100755 --- a/.eslintrc +++ b/.eslintrc @@ -1,12 +1,3 @@ { - "extends": "eslint-config-airbnb", - "env": { - "browser": true, - "mocha": true, - "node": true - }, - "rules": { - "comma-dangle": 0, // not sure why airbnb turned this on. gross! - "indent": [2, 2, {"SwitchCase": 1}] - } + "extends": "react-app" } diff --git a/.travis.yml b/.travis.yml index d2e4fff..46e5b2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,18 @@ language: node_js +before_install: + - npm install -g npm@latest + node_js: - - "4.0" - - "4" - - "6.0" - "6" + - "5" + - "4" + - "stable" script: - npm run lint - - npm test \ No newline at end of file + - npm test + +after_success: + - npm run test:cov + - npm run test:codecov \ No newline at end of file diff --git a/LICENSE b/LICENSE index 4f01f58..db83739 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 Erik Rasmussen +Copyright (c) 2017 Erik Rasmussen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/package.json b/package.json index 53e0902..28d3711 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,9 @@ "clean": "rimraf dist lib", "lint": "eslint src", "prepublish": "npm run lint && npm run test && npm run clean && npm run build", - "test": "mocha --compilers js:babel-register --recursive" + "test": "mocha --compilers js:babel-register --recursive \"src/**/__tests__/*\"", + "test:cov": "cross-env NODE_ENV=test nyc --reporter=lcov --reporter=text npm test", + "test:codecov": "cat ./coverage/lcov.info | ./node_modules/codecov.io/bin/codecov.io.js" }, "keywords": [ "memoize", @@ -31,21 +33,22 @@ }, "homepage": "https://github.com/erikras/lru-memoize", "devDependencies": { - "babel-cli": "^6.23.0", - "babel-core": "^6.23.1", - "babel-eslint": "^7.1.1", - "babel-loader": "^6.3.1", - "babel-preset-es2015": "^6.22.0", - "babel-register": "^6.23.0", - "eslint": "^3.15.0", - "eslint-config-airbnb": "14.1.0", - "eslint-plugin-import": "^2.2.0", - "eslint-plugin-jsx-a11y": "^4.0.0", - "eslint-plugin-react": "^6.9.0", + "babel-cli": "^6.24.1", + "babel-core": "^6.24.1", + "babel-eslint": "^7.2.2", + "babel-loader": "^6.4.1", + "babel-preset-es2015": "^6.24.1", + "babel-register": "^6.24.1", + "codecov.io": "^0.1.6", + "cross-env": "^4.0.0", + "eslint": "^3.19.0", + "eslint-config-react-app": "^0.6.2", + "eslint-plugin-flowtype": "^2.30.4", "expect": "^1.20.2", "mocha": "^3.2.0", + "nyc": "^10.2.0", "rifraf": "^2.0.3", - "rimraf": "^2.5.4", - "webpack": "^2.2.1" + "rimraf": "^2.6.1", + "webpack": "^2.4.1" } } diff --git a/src/__tests__/deepEquals.spec.js b/src/__tests__/deepEquals.spec.js new file mode 100644 index 0000000..cef1a3c --- /dev/null +++ b/src/__tests__/deepEquals.spec.js @@ -0,0 +1,110 @@ +import expect from 'expect' +import deepEquals from '../deepEquals' + +const tripleEquals = deepEquals((valueA, valueB) => valueA === valueB, true) + +describe('deepEquals', () => { + it('should return true if argument fields are equal', () => { + expect(tripleEquals(3, 3)).toBe(true) + + expect(tripleEquals('dog', 'dog')).toBe(true) + + expect( + tripleEquals({ a: 1, b: 2, c: undefined }, { a: 1, b: 2, c: undefined }) + ).toBe(true) + + expect(tripleEquals({ a: 1, b: 2, c: 3 }, { a: 1, b: 2, c: 3 })).toBe(true) + + const obj = {} + expect(tripleEquals({ a: 1, b: 2, c: obj }, { a: 1, b: 2, c: obj })).toBe( + true + ) + + expect(tripleEquals(null, null)).toBe(true) + }) + + it('should return false if arguments are number and string', () => { + expect(tripleEquals(2, '2')).toBe(false) + }) + + it('should return false if arguments are string and number', () => { + expect(tripleEquals('2', 2)).toBe(false) + }) + + it('should return false if arguments are number and object', () => { + expect(tripleEquals(4, {})).toBe(false) + }) + + it('should return false if arguments are object and number', () => { + expect(tripleEquals({}, 4)).toBe(false) + }) + + it('should return false if arguments are number and array', () => { + expect(tripleEquals(4, [])).toBe(false) + }) + + it('should return false if arguments are array and number', () => { + expect(tripleEquals([], 4)).toBe(false) + }) + + it('should return false if arguments are string and object', () => { + expect(tripleEquals('cat', {})).toBe(false) + }) + + it('should return false if arguments are object and string', () => { + expect(tripleEquals({}, 'cat')).toBe(false) + }) + + it('should return false if arguments are string and array', () => { + expect(tripleEquals('cat', ['c', 'a', 't'])).toBe(false) + }) + + it('should return false if arguments are array and string', () => { + expect(tripleEquals(['c', 'a', 't'], 'cat')).toBe(false) + }) + + it('should return false if arguments are array and object', () => { + expect(tripleEquals([], {})).toBe(false) + }) + + it('should return false if arguments are object and array', () => { + expect(tripleEquals({}, [])).toBe(false) + }) + + it('should return false if arguments are object and null', () => { + expect(tripleEquals({ a: 1 }, null)).toBe(false) + }) + + it('should return false if arguments are null and object', () => { + expect(tripleEquals(null, { a: 1 })).toBe(false) + }) + + it('should return false if first argument has too many keys', () => { + expect(tripleEquals({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 })).toBe(false) + }) + + it('should return false if second argument has too many keys', () => { + expect(tripleEquals({ a: 1, b: 2 }, { a: 1, b: 2, c: 3 })).toBe(false) + }) + + it('should return false if arguments have different keys', () => { + expect( + tripleEquals({ a: 1, b: 2, c: undefined }, { a: 1, bb: 2, c: undefined }) + ).toBe(false) + }) + + it('should return false if first array argument has too many items', () => { + expect(tripleEquals([1, 2, 3, 4], [1, 2, 3])).toBe(false) + }) + + it('should return false if second array argument has too many items', () => { + expect(tripleEquals([1, 2, 3], [1, 2, 3, 4])).toBe(false) + }) + + it('should work with objects inside arrays', () => { + expect(tripleEquals( + [ { val: 4 }, { val: 2 }, { val: 3 } ], + [ { val: 1 }, { val: 2 }, { val: 3 } ] + )).toBe(false) + }) +}) diff --git a/src/__tests__/memoize.spec.js b/src/__tests__/memoize.spec.js new file mode 100644 index 0000000..f066b53 --- /dev/null +++ b/src/__tests__/memoize.spec.js @@ -0,0 +1,180 @@ +import expect from 'expect' +import memoize from '../memoize' + +describe('memoize', () => { + describe('basic', () => { + it('single', () => { + let callCount = 0 + let multiply = (x, y, z) => { + callCount += 1 + return x * y * z + } + multiply = memoize()(multiply) + + expect(multiply(1, 2, 3)).toBe(6) + + expect(multiply(1, 2, 3)).toBe(6) + + expect(callCount).toBe(1) + + expect(multiply(4, 5, 6)).toBe(120) + + expect(callCount).toBe(2) + + expect(multiply(1, 2, 3)).toBe(6) + + expect(callCount).toBe(3) + }) + + it('multiple', () => { + let callCount = 0 + let multiply = (x, y, z) => { + callCount += 1 + return x * y * z + } + multiply = memoize(2)(multiply) + + expect(multiply(1, 2, 3)).toBe(6) + + expect(multiply(1, 2, 3)).toBe(6) + + expect(callCount).toBe(1) + + expect(multiply(4, 5, 6)).toBe(120) + + expect(callCount).toBe(2) + + expect(multiply(1, 2, 3)).toBe(6) + + expect(callCount).toBe(2) + + expect(multiply(4, 5, 6)).toBe(120) + + expect(callCount).toBe(2) + }) + }) + + describe('shallow', () => { + it('array', () => { + let callCount = 0 + let multiply = (x, y, z) => { + callCount += 1 + return x.concat(y, z).reduce((t, n) => t * n) + } + multiply = memoize()(multiply) + + const x = [1, 2, 3] + const y = [4, 5, 6] + const z = [7, 8, 9] + + const x2 = [1, 2, 3] + + expect(multiply(x, y, z)).toBe(362880) + + expect(multiply(x2, y, z)).toBe(362880) + + expect(callCount).toBe(2) + }) + + it('object', () => { + let callCount = 0 + let multiply = (x, y, z) => { + callCount += 1 + return x.val * y.val * z.val + } + multiply = memoize(2)(multiply) + + const x = { val: 1 } + const y = { val: 2 } + const z = { val: 3 } + + const x2 = { val: 1 } + + expect(multiply(x, y, z)).toBe(6) + + expect(multiply(x2, y, z)).toBe(6) + + expect(callCount).toBe(2) + }) + }) + + describe('deep', () => { + it('array', () => { + let callCount = 0 + let multiply = (x, y, z) => { + callCount += 1 + return x.concat(y, z).reduce((t, n) => t * n) + } + multiply = memoize(true)(multiply) + + const x = [1, 2, 3] + const y = [4, 5, 6] + const z = [7, 8, 9] + + const x2 = [1, 2, 3] + const x3 = [3, 2, 1] + + expect(multiply(x, y, z)).toBe(362880) + + expect(multiply(x2, y, z)).toBe(362880) + + expect(callCount).toBe(1) + + expect(multiply(x3, y, z)).toBe(362880) + + expect(callCount).toBe(2) + }) + + it('object', () => { + let callCount = 0 + let multiply = (x, y, z) => { + callCount += 1 + return x.val * y.val * z.val + } + multiply = memoize(true)(multiply) + + const x = { val: 1 } + const y = { val: 2 } + const z = { val: 3 } + + const x2 = { val: 1 } + const x3 = { val: 4 } + + expect(multiply(x, y, z)).toBe(6) + + expect(multiply(x2, y, z)).toBe(6) + + expect(callCount).toBe(1) + + expect(multiply(x3, y, z)).toBe(24) + + expect(callCount).toBe(2) + }) + + it('object nested', () => { + let callCount = 0 + let multiply = (x, y, z) => { + callCount += 1 + return x.inner.val * y.inner.val * z.inner.val + } + multiply = memoize(true)(multiply) + + const x = { inner: { val: 1 } } + const y = { inner: { val: 2 } } + const z = { inner: { val: 3 } } + + const x2 = { inner: { val: 1 } } + const x3 = { inner: { val: 4 } } + + expect(multiply(x, y, z)).toBe(6) + + expect(multiply(x2, y, z)).toBe(6) + + expect(callCount).toBe(1) + + expect(multiply(x3, y, z)).toBe(24) + + expect(callCount).toBe(2) + }) + }) +}) diff --git a/src/deepEquals.js b/src/deepEquals.js index 722e22c..088ffed 100755 --- a/src/deepEquals.js +++ b/src/deepEquals.js @@ -1,63 +1,67 @@ -const hasOwn = (object, key) => Object.prototype.hasOwnProperty.call(object, key); +const hasOwn = (object, key) => + Object.prototype.hasOwnProperty.call(object, key) export default function deepEquals(equals, deepObjects) { function deep(valueA, valueB) { if (equals(valueA, valueB)) { - return true; + return true } if (Array.isArray(valueA)) { if (!Array.isArray(valueB) || valueA.length !== valueB.length) { - return false; + return false } // Check deep equality of each value in A against the same indexed value in B if (!valueA.every((value, index) => deep(value, valueB[index]))) { - return false; + return false } // could not find unequal items - return true; + return true } if (Array.isArray(valueB)) { - return false; + return false } if (typeof valueA === 'object') { if (typeof valueB !== 'object') { - return false; + return false } - const isANull = valueA === null; - const isBNull = valueB === null; + const isANull = valueA === null + const isBNull = valueB === null if (isANull || isBNull) { - return isANull === isBNull; + return isANull === isBNull } - const aKeys = Object.keys(valueA); - const bKeys = Object.keys(valueB); + const aKeys = Object.keys(valueA) + const bKeys = Object.keys(valueB) if (aKeys.length !== bKeys.length) { - return false; + return false } // Should we compare with shallow equivalence or deep equivalence? - const equalityChecker = deepObjects ? deep : equals; + const equalityChecker = deepObjects ? deep : equals // Check if objects share same keys, and each of those keys are equal - if (!aKeys.every( - aKey => ( - hasOwn(valueA, aKey) && ( - hasOwn(valueB, aKey) || equalityChecker(valueA[aKey], valueB[aKey]) - ) + if ( + !aKeys.every( + aKey => + hasOwn(valueA, aKey) && + hasOwn(valueB, aKey) && + equalityChecker(valueA[aKey], valueB[aKey]) ) - )) { return false; } + ) { + return false + } // could not find unequal keys or values - return true; + return true } - return false; + return false } - return deep; + return deep } diff --git a/src/index.js b/src/index.js index 6697d2e..8691a6d 100755 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,3 @@ -import memoize from './memoize'; +import memoize from './memoize' -export default memoize; +export default memoize diff --git a/src/lruCache.js b/src/lruCache.js index 4a466bd..d554d53 100755 --- a/src/lruCache.js +++ b/src/lruCache.js @@ -1,34 +1,34 @@ export default function lruCache(limit, equals) { - const entries = []; + const entries = [] function get(key) { - const cacheIndex = entries.findIndex(entry => equals(key, entry.key)); + const cacheIndex = entries.findIndex(entry => equals(key, entry.key)) // We found a cached entry if (cacheIndex > -1) { - const entry = entries[cacheIndex]; + const entry = entries[cacheIndex] // Cached entry not at top of cache, move it to the top if (cacheIndex > 0) { - entries.slice(cacheIndex, 1); - entries.unshift(entry); + entries.slice(cacheIndex, 1) + entries.unshift(entry) } - return entry.value; + return entry.value } // No entry found in cache, return null - return undefined; + return undefined } function put(key, value) { if (!get(key)) { - entries.unshift({ key, value }); + entries.unshift({ key, value }) if (entries.length > limit) { - entries.pop(); + entries.pop() } } } - return { get, put }; + return { get, put } } diff --git a/src/memoize.js b/src/memoize.js index a8b049d..1320b6b 100755 --- a/src/memoize.js +++ b/src/memoize.js @@ -1,60 +1,62 @@ -import singletonCache from './singletonCache'; -import lruCache from './lruCache'; -import deepEquals from './deepEquals'; +import deepEquals from './deepEquals' +import lruCache from './lruCache' +import singletonCache from './singletonCache' function createCache(limit, equals) { - return limit === 1 ? singletonCache(equals) : lruCache(limit, equals); + return limit === 1 ? singletonCache(equals) : lruCache(limit, equals) } function createEqualsFn(basicEquals, deepObjects) { // Choose strategy for basic or deep object equals - const equals = deepObjects ? deepEquals(basicEquals, deepObjects) : basicEquals; + const equals = deepObjects + ? deepEquals(basicEquals, deepObjects) + : basicEquals return (valueA, valueB) => { // The arguments are always the argument array-like objects // Different lengths means they are not the same if (valueA.length !== valueB.length) { - return false; + return false } // Compare the values - for (let index = 0; index < valueA.length; index++) { + for (let index = 0; index < valueA.length; index += 1) { if (!equals(valueA[index], valueB[index])) { - return false; + return false } } // Found no conflicts - return true; - }; + return true + } } export default function memoize(...config) { - let limit = 1; - let equals = (valueA, valueB) => valueA === valueB; - let deepObjects = false; + let limit = 1 + let equals = (valueA, valueB) => valueA === valueB + let deepObjects = false if (typeof config[0] === 'number') { - limit = config.shift(); + limit = config.shift() } if (typeof config[0] === 'function') { - equals = config.shift(); + equals = config.shift() } else if (typeof config[0] === 'undefined') { // Support passing undefined equal argument; - config.shift(); + config.shift() } if (typeof config[0] === 'boolean') { - deepObjects = config[0]; + deepObjects = config[0] } - const cache = createCache(limit, createEqualsFn(equals, deepObjects)); + const cache = createCache(limit, createEqualsFn(equals, deepObjects)) return fn => (...args) => { - let value = cache.get(args); + let value = cache.get(args) if (value === undefined) { - value = fn.apply(fn, args); - cache.put(args, value); + value = fn.apply(fn, args) + cache.put(args, value) } - return value; - }; + return value + } } diff --git a/src/singletonCache.js b/src/singletonCache.js index cc146d4..e033559 100755 --- a/src/singletonCache.js +++ b/src/singletonCache.js @@ -1,15 +1,14 @@ export default function singletonCache(equals) { - let entry; + let entry return { get(key) { if (entry && equals(key, entry.key)) { - return entry.value; + return entry.value } - return null; }, put(key, value) { - entry = { key, value }; + entry = { key, value } } - }; + } } diff --git a/test/deepEquals.spec.js b/test/deepEquals.spec.js deleted file mode 100644 index 16715ec..0000000 --- a/test/deepEquals.spec.js +++ /dev/null @@ -1,171 +0,0 @@ -import expect from 'expect'; -import deepEquals from '../src/deepEquals'; - -const tripleEquals = deepEquals((valueA, valueB) => valueA === valueB); - -describe('deepEquals', () => { - it('should return true if argument fields are equal', () => { - expect( - tripleEquals(3, 3) - ).toBe(true); - - expect( - tripleEquals('dog', 'dog') - ).toBe(true); - - expect( - tripleEquals( - {a: 1, b: 2, c: undefined}, - {a: 1, b: 2, c: undefined} - ) - ).toBe(true); - - expect( - tripleEquals( - {a: 1, b: 2, c: 3}, - {a: 1, b: 2, c: 3} - ) - ).toBe(true); - - const obj = {}; - expect( - tripleEquals( - {a: 1, b: 2, c: obj}, - {a: 1, b: 2, c: obj} - ) - ).toBe(true); - - expect( - tripleEquals(null, null) - ).toBe(true); - }); - - it('should return false if arguments are number and string', () => { - expect( - tripleEquals(2, '2') - ).toBe(false); - }); - - it('should return false if arguments are string and number', () => { - expect( - tripleEquals('2', 2) - ).toBe(false); - }); - - it('should return false if arguments are number and object', () => { - expect( - tripleEquals(4, {}) - ).toBe(false); - }); - - it('should return false if arguments are object and number', () => { - expect( - tripleEquals({}, 4) - ).toBe(false); - }); - - it('should return false if arguments are number and array', () => { - expect( - tripleEquals(4, []) - ).toBe(false); - }); - - it('should return false if arguments are array and number', () => { - expect( - tripleEquals([], 4) - ).toBe(false); - }); - - it('should return false if arguments are string and object', () => { - expect( - tripleEquals('cat', {}) - ).toBe(false); - }); - - it('should return false if arguments are object and string', () => { - expect( - tripleEquals({}, 'cat') - ).toBe(false); - }); - - it('should return false if arguments are string and array', () => { - expect( - tripleEquals('cat', ['c', 'a', 't']) - ).toBe(false); - }); - - it('should return false if arguments are array and string', () => { - expect( - tripleEquals(['c', 'a', 't'], 'cat') - ).toBe(false); - }); - - it('should return false if arguments are array and object', () => { - expect( - tripleEquals([], {}) - ).toBe(false); - }); - - it('should return false if arguments are object and array', () => { - expect( - tripleEquals({}, []) - ).toBe(false); - }); - - it('should return false if arguments are object and null', () => { - expect( - tripleEquals({ a: 1 }, null) - ).toBe(false); - }); - - it('should return false if arguments are null and object', () => { - expect( - tripleEquals(null, { a: 1 }) - ).toBe(false); - }); - - it('should return false if first argument has too many keys', () => { - expect( - tripleEquals( - {a: 1, b: 2, c: 3}, - {a: 1, b: 2} - ) - ).toBe(false); - }); - - it('should return false if second argument has too many keys', () => { - expect( - tripleEquals( - {a: 1, b: 2}, - {a: 1, b: 2, c: 3} - ) - ).toBe(false); - }); - - it('should return false if arguments have different keys', () => { - expect( - tripleEquals( - {a: 1, b: 2, c: undefined}, - {a: 1, bb: 2, c: undefined} - ) - ).toBe(false); - }); - - it('should return false if first array argument has too many items', () => { - expect( - tripleEquals( - [1, 2, 3, 4], - [1, 2, 3] - ) - ).toBe(false); - }); - - it('should return false if second array argument has too many items', () => { - expect( - tripleEquals( - [1, 2, 3], - [1, 2, 3, 4] - ) - ).toBe(false); - }); -}); diff --git a/test/memoize.js b/test/memoize.js deleted file mode 100644 index 0a0c9db..0000000 --- a/test/memoize.js +++ /dev/null @@ -1,264 +0,0 @@ -import expect from 'expect'; -import memoize from '../src/memoize'; - -describe('memoize', () => { - - describe('basic', () => { - - it('single', () => { - let callCount = 0; - let multiply = (x, y, z) => { - callCount += 1; - return x*y*z; - }; - multiply = memoize()(multiply); - - expect( - multiply(1,2,3) - ).toBe(6); - - expect( - multiply(1,2,3) - ).toBe(6); - - expect( - callCount - ).toBe(1); - - expect( - multiply(4,5,6) - ).toBe(120); - - expect( - callCount - ).toBe(2); - - expect( - multiply(1,2,3) - ).toBe(6); - - expect( - callCount - ).toBe(3); - }); - - it('multiple', () => { - let callCount = 0; - let multiply = (x, y, z) => { - callCount += 1; - return x*y*z; - }; - multiply = memoize(2)(multiply); - - expect( - multiply(1,2,3) - ).toBe(6); - - expect( - multiply(1,2,3) - ).toBe(6); - - expect( - callCount - ).toBe(1); - - expect( - multiply(4,5,6) - ).toBe(120); - - expect( - callCount - ).toBe(2); - - expect( - multiply(1,2,3) - ).toBe(6); - - expect( - callCount - ).toBe(2); - - expect( - multiply(4,5,6) - ).toBe(120); - - expect( - callCount - ).toBe(2); - - }); - - }); - - describe('shallow', () => { - - it('array', () => { - let callCount = 0; - let multiply = (x, y, z) => { - callCount += 1; - return x.concat(y,z).reduce((t, n) => t*n); - }; - multiply = memoize()(multiply); - - const x = [1,2,3]; - const y = [4,5,6]; - const z = [7,8,9]; - - const x2 = [1,2,3]; - - expect( - multiply(x,y,z) - ).toBe(362880); - - expect( - multiply(x2,y,z) - ).toBe(362880); - - expect( - callCount - ).toBe(2); - }); - - it('object', () => { - let callCount = 0; - let multiply = (x, y, z) => { - callCount += 1; - return x.val*y.val*z.val; - }; - multiply = memoize(2)(multiply); - - const x = {val:1}; - const y = {val:2}; - const z = {val:3}; - - const x2 = {val:1}; - - expect( - multiply(x,y,z) - ).toBe(6); - - expect( - multiply(x2,y,z) - ).toBe(6); - - expect( - callCount - ).toBe(2); - }); - - - }); - - describe('deep', () => { - - it('array', () => { - let callCount = 0; - let multiply = (x, y, z) => { - callCount += 1; - return x.concat(y,z).reduce((t, n) => t*n); - }; - multiply = memoize(true)(multiply); - - const x = [1,2,3]; - const y = [4,5,6]; - const z = [7,8,9]; - - const x2 = [1,2,3]; - const x3 = [3,2,1]; - - expect( - multiply(x,y,z) - ).toBe(362880); - - expect( - multiply(x2,y,z) - ).toBe(362880); - - expect( - callCount - ).toBe(1); - - expect( - multiply(x3,y,z) - ).toBe(362880); - - expect( - callCount - ).toBe(2); - }); - - it('object', () => { - let callCount = 0; - let multiply = (x, y, z) => { - callCount += 1; - return x.val*y.val*z.val; - }; - multiply = memoize(true)(multiply); - - const x = {val:1}; - const y = {val:2}; - const z = {val:3}; - - const x2 = {val:1}; - const x3 = {val:4}; - - expect( - multiply(x,y,z) - ).toBe(6); - - expect( - multiply(x2,y,z) - ).toBe(6); - - expect( - callCount - ).toBe(1); - - expect( - multiply(x3,y,z) - ).toBe(24); - - expect( - callCount - ).toBe(2); - }); - - it('object nested', () => { - let callCount = 0; - let multiply = (x, y, z) => { - callCount += 1; - return x.inner.val*y.inner.val*z.inner.val; - }; - multiply = memoize(true)(multiply); - - const x = {inner:{val:1}}; - const y = {inner:{val:2}}; - const z = {inner:{val:3}}; - - const x2 = {inner:{val:1}}; - const x3 = {inner:{val:4}}; - - expect( - multiply(x,y,z) - ).toBe(6); - - expect( - multiply(x2,y,z) - ).toBe(6); - - expect( - callCount - ).toBe(1); - - expect( - multiply(x3,y,z) - ).toBe(24); - - expect( - callCount - ).toBe(2); - }); - - }); - -}); diff --git a/webpack.config.base.js b/webpack.config.base.js index 7ee6aaa..5176d9d 100644 --- a/webpack.config.base.js +++ b/webpack.config.base.js @@ -1,17 +1,7 @@ 'use strict'; var webpack = require('webpack'); -var reactExternal = { - root: 'React', - commonjs2: 'react', - commonjs: 'react', - amd: 'react' -}; - module.exports = { - externals: { - 'react': reactExternal - }, module: { rules: [ { test: /\.js$/, use: ['babel-loader'], exclude: /node_modules/ } From e0e3eac0a8e181dc48b5dded7ba067ded4f2260f Mon Sep 17 00:00:00 2001 From: Erik Rasmussen Date: Tue, 18 Apr 2017 10:40:21 +0200 Subject: [PATCH 2/2] Oops, pruned deps too much --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 28d3711..4a1f392 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,9 @@ "eslint": "^3.19.0", "eslint-config-react-app": "^0.6.2", "eslint-plugin-flowtype": "^2.30.4", + "eslint-plugin-import": "^2.2.0", + "eslint-plugin-jsx-a11y": "^4.0.0", + "eslint-plugin-react": "^6.10.3", "expect": "^1.20.2", "mocha": "^3.2.0", "nyc": "^10.2.0",