From 70be4114e26403518a38f488f0e8193d19d01267 Mon Sep 17 00:00:00 2001 From: Saran Date: Sun, 23 Dec 2018 22:36:14 +0530 Subject: [PATCH] [Saran] Introduce JavaScript Standard Style linter - fix js style using standardjs - add linter command in npm package script - add lint check before run test --- package-lock.json | 932 +++++++++++++++++- package.json | 27 +- .../end_to_end_tests/pageObjects/base_page.js | 10 +- .../end_to_end_tests/pageObjects/byor_page.js | 26 +- .../pageObjects/radar_page.js | 42 +- .../end_to_end_tests/specs/end_to_end_test.js | 59 +- spec/end_to_end_tests/util/hooks.js | 18 +- spec/graphing/radar-spec.js | 227 +++-- spec/graphing/ref-table-spec.js | 100 +- spec/models/blip-spec.js | 42 +- spec/models/quadrant-spec.js | 34 +- spec/models/radar-spec.js | 259 +++-- spec/models/ring-spec.js | 16 +- spec/util/contentValidator-spec.js | 58 +- spec/util/inputSanitizer-spec.js | 100 +- spec/util/queryParamProcessor-spec.js | 31 +- spec/util/ringCalculator-spec.js | 32 +- spec/util/sheet-spec.js | 92 +- src/common.js | 8 +- src/exceptions/malformedDataError.js | 18 +- src/exceptions/sheetNotFoundError.js | 18 +- src/graphing/radar.js | 566 ++++++----- src/models/blip.js | 44 +- src/models/quadrant.js | 26 +- src/models/radar.js | 91 +- src/models/ring.js | 16 +- src/site.js | 10 +- src/util/contentValidator.js | 39 +- src/util/exceptionMessages.js | 6 +- src/util/factory.js | 473 +++++---- src/util/inputSanitizer.js | 70 +- src/util/queryParamProcessor.js | 21 +- src/util/ringCalculator.js | 28 +- src/util/sheet.js | 52 +- webpack.config.js | 164 +-- 35 files changed, 2325 insertions(+), 1430 deletions(-) diff --git a/package-lock.json b/package-lock.json index ceb265e36..40b58e99c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -515,6 +515,12 @@ "acorn": "^5.0.0" } }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, "ajv": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", @@ -679,6 +685,16 @@ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -1984,6 +2000,12 @@ "resolved": "https://registry.npmjs.org/chance/-/chance-1.0.18.tgz", "integrity": "sha512-g9YLQVHVZS/3F+zIicfB58vjcxopvYQRp7xHzvyDFDhXH1aRZI/JhwSAO0X5qYiQluoGnaNAU6wByD2KTxJN1A==" }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, "check-more-types": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", @@ -2042,6 +2064,12 @@ "safe-buffer": "^5.0.1" } }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -2099,6 +2127,12 @@ "string-width": "^1.0.1" } }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", @@ -2346,6 +2380,12 @@ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "content-disposition": { "version": "0.5.2", "resolved": "http://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -3252,6 +3292,12 @@ "ms": "^2.1.1" } }, + "debug-log": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", + "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", + "dev": true + }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -3336,6 +3382,42 @@ } } }, + "deglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.1.tgz", + "integrity": "sha512-2kjwuGGonL7gWE1XU4Fv79+vVzpoQCl0V+boMwWtOQJV2AGDabCwez++nB1Nli/8BabAfZQ/UuHPlp6AymKdWw==", + "dev": true, + "requires": { + "find-root": "^1.0.0", + "glob": "^7.0.5", + "ignore": "^3.0.9", + "pkg-config": "^1.1.0", + "run-parallel": "^1.1.2", + "uniq": "^1.0.1" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + } + } + }, "del": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", @@ -3431,6 +3513,15 @@ "buffer-indexof": "^1.0.0" } }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -3700,14 +3791,424 @@ } } }, - "eslint-scope": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "eslint": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.4.0.tgz", + "integrity": "sha512-UIpL91XGex3qtL6qwyCQJar2j3osKxK9e3ano3OcGEIRM4oWIpCkDg9x95AXEC2wMs7PnxzOkPZ2gq+tsMS9yg==", + "dev": true, + "requires": { + "ajv": "^6.5.0", + "babel-code-frame": "^6.26.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.2", + "imurmurhash": "^0.1.4", + "inquirer": "^5.2.0", + "is-resolvable": "^1.1.0", + "js-yaml": "^3.11.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.5", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^2.0.0", + "require-uncached": "^1.0.3", + "semver": "^5.5.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^4.0.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "eslint-config-standard": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz", + "integrity": "sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ==", + "dev": true + }, + "eslint-config-standard-jsx": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-6.0.2.tgz", + "integrity": "sha512-D+YWAoXw+2GIdbMBRAzWwr1ZtvnSf4n4yL0gKGg7ShUOGXkSOLerI17K4F6LdQMJPNMoWYqepzQD/fKY+tXNSg==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", + "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "requires": { + "find-up": "^1.0.0" + } + } + } + }, + "eslint-plugin-es": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz", + "integrity": "sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw==", + "dev": true, + "requires": { + "eslint-utils": "^1.3.0", + "regexpp": "^2.0.1" + } + }, + "eslint-plugin-import": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz", + "integrity": "sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g==", + "dev": true, + "requires": { + "contains-path": "^0.1.0", + "debug": "^2.6.8", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.2.0", + "has": "^1.0.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0", + "resolve": "^1.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "http://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "eslint-plugin-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz", + "integrity": "sha512-lfVw3TEqThwq0j2Ba/Ckn2ABdwmL5dkOgAux1rvOk6CO7A6yGyPI2+zIxN6FyNkp1X1X/BSvKOceD6mBWSj4Yw==", + "dev": true, + "requires": { + "eslint-plugin-es": "^1.3.1", + "eslint-utils": "^1.3.1", + "ignore": "^4.0.2", + "minimatch": "^3.0.4", + "resolve": "^1.8.1", + "semver": "^5.5.0" + } + }, + "eslint-plugin-promise": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz", + "integrity": "sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg==", + "dev": true + }, + "eslint-plugin-react": { + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz", + "integrity": "sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.0.1", + "prop-types": "^15.6.2" + } + }, + "eslint-plugin-standard": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz", + "integrity": "sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA==", + "dev": true + }, + "eslint-scope": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + } + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz", + "integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz", + "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "estraverse": "^4.0.0" }, "dependencies": { "estraverse": { @@ -3718,12 +4219,6 @@ } } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", @@ -3986,6 +4481,28 @@ } } }, + "external-editor": { + "version": "2.2.0", + "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + }, + "dependencies": { + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + } + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -4206,6 +4723,16 @@ "object-assign": "^4.1.0" } }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, "file-loader": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-2.0.0.tgz", @@ -4282,6 +4809,12 @@ "pkg-dir": "^2.0.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true + }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -4291,6 +4824,18 @@ "locate-path": "^2.0.0" } }, + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + } + }, "flatten": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", @@ -5072,6 +5617,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "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", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -5674,6 +6225,12 @@ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", "dev": true }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, "import-cwd": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", @@ -5820,6 +6377,103 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, + "inquirer": { + "version": "5.2.0", + "resolved": "http://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz", + "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.1.0", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^5.5.2", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-escapes": { + "version": "3.1.0", + "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "internal-ip": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-3.0.1.tgz", @@ -6343,6 +6997,12 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -6383,6 +7043,15 @@ "verror": "1.10.0" } }, + "jsx-ast-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", + "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "dev": true, + "requires": { + "array-includes": "^3.0.3" + } + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", @@ -7436,6 +8105,12 @@ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, "nan": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", @@ -7461,6 +8136,12 @@ "to-regex": "^3.0.1" } }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -8530,6 +9211,47 @@ "pinkie": "^2.0.0" } }, + "pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "dependencies": { + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "pkg-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", + "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", + "dev": true, + "requires": { + "debug-log": "^1.0.0", + "find-root": "^1.0.0", + "xtend": "^4.0.1" + } + }, "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", @@ -8539,6 +9261,12 @@ "find-up": "^2.1.0" } }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, "portfinder": { "version": "1.0.20", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", @@ -9460,6 +10188,12 @@ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -9800,6 +10534,12 @@ "safe-regex": "^1.1.0" } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "regexpu-core": { "version": "2.0.0", "resolved": "http://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", @@ -10008,6 +10748,39 @@ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, + "require-uncached": { + "version": "1.0.3", + "resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "dependencies": { + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "http://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + } + } + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -10107,6 +10880,21 @@ "inherits": "^2.0.1" } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -10898,6 +11686,43 @@ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", "dev": true }, + "standard": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/standard/-/standard-12.0.1.tgz", + "integrity": "sha512-UqdHjh87OG2gUrNCSM4QRLF5n9h3TFPwrCNyVlkqu31Hej0L/rc8hzKqVvkb2W3x0WMq7PzZdkLfEcBhVOR6lg==", + "dev": true, + "requires": { + "eslint": "~5.4.0", + "eslint-config-standard": "12.0.0", + "eslint-config-standard-jsx": "6.0.2", + "eslint-plugin-import": "~2.14.0", + "eslint-plugin-node": "~7.0.1", + "eslint-plugin-promise": "~4.0.0", + "eslint-plugin-react": "~7.11.1", + "eslint-plugin-standard": "~4.0.0", + "standard-engine": "~9.0.0" + } + }, + "standard-engine": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-9.0.0.tgz", + "integrity": "sha512-ZfNfCWZ2Xq67VNvKMPiVMKHnMdvxYzvZkf1AH8/cw2NLDBm5LRsxMqvEJpsjLI/dUosZ3Z1d6JlHDp5rAvvk2w==", + "dev": true, + "requires": { + "deglob": "^2.1.0", + "get-stdin": "^6.0.0", + "minimist": "^1.1.0", + "pkg-conf": "^2.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + } + } + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -11127,6 +11952,12 @@ "get-stdin": "^4.0.1" } }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, "style-loader": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", @@ -11208,6 +12039,62 @@ "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", "dev": true }, + "table": { + "version": "4.0.3", + "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", + "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", + "dev": true, + "requires": { + "ajv": "^6.0.1", + "ajv-keywords": "^3.0.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "tabletop": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/tabletop/-/tabletop-1.5.2.tgz", @@ -11349,12 +12236,24 @@ } } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "throttleit": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", "dev": true }, + "through": { + "version": "2.3.8", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -12479,6 +13378,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "xmlhttprequest": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", diff --git a/package.json b/package.json index 2f4976ee2..b9a59699f 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "", "main": "index.js", "scripts": { - "test": "istanbul cover jasmine", + "test": "standard && istanbul cover jasmine", + "test:lint": "npx standard", "dev": "webpack-dev-server --mode development --inline", "build": "webpack --mode production", "end_to_end_test": "node_modules/.bin/cypress run --env host=$TEST_URL", @@ -25,25 +26,26 @@ "babel-preset-env": "^1.7.0", "css-loader": "^2.0.1", "cssnano": "^4.1.7", + "cypress": "^3.1.3", "file-loader": "^2.0.0", "html-webpack-plugin": "^3.2.0", "istanbul": "^0.4.5", "jasmine": "^2.5.2", "json-loader": "^0.5.7", "mini-css-extract-plugin": "^0.5.0", + "mocha": "^5.2.0", + "mochawesome": "^3.1.1", "node-sass": "^4.11.0", "postcss-loader": "^3.0.0", "postcss-preset-env": "^6.5.0", "sass-loader": "^7.1.0", + "standard": "^12.0.1", "style-loader": "^0.23.1", "webpack": "^4.28.0", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.1.10", "xmlhttprequest": "^1.8.0", - "yargs": "^5.0.0", - "cypress": "^3.1.3", - "mocha": "^5.2.0", - "mochawesome": "^3.1.1" + "yargs": "^5.0.0" }, "dependencies": { "chance": "^1.0.4", @@ -55,5 +57,20 @@ }, "peerDependencies": { "mocha": "*" + }, + "standard": { + "globals": [ + "Cypress", + "cy", + "XMLHttpRequest" + ], + "env": [ + "jasmine", + "mocha" + ], + "ignore": [ + "radar-spec.js", + "ref-table-spec.js" + ] } } diff --git a/spec/end_to_end_tests/pageObjects/base_page.js b/spec/end_to_end_tests/pageObjects/base_page.js index ffecbcd51..ffc3d31b9 100644 --- a/spec/end_to_end_tests/pageObjects/base_page.js +++ b/spec/end_to_end_tests/pageObjects/base_page.js @@ -1,9 +1,9 @@ -class base_page{ +/* eslint no-useless-constructor: "off" */ - constructor(){ - - } +class BasePage { + constructor () { + } } -module.exports = new base_page(); \ No newline at end of file +module.exports = new BasePage() diff --git a/spec/end_to_end_tests/pageObjects/byor_page.js b/spec/end_to_end_tests/pageObjects/byor_page.js index 44abbbf20..233bb525f 100644 --- a/spec/end_to_end_tests/pageObjects/byor_page.js +++ b/spec/end_to_end_tests/pageObjects/byor_page.js @@ -1,18 +1,18 @@ -var config = require('../../../cypress.json'); +var config = require('../../../cypress.json') -class byor_page{ +class ByorPage { + constructor () { + this.text_box = "[name='sheetId']" + this.submit = '.button' + } - constructor(){ - this.text_box="[name='sheetId']"; - this.submit=".button"; - } - provide_excel_name = function() { - cy.get(this.text_box).type(config.excel); - } + provideExcelName () { + cy.get(this.text_box).type(config.excel) + } - click_submit_button = function() { - cy.get(this.submit).click(); - } + clickSubmitButton () { + cy.get(this.submit).click() + } } -module.exports = new byor_page(); \ No newline at end of file +module.exports = new ByorPage() diff --git a/spec/end_to_end_tests/pageObjects/radar_page.js b/spec/end_to_end_tests/pageObjects/radar_page.js index b533f04bc..ca9967637 100644 --- a/spec/end_to_end_tests/pageObjects/radar_page.js +++ b/spec/end_to_end_tests/pageObjects/radar_page.js @@ -1,28 +1,26 @@ -class radar_page{ +class RadarPage { + constructor () { + this.blip = '.quadrant-group-second .blip-link' + this.blip_selected = '.quadrant-table.selected .blip-list-item' + this.blip_description = '.blip-item-description.expanded p' + this.sheet2 = '.alternative' + } - constructor(){ - this.blip=".quadrant-group-second .blip-link"; - this.blip_selected=".quadrant-table.selected .blip-list-item"; - this.blip_description=".blip-item-description.expanded p"; - this.sheet2=".alternative"; - } + clickTheBlipFromInteractiveSection () { + cy.get(this.blip).click() + } - click_the_blip_from_interactive_section = function() { - cy.get(this.blip).click(); - } + clickTheBlip () { + cy.get(this.blip_selected).click() + } - click_the_blip = function() { - cy.get(this.blip_selected).click(); - } + validateBlipDescription (text) { + expect(cy.get(this.blip_description).contains(text)) + } - - validate_blip_description = function(text) { - expect(cy.get(this.blip_description).contains(text)); - } - - click_sheet2 = function() { - cy.get(this.sheet2).click(); - } + clickSheet2 () { + cy.get(this.sheet2).click() + } } -module.exports = new radar_page(); \ No newline at end of file +module.exports = new RadarPage() diff --git a/spec/end_to_end_tests/specs/end_to_end_test.js b/spec/end_to_end_tests/specs/end_to_end_test.js index 8950357f0..ede9f8bcd 100644 --- a/spec/end_to_end_tests/specs/end_to_end_test.js +++ b/spec/end_to_end_tests/specs/end_to_end_test.js @@ -1,33 +1,34 @@ -var byorPage = require("../pageObjects/byor_page"); -var basePage = require("../pageObjects/base_page"); -var radarPage = require("../pageObjects/radar_page"); -var config = require('../../../cypress.json'); +var byorPage = require('../pageObjects/byor_page') +// var basePage = require('../pageObjects/base_page') +var radarPage = require('../pageObjects/radar_page') +// var config = require('../../../cypress.json') Cypress.on('uncaught:exception', (err, runnable) => { - return false -}); - -describe("Build your radar", function(){ - it("validate 1st sheet", function(){ - cy.visit(Cypress.env('host')); - byorPage.provide_excel_name(); - byorPage.click_submit_button(); - radarPage.click_the_blip_from_interactive_section(); - radarPage.click_the_blip(); - radarPage.validate_blip_description("test"); - }); -}); - -describe("Validate multiple sheet", function() { - it("validate 2nd sheet", function () { - cy.visit(Cypress.env('host')); - byorPage.provide_excel_name(); - byorPage.click_submit_button(); - radarPage.click_sheet2(); - radarPage.click_the_blip_from_interactive_section(); - radarPage.click_the_blip(); - radarPage.validate_blip_description("testing"); - }); -}); + if (err) { + console.log(err.stack) + } + return false +}) +describe('Build your radar', function () { + it('validate 1st sheet', function () { + cy.visit(Cypress.env('host')) + byorPage.provideExcelName() + byorPage.clickSubmitButton() + radarPage.clickTheBlipFromInteractiveSection() + radarPage.clickTheBlip() + radarPage.validateBlipDescription('test') + }) +}) +describe('Validate multiple sheet', function () { + it('validate 2nd sheet', function () { + cy.visit(Cypress.env('host')) + byorPage.provideExcelName() + byorPage.clickSubmitButton() + radarPage.clickSheet2() + radarPage.clickTheBlipFromInteractiveSection() + radarPage.clickTheBlip() + radarPage.validateBlipDescription('testing') + }) +}) diff --git a/spec/end_to_end_tests/util/hooks.js b/spec/end_to_end_tests/util/hooks.js index 42144568b..d32a46a95 100644 --- a/spec/end_to_end_tests/util/hooks.js +++ b/spec/end_to_end_tests/util/hooks.js @@ -1,11 +1,11 @@ -let basePage = require("../pageObjects/base_page"); +// let basePage = require('../pageObjects/base_page') -describe('Hooks', function() { - before(function() { - // basePage.login(); - }) +describe('Hooks', function () { + before(function () { + // basePage.login(); + }) - after(function() { - // runs once after all tests in the block - }) -}) \ No newline at end of file + after(function () { + // runs once after all tests in the block + }) +}) diff --git a/spec/graphing/radar-spec.js b/spec/graphing/radar-spec.js index 57ba80572..1187f28ea 100644 --- a/spec/graphing/radar-spec.js +++ b/spec/graphing/radar-spec.js @@ -1,174 +1,173 @@ // This references very old code that no longer exists // the tests for graphing will have to be rewritten -require('../../src/graphing/radar.js'); - +require('../../src/graphing/radar.js') xdescribe('tr.graphing.Radar', function () { - var radar; + var radar beforeEach(function () { - radar = new tr.models.Radar(); - spyOn(radar, 'rings').and.returnValue([]); - }); + radar = new tr.models.Radar() + spyOn(radar, 'rings').and.returnValue([]) + }) describe('init', function () { it('appends the svg', function () { - var radarGraph, selection; + var radarGraph, selection - radarGraph = new tr.graphing.Radar(500, radar); - selection = { append: jasmine.createSpy() }; - spyOn(d3, 'select').and.returnValue(selection); + radarGraph = new tr.graphing.Radar(500, radar) + selection = { append: jasmine.createSpy() } + spyOn(d3, 'select').and.returnValue(selection) - radarGraph.init(); + radarGraph.init() - expect(selection.append).toHaveBeenCalledWith('svg'); - }); + expect(selection.append).toHaveBeenCalledWith('svg') + }) it('selects body if no selector provided', function () { - var radarGraph; + var radarGraph - radarGraph = new tr.graphing.Radar(500, radar); - spyOn(d3, 'select').and.callThrough(); + radarGraph = new tr.graphing.Radar(500, radar) + spyOn(d3, 'select').and.callThrough() - radarGraph.init(); + radarGraph.init() - expect(d3.select).toHaveBeenCalledWith('body'); - }); + expect(d3.select).toHaveBeenCalledWith('body') + }) it('selects the selector if provided', function () { - var radarGraph; + var radarGraph - radarGraph = new tr.graphing.Radar(500, radar); - spyOn(d3, 'select').and.callThrough(); + radarGraph = new tr.graphing.Radar(500, radar) + spyOn(d3, 'select').and.callThrough() - radarGraph.init('#radar'); + radarGraph.init('#radar') - expect(d3.select).toHaveBeenCalledWith('#radar'); - }); - }); + expect(d3.select).toHaveBeenCalledWith('#radar') + }) + }) it('sets the size', function () { - var svg, radarGraph; + var svg, radarGraph - radarGraph = new tr.graphing.Radar(500, radar); - radarGraph.init(); + radarGraph = new tr.graphing.Radar(500, radar) + radarGraph.init() - svg = radarGraph.svg(); - spyOn(svg, 'attr').and.returnValue(svg); + svg = radarGraph.svg() + spyOn(svg, 'attr').and.returnValue(svg) - radarGraph.plot(); + radarGraph.plot() - expect(svg.attr).toHaveBeenCalledWith('width', 500); - expect(svg.attr).toHaveBeenCalledWith('height', 500); - }); + expect(svg.attr).toHaveBeenCalledWith('width', 500) + expect(svg.attr).toHaveBeenCalledWith('height', 500) + }) describe('lines', function () { it('plots a vertical line in the center', function () { - var radarGraph, svg; + var radarGraph, svg - radarGraph = new tr.graphing.Radar(500, radar); - radarGraph.init(); + radarGraph = new tr.graphing.Radar(500, radar) + radarGraph.init() - svg = radarGraph.svg(); - spyOn(svg, 'append').and.returnValue(svg); - spyOn(svg, 'attr').and.returnValue(svg); + svg = radarGraph.svg() + spyOn(svg, 'append').and.returnValue(svg) + spyOn(svg, 'attr').and.returnValue(svg) - radarGraph.plot(); + radarGraph.plot() - expect(svg.append).toHaveBeenCalledWith('line'); - expect(svg.attr).toHaveBeenCalledWith('x1', 500 / 2); - expect(svg.attr).toHaveBeenCalledWith('y1', 0); - expect(svg.attr).toHaveBeenCalledWith('x2', 500 / 2); - expect(svg.attr).toHaveBeenCalledWith('y2', 500); - expect(svg.attr).toHaveBeenCalledWith('stroke-width', 14); - }); + expect(svg.append).toHaveBeenCalledWith('line') + expect(svg.attr).toHaveBeenCalledWith('x1', 500 / 2) + expect(svg.attr).toHaveBeenCalledWith('y1', 0) + expect(svg.attr).toHaveBeenCalledWith('x2', 500 / 2) + expect(svg.attr).toHaveBeenCalledWith('y2', 500) + expect(svg.attr).toHaveBeenCalledWith('stroke-width', 14) + }) it('plots a horizontal line in the center', function () { - var svg, radarGraph; + var svg, radarGraph - radarGraph = new tr.graphing.Radar(500, radar); - radarGraph.init(); + radarGraph = new tr.graphing.Radar(500, radar) + radarGraph.init() - svg = radarGraph.svg(); - spyOn(svg, 'append').and.returnValue(svg); - spyOn(svg, 'attr').and.returnValue(svg); + svg = radarGraph.svg() + spyOn(svg, 'append').and.returnValue(svg) + spyOn(svg, 'attr').and.returnValue(svg) - radarGraph.plot(); + radarGraph.plot() - expect(svg.append).toHaveBeenCalledWith('line'); - expect(svg.attr).toHaveBeenCalledWith('x1', 0); - expect(svg.attr).toHaveBeenCalledWith('y1', 500 / 2); - expect(svg.attr).toHaveBeenCalledWith('x2', 500); - expect(svg.attr).toHaveBeenCalledWith('y2', 500 / 2); - expect(svg.attr).toHaveBeenCalledWith('stroke-width', 14); - }); - }); + expect(svg.append).toHaveBeenCalledWith('line') + expect(svg.attr).toHaveBeenCalledWith('x1', 0) + expect(svg.attr).toHaveBeenCalledWith('y1', 500 / 2) + expect(svg.attr).toHaveBeenCalledWith('x2', 500) + expect(svg.attr).toHaveBeenCalledWith('y2', 500 / 2) + expect(svg.attr).toHaveBeenCalledWith('stroke-width', 14) + }) + }) describe('circles', function () { - var svg, radarGraph; + var svg, radarGraph beforeEach(function () { - var radar; + var radar - radar = new tr.models.Radar(); + radar = new tr.models.Radar() spyOn(radar, 'rings').and.returnValue([ new tr.models.Ring('Adopt'), new tr.models.Ring('Hold') - ]); - radarGraph = new tr.graphing.Radar(500, radar); - radarGraph.init(); + ]) + radarGraph = new tr.graphing.Radar(500, radar) + radarGraph.init() - svg = radarGraph.svg(); - spyOn(svg, 'append').and.returnValue(svg); - spyOn(svg, 'attr').and.returnValue(svg); - }); + svg = radarGraph.svg() + spyOn(svg, 'append').and.returnValue(svg) + spyOn(svg, 'attr').and.returnValue(svg) + }) it('plots the circles for the rings', function () { - radarGraph.plot(); + radarGraph.plot() - expect(svg.append).toHaveBeenCalledWith('circle'); - expect(svg.attr).toHaveBeenCalledWith('cx', 500 / 2); - expect(svg.attr).toHaveBeenCalledWith('cy', 500 / 2); - expect(svg.attr).toHaveBeenCalledWith('r', Math.round(250 / 2)); + expect(svg.append).toHaveBeenCalledWith('circle') + expect(svg.attr).toHaveBeenCalledWith('cx', 500 / 2) + expect(svg.attr).toHaveBeenCalledWith('cy', 500 / 2) + expect(svg.attr).toHaveBeenCalledWith('r', Math.round(250 / 2)) - expect(svg.append).toHaveBeenCalledWith('circle'); - expect(svg.attr).toHaveBeenCalledWith('cx', 500 / 2); - expect(svg.attr).toHaveBeenCalledWith('cy', 500 / 2); - expect(svg.attr).toHaveBeenCalledWith('r', 250); - }); + expect(svg.append).toHaveBeenCalledWith('circle') + expect(svg.attr).toHaveBeenCalledWith('cx', 500 / 2) + expect(svg.attr).toHaveBeenCalledWith('cy', 500 / 2) + expect(svg.attr).toHaveBeenCalledWith('r', 250) + }) it('adds the name of each ring for the right side', function () { - var center = 500 / 2; - spyOn(svg, 'text').and.returnValue(svg); - radarGraph.plot(); + var center = 500 / 2 + spyOn(svg, 'text').and.returnValue(svg) + radarGraph.plot() - expect(svg.append).toHaveBeenCalledWith('text'); - expect(svg.attr).toHaveBeenCalledWith('y', center + 4); - expect(svg.attr).toHaveBeenCalledWith('x', 0 + 10); - expect(svg.text).toHaveBeenCalledWith('Adopt'); + expect(svg.append).toHaveBeenCalledWith('text') + expect(svg.attr).toHaveBeenCalledWith('y', center + 4) + expect(svg.attr).toHaveBeenCalledWith('x', 0 + 10) + expect(svg.text).toHaveBeenCalledWith('Adopt') - expect(svg.append).toHaveBeenCalledWith('text'); - expect(svg.attr).toHaveBeenCalledWith('y', center + 4); - expect(svg.attr).toHaveBeenCalledWith('x', 0 + (center / 2) + 10); - expect(svg.text).toHaveBeenCalledWith('Hold'); - }); + expect(svg.append).toHaveBeenCalledWith('text') + expect(svg.attr).toHaveBeenCalledWith('y', center + 4) + expect(svg.attr).toHaveBeenCalledWith('x', 0 + (center / 2) + 10) + expect(svg.text).toHaveBeenCalledWith('Hold') + }) it('adds the name of each ring for the right side', function () { - var center = 500 / 2; - spyOn(svg, 'text').and.returnValue(svg); - radarGraph.plot(); - - expect(svg.append).toHaveBeenCalledWith('text'); - expect(svg.attr).toHaveBeenCalledWith('y', center + 4); - expect(svg.attr).toHaveBeenCalledWith('x', 500 - 10); - expect(svg.attr).toHaveBeenCalledWith('text-anchor', 'end'); - expect(svg.text).toHaveBeenCalledWith('Adopt'); - - expect(svg.append).toHaveBeenCalledWith('text'); - expect(svg.attr).toHaveBeenCalledWith('y', center + 4); - expect(svg.attr).toHaveBeenCalledWith('x', 500 - (center / 2) - 10); - expect(svg.attr).toHaveBeenCalledWith('text-anchor', 'end'); - expect(svg.text).toHaveBeenCalledWith('Hold'); - }); - }); -}); + var center = 500 / 2 + spyOn(svg, 'text').and.returnValue(svg) + radarGraph.plot() + + expect(svg.append).toHaveBeenCalledWith('text') + expect(svg.attr).toHaveBeenCalledWith('y', center + 4) + expect(svg.attr).toHaveBeenCalledWith('x', 500 - 10) + expect(svg.attr).toHaveBeenCalledWith('text-anchor', 'end') + expect(svg.text).toHaveBeenCalledWith('Adopt') + + expect(svg.append).toHaveBeenCalledWith('text') + expect(svg.attr).toHaveBeenCalledWith('y', center + 4) + expect(svg.attr).toHaveBeenCalledWith('x', 500 - (center / 2) - 10) + expect(svg.attr).toHaveBeenCalledWith('text-anchor', 'end') + expect(svg.text).toHaveBeenCalledWith('Hold') + }) + }) +}) diff --git a/spec/graphing/ref-table-spec.js b/spec/graphing/ref-table-spec.js index 8d368eeb9..6e1c1dfb0 100644 --- a/spec/graphing/ref-table-spec.js +++ b/spec/graphing/ref-table-spec.js @@ -1,74 +1,74 @@ -const Quadrant = require('../../src/models/quadrant.js'); -const Ring = require('../../src/models/ring.js'); -const Blip = require('../../src/models/blip.js'); -const Radar = require('../../src/models/radar.js'); +const Quadrant = require('../../src/models/quadrant.js') +const Ring = require('../../src/models/ring.js') +const Blip = require('../../src/models/blip.js') +const Radar = require('../../src/models/radar.js') describe('graphingRadar', function () { - var radar, toolsQuadrant, techniquesQuadrant, platformsQuadrant, languageFramework, element; + var radar, toolsQuadrant, techniquesQuadrant, platformsQuadrant, languageFramework, element - beforeEach(function () { - toolsQuadrant = new Quadrant('Tools'); - techniquesQuadrant = new Quadrant('Techniques'); - platformsQuadrant = new Quadrant('Platforms'); - languageFramework = new Quadrant('Languages'); + beforeEach(function () { + toolsQuadrant = new Quadrant('Tools') + techniquesQuadrant = new Quadrant('Techniques') + platformsQuadrant = new Quadrant('Platforms') + languageFramework = new Quadrant('Languages') - radar = new Radar(); - radar.addQuadrant(toolsQuadrant); - radar.addQuadrant(techniquesQuadrant); - radar.addQuadrant(platformsQuadrant); - radar.addQuadrant(languageFramework); + radar = new Radar() + radar.addQuadrant(toolsQuadrant) + radar.addQuadrant(techniquesQuadrant) + radar.addQuadrant(platformsQuadrant) + radar.addQuadrant(languageFramework) - element = { innerHTML: '' }; - spyOn(document, 'querySelector').and.returnValue(element); - }); + element = { innerHTML: '' } + spyOn(document, 'querySelector').and.returnValue(element) + }) - xdescribe('render', function () { - it("groups blips by ring", function () { - var adopt = new Ring('Adopt'); - var assess = new Ring('Assess'); + xdescribe('render', function () { + it('groups blips by ring', function () { + var adopt = new Ring('Adopt') + var assess = new Ring('Assess') - toolsQuadrant.add([ - new Blip('foo', adopt, true, 'this is foo'), - new Blip('bar', assess, true, 'this is bar'), - new Blip('baz', adopt, true, 'this is baz') - ]); + toolsQuadrant.add([ + new Blip('foo', adopt, true, 'this is foo'), + new Blip('bar', assess, true, 'this is bar'), + new Blip('baz', adopt, true, 'this is baz') + ]) - var table = new tr.graphing.RefTable(radar); - table.init('#some-id').render(); + var table = new tr.graphing.RefTable(radar) + table.init('#some-id').render() - expect(element.innerHTML).toEqual( - '' + + expect(element.innerHTML).toEqual( + '
' + '' + '' + '' + '' + '' + - '
Adopt
-1foothis is foo
-1bazthis is baz
Assess
-1barthis is bar
'); - }); + '') + }) - it("respects the assigned order of rings", function () { - var adopt = new Ring('Adopt', 1); - var assess = new Ring('Assess', 3); - var hold = new Ring('Hold', 2); + it('respects the assigned order of rings', function () { + var adopt = new Ring('Adopt', 1) + var assess = new Ring('Assess', 3) + var hold = new Ring('Hold', 2) - toolsQuadrant.add([ - new Blip('foo', adopt, true, 'this is foo'), - new Blip('bar', assess, true, 'this is bar'), - new Blip('baz', hold, true, 'this is baz') - ]); + toolsQuadrant.add([ + new Blip('foo', adopt, true, 'this is foo'), + new Blip('bar', assess, true, 'this is bar'), + new Blip('baz', hold, true, 'this is baz') + ]) - var table = new tr.graphing.RefTable(radar); - table.init('#some-id').render(); + var table = new tr.graphing.RefTable(radar) + table.init('#some-id').render() - expect(element.innerHTML).toEqual( - '' + + expect(element.innerHTML).toEqual( + '
' + '' + '' + '' + '' + '' + '' + - '
Adopt
-1foothis is foo
Hold
-1bazthis is baz
Assess
-1barthis is bar
'); - }); - }); -}); + '') + }) + }) +}) diff --git a/spec/models/blip-spec.js b/spec/models/blip-spec.js index 2734d8a82..51f014075 100644 --- a/spec/models/blip-spec.js +++ b/spec/models/blip-spec.js @@ -1,50 +1,50 @@ -const Blip = require('../../src/models/blip'); -const Ring = require('../../src/models/ring'); +const Blip = require('../../src/models/blip') +const Ring = require('../../src/models/ring') describe('Blip', function () { - var blip; + var blip beforeEach(function () { blip = new Blip( 'My Blip', new Ring('My Ring') - ); - }); + ) + }) it('has a name', function () { - expect(blip.name()).toEqual('My Blip'); - }); + expect(blip.name()).toEqual('My Blip') + }) it('has a ring', function () { - expect(blip.ring().name()).toEqual('My Ring'); - }); + expect(blip.ring().name()).toEqual('My Ring') + }) it('has a default number', function () { - expect(blip.number()).toEqual(-1); - }); + expect(blip.number()).toEqual(-1) + }) it('sets the number', function () { - blip.setNumber(1); - expect(blip.number()).toEqual(1); - }); + blip.setNumber(1) + expect(blip.number()).toEqual(1) + }) it('is new', function () { blip = new Blip( 'My Blip', new Ring('My Ring'), true - ); + ) - expect(blip.isNew()).toBe(true); - }); + expect(blip.isNew()).toBe(true) + }) it('is not new', function () { blip = new Blip( 'My Blip', new Ring('My Ring'), false - ); + ) - expect(blip.isNew()).toBe(false); - }); -}); + expect(blip.isNew()).toBe(false) + }) +}) diff --git a/spec/models/quadrant-spec.js b/spec/models/quadrant-spec.js index 615ba42c6..993c02604 100644 --- a/spec/models/quadrant-spec.js +++ b/spec/models/quadrant-spec.js @@ -1,32 +1,32 @@ -const Quadrant = require('../../src/models/quadrant'); -const Blip = require('../../src/models/blip'); +const Quadrant = require('../../src/models/quadrant') +const Blip = require('../../src/models/blip') describe('Quadrant', function () { it('has a name', function () { - var quadrant = new Quadrant('My Quadrant'); + var quadrant = new Quadrant('My Quadrant') - expect(quadrant.name()).toEqual('My Quadrant'); - }); + expect(quadrant.name()).toEqual('My Quadrant') + }) it('has no blips by default', function () { - var quadrant = new Quadrant('My Quadrant'); + var quadrant = new Quadrant('My Quadrant') - expect(quadrant.blips()).toEqual([]); - }); + expect(quadrant.blips()).toEqual([]) + }) it('can add a single blip', function () { - var quadrant = new Quadrant('My Quadrant'); + var quadrant = new Quadrant('My Quadrant') - quadrant.add(new Blip()); + quadrant.add(new Blip()) - expect(quadrant.blips().length).toEqual(1); - }); + expect(quadrant.blips().length).toEqual(1) + }) it('can add multiple blips', function () { - var quadrant = new Quadrant('My Quadrant'); + var quadrant = new Quadrant('My Quadrant') - quadrant.add([new Blip(), new Blip()]); + quadrant.add([new Blip(), new Blip()]) - expect(quadrant.blips().length).toEqual(2); - }); -}); + expect(quadrant.blips().length).toEqual(2) + }) +}) diff --git a/spec/models/radar-spec.js b/spec/models/radar-spec.js index 177443e37..a54eafdad 100644 --- a/spec/models/radar-spec.js +++ b/spec/models/radar-spec.js @@ -1,209 +1,208 @@ -const Radar = require('../../src/models/radar'); -const Quadrant = require('../../src/models/quadrant'); -const Ring = require('../../src/models/ring'); -const Blip = require('../../src/models/blip'); -const MalformedDataError = require('../../src/exceptions/malformedDataError'); -const ExceptionMessages = require('../../src/util/exceptionMessages'); +const Radar = require('../../src/models/radar') +const Quadrant = require('../../src/models/quadrant') +const Ring = require('../../src/models/ring') +const Blip = require('../../src/models/blip') +const MalformedDataError = require('../../src/exceptions/malformedDataError') +const ExceptionMessages = require('../../src/util/exceptionMessages') describe('Radar', function () { - it('has no quadrants by default', function () { - var radar = new Radar(); + var radar = new Radar() - expect(radar.quadrants()[0].quadrant).not.toBeDefined(); - expect(radar.quadrants()[1].quadrant).not.toBeDefined(); - expect(radar.quadrants()[2].quadrant).not.toBeDefined(); - expect(radar.quadrants()[3].quadrant).not.toBeDefined(); - }); + expect(radar.quadrants()[0].quadrant).not.toBeDefined() + expect(radar.quadrants()[1].quadrant).not.toBeDefined() + expect(radar.quadrants()[2].quadrant).not.toBeDefined() + expect(radar.quadrants()[3].quadrant).not.toBeDefined() + }) it('sets the first quadrant', function () { - var quadrant, radar, blip; + var quadrant, radar, blip - blip = new Blip('A', new Ring('First')); - quadrant = new Quadrant('First'); - quadrant.add([blip]); - radar = new Radar(); + blip = new Blip('A', new Ring('First')) + quadrant = new Quadrant('First') + quadrant.add([blip]) + radar = new Radar() - radar.addQuadrant(quadrant); + radar.addQuadrant(quadrant) - expect(radar.quadrants()[0].quadrant).toEqual(quadrant); - expect(radar.quadrants()[0].quadrant.blips()[0].number()).toEqual(1); - }); + expect(radar.quadrants()[0].quadrant).toEqual(quadrant) + expect(radar.quadrants()[0].quadrant.blips()[0].number()).toEqual(1) + }) it('sets the second quadrant', function () { - var quadrant, radar, blip; + var quadrant, radar, blip - blip = new Blip('A', new Ring('First')); - quadrant = new Quadrant('Second'); - quadrant.add([blip]); - radar = new Radar(); + blip = new Blip('A', new Ring('First')) + quadrant = new Quadrant('Second') + quadrant.add([blip]) + radar = new Radar() - radar.addQuadrant(quadrant); + radar.addQuadrant(quadrant) - expect(radar.quadrants()[0].quadrant).toEqual(quadrant); - expect(radar.quadrants()[0].quadrant.blips()[0].number()).toEqual(1); - }); + expect(radar.quadrants()[0].quadrant).toEqual(quadrant) + expect(radar.quadrants()[0].quadrant.blips()[0].number()).toEqual(1) + }) it('sets the third quadrant', function () { - var quadrant, radar, blip; + var quadrant, radar, blip - blip = new Blip('A', new Ring('First')); - quadrant = new Quadrant('Third'); - quadrant.add([blip]); - radar = new Radar(); + blip = new Blip('A', new Ring('First')) + quadrant = new Quadrant('Third') + quadrant.add([blip]) + radar = new Radar() - radar.addQuadrant(quadrant); + radar.addQuadrant(quadrant) - expect(radar.quadrants()[0].quadrant).toEqual(quadrant); - expect(radar.quadrants()[0].quadrant.blips()[0].number()).toEqual(1); - }); + expect(radar.quadrants()[0].quadrant).toEqual(quadrant) + expect(radar.quadrants()[0].quadrant.blips()[0].number()).toEqual(1) + }) it('sets the fourth quadrant', function () { - var quadrant, radar, blip; + var quadrant, radar, blip - blip = new Blip('A', new Ring('First')); - quadrant = new Quadrant('Fourth'); - quadrant.add([blip]); - radar = new Radar(); + blip = new Blip('A', new Ring('First')) + quadrant = new Quadrant('Fourth') + quadrant.add([blip]) + radar = new Radar() - radar.addQuadrant(quadrant); + radar.addQuadrant(quadrant) - expect(radar.quadrants()[0].quadrant).toEqual(quadrant); - expect(radar.quadrants()[0].quadrant.blips()[0].number()).toEqual(1); - }); + expect(radar.quadrants()[0].quadrant).toEqual(quadrant) + expect(radar.quadrants()[0].quadrant.blips()[0].number()).toEqual(1) + }) - it('throws an error if too many quadrants are added', function(){ - var quadrant, radar, blip; + it('throws an error if too many quadrants are added', function () { + var quadrant, radar, blip - blip = new Blip('A', new Ring('First')); - quadrant = new Quadrant('First'); - quadrant.add([blip]); - radar = new Radar(); + blip = new Blip('A', new Ring('First')) + quadrant = new Quadrant('First') + quadrant.add([blip]) + radar = new Radar() - radar.addQuadrant(quadrant); - radar.addQuadrant(new Quadrant('Second')); - radar.addQuadrant(new Quadrant('Third')); - radar.addQuadrant(new Quadrant('Fourth')); + radar.addQuadrant(quadrant) + radar.addQuadrant(new Quadrant('Second')) + radar.addQuadrant(new Quadrant('Third')) + radar.addQuadrant(new Quadrant('Fourth')) - expect(function() { radar.addQuadrant(new Quadrant('Fifth')) }).toThrow(new MalformedDataError(ExceptionMessages.TOO_MANY_QUADRANTS)); - }); + expect(function () { radar.addQuadrant(new Quadrant('Fifth')) }).toThrow(new MalformedDataError(ExceptionMessages.TOO_MANY_QUADRANTS)) + }) - it('throws an error if less than 4 quadrants are added', function(){ - var quadrant, radar, blip; + it('throws an error if less than 4 quadrants are added', function () { + var quadrant, radar, blip - blip = new Blip('A', new Ring('First')); - quadrant = new Quadrant('First'); - quadrant.add([blip]); - radar = new Radar(); + blip = new Blip('A', new Ring('First')) + quadrant = new Quadrant('First') + quadrant.add([blip]) + radar = new Radar() - radar.addQuadrant(quadrant); - radar.addQuadrant(new Quadrant('Second')); - radar.addQuadrant(new Quadrant('Third')); + radar.addQuadrant(quadrant) + radar.addQuadrant(new Quadrant('Second')) + radar.addQuadrant(new Quadrant('Third')) - expect(function() { radar.rings() }).toThrow(new MalformedDataError(ExceptionMessages.LESS_THAN_FOUR_QUADRANTS)); - }); + expect(function () { radar.rings() }).toThrow(new MalformedDataError(ExceptionMessages.LESS_THAN_FOUR_QUADRANTS)) + }) describe('blip numbers', function () { - var firstQuadrant, secondQuadrant, radar, firstRing; + var firstQuadrant, secondQuadrant, radar, firstRing beforeEach(function () { - firstRing = new Ring('Adopt', 0); - firstQuadrant = new Quadrant('First'); - secondQuadrant = new Quadrant('Second'); + firstRing = new Ring('Adopt', 0) + firstQuadrant = new Quadrant('First') + secondQuadrant = new Quadrant('Second') firstQuadrant.add([ new Blip('A', firstRing), new Blip('B', firstRing) - ]); + ]) secondQuadrant.add([ new Blip('C', firstRing), new Blip('D', firstRing) - ]); - radar = new Radar(); - }); + ]) + radar = new Radar() + }) it('sets blip numbers starting on the first quadrant', function () { - radar.addQuadrant(firstQuadrant); + radar.addQuadrant(firstQuadrant) - expect(radar.quadrants()[0].quadrant.blips()[0].number()).toEqual(1); - expect(radar.quadrants()[0].quadrant.blips()[1].number()).toEqual(2); - }); + expect(radar.quadrants()[0].quadrant.blips()[0].number()).toEqual(1) + expect(radar.quadrants()[0].quadrant.blips()[1].number()).toEqual(2) + }) it('continues the number from the previous quadrant set', function () { - radar.addQuadrant(firstQuadrant); - radar.addQuadrant(secondQuadrant); + radar.addQuadrant(firstQuadrant) + radar.addQuadrant(secondQuadrant) - expect(radar.quadrants()[1].quadrant.blips()[0].number()).toEqual(3); - expect(radar.quadrants()[1].quadrant.blips()[1].number()).toEqual(4); - }); - }); + expect(radar.quadrants()[1].quadrant.blips()[0].number()).toEqual(3) + expect(radar.quadrants()[1].quadrant.blips()[1].number()).toEqual(4) + }) + }) - describe('alternatives', function() { - it('returns a provided alternatives', function() { - var radar = new Radar(); + describe('alternatives', function () { + it('returns a provided alternatives', function () { + var radar = new Radar() - var alternative1 = 'alternative1'; - var alternative2 = 'alternative2'; + var alternative1 = 'alternative1' + var alternative2 = 'alternative2' - radar.addAlternative(alternative1); - radar.addAlternative(alternative2); + radar.addAlternative(alternative1) + radar.addAlternative(alternative2) - expect(radar.getAlternatives()).toEqual([alternative1, alternative2]); - }); - }); + expect(radar.getAlternatives()).toEqual([alternative1, alternative2]) + }) + }) describe('rings', function () { - var quadrant, radar, firstRing, secondRing, otherQuadrant; + var quadrant, radar, firstRing, secondRing, otherQuadrant beforeEach(function () { - firstRing = new Ring('Adopt', 0); - secondRing = new Ring('Hold', 1); - quadrant = new Quadrant('Fourth'); - otherQuadrant = new Quadrant('Other'); - radar = new Radar(); - }); + firstRing = new Ring('Adopt', 0) + secondRing = new Ring('Hold', 1) + quadrant = new Quadrant('Fourth') + otherQuadrant = new Quadrant('Other') + radar = new Radar() + }) it('returns an array for a given set of blips', function () { quadrant.add([ new Blip('A', firstRing), new Blip('B', secondRing) - ]); + ]) - radar.addQuadrant(quadrant); - radar.addQuadrant(otherQuadrant); - radar.addQuadrant(otherQuadrant); - radar.addQuadrant(otherQuadrant); + radar.addQuadrant(quadrant) + radar.addQuadrant(otherQuadrant) + radar.addQuadrant(otherQuadrant) + radar.addQuadrant(otherQuadrant) - expect(radar.rings()).toEqual([firstRing, secondRing]); - }); + expect(radar.rings()).toEqual([firstRing, secondRing]) + }) it('has unique rings', function () { quadrant.add([ new Blip('A', firstRing), new Blip('B', firstRing), new Blip('C', secondRing) - ]); + ]) - radar.addQuadrant(quadrant); - radar.addQuadrant(otherQuadrant); - radar.addQuadrant(otherQuadrant); - radar.addQuadrant(otherQuadrant); + radar.addQuadrant(quadrant) + radar.addQuadrant(otherQuadrant) + radar.addQuadrant(otherQuadrant) + radar.addQuadrant(otherQuadrant) - expect(radar.rings()).toEqual([firstRing, secondRing]); - }); + expect(radar.rings()).toEqual([firstRing, secondRing]) + }) it('has sorts by the ring order', function () { quadrant.add([ new Blip('C', secondRing), new Blip('A', firstRing), new Blip('B', firstRing) - ]); + ]) - radar.addQuadrant(quadrant); - radar.addQuadrant(otherQuadrant); - radar.addQuadrant(otherQuadrant); - radar.addQuadrant(otherQuadrant); + radar.addQuadrant(quadrant) + radar.addQuadrant(otherQuadrant) + radar.addQuadrant(otherQuadrant) + radar.addQuadrant(otherQuadrant) - expect(radar.rings()).toEqual([firstRing, secondRing]); - }); - }); -}); + expect(radar.rings()).toEqual([firstRing, secondRing]) + }) + }) +}) diff --git a/spec/models/ring-spec.js b/spec/models/ring-spec.js index 2c1ff529d..b11681054 100644 --- a/spec/models/ring-spec.js +++ b/spec/models/ring-spec.js @@ -1,15 +1,15 @@ -const Ring = require('../../src/models/ring'); +const Ring = require('../../src/models/ring') describe('Ring', function () { it('has a name', function () { - var ring = Ring('My Ring'); + var ring = Ring('My Ring') - expect(ring.name()).toEqual('My Ring'); - }); + expect(ring.name()).toEqual('My Ring') + }) it('has a order', function () { - var ring = new Ring('My Ring', 0); + var ring = new Ring('My Ring', 0) - expect(ring.order()).toEqual(0); - }); -}); + expect(ring.order()).toEqual(0) + }) +}) diff --git a/spec/util/contentValidator-spec.js b/spec/util/contentValidator-spec.js index 68388817e..c05be7001 100644 --- a/spec/util/contentValidator-spec.js +++ b/spec/util/contentValidator-spec.js @@ -1,52 +1,48 @@ -const ContentValidator = require('../../src/util/contentValidator'); -const MalformedDataError = require('../../src/exceptions/malformedDataError'); -const ExceptionMessages = require('../../src/util/exceptionMessages'); - +const ContentValidator = require('../../src/util/contentValidator') +const MalformedDataError = require('../../src/exceptions/malformedDataError') +const ExceptionMessages = require('../../src/util/exceptionMessages') describe('ContentValidator', function () { - describe('verifyContent', function () { it('does not return anything if content is valid', function () { - var columnNames = ["name", "ring", "quadrant", "isNew", "description"]; - var contentValidator = new ContentValidator(columnNames); + var columnNames = ['name', 'ring', 'quadrant', 'isNew', 'description'] + var contentValidator = new ContentValidator(columnNames) - expect(contentValidator.verifyContent()).not.toBeDefined(); - }); + expect(contentValidator.verifyContent()).not.toBeDefined() + }) it('raises an error if content is empty', function () { - var columnNames = []; - var contentValidator = new ContentValidator(columnNames); + var columnNames = [] + var contentValidator = new ContentValidator(columnNames) expect(function () { contentValidator.verifyContent() - }).toThrow(new MalformedDataError(ExceptionMessages.MISSING_CONTENT)); - }); - }); + }).toThrow(new MalformedDataError(ExceptionMessages.MISSING_CONTENT)) + }) + }) describe('verifyHeaders', function () { - it('raises an error if one of the headers is empty', function () { - var columnNames = ['ring', 'quadrant', 'isNew', 'description']; - var contentValidator = new ContentValidator(columnNames); + var columnNames = ['ring', 'quadrant', 'isNew', 'description'] + var contentValidator = new ContentValidator(columnNames) expect(function () { contentValidator.verifyHeaders() - }).toThrow(new MalformedDataError(ExceptionMessages.MISSING_HEADERS)); - }); + }).toThrow(new MalformedDataError(ExceptionMessages.MISSING_HEADERS)) + }) it('does not return anything if the all required headers are present', function () { - var columnNames = ['name', 'ring', 'quadrant', 'isNew', 'description']; - var contentValidator = new ContentValidator(columnNames); - - expect(contentValidator.verifyHeaders()).not.toBeDefined(); - }); + var columnNames = ['name', 'ring', 'quadrant', 'isNew', 'description'] + var contentValidator = new ContentValidator(columnNames) - it('does not care about white spaces in the headers', function() { - var columnNames = [' name', 'ring ', ' quadrant', 'isNew ', ' description ']; - var contentValidator = new ContentValidator(columnNames); + expect(contentValidator.verifyHeaders()).not.toBeDefined() + }) - expect(contentValidator.verifyHeaders()).not.toBeDefined(); - }); + it('does not care about white spaces in the headers', function () { + var columnNames = [' name', 'ring ', ' quadrant', 'isNew ', ' description '] + var contentValidator = new ContentValidator(columnNames) - }); -}); + expect(contentValidator.verifyHeaders()).not.toBeDefined() + }) + }) +}) diff --git a/spec/util/inputSanitizer-spec.js b/spec/util/inputSanitizer-spec.js index bdb0b6345..f4212c4bb 100644 --- a/spec/util/inputSanitizer-spec.js +++ b/spec/util/inputSanitizer-spec.js @@ -1,50 +1,50 @@ -const InputSanitizer = require('../../src/util/inputSanitizer'); - -describe('InputSanitizer', function(){ - var sanitizer, rawBlip, blip; - - beforeAll(function(){ - sanitizer = new InputSanitizer(); - var description = "Hello there

