using Nonemm.Contests.Rules; using Nonemm.Core; namespace Nonemm.Contests.Tests; public class WaeTests { private static readonly Wae Cw = new(ModeCategory.Cw); private static readonly Wae Rtty = new(ModeCategory.Digital); private static ContestLog LogFor(Contest contest, StationInfo me) => new(contest, me, TestLog.CountryFile); private static Qso On(string call, double kilohertz, Mode? mode = null) => TestLog.Contact(call, kilohertz: kilohertz, mode: mode ?? Modes.Cw, exchange: WaeQtc.Contact); [Fact] public void EveryContactOnAContestBandIsOnePoint() { ContestLog log = LogFor(Cw, TestLog.Germany); Assert.Equal(1, log.Judge(On("JA1XYZ", 14_025)).Points); } /// WAE does not run on the WARC bands. [Fact] public void AContactOnAWarcBandScoresNothing() { ContestLog log = LogFor(Cw, TestLog.Germany); Assert.Equal(0, log.Judge(On("JA1XYZ", 18_080)).Points); } [Fact] public void EuropeDoesNotWorkEuropeOnCw() { ContestLog log = LogFor(Cw, TestLog.Germany); Verdict verdict = log.Judge(On("IK2XYZ", 14_025)); Assert.Equal(0, verdict.Points); Assert.Empty(verdict.NewMultipliers); } [Fact] public void OnRttyEverybodyWorksEverybody() { ContestLog log = LogFor(Rtty, TestLog.Germany); Verdict verdict = log.Judge(On("IK2XYZ", 14_080, Modes.Rtty)); Assert.Equal(1, verdict.Points); Assert.Single(verdict.NewMultipliers); } /// A multiplier is worth four on 80 metres, three on 40 and two higher up. [Theory] [InlineData(3_530, 4)] [InlineData(7_030, 3)] [InlineData(14_030, 2)] [InlineData(21_030, 2)] [InlineData(28_030, 2)] public void AMultiplierIsWorthMoreOnTheLowBands(double kilohertz, int weight) { ContestLog log = LogFor(Cw, TestLog.Germany); Multiplier multiplier = Assert.Single(log.Judge(On("JA1XYZ", kilohertz)).NewMultipliers); Assert.Equal(weight, multiplier.Weight); Assert.Equal("JA1", multiplier.Value); } [Fact] public void TheWeightGoesIntoTheScore() { ContestLog log = LogFor(Cw, TestLog.Germany); log.Add(On("JA1XYZ", 3_530)); Assert.Equal(1, log.Tally.Points); Assert.Equal(4, log.Tally.TotalMultipliers); Assert.Equal(4, log.TotalScore); } /// The countries with call areas count each area separately. [Theory] [InlineData("K1ABC", "K1")] [InlineData("W6XYZ", "K6")] [InlineData("JA1XYZ", "JA1")] [InlineData("PY2ABC", "PY2")] public void ACallAreaIsAMultiplierOfItsOwn(string call, string expected) { ContestLog log = LogFor(Cw, TestLog.Germany); Multiplier multiplier = Assert.Single(log.Judge(On(call, 14_025)).NewMultipliers); Assert.Equal(expected, multiplier.Value); } /// Asiatic Russia goes by the call area digit whatever the prefix on the /// air, so RM0W and UA0AB are the same multiplier. [Theory] [InlineData("RM0W")] [InlineData("UA0AB")] public void AsiaticRussiaCountsByCallArea(string call) { ContestLog log = LogFor(Cw, TestLog.Germany); Multiplier multiplier = Assert.Single(log.Judge(On(call, 14_025)).NewMultipliers); Assert.Equal("UA0", multiplier.Value); } /// A callsign the country file cannot place still counts, with an empty /// value, so the log scores the same here as in N1MM. All the unplaceable /// calls worked on a band share the one multiplier between them. [Fact] public void ACallWithNoCountryCountsOncePerBand() { ContestLog log = LogFor(Cw, TestLog.Germany); Assert.Equal("", Assert.Single(log.Judge(On("D1M", 14_025)).NewMultipliers).Value); log.Add(On("D1M", 14_025)); Assert.Empty(log.Judge(On("D2X", 14_025)).NewMultipliers); } [Fact] public void AQtcIsAPointAndNothingElse() { ContestLog log = LogFor(Rtty, TestLog.Germany); Qso qtc = new WaeQtc( Callsign.Parse("JA1XYZ"), IsSent: true, 1, 10, "1435", Callsign.Parse("DL9XYZ"), 42) .ApplyTo(On("JA1XYZ", 14_080, Modes.Rtty)); Verdict verdict = log.Judge(qtc); Assert.Equal(1, verdict.Points); Assert.Empty(verdict.NewMultipliers); } /// The station is worked once and then reported to ten times over; those /// rows must not read as dupes of the contact. [Fact] public void QtcTrafficWithAStationAlreadyWorkedIsNotADupe() { ContestLog log = LogFor(Rtty, TestLog.Germany); log.Add(On("JA1XYZ", 14_080, Modes.Rtty)); Qso qtc = new WaeQtc( Callsign.Parse("JA1XYZ"), IsSent: true, 1, 10, "1435", Callsign.Parse("DL9XYZ"), 42) .ApplyTo(On("JA1XYZ", 14_080, Modes.Rtty)); Assert.False(log.Judge(qtc).IsDupe); log.Add(qtc); Assert.Equal(2, log.Tally.Points); Assert.Equal(2, log.Tally.TotalMultipliers); } [Fact] public void AQtcGoesIntoTheLogTheWayN1mmKeepsIt() { WaeQtc qtc = new( Callsign.Parse("H2X"), IsSent: true, 9, 10, "0107", Callsign.Parse("OH1SIC"), 7); Qso row = qtc.ApplyTo(On("H2X", 14_099, Modes.Rtty)); Assert.Equal("SQTC", row.Exchange1); Assert.Equal("9/10", row.MiscText); Assert.Equal("0107", row.SentReport); Assert.Equal("OH1SIC", row.ReceivedReport); Assert.Equal(7, row.SentNumber); Assert.Equal(qtc, WaeQtc.From(row)); } [Fact] public void AnOrdinaryContactIsNotAQtc() => Assert.Null(WaeQtc.From(On("JA1XYZ", 14_025))); }