import 'package:flutter_test/flutter_test.dart'; import 'package:ar_autopilot_display/theme/theme_registry.dart'; void main() { group('ThemeRegistry — factory themes', () { test('exposes exactly 4 factory themes', () { expect(ThemeRegistry.all.length, 4); }); test('factory theme ids are light, cyan, wine, ochre', () { final ids = ThemeRegistry.all.map((t) => t.id).toList(); expect(ids, containsAll(['light', 'cyan', 'wine', 'ochre'])); }); test('display order is light → cyan → wine → ochre', () { final ids = ThemeRegistry.all.map((t) => t.id).toList(); expect(ids, ['light', 'cyan', 'wine', 'ochre']); }); test('all themes have non-empty id and displayName', () { for (final t in ThemeRegistry.all) { expect(t.id, isNotEmpty, reason: 'id must not be empty'); expect(t.displayName, isNotEmpty, reason: 'displayName must not be empty'); } }); group('byId', () { test('returns correct theme for each known id', () { for (final t in ThemeRegistry.all) { final found = ThemeRegistry.byId(t.id); expect(found.id, t.id, reason: 'byId("${t.id}") should return that theme'); } }); test('falls back to default (cyan) for unknown id', () { expect(ThemeRegistry.byId('does_not_exist').id, ThemeRegistry.defaultId); expect(ThemeRegistry.byId('').id, ThemeRegistry.defaultId); }); }); test('default id is cyan', () { expect(ThemeRegistry.defaultId, 'cyan'); }); test('contains() returns true for factory ids', () { for (final t in ThemeRegistry.all) { expect(ThemeRegistry.contains(t.id), isTrue); } }); test('contains() returns false for unknown id', () { expect(ThemeRegistry.contains('unknown_xyz'), isFalse); }); group('Token completeness — no null colours', () { for (final t in ThemeRegistry.all) { test('${t.id}: all Color tokens are non-null', () { // Backgrounds expect(t.background, isNotNull, reason: '${t.id}.background'); expect(t.backgroundMid, isNotNull, reason: '${t.id}.backgroundMid'); expect(t.backgroundDeep, isNotNull, reason: '${t.id}.backgroundDeep'); expect(t.backgroundDeepest, isNotNull, reason: '${t.id}.backgroundDeepest'); expect(t.panelBackground, isNotNull, reason: '${t.id}.panelBackground'); expect(t.panelBorder, isNotNull, reason: '${t.id}.panelBorder'); // Text expect(t.textMain, isNotNull, reason: '${t.id}.textMain'); expect(t.textMuted, isNotNull, reason: '${t.id}.textMuted'); expect(t.textSoft, isNotNull, reason: '${t.id}.textSoft'); expect(t.textDisabled, isNotNull, reason: '${t.id}.textDisabled'); // Accent expect(t.accentLight, isNotNull, reason: '${t.id}.accentLight'); expect(t.accentMid, isNotNull, reason: '${t.id}.accentMid'); expect(t.accentDark, isNotNull, reason: '${t.id}.accentDark'); expect(t.accentGlowColor, isNotNull, reason: '${t.id}.accentGlowColor'); // Set-point expect(t.setLight, isNotNull, reason: '${t.id}.setLight'); expect(t.setDark, isNotNull, reason: '${t.id}.setDark'); expect(t.setGlow, isNotNull, reason: '${t.id}.setGlow'); // Semantic expect(t.okColor, isNotNull, reason: '${t.id}.okColor'); expect(t.warnColor, isNotNull, reason: '${t.id}.warnColor'); expect(t.northColor, isNotNull, reason: '${t.id}.northColor'); // Disengage expect(t.disengageBackground, isNotNull, reason: '${t.id}.disengageBackground'); expect(t.disengageText, isNotNull, reason: '${t.id}.disengageText'); expect(t.disengageBorder, isNotNull, reason: '${t.id}.disengageBorder'); expect(t.disengageGlow, isNotNull, reason: '${t.id}.disengageGlow'); // Action buttons expect(t.actionButtonBackground, isNotNull, reason: '${t.id}.actionButtonBackground'); expect(t.actionButtonBorder, isNotNull, reason: '${t.id}.actionButtonBorder'); expect(t.actionButtonText, isNotNull, reason: '${t.id}.actionButtonText'); expect(t.actionButtonGlow, isNotNull, reason: '${t.id}.actionButtonGlow'); }); } }); group('Glow rules', () { test('light theme has accentGlowRadius == 0 (no glow in daytime)', () { expect(ThemeRegistry.byId('light').accentGlowRadius, 0.0); }); test('dark themes have accentGlowRadius > 0', () { for (final id in ['cyan', 'wine', 'ochre']) { expect( ThemeRegistry.byId(id).accentGlowRadius, greaterThan(0), reason: '$id should have glow', ); } }); }); group('Background gradient rules', () { test('light theme has no backgroundGradient (solid colour)', () { expect(ThemeRegistry.byId('light').backgroundGradient, isNull); }); test('dark themes have a backgroundGradient', () { for (final id in ['cyan', 'wine', 'ochre']) { expect( ThemeRegistry.byId(id).backgroundGradient, isNotNull, reason: '$id should have a radial background gradient', ); } }); }); }); }