🗃️ introduce-ef-persistence #104

Merged
alexis.drai merged 18 commits from introduce-ef-persistence into main 3 years ago

7
.gitignore vendored

@ -4,6 +4,13 @@
## ##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore ## 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 # User-specific files
*.rsuser *.rsuser
*.suo *.suo

@ -7,7 +7,6 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Data\Data.csproj" /> <ProjectReference Include="..\Data\Data.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -1,11 +1,11 @@
using Data; using Model.Dice;
using Model.Dice;
using Model.Dice.Faces; using Model.Dice.Faces;
using Model.Games; using Model.Games;
using Model.Players; using Model.Players;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Data;
namespace App namespace App
{ {

@ -1,13 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings> <TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> <Nullable>enable</Nullable>
<StartWorkingDirectory>$(MSBuildProjectDirectory)</StartWorkingDirectory>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" />
</ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
</ItemGroup>
</Project> </Project>

@ -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<PlayerEntity>? Players { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlite("Data Source=EFDice.DiceApp.db");
}
}

@ -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<PlayerEntity>().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" }
);
}
}
}

@ -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<PlayerEntity>, 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<PlayerEntity> 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();
}
}
}

@ -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<PlayerEntity>
{
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}";
}
}
}

@ -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<Player> ToModels(this IEnumerable<PlayerEntity> entities)
{
return entities.Select(entity => entity.ToModel());
}
public static PlayerEntity ToEntity(this Player model)
{
return new PlayerEntity() { Name = model.Name };
}
public static IEnumerable<PlayerEntity> ToEntities(this IEnumerable<Player> models)
{
return models.Select(model => model.ToEntity());
}
}
}

@ -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); }
}
}
}

@ -7,10 +7,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{11BDDDA8-CBED-46EE-A224-144C3CD545A7}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{11BDDDA8-CBED-46EE-A224-144C3CD545A7}"
EndProject 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}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{953D2D67-BCE7-412C-B7BB-7C63B5592359}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Data", "Data\Data.csproj", "{E9683741-E603-4ED3-8088-4099D67FCA6D}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU 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}.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.ActiveCfg = Release|Any CPU
{11BDDDA8-CBED-46EE-A224-144C3CD545A7}.Release|Any CPU.Build.0 = 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 {E9683741-E603-4ED3-8088-4099D67FCA6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3047BFD8-EF44-4095-9E54-45D47C7AB212}.Debug|Any CPU.Build.0 = Debug|Any CPU {E9683741-E603-4ED3-8088-4099D67FCA6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3047BFD8-EF44-4095-9E54-45D47C7AB212}.Release|Any CPU.ActiveCfg = Release|Any CPU {E9683741-E603-4ED3-8088-4099D67FCA6D}.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}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

@ -12,10 +12,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "App\App.csproj", "{8
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{11BDDDA8-CBED-46EE-A224-144C3CD545A7}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{11BDDDA8-CBED-46EE-A224-144C3CD545A7}"
EndProject 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}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{953D2D67-BCE7-412C-B7BB-7C63B5592359}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Data", "Data\Data.csproj", "{E9683741-E603-4ED3-8088-4099D67FCA6D}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU 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}.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.ActiveCfg = Release|Any CPU
{11BDDDA8-CBED-46EE-A224-144C3CD545A7}.Release|Any CPU.Build.0 = 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 {E9683741-E603-4ED3-8088-4099D67FCA6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3047BFD8-EF44-4095-9E54-45D47C7AB212}.Debug|Any CPU.Build.0 = Debug|Any CPU {E9683741-E603-4ED3-8088-4099D67FCA6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3047BFD8-EF44-4095-9E54-45D47C7AB212}.Release|Any CPU.ActiveCfg = Release|Any CPU {E9683741-E603-4ED3-8088-4099D67FCA6D}.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}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

@ -37,7 +37,7 @@ namespace Model.Players
public bool Equals(Player other) 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) public override bool Equals(object obj)

@ -19,7 +19,7 @@ namespace Model.Players
/// add a new player /// add a new player
/// </summary> /// </summary>
/// <param name="toAdd">player to be added</param> /// <param name="toAdd">player to be added</param>
/// <returns>added player, or null if <paramref name="toAdd"/> was null</returns> /// <returns>added player</returns>
public Player Add(Player toAdd) public Player Add(Player toAdd)
{ {
if (toAdd is null) if (toAdd is null)

@ -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()));
}
}
}

