Expand rule event coverage
This commit is contained in:
@@ -170,6 +170,141 @@ public sealed class SimulationEngineTests
|
||||
Assert.Contains(forecasts, forecast => forecast.Kind == EForecastKind.TerminalLoss);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuleEventCanTriggerFromNetworkBand()
|
||||
{
|
||||
var level = LevelState.Create("Network rule", 6, 6);
|
||||
level = AddLine(level, ECarrierType.Fuel, new(2, 2), new(3, 2));
|
||||
level = level.SetProp(new(2, 2), new() { Type = EPropType.Flow, Carrier = ECarrierType.Fuel }) with {
|
||||
RuleEvents = [
|
||||
new RuleEventState {
|
||||
Phase = ERuleEventPhase.EndOfTurn,
|
||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.NetworkBandAt, Position = new(3, 2), Carrier = ECarrierType.Fuel, NetworkValue = ENetworkValueKind.Amount, Band = EBand.Critical }],
|
||||
Effects = [new RuleEffect { Kind = ERuleEffectKind.EmitWarning, Message = "fuel pressure high" }]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var next = m_Engine.AdvanceTurn(level);
|
||||
|
||||
Assert.Contains("fuel pressure high", next.Global.Warnings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuleEventCanTriggerFromReactorReadiness()
|
||||
{
|
||||
var level = BuildReadyLevel() with {
|
||||
RuleEvents = [
|
||||
new RuleEventState {
|
||||
Phase = ERuleEventPhase.EndOfTurn,
|
||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.ReactorReadyIs, ReactorId = 1, BoolValue = true }],
|
||||
Effects = [new RuleEffect { Kind = ERuleEffectKind.EmitWarning, Message = "reactor ready rule" }]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var next = m_Engine.AdvanceTurn(level);
|
||||
|
||||
Assert.Contains("reactor ready rule", next.Global.Warnings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuleEventCanTriggerFromRobotInventory()
|
||||
{
|
||||
var level = LevelState.Create("Inventory rule", 6, 6) with {
|
||||
Robot = new() { Position = new(1, 1), FuelNeutralizers = 1 },
|
||||
RuleEvents = [
|
||||
new RuleEventState {
|
||||
Phase = ERuleEventPhase.StartOfSimulation,
|
||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.RobotInventoryAtLeast, Remedy = ERemedyType.FuelNeutralizer, InventoryCount = 1 }],
|
||||
Effects = [new RuleEffect { Kind = ERuleEffectKind.EmitWarning, Message = "fuel kit detected" }]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var next = m_Engine.AdvanceTurn(level);
|
||||
|
||||
Assert.Contains("fuel kit detected", next.Global.Warnings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuleEventCanRemoveHazardsHeatAndInventory()
|
||||
{
|
||||
var level = LevelState.Create("Remove rule", 6, 6);
|
||||
level = level.SetSurface(new(2, 2), new() { Fuel = 5, Heat = 5 }) with {
|
||||
Robot = new() { Position = new(1, 1), FuelNeutralizers = 2 },
|
||||
Doors = [
|
||||
new DoorState { A = new(2, 2), B = new(1, 2), State = EDoorState.Closed },
|
||||
new DoorState { A = new(2, 2), B = new(3, 2), State = EDoorState.Closed },
|
||||
new DoorState { A = new(2, 2), B = new(2, 1), State = EDoorState.Closed },
|
||||
new DoorState { A = new(2, 2), B = new(2, 3), State = EDoorState.Closed }
|
||||
],
|
||||
RuleEvents = [
|
||||
new RuleEventState {
|
||||
Phase = ERuleEventPhase.StartOfSimulation,
|
||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.TurnAtLeast, Turn = 0 }],
|
||||
Effects = [
|
||||
new RuleEffect { Kind = ERuleEffectKind.RemoveSurfaceHazard, Position = new(2, 2), Carrier = ECarrierType.Fuel, Amount = 2 },
|
||||
new RuleEffect { Kind = ERuleEffectKind.RemoveHeat, Position = new(2, 2), Amount = 3 },
|
||||
new RuleEffect { Kind = ERuleEffectKind.RemoveInventory, Remedy = ERemedyType.FuelNeutralizer, Amount = 1 }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var next = m_Engine.AdvanceTurn(level);
|
||||
|
||||
Assert.Equal(3, next.GetSurface(new(2, 2)).Fuel);
|
||||
Assert.Equal(2, next.GetSurface(new(2, 2)).Heat);
|
||||
Assert.Equal(1, next.Robot.FuelNeutralizers);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuleEventStartLeakUsesAuthoredElectricityAccessFace()
|
||||
{
|
||||
var level = LevelState.Create("Electricity leak rule", 6, 6);
|
||||
level = level.SetTerrain(new(2, 2), ECellTerrain.Wall);
|
||||
level = level.SetUnderground(new(2, 2), ECarrierType.Electricity, new() { State = EUndergroundState.Intact }) with {
|
||||
RuleEvents = [
|
||||
new RuleEventState {
|
||||
Phase = ERuleEventPhase.StartOfSimulation,
|
||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.TurnAtLeast, Turn = 0 }],
|
||||
Effects = [new RuleEffect { Kind = ERuleEffectKind.StartLeak, Position = new(2, 2), AccessPosition = new(2, 3), Carrier = ECarrierType.Electricity }]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var next = m_Engine.AdvanceTurn(level);
|
||||
|
||||
Assert.Single(next.Leaks);
|
||||
Assert.Equal(new(2, 3), next.Leaks[0].AccessPosition);
|
||||
Assert.True(next.GetSurface(new(2, 3)).Electricity > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ValidatorRejectsInvalidRuleTargets()
|
||||
{
|
||||
var level = LevelState.Create("Invalid rules", 6, 6);
|
||||
level = level.SetTerrain(new(2, 2), ECellTerrain.Wall) with {
|
||||
RuleEvents = [
|
||||
new RuleEventState {
|
||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.PropStateAt, Position = new(1, 1) }],
|
||||
Effects = [
|
||||
new RuleEffect { Kind = ERuleEffectKind.AddSurfaceHazard, Position = new(2, 2), Carrier = ECarrierType.Fuel, Amount = 1 },
|
||||
new RuleEffect { Kind = ERuleEffectKind.RepairNetworkCell, Position = new(3, 3), Carrier = ECarrierType.Coolant }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var report = new LevelValidator().Validate(level);
|
||||
|
||||
Assert.False(report.IsValid);
|
||||
Assert.Contains(report.Errors, error => error.Message.Contains("Rule prop predicate", StringComparison.Ordinal));
|
||||
Assert.Contains(report.Errors, error => error.Message.Contains("Rule surface effect", StringComparison.Ordinal));
|
||||
Assert.Contains(report.Errors, error => error.Message.Contains("Rule network effect", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ValidatorRejectsWallHazardsAndInvalidReactorBinding()
|
||||
{
|
||||
@@ -270,4 +405,4 @@ public sealed class SimulationEngineTests
|
||||
}
|
||||
|
||||
private readonly SimulationEngine m_Engine = new();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user