Say when the entry has two signals on the air
N1MM blocks the transmitter when a multi-operator entry is about to break its own class. This program does not touch the transmitter: a logger that decides for itself when the operator may not send loses a contact every time it is wrong, and it is wrong whenever it has stale information about the other stations — which, on a network, is whenever a laptop has just been unplugged. So the entry window says so instead. While this station is transmitting and the entry is over what it is allowed, a red box goes across the top of the window naming the station and the band. It is above the frequency and under the menu, so nothing it covers is anything the operator needs while he is sending, and it is big enough to read from the other side of the room. `TransmitRules` is what it asks: | Entry | Allowed | |---|---| | one transmitter | one signal | | two transmitters | two signals, on different bands | | anything else | one signal per band | Two on one band is wrong in every multi-operator class, so it is checked whatever the category says. A station that has not said which band it is on counts as somewhere else: a guess there puts the box in front of an operator doing nothing wrong. This is also the first thing that sends `XMIT`. The message was written and nothing called it, so the transmit column of everybody's network status window stayed empty and no station knew when another was sending. The entry window now says when its key goes down and what it is sending. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PdAYHcdRktqKry7nk414TU
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
using Nonemm.Core;
|
||||
|
||||
namespace Nonemm.Contests.Tests;
|
||||
|
||||
/// How many signals a multi-operator entry may have on the air, and what the
|
||||
/// entry window says when there is one too many.
|
||||
public class TransmitRulesTests
|
||||
{
|
||||
private static readonly ContestEntry MultiOne = new()
|
||||
{
|
||||
OperatorCategory = "MULTI-ONE",
|
||||
TransmitterCategory = "ONE",
|
||||
};
|
||||
|
||||
private static readonly ContestEntry MultiTwo = new()
|
||||
{
|
||||
OperatorCategory = "MULTI-TWO",
|
||||
TransmitterCategory = "TWO",
|
||||
};
|
||||
|
||||
private static readonly ContestEntry Unlimited = new()
|
||||
{
|
||||
OperatorCategory = "MULTI-UNLIMITED",
|
||||
TransmitterCategory = "UNLIMITED",
|
||||
};
|
||||
|
||||
private static Transmitter On(string name, Band band, ModeCategory mode = ModeCategory.Cw) =>
|
||||
new(name, band, mode);
|
||||
|
||||
[Fact]
|
||||
public void OneSignalIsAlwaysAllowed() =>
|
||||
Assert.Null(TransmitRules.Violation(MultiOne, On("RUN-PC", Bands.Band20M), []));
|
||||
|
||||
/// Two signals on one band and mode is wrong in every class.
|
||||
[Fact]
|
||||
public void TwoStationsOnOneBandAndModeIsNamed()
|
||||
{
|
||||
string? why = TransmitRules.Violation(
|
||||
Unlimited,
|
||||
On("RUN-PC", Bands.Band20M),
|
||||
[On("MULT-PC", Bands.Band20M)]);
|
||||
|
||||
Assert.Equal("MULT-PC is transmitting on 20M CW as well", why);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TwoStationsOnOneBandInDifferentModesIsNamed()
|
||||
{
|
||||
string? why = TransmitRules.Violation(
|
||||
Unlimited,
|
||||
On("RUN-PC", Bands.Band20M),
|
||||
[On("MULT-PC", Bands.Band20M, ModeCategory.Phone)]);
|
||||
|
||||
Assert.Equal("MULT-PC is transmitting on 20M as well", why);
|
||||
}
|
||||
|
||||
/// A one-transmitter entry may have one signal, wherever the other station
|
||||
/// is.
|
||||
[Fact]
|
||||
public void ASecondSignalBreaksAOneTransmitterEntry()
|
||||
{
|
||||
string? why = TransmitRules.Violation(
|
||||
MultiOne,
|
||||
On("RUN-PC", Bands.Band20M),
|
||||
[On("MULT-PC", Bands.Band40M)]);
|
||||
|
||||
Assert.NotNull(why);
|
||||
Assert.Contains("one-transmitter entry", why);
|
||||
Assert.Contains("20M CW", why);
|
||||
Assert.Contains("40M CW", why);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TwoSignalsOnDifferentBandsAreFineForTwoTransmitters() =>
|
||||
Assert.Null(TransmitRules.Violation(
|
||||
MultiTwo,
|
||||
On("RUN-PC", Bands.Band20M),
|
||||
[On("MULT-PC", Bands.Band40M)]));
|
||||
|
||||
[Fact]
|
||||
public void AThirdSignalBreaksATwoTransmitterEntry()
|
||||
{
|
||||
string? why = TransmitRules.Violation(
|
||||
MultiTwo,
|
||||
On("RUN-PC", Bands.Band20M),
|
||||
[On("MULT-PC", Bands.Band40M), On("MULT2-PC", Bands.Band15M)]);
|
||||
|
||||
Assert.NotNull(why);
|
||||
Assert.Contains("two-transmitter entry", why);
|
||||
}
|
||||
|
||||
/// A class that does not cap the transmitters is held to the one rule that
|
||||
/// applies to everybody.
|
||||
[Fact]
|
||||
public void AnUnlimitedEntryMayHaveASignalPerBand() =>
|
||||
Assert.Null(TransmitRules.Violation(
|
||||
Unlimited,
|
||||
On("RUN-PC", Bands.Band20M),
|
||||
[On("MULT-PC", Bands.Band40M), On("MULT2-PC", Bands.Band15M)]));
|
||||
|
||||
/// A station that has not said where it is counts as somewhere else. A
|
||||
/// guess here puts a red box in front of an operator doing nothing wrong.
|
||||
[Fact]
|
||||
public void AStationWithNoBandIsNotCountedAsOnThisOne() =>
|
||||
Assert.Null(TransmitRules.Violation(
|
||||
Unlimited,
|
||||
On("RUN-PC", Bands.Band20M),
|
||||
[new Transmitter("MULT-PC", null, null)]));
|
||||
|
||||
/// A single operator with two radios is nobody's multi-operator entry, but
|
||||
/// two signals on one band is still two signals on one band.
|
||||
[Fact]
|
||||
public void ASingleOperatorIsOnlyHeldToTheOneBandRule()
|
||||
{
|
||||
ContestEntry single = new() { OperatorCategory = "SINGLE-OP", TransmitterCategory = "ONE" };
|
||||
|
||||
Assert.Null(TransmitRules.Violation(single, On("RUN-PC", Bands.Band20M), [On("SO2R-PC", Bands.Band40M)]));
|
||||
Assert.NotNull(TransmitRules.Violation(single, On("RUN-PC", Bands.Band20M), [On("SO2R-PC", Bands.Band20M)]));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user