Files
Nonemm/tests/Nonemm.Contests.Tests/CqWorldWideRttyTests.cs
ericek111 5c0ca558c1 Score the last three cases the way N1MM scores them
The three differences left after replaying the log were ours on purpose. A log
has to score the same in both programs, so they now follow N1MM:

- ARRL DX and CQ WW RTTY count the 14 Canadian areas N1MM lists as `48SDC14P`,
  which keeps Newfoundland apart from Labrador. A station sending the postal
  code is counted as the area the contest names.
- A maritime mobile is scored from the call it signs. CQ WW says it counts for
  the zone alone; N1MM gives it the country, and so do we.
- A callsign the country file cannot place counts as a multiplier with an empty
  value, so every unplaceable call worked on a band shares one multiplier.

29 of the 37 contest instances in the log now agree with N1MM on every contact
and on the totals. What is left is the country file of the day and rows whose
cached points N1MM never worked out again after a call was corrected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
2026-08-31 08:36:44 +00:00

115 lines
3.8 KiB
C#

using Nonemm.Contests.Rules;
using Nonemm.Core;
namespace Nonemm.Contests.Tests;
/// CQ WW RTTY is scored differently from the CW and SSB running of the same
/// contest, so it gets its own tests rather than sharing them.
public class CqWorldWideRttyTests
{
private static readonly Contest Rtty = new CqWorldWide(ModeCategory.Digital);
private static ContestLog LogFor(StationInfo me) => new(Rtty, me, TestLog.CountryFile);
private static Qso Contact(string call, int zone, string stateOrProvince = "") =>
TestLog.Contact(call, mode: Modes.Rtty, zone: zone, section: stateOrProvince);
[Fact]
public void ContactInsideYourOwnCountryScoresOne()
{
ContestLog log = LogFor(TestLog.Germany);
Assert.Equal(1, log.Judge(Contact("DL9XYZ", 14)).Points);
}
[Fact]
public void SameContinentScoresTwo()
{
ContestLog log = LogFor(TestLog.Germany);
Assert.Equal(2, log.Judge(Contact("IK2XYZ", 15)).Points);
}
[Fact]
public void DifferentContinentScoresThree()
{
ContestLog log = LogFor(TestLog.Germany);
Assert.Equal(3, log.Judge(Contact("JA1XYZ", 25)).Points);
}
[Fact]
public void TheStateIsAThirdMultiplier()
{
ContestLog log = LogFor(TestLog.Germany);
Verdict verdict = log.Judge(Contact("K1ABC", 5, "CT"));
Assert.Equal(
["5", "K", "CT"],
verdict.NewMultipliers.Select(m => m.Value).ToList());
}
[Fact]
public void AStationOutsideTheUnitedStatesAndCanadaBringsNoStateMultiplier()
{
ContestLog log = LogFor(TestLog.Germany);
Verdict verdict = log.Judge(Contact("JA1XYZ", 25, "DX"));
Assert.Equal(["25", "JA"], verdict.NewMultipliers.Select(m => m.Value).ToList());
}
[Fact]
public void TheStateCountsAgainOnAnotherBand()
{
ContestLog log = LogFor(TestLog.Germany);
log.Add(Contact("K1ABC", 5, "CT"));
Verdict verdict = log.Judge(
TestLog.Contact("K2DEF", kilohertz: 7_040, mode: Modes.Rtty, zone: 5, section: "CT"));
Assert.Contains(verdict.NewMultipliers, m => m.Value == "CT");
}
[Fact]
public void TheThreeMultiplierNamesAreShown() =>
Assert.Equal(["Zones", "Countries", "States"], Rtty.MultiplierNames);
[Fact]
public void TheCabrilloNameIsTheRttyOne() => Assert.Equal("CQ-WW-RTTY", Rtty.CabrilloName);
/// A station outside the US and Canada sends DX in the state column.
[Fact]
public void TheSentExchangeCarriesTheStateOrDx()
{
Assert.Equal("14 DX", Rtty.SentExchangeFor(TestLog.Germany));
Assert.Equal("5 CT", Rtty.SentExchangeFor(TestLog.UnitedStates));
}
[Fact]
public void TheExchangeHasAStateBoxThatIsNotRequired()
{
IReadOnlyList<ExchangeField> fields = Rtty.ExchangeFieldsFor(TestLog.Germany);
Assert.Equal(3, fields.Count);
Assert.Equal(ExchangeSlot.Section, fields[2].Slot);
Assert.False(fields[2].IsRequired);
}
/// The Canadian areas this contest counts are its own list, which splits
/// Newfoundland from Labrador.
[Theory]
[InlineData("NF")]
[InlineData("LB")]
public void TheContestsOwnCanadianAreasCount(string area) =>
Assert.Contains(
LogFor(TestLog.Germany).Judge(Contact("VO1XYZ", 5, area)).NewMultipliers,
m => m.Index == 3 && m.Value == area);
/// A maritime mobile station is at sea and belongs to no country. It is
/// scored from the call it signs, which is the country N1MM logs for it,
/// and it brings no WPX prefix.
[Fact]
public void MaritimeMobileIsScoredFromTheCallItSigns()
{
Verdict verdict = LogFor(TestLog.Germany).Judge(Contact("IK2XYZ/MM", 15));
Assert.Equal(2, verdict.Points);
Assert.Contains(verdict.NewMultipliers, m => m.Index == 2 && m.Value == "I");
}
}