heading

"; - rawBlip = { - name: "Hello there

blip

", - description: description, - ring: 'Adopt', - quadrant: 'techniques & tools', - isNew: 'true
' - }; - - blip = sanitizer.sanitize(rawBlip); - }); - - it('strips out script tags from blip descriptions', function(){ - expect(blip.description).toEqual("Hello there

heading

"); - }); - - it('strips out all tags from blip name', function(){ - expect(blip.name).toEqual("Hello there blip"); - }); - - it('strips out all tags from blip status', function(){ - expect(blip.isNew).toEqual("true"); - }); - - it('strips out all tags from blip ring', function(){ - expect(blip.ring).toEqual("Adopt"); - }); - - it('strips out all tags from blip quadrant', function(){ - expect(blip.quadrant).toEqual("techniques & tools"); - }); - - it('trims white spaces in keys and values', function() { - rawBlip = { - ' name': ' Some name ', - ' ring ': ' Some ring name ', - }; - blip = sanitizer.sanitize(rawBlip); - - expect(blip.name).toEqual('Some name'); - expect(blip.ring).toEqual('Some ring name'); - }); -}); +const InputSanitizer = require('../../src/util/inputSanitizer') + +describe('InputSanitizer', function () { + var sanitizer, rawBlip, blip + + beforeAll(function () { + sanitizer = new InputSanitizer() + var description = "Hello there

