game/test/game_test.dart

172 lines
6.4 KiB
Dart

// test/game_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:game_test/game/game_instance.dart';
import 'package:game_test/game/game_manager.dart';
import 'package:game_test/game/model/entity.dart';
import 'package:game_test/game/model/stat.dart';
import 'package:game_test/game/model/item.dart';
void main() {
group('Game Core Logic Tests', () {
test('Stat calculation with Modifiers', () {
final strength = Stat(baseValue: 100);
expect(strength.value, 100.0);
// Add flat modifier
strength.addModifier(Modifier(type: ModifierType.flat, value: 10));
expect(strength.value, closeTo(110.0, 0.00001));
// Add percent modifier
strength.addModifier(Modifier(type: ModifierType.percent, value: 0.10)); // +10%
// 110 * (1 + 0.10) = 121
expect(strength.value, closeTo(121.0, 0.00001));
// Add another flat modifier
strength.addModifier(Modifier(type: ModifierType.flat, value: 20));
// (110 + 20) * (1 + 0.10) = 130 * 1.1 = 143
expect(strength.value, closeTo(143.0, 0.00001));
// Add another percent modifier
strength.addModifier(Modifier(type: ModifierType.percent, value: 0.05)); // +5%
// (110 + 20) * (1 + 0.10 + 0.05) = 130 * 1.15 = 149.5
expect(strength.value, closeTo(149.5, 0.00001));
// Remove a modifier
final flatModifier10 = Modifier(type: ModifierType.flat, value: 10);
strength.removeModifier(flatModifier10);
// (100 + 20) * (1 + 0.10 + 0.05) = 120 * 1.15 = 138
expect(strength.value, closeTo(138.0, 0.00001));
final percentModifier10 = Modifier(type: ModifierType.percent, value: 0.10);
strength.removeModifier(percentModifier10);
// (100 + 20) * (1 + 0.05) = 120 * 1.05 = 126
expect(strength.value, closeTo(126.0, 0.00001));
});
test('LivingEntity HP and damage', () {
final player = Player(id: 'p1', name: 'Test Player', baseHp: 100);
expect(player.hp.value, 100.0);
expect(player.isAlive, isTrue);
player.takeDamage(20);
expect(player.hp.value, 80.0);
expect(player.isAlive, isTrue);
player.takeDamage(90); // Should go to 0
expect(player.hp.value, 0.0);
expect(player.isAlive, isFalse);
player.heal(50);
expect(player.hp.value, 50.0);
expect(player.isAlive, isTrue);
});
group('Player Equipment Tests', () {
test('Player starts unarmed with base attack 1', () {
final player = Player(id: 'p1', name: 'Test Player', baseHp: 100);
expect(player.equippedWeapon?.id, 'unarmed_weapon');
expect(player.attack.value, closeTo(1.0, 0.00001));
});
test('Player equips a new weapon and attack changes', () {
final player = Player(id: 'p1', name: 'Test Player', baseHp: 100);
final sword = Weapon(
id: 'iron_sword',
name: '무쇠 검',
attackModifier: Modifier(type: ModifierType.flat, value: 10),
);
player.equipWeapon(sword);
expect(player.equippedWeapon?.id, 'iron_sword');
expect(player.attack.value, closeTo(10.0, 0.00001)); // Base attack from sword
});
test('Player unequips weapon and returns to unarmed', () {
final player = Player(id: 'p1', name: 'Test Player', baseHp: 100);
final sword = Weapon(
id: 'iron_sword',
name: '무쇠 검',
attackModifier: Modifier(type: ModifierType.flat, value: 10),
);
player.equipWeapon(sword);
expect(player.attack.value, closeTo(10.0, 0.00001));
player.unequipWeapon(EquipmentSlot.mainHand);
expect(player.equippedWeapon?.id, 'unarmed_weapon');
expect(player.attack.value, closeTo(1.0, 0.00001));
});
test('Equipping a new weapon replaces the old one', () {
final player = Player(id: 'p1', name: 'Test Player', baseHp: 100);
final sword = Weapon(
id: 'iron_sword',
name: '무쇠 검',
attackModifier: Modifier(type: ModifierType.flat, value: 10),
);
final axe = Weapon(
id: 'steel_axe',
name: '강철 도끼',
attackModifier: Modifier(type: ModifierType.flat, value: 15),
);
player.equipWeapon(sword);
expect(player.attack.value, closeTo(10.0, 0.00001));
player.equipWeapon(axe);
expect(player.equippedWeapon?.id, 'steel_axe');
expect(player.attack.value, closeTo(15.0, 0.00001));
});
});
test('GameInstance singleton and initialization', () async {
final instance1 = GameInstance();
final instance2 = GameInstance();
expect(instance1, same(instance2)); // Verify singleton
expect(instance1.isInitialized, isFalse);
await instance1.initialize();
expect(instance1.isInitialized, isTrue);
// Calling initialize again should not re-initialize
await instance2.initialize();
expect(instance2.isInitialized, isTrue);
});
test('GameManager initializes and player/enemies exist', () async {
final gameManager = GameManager();
// Allow some time for async initialization in GameManager constructor
await Future.delayed(const Duration(milliseconds: 100));
expect(gameManager.player, isNotNull);
expect(gameManager.player?.name, '용감한 검투사');
expect(gameManager.currentEnemies.length, 2);
});
test('GameManager player turn and enemy turn logic', () async {
final gameManager = GameManager();
await Future.delayed(const Duration(milliseconds: 100)); // Ensure initialization
final initialPlayerHp = gameManager.player!.hp.value;
final initialEnemyCount = gameManager.currentEnemies.length;
// Player attacks with medium risk (e.g., 0.6 for 60% success/damage)
gameManager.playerTurn(action: 'attack', risk: 0.6);
await Future.delayed(const Duration(milliseconds: 100)); // Allow enemy turn to complete
// Expect player to have taken damage from enemy's turn
expect(gameManager.player!.hp.value, lessThan(initialPlayerHp));
// Expect at least one enemy to have taken damage or been defeated
// The current simple logic removes enemy if defeated, so check count.
if (gameManager.currentEnemies.length < initialEnemyCount) {
print('Enemy was defeated during playerTurn test.');
} else {
final remainingEnemy = gameManager.currentEnemies.first;
expect(remainingEnemy.hp.value, closeTo(49.4, 0.00001));
}
});
});
}