update
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart'; // Import SharedPreferences
|
||||
import 'package:game_test/providers/battle_provider.dart';
|
||||
import 'package:game_test/providers/shop_provider.dart';
|
||||
import 'package:game_test/game/models.dart';
|
||||
import 'package:game_test/game/enums.dart';
|
||||
import 'package:game_test/game/data/item_table.dart';
|
||||
|
||||
void main() {
|
||||
group('BattleProvider Armor Reset Test', () {
|
||||
late BattleProvider battleProvider;
|
||||
late ShopProvider shopProvider;
|
||||
|
||||
setUp(() {
|
||||
// Fix Binding has not yet been initialized error
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
// Mock SharedPreferences
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
|
||||
// Mock ItemTable data to prevent RangeError in initializeBattle
|
||||
// initializeBattle accesses indices up to 5 for weapons and 3 for shields
|
||||
ItemTable.weapons = List.generate(
|
||||
10,
|
||||
(index) => ItemTemplate(
|
||||
id: "weapon_$index",
|
||||
name: "Weapon $index",
|
||||
description: "Test Weapon",
|
||||
atkBonus: 10,
|
||||
hpBonus: 0,
|
||||
armorBonus: 0,
|
||||
slot: EquipmentSlot.weapon,
|
||||
effects: [],
|
||||
price: 10,
|
||||
),
|
||||
);
|
||||
ItemTable.shields = List.generate(
|
||||
10,
|
||||
(index) => ItemTemplate(
|
||||
id: "shield_$index",
|
||||
name: "Shield $index",
|
||||
description: "Test Shield",
|
||||
atkBonus: 0,
|
||||
hpBonus: 0,
|
||||
armorBonus: 10,
|
||||
slot: EquipmentSlot.shield,
|
||||
effects: [],
|
||||
price: 10,
|
||||
),
|
||||
);
|
||||
// Initialize other lists to empty to avoid null pointer if accessed loosely
|
||||
ItemTable.armors = [];
|
||||
ItemTable.accessories = [];
|
||||
|
||||
shopProvider = ShopProvider();
|
||||
battleProvider = BattleProvider(shopProvider: shopProvider);
|
||||
battleProvider.initializeBattle(); // Initialize player and stage 1
|
||||
});
|
||||
|
||||
test('Armor should be reset to 0 when proceeding to next stage', () {
|
||||
// 1. Setup initial state
|
||||
battleProvider.player.armor = 50;
|
||||
expect(
|
||||
battleProvider.player.armor,
|
||||
50,
|
||||
reason: "Player armor should be set to 50 initially.",
|
||||
);
|
||||
|
||||
// 2. Simulate proceeding to next stage
|
||||
// Using proceedToNextStage which calls _prepareNextStage internally
|
||||
battleProvider.proceedToNextStage();
|
||||
|
||||
// 3. Verify armor is reset
|
||||
expect(battleProvider.stage, 2, reason: "Stage should advance to 2.");
|
||||
expect(
|
||||
battleProvider.player.armor,
|
||||
0,
|
||||
reason: "Player armor should be reset to 0 in the new stage.",
|
||||
);
|
||||
});
|
||||
|
||||
test('Armor should be reset to 0 when re-initializing battle', () {
|
||||
// 1. Setup initial state
|
||||
battleProvider.player.armor = 20;
|
||||
expect(battleProvider.player.armor, 20);
|
||||
|
||||
// 2. Re-initialize
|
||||
battleProvider.initializeBattle();
|
||||
|
||||
// 3. Verify armor is reset
|
||||
expect(battleProvider.stage, 1);
|
||||
expect(
|
||||
battleProvider.player.armor,
|
||||
0,
|
||||
reason: "Player armor should be reset to 0 on initialization.",
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:game_test/providers/battle_provider.dart';
|
||||
import 'package:game_test/providers/shop_provider.dart';
|
||||
import 'package:game_test/game/models.dart';
|
||||
import 'package:game_test/game/enums.dart';
|
||||
import 'package:game_test/game/data/item_table.dart';
|
||||
import 'package:game_test/game/config/game_config.dart'; // Import GameConfig for multiplier
|
||||
import 'dart:math'; // Import dart:math
|
||||
|
||||
void main() {
|
||||
group('Disarm Mechanic (Weakened Attack) Test', () {
|
||||
late BattleProvider battleProvider;
|
||||
late ShopProvider shopProvider;
|
||||
|
||||
setUp(() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
|
||||
// Mock ItemTable
|
||||
ItemTable.weapons = [];
|
||||
ItemTable.shields = [];
|
||||
ItemTable.armors = [];
|
||||
ItemTable.accessories = [];
|
||||
|
||||
shopProvider = ShopProvider();
|
||||
// Pass a fixed seed Random for predictable intent generation
|
||||
battleProvider = BattleProvider(
|
||||
shopProvider: shopProvider,
|
||||
random: Random(0),
|
||||
);
|
||||
|
||||
battleProvider.enemy = Character(
|
||||
name: "Enemy",
|
||||
maxHp: 100,
|
||||
armor: 0,
|
||||
atk: 50, // High base ATK for clear percentage reduction
|
||||
baseDefense:
|
||||
0, // Set to 0 to make canDefend false for predictable intent
|
||||
);
|
||||
|
||||
battleProvider.player = Character(
|
||||
name: "Player",
|
||||
maxHp: 100,
|
||||
armor: 0,
|
||||
atk: 50, // High base ATK for clear percentage reduction
|
||||
baseDefense: 10,
|
||||
);
|
||||
});
|
||||
|
||||
test('Enemy totalAtk reduced to 10% when Disarmed (Attack Forbidden)', () {
|
||||
// 1. Verify initial ATK
|
||||
expect(battleProvider.enemy.totalAtk, 50);
|
||||
|
||||
// 2. Apply Disarm
|
||||
battleProvider.enemy.addStatusEffect(
|
||||
StatusEffect(type: StatusEffectType.disarmed, duration: 2, value: 0),
|
||||
);
|
||||
|
||||
// 3. Verify ATK is reduced to 10%
|
||||
final expectedAtk = (50 * GameConfig.disarmedDamageMultiplier).toInt();
|
||||
expect(battleProvider.enemy.totalAtk, expectedAtk);
|
||||
|
||||
// 4. Verify enemy still generates an attack intent (now predictable due to baseDefense: 0)
|
||||
battleProvider.generateEnemyIntent();
|
||||
final intent = battleProvider.currentEnemyIntent;
|
||||
expect(intent, isNotNull);
|
||||
expect(intent!.type, EnemyActionType.attack);
|
||||
});
|
||||
|
||||
test(
|
||||
'Player totalAtk reduced to 10% when Disarmed (Attack Forbidden) and turn proceeds',
|
||||
() async {
|
||||
// 1. Verify initial ATK
|
||||
expect(battleProvider.player.totalAtk, 50);
|
||||
|
||||
// 2. Apply Disarm to Player
|
||||
battleProvider.player.addStatusEffect(
|
||||
StatusEffect(type: StatusEffectType.disarmed, duration: 2, value: 0),
|
||||
);
|
||||
|
||||
// 3. Verify ATK is reduced to 10%
|
||||
final expectedAtk = (50 * GameConfig.disarmedDamageMultiplier).toInt();
|
||||
expect(battleProvider.player.totalAtk, expectedAtk);
|
||||
|
||||
battleProvider.isPlayerTurn = true;
|
||||
|
||||
// 4. Attempt Attack - it should now proceed, not be rejected
|
||||
await battleProvider.playerAction(ActionType.attack, RiskLevel.safe);
|
||||
|
||||
// 5. Verify turn ended (proceeded)
|
||||
expect(
|
||||
battleProvider.isPlayerTurn,
|
||||
false,
|
||||
reason: "Turn should end after successful (weakened) action.",
|
||||
);
|
||||
|
||||
// 6. Verify log no longer contains "Cannot attack" (optional but good)
|
||||
expect(
|
||||
battleProvider.logs.last,
|
||||
isNot(contains("Cannot attack")),
|
||||
reason: "Should not log 'Cannot attack' anymore.",
|
||||
);
|
||||
expect(
|
||||
battleProvider.logs.last,
|
||||
contains("Player chose to attack with safe risk"),
|
||||
reason: "Should log normal attack.",
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user