@ -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<Player> expected = new Player[] {
new(n1),
new(n2),
new(n3)
}.AsEnumerable();
// Act
IEnumerable<Player> 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<PlayerEntity> expected = new PlayerEntity[] {
new() {Name = n1 },
new() {Name = n2 },
new() {Name = n3 },
}.AsEnumerable();
// Act
IEnumerable<PlayerEntity> actual = models.ToEntities();
// Assert
Assert.Equal(expected, actual);
}
}
}

@ -1,307 +1,307 @@
using Data; using Model;
using Model; using Model.Dice;
using Model.Dice; using Model.Dice.Faces;
using Model.Dice.Faces; using Model.Games;
using Model.Games; using Model.Players;
using Model.Players; using System;
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.Linq;
using System.Linq; using Xunit;
using Xunit; using Data;
namespace Tests.Model_UTs namespace Tests.Model_UTs.Games
{ {
public class GameRunnerTest public class GameRunnerTest
{ {
private readonly GameRunner stubGameRunner = new Stub().LoadApp(); private readonly GameRunner stubGameRunner = new Stub().LoadApp();
[Fact] [Fact]
public void TestConstructorWhenNoGamesThenNewIEnumerable() public void TestConstructorWhenNoGamesThenNewIEnumerable()
{ {
// Arrange // Arrange
GameRunner gameRunner = new(new PlayerManager(), new DieManager()); GameRunner gameRunner = new(new PlayerManager(), new DieManager());
IEnumerable<Game> expected; IEnumerable<Game> expected;
IEnumerable<Game> actual; IEnumerable<Game> actual;
// Act // Act
expected = new List<Game>().AsEnumerable(); expected = new List<Game>().AsEnumerable();
actual = gameRunner.GetAll(); actual = gameRunner.GetAll();
// Assert // Assert
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
[Fact] [Fact]
public void TestConstructorWhenGamesThenGamesIEnumerable() public void TestConstructorWhenGamesThenGamesIEnumerable()
{ {
// Arrange // Arrange
GameRunner gameRunner = new(new PlayerManager(), new DieManager(), stubGameRunner.GetAll().ToList()); GameRunner gameRunner = new(new PlayerManager(), new DieManager(), stubGameRunner.GetAll().ToList());
IEnumerable<Game> expected; IEnumerable<Game> expected;
IEnumerable<Game> actual; IEnumerable<Game> actual;
// Act // Act
expected = stubGameRunner.GetAll(); expected = stubGameRunner.GetAll();
actual = gameRunner.GetAll(); actual = gameRunner.GetAll();
// Assert // Assert
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
[Fact] [Fact]
public void TestAddWhenGamesThenDoAddAndReturnGames() public void TestAddWhenGamesThenDoAddAndReturnGames()
{ {
// Arrange // Arrange
GameRunner gameRunner = new(new PlayerManager(), new DieManager()); GameRunner gameRunner = new(new PlayerManager(), new DieManager());
Game game1 = stubGameRunner.GetAll().First(); Game game1 = stubGameRunner.GetAll().First();
Game game2 = stubGameRunner.GetAll().Last(); Game game2 = stubGameRunner.GetAll().Last();
// Act // Act
IEnumerable<Game> expected = new List<Game>() { game1, game2 }.AsEnumerable(); IEnumerable<Game> expected = new List<Game>() { game1, game2 }.AsEnumerable();
IEnumerable<Game> actual = new List<Game>() IEnumerable<Game> actual = new List<Game>()
{ {
gameRunner.Add(game1), gameRunner.Add(game1),
gameRunner.Add(game2) gameRunner.Add(game2)
}; };
// Assert // Assert
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
[Fact] [Fact]
public void TestAddWhenNullThenThrowsException() public void TestAddWhenNullThenThrowsException()
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
// Act // Act
void action() => gameRunner.Add(null);// Add() returns the added element if succesful void action() => gameRunner.Add(null);// Add() returns the added element if succesful
// Assert // Assert
Assert.Throws<ArgumentNullException>(action); Assert.Throws<ArgumentNullException>(action);
Assert.DoesNotContain(null, stubGameRunner.GetAll()); Assert.DoesNotContain(null, stubGameRunner.GetAll());
} }
[Theory] [Theory]
[InlineData("")] [InlineData("")]
[InlineData(null)] [InlineData(null)]
[InlineData(" ")] [InlineData(" ")]
public void TestGetOneByNameWhenInvalidThenThrowsException(string name) public void TestGetOneByNameWhenInvalidThenThrowsException(string name)
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
// Act // Act
void action() => gameRunner.GetOneByName(name); void action() => gameRunner.GetOneByName(name);
// Assert // Assert
Assert.Throws<ArgumentException>(action); Assert.Throws<ArgumentException>(action);
} }
[Fact] [Fact]
public void TestGetOneByNameWhenValidButNotExistThenReturnNull() public void TestGetOneByNameWhenValidButNotExistThenReturnNull()
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
// Act // Act
Game result = gameRunner.GetOneByName("thereisbasicallynowaythatthisgamenamealreadyexists"); Game result = gameRunner.GetOneByName("thereisbasicallynowaythatthisgamenamealreadyexists");
// Assert // Assert
Assert.Null(result); Assert.Null(result);
} }
[Fact] [Fact]
public void TestGetOneByNameWhenValidThenReturnGame() public void TestGetOneByNameWhenValidThenReturnGame()
{ {
// Arrange // Arrange
GameRunner gameRunner = new(new PlayerManager(), new DieManager()); GameRunner gameRunner = new(new PlayerManager(), new DieManager());
Game game = stubGameRunner.GetAll().First(); Game game = stubGameRunner.GetAll().First();
// Act // Act
Game actual = gameRunner.Add(game); Game actual = gameRunner.Add(game);
Game expected = game; Game expected = game;
// Assert // Assert
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
[Fact] [Fact]
public void TestWhenRemoveExistsThenSucceeds() public void TestWhenRemoveExistsThenSucceeds()
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
Game game = new("blargh", new PlayerManager(), gameRunner.GetAll().First().Dice); Game game = new("blargh", new PlayerManager(), gameRunner.GetAll().First().Dice);
gameRunner.Add(game); gameRunner.Add(game);
// Act // Act
gameRunner.Remove(game); gameRunner.Remove(game);
// Assert // Assert
Assert.DoesNotContain(game, gameRunner.GetAll()); Assert.DoesNotContain(game, gameRunner.GetAll());
} }
[Fact] [Fact]
public void TestRemoveWhenGivenNullThenThrowsException() public void TestRemoveWhenGivenNullThenThrowsException()
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
// Act // Act
void action() => gameRunner.Remove(null); void action() => gameRunner.Remove(null);
// Assert // Assert
Assert.Throws<ArgumentNullException>(action); Assert.Throws<ArgumentNullException>(action);
} }
[Fact] [Fact]
public void TestRemoveWhenGiveenNonExistentThenFailsSilently() public void TestRemoveWhenGiveenNonExistentThenFailsSilently()
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
Game notGame = new("blargh", new PlayerManager(), gameRunner.GetAll().First().Dice); Game notGame = new("blargh", new PlayerManager(), gameRunner.GetAll().First().Dice);
IEnumerable<Game> expected = gameRunner.GetAll(); IEnumerable<Game> expected = gameRunner.GetAll();
// Act // Act
gameRunner.Remove(notGame); gameRunner.Remove(notGame);
IEnumerable<Game> actual = gameRunner.GetAll(); IEnumerable<Game> actual = gameRunner.GetAll();
// Assert // Assert
Assert.Equal(actual, expected); Assert.Equal(actual, expected);
} }
[Fact] [Fact]
public void TestUpdateWhenValidThenSucceeds() public void TestUpdateWhenValidThenSucceeds()
{ {
// Arrange // Arrange
string oldName = "blargh"; string oldName = "blargh";
string newName = "blargh2.0"; string newName = "blargh2.0";
GameRunner gameRunner = new(new PlayerManager(), new DieManager()); GameRunner gameRunner = new(new PlayerManager(), new DieManager());
Game game = new(oldName, new PlayerManager(), stubGameRunner.GetAll().First().Dice); Game game = new(oldName, new PlayerManager(), stubGameRunner.GetAll().First().Dice);
game.PlayerManager.Add(new("Alice")); game.PlayerManager.Add(new("Alice"));
gameRunner.Add(game); gameRunner.Add(game);
Game oldGame = gameRunner.GetAll().First(); Game oldGame = gameRunner.GetAll().First();
Game newGame = new(newName, oldGame.PlayerManager, oldGame.Dice); Game newGame = new(newName, oldGame.PlayerManager, oldGame.Dice);
// Act // Act
int oldSize = gameRunner.GetAll().Count(); int oldSize = gameRunner.GetAll().Count();
gameRunner.Update(oldGame, newGame); gameRunner.Update(oldGame, newGame);
int newSize = gameRunner.GetAll().Count(); int newSize = gameRunner.GetAll().Count();
// Assert // Assert
Assert.NotEqual(oldName, newName); Assert.NotEqual(oldName, newName);
Assert.DoesNotContain(oldGame, gameRunner.GetAll()); Assert.DoesNotContain(oldGame, gameRunner.GetAll());
Assert.Contains(newGame, gameRunner.GetAll()); Assert.Contains(newGame, gameRunner.GetAll());
Assert.Equal(oldSize, newSize); Assert.Equal(oldSize, newSize);
} }
[Theory] [Theory]
[InlineData("")] [InlineData("")]
[InlineData(" ")] [InlineData(" ")]
[InlineData(null)] [InlineData(null)]
public void TestUpdateWhenValidBeforeAndInvalidAfterThenDoesNotGo(string badName) public void TestUpdateWhenValidBeforeAndInvalidAfterThenDoesNotGo(string badName)
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
int expectedSize = gameRunner.GetAll().Count(); int expectedSize = gameRunner.GetAll().Count();
Game oldGame = gameRunner.GetAll().First(); Game oldGame = gameRunner.GetAll().First();
// Act // Act
void action() => gameRunner.Update(oldGame, new(badName, oldGame.PlayerManager, oldGame.Dice)); void action() => gameRunner.Update(oldGame, new(badName, oldGame.PlayerManager, oldGame.Dice));
int actualSize = gameRunner.GetAll().Count(); int actualSize = gameRunner.GetAll().Count();
// Assert // Assert
Assert.Throws<ArgumentException>(action); // thrown by constructor Assert.Throws<ArgumentException>(action); // thrown by constructor
Assert.Contains(oldGame, gameRunner.GetAll()); // still there Assert.Contains(oldGame, gameRunner.GetAll()); // still there
Assert.True(expectedSize == actualSize); Assert.True(expectedSize == actualSize);
} }
[Fact] [Fact]
public void TestUpdateWhenValidBeforeAndNullAfterThenDoesNotGo() public void TestUpdateWhenValidBeforeAndNullAfterThenDoesNotGo()
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
int expectedSize = gameRunner.GetAll().Count(); int expectedSize = gameRunner.GetAll().Count();
Game oldGame = gameRunner.GetAll().First(); Game oldGame = gameRunner.GetAll().First();
// Act // Act
void action() => gameRunner.Update(oldGame, null); void action() => gameRunner.Update(oldGame, null);
int actualSize = gameRunner.GetAll().Count(); int actualSize = gameRunner.GetAll().Count();
// Assert // Assert
Assert.Throws<ArgumentNullException>(action); // thrown by constructor Assert.Throws<ArgumentNullException>(action); // thrown by constructor
Assert.Contains(oldGame, gameRunner.GetAll()); // still there Assert.Contains(oldGame, gameRunner.GetAll()); // still there
Assert.True(expectedSize == actualSize); Assert.True(expectedSize == actualSize);
} }
[Fact] [Fact]
public void TestUpdateDoesNotGoWithValidAfterAndNullBefore() public void TestUpdateDoesNotGoWithValidAfterAndNullBefore()
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
int expectedSize = gameRunner.GetAll().Count(); int expectedSize = gameRunner.GetAll().Count();
Game oldGame = gameRunner.GetAll().First(); Game oldGame = gameRunner.GetAll().First();
// Act // Act
void action() => gameRunner.Update(null, new("newgamename", oldGame.PlayerManager, oldGame.Dice)); void action() => gameRunner.Update(null, new("newgamename", oldGame.PlayerManager, oldGame.Dice));
int actualSize = gameRunner.GetAll().Count(); int actualSize = gameRunner.GetAll().Count();
// Assert // Assert
Assert.Throws<ArgumentNullException>(action); // thrown by constructor Assert.Throws<ArgumentNullException>(action); // thrown by constructor
Assert.Contains(oldGame, gameRunner.GetAll()); // still there Assert.Contains(oldGame, gameRunner.GetAll()); // still there
Assert.True(expectedSize == actualSize); Assert.True(expectedSize == actualSize);
} }
[Theory] [Theory]
[InlineData("")] [InlineData("")]
[InlineData(" ")] [InlineData(" ")]
[InlineData(null)] [InlineData(null)]
public void TestUpdateWhenInvalidBeforeAndValidAfterThenDoesNotGo(string badName) public void TestUpdateWhenInvalidBeforeAndValidAfterThenDoesNotGo(string badName)
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
int expectedSize = gameRunner.GetAll().Count(); int expectedSize = gameRunner.GetAll().Count();
Game oldGame = gameRunner.GetAll().First(); Game oldGame = gameRunner.GetAll().First();
// Act // Act
void action() => gameRunner.Update(new(badName, oldGame.PlayerManager, oldGame.Dice), new("valid", oldGame.PlayerManager, oldGame.Dice)); void action() => gameRunner.Update(new(badName, oldGame.PlayerManager, oldGame.Dice), new("valid", oldGame.PlayerManager, oldGame.Dice));
int actualSize = gameRunner.GetAll().Count(); int actualSize = gameRunner.GetAll().Count();
// Assert // Assert
Assert.Throws<ArgumentException>(action); // thrown by constructor Assert.Throws<ArgumentException>(action); // thrown by constructor
Assert.Contains(oldGame, gameRunner.GetAll()); // still there Assert.Contains(oldGame, gameRunner.GetAll()); // still there
Assert.True(expectedSize == actualSize); Assert.True(expectedSize == actualSize);
} }
[Fact] [Fact]
public void TestPlayGameWhenPlayThenAddNewTurnToHistory() public void TestPlayGameWhenPlayThenAddNewTurnToHistory()
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
Game game = gameRunner.GetAll().First(); Game game = gameRunner.GetAll().First();
// Act // Act
int turnsBefore = game.GetHistory().Count(); int turnsBefore = game.GetHistory().Count();
GameRunner.PlayGame(game); GameRunner.PlayGame(game);
int turnsAfter = game.GetHistory().Count(); int turnsAfter = game.GetHistory().Count();
// Assert // Assert
Assert.Equal(turnsBefore + 1, turnsAfter); Assert.Equal(turnsBefore + 1, turnsAfter);
} }
[Fact] [Fact]
public void TestStartNewGame() public void TestStartNewGame()
{ {
// Arrange // Arrange
GameRunner gameRunner = stubGameRunner; GameRunner gameRunner = stubGameRunner;
string name = "blargh"; string name = "blargh";
// Act // Act
Assert.DoesNotContain(gameRunner.GetOneByName(name), gameRunner.GetAll()); Assert.DoesNotContain(gameRunner.GetOneByName(name), gameRunner.GetAll());
gameRunner.StartNewGame(name, new PlayerManager(), stubGameRunner.GetAll().First().Dice); gameRunner.StartNewGame(name, new PlayerManager(), stubGameRunner.GetAll().First().Dice);
// Assert // Assert
Assert.Contains(gameRunner.GetOneByName(name), gameRunner.GetAll()); Assert.Contains(gameRunner.GetOneByName(name), gameRunner.GetAll());
} }
} }
} }

