using System; using System.Collections.Generic; using System.IO; using FluentAssertions; using FluentAssertions.Execution; using Xunit; using TwoStrings = System.ValueTuple; using TwoNumbers = System.ValueTuple; using ThreeNumbers = System.ValueTuple; using FourNumbers = System.ValueTuple; using static System.Environment; using static Games.Common.IO.Strings; namespace Games.Common.IO.TextIOTests { public class ReadMethodTests { [Theory] [MemberData(nameof(ReadStringTestCases))] [MemberData(nameof(Read2StringsTestCases))] [MemberData(nameof(ReadNumberTestCases))] [MemberData(nameof(Read2NumbersTestCases))] [MemberData(nameof(Read3NumbersTestCases))] [MemberData(nameof(Read4NumbersTestCases))] [MemberData(nameof(ReadNumbersTestCases))] public void ReadingValuesHasExpectedPromptsAndResults( Func read, string input, string expectedOutput, T expectedResult) { var inputReader = new StringReader(input + Environment.NewLine); var outputWriter = new StringWriter(); var io = new TextIO(inputReader, outputWriter); var result = read.Invoke(io); var output = outputWriter.ToString(); using var _ = new AssertionScope(); output.Should().Be(expectedOutput); result.Should().BeEquivalentTo(expectedResult); } [Fact] public void ReadNumbers_ArrayEmpty_ThrowsArgumentException() { var io = new TextIO(new StringReader(""), new StringWriter()); Action readNumbers = () => io.ReadNumbers("foo", Array.Empty()); readNumbers.Should().Throw() .WithMessage("'values' must have a non-zero length.*") .WithParameterName("values"); } public static TheoryData, string, string, string> ReadStringTestCases() { static Func ReadString(string prompt) => io => io.ReadString(prompt); return new() { { ReadString("Name"), "", "Name? ", "" }, { ReadString("prompt"), " foo ,bar", $"prompt? {ExtraInput}{NewLine}", "foo" } }; } public static TheoryData, string, string, TwoStrings> Read2StringsTestCases() { static Func Read2Strings(string prompt) => io => io.Read2Strings(prompt); return new() { { Read2Strings("2 strings"), ",", "2 strings? ", ("", "") }, { Read2Strings("Input please"), $"{NewLine}x,y", $"Input please? ?? {ExtraInput}{NewLine}", ("", "x") } }; } public static TheoryData, string, string, float> ReadNumberTestCases() { static Func ReadNumber(string prompt) => io => io.ReadNumber(prompt); return new() { { ReadNumber("Age"), $"{NewLine}42,", $"Age? {NumberExpected}{NewLine}? {ExtraInput}{NewLine}", 42 }, { ReadNumber("Guess"), "3,4,5", $"Guess? {ExtraInput}{NewLine}", 3 } }; } public static TheoryData, string, string, TwoNumbers> Read2NumbersTestCases() { static Func Read2Numbers(string prompt) => io => io.Read2Numbers(prompt); return new() { { Read2Numbers("Point"), "3,4,5", $"Point? {ExtraInput}{NewLine}", (3, 4) }, { Read2Numbers("Foo"), $"x,4,5{NewLine}4,5,x", $"Foo? {NumberExpected}{NewLine}? {ExtraInput}{NewLine}", (4, 5) } }; } public static TheoryData, string, string, ThreeNumbers> Read3NumbersTestCases() { static Func Read3Numbers(string prompt) => io => io.Read3Numbers(prompt); return new() { { Read3Numbers("Point"), "3.2, 4.3, 5.4, 6.5", $"Point? {ExtraInput}{NewLine}", (3.2F, 4.3F, 5.4F) }, { Read3Numbers("Bar"), $"x,4,5{NewLine}4,5,x{NewLine}6,7,8,y", $"Bar? {NumberExpected}{NewLine}? {NumberExpected}{NewLine}? {ExtraInput}{NewLine}", (6, 7, 8) } }; } public static TheoryData, string, string, FourNumbers> Read4NumbersTestCases() { static Func Read4Numbers(string prompt) => io => io.Read4Numbers(prompt); return new() { { Read4Numbers("Point"), "3,4,5,6,7", $"Point? {ExtraInput}{NewLine}", (3, 4, 5, 6) }, { Read4Numbers("Baz"), $"x,4,5,6{NewLine} 4, 5 , 6,7 ,x", $"Baz? {NumberExpected}{NewLine}? {ExtraInput}{NewLine}", (4, 5, 6, 7) } }; } public static TheoryData>, string, string, float[]> ReadNumbersTestCases() { static Func> ReadNumbers(string prompt) => io => { var numbers = new float[6]; io.ReadNumbers(prompt, numbers); return numbers; }; return new() { { ReadNumbers("Primes"), "2, 3, 5, 7, 11, 13", $"Primes? ", new float[] { 2, 3, 5, 7, 11, 13 } }, { ReadNumbers("Qux"), $"42{NewLine}3.141, 2.718{NewLine}3.0e8, 6.02e23{NewLine}9.11E-28", $"Qux? ?? ?? ?? ", new[] { 42, 3.141F, 2.718F, 3.0e8F, 6.02e23F, 9.11E-28F } } }; } } }