From 93f5e057ed1036c8d0f08398333e2c7989218df6 Mon Sep 17 00:00:00 2001 From: Artur Goloyad Date: Sat, 25 Jul 2026 20:47:50 +0200 Subject: [PATCH 1/7] test: approve characterization baseline of current behaviour Approve the Foo approval snapshot and the pre-existing ThirtyDays snapshot as the locked-down record of current (Conjured-still-broken) behaviour. Replace the failing fixme placeholder with a passing sanity check so the suite is fully green before refactoring. Co-Authored-By: Claude Fable 5 --- .../GildedRoseTests/ApprovalTest.Foo.verified.txt | 6 ++++++ csharp.xUnit/GildedRoseTests/GildedRoseTest.cs | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 csharp.xUnit/GildedRoseTests/ApprovalTest.Foo.verified.txt diff --git a/csharp.xUnit/GildedRoseTests/ApprovalTest.Foo.verified.txt b/csharp.xUnit/GildedRoseTests/ApprovalTest.Foo.verified.txt new file mode 100644 index 00000000..c79d294c --- /dev/null +++ b/csharp.xUnit/GildedRoseTests/ApprovalTest.Foo.verified.txt @@ -0,0 +1,6 @@ +[ + { + Name: foo, + SellIn: -1 + } +] \ No newline at end of file diff --git a/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs b/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs index 63fd7b1b..c0c793e9 100644 --- a/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs +++ b/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs @@ -7,11 +7,11 @@ namespace GildedRoseTests; public class GildedRoseTest { [Fact] - public void foo() + public void UpdateQuality_DoesNotChangeItemName() { - IList Items = new List { new Item { Name = "foo", SellIn = 0, Quality = 0 } }; - GildedRose app = new GildedRose(Items); + IList items = new List { new Item { Name = "foo", SellIn = 0, Quality = 0 } }; + GildedRose app = new GildedRose(items); app.UpdateQuality(); - Assert.Equal("fixme", Items[0].Name); + Assert.Equal("foo", items[0].Name); } } \ No newline at end of file From ecf3d7e54aa1275c2ad30bae9f65e57dd12611cd Mon Sep 17 00:00:00 2001 From: Artur Goloyad Date: Sat, 25 Jul 2026 20:48:39 +0200 Subject: [PATCH 2/7] test: add specification unit tests for existing item types Green against the legacy implementation: normal items (-1/-2, floor 0), Aged Brie (+1/+2, cap 50), Sulfuras (immutable at SellIn 0 and -1), Backstage passes (+1 / +2 at <=10 / +3 at <=5, 0 after concert, cap 50). Co-Authored-By: Claude Fable 5 --- .../GildedRoseTests/GildedRoseTest.cs | 160 +++++++++++++++++- 1 file changed, 154 insertions(+), 6 deletions(-) diff --git a/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs b/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs index c0c793e9..370a1b64 100644 --- a/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs +++ b/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs @@ -1,4 +1,4 @@ -using Xunit; +using Xunit; using System.Collections.Generic; using GildedRoseKata; @@ -6,12 +6,160 @@ namespace GildedRoseTests; public class GildedRoseTest { + private const string AgedBrie = "Aged Brie"; + private const string Sulfuras = "Sulfuras, Hand of Ragnaros"; + private const string BackstagePass = "Backstage passes to a TAFKAL80ETC concert"; + + private static Item UpdateOne(string name, int sellIn, int quality) + { + var item = new Item { Name = name, SellIn = sellIn, Quality = quality }; + var app = new GildedRose(new List { item }); + app.UpdateQuality(); + return item; + } + [Fact] public void UpdateQuality_DoesNotChangeItemName() { - IList items = new List { new Item { Name = "foo", SellIn = 0, Quality = 0 } }; - GildedRose app = new GildedRose(items); - app.UpdateQuality(); - Assert.Equal("foo", items[0].Name); + var item = UpdateOne("foo", 0, 0); + Assert.Equal("foo", item.Name); } -} \ No newline at end of file + + // ---------- Normal items ---------- + + [Fact] + public void NormalItem_BeforeSellBy_QualityDropsByOne() + { + var item = UpdateOne("+5 Dexterity Vest", 10, 20); + Assert.Equal(9, item.SellIn); + Assert.Equal(19, item.Quality); + } + + [Fact] + public void NormalItem_OnSellByDate_QualityDropsByTwo() + { + var item = UpdateOne("+5 Dexterity Vest", 0, 20); + Assert.Equal(-1, item.SellIn); + Assert.Equal(18, item.Quality); + } + + [Fact] + public void NormalItem_AfterSellBy_QualityDropsByTwo() + { + var item = UpdateOne("+5 Dexterity Vest", -1, 20); + Assert.Equal(-2, item.SellIn); + Assert.Equal(18, item.Quality); + } + + [Fact] + public void NormalItem_QualityNeverNegative() + { + var item = UpdateOne("+5 Dexterity Vest", 5, 0); + Assert.Equal(0, item.Quality); + } + + [Fact] + public void NormalItem_AfterSellByWithQualityOne_QualityStopsAtZero() + { + var item = UpdateOne("+5 Dexterity Vest", 0, 1); + Assert.Equal(0, item.Quality); + } + + // ---------- Aged Brie ---------- + + [Fact] + public void AgedBrie_BeforeSellBy_QualityIncreasesByOne() + { + var item = UpdateOne(AgedBrie, 2, 0); + Assert.Equal(1, item.SellIn); + Assert.Equal(1, item.Quality); + } + + [Fact] + public void AgedBrie_AfterSellBy_QualityIncreasesByTwo() + { + var item = UpdateOne(AgedBrie, 0, 10); + Assert.Equal(-1, item.SellIn); + Assert.Equal(12, item.Quality); + } + + [Fact] + public void AgedBrie_QualityNeverExceedsFifty() + { + var item = UpdateOne(AgedBrie, 5, 50); + Assert.Equal(50, item.Quality); + } + + [Fact] + public void AgedBrie_AfterSellByAtFortyNine_QualityCapsAtFifty() + { + var item = UpdateOne(AgedBrie, 0, 49); + Assert.Equal(50, item.Quality); + } + + // ---------- Sulfuras ---------- + + [Fact] + public void Sulfuras_AtSellInZero_NeverChanges() + { + var item = UpdateOne(Sulfuras, 0, 80); + Assert.Equal(0, item.SellIn); + Assert.Equal(80, item.Quality); + } + + [Fact] + public void Sulfuras_AtSellInMinusOne_NeverChanges() + { + var item = UpdateOne(Sulfuras, -1, 80); + Assert.Equal(-1, item.SellIn); + Assert.Equal(80, item.Quality); + } + + // ---------- Backstage passes ---------- + + [Fact] + public void BackstagePass_MoreThanTenDays_QualityIncreasesByOne() + { + var item = UpdateOne(BackstagePass, 11, 20); + Assert.Equal(10, item.SellIn); + Assert.Equal(21, item.Quality); + } + + [Fact] + public void BackstagePass_TenDaysOrLess_QualityIncreasesByTwo() + { + var item = UpdateOne(BackstagePass, 10, 20); + Assert.Equal(9, item.SellIn); + Assert.Equal(22, item.Quality); + } + + [Fact] + public void BackstagePass_SixDays_QualityIncreasesByTwo() + { + var item = UpdateOne(BackstagePass, 6, 20); + Assert.Equal(22, item.Quality); + } + + [Fact] + public void BackstagePass_FiveDaysOrLess_QualityIncreasesByThree() + { + var item = UpdateOne(BackstagePass, 5, 20); + Assert.Equal(4, item.SellIn); + Assert.Equal(23, item.Quality); + } + + [Fact] + public void BackstagePass_AfterConcert_QualityDropsToZero() + { + var item = UpdateOne(BackstagePass, 0, 20); + Assert.Equal(-1, item.SellIn); + Assert.Equal(0, item.Quality); + } + + [Fact] + public void BackstagePass_AtFortyNineCloseToConcert_QualityCapsAtFifty() + { + var item = UpdateOne(BackstagePass, 5, 49); + Assert.Equal(50, item.Quality); + } +} From a0066f58cd637c40866d5f36c7990f2b6a149bbb Mon Sep 17 00:00:00 2001 From: Artur Goloyad Date: Sat, 25 Jul 2026 20:49:08 +0200 Subject: [PATCH 3/7] test: add failing specification tests for Conjured items Conjured items must degrade twice as fast: -2 before sell-by, -4 after, never below 0. Red on purpose (TDD) - the legacy code still treats Conjured as a normal item; they go green once ConjuredItemUpdater lands. Co-Authored-By: Claude Fable 5 --- .../GildedRoseTests/GildedRoseTest.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs b/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs index 370a1b64..2f4ae367 100644 --- a/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs +++ b/csharp.xUnit/GildedRoseTests/GildedRoseTest.cs @@ -162,4 +162,37 @@ public class GildedRoseTest var item = UpdateOne(BackstagePass, 5, 49); Assert.Equal(50, item.Quality); } + + // ---------- Conjured items ---------- + + [Fact] + public void ConjuredItem_BeforeSellBy_QualityDropsByTwo() + { + var item = UpdateOne("Conjured Mana Cake", 3, 6); + Assert.Equal(2, item.SellIn); + Assert.Equal(4, item.Quality); + } + + [Fact] + public void ConjuredItem_OnSellByDate_QualityDropsByFour() + { + var item = UpdateOne("Conjured Mana Cake", 0, 6); + Assert.Equal(-1, item.SellIn); + Assert.Equal(2, item.Quality); + } + + [Fact] + public void ConjuredItem_AfterSellBy_QualityDropsByFour() + { + var item = UpdateOne("Conjured Mana Cake", -1, 6); + Assert.Equal(-2, item.SellIn); + Assert.Equal(2, item.Quality); + } + + [Fact] + public void ConjuredItem_QualityNeverNegative() + { + var item = UpdateOne("Conjured Mana Cake", 0, 3); + Assert.Equal(0, item.Quality); + } } From 8965637f18db4c7a50d4292bb46e153ac69688a0 Mon Sep 17 00:00:00 2001 From: Artur Goloyad Date: Sat, 25 Jul 2026 20:50:18 +0200 Subject: [PATCH 4/7] refactor: add IItemUpdater strategies and ItemUpdaterFactory Introduce the Strategy + Factory design: IItemUpdater (Name + Update), an ItemUpdaterBase with the single shared [0,50] clamp helper, stateless strategies for normal/Aged Brie/Sulfuras/Backstage, and a factory with two-tier resolution (exact name via case-insensitive dictionary, then Conjured prefix rule, then the default fallback). Not wired into GildedRose yet; no behaviour change. The Conjured strategy itself arrives in the feature commit. Co-Authored-By: Claude Fable 5 --- csharp.xUnit/GildedRose/AgedBrieUpdater.cs | 16 ++++++ .../GildedRose/BackstagePassUpdater.cs | 17 +++++++ csharp.xUnit/GildedRose/IItemUpdater.cs | 10 ++++ .../GildedRose/IItemUpdaterFactory.cs | 6 +++ csharp.xUnit/GildedRose/ItemUpdaterBase.cs | 15 ++++++ csharp.xUnit/GildedRose/ItemUpdaterFactory.cs | 51 +++++++++++++++++++ csharp.xUnit/GildedRose/NormalItemUpdater.cs | 16 ++++++ csharp.xUnit/GildedRose/SulfurasUpdater.cs | 11 ++++ 8 files changed, 142 insertions(+) create mode 100644 csharp.xUnit/GildedRose/AgedBrieUpdater.cs create mode 100644 csharp.xUnit/GildedRose/BackstagePassUpdater.cs create mode 100644 csharp.xUnit/GildedRose/IItemUpdater.cs create mode 100644 csharp.xUnit/GildedRose/IItemUpdaterFactory.cs create mode 100644 csharp.xUnit/GildedRose/ItemUpdaterBase.cs create mode 100644 csharp.xUnit/GildedRose/ItemUpdaterFactory.cs create mode 100644 csharp.xUnit/GildedRose/NormalItemUpdater.cs create mode 100644 csharp.xUnit/GildedRose/SulfurasUpdater.cs diff --git a/csharp.xUnit/GildedRose/AgedBrieUpdater.cs b/csharp.xUnit/GildedRose/AgedBrieUpdater.cs new file mode 100644 index 00000000..955f2d96 --- /dev/null +++ b/csharp.xUnit/GildedRose/AgedBrieUpdater.cs @@ -0,0 +1,16 @@ +namespace GildedRoseKata; + +public class AgedBrieUpdater : ItemUpdaterBase +{ + public override string Name => "Aged Brie"; + + public override void Update(Item item) + { + item.Quality = ClampQuality(item.Quality + 1); + item.SellIn -= 1; + if (item.SellIn < 0) + { + item.Quality = ClampQuality(item.Quality + 1); + } + } +} diff --git a/csharp.xUnit/GildedRose/BackstagePassUpdater.cs b/csharp.xUnit/GildedRose/BackstagePassUpdater.cs new file mode 100644 index 00000000..c1c1f4af --- /dev/null +++ b/csharp.xUnit/GildedRose/BackstagePassUpdater.cs @@ -0,0 +1,17 @@ +namespace GildedRoseKata; + +public class BackstagePassUpdater : ItemUpdaterBase +{ + public override string Name => "Backstage passes to a TAFKAL80ETC concert"; + + public override void Update(Item item) + { + var increase = item.SellIn <= 5 ? 3 : item.SellIn <= 10 ? 2 : 1; + item.Quality = ClampQuality(item.Quality + increase); + item.SellIn -= 1; + if (item.SellIn < 0) + { + item.Quality = 0; + } + } +} diff --git a/csharp.xUnit/GildedRose/IItemUpdater.cs b/csharp.xUnit/GildedRose/IItemUpdater.cs new file mode 100644 index 00000000..c7a0a823 --- /dev/null +++ b/csharp.xUnit/GildedRose/IItemUpdater.cs @@ -0,0 +1,10 @@ +namespace GildedRoseKata; + +public interface IItemUpdater +{ + /// The exact item name this strategy handles ("default" for the fallback). + string Name { get; } + + /// Applies one full day: quality change + SellIn change + clamping. + void Update(Item item); +} diff --git a/csharp.xUnit/GildedRose/IItemUpdaterFactory.cs b/csharp.xUnit/GildedRose/IItemUpdaterFactory.cs new file mode 100644 index 00000000..66855fe6 --- /dev/null +++ b/csharp.xUnit/GildedRose/IItemUpdaterFactory.cs @@ -0,0 +1,6 @@ +namespace GildedRoseKata; + +public interface IItemUpdaterFactory +{ + IItemUpdater Get(Item item); +} diff --git a/csharp.xUnit/GildedRose/ItemUpdaterBase.cs b/csharp.xUnit/GildedRose/ItemUpdaterBase.cs new file mode 100644 index 00000000..a973b8d4 --- /dev/null +++ b/csharp.xUnit/GildedRose/ItemUpdaterBase.cs @@ -0,0 +1,15 @@ +using System; + +namespace GildedRoseKata; + +public abstract class ItemUpdaterBase : IItemUpdater +{ + public const int MinQuality = 0; + public const int MaxQuality = 50; + + public abstract string Name { get; } + + public abstract void Update(Item item); + + protected static int ClampQuality(int quality) => Math.Clamp(quality, MinQuality, MaxQuality); +} diff --git a/csharp.xUnit/GildedRose/ItemUpdaterFactory.cs b/csharp.xUnit/GildedRose/ItemUpdaterFactory.cs new file mode 100644 index 00000000..a6bc365d --- /dev/null +++ b/csharp.xUnit/GildedRose/ItemUpdaterFactory.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; + +namespace GildedRoseKata; + +public class ItemUpdaterFactory : IItemUpdaterFactory +{ + public const string ConjuredPrefix = "Conjured"; + private const string DefaultName = "default"; + + private readonly Dictionary _updatersByName; + private readonly IItemUpdater _fallback; + + public ItemUpdaterFactory(IEnumerable updaters) + { + _updatersByName = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var updater in updaters) + { + _updatersByName[updater.Name] = updater; + } + + if (!_updatersByName.TryGetValue(DefaultName, out _fallback)) + { + throw new ArgumentException($"A \"{DefaultName}\" fallback updater is required.", nameof(updaters)); + } + } + + public static ItemUpdaterFactory Default() => new(new IItemUpdater[] + { + new NormalItemUpdater(), + new AgedBrieUpdater(), + new SulfurasUpdater(), + new BackstagePassUpdater(), + }); + + public IItemUpdater Get(Item item) + { + if (_updatersByName.TryGetValue(item.Name, out var updater)) + { + return updater; + } + + if (item.Name.StartsWith(ConjuredPrefix, StringComparison.OrdinalIgnoreCase) && + _updatersByName.TryGetValue(ConjuredPrefix, out var conjured)) + { + return conjured; + } + + return _fallback; + } +} diff --git a/csharp.xUnit/GildedRose/NormalItemUpdater.cs b/csharp.xUnit/GildedRose/NormalItemUpdater.cs new file mode 100644 index 00000000..5f35bf3a --- /dev/null +++ b/csharp.xUnit/GildedRose/NormalItemUpdater.cs @@ -0,0 +1,16 @@ +namespace GildedRoseKata; + +public class NormalItemUpdater : ItemUpdaterBase +{ + public override string Name => "default"; + + public override void Update(Item item) + { + item.Quality = ClampQuality(item.Quality - 1); + item.SellIn -= 1; + if (item.SellIn < 0) + { + item.Quality = ClampQuality(item.Quality - 1); + } + } +} diff --git a/csharp.xUnit/GildedRose/SulfurasUpdater.cs b/csharp.xUnit/GildedRose/SulfurasUpdater.cs new file mode 100644 index 00000000..66ee371e --- /dev/null +++ b/csharp.xUnit/GildedRose/SulfurasUpdater.cs @@ -0,0 +1,11 @@ +namespace GildedRoseKata; + +public class SulfurasUpdater : ItemUpdaterBase +{ + public override string Name => "Sulfuras, Hand of Ragnaros"; + + public override void Update(Item item) + { + // Legendary item: Quality stays at 80 and SellIn never changes. + } +} From 4074da89e3cb5af7a6ef90299630a8d256f0f879 Mon Sep 17 00:00:00 2001 From: Artur Goloyad Date: Sat, 25 Jul 2026 20:50:46 +0200 Subject: [PATCH 5/7] refactor: collapse UpdateQuality to delegate to the factory GildedRose now resolves each item to its strategy and applies it; all rules live in the strategies. The original one-arg constructor keeps working by delegating to ItemUpdaterFactory.Default(); a second constructor allows injecting a custom IItemUpdaterFactory. No behaviour change: the ThirtyDays approval snapshot and all existing-type spec tests pass unchanged. Co-Authored-By: Claude Fable 5 --- csharp.xUnit/GildedRose/GildedRose.cs | 90 ++++----------------------- 1 file changed, 13 insertions(+), 77 deletions(-) diff --git a/csharp.xUnit/GildedRose/GildedRose.cs b/csharp.xUnit/GildedRose/GildedRose.cs index c08bf5f8..9b37db99 100644 --- a/csharp.xUnit/GildedRose/GildedRose.cs +++ b/csharp.xUnit/GildedRose/GildedRose.cs @@ -1,89 +1,25 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace GildedRoseKata; public class GildedRose { - IList Items; + private readonly IList _items; + private readonly IItemUpdaterFactory _factory; - public GildedRose(IList Items) + public GildedRose(IList items) : this(items, ItemUpdaterFactory.Default()) { - this.Items = Items; + } + + public GildedRose(IList items, IItemUpdaterFactory factory) + { + _items = items; + _factory = factory; } public void UpdateQuality() { - for (var i = 0; i < Items.Count; i++) - { - if (Items[i].Name != "Aged Brie" && Items[i].Name != "Backstage passes to a TAFKAL80ETC concert") - { - if (Items[i].Quality > 0) - { - if (Items[i].Name != "Sulfuras, Hand of Ragnaros") - { - Items[i].Quality = Items[i].Quality - 1; - } - } - } - else - { - if (Items[i].Quality < 50) - { - Items[i].Quality = Items[i].Quality + 1; - - if (Items[i].Name == "Backstage passes to a TAFKAL80ETC concert") - { - if (Items[i].SellIn < 11) - { - if (Items[i].Quality < 50) - { - Items[i].Quality = Items[i].Quality + 1; - } - } - - if (Items[i].SellIn < 6) - { - if (Items[i].Quality < 50) - { - Items[i].Quality = Items[i].Quality + 1; - } - } - } - } - } - - if (Items[i].Name != "Sulfuras, Hand of Ragnaros") - { - Items[i].SellIn = Items[i].SellIn - 1; - } - - if (Items[i].SellIn < 0) - { - if (Items[i].Name != "Aged Brie") - { - if (Items[i].Name != "Backstage passes to a TAFKAL80ETC concert") - { - if (Items[i].Quality > 0) - { - if (Items[i].Name != "Sulfuras, Hand of Ragnaros") - { - Items[i].Quality = Items[i].Quality - 1; - } - } - } - else - { - Items[i].Quality = Items[i].Quality - Items[i].Quality; - } - } - else - { - if (Items[i].Quality < 50) - { - Items[i].Quality = Items[i].Quality + 1; - } - } - } - } + foreach (var item in _items) + _factory.Get(item).Update(item); } -} \ No newline at end of file +} From eb87a35411310245fccc67f9c8b1446f4272a6c6 Mon Sep 17 00:00:00 2001 From: Artur Goloyad Date: Sat, 25 Jul 2026 20:51:28 +0200 Subject: [PATCH 6/7] feat: implement ConjuredItemUpdater Conjured items degrade twice as fast: -2 before sell-by, -4 after, never below 0. Registered in ItemUpdaterFactory.Default() and resolved by the Conjured prefix rule, so the whole Conjured family is covered. The four Conjured spec tests go green. The ThirtyDays approval snapshot now shows the intended Conjured-only diff; it is re-approved in the next commit. Co-Authored-By: Claude Fable 5 --- csharp.xUnit/GildedRose/ConjuredItemUpdater.cs | 17 +++++++++++++++++ csharp.xUnit/GildedRose/ItemUpdaterFactory.cs | 1 + 2 files changed, 18 insertions(+) create mode 100644 csharp.xUnit/GildedRose/ConjuredItemUpdater.cs diff --git a/csharp.xUnit/GildedRose/ConjuredItemUpdater.cs b/csharp.xUnit/GildedRose/ConjuredItemUpdater.cs new file mode 100644 index 00000000..8d6499ef --- /dev/null +++ b/csharp.xUnit/GildedRose/ConjuredItemUpdater.cs @@ -0,0 +1,17 @@ +namespace GildedRoseKata; + +public class ConjuredItemUpdater : ItemUpdaterBase +{ + // Matched by prefix in ItemUpdaterFactory: handles every "Conjured..." item. + public override string Name => ItemUpdaterFactory.ConjuredPrefix; + + public override void Update(Item item) + { + item.Quality = ClampQuality(item.Quality - 2); + item.SellIn -= 1; + if (item.SellIn < 0) + { + item.Quality = ClampQuality(item.Quality - 2); + } + } +} diff --git a/csharp.xUnit/GildedRose/ItemUpdaterFactory.cs b/csharp.xUnit/GildedRose/ItemUpdaterFactory.cs index a6bc365d..02968064 100644 --- a/csharp.xUnit/GildedRose/ItemUpdaterFactory.cs +++ b/csharp.xUnit/GildedRose/ItemUpdaterFactory.cs @@ -31,6 +31,7 @@ public class ItemUpdaterFactory : IItemUpdaterFactory new AgedBrieUpdater(), new SulfurasUpdater(), new BackstagePassUpdater(), + new ConjuredItemUpdater(), }); public IItemUpdater Get(Item item) From 2477b5317043d4eb6a818eb44ffe7273252df1cc Mon Sep 17 00:00:00 2001 From: Artur Goloyad Date: Sat, 25 Jul 2026 20:52:03 +0200 Subject: [PATCH 7/7] test: re-approve ThirtyDays snapshot with Conjured fix The only diff vs the previous baseline is the Conjured Mana Cake line on days 1-4 (now degrading -2 before sell-by and -4 after, floored at 0). All other item types are byte-identical. Full suite: 24/24 green. Co-Authored-By: Claude Fable 5 --- .../GildedRoseTests/ApprovalTest.ThirtyDays.verified.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/csharp.xUnit/GildedRoseTests/ApprovalTest.ThirtyDays.verified.txt b/csharp.xUnit/GildedRoseTests/ApprovalTest.ThirtyDays.verified.txt index cd66984f..f80af4e4 100644 --- a/csharp.xUnit/GildedRoseTests/ApprovalTest.ThirtyDays.verified.txt +++ b/csharp.xUnit/GildedRoseTests/ApprovalTest.ThirtyDays.verified.txt @@ -21,7 +21,7 @@ Sulfuras, Hand of Ragnaros, -1, 80 Backstage passes to a TAFKAL80ETC concert, 14, 21 Backstage passes to a TAFKAL80ETC concert, 9, 50 Backstage passes to a TAFKAL80ETC concert, 4, 50 -Conjured Mana Cake, 2, 5 +Conjured Mana Cake, 2, 4 -------- day 2 -------- name, sellIn, quality @@ -33,7 +33,7 @@ Sulfuras, Hand of Ragnaros, -1, 80 Backstage passes to a TAFKAL80ETC concert, 13, 22 Backstage passes to a TAFKAL80ETC concert, 8, 50 Backstage passes to a TAFKAL80ETC concert, 3, 50 -Conjured Mana Cake, 1, 4 +Conjured Mana Cake, 1, 2 -------- day 3 -------- name, sellIn, quality @@ -45,7 +45,7 @@ Sulfuras, Hand of Ragnaros, -1, 80 Backstage passes to a TAFKAL80ETC concert, 12, 23 Backstage passes to a TAFKAL80ETC concert, 7, 50 Backstage passes to a TAFKAL80ETC concert, 2, 50 -Conjured Mana Cake, 0, 3 +Conjured Mana Cake, 0, 0 -------- day 4 -------- name, sellIn, quality @@ -57,7 +57,7 @@ Sulfuras, Hand of Ragnaros, -1, 80 Backstage passes to a TAFKAL80ETC concert, 11, 24 Backstage passes to a TAFKAL80ETC concert, 6, 50 Backstage passes to a TAFKAL80ETC concert, 1, 50 -Conjured Mana Cake, -1, 1 +Conjured Mana Cake, -1, 0 -------- day 5 -------- name, sellIn, quality