HOME 을 Figma 「홈」 구성으로 — TODAY'S QUEST · 미니맵·확장 맵(프로토타입 v6.2) · 행성 정보 박스 · 인큐베이터 · 아티스트 소식 · HOT ARCHIVE · 인기 K-INSIDE
This commit is contained in:
@@ -7,8 +7,10 @@ import 'package:fancake/core/data/planet_visual_state.dart';
|
||||
import 'package:fancake/core/theme/app_theme.dart';
|
||||
import 'package:fancake/core/ui/planet_25d.dart';
|
||||
import 'package:fancake/features/galaxy/galaxy_data.dart';
|
||||
import 'package:fancake/features/galaxy/galaxy_screen.dart';
|
||||
import 'package:fancake/features/galaxy/galaxy_search_screen.dart';
|
||||
import 'package:fancake/features/planet/planet_detail_screen.dart';
|
||||
import 'package:fancake/features/galaxy/widgets/galaxy_mini_map.dart';
|
||||
import 'package:fancake/features/galaxy/widgets/galaxy_web_view.dart';
|
||||
import 'package:fancake/features/home/home_data.dart';
|
||||
import 'package:fancake/features/home/home_screen.dart';
|
||||
import 'package:fancake/features/home/widgets/home_hero.dart';
|
||||
@@ -329,11 +331,12 @@ void main() {
|
||||
expect(micros, lessThan(paintBudgetMicros));
|
||||
});
|
||||
|
||||
testWidgets('HOME 미니맵은 같은 저장소의 Galaxy로 진입한다', (tester) async {
|
||||
Future<StreamController<PlanetVisualState>> pumpHome(
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
tester.view.physicalSize = const Size(1080, 2400);
|
||||
tester.view.devicePixelRatio = 3;
|
||||
addTearDown(tester.view.reset);
|
||||
const galaxy = SampleGalaxyRepository();
|
||||
final states = StreamController<PlanetVisualState>.broadcast();
|
||||
addTearDown(states.close);
|
||||
await tester.pumpWidget(
|
||||
@@ -343,7 +346,7 @@ void main() {
|
||||
repository: const SampleHomeRepository(),
|
||||
questRepository: const SampleQuestRepository(),
|
||||
eclipse: const NoEclipseRepository(),
|
||||
galaxyRepository: galaxy,
|
||||
galaxyRepository: const SampleGalaxyRepository(),
|
||||
planetRepository: samplePlanetRepository,
|
||||
watchPlanet: (_) => states.stream,
|
||||
),
|
||||
@@ -351,13 +354,26 @@ void main() {
|
||||
);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
return states;
|
||||
}
|
||||
|
||||
GalaxyMiniMapPainter expandedPainter(WidgetTester tester) => tester
|
||||
.widgetList<CustomPaint>(
|
||||
find.descendant(
|
||||
of: find.byType(HomeGalaxyHero),
|
||||
matching: find.byType(CustomPaint),
|
||||
),
|
||||
)
|
||||
.map((w) => w.painter)
|
||||
.whereType<GalaxyMiniMapPainter>()
|
||||
.single;
|
||||
|
||||
testWidgets('HOME 미니맵 자리 — Figma 「홈」 히어로 우측 상단', (tester) async {
|
||||
final states = await pumpHome(tester);
|
||||
final mini = find.byType(GalaxyMiniMap);
|
||||
expect(mini, findsOneWidget);
|
||||
// C-105 약 140pt · C-113 자리 = Figma 「홈」(2097:16428) 히어로 우측 상단 · 오른쪽 여백 0.
|
||||
expect(
|
||||
tester.getSize(mini),
|
||||
const Size.square(HomeHero.miniMapSize),
|
||||
);
|
||||
// C-113 자리 = Figma 「홈」(2097:16428) 히어로 우측 상단 · 오른쪽 여백 0.
|
||||
expect(tester.getSize(mini), const Size.square(HomeHero.miniMapSize));
|
||||
expect(
|
||||
tester.getTopRight(mini).dx,
|
||||
closeTo(tester.getSize(find.byType(HomeScreen)).width, 1),
|
||||
@@ -372,15 +388,162 @@ void main() {
|
||||
1,
|
||||
),
|
||||
);
|
||||
await tester.tap(mini);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(
|
||||
tester.widget<GalaxyScreen>(find.byType(GalaxyScreen)).repository,
|
||||
same(galaxy),
|
||||
);
|
||||
expect(tester.takeException(), isNull);
|
||||
await tester.pumpWidget(const SizedBox());
|
||||
expect(states.hasListener, isFalse);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'미니맵을 누르면 히어로가 「GALAXY 맵 확장」(343:211127)으로 바뀌고, GALAXY · 뒤로가기로 돌아온다',
|
||||
(tester) async {
|
||||
await pumpHome(tester);
|
||||
await tester.tap(find.byType(GalaxyMiniMap));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
expect(find.byType(HomeGalaxyHero), findsOneWidget);
|
||||
expect(find.byType(HomeHero), findsNothing);
|
||||
// 확장 맵 하나만 — 상단 미니맵은 사라진다. TODAY'S QUEST 등 아래 구획은 그대로.
|
||||
expect(find.byType(GalaxyMiniMap), findsOneWidget);
|
||||
expect(find.text('TODAY’S QUEST'), findsOneWidget);
|
||||
// 히어로 680 안 y124~680 = 맵(375×556), 아래 54 「GALAXY」 바.
|
||||
final map = find.byType(GalaxyMiniMap);
|
||||
expect(tester.getSize(map), const Size(360, 556)); // 시험 창 폭 360.
|
||||
expect(find.text('GALAXY'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byKey(const ValueKey('galaxy-bar-close')));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
expect(find.byType(HomeGalaxyHero), findsNothing);
|
||||
expect(find.byType(HomeHero), findsOneWidget);
|
||||
|
||||
await tester.tap(find.byType(GalaxyMiniMap));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
expect(find.byType(HomeGalaxyHero), findsOneWidget);
|
||||
await tester.binding.handlePopRoute();
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
expect(find.byType(HomeGalaxyHero), findsNothing);
|
||||
expect(find.byType(HomeScreen), findsOneWidget);
|
||||
expect(tester.takeException(), isNull);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('확장 맵 — 다른 행성을 누르면 그 행성이 화면 중심이 된다(2008:14486)', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Center(
|
||||
child: SizedBox(
|
||||
width: 375,
|
||||
height: 556,
|
||||
child: GalaxyMiniMap.expanded(
|
||||
data: _snap(_base),
|
||||
onOpenPlanet: (_) {},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
final painter = tester
|
||||
.widgetList<CustomPaint>(find.byType(CustomPaint))
|
||||
.map((w) => w.painter)
|
||||
.whereType<GalaxyMiniMapPainter>()
|
||||
.single;
|
||||
expect(painter.focusId, 'a');
|
||||
// Figma `343:211127` 축척 — HUD 카드는 고정 144×72, 줌과 무관.
|
||||
expect(painter.hudRectOf('a')!.size, GalaxyMiniMapPainter.figmaHud);
|
||||
painter.zoomTo(2);
|
||||
await tester.pump();
|
||||
expect(painter.hudRectOf('a')!.size, GalaxyMiniMapPainter.figmaHud);
|
||||
painter.zoomTo(1);
|
||||
await tester.pump();
|
||||
final origin = tester.getTopLeft(find.byType(GalaxyMiniMap));
|
||||
final at = painter.screenOf('b')!;
|
||||
expect(painter.hudRectOf('b')!.contains(at), isFalse);
|
||||
await tester.tapAt(origin + at);
|
||||
await tester.pump();
|
||||
expect(painter.focusId, 'b');
|
||||
// 카메라가 따라가 고른 행성이 가운데로 온다.
|
||||
await tester.pump(const Duration(seconds: 3));
|
||||
expect(painter.screenOf('b')!.dx, closeTo(375 / 2, 2));
|
||||
});
|
||||
|
||||
testWidgets('확장 맵 — 끌어 회전 · 핀치 줌 · HUD 탭 상세 · 돋보기 검색', (tester) async {
|
||||
await pumpHome(tester);
|
||||
await tester.tap(find.byType(GalaxyMiniMap));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
final painter = expandedPainter(tester);
|
||||
final map = find.byType(GalaxyMiniMap);
|
||||
final origin = tester.getTopLeft(map);
|
||||
expect(painter.focusId, isNotNull);
|
||||
|
||||
// 끌기 — 회전(±180° 한계).
|
||||
await tester.dragFrom(tester.getCenter(map), const Offset(2000, 0));
|
||||
await tester.pump(const Duration(seconds: 3));
|
||||
expect(painter.rotation, closeTo(math.pi, 0.05));
|
||||
|
||||
// 핀치 — 두 손가락 벌리기.
|
||||
final c = tester.getCenter(map);
|
||||
final a = await tester.startGesture(c - const Offset(40, 0));
|
||||
final b = await tester.startGesture(c + const Offset(40, 0));
|
||||
await a.moveBy(const Offset(-40, 0));
|
||||
await b.moveBy(const Offset(40, 0));
|
||||
await tester.pump();
|
||||
await a.up();
|
||||
await b.up();
|
||||
await tester.pump();
|
||||
expect(painter.zoom, greaterThan(1.2));
|
||||
|
||||
// HUD 탭 → 행성 상세.
|
||||
await tester.pump(const Duration(milliseconds: 16));
|
||||
final focus = painter.focusId!;
|
||||
final hud = painter.hudRectOf(focus)!;
|
||||
expect(hud.isEmpty, isFalse);
|
||||
await tester.tapAt(origin + hud.center);
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(find.byType(PlanetDetailScreen), findsOneWidget);
|
||||
Navigator.of(tester.element(find.byType(PlanetDetailScreen))).pop();
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
|
||||
// 돋보기 → 갤럭시 검색.
|
||||
await tester.tap(find.byIcon(Icons.search));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(find.byType(GalaxySearchScreen), findsOneWidget);
|
||||
});
|
||||
|
||||
test('WebView 로 넘기는 데이터 — FPI 상위 10 + 순위 밖 내 행성 · 실제 FPI · 색은 RGB 정수', () {
|
||||
final planets = [
|
||||
for (var i = 1; i <= 12; i++)
|
||||
PlanetNode(
|
||||
id: 'p$i',
|
||||
name: 'P$i',
|
||||
rank: i,
|
||||
fpi: 100000 - i,
|
||||
members: 1,
|
||||
online: i,
|
||||
isMine: i == 12,
|
||||
),
|
||||
];
|
||||
final list = GalaxyWebView.payload(_snap(planets));
|
||||
expect(list, hasLength(11));
|
||||
expect(list.first['fpi'], 99999);
|
||||
expect(list.last['id'], 'p12');
|
||||
expect(list.last['mine'], isTrue);
|
||||
expect(list.every((p) => (p['color']! as int) <= 0xFFFFFF), isTrue);
|
||||
});
|
||||
|
||||
testWidgets('미니맵 → 확장은 같은 지도 위젯 상태를 옮긴다(WebView 재생성 없음)', (tester) async {
|
||||
await pumpHome(tester);
|
||||
final before = tester.state(find.byType(GalaxyWebView));
|
||||
expect(tester.widget<GalaxyWebView>(find.byType(GalaxyWebView)).expanded, isFalse);
|
||||
await tester.tap(find.byType(GalaxyMiniMap));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
expect(tester.state(find.byType(GalaxyWebView)), same(before));
|
||||
expect(tester.widget<GalaxyWebView>(find.byType(GalaxyWebView)).expanded, isTrue);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user