Carry out the call history section directives

A call history file is built from years of logs, so its section and
state columns carry old names, and the file says at the top what to do
about that. The four lines that say it were read and passed over.

All four are now carried out, in N1MM's order: !!MapOnSection!! stores
the old Ontario sections as ON, !!ValidateArrlSection!! drops a section
that is not one of N1MM's, !!GTA2GH_NT2TER!! stores GTA as GH and NT as
TER, and !!Validate50State!! keeps a state, turns a section into the
state it is in, or drops the value.

The section list is the one N1MM's call history reader validates
against, which is not the list its entry window offers: it holds the
retired GTA and NT, and leaves out ON. It sits beside the reader in
Nonemm.Core rather than with the contest lists, which are the entry
window's.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
This commit is contained in:
2026-08-31 14:21:02 +00:00
parent 2eeda451c3
commit 76b57cee1d
5 changed files with 271 additions and 55 deletions

View File

@@ -170,9 +170,9 @@ public class CallHistoryTests
Assert.Equal("second", history.Find("OM5M")?.UserText);
}
/// A directive we do not act on must not be read as a callsign.
/// A directive must not be read as a callsign.
[Fact]
public void ADirectiveWeIgnoreIsStillNotData()
public void ADirectiveIsNotData()
{
CallHistory history = CallHistory.Parse("""
!!ValidateArrlSection!!
@@ -184,6 +184,70 @@ public class CallHistoryTests
Assert.Null(history.Find("!!ValidateArrlSection!!"));
}
/// `!!MapOnSection!!`: the old Ontario sections are stored as `ON`.
[Theory]
[InlineData("ONN", "ON")]
[InlineData("GTA", "ON")]
[InlineData("EMA", "EMA")]
public void MapOnSectionStoresTheOntarioSectionsAsOne(string section, string expected) =>
Assert.Equal(
expected,
Section("!!MapOnSection!!", section));
/// `!!ValidateArrlSection!!`: a section that is not one of N1MM's is
/// dropped rather than stored.
[Theory]
[InlineData("EMA", "EMA")]
[InlineData("XYZ", "")]
[InlineData("ON", "")]
public void ValidateArrlSectionDropsWhatIsNotASection(string section, string expected) =>
Assert.Equal(expected, Section("!!ValidateArrlSection!!", section));
/// `!!GTA2GH_NT2TER!!`: the two renamed sections.
[Theory]
[InlineData("GTA", "GH")]
[InlineData("NT", "TER")]
[InlineData("ONN", "ONN")]
public void Gta2GhRenamesTheTwoSections(string section, string expected) =>
Assert.Equal(expected, Section("!!GTA2GH_NT2TER!!", section));
/// `!!Validate50State!!`: a state stays, a section becomes the state it is
/// in, and anything else goes.
[Theory]
[InlineData("OH", "OH")]
[InlineData("EMA", "MA")]
[InlineData("SCV", "CA")]
[InlineData("ONN", "")]
[InlineData("XYZ", "")]
public void Validate50StateKeepsOnlyStates(string state, string expected) =>
Assert.Equal(
expected,
CallHistory.Parse($"""
!!Validate50State!!
!!Order!!,Call,State
OM5M,{state}
""").Find("OM5M")?.State);
/// Without the directive the column is stored as the file wrote it.
[Fact]
public void AFileThatAsksForNoCleanupIsStoredAsItIs()
{
CallHistoryEntry? found = CallHistory.Parse("""
!!Order!!,Call,Sect,State
VE3ABC,ONN,XYZ
""").Find("VE3ABC");
Assert.Equal("ONN", found?.Section);
Assert.Equal("XYZ", found?.State);
}
private static string? Section(string directive, string section) =>
CallHistory.Parse($"""
{directive}
!!Order!!,Call,Sect
VE3ABC,{section}
""").Find("VE3ABC")?.Section;
[Fact]
public void ALineWithNoCallIsNotAnEntry() =>
Assert.Equal(0, CallHistory.Parse(",Erik,JN88").Count);