/** * Verification test for Design Tokens CSS (Task 2) * * Checks that: * 1. src/styles/tokens.css exists * 2. Contains :root block with all token categories * 3. Has ~60-70 CSS custom properties * 4. Includes reduced motion media query * 5. All expected token categories are present */ import { readFileSync, existsSync } from 'fs'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const root = join(__dirname, '..'); let passed = 0; let failed = 0; function assert(condition, message) { if (condition) { console.log(` ✓ ${message}`); passed++; } else { console.error(` ✗ ${message}`); failed++; } } function readText(path) { return readFileSync(path, 'utf8'); } const tokensPath = join(root, 'src/styles/tokens.css'); // === 1. File exists === console.log('\n1. tokens.css exists'); assert(existsSync(tokensPath), 'src/styles/tokens.css exists'); if (!existsSync(tokensPath)) { console.log('\nFile not found, skipping remaining tests.'); console.log(`\n${'='.repeat(40)}`); console.log(`Results: ${passed} passed, ${failed} failed out of ${passed + failed}`); process.exit(1); } const css = readText(tokensPath); // === 2. Contains :root block === console.log('\n2. :root block'); assert(css.includes(':root {'), 'contains :root { block'); // === 3. Token count ~60-70 === console.log('\n3. Custom property count'); const propertyMatches = css.match(/--[\w-]+\s*:/g); const totalProps = propertyMatches ? propertyMatches.length : 0; // Inside :root only (exclude media query overrides) const rootBlock = css.match(/:root\s*\{([^}]*)\}/); const rootContent = rootBlock ? rootBlock[1] : ''; const rootProps = rootContent.match(/--[\w-]+\s*:/g); const rootPropCount = rootProps ? rootProps.length : 0; assert(rootPropCount >= 55 && rootPropCount <= 75, `root has ~60-70 custom properties (found ${rootPropCount})`); // === 4. Surface tokens === console.log('\n4. Surface tokens'); assert(css.includes('--surface-base: #F5F0E8'), '--surface-base: #F5F0E8'); assert(css.includes('--surface-card: #FEFCF7'), '--surface-card: #FEFCF7'); assert(css.includes('--surface-code: #EEEAE2'), '--surface-code: #EEEAE2'); assert(css.includes('--surface-inset: #E8E3DA'), '--surface-inset: #E8E3DA'); // === 5. Text tokens === console.log('\n5. Text tokens'); assert(css.includes('--text-primary: #2B2421'), '--text-primary'); assert(css.includes('--text-secondary: #6B5F55'), '--text-secondary'); assert(css.includes('--text-tertiary: #948880'), '--text-tertiary'); // === 6. Accent tokens === console.log('\n6. Accent tokens'); assert(css.includes('--accent-primary: #A0522D'), '--accent-primary'); assert(css.includes('--accent-primary-hover: #8B4726'), '--accent-primary-hover'); assert(css.includes('--accent-secondary: #7D6C2F'), '--accent-secondary'); assert(css.includes('--accent-secondary-hover: #6B5C28'), '--accent-secondary-hover'); // === 7. Code token === console.log('\n7. Code token'); assert(css.includes('--code-text: #3D342E'), '--code-text'); // === 8. Border tokens === console.log('\n8. Border tokens'); assert(css.includes('--border-subtle: #DDD7CD'), '--border-subtle'); assert(css.includes('--border-default: #C2BAA9'), '--border-default'); assert(css.includes('--border-strong: #8E857A'), '--border-strong'); // === 9. Focus token === console.log('\n9. Focus token'); assert(css.includes('--focus-ring: #A0522D'), '--focus-ring'); // === 10. State tokens === console.log('\n10. State tokens'); assert(css.includes('--success-bg:'), 'success-bg'); assert(css.includes('--success-text:'), 'success-text'); assert(css.includes('--success-border:'), 'success-border'); assert(css.includes('--warning-bg:'), 'warning-bg'); assert(css.includes('--warning-text:'), 'warning-text'); assert(css.includes('--warning-border:'), 'warning-border'); assert(css.includes('--error-bg:'), 'error-bg'); assert(css.includes('--error-text:'), 'error-text'); assert(css.includes('--error-border:'), 'error-border'); assert(css.includes('--info-bg:'), 'info-bg'); assert(css.includes('--info-text:'), 'info-text'); assert(css.includes('--info-border:'), 'info-border'); // === 11. Shadow tokens === console.log('\n11. Shadow tokens'); assert(css.includes('--shadow-sm:'), '--shadow-sm'); assert(css.includes('--shadow-md:'), '--shadow-md'); // === 12. Typography family tokens === console.log('\n12. Typography family tokens'); assert(css.includes('--font-prose:') && css.includes('Source Serif 4'), '--font-prose with Source Serif 4'); assert(css.includes('--font-structure:') && css.includes('Inter'), '--font-structure with Inter'); assert(css.includes('--font-evidence:') && css.includes('JetBrains Mono'), '--font-evidence with JetBrains Mono'); // === 13. Spacing tokens === console.log('\n13. Spacing tokens'); assert(css.includes('--space-0:'), '--space-0'); assert(css.includes('--space-1:'), '--space-1'); assert(css.includes('--space-4:'), '--space-4'); assert(css.includes('--space-12:'), '--space-12'); // === 14. Border radius tokens === console.log('\n14. Border radius tokens'); assert(css.includes('--rounded-none:'), '--rounded-none'); assert(css.includes('--rounded-sm:'), '--rounded-sm'); assert(css.includes('--rounded-full:'), '--rounded-full'); // === 15. Layout tokens === console.log('\n15. Layout tokens'); assert(css.includes('--width-prose: 45rem'), '--width-prose'); assert(css.includes('--width-code: 52.5rem'), '--width-code'); assert(css.includes('--width-container: 68.75rem'), '--width-container'); assert(css.includes('--gutter: 1.5rem'), '--gutter'); // === 16. Motion tokens === console.log('\n16. Motion tokens'); assert(css.includes('--duration-fast:'), '--duration-fast'); assert(css.includes('--duration-normal:'), '--duration-normal'); assert(css.includes('--duration-slow:'), '--duration-slow'); assert(css.includes('--ease-default:'), '--ease-default'); assert(css.includes('--ease-in-out:'), '--ease-in-out'); // === 17. Reduced motion media query === console.log('\n17. Reduced motion media query'); assert(css.includes('prefers-reduced-motion: reduce'), 'has prefers-reduced-motion media query'); assert(css.includes('--duration-fast: 0ms'), 'duration-fast zeroed in reduced motion'); assert(css.includes('--duration-normal: 0ms'), 'duration-normal zeroed in reduced motion'); assert(css.includes('--duration-slow: 0ms'), 'duration-slow zeroed in reduced motion'); // === Summary === console.log(`\n${'='.repeat(40)}`); console.log(`Results: ${passed} passed, ${failed} failed out of ${passed + failed}`); if (failed > 0) { process.exit(1); } else { console.log('All token verification tests passed!'); }