diff --git a/.gitignore b/.gitignore index e28a900..18f8a66 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,13 @@ ## ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore +# Migrations and DB files +# useful while the DB is still fluid, in the early stages +[Mm]igrations/ +*.db +*.db-wal +*.db-shm + # User-specific files *.rsuser *.suo diff --git a/README.md b/README.md index 8bbb37b..69e6130 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,40 @@ ## To use the app +### Console prototype + Open the *DiceAppConsole.sln* solution and navigate to the *App* project. The *Program.cs* file has a `Main()` method that can be launched. *If you simply load DiceApp.sln, Visual Studio will not load the App project...* The console prototype loads a stub with a few small games that you can test, and you can create new everything (with a little patience). +### DiceApp DB context with stub + +We also now have a budding persistence solution, using Entity Framework. + +Open the any of our *solutions* and navigate to the *Data* project. The *Program.cs* file has a `Main()` method that can be launched. + +The NuGet packages are managed in files that are versioned, so you shouldn't need to manage the dependencies yourself. *"The Line"* is taken care of too. + +However, you do need to create the migrations and DB. + +First, in Visual Studio's terminal ("Developer PowerShell"), go to *DiceApp/Sources/Data*, and make sure Entity Framework is installed and / or updated. +``` +dotnet tool install --global dotnet-ef +dotnet tool update --global dotnet-ef +``` +Now the migrations and DB. Since we have a `DbContext` *and* and `DbContextWithStub`, you will need to specify which one to use. Make sure you are in *DiceApp/Sources/Data*. +``` +dotnet ef migrations add dice_app_db --context DiceAppDbContextWithStub +dotnet ef database update --context DiceAppDbContextWithStub +``` +You can now run the *Data* program, and check out your local DB. + +You may not want to read tables in the debug window -- in which case, just download [DB Brower for SQLite](https://sqlitebrowser.org/dl/) and open the *.db* file in it. + +Ta-da. + ## To contribute (workflow) We are using the feature branch workflow ([details here](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow), or see the summary below) diff --git a/Sources/App/App.csproj b/Sources/App/App.csproj index a9bd887..428ab87 100644 --- a/Sources/App/App.csproj +++ b/Sources/App/App.csproj @@ -7,7 +7,6 @@ - diff --git a/Sources/App/Program.cs b/Sources/App/Program.cs index 5d89f6a..feb1b4b 100644 --- a/Sources/App/Program.cs +++ b/Sources/App/Program.cs @@ -1,5 +1,4 @@ -using Data; -using Model.Dice; +using Model.Dice; using Model.Dice.Faces; using Model.Games; using Model.Players; @@ -7,6 +6,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; +using Data; namespace App { diff --git a/Sources/Data/Data.csproj b/Sources/Data/Data.csproj index ac52241..7e30ad7 100644 --- a/Sources/Data/Data.csproj +++ b/Sources/Data/Data.csproj @@ -1,13 +1,24 @@ - + - - net6.0 - enable - enable - + + Exe + net6.0 + enable + enable + $(MSBuildProjectDirectory) + - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + diff --git a/Sources/Data/EF/DiceAppDbContext.cs b/Sources/Data/EF/DiceAppDbContext.cs new file mode 100644 index 0000000..2140253 --- /dev/null +++ b/Sources/Data/EF/DiceAppDbContext.cs @@ -0,0 +1,19 @@ +using Data.EF.Players; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Data.EF +{ + public class DiceAppDbContext : DbContext + { + public DbSet? Players { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + => optionsBuilder.UseSqlite("Data Source=EFDice.DiceApp.db"); + + } +} diff --git a/Sources/Data/EF/DiceAppDbContextWithStub.cs b/Sources/Data/EF/DiceAppDbContextWithStub.cs new file mode 100644 index 0000000..51f225b --- /dev/null +++ b/Sources/Data/EF/DiceAppDbContextWithStub.cs @@ -0,0 +1,25 @@ +using Data.EF.Players; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Data.EF +{ + public class DiceAppDbContextWithStub : DiceAppDbContext + { + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity().HasData( + new PlayerEntity { ID = Guid.Parse("e3b42372-0186-484c-9b1c-01618fbfac44"), Name = "Alice" }, + new PlayerEntity { ID = Guid.Parse("73265e15-3c43-45f8-8f5d-d02feaaf7620"), Name = "Bob" }, + new PlayerEntity { ID = Guid.Parse("5198ba9d-44d6-4660-85f9-1843828c6f0d"), Name = "Clyde" }, + new PlayerEntity { ID = Guid.Parse("386cec27-fd9d-4475-8093-93c8b569bf2e"), Name = "Dahlia" } + ); + } + } +} diff --git a/Sources/Data/EF/Players/PlayerDBManager.cs b/Sources/Data/EF/Players/PlayerDBManager.cs new file mode 100644 index 0000000..7b8e00d --- /dev/null +++ b/Sources/Data/EF/Players/PlayerDBManager.cs @@ -0,0 +1,57 @@ +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Data.EF.Players +{ + public sealed class PlayerDBManager : IManager, IDisposable + { + private readonly DiceAppDbContext db = new DiceAppDbContextWithStub(); + + public void Dispose() + { + db.Dispose(); + } + + public PlayerEntity Add(PlayerEntity toAdd) + { + if (db.Players!.Where(entity => entity.Name == toAdd.Name).Any()) + { + throw new ArgumentException("this username is already taken", nameof(toAdd)); + } + EntityEntry ee = db.Players!.Add(toAdd); + db.SaveChanges(); + return (PlayerEntity)ee.Entity; + } + + + public IEnumerable GetAll() + { + return db.Players!.AsEnumerable(); + } + + public PlayerEntity GetOneByName(string name) + { + throw new NotImplementedException(); + } + + public void Remove(PlayerEntity toRemove) + { + throw new NotImplementedException(); + } + + public PlayerEntity Update(PlayerEntity before, PlayerEntity after) + { + throw new NotImplementedException(); + } + + public PlayerEntity GetOneByID(Guid ID) + { + throw new NotImplementedException(); + } + } +} diff --git a/Sources/Data/EF/Players/PlayerEntity.cs b/Sources/Data/EF/Players/PlayerEntity.cs new file mode 100644 index 0000000..6a504cc --- /dev/null +++ b/Sources/Data/EF/Players/PlayerEntity.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore; +using Model.Players; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Data.EF.Players +{ + [Index(nameof(Name), IsUnique = true)] + public sealed class PlayerEntity : IEquatable + { + public Guid ID { get; set; } + + public string? Name { get; set; } + + public override bool Equals(object? obj) + { + if (obj is not PlayerEntity) + { + return false; + } + return Equals(obj as PlayerEntity); + } + + public bool Equals(PlayerEntity? other) + { + return other is not null && this.ID == other!.ID && this.Name == other.Name; + } + + public override int GetHashCode() + { + return HashCode.Combine(ID, Name); + } + + public override string? ToString() + { + return $"{ID.ToString().ToUpper()} -- {Name}"; + } + + + } +} diff --git a/Sources/Data/EF/Players/PlayerExtensions.cs b/Sources/Data/EF/Players/PlayerExtensions.cs new file mode 100644 index 0000000..3aa188d --- /dev/null +++ b/Sources/Data/EF/Players/PlayerExtensions.cs @@ -0,0 +1,27 @@ +using Model.Players; + +namespace Data.EF.Players +{ + public static class PlayerExtensions + { + public static Player ToModel(this PlayerEntity entity) + { + return new Player(name: entity.Name); + } + + public static IEnumerable ToModels(this IEnumerable entities) + { + return entities.Select(entity => entity.ToModel()); + } + + public static PlayerEntity ToEntity(this Player model) + { + return new PlayerEntity() { Name = model.Name }; + } + + public static IEnumerable ToEntities(this IEnumerable models) + { + return models.Select(model => model.ToEntity()); + } + } +} diff --git a/Sources/Data/Program.cs b/Sources/Data/Program.cs new file mode 100644 index 0000000..2de2b23 --- /dev/null +++ b/Sources/Data/Program.cs @@ -0,0 +1,24 @@ + +using Data.EF; +using Data.EF.Players; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Model.Players; +using System.Collections; +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.Intrinsics.Arm; + +namespace Data +{ + internal static class Program + { + static void Main(string[] args) + { + using PlayerDBManager playerDBManager = new(); + try { playerDBManager.Add(new Player("Ernesto").ToEntity()); } + catch (ArgumentException ex) { Debug.WriteLine($"{ex.Message}\n... Never mind"); } + foreach (PlayerEntity entity in playerDBManager.GetAll()) { Debug.WriteLine(entity); } + } + } +} \ No newline at end of file diff --git a/Sources/DiceApp.sln b/Sources/DiceApp.sln index 7545479..7041b1a 100644 --- a/Sources/DiceApp.sln +++ b/Sources/DiceApp.sln @@ -7,10 +7,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{11BDDDA8-CBED-46EE-A224-144C3CD545A7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Data", "Data\Data.csproj", "{3047BFD8-EF44-4095-9E54-45D47C7AB212}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{953D2D67-BCE7-412C-B7BB-7C63B5592359}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Data", "Data\Data.csproj", "{E9683741-E603-4ED3-8088-4099D67FCA6D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,10 +25,10 @@ Global {11BDDDA8-CBED-46EE-A224-144C3CD545A7}.Debug|Any CPU.Build.0 = Debug|Any CPU {11BDDDA8-CBED-46EE-A224-144C3CD545A7}.Release|Any CPU.ActiveCfg = Release|Any CPU {11BDDDA8-CBED-46EE-A224-144C3CD545A7}.Release|Any CPU.Build.0 = Release|Any CPU - {3047BFD8-EF44-4095-9E54-45D47C7AB212}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3047BFD8-EF44-4095-9E54-45D47C7AB212}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3047BFD8-EF44-4095-9E54-45D47C7AB212}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3047BFD8-EF44-4095-9E54-45D47C7AB212}.Release|Any CPU.Build.0 = Release|Any CPU + {E9683741-E603-4ED3-8088-4099D67FCA6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9683741-E603-4ED3-8088-4099D67FCA6D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9683741-E603-4ED3-8088-4099D67FCA6D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9683741-E603-4ED3-8088-4099D67FCA6D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Sources/DiceAppConsole.sln b/Sources/DiceAppConsole.sln index a6b9d77..b7e99f6 100644 --- a/Sources/DiceAppConsole.sln +++ b/Sources/DiceAppConsole.sln @@ -12,10 +12,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "App\App.csproj", "{8 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{11BDDDA8-CBED-46EE-A224-144C3CD545A7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Data", "Data\Data.csproj", "{3047BFD8-EF44-4095-9E54-45D47C7AB212}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{953D2D67-BCE7-412C-B7BB-7C63B5592359}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Data", "Data\Data.csproj", "{E9683741-E603-4ED3-8088-4099D67FCA6D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -34,10 +34,10 @@ Global {11BDDDA8-CBED-46EE-A224-144C3CD545A7}.Debug|Any CPU.Build.0 = Debug|Any CPU {11BDDDA8-CBED-46EE-A224-144C3CD545A7}.Release|Any CPU.ActiveCfg = Release|Any CPU {11BDDDA8-CBED-46EE-A224-144C3CD545A7}.Release|Any CPU.Build.0 = Release|Any CPU - {3047BFD8-EF44-4095-9E54-45D47C7AB212}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3047BFD8-EF44-4095-9E54-45D47C7AB212}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3047BFD8-EF44-4095-9E54-45D47C7AB212}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3047BFD8-EF44-4095-9E54-45D47C7AB212}.Release|Any CPU.Build.0 = Release|Any CPU + {E9683741-E603-4ED3-8088-4099D67FCA6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9683741-E603-4ED3-8088-4099D67FCA6D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9683741-E603-4ED3-8088-4099D67FCA6D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9683741-E603-4ED3-8088-4099D67FCA6D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Sources/Model/Dice/DieManager.cs b/Sources/Model/Dice/DieManager.cs index 201caa6..408c5ca 100644 --- a/Sources/Model/Dice/DieManager.cs +++ b/Sources/Model/Dice/DieManager.cs @@ -12,6 +12,15 @@ namespace Model.Dice public KeyValuePair> Add(KeyValuePair> toAdd) { // on trim la clé d'abord + if (string.IsNullOrWhiteSpace(toAdd.Key)) + { + throw new ArgumentNullException(nameof(toAdd), "param should not be null or empty"); + + } + if (diceGroups.Contains(toAdd)) + { + throw new ArgumentException("this username is already taken", nameof(toAdd)); + } diceGroups.Add(toAdd.Key.Trim(), toAdd.Value); return toAdd; } @@ -30,12 +39,28 @@ namespace Model.Dice { // les groupes de dés nommés : // ils sont case-sensistive, mais "mon jeu" == "mon jeu " == " mon jeu" - return new KeyValuePair>(name, diceGroups[name]); + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentNullException(nameof(name), "param should not be null or empty"); + } + else + { + return new KeyValuePair>(name, diceGroups[name]); + } } public void Remove(KeyValuePair> toRemove) { - diceGroups.Remove(toRemove.Key); + if (toRemove.Key is null) + { + throw new ArgumentNullException(nameof(toRemove), "param should not be null"); + } + else + { + diceGroups.Remove(toRemove.Key); + } + + } public KeyValuePair> Update(KeyValuePair> before, KeyValuePair> after) @@ -55,17 +80,6 @@ namespace Model.Dice return before; } -/* - IEnumerable>>> IManager>>>>.GetAll() - { - throw new NotImplementedException(); - } - - KeyValuePair>>> IManager>>>>.GetOneByName(string name) - { - throw new NotImplementedException(); - } -*/ } } diff --git a/Sources/Model/Players/Player.cs b/Sources/Model/Players/Player.cs index e89c98c..86d214f 100644 --- a/Sources/Model/Players/Player.cs +++ b/Sources/Model/Players/Player.cs @@ -37,7 +37,7 @@ namespace Model.Players public bool Equals(Player other) { - return Name.ToUpper() == other.Name.ToUpper(); // equality is case insensitive + return other is not null && Name.ToUpper() == other.Name.ToUpper(); // equality is case insensitive } public override bool Equals(object obj) diff --git a/Sources/Model/Players/PlayerManager.cs b/Sources/Model/Players/PlayerManager.cs index 81bd992..1b65565 100644 --- a/Sources/Model/Players/PlayerManager.cs +++ b/Sources/Model/Players/PlayerManager.cs @@ -19,7 +19,7 @@ namespace Model.Players /// add a new player /// /// player to be added - /// added player, or null if was null + /// added player public Player Add(Player toAdd) { if (toAdd is null) diff --git a/Sources/Tests/Data_UTs/Players/PlayerEntityTest.cs b/Sources/Tests/Data_UTs/Players/PlayerEntityTest.cs new file mode 100644 index 0000000..c6df368 --- /dev/null +++ b/Sources/Tests/Data_UTs/Players/PlayerEntityTest.cs @@ -0,0 +1,183 @@ +using Model.Players; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; +using Data.EF.Players; +using Tests.Model_UTs; + +namespace Tests.Data_UTs.Players +{ + public class PlayerEntityTest + { + [Fact] + public void TestGetSetName() + { + // Arrange + PlayerEntity player = new(); + string expected = "Alice"; + + // Act + player.Name = expected; + string actual = player.Name; + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestGetSetID() + { + // Arrange + PlayerEntity player = new(); + Guid expected = new("c8f60957-dd36-4e47-a7ce-1281f4f8bea4"); + + // Act + player.ID = expected; + Guid actual = player.ID; + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestToString() + { + // Arrange + PlayerEntity player = new(); + string IDString = "c8f60957-dd36-4e47-a7ce-1281f4f8bea4"; + string nameString = "Bob"; + player.ID = new Guid(IDString); + player.Name = nameString; + + // Act + string expected = $"{IDString.ToUpper()} -- {nameString}"; + + // Assert + Assert.Equal(expected, player.ToString()); + } + + [Fact] + public void TestEqualsWhenNotPlayerEntityThenFalse() + { + // Arrange + Point point; + PlayerEntity entity; + + // Act + point = new(1, 2); + entity = new() { Name = "Clyde" }; + + // Assert + Assert.False(point.Equals(entity)); + Assert.False(entity.Equals(point)); + } + + [Fact] + public void TestEqualsWhenNullThenFalse() + { + // Arrange + PlayerEntity entity; + + // Act + entity = new() { Name = "Clyde" }; + + // Assert + Assert.False(entity.Equals(null)); + } + + [Fact] + public void TestGoesThruToSecondMethodIfObjIsTypePlayerEntity() + { + // Arrange + object p1; + PlayerEntity p2; + + // Act + p1 = new PlayerEntity() { Name = "Marvin" }; + p2 = new() { Name = "Clyde" }; + + // Assert + Assert.False(p1.Equals(p2)); + Assert.False(p2.Equals(p1)); + } + + [Fact] + public void TestEqualsFalseIfNotSameNameOrID() + { + // Arrange + PlayerEntity p1; + PlayerEntity p2; + PlayerEntity p3; + + // Act + p1 = new() { ID = new Guid("ae04ef10-bd25-4f4e-b4c1-4860fe3daaa0"), Name = "Panama" }; + p2 = new() { ID = new Guid("ae04ef10-bd25-4f4e-b4c1-4860fe3daaa0"), Name = "Clyde" }; + p3 = new() { ID = new Guid("846d332f-56ca-44fc-8170-6cfd28dab88b"), Name = "Clyde" }; + + // Assert + Assert.False(p1.Equals(p2)); + Assert.False(p1.Equals(p3)); + Assert.False(p2.Equals(p1)); + Assert.False(p2.Equals(p3)); + Assert.False(p3.Equals(p1)); + Assert.False(p3.Equals(p2)); + } + + [Fact] + public void TestEqualsTrueIfSameIDAndName() + { + // Arrange + PlayerEntity p1; + PlayerEntity p2; + + // Act + p1 = new() { ID = new Guid("ae04ef10-bd25-4f4e-b4c1-4860fe3daaa0"), Name = "Marley" }; + p2 = new() { ID = new Guid("ae04ef10-bd25-4f4e-b4c1-4860fe3daaa0"), Name = "Marley" }; + + // Assert + Assert.True(p1.Equals(p2)); + Assert.True(p2.Equals(p1)); + } + + [Fact] + public void TestSameHashFalseIfNotSameNameOrID() + { + // Arrange + PlayerEntity p1; + PlayerEntity p2; + PlayerEntity p3; + + // Act + p1 = new() { ID = new Guid("ae04ef10-bd25-4f4e-b4c1-4860fe3daaa0"), Name = "Panama" }; + p2 = new() { ID = new Guid("ae04ef10-bd25-4f4e-b4c1-4860fe3daaa0"), Name = "Clyde" }; + p3 = new() { ID = new Guid("846d332f-56ca-44fc-8170-6cfd28dab88b"), Name = "Clyde" }; + + // Assert + Assert.False(p1.GetHashCode().Equals(p2.GetHashCode())); + Assert.False(p1.GetHashCode().Equals(p3.GetHashCode())); + Assert.False(p2.GetHashCode().Equals(p1.GetHashCode())); + Assert.False(p2.GetHashCode().Equals(p3.GetHashCode())); + Assert.False(p3.GetHashCode().Equals(p1.GetHashCode())); + Assert.False(p3.GetHashCode().Equals(p2.GetHashCode())); + } + + [Fact] + public void TestSameHashTrueIfSame() + { + // Arrange + PlayerEntity p1; + PlayerEntity p2; + + // Act + p1 = new() { ID = new Guid("ae04ef10-bd25-4f4e-b4c1-4860fe3daaa0"), Name = "Marley" }; + p2 = new() { ID = new Guid("ae04ef10-bd25-4f4e-b4c1-4860fe3daaa0"), Name = "Marley" }; + + // Assert + Assert.True(p1.GetHashCode().Equals(p2.GetHashCode())); + Assert.True(p2.GetHashCode().Equals(p1.GetHashCode())); + } + } +} diff --git a/Sources/Tests/Data_UTs/Players/PlayerExtensionsTest.cs b/Sources/Tests/Data_UTs/Players/PlayerExtensionsTest.cs new file mode 100644 index 0000000..bfa109e --- /dev/null +++ b/Sources/Tests/Data_UTs/Players/PlayerExtensionsTest.cs @@ -0,0 +1,93 @@ +using Data.EF.Players; +using Model.Players; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Tests.Data_UTs.Players +{ + public class PlayerExtensionsTest + { + [Fact] + public void TestToModel() + { + // Arrange + string name = "Alice"; + PlayerEntity entity = new() { Name = name }; + Player expected = new(name); + + // Act + Player actual = entity.ToModel(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestToEntity() + { + // Arrange + string name = "Bob"; + Player model = new(name); + PlayerEntity expected = new() { Name = name }; + + // Act + PlayerEntity actual = model.ToEntity(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestToModels() + { + // Arrange + string n1 = "Alice", n2 = "Bob", n3 = "Clyde"; + PlayerEntity[] entities = new PlayerEntity[] { + new() {Name = n1 }, + new() {Name = n2 }, + new() {Name = n3 }, + }; + + IEnumerable expected = new Player[] { + new(n1), + new(n2), + new(n3) + }.AsEnumerable(); + + // Act + IEnumerable actual = entities.ToModels(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestToEntities() + { + // Arrange + string n1 = "Alice", n2 = "Bob", n3 = "Clyde"; + Player[] models = new Player[] { + new(n1), + new(n2), + new(n3) + }; + + IEnumerable expected = new PlayerEntity[] { + new() {Name = n1 }, + new() {Name = n2 }, + new() {Name = n3 }, + }.AsEnumerable(); + + // Act + IEnumerable actual = models.ToEntities(); + + // Assert + Assert.Equal(expected, actual); + } + + } +} diff --git a/Sources/Tests/Model_UTs/GameRunnerTest.cs b/Sources/Tests/Model_UTs/Games/GameRunnerTest.cs similarity index 96% rename from Sources/Tests/Model_UTs/GameRunnerTest.cs rename to Sources/Tests/Model_UTs/Games/GameRunnerTest.cs index e62d157..7c48169 100644 --- a/Sources/Tests/Model_UTs/GameRunnerTest.cs +++ b/Sources/Tests/Model_UTs/Games/GameRunnerTest.cs @@ -1,307 +1,307 @@ -using Data; -using Model; -using Model.Dice; -using Model.Dice.Faces; -using Model.Games; -using Model.Players; -using System; -using System.Collections.Generic; -using System.Linq; -using Xunit; - -namespace Tests.Model_UTs -{ - public class GameRunnerTest - { - private readonly GameRunner stubGameRunner = new Stub().LoadApp(); - - [Fact] - public void TestConstructorWhenNoGamesThenNewIEnumerable() - { - // Arrange - GameRunner gameRunner = new(new PlayerManager(), new DieManager()); - IEnumerable expected; - IEnumerable actual; - - // Act - expected = new List().AsEnumerable(); - actual = gameRunner.GetAll(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TestConstructorWhenGamesThenGamesIEnumerable() - { - // Arrange - GameRunner gameRunner = new(new PlayerManager(), new DieManager(), stubGameRunner.GetAll().ToList()); - IEnumerable expected; - IEnumerable actual; - - // Act - expected = stubGameRunner.GetAll(); - actual = gameRunner.GetAll(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TestAddWhenGamesThenDoAddAndReturnGames() - { - // Arrange - GameRunner gameRunner = new(new PlayerManager(), new DieManager()); - Game game1 = stubGameRunner.GetAll().First(); - Game game2 = stubGameRunner.GetAll().Last(); - - // Act - IEnumerable expected = new List() { game1, game2 }.AsEnumerable(); - IEnumerable actual = new List() - { - gameRunner.Add(game1), - gameRunner.Add(game2) - }; - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TestAddWhenNullThenThrowsException() - { - // Arrange - GameRunner gameRunner = stubGameRunner; - - // Act - void action() => gameRunner.Add(null);// Add() returns the added element if succesful - - // Assert - Assert.Throws(action); - Assert.DoesNotContain(null, stubGameRunner.GetAll()); - } - - [Theory] - [InlineData("")] - [InlineData(null)] - [InlineData(" ")] - public void TestGetOneByNameWhenInvalidThenThrowsException(string name) - { - // Arrange - GameRunner gameRunner = stubGameRunner; - - // Act - void action() => gameRunner.GetOneByName(name); - - // Assert - Assert.Throws(action); - } - - [Fact] - public void TestGetOneByNameWhenValidButNotExistThenReturnNull() - { - // Arrange - GameRunner gameRunner = stubGameRunner; - - // Act - Game result = gameRunner.GetOneByName("thereisbasicallynowaythatthisgamenamealreadyexists"); - - // Assert - Assert.Null(result); - } - - [Fact] - public void TestGetOneByNameWhenValidThenReturnGame() - { - // Arrange - GameRunner gameRunner = new(new PlayerManager(), new DieManager()); - Game game = stubGameRunner.GetAll().First(); - - // Act - Game actual = gameRunner.Add(game); - Game expected = game; - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TestWhenRemoveExistsThenSucceeds() - { - // Arrange - GameRunner gameRunner = stubGameRunner; - Game game = new("blargh", new PlayerManager(), gameRunner.GetAll().First().Dice); - gameRunner.Add(game); - - // Act - gameRunner.Remove(game); - - // Assert - Assert.DoesNotContain(game, gameRunner.GetAll()); - } - - [Fact] - public void TestRemoveWhenGivenNullThenThrowsException() - { - // Arrange - GameRunner gameRunner = stubGameRunner; - - // Act - void action() => gameRunner.Remove(null); - - // Assert - Assert.Throws(action); - } - - [Fact] - public void TestRemoveWhenGiveenNonExistentThenFailsSilently() - { - // Arrange - GameRunner gameRunner = stubGameRunner; - Game notGame = new("blargh", new PlayerManager(), gameRunner.GetAll().First().Dice); - IEnumerable expected = gameRunner.GetAll(); - - // Act - gameRunner.Remove(notGame); - IEnumerable actual = gameRunner.GetAll(); - - // Assert - Assert.Equal(actual, expected); - } - - [Fact] - public void TestUpdateWhenValidThenSucceeds() - { - // Arrange - string oldName = "blargh"; - string newName = "blargh2.0"; - GameRunner gameRunner = new(new PlayerManager(), new DieManager()); - Game game = new(oldName, new PlayerManager(), stubGameRunner.GetAll().First().Dice); - game.PlayerManager.Add(new("Alice")); - gameRunner.Add(game); - - Game oldGame = gameRunner.GetAll().First(); - Game newGame = new(newName, oldGame.PlayerManager, oldGame.Dice); - - // Act - int oldSize = gameRunner.GetAll().Count(); - gameRunner.Update(oldGame, newGame); - int newSize = gameRunner.GetAll().Count(); - - // Assert - Assert.NotEqual(oldName, newName); - Assert.DoesNotContain(oldGame, gameRunner.GetAll()); - Assert.Contains(newGame, gameRunner.GetAll()); - Assert.Equal(oldSize, newSize); - } - - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void TestUpdateWhenValidBeforeAndInvalidAfterThenDoesNotGo(string badName) - { - // Arrange - GameRunner gameRunner = stubGameRunner; - int expectedSize = gameRunner.GetAll().Count(); - Game oldGame = gameRunner.GetAll().First(); - - // Act - void action() => gameRunner.Update(oldGame, new(badName, oldGame.PlayerManager, oldGame.Dice)); - int actualSize = gameRunner.GetAll().Count(); - - // Assert - Assert.Throws(action); // thrown by constructor - Assert.Contains(oldGame, gameRunner.GetAll()); // still there - Assert.True(expectedSize == actualSize); - } - - [Fact] - public void TestUpdateWhenValidBeforeAndNullAfterThenDoesNotGo() - { - // Arrange - GameRunner gameRunner = stubGameRunner; - int expectedSize = gameRunner.GetAll().Count(); - Game oldGame = gameRunner.GetAll().First(); - - // Act - void action() => gameRunner.Update(oldGame, null); - int actualSize = gameRunner.GetAll().Count(); - - // Assert - Assert.Throws(action); // thrown by constructor - Assert.Contains(oldGame, gameRunner.GetAll()); // still there - Assert.True(expectedSize == actualSize); - } - - [Fact] - public void TestUpdateDoesNotGoWithValidAfterAndNullBefore() - { - // Arrange - GameRunner gameRunner = stubGameRunner; - int expectedSize = gameRunner.GetAll().Count(); - Game oldGame = gameRunner.GetAll().First(); - - // Act - void action() => gameRunner.Update(null, new("newgamename", oldGame.PlayerManager, oldGame.Dice)); - int actualSize = gameRunner.GetAll().Count(); - - // Assert - Assert.Throws(action); // thrown by constructor - Assert.Contains(oldGame, gameRunner.GetAll()); // still there - Assert.True(expectedSize == actualSize); - } - - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData(null)] - public void TestUpdateWhenInvalidBeforeAndValidAfterThenDoesNotGo(string badName) - { - // Arrange - GameRunner gameRunner = stubGameRunner; - int expectedSize = gameRunner.GetAll().Count(); - Game oldGame = gameRunner.GetAll().First(); - - // Act - void action() => gameRunner.Update(new(badName, oldGame.PlayerManager, oldGame.Dice), new("valid", oldGame.PlayerManager, oldGame.Dice)); - int actualSize = gameRunner.GetAll().Count(); - - // Assert - Assert.Throws(action); // thrown by constructor - Assert.Contains(oldGame, gameRunner.GetAll()); // still there - Assert.True(expectedSize == actualSize); - } - - [Fact] - public void TestPlayGameWhenPlayThenAddNewTurnToHistory() - { - // Arrange - GameRunner gameRunner = stubGameRunner; - Game game = gameRunner.GetAll().First(); - - // Act - int turnsBefore = game.GetHistory().Count(); - GameRunner.PlayGame(game); - int turnsAfter = game.GetHistory().Count(); - - // Assert - Assert.Equal(turnsBefore + 1, turnsAfter); - } - - [Fact] - public void TestStartNewGame() - { - // Arrange - GameRunner gameRunner = stubGameRunner; - string name = "blargh"; - - // Act - Assert.DoesNotContain(gameRunner.GetOneByName(name), gameRunner.GetAll()); - gameRunner.StartNewGame(name, new PlayerManager(), stubGameRunner.GetAll().First().Dice); - - // Assert - Assert.Contains(gameRunner.GetOneByName(name), gameRunner.GetAll()); - } - } -} +using Model; +using Model.Dice; +using Model.Dice.Faces; +using Model.Games; +using Model.Players; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; +using Data; + +namespace Tests.Model_UTs.Games +{ + public class GameRunnerTest + { + private readonly GameRunner stubGameRunner = new Stub().LoadApp(); + + [Fact] + public void TestConstructorWhenNoGamesThenNewIEnumerable() + { + // Arrange + GameRunner gameRunner = new(new PlayerManager(), new DieManager()); + IEnumerable expected; + IEnumerable actual; + + // Act + expected = new List().AsEnumerable(); + actual = gameRunner.GetAll(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestConstructorWhenGamesThenGamesIEnumerable() + { + // Arrange + GameRunner gameRunner = new(new PlayerManager(), new DieManager(), stubGameRunner.GetAll().ToList()); + IEnumerable expected; + IEnumerable actual; + + // Act + expected = stubGameRunner.GetAll(); + actual = gameRunner.GetAll(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestAddWhenGamesThenDoAddAndReturnGames() + { + // Arrange + GameRunner gameRunner = new(new PlayerManager(), new DieManager()); + Game game1 = stubGameRunner.GetAll().First(); + Game game2 = stubGameRunner.GetAll().Last(); + + // Act + IEnumerable expected = new List() { game1, game2 }.AsEnumerable(); + IEnumerable actual = new List() + { + gameRunner.Add(game1), + gameRunner.Add(game2) + }; + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestAddWhenNullThenThrowsException() + { + // Arrange + GameRunner gameRunner = stubGameRunner; + + // Act + void action() => gameRunner.Add(null);// Add() returns the added element if succesful + + // Assert + Assert.Throws(action); + Assert.DoesNotContain(null, stubGameRunner.GetAll()); + } + + [Theory] + [InlineData("")] + [InlineData(null)] + [InlineData(" ")] + public void TestGetOneByNameWhenInvalidThenThrowsException(string name) + { + // Arrange + GameRunner gameRunner = stubGameRunner; + + // Act + void action() => gameRunner.GetOneByName(name); + + // Assert + Assert.Throws(action); + } + + [Fact] + public void TestGetOneByNameWhenValidButNotExistThenReturnNull() + { + // Arrange + GameRunner gameRunner = stubGameRunner; + + // Act + Game result = gameRunner.GetOneByName("thereisbasicallynowaythatthisgamenamealreadyexists"); + + // Assert + Assert.Null(result); + } + + [Fact] + public void TestGetOneByNameWhenValidThenReturnGame() + { + // Arrange + GameRunner gameRunner = new(new PlayerManager(), new DieManager()); + Game game = stubGameRunner.GetAll().First(); + + // Act + Game actual = gameRunner.Add(game); + Game expected = game; + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestWhenRemoveExistsThenSucceeds() + { + // Arrange + GameRunner gameRunner = stubGameRunner; + Game game = new("blargh", new PlayerManager(), gameRunner.GetAll().First().Dice); + gameRunner.Add(game); + + // Act + gameRunner.Remove(game); + + // Assert + Assert.DoesNotContain(game, gameRunner.GetAll()); + } + + [Fact] + public void TestRemoveWhenGivenNullThenThrowsException() + { + // Arrange + GameRunner gameRunner = stubGameRunner; + + // Act + void action() => gameRunner.Remove(null); + + // Assert + Assert.Throws(action); + } + + [Fact] + public void TestRemoveWhenGiveenNonExistentThenFailsSilently() + { + // Arrange + GameRunner gameRunner = stubGameRunner; + Game notGame = new("blargh", new PlayerManager(), gameRunner.GetAll().First().Dice); + IEnumerable expected = gameRunner.GetAll(); + + // Act + gameRunner.Remove(notGame); + IEnumerable actual = gameRunner.GetAll(); + + // Assert + Assert.Equal(actual, expected); + } + + [Fact] + public void TestUpdateWhenValidThenSucceeds() + { + // Arrange + string oldName = "blargh"; + string newName = "blargh2.0"; + GameRunner gameRunner = new(new PlayerManager(), new DieManager()); + Game game = new(oldName, new PlayerManager(), stubGameRunner.GetAll().First().Dice); + game.PlayerManager.Add(new("Alice")); + gameRunner.Add(game); + + Game oldGame = gameRunner.GetAll().First(); + Game newGame = new(newName, oldGame.PlayerManager, oldGame.Dice); + + // Act + int oldSize = gameRunner.GetAll().Count(); + gameRunner.Update(oldGame, newGame); + int newSize = gameRunner.GetAll().Count(); + + // Assert + Assert.NotEqual(oldName, newName); + Assert.DoesNotContain(oldGame, gameRunner.GetAll()); + Assert.Contains(newGame, gameRunner.GetAll()); + Assert.Equal(oldSize, newSize); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void TestUpdateWhenValidBeforeAndInvalidAfterThenDoesNotGo(string badName) + { + // Arrange + GameRunner gameRunner = stubGameRunner; + int expectedSize = gameRunner.GetAll().Count(); + Game oldGame = gameRunner.GetAll().First(); + + // Act + void action() => gameRunner.Update(oldGame, new(badName, oldGame.PlayerManager, oldGame.Dice)); + int actualSize = gameRunner.GetAll().Count(); + + // Assert + Assert.Throws(action); // thrown by constructor + Assert.Contains(oldGame, gameRunner.GetAll()); // still there + Assert.True(expectedSize == actualSize); + } + + [Fact] + public void TestUpdateWhenValidBeforeAndNullAfterThenDoesNotGo() + { + // Arrange + GameRunner gameRunner = stubGameRunner; + int expectedSize = gameRunner.GetAll().Count(); + Game oldGame = gameRunner.GetAll().First(); + + // Act + void action() => gameRunner.Update(oldGame, null); + int actualSize = gameRunner.GetAll().Count(); + + // Assert + Assert.Throws(action); // thrown by constructor + Assert.Contains(oldGame, gameRunner.GetAll()); // still there + Assert.True(expectedSize == actualSize); + } + + [Fact] + public void TestUpdateDoesNotGoWithValidAfterAndNullBefore() + { + // Arrange + GameRunner gameRunner = stubGameRunner; + int expectedSize = gameRunner.GetAll().Count(); + Game oldGame = gameRunner.GetAll().First(); + + // Act + void action() => gameRunner.Update(null, new("newgamename", oldGame.PlayerManager, oldGame.Dice)); + int actualSize = gameRunner.GetAll().Count(); + + // Assert + Assert.Throws(action); // thrown by constructor + Assert.Contains(oldGame, gameRunner.GetAll()); // still there + Assert.True(expectedSize == actualSize); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(null)] + public void TestUpdateWhenInvalidBeforeAndValidAfterThenDoesNotGo(string badName) + { + // Arrange + GameRunner gameRunner = stubGameRunner; + int expectedSize = gameRunner.GetAll().Count(); + Game oldGame = gameRunner.GetAll().First(); + + // Act + void action() => gameRunner.Update(new(badName, oldGame.PlayerManager, oldGame.Dice), new("valid", oldGame.PlayerManager, oldGame.Dice)); + int actualSize = gameRunner.GetAll().Count(); + + // Assert + Assert.Throws(action); // thrown by constructor + Assert.Contains(oldGame, gameRunner.GetAll()); // still there + Assert.True(expectedSize == actualSize); + } + + [Fact] + public void TestPlayGameWhenPlayThenAddNewTurnToHistory() + { + // Arrange + GameRunner gameRunner = stubGameRunner; + Game game = gameRunner.GetAll().First(); + + // Act + int turnsBefore = game.GetHistory().Count(); + GameRunner.PlayGame(game); + int turnsAfter = game.GetHistory().Count(); + + // Assert + Assert.Equal(turnsBefore + 1, turnsAfter); + } + + [Fact] + public void TestStartNewGame() + { + // Arrange + GameRunner gameRunner = stubGameRunner; + string name = "blargh"; + + // Act + Assert.DoesNotContain(gameRunner.GetOneByName(name), gameRunner.GetAll()); + gameRunner.StartNewGame(name, new PlayerManager(), stubGameRunner.GetAll().First().Dice); + + // Assert + Assert.Contains(gameRunner.GetOneByName(name), gameRunner.GetAll()); + } + } +} diff --git a/Sources/Tests/Model_UTs/GameTest.cs b/Sources/Tests/Model_UTs/Games/GameTest.cs similarity index 98% rename from Sources/Tests/Model_UTs/GameTest.cs rename to Sources/Tests/Model_UTs/Games/GameTest.cs index d7db841..7656044 100644 --- a/Sources/Tests/Model_UTs/GameTest.cs +++ b/Sources/Tests/Model_UTs/Games/GameTest.cs @@ -1,19 +1,15 @@ -using Model.Dice.Faces; +using Data; using Model.Dice; +using Model.Dice.Faces; using Model.Games; using Model.Players; -using Model; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Xunit; -using static System.Collections.Specialized.BitVector32; -using System.Diagnostics; -using Data; -namespace Tests.Model_UTs +namespace Tests.Model_UTs.Games { public class GameTest { diff --git a/Sources/Tests/Model_UTs/TurnTest.cs b/Sources/Tests/Model_UTs/Games/TurnTest.cs similarity index 96% rename from Sources/Tests/Model_UTs/TurnTest.cs rename to Sources/Tests/Model_UTs/Games/TurnTest.cs index cdbb9ba..081acc2 100644 --- a/Sources/Tests/Model_UTs/TurnTest.cs +++ b/Sources/Tests/Model_UTs/Games/TurnTest.cs @@ -1,245 +1,245 @@ using Data; -using Model.Dice; -using Model.Dice.Faces; -using Model.Games; -using Model.Players; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Xunit; - -namespace Tests.Model_UTs -{ - public class TurnTest - - { +using Model.Dice; +using Model.Dice.Faces; +using Model.Games; +using Model.Players; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Xunit; + +namespace Tests.Model_UTs.Games +{ + public class TurnTest + + { private readonly GameRunner stubGameRunner = new Stub().LoadApp(); - + Dictionary DICE_N_FACES_1, DICE_N_FACES_2; - - public TurnTest() - { + + public TurnTest() + { DICE_N_FACES_1 = (Dictionary)stubGameRunner.GetAll().First().GetHistory().First().DiceNFaces; DICE_N_FACES_2 = (Dictionary)stubGameRunner.GetAll().Last().GetHistory().Last().DiceNFaces; - } - - [Fact] - public void TestCreateWithSpecifiedTimeNotUTCThenValid() - { - // Arrange - DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Local); - Player player = new("Alice"); - Assert.NotEqual(DateTimeKind.Utc, dateTime.Kind); - - // Act - Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES_1); - - // Assert - Assert.Equal(DateTimeKind.Utc, turn.When.Kind); - Assert.Equal(dateTime.ToUniversalTime(), turn.When); - } - - - - [Fact] - public void TestCreateWithSpecifiedTimeUTCThenValid() - { - // Arrange - DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc); - Player player = new("Bobby"); - Assert.Equal(DateTimeKind.Utc, dateTime.Kind); - - // Act - Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES_1); - - // Assert - Assert.Equal(DateTimeKind.Utc, turn.When.Kind); - Assert.Equal(dateTime.ToUniversalTime(), turn.When); - } - - - [Fact] - public void TestCreateWithSpecifiedTimeNullPlayerThenException() - { - // Arrange - DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc); - - // Act - void action() => Turn.CreateWithSpecifiedTime(dateTime, null, DICE_N_FACES_1); - - // Assert - Assert.Throws(action); - } - - [Fact] - public void TestCreateWithSpecifiedTimeNullFacesThenException() - { - // Arrange - DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc); - Player player = new("Chucky"); - - // Act - void action() => Turn.CreateWithSpecifiedTime(dateTime, player, null); - - // Assert - Assert.Throws(action); - } - - - [Fact] - public void TestCreateWithSpecifiedTimeEmptyFacesThenException() - { - // Arrange - DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc); - Player player = new("Chucky"); - DICE_N_FACES_1.Clear(); - - // Act - void action() => Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES_1); - - // Assert - Assert.Throws(action); - } - - - - [Fact] - public void TestCreateWithDefaultTimeThenValid() - { - // Arrange - Player player = new("Chloe"); - - // Act - Turn turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1); - - // Assert - Assert.Equal(DateTimeKind.Utc, turn.When.Kind); - Assert.Equal(DateTime.Now.ToUniversalTime().Date, turn.When.Date); - // N.B.: might fail between 11:59:59PM and 00:00:00AM - } - - [Fact] - public void TestDiceNFacesProperty() - { - // Arrange - Player player = new("Erika"); - - // Act - Turn turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1); + } + + [Fact] + public void TestCreateWithSpecifiedTimeNotUTCThenValid() + { + // Arrange + DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Local); + Player player = new("Alice"); + Assert.NotEqual(DateTimeKind.Utc, dateTime.Kind); + + // Act + Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES_1); + + // Assert + Assert.Equal(DateTimeKind.Utc, turn.When.Kind); + Assert.Equal(dateTime.ToUniversalTime(), turn.When); + } + + + + [Fact] + public void TestCreateWithSpecifiedTimeUTCThenValid() + { + // Arrange + DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc); + Player player = new("Bobby"); + Assert.Equal(DateTimeKind.Utc, dateTime.Kind); + + // Act + Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES_1); + + // Assert + Assert.Equal(DateTimeKind.Utc, turn.When.Kind); + Assert.Equal(dateTime.ToUniversalTime(), turn.When); + } + + + [Fact] + public void TestCreateWithSpecifiedTimeNullPlayerThenException() + { + // Arrange + DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc); + + // Act + void action() => Turn.CreateWithSpecifiedTime(dateTime, null, DICE_N_FACES_1); + + // Assert + Assert.Throws(action); + } + + [Fact] + public void TestCreateWithSpecifiedTimeNullFacesThenException() + { + // Arrange + DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc); + Player player = new("Chucky"); + + // Act + void action() => Turn.CreateWithSpecifiedTime(dateTime, player, null); + + // Assert + Assert.Throws(action); + } + + + [Fact] + public void TestCreateWithSpecifiedTimeEmptyFacesThenException() + { + // Arrange + DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc); + Player player = new("Chucky"); + DICE_N_FACES_1.Clear(); + + // Act + void action() => Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES_1); + + // Assert + Assert.Throws(action); + } + + + + [Fact] + public void TestCreateWithDefaultTimeThenValid() + { + // Arrange + Player player = new("Chloe"); + + // Act + Turn turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1); + + // Assert + Assert.Equal(DateTimeKind.Utc, turn.When.Kind); + Assert.Equal(DateTime.Now.ToUniversalTime().Date, turn.When.Date); + // N.B.: might fail between 11:59:59PM and 00:00:00AM + } + + [Fact] + public void TestDiceNFacesProperty() + { + // Arrange + Player player = new("Erika"); + + // Act + Turn turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1); IEnumerable> expected = DICE_N_FACES_1.AsEnumerable(); - - // Assert - Assert.Equal(expected, turn.DiceNFaces); + + // Assert + Assert.Equal(expected, turn.DiceNFaces); } - [Fact] - public void TestEqualsFalseIfNotTurn() - { - // Arrange - Point point; - Turn turn; - Player player = new("Freddie"); - - // Act - point = new(1, 2); - turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1); - - // Assert - Assert.False(point.Equals(turn)); - Assert.False(point.GetHashCode().Equals(turn.GetHashCode())); - Assert.False(turn.Equals(point)); - Assert.False(turn.GetHashCode().Equals(point.GetHashCode())); - } - - [Fact] - public void TestGoesThruToSecondMethodIfObjIsTypeTurn() - { - // Arrange - Object t1; - Turn t2; - Player player1 = new Player("Marvin"); - Player player2 = new Player("Noah"); - - // Act - t1 = Turn.CreateWithDefaultTime(player1, DICE_N_FACES_1); - t2 = Turn.CreateWithDefaultTime(player2, DICE_N_FACES_2); - - // Assert - Assert.False(t1.Equals(t2)); - Assert.False(t1.GetHashCode().Equals(t2.GetHashCode())); - Assert.False(t2.Equals(t1)); - Assert.False(t2.GetHashCode().Equals(t1.GetHashCode())); - } - - - [Fact] - public void TestEqualsFalseIfNotSamePlayer() - { - // Arrange + [Fact] + public void TestEqualsFalseIfNotTurn() + { + // Arrange + Point point; + Turn turn; + Player player = new("Freddie"); + + // Act + point = new(1, 2); + turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1); + + // Assert + Assert.False(point.Equals(turn)); + Assert.False(point.GetHashCode().Equals(turn.GetHashCode())); + Assert.False(turn.Equals(point)); + Assert.False(turn.GetHashCode().Equals(point.GetHashCode())); + } + + [Fact] + public void TestGoesThruToSecondMethodIfObjIsTypeTurn() + { + // Arrange + object t1; + Turn t2; + Player player1 = new Player("Marvin"); + Player player2 = new Player("Noah"); + + // Act + t1 = Turn.CreateWithDefaultTime(player1, DICE_N_FACES_1); + t2 = Turn.CreateWithDefaultTime(player2, DICE_N_FACES_2); + + // Assert + Assert.False(t1.Equals(t2)); + Assert.False(t1.GetHashCode().Equals(t2.GetHashCode())); + Assert.False(t2.Equals(t1)); + Assert.False(t2.GetHashCode().Equals(t1.GetHashCode())); + } + + + [Fact] + public void TestEqualsFalseIfNotSamePlayer() + { + // Arrange Player player1 = new("Panama"); Player player2 = new("Clyde"); - - // Act - Turn t1 = Turn.CreateWithDefaultTime(player1, DICE_N_FACES_2); - Turn t2 = Turn.CreateWithDefaultTime(player2, DICE_N_FACES_2); - - // Assert - Assert.False(t1.Equals(t2)); - Assert.False(t1.GetHashCode().Equals(t2.GetHashCode())); - Assert.False(t2.Equals(t1)); - Assert.False(t2.GetHashCode().Equals(t1.GetHashCode())); - } - - [Fact] - public void TestEqualsFalseIfNotSameTime() - { - // Arrange - Player player = new("Oscar"); - - // Act - Turn t1 = Turn.CreateWithSpecifiedTime(new DateTime(1994, 07, 10), player, DICE_N_FACES_1); - Turn t2 = Turn.CreateWithSpecifiedTime(new DateTime(1991, 08, 20), player, DICE_N_FACES_1); - - // Assert - Assert.False(t1.Equals(t2)); - Assert.False(t1.GetHashCode().Equals(t2.GetHashCode())); - Assert.False(t2.Equals(t1)); - Assert.False(t2.GetHashCode().Equals(t1.GetHashCode())); + + // Act + Turn t1 = Turn.CreateWithDefaultTime(player1, DICE_N_FACES_2); + Turn t2 = Turn.CreateWithDefaultTime(player2, DICE_N_FACES_2); + + // Assert + Assert.False(t1.Equals(t2)); + Assert.False(t1.GetHashCode().Equals(t2.GetHashCode())); + Assert.False(t2.Equals(t1)); + Assert.False(t2.GetHashCode().Equals(t1.GetHashCode())); } - [Fact] - public void TestEqualsFalseIfNotSameDiceNFaces() - { - // Arrange - Player player = new("Django"); - - // Act - Turn t1 = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1); - Turn t2 = Turn.CreateWithDefaultTime(player, DICE_N_FACES_2); - - // Assert - Assert.False(t1.Equals(t2)); - Assert.False(t1.GetHashCode().Equals(t2.GetHashCode())); - Assert.False(t2.Equals(t1)); - Assert.False(t2.GetHashCode().Equals(t1.GetHashCode())); + [Fact] + public void TestEqualsFalseIfNotSameTime() + { + // Arrange + Player player = new("Oscar"); + + // Act + Turn t1 = Turn.CreateWithSpecifiedTime(new DateTime(1994, 07, 10), player, DICE_N_FACES_1); + Turn t2 = Turn.CreateWithSpecifiedTime(new DateTime(1991, 08, 20), player, DICE_N_FACES_1); + + // Assert + Assert.False(t1.Equals(t2)); + Assert.False(t1.GetHashCode().Equals(t2.GetHashCode())); + Assert.False(t2.Equals(t1)); + Assert.False(t2.GetHashCode().Equals(t1.GetHashCode())); } - [Fact] - public void TestEqualsTrueIfExactlySameProperties() - { - // Arrange - Player player = new("Elyse"); - - // Act - Turn t1 = Turn.CreateWithSpecifiedTime(new DateTime(1990, 04, 29), player, DICE_N_FACES_1); - Turn t2 = Turn.CreateWithSpecifiedTime(new DateTime(1990, 04, 29), player, DICE_N_FACES_1); - - // Assert - Assert.True(t1.Equals(t2)); - Assert.True(t1.GetHashCode().Equals(t2.GetHashCode())); - Assert.True(t2.Equals(t1)); - Assert.True(t2.GetHashCode().Equals(t1.GetHashCode())); - } - } -} + [Fact] + public void TestEqualsFalseIfNotSameDiceNFaces() + { + // Arrange + Player player = new("Django"); + + // Act + Turn t1 = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1); + Turn t2 = Turn.CreateWithDefaultTime(player, DICE_N_FACES_2); + + // Assert + Assert.False(t1.Equals(t2)); + Assert.False(t1.GetHashCode().Equals(t2.GetHashCode())); + Assert.False(t2.Equals(t1)); + Assert.False(t2.GetHashCode().Equals(t1.GetHashCode())); + } + + [Fact] + public void TestEqualsTrueIfExactlySameProperties() + { + // Arrange + Player player = new("Elyse"); + + // Act + Turn t1 = Turn.CreateWithSpecifiedTime(new DateTime(1990, 04, 29), player, DICE_N_FACES_1); + Turn t2 = Turn.CreateWithSpecifiedTime(new DateTime(1990, 04, 29), player, DICE_N_FACES_1); + + // Assert + Assert.True(t1.Equals(t2)); + Assert.True(t1.GetHashCode().Equals(t2.GetHashCode())); + Assert.True(t2.Equals(t1)); + Assert.True(t2.GetHashCode().Equals(t1.GetHashCode())); + } + } +} diff --git a/Sources/Tests/Model_UTs/PlayerManagerTest.cs b/Sources/Tests/Model_UTs/Players/PlayerManagerTest.cs similarity index 99% rename from Sources/Tests/Model_UTs/PlayerManagerTest.cs rename to Sources/Tests/Model_UTs/Players/PlayerManagerTest.cs index fe94980..2cdb994 100644 --- a/Sources/Tests/Model_UTs/PlayerManagerTest.cs +++ b/Sources/Tests/Model_UTs/Players/PlayerManagerTest.cs @@ -3,10 +3,9 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using System.Xml.Linq; using Xunit; -namespace Tests.Model_UTs +namespace Tests.Model_UTs.Players { public class PlayerManagerTest { diff --git a/Sources/Tests/Model_UTs/PlayerTest.cs b/Sources/Tests/Model_UTs/Players/PlayerTest.cs similarity index 94% rename from Sources/Tests/Model_UTs/PlayerTest.cs rename to Sources/Tests/Model_UTs/Players/PlayerTest.cs index e0c14ee..ca244d0 100644 --- a/Sources/Tests/Model_UTs/PlayerTest.cs +++ b/Sources/Tests/Model_UTs/Players/PlayerTest.cs @@ -2,7 +2,7 @@ using Model.Players; using System; using Xunit; -namespace Tests.Model_UTs +namespace Tests.Model_UTs.Players { public class PlayerTest { @@ -99,7 +99,7 @@ namespace Tests.Model_UTs public void TestGoesThruToSecondMethodIfObjIsTypePlayer() { // Arrange - Object p1; + object p1; Player p2; // Act @@ -128,6 +128,19 @@ namespace Tests.Model_UTs Assert.False(p2.Equals(p1)); } + [Fact] + public void TestEqualsFalseIfNull() + { + // Arrange + Player player; + + // Act + player = new("Panama"); + + // Assert + Assert.False(player.Equals(null)); + } + [Theory] [InlineData("devoN")] [InlineData(" devon")] diff --git a/Sources/Tests/Model_UTs/Point.cs b/Sources/Tests/Model_UTs/Point.cs index a9274f7..89b5f7f 100644 --- a/Sources/Tests/Model_UTs/Point.cs +++ b/Sources/Tests/Model_UTs/Point.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tests.Model_UTs +namespace Tests.Model_UTs { public class Point { diff --git a/Sources/Tests/Tests.csproj b/Sources/Tests/Tests.csproj index 2d2506b..2075e70 100644 --- a/Sources/Tests/Tests.csproj +++ b/Sources/Tests/Tests.csproj @@ -21,7 +21,6 @@ -