import { describe, it } from 'node:test'; import { strict as assert } from 'node:assert'; // Import the config - defineConfig is a passthrough so this works const configModule = await import('../astro.config.mjs'); const config = configModule.default; describe('workbenchTheme in astro.config.mjs', () => { it('should have markdown.shikiConfig.theme defined', () => { assert.ok(config.markdown, 'config.markdown should exist'); assert.ok(config.markdown.shikiConfig, 'config.markdown.shikiConfig should exist'); assert.ok(config.markdown.shikiConfig.theme, 'config.markdown.shikiConfig.theme should exist'); }); it('should have theme name "workbench" and type "light"', () => { const theme = config.markdown.shikiConfig.theme; assert.equal(theme.name, 'workbench'); assert.equal(theme.type, 'light'); }); it('should have correct editor colors', () => { const theme = config.markdown.shikiConfig.theme; assert.ok(theme.colors, 'theme.colors should exist'); assert.equal(theme.colors['editor.background'], '#EEEAE2'); assert.equal(theme.colors['editor.foreground'], '#3D342E'); }); it('should have exactly 13 tokenColor scopes', () => { const theme = config.markdown.shikiConfig.theme; assert.ok(Array.isArray(theme.tokenColors), 'tokenColors should be an array'); assert.equal(theme.tokenColors.length, 13); }); // Helper to find a tokenColor entry by matching a scope string function findTokenColor(theme, scopeSubstring) { return theme.tokenColors.find((tc) => { const scopes = Array.isArray(tc.scope) ? tc.scope : [tc.scope]; return scopes.some((s) => s.includes(scopeSubstring)); }); } it('should style comments as #948880 italic', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'comment'); assert.ok(tc, 'comments tokenColor should exist'); assert.equal(tc.settings.foreground, '#948880'); assert.equal(tc.settings.fontStyle, 'italic'); }); it('should style keywords/storage/control as #A0522D (terracotta)', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'keyword'); assert.ok(tc, 'keywords tokenColor should exist'); assert.equal(tc.settings.foreground, '#A0522D'); // Verify scope includes storage and control const scopes = Array.isArray(tc.scope) ? tc.scope : [tc.scope]; const hasStorage = scopes.some((s) => s.includes('storage')); const hasControl = scopes.some((s) => s.includes('control')); assert.ok(hasStorage, 'keywords scope should include storage'); assert.ok(hasControl, 'keywords scope should include control'); }); it('should style strings/templates as #7D6C2F (tarnished brass)', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'string'); assert.ok(tc, 'strings tokenColor should exist'); assert.equal(tc.settings.foreground, '#7D6C2F'); }); it('should style constants as #7D6C2F', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'constant'); assert.ok(tc, 'constants tokenColor should exist'); assert.equal(tc.settings.foreground, '#7D6C2F'); }); it('should style functions as #2B2421 bold', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'entity.name.function'); assert.ok(tc, 'functions tokenColor should exist'); assert.equal(tc.settings.foreground, '#2B2421'); assert.equal(tc.settings.fontStyle, 'bold'); }); it('should style types/classes as #B07051', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'entity.name.type'); assert.ok(tc, 'types/classes tokenColor should exist'); assert.equal(tc.settings.foreground, '#B07051'); }); it('should style variables as #3D342E', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'variable'); assert.ok(tc, 'variables tokenColor should exist'); assert.equal(tc.settings.foreground, '#3D342E'); }); it('should style punctuation as #6B5F55', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'punctuation'); assert.ok(tc, 'punctuation tokenColor should exist'); assert.equal(tc.settings.foreground, '#6B5F55'); }); it('should style HTML tags as #A0522D', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'entity.name.tag'); assert.ok(tc, 'HTML tags tokenColor should exist'); assert.equal(tc.settings.foreground, '#A0522D'); }); it('should style HTML attributes as #7D6C2F', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'entity.other.attribute-name'); assert.ok(tc, 'HTML attributes tokenColor should exist'); assert.equal(tc.settings.foreground, '#7D6C2F'); }); it('should style property names as #2B2421', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'support.type.property-name'); assert.ok(tc, 'property names tokenColor should exist'); assert.equal(tc.settings.foreground, '#2B2421'); }); it('should style operators as #6B5F55', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'keyword.operator'); assert.ok(tc, 'operators tokenColor should exist'); assert.equal(tc.settings.foreground, '#6B5F55'); }); it('should style imports/exports as #A0522D', () => { const theme = config.markdown.shikiConfig.theme; const tc = findTokenColor(theme, 'keyword.control.import'); assert.ok(tc, 'imports/exports tokenColor should exist'); assert.equal(tc.settings.foreground, '#A0522D'); }); it('should preserve site config', () => { assert.equal(config.site, 'https://crashtestdev.com'); }); it('should include mdx integration', () => { assert.ok(config.integrations, 'integrations should exist'); const hasMdx = config.integrations.some( (i) => i.name === '@astrojs/mdx' ); assert.ok(hasMdx, 'mdx integration should be present'); }); });