Add CW keying, function key messages and the documentation

The function keys send through cwdaemon or a WinKeyer, with N1MM's message
macros. Escape stops sending.

Settings are read with the reflection serializer rather than a generated one:
the generated one hands back null for every property the file leaves out
instead of the value the property is declared with, which crashed the program
the first time a new setting was added.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Erik
2026-08-27 11:23:30 +00:00
parent d96cbe146b
commit f5aa77ece3
25 changed files with 1002 additions and 26 deletions

View File

@@ -0,0 +1,59 @@
using Nonemm.Core;
namespace Nonemm.Network.Tests;
public class ContactMessageTests
{
private static Qso Contact() => new()
{
Id = "0123456789abcdef0123456789abcdef",
TimestampUtc = new DateTime(2026, 5, 30, 12, 34, 56, DateTimeKind.Utc),
Call = Callsign.Parse("JA1XYZ"),
Frequency = Frequency.FromKilohertz(14_025.5),
Mode = Modes.Cw,
ContestName = "CQWW",
ContestNumber = 3,
SentReport = "599",
ReceivedReport = "579",
Zone = 25,
Points = 3,
IsMultiplier1 = true,
CountryPrefix = "JA",
Continent = "AS",
WpxPrefix = "JA1",
IsRunQso = true,
};
[Fact]
public void ContactSurvivesTheRoundTrip()
{
Qso? read = ContactMessage.Read(ContactMessage.Write(Contact(), "DL1ABC", "PC1"));
Assert.NotNull(read);
Assert.Equal("0123456789abcdef0123456789abcdef", read.Id);
Assert.Equal("JA1XYZ", read.Call.Text);
Assert.Equal(14_025_500, read.Frequency.Hertz);
Assert.Equal(new DateTime(2026, 5, 30, 12, 34, 56, DateTimeKind.Utc), read.TimestampUtc);
Assert.Equal(25, read.Zone);
Assert.Equal("JA", read.CountryPrefix);
Assert.True(read.IsRunQso);
Assert.Equal("PC1", read.StationName);
}
/// A contact that arrived over the network was made somewhere else, whatever
/// the sender put in the field.
[Fact]
public void AContactFromTheNetworkIsNotOriginal() =>
Assert.False(ContactMessage.Read(ContactMessage.Write(Contact(), "DL1ABC", "PC1"))!.IsOriginal);
[Fact]
public void FrequenciesAreSentInUnitsOfTenHertz() =>
Assert.Contains("<rxfreq>1402550</rxfreq>", ContactMessage.Write(Contact(), "DL1ABC", "PC1"));
[Theory]
[InlineData("<radioinfo><app>N1MM</app></radioinfo>")]
[InlineData("not xml at all")]
[InlineData("<contactinfo><call></call></contactinfo>")]
public void AnythingThatIsNotAContactIsPassedOver(string message) =>
Assert.Null(ContactMessage.Read(message));
}