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.", ); }, ); }); }