import 'package:askiineverdie/src/core/engine/game_mutations.dart'; import 'package:askiineverdie/src/core/engine/progress_service.dart'; import 'package:askiineverdie/src/core/engine/reward_service.dart'; import 'package:askiineverdie/src/core/model/game_state.dart'; import 'package:askiineverdie/src/core/model/pq_config.dart'; import 'package:askiineverdie/src/core/util/pq_logic.dart' as pq_logic; import 'package:flutter_test/flutter_test.dart'; void main() { late ProgressService service; late PqConfig config; setUp(() { config = const PqConfig(); final mutations = GameMutations(config); service = ProgressService( config: config, mutations: mutations, rewards: RewardService(mutations), ); }); test('tick advances task bar and recalculates encumbrance', () { final state = GameState.withSeed( seed: 42, stats: const Stats( str: 5, con: 0, dex: 0, intelligence: 0, wis: 0, cha: 0, hpMax: 0, mpMax: 0, ), inventory: const Inventory( gold: 5, items: [InventoryEntry(name: 'Rock', count: 3)], ), progress: const ProgressState( task: ProgressBarState(position: 0, max: 80), quest: ProgressBarState(position: 0, max: 10), plot: ProgressBarState(position: 0, max: 10), exp: ProgressBarState(position: 0, max: 50), encumbrance: ProgressBarState(position: 0, max: 0), currentTask: TaskInfo(caption: 'Test', type: TaskType.kill), plotStageCount: 1, questCount: 0, ), ); final result = service.tick(state, 150); expect(result.leveledUp, isFalse); expect(result.completedQuest, isFalse); expect(result.completedAct, isFalse); expect(result.state.progress.task.position, 80); expect(result.state.progress.task.max, 80); expect(result.state.progress.encumbrance.position, 3); expect(result.state.progress.encumbrance.max, 15); expect(result.state.progress.currentTask.caption, 'Test'); }); test('tick levels up when EXP is full during kill task', () { final initial = GameState.withSeed( seed: 7, traits: const Traits( name: 'Hero', race: 'Human', klass: 'Fighter', level: 1, motto: '', guild: '', ), stats: const Stats( str: 10, con: 9, dex: 8, intelligence: 7, wis: 6, cha: 5, hpMax: 10, mpMax: 11, ), progress: const ProgressState( task: ProgressBarState(position: 1000, max: 1000), quest: ProgressBarState(position: 0, max: 10), plot: ProgressBarState(position: 0, max: 10), exp: ProgressBarState(position: 5, max: 5), encumbrance: ProgressBarState(position: 0, max: 0), currentTask: TaskInfo(caption: 'Battle', type: TaskType.kill), plotStageCount: 1, questCount: 0, ), ); final result = service.tick(initial, 50); expect(result.leveledUp, isTrue); expect(result.shouldAutosave, isTrue); expect(result.state.traits.level, 2); expect(result.state.stats.hpMax, greaterThan(initial.stats.hpMax)); expect(result.state.stats.mpMax, greaterThan(initial.stats.mpMax)); expect(result.state.progress.exp.position, 0); expect(result.state.progress.exp.max, pq_logic.levelUpTime(2)); // 태스크 완료 후 새 태스크가 자동으로 시작됨 expect(result.state.progress.task.position, 0); expect(result.state.progress.task.max, greaterThan(0)); }); test('quest completion enqueues next task and resets quest bar', () { final initial = GameState.withSeed( seed: 99, traits: const Traits( name: 'Questor', race: 'Elf', klass: 'Mage', level: 3, motto: '', guild: '', ), stats: const Stats( str: 4, con: 5, dex: 6, intelligence: 7, wis: 8, cha: 9, hpMax: 12, mpMax: 10, ), progress: const ProgressState( task: ProgressBarState(position: 2000, max: 2000), quest: ProgressBarState(position: 4, max: 5), plot: ProgressBarState(position: 0, max: 20), exp: ProgressBarState(position: 0, max: 30), encumbrance: ProgressBarState(position: 0, max: 0), currentTask: TaskInfo(caption: 'Hunt', type: TaskType.kill), plotStageCount: 2, questCount: 1, ), queue: QueueState(entries: const []), ); final result = service.tick(initial, 50); final nextState = result.state; expect(result.completedQuest, isTrue); expect(nextState.progress.questCount, 2); expect(nextState.progress.quest.position, 0); expect(nextState.progress.quest.max, inInclusiveRange(50, 149)); expect(nextState.progress.currentTask.type, TaskType.neutral); expect(nextState.progress.task.position, 0); expect(nextState.queue.entries, isEmpty); }); }