From bd1502436d77ac28a68692d3dcfb0aae291ec5d6 Mon Sep 17 00:00:00 2001 From: Alexis DRAI Date: Sun, 18 Sep 2022 19:40:16 +0200 Subject: [PATCH 1/3] :bug: Make hash case insensitive, check name validity --- Sources/Model/Player.cs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Sources/Model/Player.cs b/Sources/Model/Player.cs index 909028b..ca3c3f2 100644 --- a/Sources/Model/Player.cs +++ b/Sources/Model/Player.cs @@ -1,10 +1,27 @@ using System; +using System.Xml.Linq; namespace Model { public class Player : IEquatable { - public string Name { get; internal set; } + public string Name + { + get + { + return name; + } + internal set + { + if (!String.IsNullOrWhiteSpace(value) && !value.Equals("")) + { + name = value; + } + else throw new ArgumentException("player name may never be empty or null"); + } + } + + private string name; public Player(string name) { @@ -32,7 +49,7 @@ namespace Model public override int GetHashCode() { - return Name.GetHashCode(); + return Name.ToUpper().GetHashCode(); } } } -- 2.36.3 From 0995660259e36c4063c9c8c43a4cad0a76b2cf6b Mon Sep 17 00:00:00 2001 From: Alexis DRAI Date: Sun, 18 Sep 2022 19:41:19 +0200 Subject: [PATCH 2/3] :white_check_mark: Design UTs for Player --- Sources/Tests/Model_UTs/PlayerTest.cs | 186 +++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 2 deletions(-) diff --git a/Sources/Tests/Model_UTs/PlayerTest.cs b/Sources/Tests/Model_UTs/PlayerTest.cs index d786770..64cda10 100644 --- a/Sources/Tests/Model_UTs/PlayerTest.cs +++ b/Sources/Tests/Model_UTs/PlayerTest.cs @@ -1,4 +1,5 @@ using Model; +using System; using Xunit; namespace Tests.Model_UTs @@ -6,10 +7,191 @@ namespace Tests.Model_UTs public class PlayerTest { [Fact] - public void TestConstructor() + public void TestConstructorIfNameThenCorrectName() { - Player player = new Player("Alice"); + // Arrange + Player player; + + // Act + player = new("Alice"); + + // Assert Assert.Equal("Alice", player.Name); } + + [Fact] + public void TestConstructorIfWhitespaceThenException() + { + // Arrange + Player player; + + // Act + Action action = () => player = new(" "); + + // Assert + Assert.Throws(action); + } + + [Fact] + public void TestConstructorIfBlankThenException() + { + // Arrange + Player player; + + // Act + Action action = () => player = new(""); + + // Assert + Assert.Throws(action); + } + + [Fact] + public void TestConstructorIfNullThenException() + { + // Arrange + Player player; + + // Act + Action action = () => player = new(null); + + // Assert + Assert.Throws(action); + } + + [Fact] + public void TestToStringCorrectName() + { + // Arrange + string expected = "Bob"; + Player player = new(expected); + + // Act + string actual = player.ToString(); + + // Assert + Assert.Equal(expected, actual); + } + + class Point + { + public int X { get; set; } + public int Y { get; set; } + public Point(int x, int y) + { + X = x; Y = y; + } + } + + [Fact] + public void TestEqualsFalseIfNotPlayer() + { + // Arrange + Point point; + Player player; + + // Act + point = new(1, 2); + player = new("Clyde"); + + // Assert + Assert.False(point.Equals(player)); + Assert.False(player.Equals(point)); + } + + [Fact] + public void TestEqualsFalseIfNotSameName() + { + // Arrange + Player p1; + Player p2; + + // Act + p1 = new("Panama"); + p2 = new("Clyde"); + + // Assert + Assert.False(p1.Equals(p2)); + Assert.False(p2.Equals(p1)); + } + + [Fact] + public void TestEqualsTrueIfSameNameDifferentCase() + { + // Arrange + Player p1; + Player p2; + + // Act + p1 = new("Devon"); + p2 = new("devoN"); + + // Assert + Assert.True(p1.Equals(p2)); + Assert.True(p2.Equals(p1)); + } + + [Fact] + public void TestEqualsTrueIfExactlySameName() + { + // Arrange + Player p1; + Player p2; + + // Act + p1 = new("Elyse"); + p2 = new("Elyse"); + + // Assert + Assert.True(p1.Equals(p2)); + Assert.True(p2.Equals(p1)); + } + + [Fact] + public void TestSameHashFalseIfNotSameName() + { + // Arrange + Player p1; + Player p2; + + // Act + p1 = new("Panama"); + p2 = new("Clyde"); + + // Assert + Assert.False(p1.GetHashCode().Equals(p2.GetHashCode())); + Assert.False(p2.GetHashCode().Equals(p1.GetHashCode())); + } + + [Fact] + public void TestSameHashTrueIfSameNameDifferentCase() + { + // Arrange + Player p1; + Player p2; + + // Act + p1 = new("Devon"); + p2 = new("devoN"); + + // Assert + Assert.True(p1.GetHashCode().Equals(p2.GetHashCode())); + Assert.True(p2.GetHashCode().Equals(p1.GetHashCode())); + } + + [Fact] + public void TestSameHashTrueIfExactlySameName() + { + // Arrange + Player p1; + Player p2; + + // Act + p1 = new("Elyse"); + p2 = new("Elyse"); + + // Assert + Assert.True(p1.GetHashCode().Equals(p2.GetHashCode())); + Assert.True(p2.GetHashCode().Equals(p1.GetHashCode())); + } } } -- 2.36.3 From bfe20a653c416326d4ace0bc9bab6947fb4d491c Mon Sep 17 00:00:00 2001 From: Alexis DRAI Date: Sun, 18 Sep 2022 20:09:07 +0200 Subject: [PATCH 3/3] :white_check_mark: Complete #27 and Fix #44 --- Sources/Model/Player.cs | 11 +++- Sources/Model/PlayerManager.cs | 7 +-- Sources/Tests/Model_UTs/PlayerManagerTest.cs | 13 +++++ Sources/Tests/Model_UTs/PlayerTest.cs | 53 ++++++++++++++++++-- 4 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 Sources/Tests/Model_UTs/PlayerManagerTest.cs diff --git a/Sources/Model/Player.cs b/Sources/Model/Player.cs index ca3c3f2..e5d2347 100644 --- a/Sources/Model/Player.cs +++ b/Sources/Model/Player.cs @@ -20,7 +20,7 @@ namespace Model else throw new ArgumentException("player name may never be empty or null"); } } - + private string name; public Player(string name) @@ -28,6 +28,15 @@ namespace Model Name = name; } + public Player(Player player) + { + if (player != null) + { + Name = player.name; + } + else throw new ArgumentException("you may not make a copy of a null player"); + } + public override string ToString() { return Name; diff --git a/Sources/Model/PlayerManager.cs b/Sources/Model/PlayerManager.cs index cafabd6..bfe1b16 100644 --- a/Sources/Model/PlayerManager.cs +++ b/Sources/Model/PlayerManager.cs @@ -55,10 +55,11 @@ namespace Model /// player with said name public Player GetOneByName(string name) { - if (!String.IsNullOrEmpty(name)) + if (!String.IsNullOrWhiteSpace(name) && !name.Equals("")) { - Player result = players.Where(p => p.Name.Equals(name)).FirstOrDefault(); - return new Player(result.Name); // will return null if no such player exists + Player result = players.FirstOrDefault(p => p.Name.Equals(name)); + return new Player(result); // THIS IS A COPY (using a copy constructor) + // will return null by default if no such player exists } return null; // we also want ot return null if no name was provided } diff --git a/Sources/Tests/Model_UTs/PlayerManagerTest.cs b/Sources/Tests/Model_UTs/PlayerManagerTest.cs new file mode 100644 index 0000000..909275d --- /dev/null +++ b/Sources/Tests/Model_UTs/PlayerManagerTest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tests.Model_UTs +{ + internal class PlayerManagerTest + { + // TODO test that Player's copy constructer enables isolated changes + } +} diff --git a/Sources/Tests/Model_UTs/PlayerTest.cs b/Sources/Tests/Model_UTs/PlayerTest.cs index 64cda10..f0bfa96 100644 --- a/Sources/Tests/Model_UTs/PlayerTest.cs +++ b/Sources/Tests/Model_UTs/PlayerTest.cs @@ -26,7 +26,7 @@ namespace Tests.Model_UTs Player player; // Act - Action action = () => player = new(" "); + void action() => player = new(" "); // Assert Assert.Throws(action); @@ -39,7 +39,7 @@ namespace Tests.Model_UTs Player player; // Act - Action action = () => player = new(""); + void action() => player = new(""); // Assert Assert.Throws(action); @@ -50,9 +50,10 @@ namespace Tests.Model_UTs { // Arrange Player player; + string name = null; // Act - Action action = () => player = new(null); + void action() => player = new Player(name); // Assert Assert.Throws(action); @@ -98,6 +99,23 @@ namespace Tests.Model_UTs Assert.False(player.Equals(point)); } + [Fact] + public void TestGoesThruIfObjIsPlayer() + { + // Arrange + Object p1; + Player p2; + + // Act + p1 = new Player("Marvin"); + p2 = new("Clyde"); + + // Assert + Assert.False(p1.Equals(p2)); + Assert.False(p2.Equals(p1)); + } + + [Fact] public void TestEqualsFalseIfNotSameName() { @@ -193,5 +211,34 @@ namespace Tests.Model_UTs Assert.True(p1.GetHashCode().Equals(p2.GetHashCode())); Assert.True(p2.GetHashCode().Equals(p1.GetHashCode())); } + + [Fact] + public void TestCopyConstructorExactCopy() + { + // Arrange + Player p1; + Player p2; + + // Act + p1 = new("Elyse"); + p2 = new(p1); + + // Assert + Assert.True(p1.Equals(p2)); + } + + [Fact] + public void TestCopyConstructorIfNullThenException() + { + // Arrange + Player p1; + Player p2 = null; + + // Act + void action() => p1 = new Player(p2); + + // Assert + Assert.Throws(action); + } } } -- 2.36.3