eae7c066d1
- Domain: immutable entities (Resource, Recipe, Machine, Module, etc.) - Data: JSON recipe repository (34 resources, 26 recipes, Space Age) - Solver: DFS-based production planner with module support - Reporting: Console, JSON, Excel exporters - CLI: solve/list commands with Spectre.Console - Tests: 20 unit tests (xUnit) all passing - Tech: C# .NET 10, MathNet.Numerics, ClosedXML Model: GPT-4.1 (OpenAI) — executed by pi coding agent
115 lines
3.2 KiB
C#
115 lines
3.2 KiB
C#
using FactorioCalc.Domain;
|
|
using Xunit;
|
|
|
|
namespace FactorioCalc.Tests;
|
|
|
|
public class DomainTests
|
|
{
|
|
[Fact]
|
|
public void Resource_ValidConstructor_Succeeds()
|
|
{
|
|
var resource = new Resource(1, "Iron Ore");
|
|
Assert.Equal(1, resource.Id);
|
|
Assert.Equal("Iron Ore", resource.Name);
|
|
Assert.Equal("Iron Ore", resource.ToString());
|
|
}
|
|
|
|
[Fact]
|
|
public void Resource_EmptyName_Throws()
|
|
{
|
|
Assert.Throws<ArgumentException>(() => new Resource(1, ""));
|
|
Assert.Throws<ArgumentException>(() => new Resource(1, " "));
|
|
Assert.Throws<ArgumentException>(() => new Resource(1, null!));
|
|
}
|
|
|
|
[Fact]
|
|
public void Ingredient_ValidConstructor_Succeeds()
|
|
{
|
|
var ingredient = new Ingredient(1, 2.5);
|
|
Assert.Equal(1, ingredient.ResourceId);
|
|
Assert.Equal(2.5, ingredient.Amount);
|
|
}
|
|
|
|
[Fact]
|
|
public void Ingredient_NegativeAmount_Throws()
|
|
{
|
|
Assert.Throws<ArgumentException>(() => new Ingredient(1, -1));
|
|
}
|
|
|
|
[Fact]
|
|
public void Product_ValidConstructor_Succeeds()
|
|
{
|
|
var product = new Product(7, 1.0);
|
|
Assert.Equal(7, product.ResourceId);
|
|
Assert.Equal(1.0, product.Amount);
|
|
}
|
|
|
|
[Fact]
|
|
public void Product_ZeroAmount_Throws()
|
|
{
|
|
Assert.Throws<ArgumentException>(() => new Product(7, 0));
|
|
}
|
|
|
|
[Fact]
|
|
public void Machine_ValidConstructor_Succeeds()
|
|
{
|
|
var machine = new Machine(1, "Smelter", 0.5, 3.0, 2, new[] { "smelting" });
|
|
Assert.Equal(1, machine.Id);
|
|
Assert.Equal("Smelter", machine.Name);
|
|
Assert.Equal(0.5, machine.CraftingSpeed);
|
|
Assert.Equal(2, machine.ModuleSlots);
|
|
}
|
|
|
|
[Fact]
|
|
public void Machine_ZeroCraftingSpeed_Throws()
|
|
{
|
|
Assert.Throws<ArgumentException>(() => new Machine(1, "X", 0, 0, 0, Array.Empty<string>()));
|
|
}
|
|
|
|
[Fact]
|
|
public void Module_ValidConstructor_Succeeds()
|
|
{
|
|
var module = new Module(1, "Speed Module 1", ModuleType.Speed, 0.10, 0, -0.05);
|
|
Assert.Equal(ModuleType.Speed, module.Type);
|
|
Assert.Equal(0.10, module.SpeedBonus);
|
|
}
|
|
|
|
[Fact]
|
|
public void RecipeExecution_ValidConstructor_Succeeds()
|
|
{
|
|
var exec = new RecipeExecution(1, 5, 3, 10.5, Array.Empty<Module>(), 0.5, 0);
|
|
Assert.Equal(1, exec.RecipeId);
|
|
Assert.Equal(5, exec.MachineId);
|
|
Assert.Equal(3, exec.MachineCount);
|
|
Assert.Equal(10.5, exec.RecipeRate);
|
|
}
|
|
|
|
[Fact]
|
|
public void RecipeExecution_ZeroMachineCount_Throws()
|
|
{
|
|
Assert.Throws<ArgumentException>(() =>
|
|
new RecipeExecution(1, 5, 0, 10, Array.Empty<Module>(), 0.5, 0));
|
|
}
|
|
|
|
[Fact]
|
|
public void ProductionTarget_ValidConstructor_Succeeds()
|
|
{
|
|
var target = new ProductionTarget(30, 10);
|
|
Assert.Equal(30, target.ResourceId);
|
|
Assert.Equal(10, target.AmountPerSecond);
|
|
}
|
|
|
|
[Fact]
|
|
public void ProductionResult_ValidConstructor_Succeeds()
|
|
{
|
|
var result = new ProductionResult(
|
|
Array.Empty<RecipeExecution>(),
|
|
new Dictionary<int, double>(),
|
|
new Dictionary<int, double>());
|
|
|
|
Assert.Empty(result.Executions);
|
|
Assert.Empty(result.ResourceFlows);
|
|
Assert.Empty(result.RequiredInputs);
|
|
}
|
|
}
|