diff --git a/Sources/Model/Turn.cs b/Sources/Model/Turn.cs new file mode 100644 index 0000000..f951bb4 --- /dev/null +++ b/Sources/Model/Turn.cs @@ -0,0 +1,100 @@ +using System; + +namespace Model +{ + /// + /// a Turn consists of a Player, a DateTime, and a IEnumerable of AbstractDieFace + /// Like a turn in some game. + ///
+ /// Two turns are equal if they are litterally the same instance in RAM + /// (default behaviors Equals() and GetHashCode()) + ///
+ public class Turn + { + + /// + /// the date and time, adjusted to UTC + /// + public readonly DateTime when; + + /// + /// the Player who rolled the dice + /// + public readonly Player player; + + /* + public IEnumerable Faces { get; private set; } + */ + + /// + /// this private constructor is to be used only by factories + /// + /// date and time of the turn + /// player who played the turn + // TODO add faces + private Turn(DateTime when, Player player/*, IEnumerable faces*/) + { + this.when = when; + this.player = player; + /*Faces = faces;*/ + } + + /// + /// creates a Turn with a specified time, passed as a parameter. + ///
+ /// whatever the DateTimeKind of might be, + /// it will become UTC during construction + ///
+ /// date and time of the turn + /// player who played the turn + /// a new Turn object + // TODO add faces + public static Turn CreateWithSpecifiedTime(DateTime when, Player player/*, IEnumerable faces*/) + { + // TODO add validation for faces too + if (player == null) + { + throw new ArgumentNullException(nameof(player), "param should not be null"); + } + if (when.Kind != DateTimeKind.Utc) + { + when = when.ToUniversalTime(); + } + + return new Turn(when, player/*, faces*/); + } + + /// + /// creates a Turn with a default time, which is "now" in UTC. + /// + /// player who played the turn + /// a new Turn object + // TODO add faces + public static Turn CreateWithDefaultTime(Player player/*, IEnumerable faces*/) + { + return CreateWithSpecifiedTime(DateTime.UtcNow, player/*, faces*/); + } + + //TODO add faces + /// + /// represents a turn in string format + /// + /// a turn in string format + public override string ToString() + { + //string[] datetime = this.when.ToString("s", System.Globalization.CultureInfo.InvariantCulture).Split("T"); + //string date = datetime[0]; + //string time = datetime[1]; + + return String.Format("{0} -- {1} rolled {2}", + ToStringIsoWithZ(), + this.player.ToString(), + ", , ..."); + } + + private string ToStringIsoWithZ() + { + return this.when.ToString("s", System.Globalization.CultureInfo.InvariantCulture) + "Z"; + } + } +} diff --git a/Sources/Tests/Model_UTs/TurnTest.cs b/Sources/Tests/Model_UTs/TurnTest.cs new file mode 100644 index 0000000..dc85b99 --- /dev/null +++ b/Sources/Tests/Model_UTs/TurnTest.cs @@ -0,0 +1,99 @@ +using Model; +using System; +using Xunit; + +namespace Tests.Model_UTs +{ + public class TurnTest + { + [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); + + // 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); + + // 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); + + // Assert + Assert.Throws(action); + } + + [Fact] + public void TestCreateWithDefaultTimeThenValid() + { + // Arrange + Player player = new("Chloe"); + + // Act + Turn turn = Turn.CreateWithDefaultTime(player); + + // 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 TestCreateWithDefaultTimeNullPlayerThenException() + { + // Arrange + Player player = new("Devon"); + + // Act + static void action() => Turn.CreateWithDefaultTime(null); + + // Assert + Assert.Throws(action); + } + + [Fact] + public void TestToStringValidIfAllNormal() + { + // Arrange + DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc); + string name = "Bobby"; + Player player = new(name); + string expected = $"2018-06-15T16:30:00Z -- {name} rolled , , ..."; + Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player); + + // Act + string actual = turn.ToString(); + + // Assert + Assert.Equal(expected, actual); + } + } +}