|
| 1 | +## Test Cases |
| 2 | + |
| 3 | +All unit tests, `@testing-library/react`, in |
| 4 | +`packages/pluggableWidgets/chart-playground-web/src/components/__tests__/CodeEditor.spec.tsx` |
| 5 | +(new file — `CodeEditor` has no tests today). |
| 6 | + |
| 7 | +The editor is `react-simple-code-editor`, which renders a real `<textarea>` under a highlighted |
| 8 | +`<pre>`. Query the textarea via `role="textbox"` / value; assert highlight + lint via rendered |
| 9 | +output. These tests define the contract before the textarea → highlighted-editor swap. |
| 10 | + |
| 11 | +### Reproduction Tests |
| 12 | + |
| 13 | +- **Renders JSON with syntax highlighting** - the editor highlights the value instead of showing |
| 14 | + plain unstyled text (the regression the textarea introduced). (unit) |
| 15 | + - **Given**: `CodeEditor` rendered with `value='{"type":"scatter","x":[1,2,3]}'`. |
| 16 | + - **When**: component mounts. |
| 17 | + - **Then**: the rendered output contains `highlight.js` token markup (at least one |
| 18 | + `.hljs-*` span, e.g. `hljs-attr` / `hljs-string` / `hljs-number`) wrapping parts of the |
| 19 | + value — not a bare unstyled text node. |
| 20 | + |
| 21 | +- **Surfaces invalid JSON** - malformed JSON is flagged, not silently accepted (the DX gap the |
| 22 | + textarea left; ties to Leonardo's "no silent catch" note). (unit) |
| 23 | + - **Given**: `CodeEditor` rendered with `value='{"type": '` (truncated / invalid JSON). |
| 24 | + - **When**: component mounts (or value changes to invalid). |
| 25 | + - **Then**: an error indication is shown (an element with the error class / role carrying the |
| 26 | + `JSON.parse` message); the editor still renders the raw text (does not blank out or throw). |
| 27 | + |
| 28 | +- **Valid JSON shows no error** - complement to the above. (unit) |
| 29 | + - **Given**: `CodeEditor` with `value='{"a":1}'`. |
| 30 | + - **When**: component mounts. |
| 31 | + - **Then**: no error indication element is present. |
| 32 | + |
| 33 | +### Edge Cases |
| 34 | + |
| 35 | +- **Empty value renders no error and no crash** (unit) |
| 36 | + - **Given**: `CodeEditor` with `value=''`. |
| 37 | + - **When**: mounts. |
| 38 | + - **Then**: renders an empty editor, no error indication (empty ≠ invalid), no throw. |
| 39 | + |
| 40 | +- **onChange fires with new text on edit** (unit) |
| 41 | + - **Given**: `CodeEditor` with `value='{}'` and a jest mock `onChange`. |
| 42 | + - **When**: user types into the textbox (`fireEvent.input` / `userEvent.type`). |
| 43 | + - **Then**: `onChange` is called with the updated string. |
| 44 | + |
| 45 | +- **readOnly blocks edits** - modeler panel uses `readOnly`. (unit) |
| 46 | + - **Given**: `CodeEditor` with `readOnly` and a mock `onChange`. |
| 47 | + - **When**: user attempts to type in the textbox. |
| 48 | + - **Then**: the textbox is non-editable (disabled/readonly attribute) and `onChange` is not |
| 49 | + called. |
| 50 | + |
| 51 | +- **Highlighter degrades gracefully on throw** - a highlight failure must not break the editor. (unit) |
| 52 | + - **Given**: highlighting a value that would make `hljs.highlight` throw (illegal sequence). |
| 53 | + - **When**: mounts. |
| 54 | + - **Then**: falls back to rendering the raw code (no crash), matching the rich-text pattern's |
| 55 | + try/catch + `console.warn`. |
| 56 | + |
| 57 | +### Regression Tests |
| 58 | + |
| 59 | +- **Prop contract unchanged** - `ComposedEditor` calls `CodeEditor` with `value/onChange/height` |
| 60 | + (editable panel) and `readOnly/value/height` (modeler panel). Both must keep working. (unit) |
| 61 | + - **Given**: `CodeEditor` rendered with `height="var(--editor-h)"`. |
| 62 | + - **When**: mounts. |
| 63 | + - **Then**: renders without error and applies the `height` (editor container reflects the |
| 64 | + passed height, as the textarea did). |
| 65 | + |
| 66 | +- **No CodeMirror dependency reintroduced** - the whole point of WC-3348. (build/lint guard) |
| 67 | + - **Given**: the widget package after the change. |
| 68 | + - **When**: inspecting imports/deps of `chart-playground-web`. |
| 69 | + - **Then**: no `codemirror`/`@codemirror/*` import or dependency is present; only |
| 70 | + `react-simple-code-editor` + `highlight.js` added. |
| 71 | + |
| 72 | +- **preview.spec snapshot** - existing `ChartPlayground.editorPreview` snapshot still passes |
| 73 | + (design-time preview is unaffected — it renders a static Toggle button, not `CodeEditor`). (unit) |
| 74 | + - **Given**: existing `src/__tests__/preview.spec.tsx`. |
| 75 | + - **When**: test suite runs. |
| 76 | + - **Then**: snapshot matches (or is intentionally updated only if the preview markup changes). |
| 77 | + |
| 78 | +## Notes |
| 79 | + |
| 80 | +- `react-simple-code-editor` renders a genuine textarea → RTL `getByRole("textbox")` works; |
| 81 | + editing via `fireEvent.input(textarea, { target: { value } })`. |
| 82 | +- Import `highlight.js/lib/core` + register only `languages/json` (tree-shaken) — assert token |
| 83 | + markup, not a specific theme. |
| 84 | +- The "No CodeMirror" check can be a dependency/import assertion or a package.json test rather |
| 85 | + than a runtime RTL test — decide at tasks.md time. |
0 commit comments