heading

" + rawBlip = { + name: "Hello there

blip

", + description: description, + ring: 'Adopt', + quadrant: 'techniques & tools', + isNew: 'true
' + } + + blip = sanitizer.sanitize(rawBlip) + }) + + it('strips out script tags from blip descriptions', function () { + expect(blip.description).toEqual('Hello there

heading

') + }) + + it('strips out all tags from blip name', function () { + expect(blip.name).toEqual('Hello there blip') + }) + + it('strips out all tags from blip status', function () { + expect(blip.isNew).toEqual('true') + }) + + it('strips out all tags from blip ring', function () { + expect(blip.ring).toEqual('Adopt') + }) + + it('strips out all tags from blip quadrant', function () { + expect(blip.quadrant).toEqual('techniques & tools') + }) + + it('trims white spaces in keys and values', function () { + rawBlip = { + ' name': ' Some name ', + ' ring ': ' Some ring name ' + } + blip = sanitizer.sanitize(rawBlip) + + expect(blip.name).toEqual('Some name') + expect(blip.ring).toEqual('Some ring name') + }) +}) diff --git a/spec/util/queryParamProcessor-spec.js b/spec/util/queryParamProcessor-spec.js index f87cf09d3..fcf862bc8 100644 --- a/spec/util/queryParamProcessor-spec.js +++ b/spec/util/queryParamProcessor-spec.js @@ -1,23 +1,22 @@ -const QueryParams = require('../../src/util/queryParamProcessor'); +const QueryParams = require('../../src/util/queryParamProcessor') describe('QueryParams', function () { + it('retrieves one parameter', function () { + var params = QueryParams('param1=value1') - it('retrieves one parameter', function () { - var params = QueryParams('param1=value1'); + expect(params.param1).toEqual('value1') + }) - expect(params.param1).toEqual('value1'); - }); + it('retrieves zero parameter', function () { + var params = QueryParams('') - it('retrieves zero parameter', function () { - var params = QueryParams(''); + expect(params).toEqual({}) + }) - expect(params).toEqual({}); - }); + it('retrieves one parameter', function () { + var params = QueryParams('param1=value1¶m2=value2') - it('retrieves one parameter', function () { - var params = QueryParams('param1=value1¶m2=value2'); - - expect(params.param1).toEqual('value1'); - expect(params.param2).toEqual('value2'); - }); -}); \ No newline at end of file + expect(params.param1).toEqual('value1') + expect(params.param2).toEqual('value2') + }) +}) diff --git a/spec/util/ringCalculator-spec.js b/spec/util/ringCalculator-spec.js index 9e295c284..12cc2e776 100644 --- a/spec/util/ringCalculator-spec.js +++ b/spec/util/ringCalculator-spec.js @@ -1,20 +1,18 @@ -const RingCalculator = require('../../src/util/ringCalculator'); +const RingCalculator = require('../../src/util/ringCalculator') -describe('ringCalculator', function(){ - var ringLength, radarSize, ringCalculator; - beforeAll(function(){ - ringLength = 4; - radarSize = 500; - ringCalculator = new RingCalculator(ringLength, radarSize); +describe('ringCalculator', function () { + var ringLength, radarSize, ringCalculator + beforeAll(function () { + ringLength = 4 + radarSize = 500 + ringCalculator = new RingCalculator(ringLength, radarSize) + }) - }); + it('sums up the sequences', function () { + expect(ringCalculator.sum(ringLength)).toEqual(16) + }) - it('sums up the sequences', function(){ - expect(ringCalculator.sum(ringLength)).toEqual(16); - }); - - it('calculates the correct radius', function(){ - expect(ringCalculator.getRadius(ringLength)).toEqual(radarSize); - }); - -}); \ No newline at end of file + it('calculates the correct radius', function () { + expect(ringCalculator.getRadius(ringLength)).toEqual(radarSize) + }) +}) diff --git a/spec/util/sheet-spec.js b/spec/util/sheet-spec.js index 1103a037e..c74ce783c 100644 --- a/spec/util/sheet-spec.js +++ b/spec/util/sheet-spec.js @@ -1,65 +1,65 @@ -const Sheet = require('../../src/util/sheet'); +const Sheet = require('../../src/util/sheet') describe('sheet', function () { - var sheet; - var caller = {callback: function (){}}; + var sheet + var caller = { callback: function () {} } - beforeAll(function () { - spyOn(caller, 'callback'); - }); + beforeAll(function () { + spyOn(caller, 'callback') + }) - it('knows to find the sheet id from published URL', function () { - sheet = new Sheet('https://docs.google.com/spreadsheets/' + - 'd/1YXkrgV7Y6zShiPeyw4Y5_19QOfu5I6CyH5sGnbkEyiI/pubhtml'); + it('knows to find the sheet id from published URL', function () { + sheet = new Sheet('https://docs.google.com/spreadsheets/' + + 'd/1YXkrgV7Y6zShiPeyw4Y5_19QOfu5I6CyH5sGnbkEyiI/pubhtml') - expect(sheet.id).toEqual('1YXkrgV7Y6zShiPeyw4Y5_19QOfu5I6CyH5sGnbkEyiI'); - }); + expect(sheet.id).toEqual('1YXkrgV7Y6zShiPeyw4Y5_19QOfu5I6CyH5sGnbkEyiI') + }) - it('knows to find the sheet id from publicly shared URL having query params', function () { - sheet = new Sheet('https://docs.google.com/spreadsheets/' + - 'd/1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U?abc=xyz'); + it('knows to find the sheet id from publicly shared URL having query params', function () { + sheet = new Sheet('https://docs.google.com/spreadsheets/' + + 'd/1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U?abc=xyz') - expect(sheet.id).toEqual('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U'); - }); + expect(sheet.id).toEqual('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U') + }) - it('knows to find the sheet id from publicly shared URL having extra path and query params', function () { - sheet = new Sheet('https://docs.google.com/spreadsheets/' + - 'd/1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U/edit?usp=sharing'); + it('knows to find the sheet id from publicly shared URL having extra path and query params', function () { + sheet = new Sheet('https://docs.google.com/spreadsheets/' + + 'd/1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U/edit?usp=sharing') - expect(sheet.id).toEqual('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U'); - }); + expect(sheet.id).toEqual('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U') + }) - it('knows to find the sheet id from publicly shared URL having no extra path or query params', function () { - sheet = new Sheet('https://docs.google.com/spreadsheets/' + - 'd/1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U'); + it('knows to find the sheet id from publicly shared URL having no extra path or query params', function () { + sheet = new Sheet('https://docs.google.com/spreadsheets/' + + 'd/1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U') - expect(sheet.id).toEqual('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U'); - }); + expect(sheet.id).toEqual('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U') + }) - it('knows to find the sheet id from publicly shared URL with trailing slash', function () { - sheet = new Sheet('https://docs.google.com/spreadsheets/' + - 'd/1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U/'); + it('knows to find the sheet id from publicly shared URL with trailing slash', function () { + sheet = new Sheet('https://docs.google.com/spreadsheets/' + + 'd/1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U/') - expect(sheet.id).toEqual('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U'); - }); + expect(sheet.id).toEqual('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U') + }) - it('can identify a plain sheet ID', function () { - sheet = new Sheet('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U'); + it('can identify a plain sheet ID', function () { + sheet = new Sheet('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U') - expect(sheet.id).toEqual('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U'); - }); + expect(sheet.id).toEqual('1wLRmV2tVlS5PqjKFyiTA0HuoH8vp_h_DOmjciZAEG0U') + }) - xit('calls back with nothing if the sheet exists', function () { - sheet = new Sheet('http://example.com/a/b/c/d/?x=y'); - sheet.exists(caller.callback); + xit('calls back with nothing if the sheet exists', function () { + sheet = new Sheet('http://example.com/a/b/c/d/?x=y') + sheet.exists(caller.callback) - expect(caller.callback).toHaveBeenCalledWith(undefined); - }); + expect(caller.callback).toHaveBeenCalledWith(undefined) + }) - xit('calls back with error if sheet the sheet does not exist', function () { - sheet = new Sheet('http://example.com/a/b/c/d/?x=y'); - sheet.exists(caller.callback); + xit('calls back with error if sheet the sheet does not exist', function () { + sheet = new Sheet('http://example.com/a/b/c/d/?x=y') + sheet.exists(caller.callback) - expect(caller.callback).toHaveBeenCalledWith('Some error'); - }); -}); \ No newline at end of file + expect(caller.callback).toHaveBeenCalledWith('Some error') + }) +}) diff --git a/src/common.js b/src/common.js index 39afb1536..9f129f183 100644 --- a/src/common.js +++ b/src/common.js @@ -1,4 +1,4 @@ -require('./stylesheets/base.scss'); -require('./images/tech-radar-landing-page-wide.png'); -require('./images/tw-logo.png'); -require('./images/favicon.ico'); +require('./stylesheets/base.scss') +require('./images/tech-radar-landing-page-wide.png') +require('./images/tw-logo.png') +require('./images/favicon.ico') diff --git a/src/exceptions/malformedDataError.js b/src/exceptions/malformedDataError.js index 1565d092b..33ab8b1f4 100644 --- a/src/exceptions/malformedDataError.js +++ b/src/exceptions/malformedDataError.js @@ -1,11 +1,11 @@ -const MalformedDataError = function(message){ - this.message=message; -}; +const MalformedDataError = function (message) { + this.message = message +} -Object.setPrototypeOf(MalformedDataError, Error); -MalformedDataError.prototype = Object.create(Error.prototype); -MalformedDataError.prototype.name = "MalformedDataError"; -MalformedDataError.prototype.message = ""; -MalformedDataError.prototype.constructor = MalformedDataError; +Object.setPrototypeOf(MalformedDataError, Error) +MalformedDataError.prototype = Object.create(Error.prototype) +MalformedDataError.prototype.name = 'MalformedDataError' +MalformedDataError.prototype.message = '' +MalformedDataError.prototype.constructor = MalformedDataError -module.exports = MalformedDataError; +module.exports = MalformedDataError diff --git a/src/exceptions/sheetNotFoundError.js b/src/exceptions/sheetNotFoundError.js index eafc46a12..e0030eed3 100644 --- a/src/exceptions/sheetNotFoundError.js +++ b/src/exceptions/sheetNotFoundError.js @@ -1,11 +1,11 @@ -const SheetNotFoundError = function(message){ - this.message=message; -}; +const SheetNotFoundError = function (message) { + this.message = message +} -Object.setPrototypeOf(SheetNotFoundError, Error); -SheetNotFoundError.prototype = Object.create(Error.prototype); -SheetNotFoundError.prototype.name = "SheetNotFoundError"; -SheetNotFoundError.prototype.message = ""; -SheetNotFoundError.prototype.constructor = SheetNotFoundError; +Object.setPrototypeOf(SheetNotFoundError, Error) +SheetNotFoundError.prototype = Object.create(Error.prototype) +SheetNotFoundError.prototype.name = 'SheetNotFoundError' +SheetNotFoundError.prototype.message = '' +SheetNotFoundError.prototype.constructor = SheetNotFoundError -module.exports = SheetNotFoundError; +module.exports = SheetNotFoundError diff --git a/src/graphing/radar.js b/src/graphing/radar.js index 048554df3..e0ac83c6d 100644 --- a/src/graphing/radar.js +++ b/src/graphing/radar.js @@ -1,91 +1,89 @@ -const d3 = require('d3'); -const d3tip = require('d3-tip'); -const Chance = require('chance'); -const _ = require('lodash/core'); +const d3 = require('d3') +const d3tip = require('d3-tip') +const Chance = require('chance') +const _ = require('lodash/core') -const RingCalculator = require('../util/ringCalculator'); -const QueryParams = require('../util/queryParamProcessor'); +const RingCalculator = require('../util/ringCalculator') +const QueryParams = require('../util/queryParamProcessor') -const MIN_BLIP_WIDTH = 12; +const MIN_BLIP_WIDTH = 12 const Radar = function (size, radar) { - var svg, radarElement; + var svg, radarElement var tip = d3tip().attr('class', 'd3-tip').html(function (text) { - return text; - }); + return text + }) tip.direction(function () { if (d3.select('.quadrant-table.selected').node()) { - var selectedQuadrant = d3.select('.quadrant-table.selected'); - if (selectedQuadrant.classed('first') || selectedQuadrant.classed('fourth')) - return 'ne'; - else - return 'nw'; + var selectedQuadrant = d3.select('.quadrant-table.selected') + if (selectedQuadrant.classed('first') || selectedQuadrant.classed('fourth')) { return 'ne' } else { return 'nw' } } - return 'n'; - }); + return 'n' + }) - var ringCalculator = new RingCalculator(radar.rings().length, center()); + var ringCalculator = new RingCalculator(radar.rings().length, center()) - var self = {}; + var self = {} + var chance - function center() { - return Math.round(size / 2); + function center () { + return Math.round(size / 2) } - function toRadian(angleInDegrees) { - return Math.PI * angleInDegrees / 180; + function toRadian (angleInDegrees) { + return Math.PI * angleInDegrees / 180 } - function plotLines(quadrantGroup, quadrant) { - var startX = size * (1 - (-Math.sin(toRadian(quadrant.startAngle)) + 1) / 2); - var endX = size * (1 - (-Math.sin(toRadian(quadrant.startAngle - 90)) + 1) / 2); + function plotLines (quadrantGroup, quadrant) { + var startX = size * (1 - (-Math.sin(toRadian(quadrant.startAngle)) + 1) / 2) + var endX = size * (1 - (-Math.sin(toRadian(quadrant.startAngle - 90)) + 1) / 2) - var startY = size * (1 - (Math.cos(toRadian(quadrant.startAngle)) + 1) / 2); - var endY = size * (1 - (Math.cos(toRadian(quadrant.startAngle - 90)) + 1) / 2); + var startY = size * (1 - (Math.cos(toRadian(quadrant.startAngle)) + 1) / 2) + var endY = size * (1 - (Math.cos(toRadian(quadrant.startAngle - 90)) + 1) / 2) if (startY > endY) { - var aux = endY; - endY = startY; - startY = aux; + var aux = endY + endY = startY + startY = aux } quadrantGroup.append('line') .attr('x1', center()).attr('x2', center()) .attr('y1', startY - 2).attr('y2', endY + 2) - .attr('stroke-width', 10); + .attr('stroke-width', 10) quadrantGroup.append('line') .attr('x1', endX).attr('y1', center()) .attr('x2', startX).attr('y2', center()) - .attr('stroke-width', 10); + .attr('stroke-width', 10) } - function plotQuadrant(rings, quadrant) { + function plotQuadrant (rings, quadrant) { var quadrantGroup = svg.append('g') .attr('class', 'quadrant-group quadrant-group-' + quadrant.order) .on('mouseover', mouseoverQuadrant.bind({}, quadrant.order)) .on('mouseout', mouseoutQuadrant.bind({}, quadrant.order)) - .on('click', selectQuadrant.bind({}, quadrant.order, quadrant.startAngle)); + .on('click', selectQuadrant.bind({}, quadrant.order, quadrant.startAngle)) rings.forEach(function (ring, i) { var arc = d3.arc() .innerRadius(ringCalculator.getRadius(i)) .outerRadius(ringCalculator.getRadius(i + 1)) .startAngle(toRadian(quadrant.startAngle)) - .endAngle(toRadian(quadrant.startAngle - 90)); + .endAngle(toRadian(quadrant.startAngle - 90)) quadrantGroup.append('path') .attr('d', arc) .attr('class', 'ring-arc-' + ring.order()) - .attr('transform', 'translate(' + center() + ', ' + center() + ')'); - }); + .attr('transform', 'translate(' + center() + ', ' + center() + ')') + }) - return quadrantGroup; + return quadrantGroup } - function plotTexts(quadrantGroup, rings, quadrant) { + function plotTexts (quadrantGroup, rings, quadrant) { rings.forEach(function (ring, i) { if (quadrant.order === 'first' || quadrant.order === 'fourth') { quadrantGroup.append('text') @@ -93,154 +91,154 @@ const Radar = function (size, radar) { .attr('y', center() + 4) .attr('x', center() + (ringCalculator.getRadius(i) + ringCalculator.getRadius(i + 1)) / 2) .attr('text-anchor', 'middle') - .text(ring.name()); + .text(ring.name()) } else { quadrantGroup.append('text') .attr('class', 'line-text') .attr('y', center() + 4) .attr('x', center() - (ringCalculator.getRadius(i) + ringCalculator.getRadius(i + 1)) / 2) .attr('text-anchor', 'middle') - .text(ring.name()); + .text(ring.name()) } - }); + }) } - function triangle(blip, x, y, order, group) { - return group.append('path').attr('d', "M412.201,311.406c0.021,0,0.042,0,0.063,0c0.067,0,0.135,0,0.201,0c4.052,0,6.106-0.051,8.168-0.102c2.053-0.051,4.115-0.102,8.176-0.102h0.103c6.976-0.183,10.227-5.306,6.306-11.53c-3.988-6.121-4.97-5.407-8.598-11.224c-1.631-3.008-3.872-4.577-6.179-4.577c-2.276,0-4.613,1.528-6.48,4.699c-3.578,6.077-3.26,6.014-7.306,11.723C402.598,306.067,405.426,311.406,412.201,311.406") + function triangle (blip, x, y, order, group) { + return group.append('path').attr('d', 'M412.201,311.406c0.021,0,0.042,0,0.063,0c0.067,0,0.135,0,0.201,0c4.052,0,6.106-0.051,8.168-0.102c2.053-0.051,4.115-0.102,8.176-0.102h0.103c6.976-0.183,10.227-5.306,6.306-11.53c-3.988-6.121-4.97-5.407-8.598-11.224c-1.631-3.008-3.872-4.577-6.179-4.577c-2.276,0-4.613,1.528-6.48,4.699c-3.578,6.077-3.26,6.014-7.306,11.723C402.598,306.067,405.426,311.406,412.201,311.406') .attr('transform', 'scale(' + (blip.width / 34) + ') translate(' + (-404 + x * (34 / blip.width) - 17) + ', ' + (-282 + y * (34 / blip.width) - 17) + ')') - .attr('class', order); + .attr('class', order) } - function triangleLegend(x, y, group) { - return group.append('path').attr('d', "M412.201,311.406c0.021,0,0.042,0,0.063,0c0.067,0,0.135,0,0.201,0c4.052,0,6.106-0.051,8.168-0.102c2.053-0.051,4.115-0.102,8.176-0.102h0.103c6.976-0.183,10.227-5.306,6.306-11.53c-3.988-6.121-4.97-5.407-8.598-11.224c-1.631-3.008-3.872-4.577-6.179-4.577c-2.276,0-4.613,1.528-6.48,4.699c-3.578,6.077-3.26,6.014-7.306,11.723C402.598,306.067,405.426,311.406,412.201,311.406") - .attr('transform', 'scale(' + (22 / 64) + ') translate(' + (-404 + x * (64 / 22) - 17) + ', ' + (-282 + y * (64 / 22) - 17) + ')'); + function triangleLegend (x, y, group) { + return group.append('path').attr('d', 'M412.201,311.406c0.021,0,0.042,0,0.063,0c0.067,0,0.135,0,0.201,0c4.052,0,6.106-0.051,8.168-0.102c2.053-0.051,4.115-0.102,8.176-0.102h0.103c6.976-0.183,10.227-5.306,6.306-11.53c-3.988-6.121-4.97-5.407-8.598-11.224c-1.631-3.008-3.872-4.577-6.179-4.577c-2.276,0-4.613,1.528-6.48,4.699c-3.578,6.077-3.26,6.014-7.306,11.723C402.598,306.067,405.426,311.406,412.201,311.406') + .attr('transform', 'scale(' + (22 / 64) + ') translate(' + (-404 + x * (64 / 22) - 17) + ', ' + (-282 + y * (64 / 22) - 17) + ')') } - function circle(blip, x, y, order, group) { + function circle (blip, x, y, order, group) { return (group || svg).append('path') - .attr('d', "M420.084,282.092c-1.073,0-2.16,0.103-3.243,0.313c-6.912,1.345-13.188,8.587-11.423,16.874c1.732,8.141,8.632,13.711,17.806,13.711c0.025,0,0.052,0,0.074-0.003c0.551-0.025,1.395-0.011,2.225-0.109c4.404-0.534,8.148-2.218,10.069-6.487c1.747-3.886,2.114-7.993,0.913-12.118C434.379,286.944,427.494,282.092,420.084,282.092") + .attr('d', 'M420.084,282.092c-1.073,0-2.16,0.103-3.243,0.313c-6.912,1.345-13.188,8.587-11.423,16.874c1.732,8.141,8.632,13.711,17.806,13.711c0.025,0,0.052,0,0.074-0.003c0.551-0.025,1.395-0.011,2.225-0.109c4.404-0.534,8.148-2.218,10.069-6.487c1.747-3.886,2.114-7.993,0.913-12.118C434.379,286.944,427.494,282.092,420.084,282.092') .attr('transform', 'scale(' + (blip.width / 34) + ') translate(' + (-404 + x * (34 / blip.width) - 17) + ', ' + (-282 + y * (34 / blip.width) - 17) + ')') - .attr('class', order); + .attr('class', order) } - function circleLegend(x, y, group) { + function circleLegend (x, y, group) { return (group || svg).append('path') - .attr('d', "M420.084,282.092c-1.073,0-2.16,0.103-3.243,0.313c-6.912,1.345-13.188,8.587-11.423,16.874c1.732,8.141,8.632,13.711,17.806,13.711c0.025,0,0.052,0,0.074-0.003c0.551-0.025,1.395-0.011,2.225-0.109c4.404-0.534,8.148-2.218,10.069-6.487c1.747-3.886,2.114-7.993,0.913-12.118C434.379,286.944,427.494,282.092,420.084,282.092") - .attr('transform', 'scale(' + (22 / 64) + ') translate(' + (-404 + x * (64 / 22) - 17) + ', ' + (-282 + y * (64 / 22) - 17) + ')'); + .attr('d', 'M420.084,282.092c-1.073,0-2.16,0.103-3.243,0.313c-6.912,1.345-13.188,8.587-11.423,16.874c1.732,8.141,8.632,13.711,17.806,13.711c0.025,0,0.052,0,0.074-0.003c0.551-0.025,1.395-0.011,2.225-0.109c4.404-0.534,8.148-2.218,10.069-6.487c1.747-3.886,2.114-7.993,0.913-12.118C434.379,286.944,427.494,282.092,420.084,282.092') + .attr('transform', 'scale(' + (22 / 64) + ') translate(' + (-404 + x * (64 / 22) - 17) + ', ' + (-282 + y * (64 / 22) - 17) + ')') } - function addRing(ring, order) { - var table = d3.select('.quadrant-table.' + order); - table.append('h3').text(ring); - return table.append('ul'); + function addRing (ring, order) { + var table = d3.select('.quadrant-table.' + order) + table.append('h3').text(ring) + return table.append('ul') } - function calculateBlipCoordinates(blip, chance, minRadius, maxRadius, startAngle) { - var adjustX = Math.sin(toRadian(startAngle)) - Math.cos(toRadian(startAngle)); - var adjustY = -Math.cos(toRadian(startAngle)) - Math.sin(toRadian(startAngle)); + function calculateBlipCoordinates (blip, chance, minRadius, maxRadius, startAngle) { + var adjustX = Math.sin(toRadian(startAngle)) - Math.cos(toRadian(startAngle)) + var adjustY = -Math.cos(toRadian(startAngle)) - Math.sin(toRadian(startAngle)) - var radius = chance.floating({min: minRadius + blip.width / 2, max: maxRadius - blip.width / 2}); - var angleDelta = Math.asin(blip.width / 2 / radius) * 180 / Math.PI; - angleDelta = angleDelta > 45 ? 45 : angleDelta; - var angle = toRadian(chance.integer({min: angleDelta, max: 90 - angleDelta})); + var radius = chance.floating({ min: minRadius + blip.width / 2, max: maxRadius - blip.width / 2 }) + var angleDelta = Math.asin(blip.width / 2 / radius) * 180 / Math.PI + angleDelta = angleDelta > 45 ? 45 : angleDelta + var angle = toRadian(chance.integer({ min: angleDelta, max: 90 - angleDelta })) - var x = center() + radius * Math.cos(angle) * adjustX; - var y = center() + radius * Math.sin(angle) * adjustY; + var x = center() + radius * Math.cos(angle) * adjustX + var y = center() + radius * Math.sin(angle) * adjustY - return [x, y]; + return [x, y] } - function thereIsCollision(blip, coordinates, allCoordinates) { + function thereIsCollision (blip, coordinates, allCoordinates) { return allCoordinates.some(function (currentCoordinates) { return (Math.abs(currentCoordinates[0] - coordinates[0]) < blip.width) && (Math.abs(currentCoordinates[1] - coordinates[1]) < blip.width) - }); + }) } - function plotBlips(quadrantGroup, rings, quadrantWrapper) { - var blips, quadrant, startAngle, order; + function plotBlips (quadrantGroup, rings, quadrantWrapper) { + var blips, quadrant, startAngle, order - quadrant = quadrantWrapper.quadrant; - startAngle = quadrantWrapper.startAngle; - order = quadrantWrapper.order; + quadrant = quadrantWrapper.quadrant + startAngle = quadrantWrapper.startAngle + order = quadrantWrapper.order d3.select('.quadrant-table.' + order) .append('h2') .attr('class', 'quadrant-table__name') - .text(quadrant.name()); + .text(quadrant.name()) - blips = quadrant.blips(); + blips = quadrant.blips() rings.forEach(function (ring, i) { var ringBlips = blips.filter(function (blip) { - return blip.ring() == ring; - }); + return blip.ring() === ring + }) - if (ringBlips.length == 0) { - return; + if (ringBlips.length === 0) { + return } - var maxRadius, minRadius; + var maxRadius, minRadius - minRadius = ringCalculator.getRadius(i); - maxRadius = ringCalculator.getRadius(i + 1); + minRadius = ringCalculator.getRadius(i) + maxRadius = ringCalculator.getRadius(i + 1) var sumRing = ring.name().split('').reduce(function (p, c) { - return p + c.charCodeAt(0); - }, 0); + return p + c.charCodeAt(0) + }, 0) var sumQuadrant = quadrant.name().split('').reduce(function (p, c) { - return p + c.charCodeAt(0); - }, 0); - var chance = new Chance(Math.PI * sumRing * ring.name().length * sumQuadrant * quadrant.name().length); + return p + c.charCodeAt(0) + }, 0) + chance = new Chance(Math.PI * sumRing * ring.name().length * sumQuadrant * quadrant.name().length) - var ringList = addRing(ring.name(), order); - var allBlipCoordinatesInRing = []; + var ringList = addRing(ring.name(), order) + var allBlipCoordinatesInRing = [] ringBlips.forEach(function (blip) { const coordinates = findBlipCoordinates(blip, minRadius, maxRadius, startAngle, - allBlipCoordinatesInRing); + allBlipCoordinatesInRing) - allBlipCoordinatesInRing.push(coordinates); - drawBlipInCoordinates(blip, coordinates, order, quadrantGroup, ringList); - }); - }); + allBlipCoordinatesInRing.push(coordinates) + drawBlipInCoordinates(blip, coordinates, order, quadrantGroup, ringList) + }) + }) } - function findBlipCoordinates(blip, minRadius, maxRadius, startAngle, allBlipCoordinatesInRing) { - const maxIterations = 200; - var coordinates = calculateBlipCoordinates(blip, chance, minRadius, maxRadius, startAngle); - var iterationCounter = 0; - var foundAPlace = false; + function findBlipCoordinates (blip, minRadius, maxRadius, startAngle, allBlipCoordinatesInRing) { + const maxIterations = 200 + var coordinates = calculateBlipCoordinates(blip, chance, minRadius, maxRadius, startAngle) + var iterationCounter = 0 + var foundAPlace = false while (iterationCounter < maxIterations) { if (thereIsCollision(blip, coordinates, allBlipCoordinatesInRing)) { - coordinates = calculateBlipCoordinates(blip, chance, minRadius, maxRadius, startAngle); + coordinates = calculateBlipCoordinates(blip, chance, minRadius, maxRadius, startAngle) } else { - foundAPlace = true; - break; + foundAPlace = true + break } - iterationCounter++; + iterationCounter++ } if (!foundAPlace && blip.width > MIN_BLIP_WIDTH) { - blip.width = blip.width - 1; - return findBlipCoordinates(blip, minRadius, maxRadius, startAngle, allBlipCoordinatesInRing); + blip.width = blip.width - 1 + return findBlipCoordinates(blip, minRadius, maxRadius, startAngle, allBlipCoordinatesInRing) } else { - return coordinates; + return coordinates } } - function drawBlipInCoordinates(blip, coordinates, order, quadrantGroup, ringList) { - var x = coordinates[0]; - var y = coordinates[1]; + function drawBlipInCoordinates (blip, coordinates, order, quadrantGroup, ringList) { + var x = coordinates[0] + var y = coordinates[1] - var group = quadrantGroup.append('g').attr('class', 'blip-link'); + var group = quadrantGroup.append('g').attr('class', 'blip-link') if (blip.isNew()) { - triangle(blip, x, y, order, group); + triangle(blip, x, y, order, group) } else { - circle(blip, x, y, order, group); + circle(blip, x, y, order, group) } group.append('text') @@ -250,54 +248,54 @@ const Radar = function (size, radar) { // derive font-size from current blip width .style('font-size', ((blip.width * 10) / 22) + 'px') .attr('text-anchor', 'middle') - .text(blip.number()); + .text(blip.number()) - var blipListItem = ringList.append('li'); - var blipText = blip.number() + '. ' + blip.name() + (blip.topic() ? ('. - ' + blip.topic()) : ''); + var blipListItem = ringList.append('li') + var blipText = blip.number() + '. ' + blip.name() + (blip.topic() ? ('. - ' + blip.topic()) : '') blipListItem.append('div') .attr('class', 'blip-list-item') - .text(blipText); + .text(blipText) var blipItemDescription = blipListItem.append('div') - .attr('class', 'blip-item-description'); + .attr('class', 'blip-item-description') if (blip.description()) { - blipItemDescription.append('p').html(blip.description()); + blipItemDescription.append('p').html(blip.description()) } var mouseOver = function () { - d3.selectAll('g.blip-link').attr('opacity', 0.3); - group.attr('opacity', 1.0); - blipListItem.selectAll('.blip-list-item').classed('highlight', true); - tip.show(blip.name(), group.node()); - }; + d3.selectAll('g.blip-link').attr('opacity', 0.3) + group.attr('opacity', 1.0) + blipListItem.selectAll('.blip-list-item').classed('highlight', true) + tip.show(blip.name(), group.node()) + } var mouseOut = function () { - d3.selectAll('g.blip-link').attr('opacity', 1.0); - blipListItem.selectAll('.blip-list-item').classed('highlight', false); - tip.hide().style('left', 0).style('top', 0); - }; + d3.selectAll('g.blip-link').attr('opacity', 1.0) + blipListItem.selectAll('.blip-list-item').classed('highlight', false) + tip.hide().style('left', 0).style('top', 0) + } - blipListItem.on('mouseover', mouseOver).on('mouseout', mouseOut); - group.on('mouseover', mouseOver).on('mouseout', mouseOut); + blipListItem.on('mouseover', mouseOver).on('mouseout', mouseOut) + group.on('mouseover', mouseOver).on('mouseout', mouseOut) var clickBlip = function () { d3.select('.blip-item-description.expanded').node() !== blipItemDescription.node() && - d3.select('.blip-item-description.expanded').classed("expanded", false); - blipItemDescription.classed("expanded", !blipItemDescription.classed("expanded")); + d3.select('.blip-item-description.expanded').classed('expanded', false) + blipItemDescription.classed('expanded', !blipItemDescription.classed('expanded')) blipItemDescription.on('click', function () { - d3.event.stopPropagation(); - }); - }; + d3.event.stopPropagation() + }) + } - blipListItem.on('click', clickBlip); + blipListItem.on('click', clickBlip) } - function removeHomeLink(){ - d3.select('.home-link').remove(); + function removeHomeLink () { + d3.select('.home-link').remove() } - function createHomeLink(pageElement) { + function createHomeLink (pageElement) { if (pageElement.select('.home-link').empty()) { pageElement.append('div') .html('« Back to Radar home') @@ -307,101 +305,99 @@ const Radar = function (size, radar) { .append('g') .attr('fill', '#626F87') .append('path') - .attr('d', 'M27.6904224,13.939279 C27.6904224,13.7179572 27.6039633,13.5456925 27.4314224,13.4230122 L18.9285959,6.85547454 C18.6819796,6.65886965 18.410898,6.65886965 18.115049,6.85547454 L9.90776939,13.4230122 C9.75999592,13.5456925 9.68592041,13.7179572 9.68592041,13.939279 L9.68592041,25.7825947 C9.68592041,25.979501 9.74761224,26.1391059 9.87092041,26.2620876 C9.99415306,26.3851446 10.1419265,26.4467108 10.3145429,26.4467108 L15.1946918,26.4467108 C15.391698,26.4467108 15.5518551,26.3851446 15.6751633,26.2620876 C15.7984714,26.1391059 15.8600878,25.979501 15.8600878,25.7825947 L15.8600878,18.5142424 L21.4794061,18.5142424 L21.4794061,25.7822933 C21.4794061,25.9792749 21.5410224,26.1391059 21.6643306,26.2620876 C21.7876388,26.3851446 21.9477959,26.4467108 22.1448776,26.4467108 L27.024951,26.4467108 C27.2220327,26.4467108 27.3821898,26.3851446 27.505498,26.2620876 C27.6288061,26.1391059 27.6904224,25.9792749 27.6904224,25.7822933 L27.6904224,13.939279 Z M18.4849735,0.0301425662 C21.0234,0.0301425662 23.4202449,0.515814664 25.6755082,1.48753564 C27.9308469,2.45887984 29.8899592,3.77497963 31.5538265,5.43523218 C33.2173918,7.09540937 34.5358755,9.05083299 35.5095796,11.3015031 C36.4829061,13.5518717 36.9699469,15.9439104 36.9699469,18.4774684 C36.9699469,20.1744196 36.748098,21.8101813 36.3044755,23.3844521 C35.860551,24.9584216 35.238498,26.4281731 34.4373347,27.7934053 C33.6362469,29.158336 32.6753041,30.4005112 31.5538265,31.5197047 C30.432349,32.6388982 29.1876388,33.5981853 27.8199224,34.3973401 C26.4519041,35.1968717 24.9791531,35.8176578 23.4016694,36.2606782 C21.8244878,36.7033971 20.1853878,36.9247943 18.4849735,36.9247943 C16.7841816,36.9247943 15.1453837,36.7033971 13.5679755,36.2606782 C11.9904918,35.8176578 10.5180429,35.1968717 9.15002449,34.3973401 C7.78223265,33.5978839 6.53752245,32.6388982 5.41612041,31.5197047 C4.29464286,30.4005112 3.33339796,29.158336 2.53253673,27.7934053 C1.73144898,26.4281731 1.10909388,24.9584216 0.665395918,23.3844521 C0.22184898,21.8101813 0,20.1744196 0,18.4774684 C0,16.7801405 0.22184898,15.1446802 0.665395918,13.5704847 C1.10909388,11.9962138 1.73144898,10.5267637 2.53253673,9.16153157 C3.33339796,7.79652546 4.29464286,6.55435031 5.41612041,5.43523218 C6.53752245,4.3160387 7.78223265,3.35675153 9.15002449,2.55752138 C10.5180429,1.75806517 11.9904918,1.13690224 13.5679755,0.694183299 C15.1453837,0.251464358 16.7841816,0.0301425662 18.4849735,0.0301425662 L18.4849735,0.0301425662 Z'); + .attr('d', 'M27.6904224,13.939279 C27.6904224,13.7179572 27.6039633,13.5456925 27.4314224,13.4230122 L18.9285959,6.85547454 C18.6819796,6.65886965 18.410898,6.65886965 18.115049,6.85547454 L9.90776939,13.4230122 C9.75999592,13.5456925 9.68592041,13.7179572 9.68592041,13.939279 L9.68592041,25.7825947 C9.68592041,25.979501 9.74761224,26.1391059 9.87092041,26.2620876 C9.99415306,26.3851446 10.1419265,26.4467108 10.3145429,26.4467108 L15.1946918,26.4467108 C15.391698,26.4467108 15.5518551,26.3851446 15.6751633,26.2620876 C15.7984714,26.1391059 15.8600878,25.979501 15.8600878,25.7825947 L15.8600878,18.5142424 L21.4794061,18.5142424 L21.4794061,25.7822933 C21.4794061,25.9792749 21.5410224,26.1391059 21.6643306,26.2620876 C21.7876388,26.3851446 21.9477959,26.4467108 22.1448776,26.4467108 L27.024951,26.4467108 C27.2220327,26.4467108 27.3821898,26.3851446 27.505498,26.2620876 C27.6288061,26.1391059 27.6904224,25.9792749 27.6904224,25.7822933 L27.6904224,13.939279 Z M18.4849735,0.0301425662 C21.0234,0.0301425662 23.4202449,0.515814664 25.6755082,1.48753564 C27.9308469,2.45887984 29.8899592,3.77497963 31.5538265,5.43523218 C33.2173918,7.09540937 34.5358755,9.05083299 35.5095796,11.3015031 C36.4829061,13.5518717 36.9699469,15.9439104 36.9699469,18.4774684 C36.9699469,20.1744196 36.748098,21.8101813 36.3044755,23.3844521 C35.860551,24.9584216 35.238498,26.4281731 34.4373347,27.7934053 C33.6362469,29.158336 32.6753041,30.4005112 31.5538265,31.5197047 C30.432349,32.6388982 29.1876388,33.5981853 27.8199224,34.3973401 C26.4519041,35.1968717 24.9791531,35.8176578 23.4016694,36.2606782 C21.8244878,36.7033971 20.1853878,36.9247943 18.4849735,36.9247943 C16.7841816,36.9247943 15.1453837,36.7033971 13.5679755,36.2606782 C11.9904918,35.8176578 10.5180429,35.1968717 9.15002449,34.3973401 C7.78223265,33.5978839 6.53752245,32.6388982 5.41612041,31.5197047 C4.29464286,30.4005112 3.33339796,29.158336 2.53253673,27.7934053 C1.73144898,26.4281731 1.10909388,24.9584216 0.665395918,23.3844521 C0.22184898,21.8101813 0,20.1744196 0,18.4774684 C0,16.7801405 0.22184898,15.1446802 0.665395918,13.5704847 C1.10909388,11.9962138 1.73144898,10.5267637 2.53253673,9.16153157 C3.33339796,7.79652546 4.29464286,6.55435031 5.41612041,5.43523218 C6.53752245,4.3160387 7.78223265,3.35675153 9.15002449,2.55752138 C10.5180429,1.75806517 11.9904918,1.13690224 13.5679755,0.694183299 C15.1453837,0.251464358 16.7841816,0.0301425662 18.4849735,0.0301425662 L18.4849735,0.0301425662 Z') } } - function removeRadarLegend(){ - d3.select('.legend').remove(); + function removeRadarLegend () { + d3.select('.legend').remove() } - function drawLegend(order) { - removeRadarLegend(); + function drawLegend (order) { + removeRadarLegend() - var triangleKey = "New or moved"; - var circleKey = "No change"; + var triangleKey = 'New or moved' + var circleKey = 'No change' var container = d3.select('svg').append('g') - .attr('class', 'legend legend'+"-"+order); - - var x = 10; - var y = 10; + .attr('class', 'legend legend' + '-' + order) + var x = 10 + var y = 10 - if(order == "first") { - x = 4 * size / 5; - y = 1 * size / 5; + if (order === 'first') { + x = 4 * size / 5 + y = 1 * size / 5 } - if(order == "second") { - x = 1 * size / 5 - 15; - y = 1 * size / 5 - 20; + if (order === 'second') { + x = 1 * size / 5 - 15 + y = 1 * size / 5 - 20 } - if(order == "third") { - x = 1 * size / 5 - 15; - y = 4 * size / 5 + 15; + if (order === 'third') { + x = 1 * size / 5 - 15 + y = 4 * size / 5 + 15 } - if(order == "fourth") { - x = 4 * size / 5; - y = 4 * size / 5; + if (order === 'fourth') { + x = 4 * size / 5 + y = 4 * size / 5 } d3.select('.legend') - .attr('class', 'legend legend-'+order) + .attr('class', 'legend legend-' + order) .transition() - .style('visibility', 'visible'); + .style('visibility', 'visible') - triangleLegend(x, y, container); + triangleLegend(x, y, container) container .append('text') .attr('x', x + 15) .attr('y', y + 5) .attr('font-size', '0.8em') - .text(triangleKey); + .text(triangleKey) - - circleLegend(x, y + 20, container); + circleLegend(x, y + 20, container) container .append('text') .attr('x', x + 15) .attr('y', y + 25) .attr('font-size', '0.8em') - .text(circleKey); + .text(circleKey) } - function redrawFullRadar() { - removeHomeLink(); - removeRadarLegend(); + function redrawFullRadar () { + removeHomeLink() + removeRadarLegend() - svg.style('left', 0).style('right', 0); + svg.style('left', 0).style('right', 0) d3.selectAll('.button') .classed('selected', false) - .classed('full-view', true); + .classed('full-view', true) - d3.selectAll('.quadrant-table').classed('selected', false); - d3.selectAll('.home-link').classed('selected', false); + d3.selectAll('.quadrant-table').classed('selected', false) + d3.selectAll('.home-link').classed('selected', false) d3.selectAll('.quadrant-group') .transition() .duration(1000) - .attr('transform', 'scale(1)'); + .attr('transform', 'scale(1)') d3.selectAll('.quadrant-group .blip-link') .transition() .duration(1000) - .attr('transform', 'scale(1)'); + .attr('transform', 'scale(1)') d3.selectAll('.quadrant-group') - .style('pointer-events', 'auto'); + .style('pointer-events', 'auto') } - function plotRadarHeader() { - var header = d3.select('body').insert('header', "#radar"); + function plotRadarHeader () { + var header = d3.select('body').insert('header', '#radar') header.append('div') .attr('class', 'radar-title') .append('div') @@ -409,183 +405,177 @@ const Radar = function (size, radar) { .append('h1') .text(document.title) .style('cursor', 'pointer') - .on('click', redrawFullRadar); + .on('click', redrawFullRadar) header.select('.radar-title') .append('div') .attr('class', 'radar-title__logo') - .html(' '); + .html(' ') - return header; + return header } - function plotQuadrantButtons(quadrants, header) { - - function addButton(quadrant) { + function plotQuadrantButtons (quadrants, header) { + function addButton (quadrant) { radarElement .append('div') - .attr('class', 'quadrant-table ' + quadrant.order); - + .attr('class', 'quadrant-table ' + quadrant.order) header.append('div') .attr('class', 'button ' + quadrant.order + ' full-view') .text(quadrant.quadrant.name()) .on('mouseover', mouseoverQuadrant.bind({}, quadrant.order)) .on('mouseout', mouseoutQuadrant.bind({}, quadrant.order)) - .on('click', selectQuadrant.bind({}, quadrant.order, quadrant.startAngle)); + .on('click', selectQuadrant.bind({}, quadrant.order, quadrant.startAngle)) } _.each([0, 1, 2, 3], function (i) { - addButton(quadrants[i]); - }); - + addButton(quadrants[i]) + }) header.append('div') .classed('print-radar button no-capitalize', true) .text('Print this radar') - .on('click', window.print.bind(window)); + .on('click', window.print.bind(window)) } - function plotRadarFooter() { + function plotRadarFooter () { d3.select('body') .insert('div', '#radar-plot + *') .attr('id', 'footer') .append('div') .attr('class', 'footer-content') .append('p') - .html('Powered by ThoughtWorks. ' - + 'By using this service you agree to ThoughtWorks\' terms of use. ' - + 'You also agree to our privacy policy, which describes how we will gather, use and protect any personal data contained in your public Google Sheet. ' - + 'This software is open source and available for download and self-hosting.'); + .html('Powered by ThoughtWorks. ' + + 'By using this service you agree to ThoughtWorks\' terms of use. ' + + 'You also agree to our privacy policy, which describes how we will gather, use and protect any personal data contained in your public Google Sheet. ' + + 'This software is open source and available for download and self-hosting.') } - function mouseoverQuadrant(order) { - d3.select('.quadrant-group-' + order).style('opacity', 1); - d3.selectAll('.quadrant-group:not(.quadrant-group-' + order + ')').style('opacity', 0.3); + function mouseoverQuadrant (order) { + d3.select('.quadrant-group-' + order).style('opacity', 1) + d3.selectAll('.quadrant-group:not(.quadrant-group-' + order + ')').style('opacity', 0.3) } - function mouseoutQuadrant(order) { - d3.selectAll('.quadrant-group:not(.quadrant-group-' + order + ')').style('opacity', 1); + function mouseoutQuadrant (order) { + d3.selectAll('.quadrant-group:not(.quadrant-group-' + order + ')').style('opacity', 1) } - function selectQuadrant(order, startAngle) { - d3.selectAll('.home-link').classed('selected', false); - createHomeLink(d3.select('header')); + function selectQuadrant (order, startAngle) { + d3.selectAll('.home-link').classed('selected', false) + createHomeLink(d3.select('header')) - d3.selectAll('.button').classed('selected', false).classed('full-view', false); - d3.selectAll('.button.' + order).classed('selected', true); - d3.selectAll('.quadrant-table').classed('selected', false); - d3.selectAll('.quadrant-table.' + order).classed('selected', true); - d3.selectAll('.blip-item-description').classed('expanded', false); + d3.selectAll('.button').classed('selected', false).classed('full-view', false) + d3.selectAll('.button.' + order).classed('selected', true) + d3.selectAll('.quadrant-table').classed('selected', false) + d3.selectAll('.quadrant-table.' + order).classed('selected', true) + d3.selectAll('.blip-item-description').classed('expanded', false) - var scale = 2; + var scale = 2 - var adjustX = Math.sin(toRadian(startAngle)) - Math.cos(toRadian(startAngle)); - var adjustY = Math.cos(toRadian(startAngle)) + Math.sin(toRadian(startAngle)); + var adjustX = Math.sin(toRadian(startAngle)) - Math.cos(toRadian(startAngle)) + var adjustY = Math.cos(toRadian(startAngle)) + Math.sin(toRadian(startAngle)) - var translateX = (-1 * (1 + adjustX) * size / 2 * (scale - 1)) + (-adjustX * (1 - scale / 2) * size); - var translateY = (-1 * (1 - adjustY) * (size / 2 - 7) * (scale - 1)) - ((1 - adjustY) / 2 * (1 - scale / 2) * size); + var translateX = (-1 * (1 + adjustX) * size / 2 * (scale - 1)) + (-adjustX * (1 - scale / 2) * size) + var translateY = (-1 * (1 - adjustY) * (size / 2 - 7) * (scale - 1)) - ((1 - adjustY) / 2 * (1 - scale / 2) * size) - var translateXAll = (1 - adjustX) / 2 * size * scale / 2 + ((1 - adjustX) / 2 * (1 - scale / 2) * size); - var translateYAll = (1 + adjustY) / 2 * size * scale / 2; + var translateXAll = (1 - adjustX) / 2 * size * scale / 2 + ((1 - adjustX) / 2 * (1 - scale / 2) * size) + var translateYAll = (1 + adjustY) / 2 * size * scale / 2 - var moveRight = (1 + adjustX) * (0.8 * window.innerWidth - size) / 2; - var moveLeft = (1 - adjustX) * (0.8 * window.innerWidth - size) / 2; + var moveRight = (1 + adjustX) * (0.8 * window.innerWidth - size) / 2 + var moveLeft = (1 - adjustX) * (0.8 * window.innerWidth - size) / 2 - var blipScale = 3 / 4; - var blipTranslate = (1 - blipScale) / blipScale; + var blipScale = 3 / 4 + var blipTranslate = (1 - blipScale) / blipScale - svg.style('left', moveLeft + 'px').style('right', moveRight + 'px'); + svg.style('left', moveLeft + 'px').style('right', moveRight + 'px') d3.select('.quadrant-group-' + order) .transition() .duration(1000) - .attr('transform', 'translate(' + translateX + ',' + translateY + ')scale(' + scale + ')'); + .attr('transform', 'translate(' + translateX + ',' + translateY + ')scale(' + scale + ')') d3.selectAll('.quadrant-group-' + order + ' .blip-link text').each(function () { - var x = d3.select(this).attr('x'); - var y = d3.select(this).attr('y'); + var x = d3.select(this).attr('x') + var y = d3.select(this).attr('y') d3.select(this.parentNode) .transition() .duration(1000) - .attr('transform', 'scale(' + blipScale + ')translate(' + blipTranslate * x + ',' + blipTranslate * y + ')'); - }); + .attr('transform', 'scale(' + blipScale + ')translate(' + blipTranslate * x + ',' + blipTranslate * y + ')') + }) d3.selectAll('.quadrant-group') - .style('pointer-events', 'auto'); + .style('pointer-events', 'auto') d3.selectAll('.quadrant-group:not(.quadrant-group-' + order + ')') .transition() .duration(1000) .style('pointer-events', 'none') - .attr('transform', 'translate(' + translateXAll + ',' + translateYAll + ')scale(0)'); + .attr('transform', 'translate(' + translateXAll + ',' + translateYAll + ')scale(0)') - - - if (d3.select('.legend.legend-' + order).empty()){ - drawLegend(order); + if (d3.select('.legend.legend-' + order).empty()) { + drawLegend(order) } } self.init = function () { - radarElement = d3.select('body').append('div').attr('id', 'radar'); - return self; - }; - - function constructSheetUrl(sheet_name) { - var noParamUrl = window.location.href.substring(0, window.location.href.indexOf(window.location.search)); - var queryParams = QueryParams(window.location.search.substring(1)); - var sheetUrl = noParamUrl + '?sheetId=' + queryParams.sheetId + '&sheetName=' + encodeURIComponent(sheet_name); - return sheetUrl + radarElement = d3.select('body').append('div').attr('id', 'radar') + return self } - function plotAlternativeRadars(alternatives, currentSheet) { - var alternativeDiv = d3.select('body') - .insert('div', '#radar') - .attr('id', 'alternative-buttons'); - - alternativeDiv.append('p').text('Chose a sheet to populate radar'); - alternatives.forEach(function (alternative) { - alternativeDiv - .append('div:a') - .attr('class', 'first full-view alternative') - .attr('href', constructSheetUrl(alternative)) - .text(alternative); - - if (alternative === currentSheet) { - - d3.selectAll('.alternative').filter(function () { - return d3.select(this).text() === alternative - }).attr('class', 'highlight'); - } - }); + function constructSheetUrl (sheetName) { + var noParamUrl = window.location.href.substring(0, window.location.href.indexOf(window.location.search)) + var queryParams = QueryParams(window.location.search.substring(1)) + var sheetUrl = noParamUrl + '?sheetId=' + queryParams.sheetId + '&sheetName=' + encodeURIComponent(sheetName) + return sheetUrl + } + + function plotAlternativeRadars (alternatives, currentSheet) { + var alternativeDiv = d3.select('body') + .insert('div', '#radar') + .attr('id', 'alternative-buttons') + + alternativeDiv.append('p').text('Chose a sheet to populate radar') + alternatives.forEach(function (alternative) { + alternativeDiv + .append('div:a') + .attr('class', 'first full-view alternative') + .attr('href', constructSheetUrl(alternative)) + .text(alternative) + + if (alternative === currentSheet) { + d3.selectAll('.alternative').filter(function () { + return d3.select(this).text() === alternative + }).attr('class', 'highlight') + } + }) } self.plot = function () { - var rings, quadrants, alternatives, currentSheet; + var rings, quadrants, alternatives, currentSheet - rings = radar.rings(); - quadrants = radar.quadrants(); - alternatives = radar.getAlternatives(); - currentSheet = radar.getCurrentSheet(); - var header = plotRadarHeader(); + rings = radar.rings() + quadrants = radar.quadrants() + alternatives = radar.getAlternatives() + currentSheet = radar.getCurrentSheet() + var header = plotRadarHeader() - plotQuadrantButtons(quadrants, header); + plotQuadrantButtons(quadrants, header) - radarElement.style('height', size + 14 + 'px'); - svg = radarElement.append("svg").call(tip); - svg.attr('id', 'radar-plot').attr('width', size).attr('height', size + 14); + radarElement.style('height', size + 14 + 'px') + svg = radarElement.append('svg').call(tip) + svg.attr('id', 'radar-plot').attr('width', size).attr('height', size + 14) _.each(quadrants, function (quadrant) { - var quadrantGroup = plotQuadrant(rings, quadrant); - plotLines(quadrantGroup, quadrant); - plotTexts(quadrantGroup, rings, quadrant); - plotBlips(quadrantGroup, rings, quadrant); - }); - - plotAlternativeRadars(alternatives, currentSheet); - plotRadarFooter(); - }; + var quadrantGroup = plotQuadrant(rings, quadrant) + plotLines(quadrantGroup, quadrant) + plotTexts(quadrantGroup, rings, quadrant) + plotBlips(quadrantGroup, rings, quadrant) + }) + + plotAlternativeRadars(alternatives, currentSheet) + plotRadarFooter() + } - return self; -}; + return self +} -module.exports = Radar; +module.exports = Radar diff --git a/src/models/blip.js b/src/models/blip.js index 26143e1fe..c6d3ad1c0 100644 --- a/src/models/blip.js +++ b/src/models/blip.js @@ -1,41 +1,41 @@ -const IDEAL_BLIP_WIDTH = 22; +const IDEAL_BLIP_WIDTH = 22 const Blip = function (name, ring, isNew, topic, description) { - var self, number; + var self, number - self = {}; - number = -1; + self = {} + number = -1 - self.width = IDEAL_BLIP_WIDTH; + self.width = IDEAL_BLIP_WIDTH self.name = function () { - return name; - }; + return name + } self.topic = function () { - return topic || ''; - }; + return topic || '' + } self.description = function () { - return description || ''; - }; + return description || '' + } self.isNew = function () { - return isNew; - }; + return isNew + } self.ring = function () { - return ring; - }; + return ring + } self.number = function () { - return number; - }; + return number + } self.setNumber = function (newNumber) { - number = newNumber; - }; + number = newNumber + } - return self; -}; + return self +} -module.exports = Blip; +module.exports = Blip diff --git a/src/models/quadrant.js b/src/models/quadrant.js index 1739bc17a..0112097b9 100644 --- a/src/models/quadrant.js +++ b/src/models/quadrant.js @@ -1,26 +1,26 @@ const Quadrant = function (name) { - var self, blips; + var self, blips - self = {}; - blips = []; + self = {} + blips = [] self.name = function () { - return name; - }; + return name + } self.add = function (newBlips) { if (Array.isArray(newBlips)) { - blips = blips.concat(newBlips); + blips = blips.concat(newBlips) } else { - blips.push(newBlips); + blips.push(newBlips) } - }; + } self.blips = function () { - return blips.slice(0); - }; + return blips.slice(0) + } - return self; -}; + return self +} -module.exports = Quadrant; \ No newline at end of file +module.exports = Quadrant diff --git a/src/models/radar.js b/src/models/radar.js index 11ccc218e..351fba121 100644 --- a/src/models/radar.js +++ b/src/models/radar.js @@ -1,86 +1,85 @@ -const MalformedDataError = require('../exceptions/malformedDataError'); -const ExceptionMessages = require('../util/exceptionMessages'); +const MalformedDataError = require('../exceptions/malformedDataError') +const ExceptionMessages = require('../util/exceptionMessages') const _ = { map: require('lodash/map'), uniqBy: require('lodash/uniqBy'), sortBy: require('lodash/sortBy') -}; +} -const Radar = function() { - var self, quadrants, blipNumber, addingQuadrant; +const Radar = function () { + var self, quadrants, blipNumber, addingQuadrant, alternatives, currentSheetName - blipNumber = 0; - addingQuadrant = 0; + blipNumber = 0 + addingQuadrant = 0 quadrants = [ - {order: 'first', startAngle: 90}, - {order: 'second', startAngle: 0}, - {order: 'third', startAngle: -90}, - {order: 'fourth', startAngle: -180} - ]; - alternatives = []; - currentSheetName = ""; - self = {}; - - function setNumbers(blips) { + { order: 'first', startAngle: 90 }, + { order: 'second', startAngle: 0 }, + { order: 'third', startAngle: -90 }, + { order: 'fourth', startAngle: -180 } + ] + alternatives = [] + currentSheetName = '' + self = {} + + function setNumbers (blips) { blips.forEach(function (blip) { - blip.setNumber(++blipNumber); - }); + blip.setNumber(++blipNumber) + }) } self.addAlternative = function (sheetName) { - alternatives.push(sheetName); + alternatives.push(sheetName) } self.getAlternatives = function () { - return alternatives; + return alternatives } self.setCurrentSheet = function (sheetName) { - currentSheetName = sheetName; + currentSheetName = sheetName } self.getCurrentSheet = function () { - return currentSheetName; + return currentSheetName } self.addQuadrant = function (quadrant) { - if(addingQuadrant >= 4) { - throw new MalformedDataError(ExceptionMessages.TOO_MANY_QUADRANTS); + if (addingQuadrant >= 4) { + throw new MalformedDataError(ExceptionMessages.TOO_MANY_QUADRANTS) } - quadrants[addingQuadrant].quadrant = quadrant; - setNumbers(quadrant.blips()); - addingQuadrant++; - }; + quadrants[addingQuadrant].quadrant = quadrant + setNumbers(quadrant.blips()) + addingQuadrant++ + } - function allQuadrants() { - if (addingQuadrant < 4) - throw new MalformedDataError(ExceptionMessages.LESS_THAN_FOUR_QUADRANTS); + function allQuadrants () { + if (addingQuadrant < 4) { throw new MalformedDataError(ExceptionMessages.LESS_THAN_FOUR_QUADRANTS) } - return _.map(quadrants, 'quadrant'); + return _.map(quadrants, 'quadrant') } - function allBlips() { + function allBlips () { return allQuadrants().reduce(function (blips, quadrant) { - return blips.concat(quadrant.blips()); - }, []); + return blips.concat(quadrant.blips()) + }, []) } self.rings = function () { return _.sortBy(_.map(_.uniqBy(allBlips(), function (blip) { - return blip.ring().name(); + return blip.ring().name() }), function (blip) { - return blip.ring(); + return blip.ring() }), function (ring) { - return ring.order(); - }); - }; + return ring.order() + }) + } self.quadrants = function () { - return quadrants; - }; + return quadrants + } - return self; -}; + return self +} -module.exports = Radar; +module.exports = Radar diff --git a/src/models/ring.js b/src/models/ring.js index 29d61ec22..b463d3469 100644 --- a/src/models/ring.js +++ b/src/models/ring.js @@ -1,15 +1,15 @@ const Ring = function (name, order) { - var self = {}; + var self = {} self.name = function () { - return name; - }; + return name + } self.order = function () { - return order; - }; + return order + } - return self; -}; + return self +} -module.exports = Ring; \ No newline at end of file +module.exports = Ring diff --git a/src/site.js b/src/site.js index 24e5b7a32..bcc4333cc 100644 --- a/src/site.js +++ b/src/site.js @@ -1,7 +1,7 @@ -require('./common'); -require('./images/logo.png'); -require('./images/radar_legend.png'); +require('./common') +require('./images/logo.png') +require('./images/radar_legend.png') -const GoogleSheetInput = require('./util/factory'); +const GoogleSheetInput = require('./util/factory') -GoogleSheetInput().build(); \ No newline at end of file +GoogleSheetInput().build() diff --git a/src/util/contentValidator.js b/src/util/contentValidator.js index 9093e23fe..c6e6cf87c 100644 --- a/src/util/contentValidator.js +++ b/src/util/contentValidator.js @@ -3,33 +3,32 @@ const _ = { uniqBy: require('lodash/uniqBy'), capitalize: require('lodash/capitalize'), each: require('lodash/each') -}; - -const MalformedDataError = require('../../src/exceptions/malformedDataError'); -const ExceptionMessages = require('./exceptionMessages'); +} +const MalformedDataError = require('../../src/exceptions/malformedDataError') +const ExceptionMessages = require('./exceptionMessages') const ContentValidator = function (columnNames) { - var self = {}; - columnNames = columnNames.map(function(columnName) { - return columnName.trim(); - }); + var self = {} + columnNames = columnNames.map(function (columnName) { + return columnName.trim() + }) - self.verifyContent = function() { - if(columnNames.length == 0){ - throw new MalformedDataError(ExceptionMessages.MISSING_CONTENT); + self.verifyContent = function () { + if (columnNames.length === 0) { + throw new MalformedDataError(ExceptionMessages.MISSING_CONTENT) } - }; + } - self.verifyHeaders = function() { + self.verifyHeaders = function () { _.each(['name', 'ring', 'quadrant', 'isNew', 'description'], function (field) { - if (columnNames.indexOf(field) == -1) { - throw new MalformedDataError(ExceptionMessages.MISSING_HEADERS); + if (columnNames.indexOf(field) === -1) { + throw new MalformedDataError(ExceptionMessages.MISSING_HEADERS) } - }); - }; + }) + } - return self; -}; + return self +} -module.exports = ContentValidator; +module.exports = ContentValidator diff --git a/src/util/exceptionMessages.js b/src/util/exceptionMessages.js index e1adc2c96..8727b1bab 100644 --- a/src/util/exceptionMessages.js +++ b/src/util/exceptionMessages.js @@ -4,8 +4,8 @@ const ExceptionMessages = { MISSING_HEADERS: 'Document is missing one or more required headers or they are misspelled. ' + 'Check that your document contains headers for "name", "ring", "quadrant", "isNew", "description".', MISSING_CONTENT: 'Document is missing content.', - LESS_THAN_FOUR_QUADRANTS : 'There are less than 4 quadrant names listed in your data. Check the quadrant column for errors.', + LESS_THAN_FOUR_QUADRANTS: 'There are less than 4 quadrant names listed in your data. Check the quadrant column for errors.', SHEET_NOT_FOUND: 'Oops! We can’t find the Google Sheet you’ve entered. Can you check the URL?' -}; +} -module.exports = ExceptionMessages; \ No newline at end of file +module.exports = ExceptionMessages diff --git a/src/util/factory.js b/src/util/factory.js index 38655c7ac..0824ef6e2 100644 --- a/src/util/factory.js +++ b/src/util/factory.js @@ -1,297 +1,290 @@ -const d3 = require('d3'); -const Tabletop = require('tabletop'); +/* eslint no-constant-condition: "off" */ + +const d3 = require('d3') +const Tabletop = require('tabletop') const _ = { - map: require('lodash/map'), - uniqBy: require('lodash/uniqBy'), - capitalize: require('lodash/capitalize'), - each: require('lodash/each') -}; - -const InputSanitizer = require('./inputSanitizer'); -const Radar = require('../models/radar'); -const Quadrant = require('../models/quadrant'); -const Ring = require('../models/ring'); -const Blip = require('../models/blip'); -const GraphingRadar = require('../graphing/radar'); -const QueryParams = require('./queryParamProcessor'); -const MalformedDataError = require('../exceptions/malformedDataError'); -const SheetNotFoundError = require('../exceptions/sheetNotFoundError'); -const ContentValidator = require('./contentValidator'); -const Sheet = require('./sheet'); -const ExceptionMessages = require('./exceptionMessages'); + map: require('lodash/map'), + uniqBy: require('lodash/uniqBy'), + capitalize: require('lodash/capitalize'), + each: require('lodash/each') +} -const plotRadar = function (title, blips, currentRadarName, alternativeRadars) { - document.title = title; - d3.selectAll(".loading").remove(); +const InputSanitizer = require('./inputSanitizer') +const Radar = require('../models/radar') +const Quadrant = require('../models/quadrant') +const Ring = require('../models/ring') +const Blip = require('../models/blip') +const GraphingRadar = require('../graphing/radar') +const QueryParams = require('./queryParamProcessor') +const MalformedDataError = require('../exceptions/malformedDataError') +const SheetNotFoundError = require('../exceptions/sheetNotFoundError') +const ContentValidator = require('./contentValidator') +const Sheet = require('./sheet') +const ExceptionMessages = require('./exceptionMessages') - var rings = _.map(_.uniqBy(blips, 'ring'), 'ring'); - var ringMap = {}; - var maxRings = 4; +const plotRadar = function (title, blips, currentRadarName, alternativeRadars) { + document.title = title + d3.selectAll('.loading').remove() - _.each(rings, function (ringName, i) { - if (i == maxRings) { - throw new MalformedDataError(ExceptionMessages.TOO_MANY_RINGS); - } - ringMap[ringName] = new Ring(ringName, i); - }); + var rings = _.map(_.uniqBy(blips, 'ring'), 'ring') + var ringMap = {} + var maxRings = 4 - var quadrants = {}; - _.each(blips, function (blip) { - if (!quadrants[blip.quadrant]) { - quadrants[blip.quadrant] = new Quadrant(_.capitalize(blip.quadrant)); - } - quadrants[blip.quadrant].add(new Blip(blip.name, ringMap[blip.ring], blip.isNew.toLowerCase() === 'true', blip.topic, blip.description)) - }); - - var radar = new Radar(); - _.each(quadrants, function (quadrant) { - radar.addQuadrant(quadrant) - }); - - if(alternativeRadars != undefined || true) { - alternativeRadars.forEach(function(sheetName) { - radar.addAlternative(sheetName); - }); + _.each(rings, function (ringName, i) { + if (i === maxRings) { + throw new MalformedDataError(ExceptionMessages.TOO_MANY_RINGS) } - - if(currentRadarName != undefined || true) { - radar.setCurrentSheet(currentRadarName); + ringMap[ringName] = new Ring(ringName, i) + }) + + var quadrants = {} + _.each(blips, function (blip) { + if (!quadrants[blip.quadrant]) { + quadrants[blip.quadrant] = new Quadrant(_.capitalize(blip.quadrant)) } + quadrants[blip.quadrant].add(new Blip(blip.name, ringMap[blip.ring], blip.isNew.toLowerCase() === 'true', blip.topic, blip.description)) + }) + + var radar = new Radar() + _.each(quadrants, function (quadrant) { + radar.addQuadrant(quadrant) + }) + + if (alternativeRadars !== undefined || true) { + alternativeRadars.forEach(function (sheetName) { + radar.addAlternative(sheetName) + }) + } - var size = (window.innerHeight - 133) < 620 ? 620 : window.innerHeight - 133; + if (currentRadarName !== undefined || true) { + radar.setCurrentSheet(currentRadarName) + } - new GraphingRadar(size, radar).init().plot(); + var size = (window.innerHeight - 133) < 620 ? 620 : window.innerHeight - 133 + + new GraphingRadar(size, radar).init().plot() } const GoogleSheet = function (sheetReference, sheetName) { - var self = {}; - - self.build = function () { - var sheet = new Sheet(sheetReference); - sheet.exists(function(notFound) { - if (notFound) { - plotErrorMessage(notFound); - return; - } - - Tabletop.init({ - key: sheet.id, - callback: createBlips - }); - }); - - function createBlips(__, tabletop) { - - try { - - if (!sheetName) { - sheetName = tabletop.foundSheetNames[0]; - } - var columnNames = tabletop.sheets(sheetName).columnNames; - - var contentValidator = new ContentValidator(columnNames); - contentValidator.verifyContent(); - contentValidator.verifyHeaders(); - - var all = tabletop.sheets(sheetName).all(); - var blips = _.map(all, new InputSanitizer().sanitize); - - plotRadar(tabletop.googleSheetName + ' - ' + sheetName, blips, sheetName, tabletop.foundSheetNames); - } catch (exception) { - plotErrorMessage(exception); - } + var self = {} + + self.build = function () { + var sheet = new Sheet(sheetReference) + sheet.exists(function (notFound) { + if (notFound) { + plotErrorMessage(notFound) + return + } + + Tabletop.init({ + key: sheet.id, + callback: createBlips + }) + }) + + function createBlips (__, tabletop) { + try { + if (!sheetName) { + sheetName = tabletop.foundSheetNames[0] } - }; - - self.init = function () { - plotLoading(); - return self; - }; + var columnNames = tabletop.sheets(sheetName).columnNames - return self; -}; + var contentValidator = new ContentValidator(columnNames) + contentValidator.verifyContent() + contentValidator.verifyHeaders() -const CSVDocument = function (url) { - var self = {}; + var all = tabletop.sheets(sheetName).all() + var blips = _.map(all, new InputSanitizer().sanitize) - self.build = function () { - d3.csv(url, createBlips); + plotRadar(tabletop.googleSheetName + ' - ' + sheetName, blips, sheetName, tabletop.foundSheetNames) + } catch (exception) { + plotErrorMessage(exception) + } } + } - var createBlips = function (data) { - try { - var columnNames = data['columns']; - delete data['columns']; - var contentValidator = new ContentValidator(columnNames); - contentValidator.verifyContent(); - contentValidator.verifyHeaders(); - var blips = _.map(data, new InputSanitizer().sanitize); - plotRadar(FileName(url), blips, "CSV File", []); - } catch (exception) { - plotErrorMessage(exception); - } + self.init = function () { + plotLoading() + return self + } + + return self +} + +const CSVDocument = function (url) { + var self = {} + + self.build = function () { + d3.csv(url, createBlips) + } + + var createBlips = function (data) { + try { + var columnNames = data['columns'] + delete data['columns'] + var contentValidator = new ContentValidator(columnNames) + contentValidator.verifyContent() + contentValidator.verifyHeaders() + var blips = _.map(data, new InputSanitizer().sanitize) + plotRadar(FileName(url), blips, 'CSV File', []) + } catch (exception) { + plotErrorMessage(exception) } + } - self.init = function () { - plotLoading(); - return self; - }; + self.init = function () { + plotLoading() + return self + } - return self; -}; + return self +} const DomainName = function (url) { - var search = /.+:\/\/([^\/]+)/; - var match = search.exec(decodeURIComponent(url.replace(/\+/g, " "))); - return match == null ? null : match[1]; + var search = /.+:\/\/([^\\/]+)/ + var match = search.exec(decodeURIComponent(url.replace(/\+/g, ' '))) + return match == null ? null : match[1] } - const FileName = function (url) { - var search = /([^\/]+)$/; - var match = search.exec(decodeURIComponent(url.replace(/\+/g, " "))); - if (match != null) { - var str = match[1]; - return str; - } - return url; + var search = /([^\\/]+)$/ + var match = search.exec(decodeURIComponent(url.replace(/\+/g, ' '))) + if (match != null) { + var str = match[1] + return str + } + return url } - const GoogleSheetInput = function () { - var self = {}; - - self.build = function () { - var domainName = DomainName(window.location.search.substring(1)); - var queryString = window.location.href.match(/sheetId(.*)/); - var queryParams = queryString ? QueryParams(queryString[0]) : {}; - - if (domainName && queryParams.sheetId.endsWith('csv')) { - var sheet = CSVDocument(queryParams.sheetId); - sheet.init().build(); - } - else if (domainName && domainName.endsWith('google.com') && queryParams.sheetId) { - var sheet = GoogleSheet(queryParams.sheetId, queryParams.sheetName); - console.log(queryParams.sheetName) - - sheet.init().build(); - } else { - var content = d3.select('body') - .append('div') - .attr('class', 'input-sheet'); - set_document_title(); - - plotLogo(content); + var self = {} + var sheet + + self.build = function () { + var domainName = DomainName(window.location.search.substring(1)) + var queryString = window.location.href.match(/sheetId(.*)/) + var queryParams = queryString ? QueryParams(queryString[0]) : {} + + if (domainName && queryParams.sheetId.endsWith('csv')) { + sheet = CSVDocument(queryParams.sheetId) + sheet.init().build() + } else if (domainName && domainName.endsWith('google.com') && queryParams.sheetId) { + sheet = GoogleSheet(queryParams.sheetId, queryParams.sheetName) + console.log(queryParams.sheetName) + + sheet.init().build() + } else { + var content = d3.select('body') + .append('div') + .attr('class', 'input-sheet') + setDocumentTitle() - var bannerText = '

