451181e60175 — MiyamotoAkira 2 years ago
Refactoring Program and changing Item from class to F# Record Type
M src/GildedRose.Console/GildedRose.Console.csproj +4 -0
@@ 1,5 1,9 @@ 
 <Project Sdk="Microsoft.NET.Sdk">
 
+  <ItemGroup>
+    <ProjectReference Include="..\GildedRose.FSharp.Library\GildedRose.FSharp.Library.fsproj" />
+  </ItemGroup>
+
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <TargetFramework>net5.0</TargetFramework>

          
M src/GildedRose.Console/Program.cs +88 -86
@@ 1,32 1,36 @@ 
 using System.Collections.Generic;
+using System.Linq;
+using GildedRose.FSharp.Library;
 
 namespace GildedRose.Console
 {
     public class Program
     {
-        public IList<Item> Items;
+        public const string Brie = "Aged Brie";
+        public const string Vest = "+5 Dexterity Vest";
+        public const string Elixir = "Elixir of the Mongoose";
+        public const string Sulfuras = "Sulfuras, Hand of Ragnaros";
+        public const string Backstage = "Backstage passes to a TAFKAL80ETC concert";
+        public const string ConjuredCake = "Conjured Mana Cake";
+
+        public IList<Data.Item> Items;
         static void Main(string[] args)
         {
             System.Console.WriteLine("OMGHAI!");
 
             var app = new Program()
-                          {
-                              Items = new List<Item>
-                                          {
-                                              new Item {Name = "+5 Dexterity Vest", SellIn = 10, Quality = 20},
-                                              new Item {Name = "Aged Brie", SellIn = 2, Quality = 0},
-                                              new Item {Name = "Elixir of the Mongoose", SellIn = 5, Quality = 7},
-                                              new Item {Name = "Sulfuras, Hand of Ragnaros", SellIn = 0, Quality = 80},
-                                              new Item
-                                                  {
-                                                      Name = "Backstage passes to a TAFKAL80ETC concert",
-                                                      SellIn = 15,
-                                                      Quality = 20
-                                                  },
-                                              new Item {Name = "Conjured Mana Cake", SellIn = 3, Quality = 6}
-                                          }
+            {
+                Items = new List<Data.Item>
+                {
+                    new Data.Item(Vest, 10, 20),
+                    new Data.Item (Brie, 2, 0),
+                    new Data.Item  (Elixir, 5, 7),
+                    new Data.Item (Sulfuras, 0, 80),
+                    new Data.Item (Backstage, 15, 20),
+                    new Data.Item (ConjuredCake, 3, 6)
+                }
 
-                          };
+            };
 
             app.UpdateQuality();
 

          
@@ 36,93 40,91 @@ namespace GildedRose.Console
 
         public void UpdateQuality()
         {
-            for (var i = 0; i < Items.Count; i++)
+            Items.ToList().ForEach(item => {
+                UpdateQualityBeforeSellIn(item);;
+                UpdateSellIn(item);
+                UpdateQualityAfterSellIn(item);
+            });
+        }
+
+        private void UpdateQualityBeforeSellIn(Data.Item item)
+        {
+            switch (item.Name)
             {
-                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)
+                case Brie:
+                    if (item.Quality < 50)
                     {
-                        Items[i].Quality = Items[i].Quality + 1;
+                        item.Quality = item.Quality + 1;
+                    }
+                    return;
+                case Backstage:
+                    if (item.Quality < 50)
+                    {
+                        item.Quality = item.Quality + 1;
 
-                        if (Items[i].Name == "Backstage passes to a TAFKAL80ETC concert")
+                        if (item.SellIn < 11)
                         {
-                            if (Items[i].SellIn < 11)
+                            if (item.Quality < 50)
                             {
-                                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;
-                                }
+                                item.Quality = item.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 (item.SellIn < 6)
                         {
-                            if (Items[i].Quality > 0)
+                            if (item.Quality < 50)
                             {
-                                if (Items[i].Name != "Sulfuras, Hand of Ragnaros")
-                                {
-                                    Items[i].Quality = Items[i].Quality - 1;
-                                }
+                                item.Quality = item.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;
-                        }
-                    }
-                }
+                    return;
+                case Sulfuras:
+                    return;
+                default:
+                    if (item.Quality > 0)
+                        item.Quality = item.Quality - 1;
+                    return;
             }
         }
 
-    }
-
-    public class Item
-    {
-        public string Name { get; set; }
+        private void UpdateQualityAfterSellIn(Data.Item item)
+        {
+            if (item.SellIn >= 0) return;
 
-        public int SellIn { get; set; }
-
-        public int Quality { get; set; }
-
-        public override string ToString()
+            switch (item.Name)
+            {
+                case Brie:
+                    if (item.Quality < 50)
+                    {
+                        item.Quality = item.Quality + 1;
+                    }
+                    return;
+                case Sulfuras:
+                    return;
+                case Backstage:
+                    item.Quality = item.Quality - item.Quality;
+                    return;
+                default:
+                    if (item.Quality > 0)
+                    {
+                        item.Quality = item.Quality - 1;
+                    }
+                    return;
+            }
+        }
+        
+        private void UpdateSellIn(Data.Item item)
         {
-            return $"Name: {Name}, SellIn: {SellIn}, Quality: {Quality}";
+            switch (item.Name)
+            {
+                case Sulfuras:
+                    break;
+                default:
+                    item.SellIn = item.SellIn -1;
+                    break;
+            }
         }
     }
 

          
A => src/GildedRose.FSharp.Library/GildedRose.FSharp.Library.fsproj +11 -0
@@ 0,0 1,11 @@ 
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Compile Include="Library.fs" />
+  </ItemGroup>
+
+</Project>

          
A => src/GildedRose.FSharp.Library/Library.fs +7 -0
@@ 0,0 1,7 @@ 
+namespace GildedRose.FSharp.Library
+
+module Data =
+    type Item =
+        { mutable Name : string
+          mutable SellIn : int
+          mutable Quality : int}

          
M tests/GildedRose.FSharp.Tests/GildedRose.FSharp.Tests.fsproj +1 -0
@@ 27,6 27,7 @@ 
 
   <ItemGroup>
     <ProjectReference Include="..\..\src\GildedRose.Console\GildedRose.Console.csproj" />
+    <ProjectReference Include="..\..\src\GildedRose.FSharp.Library\GildedRose.FSharp.Library.fsproj" />
   </ItemGroup>
 
 </Project>

          
M tests/GildedRose.FSharp.Tests/Tests.fs +14 -12
@@ 4,6 4,7 @@ open System
 open Xunit
 
 open GildedRose.Console
+open GildedRose.FSharp.Library.Data
 
 module Tests =
 

          
@@ 16,7 17,7 @@ module Tests =
         [<Fact>]
         let ``Standard item degrades quality before "sell in"`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Vest, SellIn = 2, Quality = 20)])
+            app.Items <- ResizeArray<Item>([ {Name = Vest; SellIn = 2; Quality = 20}])
             let item = findItemByName app Vest
 
             Assert.Equal(20, item.Quality)

          
@@ 27,7 28,7 @@ module Tests =
         [<Fact>]
         let ``Standard item sell in gets reduced`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Vest, SellIn = 2, Quality = 20)])
