29c697fc4d45 — MiyamotoAkira 11 months ago
Basic new project using the original code for the GildedRose
A => .hgignore +2 -0
@@ 0,0 1,2 @@ 
+obj/
+bin/
  No newline at end of file

          
A => GildedRose.sln +71 -0
@@ 0,0 1,71 @@ 
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26124.0
+MinimumVisualStudioVersion = 15.0.26124.0
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{87668963-65F4-4F94-80A4-EDF81E142AD9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GildedRose.Console", "src\GildedRose.Console\GildedRose.Console.csproj", "{955348D2-E8BB-4A86-8CB1-1872C97B8B95}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{1272742F-AB84-430F-BADF-A036532A31FA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GildedRose.Tests", "tests\GildedRose.Tests\GildedRose.Tests.csproj", "{32F083A7-48EA-45AD-8194-1154E9BCF58C}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "GildedRose.FSharp.Tests", "tests\GildedRose.FSharp.Tests\GildedRose.FSharp.Tests.fsproj", "{B55EB18E-2477-4D49-B31C-2E543212443A}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Debug|x64.Build.0 = Debug|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Debug|x86.Build.0 = Debug|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Release|Any CPU.Build.0 = Release|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Release|x64.ActiveCfg = Release|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Release|x64.Build.0 = Release|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Release|x86.ActiveCfg = Release|Any CPU
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95}.Release|x86.Build.0 = Release|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Debug|x64.Build.0 = Debug|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Debug|x86.Build.0 = Debug|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Release|x64.ActiveCfg = Release|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Release|x64.Build.0 = Release|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Release|x86.ActiveCfg = Release|Any CPU
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C}.Release|x86.Build.0 = Release|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Debug|x64.Build.0 = Debug|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Debug|x86.Build.0 = Debug|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Release|x64.ActiveCfg = Release|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Release|x64.Build.0 = Release|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Release|x86.ActiveCfg = Release|Any CPU
+		{B55EB18E-2477-4D49-B31C-2E543212443A}.Release|x86.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{955348D2-E8BB-4A86-8CB1-1872C97B8B95} = {87668963-65F4-4F94-80A4-EDF81E142AD9}
+		{32F083A7-48EA-45AD-8194-1154E9BCF58C} = {1272742F-AB84-430F-BADF-A036532A31FA}
+		{B55EB18E-2477-4D49-B31C-2E543212443A} = {1272742F-AB84-430F-BADF-A036532A31FA}
+	EndGlobalSection
+EndGlobal

          
A => MIT-LICENSE.txt +49 -0
@@ 0,0 1,49 @@ 
+This works is based on the git repo set by NotMyself.
+
+For my modifications:
+
+The MIT License (MIT)
+
+Copyright (c) 2020 Jorge Gueorguiev Garcia
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+For the original work:
+
+The MIT License (MIT)
+
+Copyright (c) 2011 @NotMyself
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

          
A => NuGet.config +9 -0
@@ 0,0 1,9 @@ 
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <config>
+    	<add key="repositoryPath" value="packages" />
+    </config>
+    <packageSources>
+	<add key="NuGet official package source" value="https://nuget.org/api/v2/" />
+    </packageSources>
+</configuration>

          
A => README.md +72 -0
@@ 0,0 1,72 @@ 
+# Gilded Rose Refactoring Kata
+
+This repo is to be used as an example of start the usage of F#.
+
+# Original Documentation: Gilded Rose Refactoring Kata
+
+Hi and welcome to team Gilded Rose. As you know, we are a small inn with a 
+prime location in a prominent city ran by a friendly innkeeper named 
+Allison. We also buy and sell only the finest goods. Unfortunately, our 
+goods are constantly degrading in quality as they approach their sell by 
+date. We have a system in place that updates our inventory for us. It was 
+developed by a no-nonsense type named Leeroy, who has moved on to new 
+adventures. Your task is to add the new feature to our system so that we 
+can begin selling a new category of items. First an introduction to our 
+system:
+
+- All items have a SellIn value which denotes the number of days we have 
+to sell the item
+- All items have a Quality value which denotes how valuable the item is
+- At the end of each day our system lowers both values for every item
+
+Pretty simple, right? Well this is where it gets interesting:
+
+- Once the sell by date has passed, Quality degrades twice as fast
+- The Quality of an item is never negative
+- "Aged Brie" actually increases in Quality the older it gets
+- The Quality of an item is never more than 50
+- "Sulfuras", being a legendary item, never has to be sold or decreases 
+in Quality
+- "Backstage passes", like aged brie, increases in Quality as it's SellIn 
+value approaches; Quality increases by 2 when there are 10 days or less 
+and by 3 when there are 5 days or less but Quality drops to 0 after the 
+concert
+
+We have recently signed a supplier of conjured items. This requires an 
+update to our system:
+
+- "Conjured" items degrade in Quality twice as fast as normal items
+
+Feel free to make any changes to the UpdateQuality method and add any 
+new code as long as everything still works correctly. However, do not 
+alter the Item class or Items property as those belong to the goblin 
+in the corner who will insta-rage and one-shot you as he doesn't 
+believe in shared code ownership (you can make the UpdateQuality 
+method and Items property static if you like, we'll cover for you).
+
+Just for clarification, an item can never have its Quality increase 
+above 50, however "Sulfuras" is a legendary item and as such its 
+Quality is 80 and it never alters.
+
+## Getting Started
+
+Clone the repository. Run build.bat from Powershell. If you see 
+output similar to the following screenshot, you are ready to 
+start refactoring.
+
+![alt text](images/build_output.png "Good Build Output")
+
+## Who, What, Why?
+Who: [@TerryHughes](https://twitter.com/TerryHughes), [@NotMyself](https://twitter.com/NotMyself)
+
+What & Why: [Refactor This: The Gilded Rose Kata](http://iamnotmyself.com/2011/02/13/refactor-this-the-gilded-rose-kata/)
+
+## License
+
+MIT
+
+## Suggested attribution
+
+This work is by [@TerryHughes](https://twitter.com/TerryHughes), [@NotMyself](https://twitter.com/NotMyself)
+
+The repository can be found at [https://github.com/NotMyself/GildedRose](https://github.com/NotMyself/GildedRose)

          
A => build.bat +57 -0
@@ 0,0 1,57 @@ 
+@ECHO OFF
+
+powershell -NoProfile -ExecutionPolicy Unrestricted -Command ^
+
+$ErrorActionPreference = 'Stop'; ^
+$WorkingDir = Convert-Path .; ^
+$BuildPackageName = 'psake.net'; ^
+$PSMajorVersion = 3; ^
+
+if ($PSVersionTable.PSVersion.Major -lt $PSMajorVersion) { Write-Host -ForegroundColor Red "ERROR: The script cannot be run because it requires Windows PowerShell version 3.0 or greater"; exit 1 }; ^
+
+function Get-PackageDir() { ^
+	param([xml]$packagesXml, [string]$packagesDir, [string]$packageName); ^
+	ForEach ($package in $packagesXml.packages.package) { ^
+		if ($package.id -eq $packageName) { return Join-Path $packagesDir ($package.id + '.' + $package.version) } ^
+	} else { ^
+		Write-Host -ForegroundColor Red "ERROR: Cannot find '$packageName' package"; ^
+		exit 1; ^
+	}; ^
+}; ^
+
+function Test-LastExitCode { if ($LastExitCode -ne 0 -and $LastExitCode) { Write-Host "ExitCode: $LastExitCode" -ForegroundColor Red; exit $LastExitCode } }; ^
+
+$NuGet = Join-Path $WorkingDir '.nuget\NuGet.exe'; ^
+if (-not (Test-Path $NuGet)) { ^
+	Write-Host 'Downloading NuGet.exe' -ForegroundColor Cyan; ^
+	$(New-Object System.Net.WebClient).DownloadFile('https://www.nuget.org/nuget.exe', $NuGet); ^
+}; ^
+
+$PackagesDir = cmd /c "$NuGet" config RepositoryPath -AsPath; ^
+if ($PackagesDir -eq '"WARNING: Key ''RepositoryPath'' not found.'") { Write-Host -ForegroundColor Red "ERROR: Cannot find 'RepositoryPath' key in NuGet.config"; exit 1 }; ^
+
+$PackagesConfig = Join-Path $WorkingDir '.nuget\packages.config'; ^
+if (-not (Test-Path $PackagesConfig)) { Write-Host -ForegroundColor Red "ERROR: Cannot find solution 'packages.config'"; exit 1 }; ^
+[xml]$PackagesXml = Get-Content $PackagesConfig; ^
+
+Write-Host "Restoring NuGet packages" -ForegroundColor Cyan; ^
+cmd /c $NuGet restore; ^
+Test-LastExitCode; ^
+
+Write-Host "Atempting to resolve semantic version" -ForegroundColor Cyan; ^
+$GitVersion =  Out-String -InputObject (cmd /c (Join-Path (Get-PackageDir $PackagesXml $PackagesDir 'GitVersion.CommandLine') 'tools\GitVersion.exe')); ^
+try { Write-Host "Semantic version: " $(ConvertFrom-Json -InputObject $GitVersion).SemVer } catch [System.Exception] { Write-Host -ForegroundColor Red $GitVersion; exit 1 }; ^
+
+$Psake = Join-Path (Get-PackageDir $PackagesXml $PackagesDir 'psake') 'tools\psake.psm1'; ^
+if (Test-Path $(Join-Path $WorkingDir ($BuildPackageName + '\Functions.psm1'))) { ^
+	$Functions = Join-Path $WorkingDir ($BuildPackageName + '\Functions.psm1') ^
+} else { ^
+	$Functions = Join-Path (Get-PackageDir $PackagesXml $PackagesDir $BuildPackageName) '\Functions.psm1'; ^
+}; ^
+
+Import-Module "$Psake", "$Functions"; ^
+Write-Host 'Invoking psake' -ForegroundColor Cyan; ^
+Invoke-psake $(Join-Path $WorkingDir '.\tasks.ps1') %*; ^
+
+if (($psake.build_success -eq $false) -and ($LastExitCode -eq 0 -or -not ($LastExitCode))) { $LastExitCode = 1 }; ^
+Test-LastExitCode;
  No newline at end of file

          
A => src/GildedRose.Console/GildedRose.Console.csproj +8 -0
@@ 0,0 1,8 @@ 
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net5.0</TargetFramework>
+  </PropertyGroup>
+
+</Project>

          
A => src/GildedRose.Console/Program.cs +124 -0
@@ 0,0 1,124 @@ 
+using System.Collections.Generic;
+
+namespace GildedRose.Console
+{
+    class Program
+    {
+        IList<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}
+                                          }
+
+                          };
+
+            app.UpdateQuality();
+
+            System.Console.ReadKey();
+
+        }
+
+        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;
+                        }
+                    }
+                }
+            }
+        }
+
+    }
+
+    public class Item
+    {
+        public string Name { get; set; }
+
+        public int SellIn { get; set; }
+
+        public int Quality { get; set; }
+    }
+
+}

          
A => tasks.ps1 +13 -0
@@ 0,0 1,13 @@ 
+# Needed because running 'psake.bat -doc' result in $psake.build_success being false
+$psake.build_success = $true
+
+properties {
+	. $(Get-DefaultPropertiesFile)
+	$src_dir = Join-Path $base_dir "src"
+	$project_name = "GildedRose.Console"
+	$project_dir = Join-Path $src_dir $project_name
+}
+
+Import-DefaultTasks Version, Clean, Build, Test
+
+Task Default -Depends Clean, Build, Test
  No newline at end of file

          
