Skip to content

Commit ebdc5a2

Browse files
committed
test(chart-playground-web): cover CodeEditor highlighting, lint, and readOnly
1 parent 8eae73d commit ebdc5a2

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { readFileSync } from "fs";
2+
import { join } from "path";
3+
import { fireEvent, render, screen } from "@testing-library/react";
4+
import { CodeEditor } from "../CodeEditor";
5+
6+
describe("CodeEditor", () => {
7+
it("renders JSON value with syntax highlighting", () => {
8+
const { container } = render(<CodeEditor value='{"type":"scatter","x":[1,2,3]}' />);
9+
10+
// highlight.js wraps tokens in .hljs-* spans; a bare textarea would not.
11+
expect(container.querySelector(".hljs-attr, .hljs-string, .hljs-number")).not.toBeNull();
12+
});
13+
14+
it("calls onChange with the new text when edited", () => {
15+
const onChange = jest.fn();
16+
render(<CodeEditor value="{}" onChange={onChange} />);
17+
18+
fireEvent.input(screen.getByRole("textbox"), { target: { value: '{"a":1}' } });
19+
20+
expect(onChange).toHaveBeenCalledWith('{"a":1}');
21+
});
22+
23+
it("disables the editor when readOnly", () => {
24+
render(<CodeEditor value="{}" readOnly />);
25+
26+
// The disabled textarea is what blocks user edits in the modeler panel.
27+
expect((screen.getByRole("textbox") as HTMLTextAreaElement).disabled).toBe(true);
28+
});
29+
30+
it("surfaces an error for invalid JSON", () => {
31+
render(<CodeEditor value='{"type": ' />);
32+
33+
// Malformed JSON must be flagged, not silently accepted.
34+
expect(screen.queryByRole("alert")).not.toBeNull();
35+
});
36+
37+
it("shows no error for valid JSON", () => {
38+
render(<CodeEditor value='{"a":1}' />);
39+
40+
expect(screen.queryByRole("alert")).toBeNull();
41+
});
42+
43+
it("shows no error for an empty value", () => {
44+
render(<CodeEditor value="" />);
45+
46+
// Empty is not invalid.
47+
expect(screen.queryByRole("alert")).toBeNull();
48+
});
49+
50+
it("honors the height prop (unchanged prop contract)", () => {
51+
render(<CodeEditor value="{}" height="300px" />);
52+
53+
// react-simple-code-editor applies the style prop to its container (parent of the textarea).
54+
const container = screen.getByRole("textbox").parentElement as HTMLElement;
55+
expect(container.style.height).toBe("300px");
56+
});
57+
58+
it("does not reintroduce CodeMirror (the v6.3.0 bundling break)", () => {
59+
const pkg = JSON.parse(readFileSync(join(__dirname, "../../../package.json"), "utf8"));
60+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
61+
const codeMirrorDep = Object.keys(deps).find(name => /codemirror/i.test(name));
62+
63+
expect(codeMirrorDep).toBeUndefined();
64+
});
65+
});

0 commit comments

Comments
 (0)