b451f83174
Captures the pre-Godot-port state of the codebase. This is the rollback anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md). All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
111 lines
3.9 KiB
C#
111 lines
3.9 KiB
C#
using Theriapolis.Core;
|
||
using Theriapolis.Core.Data;
|
||
using Theriapolis.Core.Rules.Reputation;
|
||
using Xunit;
|
||
|
||
namespace Theriapolis.Tests.Reputation;
|
||
|
||
/// <summary>
|
||
/// Phase 6 M2 — opposition matrix application.
|
||
///
|
||
/// The plan §I-2 spells out the exact multipliers; this suite verifies
|
||
/// the cascade fires in both directions (gains and losses) and stays
|
||
/// inside the clamp range.
|
||
/// </summary>
|
||
public sealed class FactionOppositionTests
|
||
{
|
||
private static IReadOnlyDictionary<string, FactionDef> LoadFactions()
|
||
=> new ContentResolver(new ContentLoader(TestHelpers.DataDirectory)).Factions;
|
||
|
||
[Fact]
|
||
public void GainWithInheritors_CascadesIntoOppositionLosses()
|
||
{
|
||
var factions = LoadFactions();
|
||
var standing = new FactionStanding();
|
||
|
||
var applied = standing.Apply("inheritors", 10, factions);
|
||
|
||
// Per the doc: +10 with Inheritors should yield -5 Enforcers,
|
||
// -2 Thorn Council, -3 Hybrid Underground, -3 Unsheathed.
|
||
Assert.Equal( 10, standing.Get("inheritors"));
|
||
Assert.Equal( -5, standing.Get("covenant_enforcers"));
|
||
Assert.Equal( -2, standing.Get("thorn_council"));
|
||
Assert.Equal( -3, standing.Get("hybrid_underground"));
|
||
Assert.Equal( -3, standing.Get("unsheathed"));
|
||
Assert.Equal( 0, standing.Get("merchant_guilds")); // multiplier 0
|
||
|
||
// The applied list reports every actually-changed faction.
|
||
Assert.Contains(applied, t => t.FactionId == "inheritors" && t.Delta == 10);
|
||
Assert.Contains(applied, t => t.FactionId == "covenant_enforcers" && t.Delta == -5);
|
||
}
|
||
|
||
[Fact]
|
||
public void LossWithInheritors_CascadesIntoOppositionGains()
|
||
{
|
||
var factions = LoadFactions();
|
||
var standing = new FactionStanding();
|
||
standing.Apply("inheritors", -20, factions);
|
||
|
||
// -20 × -0.5 = +10 with Enforcers.
|
||
Assert.Equal(-20, standing.Get("inheritors"));
|
||
Assert.Equal( 10, standing.Get("covenant_enforcers"));
|
||
Assert.Equal( 4, standing.Get("thorn_council"));
|
||
Assert.Equal( 6, standing.Get("hybrid_underground"));
|
||
Assert.Equal( 6, standing.Get("unsheathed"));
|
||
}
|
||
|
||
[Fact]
|
||
public void Standing_IsClampedToRepRange()
|
||
{
|
||
var factions = LoadFactions();
|
||
var standing = new FactionStanding();
|
||
standing.Apply("inheritors", 200, factions);
|
||
Assert.Equal(C.REP_MAX, standing.Get("inheritors"));
|
||
// Cascaded -100 is below the floor — verify clamping.
|
||
Assert.Equal(C.REP_MIN, standing.Get("covenant_enforcers"));
|
||
}
|
||
|
||
[Fact]
|
||
public void ZeroDelta_DoesNothing()
|
||
{
|
||
var factions = LoadFactions();
|
||
var standing = new FactionStanding();
|
||
standing.Set("inheritors", 25);
|
||
standing.Apply("inheritors", 0, factions);
|
||
Assert.Equal(25, standing.Get("inheritors"));
|
||
Assert.Equal( 0, standing.Get("covenant_enforcers"));
|
||
}
|
||
|
||
[Fact]
|
||
public void UnknownFaction_NoCascade()
|
||
{
|
||
var factions = LoadFactions();
|
||
var standing = new FactionStanding();
|
||
// No throw; standing accumulates against the unknown id.
|
||
standing.Apply("not_a_real_faction", 10, factions);
|
||
Assert.Equal(10, standing.Get("not_a_real_faction"));
|
||
Assert.Equal( 0, standing.Get("covenant_enforcers"));
|
||
}
|
||
|
||
[Fact]
|
||
public void SubmitEvent_AppliesFactionAndPersonal()
|
||
{
|
||
var factions = LoadFactions();
|
||
var rep = new PlayerReputation();
|
||
|
||
rep.Submit(new RepEvent
|
||
{
|
||
Kind = RepEventKind.Quest,
|
||
FactionId = "inheritors",
|
||
RoleTag = "test.someone",
|
||
Magnitude = 10,
|
||
Note = "test event",
|
||
}, factions);
|
||
|
||
Assert.Equal(10, rep.Factions.Get("inheritors"));
|
||
Assert.Equal(-5, rep.Factions.Get("covenant_enforcers"));
|
||
Assert.Equal(10, rep.PersonalFor("test.someone").Score);
|
||
Assert.Single(rep.Ledger.Entries);
|
||
}
|
||
}
|