Files
Nonemm/tests/Nonemm.Spotting.Tests/BandmapTests.cs
ericek111 9b84b103ac Add N1MM's Mark and Store buttons
Both put something on our own bandmap and nothing on the cluster, which is
what separates them from Spot It.

Mark, Alt+M, leaves a mark where the radio is to say the frequency is busy.
The label is N1MM's, Busy@ and the time. It is not a station, so Spot carries
IsStation: nothing judges it, the check window does not offer it as a call,
available mults and Qs leaves it out, space does not take it into the callsign
box, and the bandmap paints it like a station already worked, which is how
N1MM marks it. The station count under the bandmap counts stations.

Store, Alt+O, puts the call being typed on the bandmap at this frequency so it
can be worked later. N1MM writes "Local spot" in the comment and this does the
same.

The action row now holds the eight buttons N1MM has, in N1MM's order and at
N1MM's widths: 23 per cent to Esc: Stop and 11 to each of the rest.

Left out of Store: N1MM also adds the call to what the check window's Master
column offers for the rest of the session. The call is on the bandmap, which
the check window already reads, so it is offered either way.

Driven under Xvfb: Alt+M leaving BUSY@22:32:27 on 14000, Alt+O storing
SP9XYZ there, and both drawn on the bandmap in the worked colour.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
2026-08-30 22:34:32 +00:00

107 lines
3.1 KiB
C#

using Nonemm.Core;
namespace Nonemm.Spotting.Tests;
public class BandmapTests
{
private static readonly DateTime Now = new(2026, 5, 30, 12, 0, 0, DateTimeKind.Utc);
private static Spot At(string call, double kilohertz, DateTime? at = null) =>
new(Callsign.Parse(call), Frequency.FromKilohertz(kilohertz), at ?? Now, SpotSource.Cluster);
[Fact]
public void SpotsComeBackInFrequencyOrder()
{
Bandmap map = new();
map.Add(At("DL1ABC", 14_100));
map.Add(At("JA1XYZ", 14_010));
Assert.Equal(["JA1XYZ", "DL1ABC"], map.On(Bands.Band20M).Select(s => s.Call.Text));
}
[Fact]
public void AStationThatMovesKeepsOneEntryOnItsBand()
{
Bandmap map = new();
map.Add(At("DL1ABC", 14_010));
map.Add(At("DL1ABC", 14_020));
Spot only = Assert.Single(map.On(Bands.Band20M));
Assert.Equal(14_020_000, only.Frequency.Hertz);
}
[Fact]
public void TheSameStationOnAnotherBandIsASeparateEntry()
{
Bandmap map = new();
map.Add(At("DL1ABC", 14_010));
map.Add(At("DL1ABC", 7_010));
Assert.Equal(2, map.All().Count);
}
[Fact]
public void SpotsOlderThanAnHourAreDropped()
{
DateTime arriving = Now.AddHours(-2);
Bandmap map = new(clock: () => arriving);
map.Add(At("DL1ABC", 14_010));
arriving = Now.AddMinutes(-5);
map.Add(At("JA1XYZ", 14_020));
map.DropOlderThan(Now);
Assert.Equal("JA1XYZ", Assert.Single(map.All()).Call.Text);
}
/// Nodes get their clocks wrong and replay their backlog on connect. Age is
/// counted from when the spot arrived, so a spot stamped hours ago still
/// shows for the hour after it turned up.
[Fact]
public void ASpotStampedLongAgoIsKeptIfItOnlyJustArrived()
{
Bandmap map = new(clock: () => Now);
map.Add(At("DL1ABC", 14_010, Now.AddHours(-4)));
map.DropOlderThan(Now);
Assert.Single(map.All());
}
[Fact]
public void ARespottedStationStartsItsHourAgain()
{
DateTime arriving = Now.AddMinutes(-50);
Bandmap map = new(clock: () => arriving);
map.Add(At("DL1ABC", 14_010));
arriving = Now;
map.Add(At("DL1ABC", 14_012));
map.DropOlderThan(Now.AddMinutes(30));
Assert.Single(map.All());
}
/// N1MM's Mark button leaves this where the radio is, to say the frequency
/// is busy.
[Fact]
public void AMarkIsLabelledWithTheTimeAndIsNotAStation()
{
Spot mark = Spot.Mark(
Frequency.FromKilohertz(14_030),
new DateTime(2026, 1, 1, 22, 31, 5, DateTimeKind.Utc));
Assert.Equal("BUSY@22:31:05", mark.Call.Text);
Assert.False(mark.IsStation);
}
[Fact]
public void TheNearestSpotInsideTheWindowIsFound()
{
Bandmap map = new();
map.Add(At("DL1ABC", 14_010));
map.Add(At("JA1XYZ", 14_050));
Assert.Equal(
"DL1ABC",
map.Near(Frequency.FromKilohertz(14_010.2), Frequency.FromKilohertz(0.5))?.Call.Text);
Assert.Null(map.Near(Frequency.FromKilohertz(14_030), Frequency.FromKilohertz(0.5)));
}
}