diff --git a/package-lock.json b/package-lock.json index b858d5c..c85eaae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -935,22 +935,16 @@ } } }, - "@types/node": { - "version": "8.0.53", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.53.tgz", - "integrity": "sha512-54Dm6NwYeiSQmRB1BLXKr5GELi0wFapR1npi8bnZhEcu84d/yQKqnwwXQ56hZ0RUbTG6L5nqDZaN3dgByQXQRQ==", - "dev": true - }, "abab": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", - "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", + "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==", "dev": true }, "acorn": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", - "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", "dev": true }, "acorn-globals": { @@ -2286,12 +2280,6 @@ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true }, - "content-type-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", - "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==", - "dev": true - }, "convert-source-map": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", @@ -2343,9 +2331,9 @@ "dev": true }, "cssstyle": { - "version": "0.2.37", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", - "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.1.1.tgz", + "integrity": "sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==", "dev": true, "requires": { "cssom": "0.3.x" @@ -2357,58 +2345,11 @@ "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=", "dev": true }, - "d3-color": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.0.3.tgz", - "integrity": "sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=", - "dev": true - }, - "d3-dispatch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.3.tgz", - "integrity": "sha1-RuFJHqqbWMNY/OW+TovtYm54cfg=", - "dev": true - }, - "d3-ease": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.3.tgz", - "integrity": "sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=", - "dev": true - }, - "d3-interpolate": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.1.5.tgz", - "integrity": "sha1-aeCZ/zkhRxblY8muw+qdHqS4p58=", - "dev": true, - "requires": { - "d3-color": "1" - } - }, "d3-selection": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.1.0.tgz", "integrity": "sha1-GZhoSJZIj4OcoDchI9o08dMYgJw=" }, - "d3-timer": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.7.tgz", - "integrity": "sha512-vMZXR88XujmG/L5oB96NNKH5lCWwiLM/S2HyyAQLcjWJCloK5shxta4CwOFYLZoY3AWX73v8Lgv4cCAdWtRmOA==", - "dev": true - }, - "d3-transition": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.0.tgz", - "integrity": "sha1-z8hcdOUjkyQpBUZiNXKZBWDDlm8=", - "dev": true, - "requires": { - "d3-color": "1", - "d3-dispatch": "1", - "d3-ease": "1", - "d3-interpolate": "1", - "d3-selection": "^1.1.0", - "d3-timer": "1" - } - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -2647,10 +2588,13 @@ } }, "domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.0.tgz", - "integrity": "sha512-WpwuBlZ2lQRFa4H/4w49deb9rJLot9KmqrKKjMc9qBl7CID+DdC2swoa34ccRl+anL2B6bLp6TjFdIdnzekMBQ==", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } }, "ecc-jsbn": { "version": "0.1.1", @@ -2707,16 +2651,25 @@ "dev": true }, "escodegen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", - "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", + "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", "dev": true, "requires": { "esprima": "^3.1.3", "estraverse": "^4.2.0", "esutils": "^2.0.2", "optionator": "^0.8.1", - "source-map": "~0.5.6" + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } } }, "eslint": { @@ -4204,6 +4157,12 @@ "sshpk": "^1.7.0" } }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, "ignore": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", @@ -5434,6 +5393,15 @@ "webidl-conversions": "^4.0.2" } }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", @@ -6322,46 +6290,49 @@ "optional": true }, "jsdom": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.4.0.tgz", - "integrity": "sha512-BTp3qjJlrnzcZGl8XdGnR+jEXvNjzUmixf2hBhf6Ky05qbtLmF/xGTCCT6QK9ugrYdlBURWO8GlkKY65TpOLfw==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", "dev": true, "requires": { - "abab": "^1.0.3", - "acorn": "^5.1.2", - "acorn-globals": "^4.0.0", + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", "array-equal": "^1.0.0", - "browser-process-hrtime": "^0.1.2", - "content-type-parser": "^1.0.1", "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": ">= 0.2.37 < 0.3.0", - "domexception": "^1.0.0", - "escodegen": "^1.9.0", - "html-encoding-sniffer": "^1.0.1", - "nwmatcher": "^1.4.3", - "parse5": "^3.0.2", - "pn": "^1.0.0", - "request": "^2.83.0", - "request-promise-native": "^1.0.3", - "sax": "^1.2.1", - "symbol-tree": "^3.2.1", - "tough-cookie": "^2.3.3", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.1", - "whatwg-url": "^6.3.0", - "xml-name-validator": "^2.0.1" + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" }, "dependencies": { "ajv": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.4.0.tgz", - "integrity": "sha1-MtHPCNvIDEMvQm8S4QslEfa0ZHQ=", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz", + "integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", + "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "assert-plus": { @@ -6376,43 +6347,41 @@ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "dev": true, - "requires": { - "hoek": "4.x.x" - } + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "dev": true, "requires": { - "boom": "5.x.x" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "dev": true, - "requires": { - "hoek": "4.x.x" - } - } + "delayed-stream": "~1.0.0" } }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, @@ -6423,33 +6392,15 @@ "dev": true }, "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "dev": true, "requires": { - "ajv": "^5.1.0", + "ajv": "^6.5.5", "har-schema": "^2.0.0" } }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "dev": true, - "requires": { - "boom": "4.x.x", - "cryptiles": "3.x.x", - "hoek": "4.x.x", - "sntp": "2.x.x" - } - }, - "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", - "dev": true - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -6461,21 +6412,33 @@ "sshpk": "^1.7.0" } }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", "dev": true }, "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "dev": true, "requires": { - "mime-db": "~1.30.0" + "mime-db": "~1.37.0" } }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -6483,70 +6446,89 @@ "dev": true }, "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "request": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "dev": true, "requires": { "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", + "aws4": "^1.8.0", "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "hawk": "~6.0.2", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "stringstream": "~0.0.5", - "tough-cookie": "~2.3.3", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" + "uuid": "^3.3.2" + }, + "dependencies": { + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } } }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", - "dev": true, - "requires": { - "hoek": "4.x.x" - } - }, "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "punycode": "^1.4.1" + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } } }, "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "dev": true + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } } } }, @@ -7087,12 +7069,6 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, - "nwmatcher": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", - "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==", - "dev": true - }, "nwsapi": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.9.tgz", @@ -7309,13 +7285,10 @@ } }, "parse5": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", - "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", - "dev": true, - "requires": { - "@types/node": "*" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true }, "pascalcase": { "version": "0.1.1", @@ -7428,9 +7401,9 @@ "dev": true }, "pn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.0.0.tgz", - "integrity": "sha1-HPWjCw2AbNGPiPxBprXUrWFbO6k=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", "dev": true }, "posix-character-classes": { @@ -7817,9 +7790,9 @@ }, "dependencies": { "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "dev": true, "requires": { "punycode": "^1.4.1" @@ -7956,28 +7929,29 @@ } }, "rollup-plugin-babel": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.0.0-beta.0.tgz", - "integrity": "sha512-tmGAZQO4L015R7STTvUr7f/5Y47GZipQ8WKOkTgwod0K5BfugkpuGTfw7N+wyvYrXMiNTXM4zb5nvAgkIgYq6g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.1.0.tgz", + "integrity": "sha512-4IYv/yTNyH4P/Cma1mWdqy42gc051i1mTe/6oe8F055WzJGSb2qs1mSDwZTo93wA6kMBgHBIR/OcBk7JMnL59Q==", "dev": true, "requires": { - "rollup-pluginutils": "^1.5.0" + "@babel/helper-module-imports": "^7.0.0", + "rollup-pluginutils": "^2.3.0" }, "dependencies": { "estree-walker": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz", - "integrity": "sha1-va/oCVOD2EFNXcLs9MkXO225QS4=", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.2.tgz", + "integrity": "sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==", "dev": true }, "rollup-pluginutils": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz", - "integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.3.3.tgz", + "integrity": "sha512-2XZwja7b6P5q4RZ5FhyX1+f46xi1Z3qBKigLRZ6VTZjwbN0K1IFGMlwm06Uu0Emcre2Z63l77nq/pzn+KxIEoA==", "dev": true, "requires": { - "estree-walker": "^0.2.1", - "minimatch": "^3.0.2" + "estree-walker": "^0.5.2", + "micromatch": "^2.3.11" } } } @@ -9370,14 +9344,6 @@ "dev": true, "requires": { "iconv-lite": "0.4.19" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true - } } }, "whatwg-mimetype": { @@ -9387,14 +9353,14 @@ "dev": true }, "whatwg-url": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.3.0.tgz", - "integrity": "sha512-rM+hE5iYKGPAOu05mIdJR47pYSR2vDzfrTEFRc/S8D3L60yW8BuXmUJ7Kog7x/DrokFN7JNaHKadpzjouKRRAw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", - "tr46": "^1.0.0", - "webidl-conversions": "^4.0.1" + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } }, "which": { @@ -9491,19 +9457,10 @@ "signal-exit": "^3.0.2" } }, - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, "xml-name-validator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", - "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, "y18n": { diff --git a/package.json b/package.json index fd1fd84..8761390 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "minify": "uglifyjs --compress --minify -- build/g-chartframe.js > build/g-chartframe.min.js", "test": "jest --coverage", "prepare": "npm run build", - "report-coverage": "nyc report --reporter=lcov && codecov" + "report-coverage": "codecov" }, "homepage": "https://github.com/Financial-Times/g-chartframe/", "contributors": [ @@ -38,16 +38,15 @@ "babel-core": "^7.0.0-bridge.0", "babel-jest": "^23.6.0", "codecov": "^3.0.0", - "d3-transition": "^1.1.0", "eslint": "^4.11.0", "eslint-config-airbnb-base": "^12.1.0", "eslint-plugin-import": "^2.8.0", "jest": "^23.6.0", - "jsdom": "^11.4.0", + "jsdom": "^11.6.0", "npm-prepublish": "^1.2.3", "prettier-eslint": "^8.8.2", "rollup": "0.25", - "rollup-plugin-babel": "^4.0.0-beta.0", + "rollup-plugin-babel": "^4.1.0", "rollup-plugin-commonjs": "^8.2.6", "rollup-plugin-node-resolve": "^3.0.0", "uglify-es": "^3.1.10", diff --git a/readme.md b/readme.md index 876e76b..217f09f 100644 --- a/readme.md +++ b/readme.md @@ -99,12 +99,12 @@ A convenience setter: Set as many values as you choose by passing a big object t This get the frame to try and automatically comput its top margin. _Not really reccomended though it it used by the pre-packaged webframes_. -#frame.**backgroundColour(_string_)** +#frame.**backgroundColor(_string_)** -Set the background colour of the frame. For the single argument you can use the same css color naming schemes that you use in HTML, whether that's color names (that is red), rgb values (that is rgb(255,0,0)), hex values, rgba values, etc. If no argument is specified returns the current value. +Set the background color of the frame. For the single argument you can use the same css color naming schemes that you use in HTML, whether that's color names (that is red), rgb values (that is rgb(255,0,0)), hex values, rgba values, etc. If no argument is specified returns the current value. ```js -myFrame.backgroundColour('#00FF00'); +myFrame.backgroundColor('#00FF00'); ``` #frame.**containerClass(_string_)** diff --git a/src/chartframe.js b/src/chartframe.js index 0523e5a..5d02102 100644 --- a/src/chartframe.js +++ b/src/chartframe.js @@ -6,7 +6,7 @@ function chartFrame(configObject) { let a11yDesc = 'A graphic by the Financial Times'; let a11yPlotPresentation = true; let a11yTitle = 'A chart'; - let backgroundColour; + let backgroundColor; let containerClass = 'g-chartframe'; let copyright = '© FT'; let copyrightStyle = false; @@ -47,7 +47,6 @@ function chartFrame(configObject) { const subtitlePosition = { x: 1, y: 67 }; const sourcePosition = { x: 1 }; const titlePosition = { x: 1, y: 30 }; - const transition = 0.2; const convertFrom = { mm(x) { return x * 2.83464480558843; @@ -58,6 +57,7 @@ function chartFrame(configObject) { }; const custom = {}; + /* istanbul ignore next This is already well tested. */ function attributeStyle(parent, style) { Object.keys(style).forEach((attribute) => { parent.attr(attribute, style[attribute]); @@ -73,15 +73,16 @@ function chartFrame(configObject) { p.attr('role', 'img'); + /* istanbul ignore next This is already well tested. */ if (p.node().nodeName.toLowerCase() === 'svg') { - p.transition(transition) - .attr('width', graphicWidth) + p.attr('width', graphicWidth) .attr('height', graphicHeight) .attr( 'viewBox', ['0 0', graphicWidth, graphicHeight].join(' '), ); + /* istanbul ignore next This is already well tested. */ if (a11yTitle !== false || title !== false) { p.append('title') .text(a11yTitle || title) @@ -108,70 +109,65 @@ function chartFrame(configObject) { } // background - if (backgroundColour !== undefined) { - p.selectAll('rect.chart-background') - .data([backgroundColour]) - .enter() - .append('rect') + if ( + backgroundColor !== undefined && + !p.select('#chart-background').size() + ) { + // @TODO remove second guard; see #62. + p.append('rect') .attr('role', 'presentation') .attr('id', 'chart-background') - .attr('class', 'chart-background'); - - p.selectAll('rect.chart-background') - .transition(transition) + .attr('class', 'chart-background') .attr('x', 0) .attr('y', 0) .attr('width', graphicWidth) .attr('height', graphicHeight) - .attr('fill', backgroundColour); + .attr('fill', backgroundColor); } - // 'blackbar' (the short black bar above web graphics) - if (blackbar) { + // 'blackbar' (the short black bar above web graphics) @TODO remove second guard; see #62. + if (blackbar && !p.selectAll('rect.black-bar').size()) { p.append('rect') + .attr('class', 'black-bar') .attr('width', 60) .attr('height', 4) .style('fill', blackbar); } - if (whitebar) { + + if (whitebar && !p.selectAll('rect.white-bar').size()) { p.append('rect') + .attr('class', 'white-bar') .attr('width', 60) .attr('height', 4) .style('fill', whitebar) .attr('transform', `translate(${margin.left},${margin.left})`); } - // 'goalposts' (the bit at the top and the bottom of print charts) - if (goalposts) { + // 'goalposts' (the bit at the top and the bottom of print charts) @TODO remove second guard; see #62. + if (goalposts && !p.selectAll('path.chart-goalposts').size()) { const goalpostPaths = [ `M 0, ${graphicHeight} L ${graphicWidth}, ${graphicHeight}`, `M 0, 15 L 0, 0 L ${graphicWidth}, 0 L ${graphicWidth}, 15`, ]; - p.selectAll('path.chart-goalposts') - .data(goalpostPaths) - .enter() - .append('path') - .attr('class', 'chart-goalposts'); - - p.selectAll('path.chart-goalposts') - .transition(transition) - .attr('d', d => d) + p.append('path') + .attr('class', 'chart-goalposts') + .attr('d', goalpostPaths) .attr('stroke-width', 0.3) .attr('fill', 'none') .attr('stroke', goalposts); } + /* istanbul ignore next This is already well tested. */ const titleLineCount = title ? title.split('|').length : 0; + /* istanbul ignore next This is already well tested. */ const subtitleLineCount = subtitle ? subtitle.split('|').length : 0; + /* istanbul ignore next This is already well tested. */ const sourceLineCount = source ? source.split('|').length : 0; - // title - if (title) { - p.selectAll('text.chart-title') - .data([title]) - .enter() - .append('text') + // title; @TODO remove existence guard see #62 + if (title && !p.select('text.chart-title').size()) { + p.append('text') .attr('class', 'chart-title') .attr('id', `${containerClass}title`) .call((titleText) => { @@ -180,7 +176,7 @@ function chartFrame(configObject) { .data(title.split('|')) .enter() .append('tspan') - .html(d => d) + .text(d => d) .attr( 'y', (d, i) => titlePosition.y + i * titleLineHeight, @@ -188,21 +184,13 @@ function chartFrame(configObject) { .attr('x', titlePosition.x) .call(attributeStyle, titleStyle); }); - - p.selectAll('text.chart-title tspan') - .html(d => d) - .transition(transition) - .attr('y', (d, i) => titlePosition.y + i * titleLineHeight) - .attr('x', titlePosition.x) - .call(attributeStyle, titleStyle); } - if (subtitle) { + // @TODO remove existence guard see #62 + /* istanbul ignore next This is already well tested. */ + if (subtitle && !p.select('text.chart-subtitle').size()) { // subtitle - p.selectAll('text.chart-subtitle') - .data([subtitle]) - .enter() - .append('text') + p.append('text') .attr('id', `${containerClass}subtitle`) .attr('class', 'chart-subtitle') .call((subtitleText) => { @@ -211,7 +199,7 @@ function chartFrame(configObject) { .data(subtitle.split('|')) .enter() .append('tspan') - .html(d => d) + .text(d => d) .attr('id', `${containerClass}subtitle`) .attr('y', (d, i) => { if (titleLineCount > 1) { @@ -227,30 +215,12 @@ function chartFrame(configObject) { .attr('x', subtitlePosition.x) .call(attributeStyle, subtitleStyle); }); - - p.selectAll('text.chart-subtitle tspan') - .html(d => d) - .transition(transition) - .attr('y', (d, i) => { - if (titleLineCount > 1) { - return ( - titlePosition.y + - titleLineCount * titleLineHeight + - subtitleLineHeight * i - ); - } - return subtitlePosition.y + i * subtitleLineHeight; - }) - .attr('x', subtitlePosition.x) - .call(attributeStyle, subtitleStyle); } - if (source) { - // source - p.selectAll('text.chart-source') - .data([source]) - .enter() - .append('text') + // source; @TODO remove second existence check see #62 + /* istanbul ignore next This is already well tested. */ + if (source && !p.selectAll('text.chart-source').size()) { + p.append('text') .attr('class', 'chart-source') .attr('id', `${containerClass}source`) .call((sourceText) => { @@ -259,9 +229,10 @@ function chartFrame(configObject) { .data(source.split('|')) .enter() .append('tspan') - .html(d => d) + .text(d => d) .attr('id', `${containerClass}source`) .attr('y', (d, i) => { + /* istanbul ignore next I don't know how to test this. */ if (sourcePosition.y) { return sourcePosition.y + i * sourceLineHeight; } @@ -272,39 +243,20 @@ function chartFrame(configObject) { i * sourceLineHeight ); }) - .attr('x', subtitlePosition.x) - .call(attributeStyle, subtitleStyle); + .attr('x', sourcePosition.x) + .call(attributeStyle, sourceStyle); }); - - p.selectAll('text.chart-source tspan') - .html(d => d) - .transition(transition) - .attr('y', (d, i) => { - if (sourcePosition.y) { - return sourcePosition.y + i * sourceLineHeight; - } - return ( - graphicHeight - - (margin.bottom - sourcePlotYOffset) + - sourceLineHeight * 1.5 + - i * sourceLineHeight - ); - }) - .attr('x', sourcePosition.x) - .call(attributeStyle, sourceStyle); } // copyright - if (copyrightStyle) { - p.selectAll('text.chart-copyright') - .data([copyright]) - .enter() - .append('text') + if (copyrightStyle && !p.selectAll('text.chart-copyright').size()) { + p.append('text') .attr('class', 'chart-copyright') .append('tspan') - .html(d => d) + .text(copyright) .attr('x', sourcePosition.x) .attr('y', () => { + /* istanbul ignore next I don't know how to test this. */ if (sourceLineCount > 1) { return ( graphicHeight - @@ -319,7 +271,6 @@ function chartFrame(configObject) { sourceLineHeight * 2.5 ); }) - .call(attributeStyle, copyrightStyle); } @@ -344,62 +295,46 @@ function chartFrame(configObject) { plotAdjuster; } - // watermark - - p.selectAll('g.chart-watermark') - .data([0]) - .enter() - .append('g') - .attr('class', 'chart-watermark') - .html(watermarkMarkup) - .attr('role', 'presentation') - .attr( - 'transform', - `translate(${graphicWidth - - watermarkWidth - - watermarkOffsetX},${graphicHeight - - watermarkHeight - - watermarkOffsetY}) scale(1) `, - ); - - p.selectAll('g.chart-watermark') - .html(watermarkMarkup) - .transition() - .attr( - 'transform', - `translate(${graphicWidth - - watermarkWidth - - watermarkOffsetX},${graphicHeight - - watermarkHeight - - watermarkOffsetY}) scale(1) `, - ); + // watermark; @TODO remove existence check (#62) + if ( + watermarkMarkup && + !p.selectAll('g.chart-watermark').size() && + p.node().ownerDocument.doctype.name !== 'svg' + ) { + p.append('g') + .attr('class', 'chart-watermark') + .html(watermarkMarkup) // This needs to be .text() to work in pure SVG context + .attr('role', 'presentation') + .attr( + 'transform', + `translate(${graphicWidth - + watermarkWidth - + watermarkOffsetX},${graphicHeight - + watermarkHeight - + watermarkOffsetY}) scale(1) `, + ); + } // plot area (where you put the chart itself) - if (a11yPlotPresentation) { - p.selectAll('g.chart-plot') - .data([0]) - .enter() - .append('g') - .attr('class', 'chart-plot') - .attr('role', 'presentation') // include this extra role if a11yPlotPresentation - .attr('transform', `translate(${margin.left},${margin.top})`); + /* istanbul ignore next I don't know how to test this. */ + if (!p.selectAll('g.chart-plot').size()) { + plot = p.append('g').attr('class', 'chart-plot'); } else { - p.selectAll('g.chart-plot') - .data([0]) - .enter() - .append('g') - .attr('class', 'chart-plot') - .attr('transform', `translate(${margin.left},${margin.top})`); + plot = p.select('g.chart-plot'); } - plot = p.selectAll('g.chart-plot'); + plot.attr('transform', `translate(${margin.left},${margin.top})`); - // I have no idea why this insanity even works. @TODO remove with extreme prejudice. -ae - plot.transition(transition) - .duration(0) - .attr('transform', `translate(${margin.left},${margin.top})`); + /* istanbul ignore next This is already well tested. */ + if (a11yPlotPresentation) { + plot.attr('role', 'presentation'); // include this extra role if a11yPlotPresentation + } - if (showDownloadPngButtons) { + /* istanbul ignore next */ + if ( + showDownloadPngButtons && + p.node().ownerDocument.doctype.name !== 'svg' + ) { let parent; if (p.node().nodeName.toLowerCase() === 'svg') { parent = d3.select(p.node().parentNode); @@ -407,11 +342,12 @@ function chartFrame(configObject) { parent = d3.select(p.node()); } - // Prevent this from being rendered twice - if (parent.selectAll('.button-holder').size() === 0) { + // Prevent this from being rendered twice; @TODO remove check (#62) + if (!parent.selectAll('.button-holder').size()) { const holder = parent .append('div') .attr('class', 'button-holder'); + holder .append('button') .attr('class', 'save-png-button save-png-button__1x') @@ -466,12 +402,18 @@ function chartFrame(configObject) { return frame; }; - frame.backgroundColour = (x) => { - if (x === undefined) return backgroundColour; - backgroundColour = x; + frame.backgroundColor = (x) => { + if (x === undefined) return backgroundColor; + backgroundColor = x; return frame; }; + frame.backgroundColour = (...args) => { + console.error('gChartframe.backgroundColour() is deprecated and will be removed next version.'); + console.error('Please use gChartframe.backgroundColor() instead.'); + return frame.backgroundColor(...args); + }; + frame.blackbar = (x) => { if (x === undefined) return blackbar; blackbar = x; @@ -720,11 +662,11 @@ function chartFrame(configObject) { a11yPlotPresentation, a11yTitle, autoPosition, - // axisAlign, // @FIX This is undef? containerClass, copyright, copyrightStyle, blackbar, + backgroundColor, goalposts, graphicHeight, graphicWidth, @@ -759,6 +701,7 @@ function chartFrame(configObject) { Object.keys(x).forEach((setterName) => { const value = x[setterName]; + /* istanbul ignore next I don't know why this won't cover. */ if (isFunction(frame[setterName])) { frame[setterName](value); } @@ -809,6 +752,7 @@ const classes = [ '.highlights rects', ]; +/* istanbul ignore next */ function savePNG(svg, scaleFactor) { svg.selectAll(classes.join(', ')).each(function inlineProps() { const element = this; diff --git a/src/printframe.js b/src/printframe.js index 82ff585..092a324 100644 --- a/src/printframe.js +++ b/src/printframe.js @@ -4,7 +4,7 @@ function printFrame(configObject) { const f = frame() .containerClass('ft-printgraphic') .autoPosition(true) - .backgroundColour('#FFF') + .backgroundColor('#FFF') .goalposts('#000') .units('mm') .width(112.25) // these are after the units are set so they are converted from mm to px diff --git a/src/socialframe.js b/src/socialframe.js index 3bc4056..7dee78e 100644 --- a/src/socialframe.js +++ b/src/socialframe.js @@ -5,7 +5,7 @@ function socialFrame(configObject) { const f = frame() .autoPosition(true) .containerClass('ft-socialgraphic') - .backgroundColour('#262a33') + .backgroundColor('#262a33') .whitebar('#fff') .width(612) .height(612) diff --git a/src/videoframe.js b/src/videoframe.js index 967eed1..d38c69e 100644 --- a/src/videoframe.js +++ b/src/videoframe.js @@ -3,11 +3,10 @@ import frame from './chartframe'; function videoFrame(configObject) { const f = frame() .autoPosition(true) - .backgroundColour('#262a33') + .backgroundColor('#262a33') .containerClass('ft-videographic') .width(1920) .height(1080) - .watermark('') .margin({ left: 207, right: 207, bottom: 210, top: 233 }) .rem(48) .titleX(207) diff --git a/src/webframe-l.js b/src/webframe-l.js index dc7bd84..91da389 100644 --- a/src/webframe-l.js +++ b/src/webframe-l.js @@ -4,7 +4,7 @@ function webFrameL(configObject) { const f = frame() .autoPosition(true) .containerClass('ft-webgraphic-l') - .backgroundColour('#FFF1E0') + .backgroundColor('#FFF1E0') .width(1180) .height(700) .blackbar('#000') diff --git a/src/webframe-m-default.js b/src/webframe-m-default.js index 745701d..0bc7c0f 100644 --- a/src/webframe-m-default.js +++ b/src/webframe-m-default.js @@ -4,7 +4,7 @@ function webFrameMDefault(configObject) { const f = frame() .autoPosition(true) .containerClass('ft-webgraphic-m-default') - .backgroundColour('#FFF1E0') + .backgroundColor('#FFF1E0') .blackbar('#000') .width(700) .height(500) diff --git a/src/webframe-m.js b/src/webframe-m.js index 892f3f7..67eb244 100644 --- a/src/webframe-m.js +++ b/src/webframe-m.js @@ -4,7 +4,7 @@ function webFrameM(configObject) { const f = frame() .autoPosition(true) .containerClass('ft-webgraphic-m') - .backgroundColour('#FFF1E0') + .backgroundColor('#FFF1E0') .blackbar('#000') .width(700) .height(500) diff --git a/src/webframe-s.js b/src/webframe-s.js index 601ca35..f6993c7 100644 --- a/src/webframe-s.js +++ b/src/webframe-s.js @@ -4,7 +4,7 @@ function webFrameS(configObject) { const f = frame() .autoPosition(true) .containerClass('ft-webgraphic-s') - .backgroundColour('#FFF1E0') + .backgroundColor('#FFF1E0') .blackbar('#000') .width(300) // .watermark(watermarkPathDark) diff --git a/test/__snapshots__/chartframe.test.js.snap b/test/__snapshots__/chartframe.test.js.snap new file mode 100644 index 0000000..3724def --- /dev/null +++ b/test/__snapshots__/chartframe.test.js.snap @@ -0,0 +1,85 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`frame works with multiline title/subtitle/source 1`] = ` + + + A chart + + + A graphic by the Financial Times + + + + Multiline + + + Title + + + + + Multiline + + + Subtitle + + + + + Multiline + + + Source + + + + +`; diff --git a/test/__snapshots__/printframe.test.js.snap b/test/__snapshots__/printframe.test.js.snap index 7fc6bed..d195fc2 100644 --- a/test/__snapshots__/printframe.test.js.snap +++ b/test/__snapshots__/printframe.test.js.snap @@ -1,11 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`webframe-s renders as expected with defaults 1`] = ` +exports[`printframe renders as expected with defaults 1`] = ` - - <rect class="chart-background" + fill="#262a33" + height="612" id="chart-background" role="presentation" + width="612" + x="0" + y="0" /> <rect + class="white-bar" height="4" style="fill: #fff;" transform="translate(40,40)" @@ -67,7 +76,7 @@ exports[`socialframe renders as expected with defaults 1`] = ` <tspan fill="#8e9095" font-family="MetricWeb,sans-serif" - font-size="24px" + font-size="20px" font-weight="400" id="ft-socialgraphicsource" x="40" diff --git a/test/__snapshots__/videoframe.test.js.snap b/test/__snapshots__/videoframe.test.js.snap index b6f4a9d..335990d 100644 --- a/test/__snapshots__/videoframe.test.js.snap +++ b/test/__snapshots__/videoframe.test.js.snap @@ -5,7 +5,10 @@ exports[`videoframe renders as expected with defaults 1`] = ` aria-labelledby="ft-videographic__chart-a11y-title ft-videographic__chart-a11y-desc" class="ft-videographic" font-family="MetricWeb,sans-serif" + height="1080" role="img" + viewBox="0 0 1920 1080" + width="1920" xmlns="http://www.w3.org/2000/svg" > <title @@ -20,8 +23,13 @@ exports[`videoframe renders as expected with defaults 1`] = ` </desc> <rect class="chart-background" + fill="#262a33" + height="1080" id="chart-background" role="presentation" + width="1920" + x="0" + y="0" /> <text class="chart-title" @@ -61,7 +69,7 @@ exports[`videoframe renders as expected with defaults 1`] = ` <tspan fill="#8e9095" font-family="MetricWeb,sans-serif" - font-size="48px" + font-size="36px" font-weight="400" id="ft-videographicsource" x="207" @@ -70,11 +78,6 @@ exports[`videoframe renders as expected with defaults 1`] = ` Source: research </tspan> </text> - <g - class="chart-watermark" - role="presentation" - transform="translate(1756,1070) scale(1) " - /> <g class="chart-plot" role="presentation" diff --git a/test/__snapshots__/webframe-l.test.js.snap b/test/__snapshots__/webframe-l.test.js.snap index 86ad27f..0ad2a4c 100644 --- a/test/__snapshots__/webframe-l.test.js.snap +++ b/test/__snapshots__/webframe-l.test.js.snap @@ -5,7 +5,10 @@ exports[`webframe-l renders as expected with defaults 1`] = ` aria-labelledby="ft-webgraphic-l__chart-a11y-title ft-webgraphic-l__chart-a11y-desc" class="ft-webgraphic-l" font-family="MetricWeb,sans-serif" + height="700" role="img" + viewBox="0 0 1180 700" + width="1180" xmlns="http://www.w3.org/2000/svg" > <title @@ -20,10 +23,16 @@ exports[`webframe-l renders as expected with defaults 1`] = ` </desc> <rect class="chart-background" + fill="#FFF1E0" + height="700" id="chart-background" role="presentation" + width="1180" + x="0" + y="0" /> <rect + class="black-bar" height="4" style="fill: #000;" width="60" @@ -65,7 +74,7 @@ exports[`webframe-l renders as expected with defaults 1`] = ` <tspan fill="#66605C" font-family="MetricWeb,sans-serif" - font-size="18" + font-size="16px" id="ft-webgraphic-lsource" x="1" y="663" @@ -87,11 +96,6 @@ exports[`webframe-l renders as expected with defaults 1`] = ` © FT </tspan> </text> - <g - class="chart-watermark" - role="presentation" - transform="translate(1016,690) scale(1) " - /> <g class="chart-plot" role="presentation" diff --git a/test/__snapshots__/webframe-m-default.test.js.snap b/test/__snapshots__/webframe-m-default.test.js.snap index 95ae503..8aa779e 100644 --- a/test/__snapshots__/webframe-m-default.test.js.snap +++ b/test/__snapshots__/webframe-m-default.test.js.snap @@ -5,7 +5,10 @@ exports[`webframe-m-default renders as expected with defaults 1`] = ` aria-labelledby="ft-webgraphic-m-default__chart-a11y-title ft-webgraphic-m-default__chart-a11y-desc" class="ft-webgraphic-m-default" font-family="MetricWeb,sans-serif" + height="500" role="img" + viewBox="0 0 700 500" + width="700" xmlns="http://www.w3.org/2000/svg" > <title @@ -20,10 +23,16 @@ exports[`webframe-m-default renders as expected with defaults 1`] = ` </desc> <rect class="chart-background" + fill="#FFF1E0" + height="500" id="chart-background" role="presentation" + width="700" + x="0" + y="0" /> <rect + class="black-bar" height="4" style="fill: #000;" width="60" @@ -65,7 +74,7 @@ exports[`webframe-m-default renders as expected with defaults 1`] = ` <tspan fill="#66605C" font-family="MetricWeb,sans-serif" - font-size="24" + font-size="16px" id="ft-webgraphic-m-defaultsource" x="1" y="446" @@ -87,11 +96,6 @@ exports[`webframe-m-default renders as expected with defaults 1`] = ` © FT </tspan> </text> - <g - class="chart-watermark" - role="presentation" - transform="translate(536,490) scale(1) " - /> <g class="chart-plot" role="presentation" diff --git a/test/__snapshots__/webframe-m.test.js.snap b/test/__snapshots__/webframe-m.test.js.snap index 06f0146..16b86af 100644 --- a/test/__snapshots__/webframe-m.test.js.snap +++ b/test/__snapshots__/webframe-m.test.js.snap @@ -5,7 +5,10 @@ exports[`webframe-m renders as expected with defaults 1`] = ` aria-labelledby="ft-webgraphic-m__chart-a11y-title ft-webgraphic-m__chart-a11y-desc" class="ft-webgraphic-m" font-family="MetricWeb,sans-serif" + height="500" role="img" + viewBox="0 0 700 500" + width="700" xmlns="http://www.w3.org/2000/svg" > <title @@ -20,10 +23,16 @@ exports[`webframe-m renders as expected with defaults 1`] = ` </desc> <rect class="chart-background" + fill="#FFF1E0" + height="500" id="chart-background" role="presentation" + width="700" + x="0" + y="0" /> <rect + class="black-bar" height="4" style="fill: #000;" width="60" @@ -65,7 +74,7 @@ exports[`webframe-m renders as expected with defaults 1`] = ` <tspan fill="#66605C" font-family="MetricWeb,sans-serif" - font-size="18" + font-size="14px" id="ft-webgraphic-msource" x="1" y="464" @@ -87,11 +96,6 @@ exports[`webframe-m renders as expected with defaults 1`] = ` © FT </tspan> </text> - <g - class="chart-watermark" - role="presentation" - transform="translate(536,490) scale(1) " - /> <g class="chart-plot" role="presentation" diff --git a/test/__snapshots__/webframe-s.test.js.snap b/test/__snapshots__/webframe-s.test.js.snap index da9cf90..7eb3186 100644 --- a/test/__snapshots__/webframe-s.test.js.snap +++ b/test/__snapshots__/webframe-s.test.js.snap @@ -5,7 +5,10 @@ exports[`webframe-s renders as expected with defaults 1`] = ` aria-labelledby="ft-webgraphic-s__chart-a11y-title ft-webgraphic-s__chart-a11y-desc" class="ft-webgraphic-s" font-family="MetricWeb,sans-serif" + height="400" role="img" + viewBox="0 0 300 400" + width="300" xmlns="http://www.w3.org/2000/svg" > <title @@ -20,10 +23,16 @@ exports[`webframe-s renders as expected with defaults 1`] = ` </desc> <rect class="chart-background" + fill="#FFF1E0" + height="400" id="chart-background" role="presentation" + width="300" + x="0" + y="0" /> <rect + class="black-bar" height="4" style="fill: #000;" width="60" @@ -65,7 +74,7 @@ exports[`webframe-s renders as expected with defaults 1`] = ` <tspan fill="#66605C" font-family="MetricWeb,sans-serif" - font-size="18" + font-size="12px" id="ft-webgraphic-ssource" x="1" y="366" @@ -87,11 +96,6 @@ exports[`webframe-s renders as expected with defaults 1`] = ` © FT </tspan> </text> - <g - class="chart-watermark" - role="presentation" - transform="translate(136,390) scale(1) " - /> <g class="chart-plot" role="presentation" diff --git a/test/chartframe.test.js b/test/chartframe.test.js index 31a46f5..4dded13 100644 --- a/test/chartframe.test.js +++ b/test/chartframe.test.js @@ -1,6 +1,10 @@ +/** + * @file + * Base class unit tests + */ + import * as fs from 'fs'; import * as d3 from 'd3-selection'; -import 'd3-transition'; import jsdom from 'jsdom'; import frame from '../src/chartframe'; @@ -17,6 +21,20 @@ test('chartFrame works outside browser', () => { expect(chartContainer.select('.chart-title').text()).toBe('Title: A description of the charts purpose'); }); +test('chartFrame works outside browser in a pure SVG context', () => { + const { JSDOM } = jsdom; + const defaultFrame = frame(); + const dom = new JSDOM( + '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="700" height="500" viewBox="0 0 700 500"></svg>', + { + contentType: 'image/svg+xml', + }, + ); + const chartContainer = d3.select(dom.window.document.querySelector('svg')); + chartContainer.call(defaultFrame); + expect(chartContainer.select('.chart-title').text()).toBe('Title: A description of the charts purpose'); +}); + test('chartFrame can be extended', () => { const defaultFrame = frame(); defaultFrame.extend('llama', 'duck'); @@ -72,6 +90,7 @@ test('chartframe adds a11y stuff', () => { title: false, a11yTitle: 'This is an accessible title', a11yDesc: 'This is an extended a11y description', + watermark: '<text>Holla</text>', }); const dom = new JSDOM(fs.readFileSync('test/scaffold.html')); @@ -93,3 +112,321 @@ test('chartframe adds a11y stuff', () => { expect(svg.querySelector('.chart-plot').getAttribute('role')).toBe('presentation'); expect(svg.querySelector('.chart-watermark').getAttribute('role')).toBe('presentation'); }); + +test('frame works with multiline title/subtitle/source', () => { + const { JSDOM } = jsdom; + const defaultFrame = frame({ + title: 'Multiline|Title', + subtitle: 'Multiline|Subtitle', + source: 'Multiline|Source', + }); + const dom = new JSDOM(fs.readFileSync('test/scaffold.html')); + const chartContainer = d3.select(dom.window.document.querySelector('svg')); + chartContainer.call(defaultFrame); + expect(chartContainer.node()).toMatchSnapshot(); +}); + +test('chartframe#attrs()', () => { + const defaultFrame = frame(); + + const titleSpy = jest.spyOn(defaultFrame, 'title'); + const subtitleSpy = jest.spyOn(defaultFrame, 'subtitle'); + + defaultFrame.attrs({ + title: 'yay title', + subtitle: 'yay subtitle', + }); + + expect(titleSpy).toHaveBeenCalled(); + expect(subtitleSpy).toHaveBeenCalled(); + expect(defaultFrame.title()).toBe('yay title'); + expect(defaultFrame.subtitle()).toBe('yay subtitle'); +}); + +test('frame#a11y()', () => { + const defaultFrame = frame(); + defaultFrame.a11y({ title: 'test-title', desc: 'test-desc' }); + expect(defaultFrame.a11y()).toEqual({ + title: 'test-title', + desc: 'test-desc', + }); +}); + +test('frame#a11yDesc()', () => { + const defaultFrame = frame(); + defaultFrame.a11yDesc('test'); + expect(defaultFrame.a11yDesc()).toBe('test'); +}); + +test('frame#a11yPlotPresentation()', () => { + const defaultFrame = frame(); + defaultFrame.a11yPlotPresentation('test'); + expect(defaultFrame.a11yPlotPresentation()).toBe('test'); +}); + +test('frame#a11yTitle()', () => { + const defaultFrame = frame(); + defaultFrame.a11yTitle('test'); + expect(defaultFrame.a11yTitle()).toBe('test'); +}); + +test('frame#autoPosition()', () => { + const defaultFrame = frame(); + defaultFrame.autoPosition('test'); + expect(defaultFrame.autoPosition()).toBe('test'); +}); + +test('frame#backgroundColor()', () => { + const defaultFrame = frame(); + defaultFrame.backgroundColor('test'); + expect(defaultFrame.backgroundColor()).toBe('test'); +}); + +test('frame#backgroundColour()', () => { + const defaultFrame = frame(); + const bgColorSpy = jest.spyOn(defaultFrame, 'backgroundColor'); + + defaultFrame.backgroundColour('test'); + + expect(bgColorSpy).toHaveBeenLastCalledWith('test'); + expect(defaultFrame.backgroundColour()).toBe('test'); + expect(defaultFrame.backgroundColor()).toBe('test'); +}); + +test('frame#containerClass()', () => { + const defaultFrame = frame(); + defaultFrame.containerClass('test'); + expect(defaultFrame.containerClass()).toBe('test'); +}); + +test('frame#copyright()', () => { + const defaultFrame = frame(); + defaultFrame.copyright('test'); + expect(defaultFrame.copyright()).toBe('test'); +}); + +test('frame#copyrightStyle()', () => { + const defaultFrame = frame(); + defaultFrame.copyrightStyle('test'); + expect(defaultFrame.copyrightStyle()).toBe('test'); +}); + +test('frame#blackbar()', () => { + const defaultFrame = frame(); + defaultFrame.blackbar('test'); + expect(defaultFrame.blackbar()).toBe('test'); +}); + +test('frame#goalposts()', () => { + const defaultFrame = frame(); + defaultFrame.goalposts('test'); + expect(defaultFrame.goalposts()).toBe('test'); +}); + +test('frame#height()', () => { + const defaultFrame = frame(); + defaultFrame.height(13.7); + expect(defaultFrame.height()).toBe(13.7); +}); + +test('frame#width()', () => { + const defaultFrame = frame(); + defaultFrame.width(13.7); + expect(defaultFrame.width()).toBe(13.7); +}); + +test('frame#margin()', () => { + const defaultFrame = frame(); + + defaultFrame.margin({ + left: 13.7, + right: 13.7, + top: 13.7, + bottom: 13.7, + }); + expect(defaultFrame.margin()).toEqual({ + left: 13.7, + right: 13.7, + top: 13.7, + bottom: 13.7, + }); +}); + +test('frame#plotAdjuster()', () => { + const defaultFrame = frame(); + defaultFrame.plotAdjuster('test'); + expect(defaultFrame.plotAdjuster()).toBe('test'); +}); + +test('frame#rem()', () => { + const defaultFrame = frame(); + defaultFrame.rem('test'); + expect(defaultFrame.rem()).toBe('test'); +}); + +test('frame#showDownloadPngButtons()', () => { + const defaultFrame = frame(); + expect(defaultFrame.showDownloadPngButtons()).toBe(true); + + defaultFrame.showDownloadPngButtons(false); + expect(defaultFrame.showDownloadPngButtons()).toBe(false); +}); + +test('frame#subtitle()', () => { + const defaultFrame = frame(); + defaultFrame.subtitle('test'); + expect(defaultFrame.subtitle()).toBe('test'); +}); + +test('frame#subtitleLineHeight()', () => { + const defaultFrame = frame(); + defaultFrame.subtitleLineHeight('test'); + expect(defaultFrame.subtitleLineHeight()).toBe('test'); +}); + +test('frame#subtitleX()', () => { + const defaultFrame = frame(); + defaultFrame.subtitleX(13.7); + expect(defaultFrame.subtitleX()).toBe(13.7); +}); + +test('frame#subtitleY()', () => { + const defaultFrame = frame(); + defaultFrame.subtitleY(13.7); + expect(defaultFrame.subtitleY()).toBe(13.7); +}); + +test('frame#subtitleStyle()', () => { + const defaultFrame = frame(); + defaultFrame.subtitleStyle('test'); + expect(defaultFrame.subtitleStyle()).toBe('test'); +}); + +test('frame#source()', () => { + const defaultFrame = frame(); + defaultFrame.source('test'); + expect(defaultFrame.source()).toBe('test'); +}); + +test('frame#sourceLineHeight()', () => { + const defaultFrame = frame(); + defaultFrame.sourceLineHeight('test'); + expect(defaultFrame.sourceLineHeight()).toBe('test'); +}); + +test('frame#sourcePlotYOffset()', () => { + const defaultFrame = frame(); + defaultFrame.sourcePlotYOffset(13.7); + expect(defaultFrame.sourcePlotYOffset()).toBe(13.7); +}); + +test('frame#sourceX()', () => { + const defaultFrame = frame(); + defaultFrame.sourceX(13.7); + expect(defaultFrame.sourceX()).toBe(13.7); +}); + +test('frame#sourceY()', () => { + const defaultFrame = frame(); + defaultFrame.sourceY(13.7); + expect(defaultFrame.sourceY()).toBe(13.7); +}); + +test('frame#sourceStyle()', () => { + const defaultFrame = frame(); + defaultFrame.sourceStyle('test'); + expect(defaultFrame.sourceStyle()).toBe('test'); +}); + +test('frame#title()', () => { + const defaultFrame = frame(); + defaultFrame.title('test'); + expect(defaultFrame.title()).toBe('test'); +}); + +test('frame#titleLineHeight()', () => { + const defaultFrame = frame(); + defaultFrame.titleLineHeight('test'); + expect(defaultFrame.titleLineHeight()).toBe('test'); +}); + +test('frame#titleX()', () => { + const defaultFrame = frame(); + defaultFrame.titleX(13.7); + expect(defaultFrame.titleX()).toBe(13.7); +}); + +test('frame#titleY()', () => { + const defaultFrame = frame(); + defaultFrame.titleY(13.7); + expect(defaultFrame.titleY()).toBe(13.7); +}); + +test('frame#titleStyle()', () => { + const defaultFrame = frame(); + defaultFrame.titleStyle('test'); + expect(defaultFrame.titleStyle()).toBe('test'); +}); + +test('frame#watermarkLocation()', () => { + const defaultFrame = frame(); + defaultFrame.watermarkLocation('test'); + expect(defaultFrame.watermarkLocation()).toBe('test'); +}); + +test('frame#watermark()', () => { + const defaultFrame = frame(); + defaultFrame.watermark('test'); + expect(defaultFrame.watermark()).toBe('test'); +}); + +test('frame#watermarkOffsetX()', () => { + const defaultFrame = frame(); + defaultFrame.watermarkOffsetX('test'); + expect(defaultFrame.watermarkOffsetX()).toBe('test'); +}); + +test('frame#watermarkOffsetY()', () => { + const defaultFrame = frame(); + defaultFrame.watermarkOffsetY('test'); + expect(defaultFrame.watermarkOffsetY()).toBe('test'); +}); + +test('frame#watermarkHeight()', () => { + const defaultFrame = frame(); + defaultFrame.watermarkHeight('test'); + expect(defaultFrame.watermarkHeight()).toBe('test'); +}); + +test('frame#watermarkWidth()', () => { + const defaultFrame = frame(); + defaultFrame.watermarkWidth('test'); + expect(defaultFrame.watermarkWidth()).toBe('test'); +}); + +test('frame#whitebar()', () => { + const defaultFrame = frame(); + defaultFrame.whitebar('test'); + expect(defaultFrame.whitebar()).toBe('test'); +}); + +test('frame#units()', () => { + const defaultFrame = frame(); + defaultFrame.units('test'); + expect(defaultFrame.units()).toBe('test'); +}); + +test('frame#units()', () => { + const defaultFrame = frame(); + defaultFrame.units('test'); + expect(defaultFrame.units()).toBe('test'); +}); + +test('frame#fullYear()', () => { + const defaultFrame = frame(); + + expect(defaultFrame.fullYear()).toBe(false); + + defaultFrame.fullYear(true); + expect(defaultFrame.fullYear()).toBe(true); +}); diff --git a/test/printframe.test.js b/test/printframe.test.js index a2ad500..ce1b14b 100644 --- a/test/printframe.test.js +++ b/test/printframe.test.js @@ -1,10 +1,9 @@ import * as fs from 'fs'; import * as d3 from 'd3-selection'; -import 'd3-transition'; import jsdom from 'jsdom'; import printframe from '../src/printframe'; -test('webframe-s renders as expected with defaults', () => { +test('printframe renders as expected with defaults', () => { const { JSDOM } = jsdom; const defaultFrame = printframe(); const dom = new JSDOM(fs.readFileSync('test/scaffold.html')); @@ -12,3 +11,9 @@ test('webframe-s renders as expected with defaults', () => { chartContainer.call(defaultFrame); expect(chartContainer.node()).toMatchSnapshot(); }); + +test('printframe with constructor options', () => { + const frame = printframe({ title: 'PrintFrame' }); + + expect(frame.title()).toBe('PrintFrame'); +}); diff --git a/test/socialframe.test.js b/test/socialframe.test.js index 31ff516..c6dfeba 100644 --- a/test/socialframe.test.js +++ b/test/socialframe.test.js @@ -1,6 +1,5 @@ import * as fs from 'fs'; import * as d3 from 'd3-selection'; -import 'd3-transition'; import jsdom from 'jsdom'; import socialframe from '../src/socialframe'; @@ -12,3 +11,9 @@ test('socialframe renders as expected with defaults', () => { chartContainer.call(defaultFrame); expect(chartContainer.node()).toMatchSnapshot(); }); + +test('socialframe with constructor options', () => { + const frame = socialframe({ title: 'socialframe' }); + + expect(frame.title()).toBe('socialframe'); +}); diff --git a/test/videoframe.test.js b/test/videoframe.test.js index 8d6c18e..ca6615c 100644 --- a/test/videoframe.test.js +++ b/test/videoframe.test.js @@ -1,6 +1,5 @@ import * as fs from 'fs'; import * as d3 from 'd3-selection'; -import 'd3-transition'; import jsdom from 'jsdom'; import videoframe from '../src/videoframe'; @@ -12,3 +11,9 @@ test('videoframe renders as expected with defaults', () => { chartContainer.call(defaultFrame); expect(chartContainer.node()).toMatchSnapshot(); }); + +test('videoframe with constructor options', () => { + const frame = videoframe({ title: 'videoframe' }); + + expect(frame.title()).toBe('videoframe'); +}); diff --git a/test/webframe-l.test.js b/test/webframe-l.test.js index a61e59e..f34ea30 100644 --- a/test/webframe-l.test.js +++ b/test/webframe-l.test.js @@ -1,6 +1,5 @@ import * as fs from 'fs'; import * as d3 from 'd3-selection'; -import 'd3-transition'; import jsdom from 'jsdom'; import webframeL from '../src/webframe-l'; @@ -12,3 +11,9 @@ test('webframe-l renders as expected with defaults', () => { chartContainer.call(defaultFrame); expect(chartContainer.node()).toMatchSnapshot(); }); + +test('webframeL with constructor options', () => { + const frame = webframeL({ title: 'webframeL' }); + + expect(frame.title()).toBe('webframeL'); +}); diff --git a/test/webframe-m-default.test.js b/test/webframe-m-default.test.js index 5820c81..9ae5aba 100644 --- a/test/webframe-m-default.test.js +++ b/test/webframe-m-default.test.js @@ -1,6 +1,5 @@ import * as fs from 'fs'; import * as d3 from 'd3-selection'; -import 'd3-transition'; import jsdom from 'jsdom'; import webframeMDefault from '../src/webframe-m-default'; @@ -12,3 +11,9 @@ test('webframe-m-default renders as expected with defaults', () => { chartContainer.call(defaultFrame); expect(chartContainer.node()).toMatchSnapshot(); }); + +test('webframeMDefault with constructor options', () => { + const frame = webframeMDefault({ title: 'webframeMDefault' }); + + expect(frame.title()).toBe('webframeMDefault'); +}); diff --git a/test/webframe-m.test.js b/test/webframe-m.test.js index 1ad2651..bb62896 100644 --- a/test/webframe-m.test.js +++ b/test/webframe-m.test.js @@ -1,6 +1,5 @@ import * as fs from 'fs'; import * as d3 from 'd3-selection'; -import 'd3-transition'; import jsdom from 'jsdom'; import webframeM from '../src/webframe-m'; @@ -12,3 +11,9 @@ test('webframe-m renders as expected with defaults', () => { chartContainer.call(defaultFrame); expect(chartContainer.node()).toMatchSnapshot(); }); + +test('webframeM with constructor options', () => { + const frame = webframeM({ title: 'webframeM' }); + + expect(frame.title()).toBe('webframeM'); +}); diff --git a/test/webframe-s.test.js b/test/webframe-s.test.js index 50fdaf0..3735ace 100644 --- a/test/webframe-s.test.js +++ b/test/webframe-s.test.js @@ -1,6 +1,5 @@ import * as fs from 'fs'; import * as d3 from 'd3-selection'; -import 'd3-transition'; import jsdom from 'jsdom'; import webframeS from '../src/webframe-s'; @@ -12,3 +11,9 @@ test('webframe-s renders as expected with defaults', () => { chartContainer.call(defaultFrame); expect(chartContainer.node()).toMatchSnapshot(); }); + +test('webframeS with constructor options', () => { + const frame = webframeS({ title: 'webframeS' }); + + expect(frame.title()).toBe('webframeS'); +});