|
@@ -11,21 +11,415 @@
|
|
|
* specific language governing permissions and limitations under the License.
|
|
|
*/
|
|
|
|
|
|
-import React from "react";
|
|
|
-import {render} from "@testing-library/react";
|
|
|
+import React, {act} from "react";
|
|
|
+import {render, waitFor, RenderResult} from "@testing-library/react";
|
|
|
import "@testing-library/jest-dom";
|
|
|
+import {ThemeProvider} from '@mui/material/styles';
|
|
|
+import {createTheme} from '@mui/material/styles';
|
|
|
|
|
|
import Metric from "./Metric";
|
|
|
|
|
|
+const template = {
|
|
|
+ "layout": {
|
|
|
+ "colorscale": {
|
|
|
+ "diverging": [
|
|
|
+ [
|
|
|
+ 0,
|
|
|
+ "#8e0152"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.1,
|
|
|
+ "#c51b7d"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.2,
|
|
|
+ "#de77ae"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.3,
|
|
|
+ "#f1b6da"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.4,
|
|
|
+ "#fde0ef"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.5,
|
|
|
+ "#f7f7f7"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.6,
|
|
|
+ "#e6f5d0"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.7,
|
|
|
+ "#b8e186"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.8,
|
|
|
+ "#7fbc41"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.9,
|
|
|
+ "#4d9221"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 1,
|
|
|
+ "#276419"
|
|
|
+ ]
|
|
|
+ ],
|
|
|
+ "sequential": [
|
|
|
+ [
|
|
|
+ 0,
|
|
|
+ "#0d0887"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.1111111111111111,
|
|
|
+ "#46039f"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.2222222222222222,
|
|
|
+ "#7201a8"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.3333333333333333,
|
|
|
+ "#9c179e"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.4444444444444444,
|
|
|
+ "#bd3786"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.5555555555555556,
|
|
|
+ "#d8576b"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.6666666666666666,
|
|
|
+ "#ed7953"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.7777777777777778,
|
|
|
+ "#fb9f3a"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.8888888888888888,
|
|
|
+ "#fdca26"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 1,
|
|
|
+ "#f0f921"
|
|
|
+ ]
|
|
|
+ ],
|
|
|
+ "sequentialminus": [
|
|
|
+ [
|
|
|
+ 0,
|
|
|
+ "#0d0887"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.1111111111111111,
|
|
|
+ "#46039f"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.2222222222222222,
|
|
|
+ "#7201a8"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.3333333333333333,
|
|
|
+ "#9c179e"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.4444444444444444,
|
|
|
+ "#bd3786"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.5555555555555556,
|
|
|
+ "#d8576b"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.6666666666666666,
|
|
|
+ "#ed7953"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.7777777777777778,
|
|
|
+ "#fb9f3a"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 0.8888888888888888,
|
|
|
+ "#fdca26"
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 1,
|
|
|
+ "#f0f921"
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const colorMap = {
|
|
|
+ 20: "red",
|
|
|
+ 40: null,
|
|
|
+ 60: "blue",
|
|
|
+ 80: null
|
|
|
+};
|
|
|
+
|
|
|
+const darkTemplate = {
|
|
|
+ layout: {
|
|
|
+ colorscale: {
|
|
|
+ diverging: [
|
|
|
+ [0, "#8e0152"],
|
|
|
+ [0.1, "#c51b7d"],
|
|
|
+ [0.2, "#de77ae"],
|
|
|
+ [0.3, "#f1b6da"],
|
|
|
+ [0.4, "#fde0ef"],
|
|
|
+ [0.5, "#f7f7f7"],
|
|
|
+ [0.6, "#e6f5d0"],
|
|
|
+ [0.7, "#b8e186"],
|
|
|
+ [0.8, "#7fbc41"],
|
|
|
+ [0.9, "#4d9221"],
|
|
|
+ [1, "#276419"]
|
|
|
+ ],
|
|
|
+ sequential: [
|
|
|
+ [0, "#0d0887"],
|
|
|
+ [0.1111111111111111, "#46039f"],
|
|
|
+ [0.2222222222222222, "#7201a8"],
|
|
|
+ [0.3333333333333333, "#9c179e"],
|
|
|
+ [0.4444444444444444, "#bd3786"],
|
|
|
+ [0.5555555555555556, "#d8576b"],
|
|
|
+ [0.6666666666666666, "#ed7953"],
|
|
|
+ [0.7777777777777778, "#fb9f3a"],
|
|
|
+ [0.8888888888888888, "#fdca26"],
|
|
|
+ [1, "#f0f921"]
|
|
|
+ ],
|
|
|
+ sequentialminus: [
|
|
|
+ [0, "#0d0887"],
|
|
|
+ [0.1111111111111111, "#46039f"],
|
|
|
+ [0.2222222222222222, "#7201a8"],
|
|
|
+ [0.3333333333333333, "#9c179e"],
|
|
|
+ [0.4444444444444444, "#bd3786"],
|
|
|
+ [0.5555555555555556, "#d8576b"],
|
|
|
+ [0.6666666666666666, "#ed7953"],
|
|
|
+ [0.7777777777777778, "#fb9f3a"],
|
|
|
+ [0.8888888888888888, "#fdca26"],
|
|
|
+ [1, "#f0f921"]
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ paper_bgcolor: "rgb(31,47,68)",
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const lightTemplate = {
|
|
|
+ layout: {
|
|
|
+ colorscale: {
|
|
|
+ diverging: [
|
|
|
+ [0, "#053061"],
|
|
|
+ [0.1, "#2166ac"],
|
|
|
+ [0.2, "#4393c3"],
|
|
|
+ [0.3, "#92c5de"],
|
|
|
+ [0.4, "#d1e5f0"],
|
|
|
+ [0.5, "#f7f7f7"],
|
|
|
+ [0.6, "#fddbc7"],
|
|
|
+ [0.7, "#f4a582"],
|
|
|
+ [0.8, "#d6604d"],
|
|
|
+ [0.9, "#b2182b"],
|
|
|
+ [1, "#67001f"]
|
|
|
+ ],
|
|
|
+ sequential: [
|
|
|
+ [0, "#f7fcf5"],
|
|
|
+ [0.1111111111111111, "#e5f5e0"],
|
|
|
+ [0.2222222222222222, "#c7e9c0"],
|
|
|
+ [0.3333333333333333, "#a1d99b"],
|
|
|
+ [0.4444444444444444, "#74c476"],
|
|
|
+ [0.5555555555555556, "#41ab5d"],
|
|
|
+ [0.6666666666666666, "#238b45"],
|
|
|
+ [0.7777777777777778, "#006d2c"],
|
|
|
+ [0.8888888888888888, "#00441b"],
|
|
|
+ [1, "#000000"]
|
|
|
+ ],
|
|
|
+ sequentialminus: [
|
|
|
+ [0, "#f7fcf5"],
|
|
|
+ [0.1111111111111111, "#e5f5e0"],
|
|
|
+ [0.2222222222222222, "#c7e9c0"],
|
|
|
+ [0.3333333333333333, "#a1d99b"],
|
|
|
+ [0.4444444444444444, "#74c476"],
|
|
|
+ [0.5555555555555556, "#41ab5d"],
|
|
|
+ [0.6666666666666666, "#238b45"],
|
|
|
+ [0.7777777777777778, "#006d2c"],
|
|
|
+ [0.8888888888888888, "#00441b"],
|
|
|
+ [1, "#000000"]
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ paper_bgcolor: "rgb(255,255,255)",
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
describe("Metric Component", () => {
|
|
|
- it("renders", async () => {
|
|
|
- const { getByTestId } = render(<Metric testId="test-id"/>);
|
|
|
- const elt = getByTestId("test-id");
|
|
|
- expect(elt.tagName).toBe("DIV");
|
|
|
- })
|
|
|
- it("displays the right info for class", async () => {
|
|
|
- const { getByTestId } = render(<Metric testId="test-id" className={'taipy-gauge'}/>);
|
|
|
- const elt = getByTestId('test-id');
|
|
|
- expect(elt).toHaveClass('taipy-gauge');
|
|
|
- })
|
|
|
+ it("renders", async () => {
|
|
|
+ const {getByTestId} = render(<Metric testId="test-id"/>);
|
|
|
+ const elt = getByTestId("test-id");
|
|
|
+ expect(elt.tagName).toBe("DIV");
|
|
|
+ })
|
|
|
+
|
|
|
+ it("displays the right info for class", async () => {
|
|
|
+ const {getByTestId} = render(<Metric testId="test-id" className={'taipy-gauge'}/>);
|
|
|
+ const elt = getByTestId('test-id');
|
|
|
+ expect(elt).toHaveClass('taipy-gauge');
|
|
|
+ })
|
|
|
+
|
|
|
+ it("sets the title when provided", async () => {
|
|
|
+ const title = "Test Title";
|
|
|
+ let container: RenderResult | null = null;
|
|
|
+ container = render(<Metric title={title}/>);
|
|
|
+ await waitFor(() => {
|
|
|
+ const titleElement = container!.container.querySelector('.gtitle');
|
|
|
+ if (!titleElement) {
|
|
|
+ throw new Error('Title element not found');
|
|
|
+ }
|
|
|
+ expect(titleElement.textContent).toContain(title);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('logs an error when template prop is a malformed JSON string', () => {
|
|
|
+ const consoleSpy = jest.spyOn(console, 'info');
|
|
|
+ const malformedJson = "{ key: 'value'";
|
|
|
+ render(<Metric template={malformedJson}/>);
|
|
|
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Error while parsing Metric.template'));
|
|
|
+ consoleSpy.mockRestore();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('logs an error when colorMap prop is a malformed JSON string', () => {
|
|
|
+ const consoleSpy = jest.spyOn(console, 'info');
|
|
|
+ const malformedJson = "{ key: 'value'"; // missing closing brace
|
|
|
+ render(<Metric colorMap={malformedJson}/>);
|
|
|
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Error parsing color_map value (metric)'));
|
|
|
+ consoleSpy.mockRestore();
|
|
|
+ });
|
|
|
+
|
|
|
+ it("sets the template when provided", async () => {
|
|
|
+ let container: RenderResult | null = null;
|
|
|
+ container = render(<Metric template={JSON.stringify(template)}/>);
|
|
|
+ await waitFor(() => {
|
|
|
+ const elmWithTpl = container!.container.querySelector('.user-select-none')
|
|
|
+ expect(elmWithTpl).toBeInTheDocument()
|
|
|
+ })
|
|
|
+ });
|
|
|
+
|
|
|
+ it('processes colorMap prop correctly', async () => {
|
|
|
+ render(<Metric colorMap={JSON.stringify(colorMap)}/>);
|
|
|
+ await waitFor(() => {
|
|
|
+ const elts = document.querySelectorAll('.bg-arc');
|
|
|
+ const redElt = Array.from(elts[1].children);
|
|
|
+ const redEltHasRedFill = redElt.some((elt) => (elt as HTMLElement).style.fill === 'rgb(255, 0, 0)');
|
|
|
+ expect(redEltHasRedFill).toBeTruthy();
|
|
|
+
|
|
|
+ const blueElt = Array.from(elts[2].children);
|
|
|
+ const blueEltHasBlueFill = blueElt.some((elt) => (elt as HTMLElement).style.fill === 'rgb(0, 0, 255)');
|
|
|
+ expect(blueEltHasBlueFill).toBeTruthy();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('processes delta prop correctly when delta is defined', async () => {
|
|
|
+ render(<Metric delta={10} testId="test-id"/>);
|
|
|
+ await waitFor(() => {
|
|
|
+ const elt = document.querySelector('.delta');
|
|
|
+ if (elt) {
|
|
|
+ expect(elt.textContent).toContain('10');
|
|
|
+ } else {
|
|
|
+ throw new Error('Element with class .delta not found');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('processes type and threshold props correctly when type is linear', async () => {
|
|
|
+ render(<Metric type="linear" threshold={50} testId="test-id"/>);
|
|
|
+ await waitFor(() => {
|
|
|
+ const elt = document.querySelector('.bullet');
|
|
|
+ expect(elt).toBeInTheDocument();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('processes type and threshold props correctly when type is not linear', async () => {
|
|
|
+ render(<Metric type="angular" threshold={50} testId="test-id"/>);
|
|
|
+ await waitFor(() => {
|
|
|
+ const elt = document.querySelector('.angular');
|
|
|
+ expect(elt).toBeInTheDocument();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('applies style correctly when height is undefined', async () => {
|
|
|
+ render(<Metric testId="test-id"/>);
|
|
|
+ await waitFor(() => {
|
|
|
+ const elt = document.querySelector('.js-plotly-plot');
|
|
|
+ expect(elt).toHaveStyle({
|
|
|
+ width: '100%',
|
|
|
+ position: 'relative',
|
|
|
+ display: 'inline-block'
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('processes type prop correctly when type is none', async () => {
|
|
|
+ render(<Metric type="none" testId="test-id"/>);
|
|
|
+ await waitFor(() => {
|
|
|
+ const angularElm = document.querySelector('.angular');
|
|
|
+ const angularAxis = document.querySelector('.angularaxis');
|
|
|
+ expect(angularElm).not.toBeInTheDocument();
|
|
|
+ expect(angularAxis).not.toBeInTheDocument();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('processes template_Dark_ prop correctly when theme is dark', async () => {
|
|
|
+ const darkTheme = createTheme({
|
|
|
+ palette: {
|
|
|
+ mode: 'dark',
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ render(
|
|
|
+ <ThemeProvider theme={darkTheme}>
|
|
|
+ <Metric template_Dark_={JSON.stringify(darkTemplate)} testId="test-id"/>
|
|
|
+ </ThemeProvider>
|
|
|
+ );
|
|
|
+ await waitFor(() => {
|
|
|
+ const elt = document.querySelector('.main-svg');
|
|
|
+ expect(elt).toHaveStyle({
|
|
|
+ backgroundColor: 'rgb(31, 47, 68)'
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('processes template_Light_ prop correctly when theme is not dark', async () => {
|
|
|
+ const lightTheme = createTheme({
|
|
|
+ palette: {
|
|
|
+ mode: 'light',
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ render(
|
|
|
+ <ThemeProvider theme={lightTheme}>
|
|
|
+ <Metric template_Light_={JSON.stringify(lightTemplate)} testId="test-id"/>
|
|
|
+ </ThemeProvider>
|
|
|
+ );
|
|
|
+ await waitFor(() => {
|
|
|
+ const elt = document.querySelector('.main-svg');
|
|
|
+ expect(elt).toHaveStyle({
|
|
|
+ backgroundColor: 'rgb(255, 255, 255)'
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it('logs an error when template_Dark_ prop is not a valid JSON string', () => {
|
|
|
+ const consoleSpy = jest.spyOn(console, 'info');
|
|
|
+ render(<Metric template_Dark_="not a valid JSON string" testId="test-id"/>);
|
|
|
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Error while parsing Metric.template'));
|
|
|
+ consoleSpy.mockRestore();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('logs an error when template_Light_ prop is not a valid JSON string', () => {
|
|
|
+ const consoleSpy = jest.spyOn(console, 'info');
|
|
|
+ render(<Metric template_Light_="not a valid JSON string" testId="test-id"/>);
|
|
|
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Error while parsing Metric.template'));
|
|
|
+ consoleSpy.mockRestore();
|
|
|
+ });
|
|
|
+
|
|
|
});
|