Files
TheriapolisV3/Theriapolis.Tests/Dialogue/ShopPricingTests.cs
T
Christopher Wiebe b451f83174 Initial commit: Theriapolis baseline at port/godot branch point
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>
2026-04-30 20:40:51 -07:00

65 lines
2.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Theriapolis.Core;
using Theriapolis.Core.Rules.Dialogue;
using Theriapolis.Core.Rules.Reputation;
using Xunit;
namespace Theriapolis.Tests.Dialogue;
/// <summary>
/// Phase 6 M3 — disposition-driven shop pricing per the design doc.
/// </summary>
public sealed class ShopPricingTests
{
[Fact]
public void ServiceAvailable_RefusesAtNemesisAndHostile()
{
Assert.False(ShopPricing.ServiceAvailable(-100));
Assert.False(ShopPricing.ServiceAvailable( -90));
Assert.False(ShopPricing.ServiceAvailable( -76));
Assert.False(ShopPricing.ServiceAvailable( -75));
Assert.False(ShopPricing.ServiceAvailable( -60));
Assert.False(ShopPricing.ServiceAvailable( -51));
Assert.True(ShopPricing.ServiceAvailable( -50));
Assert.True(ShopPricing.ServiceAvailable( 0));
Assert.True(ShopPricing.ServiceAvailable( 100));
}
[Fact]
public void BuyMultiplier_HitsKeyTiers()
{
Assert.Equal(1.25f, ShopPricing.BuyMultiplier(-30)); // Antagonistic
Assert.Equal(1.25f, ShopPricing.BuyMultiplier(-10)); // Unfriendly
Assert.Equal(1.00f, ShopPricing.BuyMultiplier( 0)); // Neutral
Assert.Equal(0.90f, ShopPricing.BuyMultiplier( 10)); // Favorable
Assert.Equal(0.80f, ShopPricing.BuyMultiplier( 30)); // Friendly
Assert.Equal(0.70f, ShopPricing.BuyMultiplier( 60)); // Allied
Assert.Equal(0.60f, ShopPricing.BuyMultiplier( 90)); // Champion
}
[Fact]
public void BuyPriceFor_RoundsUp_NeverBelowOne()
{
// Item base cost 10 fang, friendly disposition (×0.80) = 8 fang.
Assert.Equal(8, ShopPricing.BuyPriceFor(10, 30));
// Champion (×0.60) = 6.
Assert.Equal(6, ShopPricing.BuyPriceFor(10, 90));
// Tiny item, large discount, but minimum 1.
Assert.Equal(1, ShopPricing.BuyPriceFor(1, 90));
}
[Fact]
public void SellPriceFor_FloorsToZero_AtRefusedTiers()
{
Assert.Equal(0, ShopPricing.SellPriceFor(20, -90)); // Nemesis
Assert.Equal(0, ShopPricing.SellPriceFor(20, -60)); // Hostile
}
[Fact]
public void SellPriceFor_BetterAtHigherTrust()
{
int neutral = ShopPricing.SellPriceFor(40, 0);
int champion = ShopPricing.SellPriceFor(40, 90);
Assert.True(champion > neutral, $"Champion sell ({champion}) should beat neutral ({neutral}).");
}
}