The zoom list gains 60 kHz and a "mode" level that shows the CW, digital or phone part of the band the receiver is in, before "band". For views from 40 to 200 kHz wide, the scale picks the smallest round step that keeps three lines of text between ticks. The font size buttons are removed; Ctrl with the wheel or plus and minus still change the size. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
122 lines
4.0 KiB
C#
122 lines
4.0 KiB
C#
using Nonemm.Core;
|
|
|
|
namespace Nonemm.Spotting.Tests;
|
|
|
|
public class BandmapLayoutTests
|
|
{
|
|
private const double LabelHeight = 10;
|
|
|
|
private static readonly DateTime Now = new(2026, 5, 30, 12, 0, 0, DateTimeKind.Utc);
|
|
|
|
/// 14000 to 14100 kHz over 100 pixels, so one pixel is one kilohertz.
|
|
private static BandmapScale Scale() =>
|
|
new(Frequency.FromKilohertz(14_000), Frequency.FromKilohertz(14_100), 100);
|
|
|
|
private static Spot At(double kilohertz, string call = "DL1ABC") =>
|
|
new(Callsign.Parse(call), Frequency.FromKilohertz(kilohertz), Now, SpotSource.Cluster);
|
|
|
|
[Fact]
|
|
public void ALabelSitsCentredOnItsFrequency()
|
|
{
|
|
IReadOnlyList<BandmapLabel> placed = BandmapLayout.Place([At(14_050)], Scale(), LabelHeight);
|
|
|
|
Assert.Equal(50, placed[0].MarkY);
|
|
Assert.Equal(45, placed[0].LabelY);
|
|
}
|
|
|
|
[Fact]
|
|
public void LabelsComeOutInFrequencyOrder()
|
|
{
|
|
IReadOnlyList<BandmapLabel> placed = BandmapLayout.Place(
|
|
[At(14_080, "JA1XYZ"), At(14_010, "DL1ABC")],
|
|
Scale(),
|
|
LabelHeight);
|
|
|
|
Assert.Equal(["DL1ABC", "JA1XYZ"], placed.Select(l => l.Spot.Call.Text));
|
|
}
|
|
|
|
/// Two stations a hundred hertz apart would have their text on top of each
|
|
/// other, so the lower one moves down and its leader line does the work.
|
|
[Fact]
|
|
public void ALabelThatWouldCoverTheOneAboveIsPushedDown()
|
|
{
|
|
IReadOnlyList<BandmapLabel> placed = BandmapLayout.Place(
|
|
[At(14_050, "DL1ABC"), At(14_050.1, "JA1XYZ")],
|
|
Scale(),
|
|
LabelHeight);
|
|
|
|
Assert.Equal(45, placed[0].LabelY);
|
|
Assert.Equal(55.5, placed[1].LabelY);
|
|
// the leader still points at where the station really is
|
|
Assert.Equal(50.1, placed[1].MarkY, 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void ALabelWithRoomKeepsItsOwnPlace()
|
|
{
|
|
IReadOnlyList<BandmapLabel> placed = BandmapLayout.Place(
|
|
[At(14_010, "DL1ABC"), At(14_090, "JA1XYZ")],
|
|
Scale(),
|
|
LabelHeight);
|
|
|
|
Assert.Equal(5, placed[0].LabelY);
|
|
Assert.Equal(85, placed[1].LabelY);
|
|
}
|
|
|
|
[Fact]
|
|
public void AStationOutsideTheSliceIsNotDrawn() =>
|
|
Assert.Empty(BandmapLayout.Place([At(14_200)], Scale(), LabelHeight));
|
|
|
|
[Fact]
|
|
public void TheTicksStartAtTheFirstRoundFrequencyInTheSlice()
|
|
{
|
|
IReadOnlyList<Frequency> ticks = BandmapLayout.Ticks(
|
|
new BandmapScale(Frequency.FromKilohertz(14_003), Frequency.FromKilohertz(14_012), 100),
|
|
Frequency.FromKilohertz(5));
|
|
|
|
Assert.Equal([14_005_000, 14_010_000], ticks.Select(t => t.Hertz));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(60, 590, 5)]
|
|
[InlineData(75, 590, 10)]
|
|
[InlineData(100, 590, 10)]
|
|
[InlineData(150, 590, 20)]
|
|
public void TheTickStepKeepsThreeLinesBetweenTicks(int spanKilohertz, double height, int expectedKilohertz)
|
|
{
|
|
BandmapScale scale = new(
|
|
Frequency.FromKilohertz(14_000), Frequency.FromKilohertz(14_000 + spanKilohertz), height);
|
|
|
|
Assert.Equal(expectedKilohertz, BandmapLayout.StepFor(scale, 3 * 16).Kilohertz);
|
|
}
|
|
|
|
[Fact]
|
|
public void TheScaleTurnsPixelsBackIntoFrequencies() =>
|
|
Assert.Equal(14_050_000, Scale().At(50).Hertz);
|
|
|
|
[Fact]
|
|
public void ACwReceiverBarIsCentredOnTheCarrier()
|
|
{
|
|
VfoMarker vfo = VfoMarker.For(Frequency.FromKilohertz(14_025), Modes.Cw, VfoRole.Receive);
|
|
|
|
Assert.Equal((14_024_750, 14_025_250), (vfo.Low.Hertz, vfo.High.Hertz));
|
|
Assert.Equal(14_025_000, vfo.Carrier.Hertz);
|
|
}
|
|
|
|
[Fact]
|
|
public void AnUpperSidebandBarStartsAtTheCarrier()
|
|
{
|
|
VfoMarker vfo = VfoMarker.For(Frequency.FromKilohertz(14_200), Modes.Usb, VfoRole.Receive);
|
|
|
|
Assert.Equal((14_200_000, 14_202_700), (vfo.Low.Hertz, vfo.High.Hertz));
|
|
}
|
|
|
|
[Fact]
|
|
public void ALowerSidebandBarEndsAtTheCarrier()
|
|
{
|
|
VfoMarker vfo = VfoMarker.For(Frequency.FromKilohertz(7_100), Modes.Lsb, VfoRole.Receive);
|
|
|
|
Assert.Equal((7_097_300, 7_100_000), (vfo.Low.Hertz, vfo.High.Hertz));
|
|
}
|
|
}
|