This commit is contained in:
Michal Vrba
2026-09-16 22:20:44 +02:00
commit 121d013d14
53 changed files with 10410 additions and 0 deletions
+146
View File
@@ -0,0 +1,146 @@
using SlaySharp.Core.Catalogs;
using SlaySharp.Core.Combat;
using SlaySharp.Core.Enums;
using SlaySharp.Core.Models;
using Xunit;
namespace SlaySharp.Tests;
public class CombatEngineTests
{
[Fact]
public void CombatEngine_InitializesDeckAndDraws5Cards()
{
var player = new Player("Senior Dev", 70, maxEnergy: 3, seed: 42);
player.MasterDeck.AddRange(StarterDecks.CreateCsharpArchitectDeck());
var engine = new CombatEngine();
var enemy = new NullReferenceExceptionEnemy();
engine.StartCombat(player, new List<Enemy> { enemy });
Assert.Equal(CombatPhase.PlayerTurn, engine.Phase);
Assert.Equal(3, player.CurrentEnergy);
Assert.Equal(5, player.Hand.Count);
Assert.Equal(7, player.DrawPile.Count);
Assert.Empty(player.DiscardPile);
}
[Fact]
public void PlayCard_DealsDamage_AndConsumesEnergy()
{
var player = new Player("Senior Dev", 70, maxEnergy: 3);
var card = new ConsoleWriteLineCard(); // Cost 1, dmg 6
var enemy = new NullReferenceExceptionEnemy(); // 45 HP
var engine = new CombatEngine();
engine.StartCombat(player, new List<Enemy> { enemy });
// Force hand
player.Hand.Clear();
player.Hand.Add(card);
player.CurrentEnergy = 3;
var success = engine.PlayCard(card, enemy);
Assert.True(success);
Assert.Equal(2, player.CurrentEnergy);
Assert.Equal(39, enemy.CurrentHp);
Assert.Contains(card, player.DiscardPile);
}
[Fact]
public void SpanSliceCard_PiercesThroughShield()
{
var player = new Player("Senior Dev", 70, maxEnergy: 3);
var card = new SpanSliceCard(); // 8 piercing dmg
var enemy = new NullReferenceExceptionEnemy(); // 45 HP
var engine = new CombatEngine();
engine.StartCombat(player, new List<Enemy> { enemy });
enemy.GainShield(10);
player.Hand.Clear();
player.Hand.Add(card);
player.CurrentEnergy = 3;
var success = engine.PlayCard(card, enemy);
Assert.True(success);
Assert.Equal(10, enemy.Shield); // Shield remains 10!
Assert.Equal(37, enemy.CurrentHp); // 45 - 8 = 37
}
[Fact]
public void StatusEffects_StrengthAndVulnerable_MultiplyDamage()
{
var player = new Player("Senior Dev", 70, maxEnergy: 3);
var enemy = new NullReferenceExceptionEnemy(); // 45 HP
var card = new ConsoleWriteLineCard(); // 6 dmg
var engine = new CombatEngine();
engine.StartCombat(player, new List<Enemy> { enemy });
player.Statuses.Add(StatusType.Strength, 2); // Base 6 + 2 = 8
enemy.Statuses.Add(StatusType.Vulnerable, 1); // 8 * 1.5 = 12
player.Hand.Clear();
player.Hand.Add(card);
player.CurrentEnergy = 3;
engine.PlayCard(card, enemy);
Assert.Equal(33, enemy.CurrentHp); // 45 - 12 = 33
}
[Fact]
public void DiscardPile_Reshuffles_WhenDrawPileEmpty()
{
var player = new Player("Senior Dev", 70, maxEnergy: 3, seed: 123);
// Only 3 cards in master deck
player.MasterDeck.Add(new ConsoleWriteLineCard());
player.MasterDeck.Add(new TryCatchCard());
player.MasterDeck.Add(new LinqWhereCard());
var engine = new CombatEngine();
var enemy = new OffByOneBugEnemy();
engine.StartCombat(player, new List<Enemy> { enemy });
// All 3 cards drawn to hand, draw pile empty
Assert.Equal(3, player.Hand.Count);
Assert.Empty(player.DrawPile);
// Discard 2 cards
player.DiscardPile.Add(player.Hand[0]);
player.DiscardPile.Add(player.Hand[1]);
player.Hand.RemoveRange(0, 2);
// Request drawing 2 cards
player.DrawCards(2, engine.Log);
Assert.Equal(3, player.Hand.Count);
Assert.Empty(player.DiscardPile);
}
[Fact]
public void KillingAllEnemies_TriggersVictory()
{
var player = new Player("Senior Dev", 70, maxEnergy: 3);
var card = new ThrowExceptionCard(); // 16 dmg
var enemy = new OffByOneBugEnemy(); // 22 HP
var engine = new CombatEngine();
engine.StartCombat(player, new List<Enemy> { enemy });
enemy.CurrentHp = 10; // low HP
player.Hand.Clear();
player.Hand.Add(card);
player.CurrentEnergy = 2;
engine.PlayCard(card, enemy);
Assert.Equal(CombatPhase.Victory, engine.Phase);
Assert.Empty(engine.Enemies);
}
}
+1
View File
@@ -0,0 +1 @@
global using Xunit;
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\SlaySharp.Core\SlaySharp.Core.csproj" />
</ItemGroup>
</Project>