A => tests/GildedRose.FSharp.Tests/GildedRose.FSharp.Tests.fsproj +32 -0
@@ 0,0 1,32 @@ 
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+
+    <IsPackable>false</IsPackable>
+    <GenerateProgramFile>false</GenerateProgramFile>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Compile Include="Tests.fs" />
+    <Compile Include="Program.fs" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
+    <PackageReference Include="xunit" Version="2.4.1" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+      <PrivateAssets>all</PrivateAssets>
+    </PackageReference>
+    <PackageReference Include="coverlet.collector" Version="1.3.0">
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+      <PrivateAssets>all</PrivateAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\GildedRose.Console\GildedRose.Console.csproj" />
+  </ItemGroup>
+
+</Project>

          
A => tests/GildedRose.FSharp.Tests/Program.fs +1 -0
@@ 0,0 1,1 @@ 
+module Program = let [<EntryPoint>] main _ = 0

          
A => tests/GildedRose.FSharp.Tests/Tests.fs +8 -0
@@ 0,0 1,8 @@ 
+module Tests
+
+open System
+open Xunit
+
+[<Fact>]
+let ``My test`` () =
+    Assert.True(true)

          
A => tests/GildedRose.Tests/GildedRose.Tests.csproj +26 -0
@@ 0,0 1,26 @@ 
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+
+    <IsPackable>false</IsPackable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
+    <PackageReference Include="xunit" Version="2.4.1" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+      <PrivateAssets>all</PrivateAssets>
+    </PackageReference>
+    <PackageReference Include="coverlet.collector" Version="1.3.0">
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+      <PrivateAssets>all</PrivateAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\GildedRose.Console\GildedRose.Console.csproj" />
+  </ItemGroup>
+
+</Project>

          
A => tests/GildedRose.Tests/UnitTest1.cs +14 -0
@@ 0,0 1,14 @@ 
+using System;
+using Xunit;
+
+namespace GildedRose.Tests
+{
+    public class UnitTest1
+    {
+        [Fact]
+        public void Test1()
+        {
+
+        }
+    }
+}