|
| 1 | +// @vitest-environment node |
| 2 | +// Checks over the page sources: every page uses the shared search field, and the pages with a |
| 3 | +// list and a detail use the splitter. Kept apart from the component tests, which the Angular |
| 4 | +// compiler transforms. |
| 5 | +import { describe, expect, it } from 'vitest'; |
| 6 | + |
| 7 | +const PAGES = new URL('../pages/', import.meta.url).pathname; |
| 8 | + |
| 9 | +/** The page sources by file name. The panel tsconfig has no Node types, so fs is a loose import. */ |
| 10 | +async function pageSources(): Promise<Map<string, string>> { |
| 11 | + const fsName = 'node:fs'; |
| 12 | + const fs = (await import(/* @vite-ignore */ fsName)) as { |
| 13 | + readFileSync(path: string, encoding: 'utf8'): string; |
| 14 | + readdirSync(path: string): string[]; |
| 15 | + }; |
| 16 | + const files = fs.readdirSync(PAGES).filter((file) => file.endsWith('.ts')); |
| 17 | + return new Map(files.map((file) => [file, fs.readFileSync(`${PAGES}${file}`, 'utf8')])); |
| 18 | +} |
| 19 | + |
| 20 | +describe('every page uses the shared search field', () => { |
| 21 | + it('has no hand-written search input left in a page', async () => { |
| 22 | + const raw = [...(await pageSources())] |
| 23 | + .filter(([, source]) => /type="search"/.test(source)) |
| 24 | + .map(([file]) => file); |
| 25 | + expect(raw).toEqual([]); |
| 26 | + }); |
| 27 | + |
| 28 | + it('names no field anything other than Filter, except a second field on the same page', async () => { |
| 29 | + const labels = [...(await pageSources())].flatMap(([file, source]) => |
| 30 | + [...source.matchAll(/<app-search-field[^>]*?\blabel="([^"]+)"/gs)].map( |
| 31 | + (match) => `${file}: ${match[1]}`, |
| 32 | + ), |
| 33 | + ); |
| 34 | + // The values filter sits under the component filter in the Components detail panel. |
| 35 | + expect(labels).toEqual(['component-tree.ts: Filter values']); |
| 36 | + }); |
| 37 | + |
| 38 | + it('uses Filter, not Find, in every placeholder', async () => { |
| 39 | + const placeholders = [...(await pageSources()).values()].flatMap((source) => |
| 40 | + [...source.matchAll(/<app-search-field[^>]*?\bplaceholder="([^"]+)"/gs)].map( |
| 41 | + (match) => match[1]!, |
| 42 | + ), |
| 43 | + ); |
| 44 | + expect(placeholders.length).toBeGreaterThan(15); |
| 45 | + for (const placeholder of placeholders) { |
| 46 | + expect(placeholder).toMatch(/^Filter\b/); |
| 47 | + expect(placeholder).not.toMatch(/…$/); |
| 48 | + } |
| 49 | + }); |
| 50 | +}); |
| 51 | + |
| 52 | +describe('pages with a splitter', () => { |
| 53 | + it('size the injector detail and the store change list from a saved width', async () => { |
| 54 | + const sources = await pageSources(); |
| 55 | + const page = (name: string) => sources.get(name) ?? ''; |
| 56 | + expect(page('di-inspector.ts')).toMatch(/<app-splitter[^>]*view="injectors"/s); |
| 57 | + expect(page('di-inspector.ts')).toContain("storedPaneSize('injectors', 420)"); |
| 58 | + expect(page('store-inspector.ts')).toMatch( |
| 59 | + /<app-splitter[^>]*view="store-log"[^>]*pane="before"/s, |
| 60 | + ); |
| 61 | + expect(page('store-inspector.ts')).toContain("storedPaneSize('store-log', 300)"); |
| 62 | + }); |
| 63 | +}); |
0 commit comments