Merge pull request '🗃️ introduce-ef-persistence' (#104) from introduce-ef-persistence into main
continuous-integration/drone/push Build is passing Details

Reviewed-on: #104
pull/106/head
Alexis Drai 2 years ago
commit ebf8a9ac91

7
.gitignore vendored

@ -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

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

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

@ -1,13 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<StartWorkingDirectory>$(MSBuildProjectDirectory)</StartWorkingDirectory>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" />
<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>

@ -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
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

@ -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

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

@ -19,7 +19,7 @@ namespace Model.Players
/// add a new player
/// </summary>
/// <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)
{
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.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<Game> expected;
IEnumerable<Game> actual;
// Act
expected = new List<Game>().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<Game> expected;
IEnumerable<Game> 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<Game> expected = new List<Game>() { game1, game2 }.AsEnumerable();
IEnumerable<Game> actual = new List<Game>()
{
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<ArgumentNullException>(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<ArgumentException>(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<ArgumentNullException>(action);
}
[Fact]
public void TestRemoveWhenGiveenNonExistentThenFailsSilently()
{
// Arrange
GameRunner gameRunner = stubGameRunner;
Game notGame = new("blargh", new PlayerManager(), gameRunner.GetAll().First().Dice);
IEnumerable<Game> expected = gameRunner.GetAll();
// Act
gameRunner.Remove(notGame);
IEnumerable<Game> 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<ArgumentException>(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<ArgumentNullException>(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<ArgumentNullException>(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<ArgumentException>(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<Game> expected;
IEnumerable<Game> actual;
// Act
expected = new List<Game>().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<Game> expected;
IEnumerable<Game> 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<Game> expected = new List<Game>() { game1, game2 }.AsEnumerable();
IEnumerable<Game> actual = new List<Game>()
{
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<ArgumentNullException>(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<ArgumentException>(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<ArgumentNullException>(action);
}
[Fact]
public void TestRemoveWhenGiveenNonExistentThenFailsSilently()
{
// Arrange
GameRunner gameRunner = stubGameRunner;
Game notGame = new("blargh", new PlayerManager(), gameRunner.GetAll().First().Dice);
IEnumerable<Game> expected = gameRunner.GetAll();
// Act
gameRunner.Remove(notGame);
IEnumerable<Game> 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<ArgumentException>(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<ArgumentNullException>(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<ArgumentNullException>(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<ArgumentException>(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());
}
}
}

@ -1,18 +1,14 @@
using Model.Dice.Faces;
using Model.Dice;
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;
namespace Tests.Model_UTs
namespace Tests.Model_UTs.Games
{
public class GameTest
{

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

@ -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
{

@ -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")]

@ -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
{

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

Loading…
Cancel
Save