164 lines
4.6 KiB
Dart
164 lines
4.6 KiB
Dart
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<PlanetNode> 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<void> loadAppFonts() async {
|
||
final manifest =
|
||
json.decode(await rootBundle.loadString('FontManifest.json')) as List;
|
||
for (final font in manifest.cast<Map<String, dynamic>>()) {
|
||
final loader = FontLoader(font['family'] as String);
|
||
for (final f in (font['fonts'] as List).cast<Map<String, dynamic>>()) {
|
||
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());
|
||
});
|
||
});
|
||
}
|
||
}
|