Build your own radar

Once you\'ve created your Radar, you can use this service' + - ' to generate an
interactive version of your Technology Radar. Not sure how? Read this first.

'; + plotLogo(content) - plotBanner(content, bannerText); + var bannerText = '

Build your own radar

Once you\'ve created your Radar, you can use this service' + + ' to generate an
interactive version of your Technology Radar. Not sure how? Read this first.

' - plotForm(content); + plotBanner(content, bannerText) - plotFooter(content); + plotForm(content) - } - }; + plotFooter(content) + } + } - return self; -}; + return self +} -function set_document_title() { - document.title = "Build your own Radar"; +function setDocumentTitle () { + document.title = 'Build your own Radar' } -function plotLoading(content) { - var content = d3.select('body') - .append('div') - .attr('class', 'loading') - .append('div') - .attr('class', 'input-sheet'); +function plotLoading (content) { + content = d3.select('body') + .append('div') + .attr('class', 'loading') + .append('div') + .attr('class', 'input-sheet') - set_document_title(); + setDocumentTitle() - plotLogo(content); + plotLogo(content) - var bannerText = '

Building your radar...

Your Technology Radar will be available in just a few seconds

'; - plotBanner(content, bannerText); - plotFooter(content); + var bannerText = '

Building your radar...

Your Technology Radar will be available in just a few seconds

