Skip to content

Commit 45c5348

Browse files
Merge pull request #2259 from FormidableLabs/feature/victory-legend-jest-tests
migrate existing legend tests to jest
2 parents f1d9e70 + 2129e4a commit 45c5348

File tree

2 files changed

+246
-0
lines changed

2 files changed

+246
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/* eslint-disable max-nested-callbacks */
2+
import React from "react";
3+
import { render, screen } from "@testing-library/react";
4+
import { VictoryLegend } from "victory-legend";
5+
import { isCircle, isTriangle } from "../../svg-test-helper";
6+
7+
describe("components/victory-legend", () => {
8+
const initialData = [
9+
{
10+
name: "Series 1",
11+
symbol: {
12+
type: "circle"
13+
}
14+
},
15+
{
16+
name: "Series 2",
17+
labels: {
18+
fill: "red"
19+
},
20+
symbol: {
21+
type: "triangleUp",
22+
fill: "blue"
23+
}
24+
}
25+
];
26+
27+
it("renders provided data correctly", () => {
28+
const { container } = render(<VictoryLegend data={initialData} />);
29+
const legendLabels = container.querySelectorAll("text");
30+
31+
expect(legendLabels).toHaveLength(initialData.length);
32+
});
33+
34+
it("has expected horizontal label position", () => {
35+
const { container } = render(
36+
<VictoryLegend data={initialData} orientation="horizontal" />
37+
);
38+
39+
const [label1, label2] = container.querySelectorAll("text");
40+
41+
expect(label1.getAttribute("y")).toEqual(label2.getAttribute("y"));
42+
});
43+
44+
it("has expected vertical symbol position", () => {
45+
const { container } = render(
46+
<VictoryLegend data={initialData} orientation="vertical" />
47+
);
48+
49+
const [label1, label2] = container.querySelectorAll("text");
50+
51+
expect(label1.getAttribute("x")).toEqual(label2.getAttribute("x"));
52+
});
53+
54+
describe("symbols", () => {
55+
const legendData = [
56+
{
57+
name: "Series 1",
58+
labels: {
59+
fontSize: 10
60+
},
61+
symbol: {
62+
type: "circle",
63+
fill: "red"
64+
}
65+
},
66+
{
67+
name: "Long Series Name",
68+
labels: {
69+
fontSize: 12
70+
},
71+
symbol: {
72+
type: "triangleUp",
73+
fill: "blue"
74+
}
75+
}
76+
];
77+
78+
it("has expected symbols length", () => {
79+
const { container } = render(<VictoryLegend data={legendData} />);
80+
const symbols = container.querySelectorAll("path");
81+
expect(symbols).toHaveLength(2);
82+
});
83+
84+
it("has expected symbol colors", () => {
85+
const { container } = render(<VictoryLegend data={legendData} />);
86+
const symbols = container.querySelectorAll("path");
87+
88+
symbols.forEach((symbol, index) => {
89+
const style = symbol.getAttribute("style");
90+
expect(style).toContain(legendData[index].symbol.fill);
91+
});
92+
});
93+
94+
it("has expected symbol type", () => {
95+
const { container } = render(<VictoryLegend data={legendData} />);
96+
const [circleSymbol, triangleSymbol] = Array.from(
97+
container.querySelectorAll("path")
98+
).map((symbol) => symbol.getAttribute("d"));
99+
100+
expect(isCircle(circleSymbol)).toBeTruthy();
101+
expect(isTriangle(triangleSymbol)).toBeTruthy();
102+
});
103+
});
104+
105+
describe("legend style prop", () => {
106+
const legendData = [
107+
{
108+
name: "Thing 1"
109+
},
110+
{
111+
name: "Thing 2"
112+
}
113+
];
114+
115+
const styleObject = {
116+
data: {
117+
type: "triangleUp",
118+
fill: "green"
119+
},
120+
labels: {
121+
fontSize: 16
122+
}
123+
};
124+
125+
it("has expected symbol type", () => {
126+
const { container } = render(
127+
<VictoryLegend data={legendData} style={styleObject} />
128+
);
129+
130+
container.querySelectorAll("path").forEach((symbol) => {
131+
const svgPath = symbol.getAttribute("d");
132+
expect(isTriangle(svgPath)).toBeTruthy();
133+
});
134+
});
135+
136+
it("has expected symbol colors", () => {
137+
const { container } = render(
138+
<VictoryLegend data={legendData} style={styleObject} />
139+
);
140+
141+
container.querySelectorAll("path").forEach((item) => {
142+
expect(item.getAttribute("style")).toContain(styleObject.data.fill);
143+
});
144+
});
145+
146+
it("has expected label colors", () => {
147+
render(<VictoryLegend data={legendData} style={styleObject} />);
148+
149+
legendData.forEach(({ name }) => {
150+
const label = screen.getByText(name);
151+
expect(label.getAttribute("style")).toContain("#252525");
152+
});
153+
});
154+
});
155+
156+
describe("itemsPerRow", () => {
157+
const legendData = [
158+
{
159+
name: "Thing 1"
160+
},
161+
{
162+
name: "Thing 2"
163+
},
164+
{
165+
name: "Thing 3"
166+
},
167+
{
168+
name: "Thing 4"
169+
},
170+
{
171+
name: "Thing 5"
172+
},
173+
{
174+
name: "Thing 6"
175+
}
176+
];
177+
178+
const splitArrayAtIndex = (array, index) => {
179+
const half1 = array.slice(0, index);
180+
const half2 = array.slice(index, array.length);
181+
return [half1, half2];
182+
};
183+
184+
it("aligns items in columns", () => {
185+
const { container } = render(
186+
<VictoryLegend data={legendData} itemsPerRow={3} />
187+
);
188+
const labels = Array.from(container.querySelectorAll("text"));
189+
190+
expect(labels).toHaveLength(6);
191+
192+
const [column1, column2] = splitArrayAtIndex(labels, 3);
193+
194+
// items line up between columns
195+
column1.forEach((item, index) => {
196+
const correspondingColumnItemY = column2[index].getAttribute("y");
197+
expect(item.getAttribute("y")).toEqual(correspondingColumnItemY);
198+
});
199+
});
200+
201+
it("aligns items in rows", () => {
202+
const { container } = render(
203+
<VictoryLegend
204+
data={legendData}
205+
itemsPerRow={3}
206+
orientation="horizontal"
207+
/>
208+
);
209+
210+
const labels = Array.from(container.querySelectorAll("text"));
211+
212+
expect(labels).toHaveLength(6);
213+
214+
const rows = splitArrayAtIndex(labels, 3);
215+
216+
// each row is on the same y axis
217+
rows.forEach((row) => {
218+
const rowYValue = row[0].getAttribute("y");
219+
const allInSameRow = row.every(
220+
(item) => item.getAttribute("y") === rowYValue
221+
);
222+
expect(allInSameRow).toBeTruthy();
223+
});
224+
});
225+
});
226+
});

