96 lines
3.5 KiB
Dart
96 lines
3.5 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:fancake/core/data/planet_visual_state.dart';
|
|
import 'package:fancake/features/galaxy/galaxy_data.dart';
|
|
import 'package:fancake/features/galaxy/galaxy_motion.dart';
|
|
import 'package:fancake/features/galaxy/galaxy_screen.dart';
|
|
import 'package:fancake/features/galaxy/widgets/galaxy_field.dart';
|
|
import 'package:fancake/features/planet/planet_data.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'eclipse_stubs.dart';
|
|
|
|
void main() {
|
|
test('상태별 표류는 점진적으로 변하고 사용자 드래그는 유지된다', () {
|
|
final clock = GalaxyClock();
|
|
addTearDown(clock.dispose);
|
|
for (final scale in [0.25, 0.5, 1.5, 1.0]) {
|
|
final before = clock.velocity;
|
|
clock.idleSpeedScale = scale;
|
|
clock.advance(1 / 60);
|
|
final target = GalaxyMotion.idleSpin * scale;
|
|
expect(
|
|
clock.velocity,
|
|
inExclusiveRange(
|
|
before < target ? before : target,
|
|
before > target ? before : target,
|
|
),
|
|
);
|
|
for (var i = 0; i < 600; i++) {
|
|
clock.advance(1 / 60);
|
|
}
|
|
expect(clock.velocity, closeTo(target, 1e-6));
|
|
}
|
|
clock.idleSpeedScale = 0.25;
|
|
clock.drag(10);
|
|
clock.advance(1 / 60);
|
|
expect(clock.velocity, closeTo(10 * 60 * GalaxyMotion.dragSpinGain, 1e-9));
|
|
});
|
|
|
|
testWidgets('선택 행성의 서버 상태만 주변 궤도에 적용하고 Reduce Motion은 정지한다', (tester) async {
|
|
final streams = <String, StreamController<PlanetVisualState>>{};
|
|
Stream<PlanetVisualState> watch(String id) => streams
|
|
.putIfAbsent(id, () => StreamController<PlanetVisualState>.broadcast())
|
|
.stream;
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: GalaxyScreen(
|
|
repository: const SampleGalaxyRepository(),
|
|
planetRepository: samplePlanetRepository,
|
|
eclipse: const NoEclipseRepository(),
|
|
watchPlanet: watch,
|
|
),
|
|
),
|
|
);
|
|
await tester.pump();
|
|
await tester.pump();
|
|
final clock = tester
|
|
.widgetList<AnimatedBuilder>(find.byType(AnimatedBuilder))
|
|
.map((w) => w.listenable)
|
|
.whereType<GalaxyClock>()
|
|
.first;
|
|
GalaxyField field() => tester.widget<GalaxyField>(find.byType(GalaxyField));
|
|
final mine = field().planets.firstWhere((p) => p.isMine);
|
|
for (final entry in [
|
|
(const PlanetVisualState(isHeroTime: true), 1.5),
|
|
(const PlanetVisualState(isHeroTime: true, isEclipsed: true), 0.5),
|
|
(const PlanetVisualState(isHeroTime: true, isHibernating: true), 0.25),
|
|
(const PlanetVisualState(), 1.0),
|
|
]) {
|
|
streams[mine.id]!.add(entry.$1);
|
|
await tester.pump();
|
|
expect(clock.idleSpeedScale, entry.$2);
|
|
}
|
|
final other = field().planets.firstWhere((p) => !p.isMine);
|
|
field().onSelect(other);
|
|
await tester.pump();
|
|
streams[mine.id]!.add(const PlanetVisualState(isHibernating: true));
|
|
streams[other.id]!.add(const PlanetVisualState(isHeroTime: true));
|
|
await tester.pump();
|
|
expect(clock.idleSpeedScale, 1.5);
|
|
tester.platformDispatcher.accessibilityFeaturesTestValue =
|
|
const FakeAccessibilityFeatures(disableAnimations: true);
|
|
addTearDown(tester.platformDispatcher.clearAccessibilityFeaturesTestValue);
|
|
await tester.pump();
|
|
final spin = clock.spin;
|
|
await tester.pump(const Duration(seconds: 1));
|
|
expect(clock.spin, spin);
|
|
await tester.pumpWidget(const SizedBox());
|
|
for (final stream in streams.values) {
|
|
expect(stream.hasListener, isFalse);
|
|
await stream.close();
|
|
}
|
|
});
|
|
}
|