+            app.Items <- ResizeArray<Item>([ {Name = Vest; SellIn = 2; Quality = 20}])
             let item = findItemByName app Vest
 
             Assert.Equal(2, item.SellIn)

          
@@ 37,7 38,7 @@ module Tests =
         [<Fact>]
         let ``Standard item degrades in quality after "sell in"`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Vest, SellIn = 0, Quality = 20)])
+            app.Items <- ResizeArray<Item>([ {Name = Vest; SellIn = 0; Quality = 20}])
             let item = findItemByName app Vest
 
             Assert.Equal(20, item.Quality)

          
@@ 47,7 48,7 @@ module Tests =
         [<Fact>]
         let ``Standard item don't go below 0 quality`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Vest, SellIn = 0, Quality = 0)])
+            app.Items <- ResizeArray<Item>([ {Name = Vest; SellIn = 0; Quality = 0}])
             let item = findItemByName app Vest
             
             Assert.Equal(0, item.Quality)

          
@@ 60,7 61,7 @@ module Tests =
         [<Fact>]
         let ``Sulfuras quality is constant`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Sulfuras, SellIn = 0, Quality = 80)])
+            app.Items <- ResizeArray<Item>([ {Name = Sulfuras; SellIn = 0; Quality = 80}])
             let item = findItemByName app Sulfuras
 
             Assert.Equal(80, item.Quality)

          
@@ 70,7 71,7 @@ module Tests =
         [<Fact>]
         let ``Sulfuras "sell in" is always Zero`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Sulfuras, SellIn = 0, Quality = 80)])
+            app.Items <- ResizeArray<Item>([ {Name = Sulfuras; SellIn = 0; Quality = 80}])
             let item = findItemByName app Sulfuras
 
             Assert.Equal(0, item.SellIn)

          
@@ 83,7 84,7 @@ module Tests =
         [<Fact>]
         let ``Backstage goes to zero quality after "sell in"`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Backstage, SellIn = 0, Quality = 3)])
+            app.Items <- ResizeArray<Item>([ {Name = Backstage; SellIn = 0; Quality = 3}])
             let item = findItemByName app Backstage
 
             Assert.Equal(3, item.Quality)

          
@@ 93,7 94,7 @@ module Tests =
         [<Fact>]
         let ``Backstage quality goes up by two with 10 or less days`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Backstage, SellIn = 10, Quality = 3)])
