using FluentAssertions; using Xunit; namespace EMQual.Test; public sealed class QualDataTests { [Fact] public void IsCountryMatch_None() { Match match = new(new TeamResult("Foo", 1), new TeamResult("Bar", 2)); QualData.IsCountryMatch(match, "Baz") .Should().BeFalse("Country did not play in this match"); } [Fact] public void IsCountryMatch_Home() { const string Country = "Baz"; Match match = new(new TeamResult(Country, 1), new TeamResult("Bar", 2)); QualData.IsCountryMatch(match, Country) .Should().BeTrue("Country participated in match"); } [Fact] public void IsCountryMatch_Guest() { const string Country = "Baz"; Match match = new(new TeamResult("Foo", 1), new TeamResult(Country, 2)); QualData.IsCountryMatch(match, Country) .Should().BeTrue("Country participated in match"); } [Fact] public void FilterMatchesByCountry_None() { var matches = new Match[] { new(new TeamResult("Foo", 3), new TeamResult("Bar", 0)), new(new TeamResult("Foo", 1), new TeamResult("Qux", 1)) }; QualData.FilterMatchesByCountry(matches, "Baz") .Should().NotBeNull("array has been created") .And.BeEmpty("no matches for the supplied country"); } [Fact] public void FilterMatchesByCountry_Simple() { var matches = new Match[] { new(new TeamResult("Foo", 3), new TeamResult("Bar", 0)), new(new TeamResult("Qux", 1), new TeamResult("Foo", 1)), new(new TeamResult("Bar", 1), new TeamResult("Qux", 2)) }; QualData.FilterMatchesByCountry(matches, "Foo") .Should().NotBeNull("array has been created") .And.HaveCount(2, "country participated in two matches") .And.Contain(new[] { matches[0], matches[1] }); } [Fact] public void ExtractUniqueCountryNames_Simple() { var matches = new Match[] { new(new TeamResult("Foo", 3), new TeamResult("Bar", 0)), new(new TeamResult("Qux", 1), new TeamResult("Foo", 1)), new(new TeamResult("Bar", 1), new TeamResult("Qux", 2)), new(new TeamResult("Baz", 3), new TeamResult("Qux", 1)) }; QualData.ExtractUniqueCountryNames(matches) .Should().NotBeNull("array has been created") .And.HaveCount(4, "number of different countries in all matches") .And.Contain(new[] { "Foo", "Bar", "Qux", "Baz" }, "names of the countries"); } [Fact] public void IsContained_Empty() { QualData.IsContained("Foo", Array.Empty()) .Should().BeFalse("array is empty"); } [Fact] public void IsContained_NotContained() { var possValues = new[] { "Bar", "Baz", "Qux" }; QualData.IsContained("Foo", possValues) .Should().BeFalse("value not contained"); } [Fact] public void IsContained_Contained() { var possValues = new[] { "Bar", "Baz", "Foo", "Qux" }; QualData.IsContained("Foo", possValues) .Should().BeTrue("value is contained"); } [Fact] public void IsContained_IgnoreCase() { var possValues = new[] { "Bar", "Baz", "Foo", "Qux" }; QualData.IsContained("fOo", possValues) .Should().BeTrue("value is contained"); } [Fact] public void TryParseMatch_Simple() { const string Line = "Foo;Bar;2;3"; QualData.TryParseMatch(Line, out var parsedMatch) .Should().BeTrue("valid line could be parsed"); parsedMatch.Should().NotBeNull("successful parse, instance created") .And.BeEquivalentTo(new Match(new TeamResult("Foo", 2), new TeamResult("Bar", 3))); } [Theory] [InlineData("Foo;Bar;2;-3", "invalid goals")] [InlineData("Foo;Bar;t;3", "invalid goals")] [InlineData("Foo;Bar;2", "missing value")] [InlineData("Foo;Bar;2;1;4", "superfluous value")] [InlineData("Foo;1;Bar;2", "wrong order")] [InlineData("Foo;;1;2", "empty name")] [InlineData("Foo-Bar-1-2", "invalid separator")] public void TryParseMatch_Invalid(string line, string reason) { QualData.TryParseMatch(line, out var parsedMatch) .Should().BeFalse($"line could not be parsed: {reason}"); parsedMatch.Should().BeNull("parsing failed, no instance created"); } [Fact] public void ReadMatchesFromFile_Simple() { var expectedMatches = new Match[] { new(new TeamResult("Belgien", 0), new TeamResult("Deutschland", 1)), new(new TeamResult("Kasachstan", 0), new TeamResult("Türkei", 3)), new(new TeamResult("Deutschland", 6), new TeamResult("Aserbaidschan", 1)) }; var matches = QualData.ReadMatchesFromFile("Data/valid.csv"); matches.Should().NotBeNullOrEmpty("valid file containing valid matches processed") .And.HaveCount(3, "three matches defined in the file") .And.ContainInOrder(expectedMatches, "how the matches should have been parsed"); } [Theory] [InlineData("Data/none.csv", "the file does not exist, so no entries could be parsed")] [InlineData("Data/empty_01.csv", "the file exists but is empty, so no entries could be parsed")] [InlineData("Data/empty_02.csv", "the file exists but contains only the header, so no entries could be parsed")] [InlineData("Data/invalid_01.csv", "the file contains unexpected information, so parsing failed")] [InlineData("Data/invalid_02.csv", "the file contains an invalid entry, so none are returned")] public void ReadMatchesFromFile_Invalid(string filePath, string reason) { QualData.ReadMatchesFromFile(filePath) .Should().NotBeNull("an array is created and returned in any case") .And.HaveCount(0, reason) .And.BeSameAs(Array.Empty(), "empty array created properly"); } }