From 7c3693c49e70cdbf11858daaa7cadf04a813a4b6 Mon Sep 17 00:00:00 2001 From: Kris Salvador Date: Tue, 29 Oct 2019 23:39:44 -0400 Subject: [PATCH 1/5] Update event handler test on XYPlot --- .eslintrc.json | 6 ++- package-lock.json | 84 ++++++++++----------------------- package.json | 1 + tests/jsdom/spec/XYPlot.spec.js | 51 ++++++++++++-------- 4 files changed, 60 insertions(+), 82 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 1609a04e..e6ff5e80 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,9 +8,11 @@ "extends": [ "@spotify/eslint-config-react", "@spotify/eslint-config-base", - "prettier" + "prettier", + "plugin:chai-friendly/recommended" ], - "plugins": ["jest"], + "env": { "jest": true }, + "plugins": ["jest", "chai-friendly"], "rules": { "consistent-return": "off", "no-nested-ternary": "off", diff --git a/package-lock.json b/package-lock.json index 20ff2873..895d8bc3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3755,8 +3755,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "optional": true + "dev": true }, "arr-flatten": { "version": "1.1.0", @@ -3823,8 +3822,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "optional": true + "dev": true }, "array.prototype.flat": { "version": "1.2.1", @@ -4353,7 +4351,6 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, - "optional": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -4372,7 +4369,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -4788,8 +4784,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -4811,14 +4806,12 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4834,22 +4827,19 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -4967,8 +4957,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -4980,7 +4969,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4995,7 +4983,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5004,14 +4991,12 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5030,7 +5015,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5112,8 +5096,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5125,7 +5108,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5212,8 +5194,7 @@ "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, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -5249,7 +5230,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5269,7 +5249,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5314,15 +5293,13 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true, - "optional": true + "dev": true } } }, @@ -7224,6 +7201,12 @@ "get-stdin": "^5.0.1" } }, + "eslint-plugin-chai-friendly": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.5.0.tgz", + "integrity": "sha512-Pxe6z8C9fP0pn2X2nGFU/b3GBOCM/5FVus1hsMwJsXP3R7RiXFl7g0ksJbsc0GxiLyidTW4mEFk77qsNn7Tk7g==", + "dev": true + }, "eslint-plugin-jest": { "version": "22.14.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.14.1.tgz", @@ -7471,7 +7454,6 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, - "optional": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -7487,7 +7469,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -7497,7 +7478,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -7610,7 +7590,6 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, - "optional": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -7627,7 +7606,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "optional": true, "requires": { "is-descriptor": "^1.0.0" } @@ -7637,7 +7615,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -7647,7 +7624,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -7657,7 +7633,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -7667,7 +7642,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, - "optional": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -7678,8 +7652,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true, - "optional": true + "dev": true } } }, @@ -7804,7 +7777,6 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, - "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -7817,7 +7789,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -9741,8 +9712,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "optional": true + "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", @@ -9771,7 +9741,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, - "optional": true, "requires": { "kind-of": "^3.0.2" } @@ -9925,8 +9894,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true + "dev": true }, "isomorphic-fetch": { "version": "2.2.1", @@ -10498,7 +10466,6 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, - "optional": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -10519,8 +10486,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true, - "optional": true + "dev": true } } }, @@ -10593,7 +10559,6 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -10603,8 +10568,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index dd43a832..c5b9ff5d 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "enzyme-adapter-react-16": "^1.7.0", "eslint": "^5.16.0", "eslint-config-prettier": "2.9.0", + "eslint-plugin-chai-friendly": "^0.5.0", "eslint-plugin-jest": "^22.14.1", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-react": "^7.14.3", diff --git a/tests/jsdom/spec/XYPlot.spec.js b/tests/jsdom/spec/XYPlot.spec.js index 35468c2b..649d6605 100644 --- a/tests/jsdom/spec/XYPlot.spec.js +++ b/tests/jsdom/spec/XYPlot.spec.js @@ -36,10 +36,10 @@ describe("XYPlot", () => { const chart2 = mount(); const node2 = chart2.find("svg").instance(); expect(node2.tagName.toLowerCase()).to.equal("svg"); - expect(parseInt(node2.getAttribute("width"))) + expect(parseInt(node2.getAttribute("width"), 10)) .to.be.a("number") .and.to.be.above(0); - expect(parseInt(node2.getAttribute("height"))) + expect(parseInt(node2.getAttribute("height"), 10)) .to.be.a("number") .and.to.be.above(0); }); @@ -60,10 +60,10 @@ describe("XYPlot", () => { expect(inner.getAttribute("transform").replace(/\s/, "")).to.contain( `translate(${margin.marginLeft},${margin.marginTop})` ); - expect(parseInt(bg.getAttribute("width"))).to.equal( + expect(parseInt(bg.getAttribute("width"), 10)).to.equal( size - (margin.marginLeft + margin.marginRight) ); - expect(parseInt(bg.getAttribute("height"))).to.equal( + expect(parseInt(bg.getAttribute("height"), 10)).to.equal( size - (margin.marginTop + margin.marginBottom) ); }); @@ -108,23 +108,34 @@ describe("XYPlot", () => { onMouseEnter: sinon.spy(), onMouseLeave: sinon.spy(), onMouseDown: sinon.spy(), - onMouseUp: sinon.spy() + onMouseUp: sinon.spy(), + onClick: sinon.spy(), }; const chart = mount(); - expect(chart.props().onMouseMove).not.to.have.been.called; - chart.simulate("mousemove"); - expect(chart.props().onMouseMove).to.have.been.called; - // expect(chart.props().onMouseEnter).not.to.have.been.called; - // chart.simulate("mouseenter"); - // expect(chart.props().onMouseEnter).to.have.been.called; - // expect(chart.props().onMouseLeave).not.to.have.been.called; - // chart.simulate("mouseleave"); - // expect(chart.props().onMouseLeave).to.have.been.called; - // expect(chart.props().onMouseDown).not.to.have.been.called; - // chart.simulate("mousedown"); - // expect(chart.props().onMouseDown).to.have.been.called; - // expect(chart.props().onMouseUp).not.to.have.been.called; - // chart.simulate("mouseup"); - // expect(chart.props().onMouseUp).to.have.been.called; + const chartProps = chart.props(); + const expectedKeys = [ + 'event', + 'outerX', + 'outerY', + 'innerX', + 'innerY', + 'xValue', + 'yValue', + 'xScale', + 'yScale', + 'marginTop', + 'marginBottom', + 'marginLeft', + 'marginRight', + ]; + + Object.keys(mouseHandlers).forEach(handler => { + const handlerSimulateEventName = handler.substring(2).toLowerCase(); + + expect(chartProps[handler]).not.to.have.been.called; + chart.simulate(handlerSimulateEventName); + expect(chartProps[handler]).to.have.been.called; + expect(Object.keys(chartProps[handler].args[0][0])).to.eql(expectedKeys); + }); }); }); From 89ef2909b5a8e3f6953fe37756c46e05af60728b Mon Sep 17 00:00:00 2001 From: Kris Salvador Date: Wed, 30 Oct 2019 12:50:07 -0400 Subject: [PATCH 2/5] Fix Bar warnings in tests --- tests/jsdom/spec/Bar.spec.js | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/tests/jsdom/spec/Bar.spec.js b/tests/jsdom/spec/Bar.spec.js index 6ec7069e..ac79d61c 100644 --- a/tests/jsdom/spec/Bar.spec.js +++ b/tests/jsdom/spec/Bar.spec.js @@ -10,13 +10,6 @@ const { expect } = chai; import { Bar } from "../../../src/index.js"; -function expectProps(el, expectedProps) { - const props = el.props(); - _.forEach(expectedProps, (expectedValue, key) => { - expect(props[key]).to.equal(expectedValue); - }); -} - describe("Bar", () => { let horizontalBarProps; let verticalBarProps; @@ -138,38 +131,26 @@ describe("Bar", () => { }); it("passes className and style props through to the bar's rectangle element", () => { - const verticalProps = { - ...verticalBarProps, + const barProps = { className: "foo-bar-test-class", style: { fill: "thistle" } }; - const verticalBar = shallow(); + const verticalBar = shallow(); const rect = verticalBar.find("rect"); expect(rect).to.have.length(1); expect(rect.props().className).to.include("foo-bar-test-class"); - expect(rect.props().style).to.deep.equal(verticalProps.style); + expect(rect.props().style).to.deep.equal(barProps.style); }); it("attaches onMouseMove, onMouseEnter and onMouseLeave handlers to the bar's rectangle", () => { const barProps = { - xScale: d3 - .scaleLinear() - .domain([0, 1]) - .range([0, 100]), - yScale: d3 - .scalePoint() - .domain(["a", "b", "c"]) - .range([100, 0]), - x: "a", - y: 0, - yEnd: 1, onMouseMove: sinon.spy(), onMouseEnter: sinon.spy(), onMouseLeave: sinon.spy() }; - const bar = mount(); + const bar = mount(); const rect = bar.find("rect"); expect(barProps.onMouseEnter).not.to.have.been.called; @@ -204,10 +185,6 @@ describe("Bar", () => { expect(() => { shallow(); }).to.throw(Error); - // throw if one scale is invalid - expect(() => { - shallow(); - }).to.throw(Error); // don't throw if both are provided expect(() => { shallow(); From 26891777308e021796204a7cd6c7e2bd4514666f Mon Sep 17 00:00:00 2001 From: Kris Salvador Date: Wed, 30 Oct 2019 12:51:56 -0400 Subject: [PATCH 3/5] Fix XLine warnings in tests --- tests/jsdom/spec/XLine.spec.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/jsdom/spec/XLine.spec.js b/tests/jsdom/spec/XLine.spec.js index d7053668..e3082911 100644 --- a/tests/jsdom/spec/XLine.spec.js +++ b/tests/jsdom/spec/XLine.spec.js @@ -1,7 +1,6 @@ -import _ from "lodash"; import * as d3 from "d3"; import React from "react"; -import { shallow, mount } from "enzyme"; +import { shallow } from "enzyme"; import chaiEnzyme from "chai-enzyme"; import chai from "chai"; chai.use(chaiEnzyme()); @@ -117,7 +116,7 @@ describe("XLine", () => { Date: Wed, 30 Oct 2019 13:27:56 -0400 Subject: [PATCH 4/5] Fix AreaBarChart warnings --- tests/jsdom/spec/AreaBarChart.spec.js | 82 ++++++++++++++------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/tests/jsdom/spec/AreaBarChart.spec.js b/tests/jsdom/spec/AreaBarChart.spec.js index f30b06b4..008e2201 100644 --- a/tests/jsdom/spec/AreaBarChart.spec.js +++ b/tests/jsdom/spec/AreaBarChart.spec.js @@ -7,11 +7,11 @@ import { AreaBarChart, RangeRect } from "../../../src/index.js"; import { getValue } from "../../../src/utils/Data.js"; describe("AreaBarChart", () => { - it("passes props correctly to RangeRect", () => { + describe("renders and passes props correctly to RangeRect", () => { const props = { xScale: d3 - .scalePoint() - .domain(["a", "b", "c"]) + .scaleLinear() + .domain([0, 100]) .range([0, 100]), yScale: d3 .scaleLinear() @@ -24,7 +24,7 @@ describe("AreaBarChart", () => { ], x: d => d.ageMin, xEnd: d => d.ageMax, - y: d => 0, + y: () => 0, yEnd: d => d.rate, barClassName: "test-bar-class-name", barStyle: { fill: "red" }, @@ -33,44 +33,48 @@ describe("AreaBarChart", () => { onMouseLeaveBar: () => {} }; - // renders individual RangeRects for the length of data - const chart = mount(); - const group = chart.find("g"); - const rangeRects = chart.find(RangeRect); - expect(group).to.have.length(1); - expect(rangeRects).to.have.length(props.data.length); + it("when horizontal is false", () => { + // renders individual RangeRects for the length of data + const chart = mount(); + const group = chart.find("g"); + const rangeRects = chart.find(RangeRect); + expect(group).to.have.length(1); + expect(rangeRects).to.have.length(props.data.length); - // sets / transforms props correctly for vertical bar chart - expect(rangeRects.at(0).props().xScale).to.equal(props.xScale); - expect(rangeRects.at(0).props().yScale).to.equal(props.yScale); - expect(rangeRects.at(0).props().className).to.contain(props.barClassName); - expect(rangeRects.at(0).props().style).to.equal(props.barStyle); - expect(rangeRects.at(0).props().x).to.equal( - getValue(props.x, props.data[0]) - ); - expect(rangeRects.at(0).props().xEnd).to.equal( - getValue(props.xEnd, props.data[0]) - ); - expect(rangeRects.at(0).props().y).to.equal(0); - expect(rangeRects.at(0).props().yEnd).to.equal( - getValue(props.y, props.data[0]) - ); + // sets / transforms props correctly for vertical bar chart + expect(rangeRects.at(0).props().xScale).to.equal(props.xScale); + expect(rangeRects.at(0).props().yScale).to.equal(props.yScale); + expect(rangeRects.at(0).props().className).to.contain(props.barClassName); + expect(rangeRects.at(0).props().style).to.equal(props.barStyle); + expect(rangeRects.at(0).props().x).to.equal( + getValue(props.x, props.data[0]) + ); + expect(rangeRects.at(0).props().xEnd).to.equal( + getValue(props.xEnd, props.data[0]) + ); + expect(rangeRects.at(0).props().y).to.equal(0); + expect(rangeRects.at(0).props().yEnd).to.equal( + getValue(props.y, props.data[0]) + ); + }); - // check that correct props are passed through in horizontal case - const horizontalProps = { ...props, horizontal: true }; + it("when horizontal is true", () => { + // check that correct props are passed through in horizontal case + const horizontalProps = { ...props, horizontal: true }; - const horizontalAreaBarChart = mount(); - const horizontalRangeRects = horizontalAreaBarChart.find(RangeRect); + const horizontalAreaBarChart = mount(); + const horizontalRangeRects = horizontalAreaBarChart.find(RangeRect); - expect(horizontalRangeRects.at(0).props().x).to.equal(0); - expect(horizontalRangeRects.at(0).props().xEnd).to.equal( - getValue(props.x, props.data[0]) - ); - expect(horizontalRangeRects.at(0).props().y).to.equal( - getValue(props.y, props.data[0]) - ); - expect(horizontalRangeRects.at(0).props().yEnd).to.equal( - getValue(props.yEnd, props.data[0]) - ); + expect(horizontalRangeRects.at(0).props().x).to.equal(0); + expect(horizontalRangeRects.at(0).props().xEnd).to.equal( + getValue(props.x, props.data[0]) + ); + expect(horizontalRangeRects.at(0).props().y).to.equal( + getValue(props.y, props.data[0]) + ); + expect(horizontalRangeRects.at(0).props().yEnd).to.equal( + getValue(props.yEnd, props.data[0]) + ); + }); }); }); From 4d144c4b1cd01a3637adc81562cc1ead66fa4374 Mon Sep 17 00:00:00 2001 From: Kris Salvador Date: Wed, 30 Oct 2019 14:21:17 -0400 Subject: [PATCH 5/5] Update SankeyDiagram tests --- src/SankeyDiagram.js | 1 + tests/jsdom/spec/SankeyDiagram.spec.js | 127 ++++++++++++++++++++----- 2 files changed, 106 insertions(+), 22 deletions(-) diff --git a/src/SankeyDiagram.js b/src/SankeyDiagram.js index f7e61388..d6996d58 100644 --- a/src/SankeyDiagram.js +++ b/src/SankeyDiagram.js @@ -981,6 +981,7 @@ export default class SankeyDiagram extends React.Component { componentWillMount() { this._makeSankeyGraph(); } + componentWillReceiveProps(nextProps) { // only update this._graph if a prop which affects the sankey layout has changed (most don't) const sankeyLayoutPropKeys = [ diff --git a/tests/jsdom/spec/SankeyDiagram.spec.js b/tests/jsdom/spec/SankeyDiagram.spec.js index 125a81f1..16e3dd91 100644 --- a/tests/jsdom/spec/SankeyDiagram.spec.js +++ b/tests/jsdom/spec/SankeyDiagram.spec.js @@ -1,7 +1,6 @@ import React from "react"; -import * as d3 from "d3"; import _ from "lodash"; -import { mount, shallow } from "enzyme"; +import { mount } from "enzyme"; import chai from "chai"; import sinon from "sinon"; import sinonChai from "sinon-chai"; @@ -14,7 +13,7 @@ const Sankey = rewire("../../../src/SankeyDiagram"); const SankeyDiagram = Sankey.default; const SankeyNode = Sankey.__get__("SankeyNode"); const SankeyLink = Sankey.__get__("SankeyLink"); -const SankeyNodeTerminal = Sankey.__get__("SankeyLink"); +const SankeyNodeTerminal = Sankey.__get__("SankeyNodeTerminal"); const SankeyNodeLabel = Sankey.__get__("SankeyNodeLabel"); const SankeyLinkLabel = Sankey.__get__("SankeyLinkLabel"); const SankeyStepLabel = Sankey.__get__("SankeyStepLabel"); @@ -152,7 +151,8 @@ describe("SankeyDiagram", () => { height: 400, shouldClone: true }; - const cloneChart = mount(); + // mount Sankey and check that dataToClone is deeply equal to sample data + mount(); expect(dataToClone).to.deep.equal(getSampleData()); const dataToMutate = getSampleData(); @@ -162,7 +162,8 @@ describe("SankeyDiagram", () => { height: 400, shouldClone: false }; - const mutateChart = mount(); + // mount Sankey and check that dataToMutate is not deeply equal to sample data + mount(); expect(dataToMutate).not.to.deep.equal(getSampleData()); expect(dataToMutate.links[0].source).to.deep.equal(dataToMutate.nodes[0]); }); @@ -172,7 +173,7 @@ describe("SankeyDiagram", () => { width: 600, height: 400, ...getSampleDataWithId(), - nodeId: (node, graph) => node.id + nodeId: node => node.id }; const chart = mount(); const svg = chart.find("svg"); @@ -185,7 +186,7 @@ describe("SankeyDiagram", () => { expect(sankeyNodes).to.have.length(5); expect(sankeyLinks).to.have.length(6); - sankeyNodes.forEach((node, i) => { + sankeyNodes.forEach(node => { const nodeProps = node.props(); expect(nodeProps.node).to.be.an("object"); const sourceLinks = sampleData.links.filter( @@ -281,7 +282,7 @@ describe("SankeyDiagram", () => { const showSomeLinksProps = { ...size, ...getSampleData(), - showLinks: (link, graph) => link.target.index === 2 + showLinks: link => link.target.index === 2 }; const showSomeLinksChart = mount(); expect(showSomeLinksChart.find(SankeyLink)).to.have.length(2); @@ -298,7 +299,7 @@ describe("SankeyDiagram", () => { const sankeyNodes = chart.find(SankeyNode); expect(sankeyNodes).to.have.length(5); - sankeyNodes.forEach((node, i) => { + sankeyNodes.forEach(node => { const nodeProps = node.props(); expect(nodeProps.node).to.be.an("object"); expect(nodeProps.node.x0).to.be.finite; @@ -348,7 +349,7 @@ describe("SankeyDiagram", () => { const sankeyNodes = chart.find(SankeyNode); expect(sankeyNodes).to.have.length(5); - sankeyNodes.forEach((node, i) => { + sankeyNodes.forEach(node => { const nodeProps = node.props(); expect(nodeProps.nodeClassName).to.equal("doggo"); expect(nodeProps.nodeStyle).to.be.an("object"); @@ -380,7 +381,7 @@ describe("SankeyDiagram", () => { const sankeyLinks = chart.find(SankeyLink); expect(sankeyLinks).to.have.length(6); - sankeyLinks.forEach((link, i) => { + sankeyLinks.forEach(link => { const linkProps = link.props(); expect(linkProps.linkClassName).to.equal("kitten"); expect(linkProps.linkStyle).to.be.an("object"); @@ -408,7 +409,7 @@ describe("SankeyDiagram", () => { const sankeyStepLabels = chart.find(SankeyStepLabel); expect(sankeyStepLabels).to.have.length(3); - sankeyStepLabels.forEach((label, i) => { + sankeyStepLabels.forEach(label => { const stepLabelProps = label.props(); expect(stepLabelProps.stepLabelText).to.equal("text"); expect(stepLabelProps.stepLabelClassName).to.equal("scoop"); @@ -476,7 +477,7 @@ describe("SankeyDiagram", () => { const showSomeLinkLabelsProps = { ...size, ...getSampleData(), - showLinkLabels: (link, graph) => link.target.index === 2 + showLinkLabels: link => link.target.index === 2 }; const showSomeLinkLabelsChart = mount( @@ -528,8 +529,8 @@ describe("SankeyDiagram", () => { expect(rect.props().style.fill).to.equal("coral"); }); it("calls nodeClassName & nodeStyle to get class & style, if they are functions", () => { - const className = (node, graph) => `i-${node.index}-x0-${node.x0}`; - const style = (node, graph) => ({ strokeWidth: `${node.x1}px` }); + const className = node => `i-${node.index}-x0-${node.x0}`; + const style = node => ({ strokeWidth: `${node.x1}px` }); const nodeProps = { node: basicNodeObj, nodeClassName: className, @@ -619,8 +620,8 @@ describe("SankeyDiagram", () => { expect(path.props().style.fill).to.equal("thistle"); }); it("calls linkClassName & linkStyle to get class & style, if they are functions", () => { - const linkClassName = (link, graph) => `w-${link.width}`; - const linkStyle = (link, graph) => ({ borderWidth: link.width }); + const linkClassName = link => `w-${link.width}`; + const linkStyle = link => ({ borderWidth: link.width }); const linkProps = { link: linkObj, linkClassName, linkStyle }; const link = mount(); const path = link.find("path"); @@ -883,7 +884,7 @@ describe("SankeyDiagram", () => { const labelBelowText = labelBelow.find("text"); expect(labelBelowText.props().y).to.equal(109); - const getDistance = node => 7; + const getDistance = () => 7; const labelDynamic = mount( { step + stepLabelText: currentStep => currentStep }} /> ); @@ -1015,7 +1016,7 @@ describe("SankeyDiagram", () => { const props = { step, stepLabelText: () => "r2d2", - stepLabelClassName: step => `step-${step}`, + stepLabelClassName: (currentStep) => `step-${currentStep}`, stepLabelStyle: () => ({ fill: "thistle" }) }; const label = mount(); @@ -1027,6 +1028,88 @@ describe("SankeyDiagram", () => { }); }); - // todo test terminals - // test their properties & rendered correctly + describe("SankeyNodeTerminal", () => { + const basicNodeObj = { + index: 5, + x0: 30, + x1: 50, + y0: 25, + y1: 100, + terminalValue: 10 + }; + const nodeTerminalProps = { + node: basicNodeObj, + graph: { nodes: [], links: [] }, + nodeTerminalWidth: 5, + nodeTerminalDistance: 1, + nodeTerminalStyle: { stroke: "blue" }, + nodeTerminalClassName: "merpy", + nodeTerminalAttributes: { rx: 3, ry: 3 }, + onMouseEnterNodeTerminal: sinon.spy(), + onMouseLeaveNodeTerminal: sinon.spy(), + onMouseMoveNodeTerminal: sinon.spy(), + onMouseDownNodeTerminal: sinon.spy(), + onMouseUpNodeTerminal: sinon.spy(), + onClickNodeTerminal: sinon.spy() + }; + + it("renders nothing when terminalValue is falsey", () => { + const nodeTerminal = mount(); + const rect = nodeTerminal.find("rect"); + expect(rect).to.have.length(0); + }); + + it("renders a rect with passed in props", () => { + const nodeTerminal = mount(); + const rect = nodeTerminal.find("rect"); + expect(rect).to.have.length(1); + expect(rect.props()).to.have.property("x"); + expect(rect.props()).to.have.property("y"); + expect(rect.props().style).to.equal(nodeTerminalProps.nodeTerminalStyle); + expect(rect.props().className).to.contain(nodeTerminalProps.nodeTerminalClassName); + expect(rect.props().attributes).to.equal(nodeTerminalProps.attributes); + }); + + it("attaches mouse event handlers (enter, leave, move, down, up, click) to the link path", () => { + const nodeTerminal = mount(); + const rect = nodeTerminal.find("rect"); + + expect(rect.props().onMouseEnter).to.be.a("function"); + expect(rect.props().onMouseLeave).to.be.a("function"); + expect(rect.props().onMouseMove).to.be.a("function"); + expect(rect.props().onMouseDown).to.be.a("function"); + expect(rect.props().onMouseUp).to.be.a("function"); + expect(rect.props().onClick).to.be.a("function"); + + expect(nodeTerminalProps.onMouseEnterNodeTerminal).not.to.have.been.called; + rect.simulate("mouseenter"); + expect(nodeTerminalProps.onMouseEnterNodeTerminal).to.have.been.called; + expect(nodeTerminalProps.onMouseLeaveNodeTerminal).not.to.have.been.called; + rect.simulate("mouseleave"); + expect(nodeTerminalProps.onMouseLeaveNodeTerminal).to.have.been.called; + expect(nodeTerminalProps.onMouseMoveNodeTerminal).not.to.have.been.called; + rect.simulate("mousemove"); + expect(nodeTerminalProps.onMouseMoveNodeTerminal).to.have.been.called; + expect(nodeTerminalProps.onMouseDownNodeTerminal).not.to.have.been.called; + rect.simulate("mousedown"); + expect(nodeTerminalProps.onMouseDownNodeTerminal).to.have.been.called; + expect(nodeTerminalProps.onMouseUpNodeTerminal).not.to.have.been.called; + rect.simulate("mouseup"); + expect(nodeTerminalProps.onMouseUpNodeTerminal).to.have.been.called; + expect(nodeTerminalProps.onClickNodeTerminal).not.to.have.been.called; + rect.simulate("click"); + expect(nodeTerminalProps.onClickNodeTerminal).to.have.been.called; + + // make sure callbacks are called with (event, {node, graph}) + expect(nodeTerminalProps.onClickNodeTerminal.args[0]).to.have.length(2); + const eventArg = nodeTerminalProps.onClickNodeTerminal.args[0][0]; + const infoArg = nodeTerminalProps.onClickNodeTerminal.args[0][1]; + expect(eventArg).to.be.an("object"); + expect(eventArg).to.have.property("target"); + expect(eventArg.target).to.be.an("object"); + expect(infoArg).to.be.an("object"); + expect(infoArg.node).to.equal(basicNodeObj); + expect(infoArg.graph).to.equal(nodeTerminalProps.graph); + }); + }); });