import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pluriwave/tema/pluriwave_theme.dart'; import 'package:pluriwave/tema/pluriwave_typography.dart'; /// Design ADR-1: the named type scale is a second ThemeExtension, closed at /// six styles. Pins the documented size/weight/letter-spacing per style and /// confirms PluriWaveTheme.dark() registers it, mirroring how /// PluriWaveTokens/PluriWaveMotion are already tested. /// /// PluriWaveTheme.dark() is only ever resolved from inside a testWidgets /// callback (never from setUpAll or a plain test()). GoogleFonts. /// plusJakartaSansTextTheme fires a background network fetch per text role; /// TestWidgetsFlutterBinding only installs its HTTP-blocking override /// inside an active test-widgets zone, so calling PluriWaveTheme.dark() /// outside one lets a real (and here unreachable) network request escape /// and fail asynchronously. The numeric values asserted below (fontSize/ /// weight/letterSpacing/height) are set synchronously by /// PluriWaveTypography.from regardless of that background fetch's outcome. void main() { late PluriWaveTypography type; group('PluriWaveTypography', () { testWidgets('PluriWaveTheme.dark() registers the extension', ( tester, ) async { final theme = PluriWaveTheme.dark(); final extension = theme.extension(); expect(extension, isNotNull); type = extension!; }); test('heroTime is 88 / w800 / height 1.0 / letter-spacing -2.0', () { expect(type.heroTime.fontSize, 88); expect(type.heroTime.fontWeight, FontWeight.w800); expect(type.heroTime.height, 1.0); expect(type.heroTime.letterSpacing, -2.0); }); test('sectionTitle is 23 / w800 / letter-spacing -0.6', () { expect(type.sectionTitle.fontSize, 23); expect(type.sectionTitle.fontWeight, FontWeight.w800); expect(type.sectionTitle.letterSpacing, -0.6); }); test('screenTitle is 19 / w800 / letter-spacing -0.4', () { expect(type.screenTitle.fontSize, 19); expect(type.screenTitle.fontWeight, FontWeight.w800); expect(type.screenTitle.letterSpacing, -0.4); }); test('cardTitle is 14.5 / w700', () { expect(type.cardTitle.fontSize, 14.5); expect(type.cardTitle.fontWeight, FontWeight.w700); }); test('bodyStrong is 13 / w600', () { expect(type.bodyStrong.fontSize, 13); expect(type.bodyStrong.fontWeight, FontWeight.w600); }); test('eyebrowLabel is 11 / w800 / letter-spacing 0.8', () { expect(type.eyebrowLabel.fontSize, 11); expect(type.eyebrowLabel.fontWeight, FontWeight.w800); expect(type.eyebrowLabel.letterSpacing, 0.8); }); test( 'S7 (visual fidelity): inPageSectionHeading is 15 / w800 / ' 'letter-spacing -0.2 -- the ADR-1 amendment adding a seventh style', () { expect( type.inPageSectionHeading.fontSize, 15, reason: 'prototype t4 lines 80, 153, 164, 173', ); expect(type.inPageSectionHeading.fontWeight, FontWeight.w800); expect(type.inPageSectionHeading.letterSpacing, -0.2); }, ); test('S9 (Tier 1 visual fidelity): eyebrowLabel bakes in the prototype ' "colour rgba(242,247,250,.42) — it used to carry no colour at all, " 'so it rendered at full onSurface opacity', () { expect( type.eyebrowLabel.color, const Color(0xFFF2F7FA).withValues(alpha: 0.42), ); }); testWidgets('context.pluriType exposes the registered extension', ( tester, ) async { late BuildContext capturedContext; await tester.pumpWidget( MaterialApp( theme: PluriWaveTheme.dark(), home: Builder( builder: (context) { capturedContext = context; return const SizedBox.shrink(); }, ), ), ); expect(capturedContext.pluriType.cardTitle.fontSize, 14.5); }); }); }