longevity: test anti-semaforo strutturale (colori ammessi, non nomi vietati) e rotta verificata sul contenuto
This commit is contained in:
@@ -18,7 +18,8 @@ describe('il guscio della piattaforma', () => {
|
||||
const css = leggi('src/styles/longevity.css');
|
||||
const classi = [...css.matchAll(/^\.([a-z-]+)/gm)].map((m) => m[1]);
|
||||
expect(classi.length).toBeGreaterThan(3);
|
||||
expect(classi.every((c) => c.startsWith('lg'))).toBe(true);
|
||||
// "lg" da solo o "lg-qualcosa": il solo startsWith('lg') lascerebbe passare anche "lgfoo".
|
||||
expect(classi.every((c) => c === 'lg' || c.startsWith('lg-'))).toBe(true);
|
||||
});
|
||||
|
||||
it('usa i token del sito invece di inventare colori', () => {
|
||||
@@ -26,13 +27,52 @@ describe('il guscio della piattaforma', () => {
|
||||
expect(css).toMatch(/var\(--c-/);
|
||||
});
|
||||
|
||||
it('nessun semaforo sui punteggi: il colore non giudica il corpo', () => {
|
||||
it('nessuna variabile porta un nome da semaforo (verde/buono/ok)', () => {
|
||||
const css = leggi('src/styles/longevity.css').toLowerCase();
|
||||
// il mattone del fuori range e ammesso; un verde "tutto bene" no
|
||||
expect(css).not.toMatch(/--lg-ok|--lg-buono|--lg-verde/);
|
||||
});
|
||||
|
||||
it('la rotta del cliente e sotto /longevity, dove le regole la proteggono', () => {
|
||||
expect(existsSync(join(process.cwd(), 'src/pages/longevity/index.astro'))).toBe(true);
|
||||
it("nelle regole di un punteggio compaiono solo i colori ammessi: l'accento, il tratteggio, il fuori range", () => {
|
||||
// Il test sopra cerca nomi vietati: chi scrivesse un verde in esadecimale, o lo
|
||||
// chiamasse con un nome innocuo (var(--lg-buona-salute)), passerebbe indisturbato.
|
||||
// Qui si fa il contrario: si elenca ciò che PUò comparire in una regola che riguarda
|
||||
// un punteggio (selettore con "lg-score"), e qualunque altro colore — letterale
|
||||
// (esadecimale, rgb(), nome CSS) o var() con un altro nome — è una regressione.
|
||||
const css = leggi('src/styles/longevity.css');
|
||||
const AMMESSI = new Set([
|
||||
'--c-accent', '--c-accent-dark', // l'accento del sito: l'unica leva per l'intensità
|
||||
'--c-heading', '--c-text', '--c-text-light', // testo neutro, uguale ovunque nel sito
|
||||
'--c-bg', '--c-bg-alt', // sfondi neutri
|
||||
'--lg-line', '--lg-surface', // struttura locale, neutra
|
||||
'--lg-tratteggio', // il perimetro di ciò che non sappiamo
|
||||
'--lg-fuori-range', // SOLO una misura sospetta, mai un punteggio
|
||||
]);
|
||||
const NON_COLORE = /^(transparent|inherit|initial|unset|currentcolor|none)$/i;
|
||||
const PROP_COLORE = /^(color|background|background-color|border(-\w+)?-color|outline-color|fill|stroke)$/i;
|
||||
|
||||
const violazioni: string[] = [];
|
||||
for (const regola of css.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
|
||||
const selettore = regola[1].trim();
|
||||
if (!/lg-score/i.test(selettore)) continue; // solo le regole che riguardano un punteggio
|
||||
for (const dich of regola[2].split(';')) {
|
||||
const due = dich.indexOf(':');
|
||||
if (due < 0) continue;
|
||||
const prop = dich.slice(0, due).trim().toLowerCase();
|
||||
const val = dich.slice(due + 1).trim();
|
||||
if (!PROP_COLORE.test(prop) || val === '' || NON_COLORE.test(val)) continue;
|
||||
const varMatch = val.match(/^var\(\s*(--[a-z0-9-]+)\s*(?:,.*)?\)$/i);
|
||||
if (varMatch && AMMESSI.has(varMatch[1])) continue;
|
||||
violazioni.push(`${selettore} { ${prop}: ${val} }`);
|
||||
}
|
||||
}
|
||||
expect(violazioni).toEqual([]);
|
||||
});
|
||||
|
||||
it('la rotta del cliente e sotto /longevity, e rimanda davvero al referto', () => {
|
||||
const p = join(process.cwd(), 'src/pages/longevity/index.astro');
|
||||
expect(existsSync(p)).toBe(true);
|
||||
const src = readFileSync(p, 'utf8');
|
||||
expect(src).toMatch(/Astro\.redirect\(\s*['"`]\/longevity\/io['"`]/);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user