import 'dart:convert'; import 'dart:io'; import 'dart:ui' as ui; import 'package:fancake/features/galaxy/galaxy_data.dart'; import 'package:fancake/features/galaxy/widgets/galaxy_mini_map.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; /// 프로토타입 v6.2 와 나란히 볼 미니맵 캡처. `MINIMAP_OUT=<폴더>` 일 때만 PNG 를 쓴다. /// MINIMAP_OUT=build/minimap fvm flutter test test/galaxy_mini_map_capture_test.dart /// 표본은 프로토타입 `FPI_DATA` 5행성 — 같은 데이터로 두 장면을 비교한다. const protoPlanets = [ PlanetNode( id: '1', name: 'NewJeans', rank: 1, fpi: 3200, members: 1, online: 4820, isMine: true, ), PlanetNode( id: '2', name: 'BTS', rank: 2, fpi: 2800, members: 1, online: 12540, ), PlanetNode( id: '3', name: 'aespa', rank: 3, fpi: 2100, members: 1, online: 3910, ), PlanetNode( id: '4', name: 'IVE', rank: 4, fpi: 1700, members: 1, online: 2840, ), PlanetNode( id: '5', name: 'PLAVE', rank: 5, fpi: 1300, members: 1, online: 5120, ), ]; /// 내 행성이 3위인 경우(C-103 — 1위가 아니어도 내 행성이 가운데). List mineAt(int rank) => [ for (final p in protoPlanets) PlanetNode( id: p.id, name: p.name, rank: p.rank, fpi: p.fpi, members: p.members, online: p.online, isMine: p.rank == rank, ), ]; /// 테스트 기본 글꼴(Ahem 네모) 대신 앱 글꼴로 글자 폭을 잰다. Future loadAppFonts() async { final manifest = json.decode(await rootBundle.loadString('FontManifest.json')) as List; for (final font in manifest.cast>()) { final loader = FontLoader(font['family'] as String); for (final f in (font['fonts'] as List).cast>()) { loader.addFont(rootBundle.load(Uri.decodeFull(f['asset'] as String))); } await loader.load(); } } void main() { final out = Platform.environment['MINIMAP_OUT']; if (out == null) return; setUpAll(() async { Directory(out).createSync(recursive: true); await loadAppFonts(); }); for (final (name, planets, size) in [ ('minimap-140-mine1', protoPlanets, 140.0), ('minimap-140-mine3', mineAt(3), 140.0), ('minimap-360-mine1', protoPlanets, 360.0), // Figma 「홈」(2097:16428) 실측 박스 약 93pt — C-105 140pt 와 비교용. ('after_93', protoPlanets, 93.0), ('after_93-mine3', mineAt(3), 93.0), ]) { testWidgets(name, (tester) async { final key = GlobalKey(); await tester.pumpWidget( MaterialApp( home: Center( child: RepaintBoundary( key: key, child: GalaxyMiniMap( data: GalaxySnapshot(planets: planets, myPop: 0), onOpen: () {}, size: size, ), ), ), ), ); await tester.pump(); await tester.runAsync(() async { final boundary = key.currentContext!.findRenderObject()! as RenderRepaintBoundary; final image = await boundary.toImage(pixelRatio: 3); final bytes = await image.toByteData(format: ui.ImageByteFormat.png); File('$out/$name.png').writeAsBytesSync(bytes!.buffer.asUint8List()); }); }); } // HOME 「GALAXY 맵 확장」(`343:211127`) — 히어로 안 맵 영역 375×556. for (final (name, planets) in [ ('expanded_v2_app_mine1', protoPlanets), ('expanded_v2_app_mine3', mineAt(3)), ]) { testWidgets(name, (tester) async { final key = GlobalKey(); await tester.pumpWidget( MaterialApp( home: Center( child: RepaintBoundary( key: key, child: SizedBox( width: 375, height: 556, child: GalaxyMiniMap.expanded( data: GalaxySnapshot(planets: planets, myPop: 0), onOpenPlanet: (_) {}, ), ), ), ), ), ); await tester.pump(); await tester.runAsync(() async { final boundary = key.currentContext!.findRenderObject()! as RenderRepaintBoundary; final image = await boundary.toImage(pixelRatio: 3); final bytes = await image.toByteData(format: ui.ImageByteFormat.png); File('$out/$name.png').writeAsBytesSync(bytes!.buffer.asUint8List()); }); }); } }