using Nonemm.Core; namespace Nonemm.Session.Tests; public class EarlierContactsTests { private static Qso Contact( string call, double kilohertz = 14_030, Mode? mode = null, int minute = 0, string grid = "") { return new Qso { Id = Qso.NewId(), TimestampUtc = new DateTime(2026, 1, 1, 0, minute, 0, DateTimeKind.Utc), Call = Callsign.Parse(call), Frequency = Frequency.FromKilohertz(kilohertz), Mode = mode ?? Modes.Cw, ContestName = "CQWW", GridSquare = grid, }; } [Fact] public void FindsEveryContactWhoseCallHoldsWhatIsTyped() { List log = [Contact("DL1ABC"), Contact("OM3KFF"), Contact("W1ABCD")]; IReadOnlyList found = EarlierContacts.Matching(log, "ABC"); Assert.Equal(["DL1ABC", "W1ABCD"], found.Select(q => q.Call.Text)); } [Fact] public void SaysNothingUntilThreeCharactersAreTyped() { List log = [Contact("DL1ABC")]; Assert.Empty(EarlierContacts.Matching(log, "DL")); Assert.Single(EarlierContacts.Matching(log, "DL1")); } [Fact] public void AStarStandsForAnyRunOfCharacters() { List log = [Contact("DL1ABC"), Contact("DL2XYZ"), Contact("OM3DL1")]; IReadOnlyList found = EarlierContacts.Matching(log, "DL*C"); Assert.Equal(["DL1ABC"], found.Select(q => q.Call.Text)); } [Fact] public void AQuestionMarkStandsForOneCharacter() { List log = [Contact("DL1ABC"), Contact("DL11ABC")]; IReadOnlyList found = EarlierContacts.Matching(log, "DL?ABC"); Assert.Equal(["DL1ABC"], found.Select(q => q.Call.Text)); } [Fact] public void AWildcardPatternCoversTheWholeCall() { List log = [Contact("DL1ABC"), Contact("OM3DL1")]; Assert.Equal(["DL1ABC"], EarlierContacts.Matching(log, "DL1*").Select(q => q.Call.Text)); } [Fact] public void WithNothingTypedItFollowsTheGridSquare() { List log = [ Contact("DL1ABC", grid: "JN88MD"), Contact("OM3KFF", grid: "JO70AA"), ]; IReadOnlyList found = EarlierContacts.Matching(log, "", "JN88"); Assert.Equal(["DL1ABC"], found.Select(q => q.Call.Text)); } [Fact] public void WithNeitherACallNorAGridItSaysNothing() { Assert.Empty(EarlierContacts.Matching([Contact("DL1ABC", grid: "JN88MD")], "", "")); } [Fact] public void OrdersByCallThenModeThenFrequencyThenTime() { List log = [ Contact("OM3KFF", kilohertz: 14_200, mode: Modes.Usb, minute: 4), Contact("DL1ABC", kilohertz: 21_030, minute: 3), Contact("DL1ABC", kilohertz: 14_030, mode: Modes.Usb, minute: 2), Contact("DL1ABC", kilohertz: 14_030, minute: 1), ]; IReadOnlyList found = EarlierContacts.Matching(log, "??????"); Assert.Equal( [(1, "DL1ABC"), (3, "DL1ABC"), (2, "DL1ABC"), (4, "OM3KFF")], found.Select(q => (q.TimestampUtc.Minute, q.Call.Text))); } [Fact] public void KeepsAtMostTheLimit() { List log = [.. Enumerable.Range(0, 60).Select(n => Contact($"DL1AB{n:00}"))]; Assert.Equal(EarlierContacts.Limit, EarlierContacts.Matching(log, "DL1").Count); } }