From 6ca43c4291d9f3078e2b8e7488acec738864cc02 Mon Sep 17 00:00:00 2001 From: Billy Date: Wed, 12 Jun 2019 21:45:55 -0700 Subject: [PATCH 1/3] action creators tests --- package-lock.json | 479 +++++++++++++++++++++++++++- package.json | 2 + src/actions/action-creators.test.js | 146 ++++++++- src/actions/index.js | 12 +- src/components/App.js | 8 +- src/index.js | 6 +- src/lib/calc-helpers.js | 2 +- src/lib/calculator.js | 9 + src/setupFiles.js | 0 9 files changed, 641 insertions(+), 23 deletions(-) create mode 100644 src/lib/calculator.js create mode 100644 src/setupFiles.js diff --git a/package-lock.json b/package-lock.json index 174dc95..9987bd9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -898,6 +898,11 @@ "loader-utils": "^1.1.0" } }, + "@types/node": { + "version": "12.0.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.8.tgz", + "integrity": "sha512-b8bbUOTwzIY3V5vDTY1fIJ+ePKDUBqt2hC2woVGotdQQhG/2Sh62HOKHrT7ab+VerXAcPyAiTEipPu/FsreUtg==" + }, "@types/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.1.tgz", @@ -1135,6 +1140,40 @@ "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz", "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==" }, + "airbnb-prop-types": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.13.2.tgz", + "integrity": "sha512-2FN6DlHr6JCSxPPi25EnqGaXC4OC3/B3k1lCd6MMYrZ51/Gf/1qDfaR+JElzWa+Tl7cY2aYOlsYJGFeQyVHIeQ==", + "requires": { + "array.prototype.find": "^2.0.4", + "function.prototype.name": "^1.1.0", + "has": "^1.0.3", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0", + "prop-types": "^15.7.2", + "prop-types-exact": "^1.2.0", + "react-is": "^16.8.6" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" + } + } + }, "ajv": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", @@ -1556,6 +1595,25 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" }, + "array.prototype.find": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.0.tgz", + "integrity": "sha512-Wn41+K1yuO5p7wRZDl7890c3xvv5UBrfVXTVIe28rSQb6LS0fZMDrQB6PAcxQFRFy6vJTLDc3A2+3CjQdzVKRg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.13.0" + } + }, + "array.prototype.flat": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.1.tgz", + "integrity": "sha512-rVqIs330nLJvfC7JqYvEWwqVr5QjYF1ib02i3YJtR/fICO6527Tjpc/e4Mvmxh3GIePPreRXMdaGyC99YphWEw==", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.10.0", + "function-bind": "^1.1.1" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -2663,6 +2721,89 @@ "resolved": "https://registry.npmjs.org/check-types/-/check-types-7.4.0.tgz", "integrity": "sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg==" }, + "cheerio": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.1", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + }, + "dependencies": { + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "requires": { + "@types/node": "*" + } + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "chokidar": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", @@ -3763,6 +3904,11 @@ } } }, + "discontinuous-range": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=" + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -3974,6 +4120,109 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" }, + "enzyme": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.10.0.tgz", + "integrity": "sha512-p2yy9Y7t/PFbPoTvrWde7JIYB2ZyGC+NgTNbVEGvZ5/EyoYSr9aG/2rSbVvyNvMHEhw9/dmGUJHWtfQIEiX9pg==", + "requires": { + "array.prototype.flat": "^1.2.1", + "cheerio": "^1.0.0-rc.2", + "function.prototype.name": "^1.1.0", + "has": "^1.0.3", + "html-element-map": "^1.0.0", + "is-boolean-object": "^1.0.0", + "is-callable": "^1.1.4", + "is-number-object": "^1.0.3", + "is-regex": "^1.0.4", + "is-string": "^1.0.4", + "is-subset": "^0.1.1", + "lodash.escape": "^4.0.1", + "lodash.isequal": "^4.5.0", + "object-inspect": "^1.6.0", + "object-is": "^1.0.1", + "object.assign": "^4.1.0", + "object.entries": "^1.0.4", + "object.values": "^1.0.4", + "raf": "^3.4.0", + "rst-selector-parser": "^2.2.3", + "string.prototype.trim": "^1.1.2" + } + }, + "enzyme-adapter-react-16": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.14.0.tgz", + "integrity": "sha512-7PcOF7pb4hJUvjY7oAuPGpq3BmlCig3kxXGi2kFx0YzJHppqX1K8IIV9skT1IirxXlu8W7bneKi+oQ10QRnhcA==", + "requires": { + "enzyme-adapter-utils": "^1.12.0", + "has": "^1.0.3", + "object.assign": "^4.1.0", + "object.values": "^1.1.0", + "prop-types": "^15.7.2", + "react-is": "^16.8.6", + "react-test-renderer": "^16.0.0-0", + "semver": "^5.7.0" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } + } + }, + "enzyme-adapter-utils": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.12.0.tgz", + "integrity": "sha512-wkZvE0VxcFx/8ZsBw0iAbk3gR1d9hK447ebnSYBf95+r32ezBq+XDSAvRErkc4LZosgH8J7et7H7/7CtUuQfBA==", + "requires": { + "airbnb-prop-types": "^2.13.2", + "function.prototype.name": "^1.1.0", + "object.assign": "^4.1.0", + "object.fromentries": "^2.0.0", + "prop-types": "^15.7.2", + "semver": "^5.6.0" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" + } + } + }, + "enzyme-to-json": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.3.5.tgz", + "integrity": "sha512-DmH1wJ68HyPqKSYXdQqB33ZotwfUhwQZW3IGXaNXgR69Iodaoj8TF/D9RjLdz4pEhGq2Tx2zwNUIjBuqoZeTgA==", + "requires": { + "lodash": "^4.17.4" + } + }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -5508,7 +5757,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -5526,11 +5776,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5543,15 +5795,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5654,7 +5909,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5664,6 +5920,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5676,17 +5933,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -5703,6 +5963,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5775,7 +6036,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5785,6 +6047,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5860,7 +6123,8 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5890,6 +6154,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5907,6 +6172,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5945,11 +6211,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.0.2", - "bundled": true + "bundled": true, + "optional": true } } }, @@ -5958,6 +6226,16 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "function.prototype.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.0.tgz", + "integrity": "sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "is-callable": "^1.1.3" + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", @@ -6352,6 +6630,21 @@ "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" }, + "html-element-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.0.1.tgz", + "integrity": "sha512-BZSfdEm6n706/lBfXKWa4frZRZcT5k1cOusw95ijZsHlI+GdgY0v95h6IzO3iIDf2ROwq570YTwqNPqHcNMozw==", + "requires": { + "array-filter": "^1.0.0" + }, + "dependencies": { + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" + } + } + }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -7109,6 +7402,11 @@ "binary-extensions": "^1.0.0" } }, + "is-boolean-object": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.0.0.tgz", + "integrity": "sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M=" + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -7240,6 +7538,11 @@ "kind-of": "^3.0.2" } }, + "is-number-object": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.3.tgz", + "integrity": "sha1-8mWrian0RQNO9q/xWo8AsA9VF5k=" + }, "is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", @@ -7317,6 +7620,16 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, + "is-string": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.4.tgz", + "integrity": "sha1-zDqbaYV9Yh6WNyWiTK7shzuCbmQ=" + }, + "is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=" + }, "is-svg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", @@ -8379,6 +8692,21 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, + "lodash.escape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", + "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", @@ -8723,6 +9051,11 @@ } } }, + "moo": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.4.3.tgz", + "integrity": "sha512-gFD2xGCl8YFgGHsqJ9NKRVdwlioeW3mI1iqfLNYQOv0+6JRwG58Zk9DIGQgyIaffSYaO1xsKnMaYzzNr1KyIAw==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -8812,6 +9145,18 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, + "nearley": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.16.0.tgz", + "integrity": "sha512-Tr9XD3Vt/EujXbZBv6UAHYoLUSMQAxSsTnm9K3koXzjzNWY195NqALeyrzLZBKzAkL3gl92BcSogqrHjD8QuUg==", + "requires": { + "commander": "^2.19.0", + "moo": "^0.4.3", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6", + "semver": "^5.4.1" + } + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -8996,6 +9341,16 @@ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==" }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" + }, + "object-is": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", + "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=" + }, "object-keys": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", @@ -9020,6 +9375,28 @@ "object-keys": "^1.0.11" } }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.fromentries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", + "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.11.0", + "function-bind": "^1.1.1", + "has": "^1.0.1" + } + }, "object.getownpropertydescriptors": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", @@ -11070,6 +11447,16 @@ "object-assign": "^4.1.1" } }, + "prop-types-exact": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz", + "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==", + "requires": { + "has": "^1.0.3", + "object.assign": "^4.1.0", + "reflect.ownkeys": "^0.2.0" + } + }, "proxy-addr": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", @@ -11175,6 +11562,20 @@ "performance-now": "^2.1.0" } }, + "railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", + "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=" + }, + "randexp": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", + "requires": { + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" + } + }, "randomatic": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", @@ -11493,6 +11894,33 @@ "workbox-webpack-plugin": "3.6.3" } }, + "react-test-renderer": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.8.6.tgz", + "integrity": "sha512-H2srzU5IWYT6cZXof6AhUcx/wEyJddQ8l7cLM/F7gDXYyPr4oq+vCIxJYXVGhId1J706sqziAjuOEjyNkfgoEw==", + "requires": { + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "react-is": "^16.8.6", + "scheduler": "^0.13.6" + }, + "dependencies": { + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" + }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } + } + }, "react-testing-library": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/react-testing-library/-/react-testing-library-5.4.2.tgz", @@ -11868,6 +12296,11 @@ "symbol-observable": "^1.2.0" } }, + "redux-devtools-extension": { + "version": "2.13.8", + "resolved": "https://registry.npmjs.org/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz", + "integrity": "sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg==" + }, "redux-mock-store": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/redux-mock-store/-/redux-mock-store-1.5.3.tgz", @@ -11882,6 +12315,11 @@ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" }, + "reflect.ownkeys": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", + "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=" + }, "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", @@ -12211,6 +12649,15 @@ "inherits": "^2.0.1" } }, + "rst-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", + "integrity": "sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=", + "requires": { + "lodash.flattendeep": "^4.4.0", + "nearley": "^2.7.10" + } + }, "rsvp": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", @@ -13316,6 +13763,16 @@ } } }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", diff --git a/package.json b/package.json index 8079fd8..e25536c 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,14 @@ "react-redux": "^6.0.0", "react-scripts": "2.1.2", "redux": "^4.0.1", + "redux-devtools-extension": "^2.13.8", "redux-thunk": "^2.3.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", + "test:debug": "react-scripts --inspect-brk test --runInBand --no-cache", "eject": "react-scripts eject", "predeploy": "npm run -s build", "deploy": "node scripts/deploy.js" diff --git a/src/actions/action-creators.test.js b/src/actions/action-creators.test.js index bb460cf..0dd6343 100644 --- a/src/actions/action-creators.test.js +++ b/src/actions/action-creators.test.js @@ -3,11 +3,13 @@ import * as types from '../constants/action-types'; import thunkMiddleware from 'redux-thunk'; import configureMockStore from 'redux-mock-store'; import panes from '../constants/pane-types'; +import { initializeCalculator } from '../lib/calculator'; const middlewares = [thunkMiddleware]; -const mockStore = configureMockStore(middlewares); +let mockStore = configureMockStore(middlewares); describe('Action creators', () => { + /***** sync *****/ describe('synchronous action creators', () => { it('return an action to add a frame', () => { const imageData = 'URI'; @@ -126,7 +128,147 @@ describe('Action creators', () => { }); }); + /***** async *****/ describe('async action creators', () => { - // TODO + let store; + beforeEach(() => { + store = mockStore({ + images: { + frames: {}, + frameIDs: [], + gifProgress: 0, + gifData: '' + }, + settings: { + image: { + width: 300, + height: 300, + interval: 100, + oversample: false + }, + bounds: { + left: -10, + right: 10, + bottom: -10, + top: 10 + }, + strategy: 'contain' + }, + ui: { + expandedPane: 'NONE', + previewIdx: 0, + playing: false, + error: '' + } + }); + }); + + // flashError + it('return an action to temporarily display error message', () => { + jest.useFakeTimers(); + const expectedActions = [ + { type: types.SET_ERROR, payload: { message: 'error' } }, + { type: types.CLEAR_ERROR } + ]; + store.dispatch(actions.flashError('error')); + jest.runAllTimers(); + expect(store.getActions()).toEqual(expectedActions); + }); + + // requestFrame + it('return an action to request a frame from the calculator', () => { + const expectedActions = [ + { + type: types.ADD_FRAME, + payload: { id: 2, imageData: expect.any(String) } + } + ]; + const opts = { + height: 300, + targetPixelRatio: 1, + width: 300 + }; + initializeCalculator( + // desmos mock + { + GraphingCalculator: jest.fn(() => ({ + asyncScreenshot: (opts, cb) => cb('') + })) + }, + // calcContainer mock + { current: undefined } + ); + return store.dispatch(actions.requestFrame(opts)).then(() => { + expect(store.getActions()).toEqual(expectedActions); + }); + }); + + // requestBurst + it('return an action to request a burst of frames from the calculator', () => { + const opts = { + height: 300, + idx: 1, + max: 3, + min: -3, + oversample: false, + step: 1, + width: 300 + }; + initializeCalculator( + // desmos mock + { + GraphingCalculator: jest.fn(() => { + return { + asyncScreenshot: (opts, cb) => cb(''), + getExpressions: () => [ + { id: 1, latex: 'x =3' }, + { id: 2, latex: '' } + ], + setExpression: () => null + }; + }) + }, + // calcContainer mock + { current: undefined } + ); + return store.dispatch(actions.requestBurst(opts)).then(() => { + // slide with min/max of -3/3 should dispatch addFrame 7 times + expect(store.getActions().length).toEqual(7); + }); + }); + + // startAnimation + it('return actions to play animation via frames in state', () => { + const expectedActions = [ + { type: types.PLAY_PREVIEW }, + { type: types.UPDATE_PREVIEW_IDX, payload: { idx: 1 } } + ]; + store.dispatch(actions.startAnimation()); + expect(store.getActions()).toEqual(expectedActions); + }); + + // generateGIF + it('return action to generate a GIF via frames in state', () => { + const expectedActions = [ + { type: types.UPDATE_GIF_PROGRESS, payload: { progress: 100 } }, + { type: types.ADD_GIF, payload: { imageData: expect.any(String) } } + ]; + const opts = { + gifHeight: 300, + gifWidth: 300, + images: ['img1', 'img2', 'img3'], + interval: 0.1, + progressCallback: jest.fn() + }; + // gifshot mock + const gifshot = { + createGIF: (args, cb) => { + args.progressCallback(100); + return cb({ image: 'test' }); + } + }; + store.dispatch(actions.generateGIF([], opts, gifshot)); + expect(store.getActions()).toEqual(expectedActions); + }); }); }); diff --git a/src/actions/index.js b/src/actions/index.js index 4e6e298..b98e00f 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -40,6 +40,10 @@ const ERROR_DELAY = 3000; let nextFrameID = 0; let errorTimeout; +/********************************************************************************/ +/*** Synchronous ****************************************************************/ +/********************************************************************************/ + export const addFrame = imageData => ({ type: types.ADD_FRAME, payload: { @@ -166,6 +170,7 @@ export const requestBurst = opts => async (dispatch, getState) => { for (let val = min; val <= max; val += step) { sliderErrorMessage = setSliderByIndex(idx, val); if (sliderErrorMessage) { + dispatch(addFrame(sliderErrorMessage)); dispatch(flashError(sliderErrorMessage)); return; } @@ -195,7 +200,10 @@ export const startAnimation = () => (dispatch, getState) => { // The gifshot library is loaded in index.html const gifshot = window.gifshot; -export const generateGIF = (images, opts) => (dispatch, getState) => { +export const generateGIF = (images, opts, library = gifshot) => ( + dispatch, + getState +) => { // Have to check state interval and not opts because opts is in seconds const { interval } = getState().settings.image; const settingsErrors = getSettingsErrors({ interval }); @@ -209,7 +217,7 @@ export const generateGIF = (images, opts) => (dispatch, getState) => { ...opts, progressCallback: progress => dispatch(updateGIFProgress(progress)) }; - gifshot.createGIF(gifshotArgs, data => { + library.createGIF(gifshotArgs, data => { if (data.error) { dispatch(flashError(gifCreationProblem())); } else { diff --git a/src/components/App.js b/src/components/App.js index 8c16571..cf2715b 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -6,12 +6,12 @@ import BurstContainer from '../containers/BurstContainer'; import SettingsContainer from '../containers/SettingsContainer'; import ErrorToastContainer from '../containers/ErrorToastContainer'; import CALCULATOR_OPTIONS from '../constants/calculator-options'; +import { initializeCalculator } from '../lib/calculator'; import './App.css'; // The Desmos API is loaded in index.html const Desmos = window.Desmos; const calcContainer = React.createRef(); -export let calculator; class App extends Component { constructor(props) { @@ -25,11 +25,7 @@ class App extends Component { } componentDidMount() { - calculator = Desmos.GraphingCalculator( - calcContainer.current, - CALCULATOR_OPTIONS - ); - + initializeCalculator(Desmos, calcContainer, CALCULATOR_OPTIONS); window.addEventListener('keydown', this.handleKeyDown); } diff --git a/src/index.js b/src/index.js index 9605613..da50e73 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { createStore, applyMiddleware } from 'redux'; +import { composeWithDevTools } from 'redux-devtools-extension'; import { Provider } from 'react-redux'; import thunkMiddleware from 'redux-thunk'; import rootReducer from './reducers'; @@ -10,7 +11,10 @@ import { togglePane } from './actions'; import greet from './lib/dev-greeting'; import './index.css'; -const store = createStore(rootReducer, applyMiddleware(thunkMiddleware)); +const store = createStore( + rootReducer, + composeWithDevTools(applyMiddleware(thunkMiddleware)) +); const closePane = () => store.dispatch(togglePane(panes.NONE)); diff --git a/src/lib/calc-helpers.js b/src/lib/calc-helpers.js index 57cda8c..ace4548 100644 --- a/src/lib/calc-helpers.js +++ b/src/lib/calc-helpers.js @@ -6,7 +6,7 @@ * and concise. */ -import { calculator } from '../components/App'; +import { calculator } from './calculator'; import { noSuchExpression, notASlider } from './error-messages'; /* diff --git a/src/lib/calculator.js b/src/lib/calculator.js new file mode 100644 index 0000000..9be4f4b --- /dev/null +++ b/src/lib/calculator.js @@ -0,0 +1,9 @@ +let calculator; + +function initializeCalculator(desmos, calcContainer, calcOptions) { + calculator = desmos.GraphingCalculator(calcContainer.current, calcOptions); + window.calculator = calculator; + return calculator; +} + +export { calculator, initializeCalculator }; diff --git a/src/setupFiles.js b/src/setupFiles.js new file mode 100644 index 0000000..e69de29 From 7ac594489f139aa4e60b6fceb23dd49f81a5f49f Mon Sep 17 00:00:00 2001 From: Billy Date: Thu, 13 Jun 2019 10:32:57 -0700 Subject: [PATCH 2/3] clean up code for pull request --- package.json | 2 -- src/actions/action-creators.test.js | 2 +- src/actions/index.js | 5 ----- src/index.js | 6 +----- 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index e25536c..8079fd8 100644 --- a/package.json +++ b/package.json @@ -10,14 +10,12 @@ "react-redux": "^6.0.0", "react-scripts": "2.1.2", "redux": "^4.0.1", - "redux-devtools-extension": "^2.13.8", "redux-thunk": "^2.3.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "test:debug": "react-scripts --inspect-brk test --runInBand --no-cache", "eject": "react-scripts eject", "predeploy": "npm run -s build", "deploy": "node scripts/deploy.js" diff --git a/src/actions/action-creators.test.js b/src/actions/action-creators.test.js index 0dd6343..86a2bcc 100644 --- a/src/actions/action-creators.test.js +++ b/src/actions/action-creators.test.js @@ -6,7 +6,7 @@ import panes from '../constants/pane-types'; import { initializeCalculator } from '../lib/calculator'; const middlewares = [thunkMiddleware]; -let mockStore = configureMockStore(middlewares); +const mockStore = configureMockStore(middlewares); describe('Action creators', () => { /***** sync *****/ diff --git a/src/actions/index.js b/src/actions/index.js index b98e00f..63faaaf 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -40,10 +40,6 @@ const ERROR_DELAY = 3000; let nextFrameID = 0; let errorTimeout; -/********************************************************************************/ -/*** Synchronous ****************************************************************/ -/********************************************************************************/ - export const addFrame = imageData => ({ type: types.ADD_FRAME, payload: { @@ -170,7 +166,6 @@ export const requestBurst = opts => async (dispatch, getState) => { for (let val = min; val <= max; val += step) { sliderErrorMessage = setSliderByIndex(idx, val); if (sliderErrorMessage) { - dispatch(addFrame(sliderErrorMessage)); dispatch(flashError(sliderErrorMessage)); return; } diff --git a/src/index.js b/src/index.js index da50e73..9605613 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { createStore, applyMiddleware } from 'redux'; -import { composeWithDevTools } from 'redux-devtools-extension'; import { Provider } from 'react-redux'; import thunkMiddleware from 'redux-thunk'; import rootReducer from './reducers'; @@ -11,10 +10,7 @@ import { togglePane } from './actions'; import greet from './lib/dev-greeting'; import './index.css'; -const store = createStore( - rootReducer, - composeWithDevTools(applyMiddleware(thunkMiddleware)) -); +const store = createStore(rootReducer, applyMiddleware(thunkMiddleware)); const closePane = () => store.dispatch(togglePane(panes.NONE)); From 2d5b3f04e9e923f3fb73a9708cb824fac2c3c4df Mon Sep 17 00:00:00 2001 From: Billy Date: Thu, 13 Jun 2019 16:25:30 -0700 Subject: [PATCH 3/3] PR notes addressed --- src/actions/action-creators.test.js | 111 ++++++++++++---------------- src/actions/index.js | 4 +- 2 files changed, 50 insertions(+), 65 deletions(-) diff --git a/src/actions/action-creators.test.js b/src/actions/action-creators.test.js index 86a2bcc..abb842c 100644 --- a/src/actions/action-creators.test.js +++ b/src/actions/action-creators.test.js @@ -8,8 +8,51 @@ import { initializeCalculator } from '../lib/calculator'; const middlewares = [thunkMiddleware]; const mockStore = configureMockStore(middlewares); +const initialState = { + images: { + frames: {}, + frameIDs: [], + gifProgress: 0, + gifData: '' + }, + settings: { + image: { + width: 300, + height: 300, + interval: 100, + oversample: false + }, + bounds: { + left: -10, + right: 10, + bottom: -10, + top: 10 + }, + strategy: 'contain' + }, + ui: { + expandedPane: 'NONE', + previewIdx: 0, + playing: false, + error: '' + } +}; + +const desmosMock = { + GraphingCalculator: jest.fn(() => { + return { + asyncScreenshot: (opts, cb) => cb(''), + getExpressions: () => [{ id: 1, latex: 'x = 3' }, { id: 2, latex: '' }], + setExpression: () => null + }; + }) +}; + +const calcContainerMock = { current: undefined }; + +// Tests + describe('Action creators', () => { - /***** sync *****/ describe('synchronous action creators', () => { it('return an action to add a frame', () => { const imageData = 'URI'; @@ -128,42 +171,13 @@ describe('Action creators', () => { }); }); - /***** async *****/ describe('async action creators', () => { let store; + beforeEach(() => { - store = mockStore({ - images: { - frames: {}, - frameIDs: [], - gifProgress: 0, - gifData: '' - }, - settings: { - image: { - width: 300, - height: 300, - interval: 100, - oversample: false - }, - bounds: { - left: -10, - right: 10, - bottom: -10, - top: 10 - }, - strategy: 'contain' - }, - ui: { - expandedPane: 'NONE', - previewIdx: 0, - playing: false, - error: '' - } - }); + store = mockStore(initialState); }); - // flashError it('return an action to temporarily display error message', () => { jest.useFakeTimers(); const expectedActions = [ @@ -175,7 +189,6 @@ describe('Action creators', () => { expect(store.getActions()).toEqual(expectedActions); }); - // requestFrame it('return an action to request a frame from the calculator', () => { const expectedActions = [ { @@ -188,22 +201,12 @@ describe('Action creators', () => { targetPixelRatio: 1, width: 300 }; - initializeCalculator( - // desmos mock - { - GraphingCalculator: jest.fn(() => ({ - asyncScreenshot: (opts, cb) => cb('') - })) - }, - // calcContainer mock - { current: undefined } - ); + initializeCalculator(desmosMock, calcContainerMock); return store.dispatch(actions.requestFrame(opts)).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); - // requestBurst it('return an action to request a burst of frames from the calculator', () => { const opts = { height: 300, @@ -214,30 +217,13 @@ describe('Action creators', () => { step: 1, width: 300 }; - initializeCalculator( - // desmos mock - { - GraphingCalculator: jest.fn(() => { - return { - asyncScreenshot: (opts, cb) => cb(''), - getExpressions: () => [ - { id: 1, latex: 'x =3' }, - { id: 2, latex: '' } - ], - setExpression: () => null - }; - }) - }, - // calcContainer mock - { current: undefined } - ); + initializeCalculator(desmosMock, calcContainerMock); return store.dispatch(actions.requestBurst(opts)).then(() => { // slide with min/max of -3/3 should dispatch addFrame 7 times expect(store.getActions().length).toEqual(7); }); }); - // startAnimation it('return actions to play animation via frames in state', () => { const expectedActions = [ { type: types.PLAY_PREVIEW }, @@ -247,7 +233,6 @@ describe('Action creators', () => { expect(store.getActions()).toEqual(expectedActions); }); - // generateGIF it('return action to generate a GIF via frames in state', () => { const expectedActions = [ { type: types.UPDATE_GIF_PROGRESS, payload: { progress: 100 } }, diff --git a/src/actions/index.js b/src/actions/index.js index 63faaaf..b36bcad 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -195,7 +195,7 @@ export const startAnimation = () => (dispatch, getState) => { // The gifshot library is loaded in index.html const gifshot = window.gifshot; -export const generateGIF = (images, opts, library = gifshot) => ( +export const generateGIF = (images, opts, gifMaker = gifshot) => ( dispatch, getState ) => { @@ -212,7 +212,7 @@ export const generateGIF = (images, opts, library = gifshot) => ( ...opts, progressCallback: progress => dispatch(updateGIFProgress(progress)) }; - library.createGIF(gifshotArgs, data => { + gifMaker.createGIF(gifshotArgs, data => { if (data.error) { dispatch(flashError(gifCreationProblem())); } else {