diff --git a/Sources/Model/Player.cs b/Sources/Model/Player.cs index 909028b..e5d2347 100644 --- a/Sources/Model/Player.cs +++ b/Sources/Model/Player.cs @@ -1,16 +1,42 @@ 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) { 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; @@ -32,7 +58,7 @@ namespace Model public override int GetHashCode() { - return Name.GetHashCode(); + return Name.ToUpper().GetHashCode(); } } } 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 d786770..f0bfa96 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,238 @@ 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 + void action() => player = new(" "); + + // Assert + Assert.Throws(action); + } + + [Fact] + public void TestConstructorIfBlankThenException() + { + // Arrange + Player player; + + // Act + void action() => player = new(""); + + // Assert + Assert.Throws(action); + } + + [Fact] + public void TestConstructorIfNullThenException() + { + // Arrange + Player player; + string name = null; + + // Act + void action() => player = new Player(name); + + // 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 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() + { + // 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())); + } + + [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); + } } }