test/svg-test-helper.js

+20
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { _internalD3Voronoi as d3Voronoi } from "victory-voronoi/lib/helper-meth
44
import { without, min, max, property } from "lodash";
55

66
const RECTANGULAR_SEQUENCE = ["M", "A", "L", "A", "L", "A", "L", "A", "z"];
7+
const CIRCULAR_SEQUENCE = ["M", "m", "a", "a"];
8+
const TRIANGULAR_SEQUENCE = ["M", "L", "L", "z"];
79

810
export const calculateD3Path = (props, pathType, index = 0) => {
911
const { width, height, padding, scale, interpolation, data, domain } = props;
@@ -161,3 +163,21 @@ export const getBarShape = (path) => {
161163
*/
162164
export const isBar = (commandString) =>
163165
exhibitsShapeSequence(commandString, RECTANGULAR_SEQUENCE);
166+
167+
/**
168+
* Determines if a circular shape is produced from the provided path command.
169+
*
170+
* @param {String} commandString - The command attribute of a `path` element.
171+
* @returns {Boolean} - Boolean indicating if the command string produces a circular shape.
172+
*/
173+
export const isCircle = (commandString) =>
174+
exhibitsShapeSequence(commandString, CIRCULAR_SEQUENCE);
175+
176+
/**
177+
* Determines if a triangular shape is produced from the provided path command.
178+
*
179+
* @param {String} commandString - The command attribute of a `path` element.
180+
* @returns {Boolean} - Boolean indicating if the command string produces a triangular shape.
181+
*/
182+
export const isTriangle = (commandString) =>
183+
exhibitsShapeSequence(commandString, TRIANGULAR_SEQUENCE);

0 commit comments

Comments
 (0)