' + plotBanner(content, bannerText) + plotFooter(content) } -function plotLogo(content) { - content.append('div') - .attr('class', 'input-sheet__logo') - .html(''); +function plotLogo (content) { + content.append('div') + .attr('class', 'input-sheet__logo') + .html('') } -function plotFooter(content) { - content - .append('div') - .attr('id', 'footer') - .append('div') - .attr('class', 'footer-content') - .append('p') - .html('Powered by ThoughtWorks. ' - + 'By using this service you agree to ThoughtWorks\' terms of use. ' - + 'You also agree to our privacy policy, which describes how we will gather, use and protect any personal data contained in your public Google Sheet. ' - + 'This software is open source and available for download and self-hosting.'); - - - +function plotFooter (content) { + content + .append('div') + .attr('id', 'footer') + .append('div') + .attr('class', 'footer-content') + .append('p') + .html('Powered by ThoughtWorks. ' + + 'By using this service you agree to ThoughtWorks\' terms of use. ' + + 'You also agree to our privacy policy, which describes how we will gather, use and protect any personal data contained in your public Google Sheet. ' + + 'This software is open source and available for download and self-hosting.') } -function plotBanner(content, text) { - content.append('div') - .attr('class', 'input-sheet__banner') - .html(text); - +function plotBanner (content, text) { + content.append('div') + .attr('class', 'input-sheet__banner') + .html(text) } -function plotForm(content) { - content.append('div') - .attr('class', 'input-sheet__form') - .append('p') - .html('Enter the URL of your published Google Sheet or CSV file below…'); +function plotForm (content) { + content.append('div') + .attr('class', 'input-sheet__form') + .append('p') + .html('Enter the URL of your published Google Sheet or CSV file below…') - var form = content.select('.input-sheet__form').append('form') - .attr('method', 'get'); + var form = content.select('.input-sheet__form').append('form') + .attr('method', 'get') - form.append('input') - .attr('type', 'text') - .attr('name', 'sheetId') - .attr('placeholder', "e.g. https://docs.google.com/spreadsheets/d/<\sheetid\> or hosted CSV file") - .attr('required',''); + form.append('input') + .attr('type', 'text') + .attr('name', 'sheetId') + .attr('placeholder', 'e.g. https://docs.google.com/spreadsheets/d/ or hosted CSV file') + .attr('required', '') - form.append('button') - .attr('type', 'submit') - .append('a') - .attr('class', 'button') - .text('Build my radar'); + form.append('button') + .attr('type', 'submit') + .append('a') + .attr('class', 'button') + .text('Build my radar') - form.append('p').html("Need help?"); + form.append('p').html("Need help?") } -function plotErrorMessage(exception) { - d3.selectAll(".loading").remove(); - var message = 'Oops! It seems like there are some problems with loading your data. '; - - if (exception instanceof MalformedDataError) { - message = message.concat(exception.message); - } else if (exception instanceof SheetNotFoundError) { - message = exception.message; - } else { - console.error(exception); - } - - message = message.concat('
', 'Please check FAQs for possible solutions.'); - - d3.select('body') - .append('div') - .attr('class', 'error-container') - .append('div') - .attr('class', 'error-container__message') - .append('p') - .html(message); +function plotErrorMessage (exception) { + d3.selectAll('.loading').remove() + var message = 'Oops! It seems like there are some problems with loading your data. ' + + if (exception instanceof MalformedDataError) { + message = message.concat(exception.message) + } else if (exception instanceof SheetNotFoundError) { + message = exception.message + } else { + console.error(exception) + } + + message = message.concat('
', 'Please check FAQs for possible solutions.') + + d3.select('body') + .append('div') + .attr('class', 'error-container') + .append('div') + .attr('class', 'error-container__message') + .append('p') + .html(message) } -module.exports = GoogleSheetInput; +module.exports = GoogleSheetInput diff --git a/src/util/inputSanitizer.js b/src/util/inputSanitizer.js index 28c7ad245..04478008a 100644 --- a/src/util/inputSanitizer.js +++ b/src/util/inputSanitizer.js @@ -1,46 +1,46 @@ -const sanitizeHtml = require('sanitize-html'); +const sanitizeHtml = require('sanitize-html') const _ = { forOwn: require('lodash/forOwn') } const InputSanitizer = function () { - var relaxedOptions = { - allowedTags: ['b', 'i', 'em', 'strong', 'a', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'ul', - 'br', 'p', 'u'], - allowedAttributes: { - 'a': ['href'] - } - }; - - var restrictedOptions = { - allowedTags: [], - allowedAttributes: {}, - textFilter: function(text) { - return text.replace(/&/, '&'); - } - }; + var relaxedOptions = { + allowedTags: ['b', 'i', 'em', 'strong', 'a', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'ul', + 'br', 'p', 'u'], + allowedAttributes: { + 'a': ['href'] + } + } - function trimWhiteSpaces(blip) { - var processedBlip = {}; - _.forOwn(blip, function(value, key) { - processedBlip[key.trim()] = value.trim(); - }); - return processedBlip; + var restrictedOptions = { + allowedTags: [], + allowedAttributes: {}, + textFilter: function (text) { + return text.replace(/&/, '&') } + } - var self = {}; - self.sanitize = function (rawBlip) { - var blip = trimWhiteSpaces(rawBlip); - blip.description = sanitizeHtml(blip.description, relaxedOptions); - blip.name = sanitizeHtml(blip.name, restrictedOptions); - blip.isNew = sanitizeHtml(blip.isNew, restrictedOptions); - blip.ring = sanitizeHtml(blip.ring, restrictedOptions); - blip.quadrant = sanitizeHtml(blip.quadrant, restrictedOptions); + function trimWhiteSpaces (blip) { + var processedBlip = {} + _.forOwn(blip, function (value, key) { + processedBlip[key.trim()] = value.trim() + }) + return processedBlip + } - return blip; - }; + var self = {} + self.sanitize = function (rawBlip) { + var blip = trimWhiteSpaces(rawBlip) + blip.description = sanitizeHtml(blip.description, relaxedOptions) + blip.name = sanitizeHtml(blip.name, restrictedOptions) + blip.isNew = sanitizeHtml(blip.isNew, restrictedOptions) + blip.ring = sanitizeHtml(blip.ring, restrictedOptions) + blip.quadrant = sanitizeHtml(blip.quadrant, restrictedOptions) - return self; -}; + return blip + } + + return self +} -module.exports = InputSanitizer; +module.exports = InputSanitizer diff --git a/src/util/queryParamProcessor.js b/src/util/queryParamProcessor.js index 9f435a5e1..9e910adbf 100644 --- a/src/util/queryParamProcessor.js +++ b/src/util/queryParamProcessor.js @@ -1,16 +1,15 @@ const QueryParams = function (queryString) { - var decode = function (s) { - return decodeURIComponent(s.replace(/\+/g, " ")); - }; + var decode = function (s) { + return decodeURIComponent(s.replace(/\+/g, ' ')) + } - var search = /([^&=]+)=?([^&]*)/g; + var search = /([^&=]+)=?([^&]*)/g - var queryParams = {}; - var match; - while (match = search.exec(queryString)) - queryParams[decode(match[1])] = decode(match[2]); + var queryParams = {} + var match + while ((match = search.exec(queryString))) { queryParams[decode(match[1])] = decode(match[2]) } - return queryParams -}; + return queryParams +} -module.exports = QueryParams; \ No newline at end of file +module.exports = QueryParams diff --git a/src/util/ringCalculator.js b/src/util/ringCalculator.js index 09089e069..5a9872f62 100644 --- a/src/util/ringCalculator.js +++ b/src/util/ringCalculator.js @@ -1,22 +1,22 @@ const RingCalculator = function (numberOfRings, maxRadius) { - var sequence = [0, 6, 5, 3, 2, 1, 1, 1]; + var sequence = [0, 6, 5, 3, 2, 1, 1, 1] - var self = {}; + var self = {} - self.sum = function(length) { + self.sum = function (length) { return sequence.slice(0, length + 1).reduce(function (previous, current) { - return previous + current; - }, 0); - }; + return previous + current + }, 0) + } - self.getRadius = function(ring) { - var total = self.sum(numberOfRings); - var sum = self.sum(ring); + self.getRadius = function (ring) { + var total = self.sum(numberOfRings) + var sum = self.sum(ring) - return maxRadius * sum / total; - }; + return maxRadius * sum / total + } - return self; -}; + return self +} -module.exports = RingCalculator; \ No newline at end of file +module.exports = RingCalculator diff --git a/src/util/sheet.js b/src/util/sheet.js index 2f4b8c53b..294dcca04 100644 --- a/src/util/sheet.js +++ b/src/util/sheet.js @@ -1,33 +1,33 @@ -const SheetNotFoundError = require('../../src/exceptions/sheetNotFoundError'); -const ExceptionMessages = require('./exceptionMessages'); +const SheetNotFoundError = require('../../src/exceptions/sheetNotFoundError') +const ExceptionMessages = require('./exceptionMessages') const Sheet = function (sheetReference) { - var self = {}; + var self = {}; - (function () { - var matches = sheetReference.match("https:\\/\\/docs.google.com\\/spreadsheets\\/d\\/(.*?)($|\\/$|\\/.*|\\?.*)"); - self.id = matches !== null ? matches[1] : sheetReference; - })(); + (function () { + var matches = sheetReference.match('https:\\/\\/docs.google.com\\/spreadsheets\\/d\\/(.*?)($|\\/$|\\/.*|\\?.*)') + self.id = matches !== null ? matches[1] : sheetReference + })() - self.exists = function (callback) { - var feedURL = "https://spreadsheets.google.com/feeds/worksheets/" + self.id + "/public/basic?alt=json"; + self.exists = function (callback) { + var feedURL = 'https://spreadsheets.google.com/feeds/worksheets/' + self.id + '/public/basic?alt=json' - // TODO: Move this out (as HTTPClient) - var xhr = new XMLHttpRequest(); - xhr.open('GET', feedURL, true); - xhr.onreadystatechange = function () { - if (xhr.readyState === 4) { - if (xhr.status === 200) { - return callback(); - } else { - return callback(new SheetNotFoundError(ExceptionMessages.SHEET_NOT_FOUND)); - } - } - }; - xhr.send(null); - }; + // TODO: Move this out (as HTTPClient) + var xhr = new XMLHttpRequest() + xhr.open('GET', feedURL, true) + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + if (xhr.status === 200) { + return callback() + } else { + return callback(new SheetNotFoundError(ExceptionMessages.SHEET_NOT_FOUND)) + } + } + } + xhr.send(null) + } - return self; -}; + return self +} -module.exports = Sheet; +module.exports = Sheet diff --git a/webpack.config.js b/webpack.config.js index 2fd8ae421..56564f81c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,101 +1,101 @@ -'use strict'; +'use strict' -const webpack = require('webpack'); -const path = require('path'); -const buildPath = path.join(__dirname, './dist'); -const args = require('yargs').argv; +const webpack = require('webpack') +const path = require('path') +const buildPath = path.join(__dirname, './dist') +const args = require('yargs').argv -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const postcssPresetEnv = require('postcss-preset-env'); -const cssnano = require('cssnano'); +const HtmlWebpackPlugin = require('html-webpack-plugin') +const MiniCssExtractPlugin = require('mini-css-extract-plugin') +const postcssPresetEnv = require('postcss-preset-env') +const cssnano = require('cssnano') -let isProd = args.prod; -let isDev = args.dev; +let isProd = args.prod +let isDev = args.dev -let main = ['./src/site.js']; -let common = ['./src/common.js']; -let devtool; +let main = ['./src/site.js'] +let common = ['./src/common.js'] +let devtool if (isDev) { - main.push('webpack-dev-server/client?http://0.0.0.0:8080'); - devtool = 'source-map'; + main.push('webpack-dev-server/client?http://0.0.0.0:8080') + devtool = 'source-map' } let plugins = [ - new MiniCssExtractPlugin({filename: '[name].[hash].css'}), - new HtmlWebpackPlugin({ - template: './src/index.html', - chunks: ['main'], - inject: 'body' - }), - new HtmlWebpackPlugin({ - template: './src/error.html', - chunks: ['common'], - inject: 'body', - filename: 'error.html' - }) -]; + new MiniCssExtractPlugin({ filename: '[name].[hash].css' }), + new HtmlWebpackPlugin({ + template: './src/index.html', + chunks: ['main'], + inject: 'body' + }), + new HtmlWebpackPlugin({ + template: './src/error.html', + chunks: ['common'], + inject: 'body', + filename: 'error.html' + }) +] if (isProd) { - plugins.push( - new webpack.NoEmitOnErrorsPlugin() - ); + plugins.push( + new webpack.NoEmitOnErrorsPlugin() + ) } module.exports = { - entry: { - 'main': main, - 'common': common - }, - node: { - fs: 'empty', - net: 'empty', - tls: 'empty', - child_process: 'empty' - }, + entry: { + 'main': main, + 'common': common + }, + node: { + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + }, - output: { - path: buildPath, - publicPath: '/', - filename: '[name].[hash].js' - }, + output: { + path: buildPath, + publicPath: '/', + filename: '[name].[hash].js' + }, - module: { - rules: [ - {test: /\.js$/, exclude: /node_modules/, use: [{loader: 'babel-loader'}]}, - { - test: /\.scss$/, - exclude: /node_modules/, - use: ['style-loader', MiniCssExtractPlugin.loader, { - loader: 'css-loader', - options: {importLoaders: 1} - }, { - loader: 'postcss-loader', options: { - ident: 'postcss', - plugins: () => [ - postcssPresetEnv({browsers: 'last 2 versions'}), - cssnano({preset: ['default', {discardComments: {removeAll: true}}]}) - ] - } - }, 'sass-loader'], - }, - { - test: /\.(png|jpg|ico)$/, - exclude: /node_modules/, - use: [{loader: 'file-loader?name=images/[name].[ext]&context=./src/images'}] - } - ] - }, + module: { + rules: [ + { test: /\.js$/, exclude: /node_modules/, use: [{ loader: 'babel-loader' }] }, + { + test: /\.scss$/, + exclude: /node_modules/, + use: ['style-loader', MiniCssExtractPlugin.loader, { + loader: 'css-loader', + options: { importLoaders: 1 } + }, { + loader: 'postcss-loader', + options: { + ident: 'postcss', + plugins: () => [ + postcssPresetEnv({ browsers: 'last 2 versions' }), + cssnano({ preset: ['default', { discardComments: { removeAll: true } }] }) + ] + } + }, 'sass-loader'] + }, + { + test: /\.(png|jpg|ico)$/, + exclude: /node_modules/, + use: [{ loader: 'file-loader?name=images/[name].[ext]&context=./src/images' }] + } + ] + }, - plugins: plugins, + plugins: plugins, - devtool: devtool, - - devServer: { - contentBase: buildPath, - host: '0.0.0.0', - port: 8080 - } -}; + devtool: devtool, + devServer: { + contentBase: buildPath, + host: '0.0.0.0', + port: 8080 + } +}