@ -1,18 +1,14 @@
using Model.Dice.Faces; using Model.Dice;
using Model.Dice; using Model.Dice.Faces;
using Model.Games; using Model.Games;
using Model.Players; using Model.Players;
using Model;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit; using Xunit;
using static System.Collections.Specialized.BitVector32;
using System.Diagnostics;
namespace Tests.Model_UTs namespace Tests.Model_UTs.Games
{ {
public class GameTest public class GameTest
{ {

@ -8,7 +8,7 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using Xunit; using Xunit;
namespace Tests.Model_UTs namespace Tests.Model_UTs.Games
{ {
public class TurnTest public class TurnTest
@ -208,8 +208,8 @@ namespace Tests.Model_UTs
// Assert // Assert
Assert.Equal(expected, turn.DiceNFaces); Assert.Equal(expected, turn.DiceNFaces);
} }
[Fact] [Fact]
public void TestEqualsFalseIfNotTurn() public void TestEqualsFalseIfNotTurn()
{ {
@ -233,7 +233,7 @@ namespace Tests.Model_UTs
public void TestGoesThruToSecondMethodIfObjIsTypeTurn() public void TestGoesThruToSecondMethodIfObjIsTypeTurn()
{ {
// Arrange // Arrange
Object t1; object t1;
Turn t2; Turn t2;
Player player1 = new Player("Marvin"); Player player1 = new Player("Marvin");
Player player2 = new Player("Noah"); Player player2 = new Player("Noah");
@ -254,8 +254,8 @@ namespace Tests.Model_UTs
public void TestEqualsFalseIfNotSamePlayer() public void TestEqualsFalseIfNotSamePlayer()
{ {
// Arrange // Arrange
Player player1= new("Panama"); Player player1 = new("Panama");
Player player2= new("Clyde"); Player player2 = new("Clyde");
// Act // Act
Turn t1 = Turn.CreateWithDefaultTime(player1, DICE_N_FACES_2); Turn t1 = Turn.CreateWithDefaultTime(player1, DICE_N_FACES_2);
@ -266,8 +266,8 @@ namespace Tests.Model_UTs
Assert.False(t1.GetHashCode().Equals(t2.GetHashCode())); Assert.False(t1.GetHashCode().Equals(t2.GetHashCode()));
Assert.False(t2.Equals(t1)); Assert.False(t2.Equals(t1));
Assert.False(t2.GetHashCode().Equals(t1.GetHashCode())); Assert.False(t2.GetHashCode().Equals(t1.GetHashCode()));
} }
[Fact] [Fact]
public void TestEqualsFalseIfNotSameTime() public void TestEqualsFalseIfNotSameTime()
{ {
@ -283,8 +283,8 @@ namespace Tests.Model_UTs
Assert.False(t1.GetHashCode().Equals(t2.GetHashCode())); Assert.False(t1.GetHashCode().Equals(t2.GetHashCode()));
Assert.False(t2.Equals(t1)); Assert.False(t2.Equals(t1));
Assert.False(t2.GetHashCode().Equals(t1.GetHashCode())); Assert.False(t2.GetHashCode().Equals(t1.GetHashCode()));
} }
[Fact] [Fact]
public void TestEqualsFalseIfNotSameDiceNFaces() public void TestEqualsFalseIfNotSameDiceNFaces()
{ {

@ -3,10 +3,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Xml.Linq;
using Xunit; using Xunit;
namespace Tests.Model_UTs namespace Tests.Model_UTs.Players
{ {
public class PlayerManagerTest public class PlayerManagerTest
{ {

@ -2,7 +2,7 @@ using Model.Players;
using System; using System;
using Xunit; using Xunit;
namespace Tests.Model_UTs namespace Tests.Model_UTs.Players
{ {
public class PlayerTest public class PlayerTest
{ {
@ -99,7 +99,7 @@ namespace Tests.Model_UTs
public void TestGoesThruToSecondMethodIfObjIsTypePlayer() public void TestGoesThruToSecondMethodIfObjIsTypePlayer()
{ {
// Arrange // Arrange
Object p1; object p1;
Player p2; Player p2;
// Act // Act
@ -128,6 +128,19 @@ namespace Tests.Model_UTs
Assert.False(p2.Equals(p1)); Assert.False(p2.Equals(p1));
} }
[Fact]
public void TestEqualsFalseIfNull()
{
// Arrange
Player player;
// Act
player = new("Panama");
// Assert
Assert.False(player.Equals(null));
}
[Theory] [Theory]
[InlineData("devoN")] [InlineData("devoN")]
[InlineData(" devon")] [InlineData(" devon")]

@ -1,10 +1,4 @@
using System; namespace Tests.Model_UTs
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tests.Model_UTs
{ {
public class Point public class Point
{ {

@ -21,7 +21,6 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Data\Data.csproj" /> <ProjectReference Include="..\Data\Data.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

Loading…
Cancel
Save