fleeting-garden/src/index.dom-contract.test.ts
Andras Schmelczer 2347ecd201
Some checks failed
Deploy to Pages / build (pull_request) Failing after 3m15s
.
2026-05-13 22:13:15 +01:00

65 lines
2.1 KiB
TypeScript

import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { describe, expect, it } from 'vitest';
const projectRoot = process.cwd();
const indexSource = readFileSync(join(projectRoot, 'src/index.ts'), 'utf8');
const html = readFileSync(join(projectRoot, 'index.html'), 'utf8');
const escapeRegex = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const hasClass = (className: string, tagName?: string) => {
const tagPattern = tagName ? `<${tagName}\\b[^>]*` : '<[a-z][^>]*';
return new RegExp(
`${tagPattern}class="[^"]*\\b${escapeRegex(className)}\\b[^"]*"`,
'i'
).test(html);
};
const hasId = (id: string) => new RegExp(`\\bid="${escapeRegex(id)}"`, 'i').test(html);
const hasTag = (tagName: string) =>
new RegExp(`<${escapeRegex(tagName)}(?:\\s|>|/)`, 'i').test(html);
const selectorExists = (selector: string) => {
const idSelector = /^#(?<id>[\w-]+)$/.exec(selector);
if (idSelector?.groups?.id) {
return hasId(idSelector.groups.id);
}
const classSelector = /^\.([\w-]+)$/.exec(selector);
if (classSelector?.[1]) {
return hasClass(classSelector[1]);
}
const tagClassSelector = /^(?<tagName>[a-z]+)\.(?<className>[\w-]+)$/.exec(selector);
if (tagClassSelector?.groups) {
return hasClass(tagClassSelector.groups.className, tagClassSelector.groups.tagName);
}
if (/^[a-z]+$/.test(selector)) {
return hasTag(selector);
}
throw new Error(`Unsupported selector contract syntax: ${selector}`);
};
describe('index DOM selector contract', () => {
it('keeps every boot-time required selector target present in index.html', () => {
const selectors = Array.from(
indexSource.matchAll(/queryRequiredElements?\(\s*'([^']+)'\s*,/g),
(match) => match[1]
);
expect(selectors.length).toBeGreaterThan(0);
expect(selectors.filter((selector) => !selectorExists(selector))).toEqual([]);
});
it('keeps the three color swatches expected by the palette UI', () => {
const colorSwatchCount = Array.from(
html.matchAll(/class="[^"]*\bcolor-swatch\b[^"]*"/g)
).length;
expect(colorSwatchCount).toBe(3);
});
});