Check the signal report before it goes in the log
The log window took any text in the two report columns. It now checks the report the same way it checks the zone or the section: RST on most modes, and a signal-to-noise ratio in decibels on FT8, FT4, JT65, Q65 and MSK144. A WAE QTC row is skipped, because it keeps the time sent and the other station's call in those two columns. The grid column is checked on every contest now, not only when the contest asks for a locator, and the value is stored as JN88dd. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015NZkFxHde1iifAQemFTHxf
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
namespace Nonemm.Core.Tests;
|
||||
|
||||
public class SignalReportTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("599")]
|
||||
[InlineData("59")]
|
||||
[InlineData("339")]
|
||||
[InlineData("111")]
|
||||
public void AnRstReportIsTaken(string report) =>
|
||||
Assert.True(SignalReport.IsPlausible(report, Modes.Cw));
|
||||
|
||||
[Theory]
|
||||
[InlineData("nice signal")]
|
||||
[InlineData("5")]
|
||||
[InlineData("5999")]
|
||||
[InlineData("699")]
|
||||
[InlineData("509")]
|
||||
[InlineData("590")]
|
||||
[InlineData("5N9")]
|
||||
public void TextThatIsNotAnRstReportIsRefused(string report) =>
|
||||
Assert.False(SignalReport.IsPlausible(report, Modes.Cw));
|
||||
|
||||
/// FT8 and the other weak-signal modes exchange a signal-to-noise ratio.
|
||||
[Theory]
|
||||
[InlineData("-12", true)]
|
||||
[InlineData("+03", true)]
|
||||
[InlineData("0", true)]
|
||||
[InlineData("599", false)]
|
||||
[InlineData("-99", false)]
|
||||
public void AWeakSignalModeReportsDecibels(string report, bool taken) =>
|
||||
Assert.Equal(taken, SignalReport.IsPlausible(report, Modes.Ft8));
|
||||
|
||||
[Fact]
|
||||
public void RttyStillReportsRst() =>
|
||||
Assert.True(SignalReport.IsPlausible("599", Modes.Rtty));
|
||||
|
||||
[Fact]
|
||||
public void ThePhoneExampleHasNoTone() =>
|
||||
Assert.Equal("59", SignalReport.Example(Modes.Usb));
|
||||
}
|
||||
@@ -208,6 +208,57 @@ public class QsoEditorTests
|
||||
public void TheWorkingFrequencyCannotBeCleared() =>
|
||||
Assert.False(CqWw().Apply(Contact(), QsoField.Frequency, "").IsAccepted);
|
||||
|
||||
[Fact]
|
||||
public void ArbitraryTextInTheReportColumnIsRefused()
|
||||
{
|
||||
QsoEdit edit = CqWw().Apply(Contact(), QsoField.ReceivedReport, "good copy");
|
||||
|
||||
Assert.False(edit.IsAccepted);
|
||||
Assert.Contains("signal report", edit.Error);
|
||||
Assert.Equal(QsoField.ReceivedReport, edit.Field);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TheSentReportIsCheckedTheSameWay() =>
|
||||
Assert.False(CqWw().Apply(Contact(), QsoField.SentReport, "699").IsAccepted);
|
||||
|
||||
[Fact]
|
||||
public void AReportCanStillBeCorrected() =>
|
||||
Assert.Equal("339", CqWw().Apply(Contact(), QsoField.ReceivedReport, "339").Result!.ReceivedReport);
|
||||
|
||||
/// FT8 exchanges a signal-to-noise ratio, so RST is the wrong thing there
|
||||
/// and decibels are the wrong thing on CW.
|
||||
[Fact]
|
||||
public void AWeakSignalContactReportsDecibels()
|
||||
{
|
||||
Qso ft8 = Contact() with { Mode = Modes.Ft8, ReceivedReport = "-12" };
|
||||
|
||||
Assert.True(CqWw().Apply(ft8, QsoField.ReceivedReport, "-07").IsAccepted);
|
||||
Assert.False(CqWw().Apply(ft8, QsoField.ReceivedReport, "599").IsAccepted);
|
||||
Assert.False(CqWw().Apply(Contact(), QsoField.ReceivedReport, "-07").IsAccepted);
|
||||
}
|
||||
|
||||
/// A WAE QTC row keeps the time sent and the other station's call in the
|
||||
/// two report columns, so those are not reports to check.
|
||||
[Fact]
|
||||
public void TheReportColumnsOfAQtcRowAreLeftAlone()
|
||||
{
|
||||
QsoEditor editor = new(new Wae(ModeCategory.Cw), Me, CountryFile.Parse(Countries));
|
||||
Qso traffic = Contact() with { ContestName = "WAEDC", Exchange1 = "SQTC", MiscText = "3/10" };
|
||||
|
||||
Assert.True(editor.Apply(traffic, QsoField.SentReport, "1234").IsAccepted);
|
||||
Assert.True(editor.Apply(traffic, QsoField.ReceivedReport, "DL1ABC").IsAccepted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TextThatIsNotALocatorIsRefused() =>
|
||||
Assert.False(CqWw().Apply(Contact(), QsoField.GridSquare, "nowhere").IsAccepted);
|
||||
|
||||
/// A locator is stored the way it is written, whatever case it was typed in.
|
||||
[Fact]
|
||||
public void ALocatorIsStoredWithALowerCaseSubsquare() =>
|
||||
Assert.Equal("JN88dd", CqWw().Apply(Contact(), QsoField.GridSquare, "jn88dd").Result!.GridSquare);
|
||||
|
||||
[Fact]
|
||||
public void ACorrectedCountryPrefixIsKept() =>
|
||||
Assert.Equal("DL", CqWw().Apply(Contact(), QsoField.CountryPrefix, "dl").Result!.CountryPrefix);
|
||||
|
||||
Reference in New Issue
Block a user