diff --git a/tests/longevity/pagine.test.ts b/tests/longevity/pagine.test.ts index 5608a53..399c048 100644 --- a/tests/longevity/pagine.test.ts +++ b/tests/longevity/pagine.test.ts @@ -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['"`]/); }); });