+            app.Items <- ResizeArray<Item>([ {Name = Backstage; SellIn = 10; Quality = 3}])
             let item = findItemByName app Backstage
 
             Assert.Equal(3, item.Quality)

          
@@ 103,7 104,7 @@ module Tests =
         [<Fact>]
         let ``Backstage quality goes up by three with 5 or less days`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Backstage, SellIn = 5, Quality = 3)])
+            app.Items <- ResizeArray<Item>([ {Name = Backstage; SellIn = 5; Quality = 3}])
             let item = findItemByName app Backstage
 
             Assert.Equal(3, item.Quality)

          
@@ 116,7 117,7 @@ module Tests =
         [<Fact>]
         let ``Aged brie increases quality `` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Brie, SellIn = 2, Quality = 0)])
+            app.Items <- ResizeArray<Item>([ {Name = Brie; SellIn = 2; Quality = 0}])
             let item = findItemByName app Brie
 
             Assert.Equal(0, item.Quality)

          
@@ 126,7 127,8 @@ module Tests =
         [<Fact>]
         let ``Aged brie quality doesn't go over 50`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Brie, SellIn = 2, Quality = 50)])
+            app.Items <- ResizeArray<Item>([ {Name = Brie; SellIn = 2; Quality = 50}])
+
             let item = findItemByName app Brie
 
             Assert.Equal(50, item.Quality)

          
@@ 136,7 138,7 @@ module Tests =
         [<Fact>]
         let ``Aged brie quality doesn't increase if already over 50`` () =
             let app = new Program()
-            app.Items <- ResizeArray<Item>([new Item (Name = Brie, SellIn = 2, Quality = 51)])
+            app.Items <- ResizeArray<Item>([ {Name = Brie; SellIn = 2; Quality = 51}])
             let item = findItemByName app Brie
 
             Assert.Equal(51, item.Quality)

          
M tests/GildedRose.Tests/BaseRules.cs +14 -13
@@ 3,6 3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using Xunit;
 using GildedRose.Console;
