Files
asciinevrdie/test/helpers/mock_factories.dart
JiWoong Sul 9f077d74a1 chore: 플랫폼 설정 및 테스트 업데이트
- Android 광고 권한 추가
- macOS 플러그인 등록
- 테스트 mock 업데이트
2026-01-16 20:11:00 +09:00

204 lines
5.5 KiB
Dart

import 'package:asciineverdie/src/core/engine/game_mutations.dart';
import 'package:asciineverdie/src/core/engine/progress_service.dart';
import 'package:asciineverdie/src/core/engine/reward_service.dart';
import 'package:asciineverdie/src/core/model/combat_state.dart';
import 'package:asciineverdie/src/core/model/combat_stats.dart';
import 'package:asciineverdie/src/core/model/game_state.dart';
import 'package:asciineverdie/src/core/model/monetization_state.dart';
import 'package:asciineverdie/src/core/model/monster_combat_stats.dart';
import 'package:asciineverdie/src/core/model/pq_config.dart';
import 'package:asciineverdie/src/core/storage/save_manager.dart';
import 'package:asciineverdie/src/core/storage/save_repository.dart';
import 'package:asciineverdie/src/core/storage/save_service.dart';
import 'package:asciineverdie/src/core/util/balance_constants.dart';
export 'package:asciineverdie/src/core/storage/save_repository.dart'
show SaveOutcome;
export 'package:asciineverdie/src/core/storage/save_service.dart'
show SaveFileInfo;
/// 테스트용 Fake SaveManager
///
/// 여러 테스트 파일에서 중복되던 Mock을 통합
class FakeSaveManager implements SaveManager {
final List<GameState> savedStates = [];
/// 커스텀 로드 동작 설정
(SaveOutcome, GameState?, bool, MonetizationState?) Function(String?)? onLoad;
/// 저장 결과 설정 (기본: 성공)
SaveOutcome saveOutcome = const SaveOutcome.success();
@override
Future<SaveOutcome> saveState(
GameState state, {
String? fileName,
bool cheatsEnabled = false,
MonetizationState? monetization,
}) async {
savedStates.add(state);
return saveOutcome;
}
@override
Future<(SaveOutcome, GameState?, bool, MonetizationState?)> loadState({
String? fileName,
}) async {
if (onLoad != null) {
return onLoad!(fileName);
}
return (const SaveOutcome.success(), null, false, null);
}
@override
Future<List<SaveFileInfo>> listSaves() async => [];
@override
Future<SaveOutcome> deleteSave({String? fileName}) async {
return const SaveOutcome.success();
}
@override
Future<bool> saveExists({String? fileName}) async => false;
}
/// 테스트용 팩토리 클래스
///
/// 테스트에서 자주 사용되는 객체 생성을 중앙화
class MockFactories {
MockFactories._();
/// 기본 PqConfig 생성
static const PqConfig config = PqConfig();
/// GameMutations 생성
static GameMutations createMutations([PqConfig? cfg]) {
return GameMutations(cfg ?? config);
}
/// ProgressService 생성
static ProgressService createProgressService([PqConfig? cfg]) {
final c = cfg ?? config;
final mutations = GameMutations(c);
return ProgressService(
config: c,
mutations: mutations,
rewards: RewardService(mutations, c),
);
}
/// 기본 GameState 생성
///
/// [seed]: 결정론적 랜덤 시드
/// [level]: 캐릭터 레벨
static GameState createGameState({
int seed = 42,
int level = 1,
}) {
return GameState.withSeed(seed: seed);
}
/// 테스트용 CombatState 생성
static CombatState createCombat({
int playerHpMax = 100,
int playerHpCurrent = 100,
int monsterHpMax = 50,
int monsterHpCurrent = 50,
int monsterLevel = 1,
String monsterName = 'Test Monster',
}) {
final playerStats = CombatStats.empty().copyWith(
hpMax: playerHpMax,
hpCurrent: playerHpCurrent,
mpMax: 50,
mpCurrent: 50,
atk: 20,
def: 10,
attackDelayMs: 1000,
);
final monsterStats = MonsterCombatStats(
name: monsterName,
level: monsterLevel,
atk: 10,
def: 5,
magDef: 5,
hpMax: monsterHpMax,
hpCurrent: monsterHpCurrent,
criRate: 0.05,
criDamage: 1.5,
evasion: 0.0,
accuracy: 0.8,
attackDelayMs: 1000,
expReward: 100,
);
return CombatState(
playerStats: playerStats,
monsterStats: monsterStats,
playerAttackAccumulatorMs: 0,
monsterAttackAccumulatorMs: 0,
totalDamageDealt: 0,
totalDamageTaken: 0,
turnsElapsed: 0,
isActive: true,
);
}
/// 테스트용 MonsterCombatStats 생성
static MonsterCombatStats createMonsterStats({
String name = 'Test Monster',
int level = 1,
int atk = 10,
int def = 5,
int magDef = 5,
int hpMax = 100,
int? hpCurrent,
double criRate = 0.05,
double criDamage = 1.5,
double evasion = 0.0,
double accuracy = 0.8,
int attackDelayMs = 1000,
int expReward = 100,
}) {
return MonsterCombatStats(
name: name,
level: level,
atk: atk,
def: def,
magDef: magDef,
hpMax: hpMax,
hpCurrent: hpCurrent ?? hpMax,
criRate: criRate,
criDamage: criDamage,
evasion: evasion,
accuracy: accuracy,
attackDelayMs: attackDelayMs,
expReward: expReward,
);
}
/// 밸런스 상수 기반 몬스터 스탯 생성
static MonsterCombatStats createBalancedMonsterStats({
required int level,
MonsterType type = MonsterType.normal,
}) {
final base = MonsterBaseStats.generate(level, type);
return MonsterCombatStats(
name: 'Balanced Monster Lv$level',
level: level,
atk: base.atk,
def: base.def,
magDef: base.def, // 물리 방어와 동일
hpMax: base.hp,
hpCurrent: base.hp,
criRate: 0.05,
criDamage: 1.5,
evasion: 0.0,
accuracy: 0.8,
attackDelayMs: 1000,
expReward: base.exp,
);
}
}