using System.Collections.Generic; using NUnit.Framework; using UnityEngine; using YachtDice.Modifiers; using YachtDice.Scoring; namespace YachtDice.Tests { public class ModifierPipelineTests { [Test] public void Apply_AdditiveBeforeMultiplicative() { var addMod = ModifierData.CreateForTest("add", ModifierScope.SelectedCategory, ModifierEffectType.AddFlatToFinalScore, 10f); var mulMod = ModifierData.CreateForTest("mul", ModifierScope.SelectedCategory, ModifierEffectType.MultiplyFinalScore, 2f); var modifiers = new List { mulMod, addMod }; var result = ScoreResult.Create(20, new[] { 1, 2, 3, 4, 5 }, YachtCategory.Chance); ModifierPipeline.Apply(modifiers, ref result, ModifierScope.SelectedCategory); // (20 + 10) * 2 = 60 Assert.AreEqual(60, result.FinalScore); } [Test] public void Apply_CategoryLevelBeforeFinalScore() { var perDie = ModifierData.CreateForTest("perDie", ModifierScope.SelectedCategory, ModifierEffectType.AddPerDieValue, 5f, dieValue: 1); var flat = ModifierData.CreateForTest("flat", ModifierScope.SelectedCategory, ModifierEffectType.AddFlatToFinalScore, 100f); var modifiers = new List { flat, perDie }; var result = ScoreResult.Create(3, new[] { 1, 1, 1, 2, 3 }, YachtCategory.Ones); ModifierPipeline.Apply(modifiers, ref result, ModifierScope.SelectedCategory); // FlatBonus = 15 (perDie: 5*3) + 100 (flat) = 115 // FinalScore = (3 + 115) * 1 = 118 Assert.AreEqual(118, result.FinalScore); } [Test] public void Apply_ScopeFiltering_SkipsWrongScope() { var mod = ModifierData.CreateForTest("any", ModifierScope.AnyCategoryClosed, ModifierEffectType.AddFlatToFinalScore, 50f); var modifiers = new List { mod }; var result = ScoreResult.Create(10, new[] { 1, 2, 3, 4, 5 }, YachtCategory.Chance); ModifierPipeline.Apply(modifiers, ref result, ModifierScope.SelectedCategory); Assert.AreEqual(0, result.FlatBonus); Assert.AreEqual(10, result.FinalScore); } [Test] public void Apply_CategoryFilter_SkipsWrongCategory() { var mod = ModifierData.CreateForTest("fh", ModifierScope.SelectedCategory, ModifierEffectType.AddFlatToFinalScore, 15f, targetCategory: YachtCategory.FullHouse, hasCategoryFilter: true); var modifiers = new List { mod }; var result = ScoreResult.Create(5, new[] { 1, 1, 1, 1, 1 }, YachtCategory.Ones); ModifierPipeline.Apply(modifiers, ref result, ModifierScope.SelectedCategory); Assert.AreEqual(0, result.FlatBonus); } [Test] public void Apply_CategoryFilter_AppliesMatchingCategory() { var mod = ModifierData.CreateForTest("fh", ModifierScope.SelectedCategory, ModifierEffectType.AddFlatToFinalScore, 15f, targetCategory: YachtCategory.FullHouse, hasCategoryFilter: true); var modifiers = new List { mod }; var result = ScoreResult.Create(25, new[] { 3, 3, 3, 2, 2 }, YachtCategory.FullHouse); ModifierPipeline.Apply(modifiers, ref result, ModifierScope.SelectedCategory); Assert.AreEqual(15, result.FlatBonus); Assert.AreEqual(40, result.FinalScore); } [Test] public void Apply_MultipleModifiers_CorrectOrder() { var perDieAdd = ModifierData.CreateForTest("pda", ModifierScope.SelectedCategory, ModifierEffectType.AddPerDieValue, 2f, dieValue: 3); var perDieMul = ModifierData.CreateForTest("pdm", ModifierScope.SelectedCategory, ModifierEffectType.MultiplyPerDieValue, 1.5f, dieValue: 3); var flatAdd = ModifierData.CreateForTest("fa", ModifierScope.SelectedCategory, ModifierEffectType.AddFlatToFinalScore, 10f); var finalMul = ModifierData.CreateForTest("fm", ModifierScope.SelectedCategory, ModifierEffectType.MultiplyFinalScore, 2f); var modifiers = new List { finalMul, flatAdd, perDieMul, perDieAdd }; // dice: [3, 3, 3, 1, 2] — 3 threes var result = ScoreResult.Create(9, new[] { 3, 3, 3, 1, 2 }, YachtCategory.Threes); ModifierPipeline.Apply(modifiers, ref result, ModifierScope.SelectedCategory); // Pass 1 (cat additive): perDieAdd: +2*3 = +6 FlatBonus // Pass 2 (cat multiplicative): perDieMul: 1.5^3 = 3.375 Multiplier // Pass 3 (final additive): flatAdd: +10 FlatBonus → total FlatBonus = 16 // Pass 4 (final multiplicative): finalMul: 3.375 * 2 = 6.75 Multiplier // FinalScore = floor((9 + 16) * 6.75) = floor(168.75) = 168 Assert.AreEqual(6, result.FlatBonus + 10); // just check pipeline ran; full calc below Assert.AreEqual(168, result.FinalScore); } [Test] public void Apply_NullModifiers_DoesNotThrow() { var result = ScoreResult.Create(10, new[] { 1, 2, 3, 4, 5 }, YachtCategory.Chance); Assert.DoesNotThrow(() => ModifierPipeline.Apply(null, ref result, ModifierScope.SelectedCategory)); Assert.AreEqual(10, result.FinalScore); } [Test] public void Apply_EmptyList_NoChange() { var modifiers = new List(); var result = ScoreResult.Create(10, new[] { 1, 2, 3, 4, 5 }, YachtCategory.Chance); ModifierPipeline.Apply(modifiers, ref result, ModifierScope.SelectedCategory); Assert.AreEqual(10, result.FinalScore); } } }