+using GildedRose.FSharp.Library;
 
 namespace GildedRose.Tests
 {

          
@@ 14,7 15,7 @@ namespace GildedRose.Tests
         public const string Sulfuras = "Sulfuras, Hand of Ragnaros";
         public const string Backstage = "Backstage passes to a TAFKAL80ETC concert";
         
-        public Item FindItemByName(IList<Item> items, string name)
+        public Data.Item FindItemByName(IList<Data.Item> items, string name)
         {
             return items.First(x => x.Name.Equals(name));
         }

          
@@ 24,7 25,7 @@ namespace GildedRose.Tests
             [Fact]
             void VestItemDegradesQualityBeforeSellIn()
             {
-                var app = new Program() { Items = new List<Item> {new Item {Name = Vest, SellIn = 2, Quality = 20}}};
+                var app = new Program() { Items = new List<Data.Item> {new Data.Item (Vest, 2, 20)}};
                 var item = FindItemByName(app.Items, Vest);
                 Assert.Equal(20, item.Quality);
                 app.UpdateQuality();

          
@@ 34,7 35,7 @@ namespace GildedRose.Tests
             [Fact]
             void AnItemSellInGetsReduced()
             {
-                var app = new Program() { Items = new List<Item> {new Item {Name = Vest, SellIn = 2, Quality = 3}}};
+                var app = new Program() { Items = new List<Data.Item> {new Data.Item (Vest, 2, 3)}};
                 var item = FindItemByName(app.Items, Vest);
                 Assert.Equal(2, item.SellIn);
                 app.UpdateQuality();

          
@@ 44,7 45,7 @@ namespace GildedRose.Tests
             [Fact]
             void ItemDegradesQualityTwiceAfterSellIn()
             {
-                var app = new Program() { Items = new List<Item> {new Item {Name = Vest, SellIn = 0, Quality = 3}}};
+                var app = new Program() { Items = new List<Data.Item> {new Data.Item (Vest, 0, 3)}};
                 var item = FindItemByName(app.Items, Vest);
                 Assert.Equal(3, item.Quality);
                 app.UpdateQuality();

          
@@ 54,7 55,7 @@ namespace GildedRose.Tests
             [Fact]
             void AnItemDontGoBelowZeroQuality()
             {
-                var app = new Program() { Items = new List<Item> {new Item {Name = "Test", SellIn = 1, Quality = 0}}};
+                var app = new Program() { Items = new List<Data.Item> {new Data.Item ("Test", 1, 0)}};
                 var item = FindItemByName(app.Items, "Test");
                 Assert.Equal(0, item.Quality);
                 app.UpdateQuality();

          
@@ 67,7 68,7 @@ namespace GildedRose.Tests
             [Fact]
             void SulfurasQualityIsConstant()
             {
-                var app = new Program() {Items = new List<Item> {new Item {Name = Sulfuras, SellIn = 0, Quality = 80}}};
+                var app = new Program() {Items = new List<Data.Item> {new Data.Item (Sulfuras, 0, 80)}};
                 var item = FindItemByName(app.Items, Sulfuras);
                 Assert.Equal(80, item.Quality);
                 app.UpdateQuality();

          
@@ 77,7 78,7 @@ namespace GildedRose.Tests
             [Fact]
             void SulfurasSellInIsAlwaysZero()
             {
-                var app = new Program() {Items = new List<Item> {new Item {Name = Sulfuras, SellIn = 0, Quality = 80}}};
+                var app = new Program() {Items = new List<Data.Item> {new Data.Item (Sulfuras, 0, 80)}};
                 var item = FindItemByName(app.Items, Sulfuras);
                 Assert.Equal(0, item.SellIn);
                 app.UpdateQuality();

          
@@ 90,7 91,7 @@ namespace GildedRose.Tests
             [Fact]
             void BackstageGoesToZeroQualityAfterSellIn()
             {
-                var app = new Program() { Items = new List<Item> {new Item {Name = Backstage, SellIn = 0, Quality = 3}}};
+                var app = new Program() { Items = new List<Data.Item> {new Data.Item (Backstage, 0, 3)}};
                 var item = FindItemByName(app.Items, Backstage);
                 Assert.Equal(3, item.Quality);
                 app.UpdateQuality();

          
@@ 100,7 101,7 @@ namespace GildedRose.Tests
             [Fact]
             void BackstageGoesQualityByTwoWith10OrLessDays()
             {
-                var app = new Program() { Items = new List<Item> {new Item {Name = Backstage, SellIn = 10, Quality = 3}}};
+                var app = new Program() { Items = new List<Data.Item> {new Data.Item (Backstage, 10, 3)}};
                 var item = FindItemByName(app.Items, Backstage);
                 Assert.Equal(3, item.Quality);
                 app.UpdateQuality();

          
@@ 110,7 111,7 @@ namespace GildedRose.Tests
             [Fact]
             void BackstageGoesQualityByThreeWith5OrLessDays()
             {
-                var app = new Program() { Items = new List<Item> {new Item {Name = Backstage, SellIn = 5, Quality = 3}}};
+                var app = new Program() { Items = new List<Data.Item> {new Data.Item (Backstage, 5, 3)}};
                 var item = FindItemByName(app.Items, Backstage);
                 Assert.Equal(3, item.Quality);
                 app.UpdateQuality();

          
@@ 123,7 124,7 @@ namespace GildedRose.Tests
             [Fact]
             void AgedBriesIncreasesQuality()
             {
-                var app = new Program() { Items = new List<Item> {new Item {Name = Brie, SellIn = 2, Quality = 0}}};
+                var app = new Program() { Items = new List<Data.Item> {new Data.Item (Brie, 2, 0)}};
                 var item = FindItemByName(app.Items, Brie);
                 Assert.Equal(0, item.Quality);
                 app.UpdateQuality();

          
@@ 133,7 134,7 @@ namespace GildedRose.Tests
             [Fact]
             void AgedBrieQualityDoesntGoOver50()
             {
-                var app = new Program() { Items = new List<Item> {new Item {Name = Brie, SellIn = 2, Quality = 50}}};
+                var app = new Program() { Items = new List<Data.Item> {new Data.Item (Brie, 2, 50)}};
                 var item = FindItemByName(app.Items, Brie);
                 Assert.Equal(50, item.Quality);
                 app.UpdateQuality();

          
@@ 143,7 144,7 @@ namespace GildedRose.Tests
             [Fact]
             void AgedBrieQualityDoesntIncreaseAfter50()
             {
-                var app = new Program() { Items = new List<Item> {new Item {Name = Brie, SellIn = 2, Quality = 51}}};
+                var app = new Program() { Items = new List<Data.Item> {new Data.Item (Brie, 2, 51)}};
                 var item = FindItemByName(app.Items, Brie);
                 Assert.Equal(51, item.Quality);
                 app.UpdateQuality();

          
M tests/GildedRose.Tests/GildedRose.Tests.csproj +1 -0
@@ 21,6 21,7 @@ 
 
   <ItemGroup>
     <ProjectReference Include="..\..\src\GildedRose.Console\GildedRose.Console.csproj" />
+    <ProjectReference Include="..\..\src\GildedRose.FSharp.Library\GildedRose.FSharp.Library.fsproj" />
   </ItemGroup>
 
 </Project>