Copy All takes whichever tab is open, as N1MM's does: the table off the table tab, a picture of the graph off the graph tab. Copy Table as Text and Copy Graph as Image do either one from either tab. `StatisticsTable` lays the pivot out as the window prints it — the headings, the rows, the Total line — and pads it into columns for the text form, so the grid, the clipboard and Print to File all say the same thing. X11 asks for a picture when the other program pastes rather than when it is copied, so the bitmap given to the clipboard is held until the clipboard is given a different one. Disposing it at the end of the copy killed the program on the next paste; the table pasted into a second Avalonia program reads back lined up, and the picture reads back as a 916x438 bitmap. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PdAYHcdRktqKry7nk414TU
79 lines
2.5 KiB
C#
79 lines
2.5 KiB
C#
using Nonemm.Core;
|
|
|
|
namespace Nonemm.Session.Tests;
|
|
|
|
public class StatisticsTableTests
|
|
{
|
|
private static readonly DateTime Start = new(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
|
|
private static Qso Contact(double kilohertz, Mode? mode = null, int minute = 0) => new()
|
|
{
|
|
Id = Qso.NewId(),
|
|
TimestampUtc = Start.AddMinutes(minute),
|
|
Call = Callsign.Parse("DL1ABC"),
|
|
Frequency = Frequency.FromKilohertz(kilohertz),
|
|
Mode = mode ?? Modes.Cw,
|
|
ContestName = "CQWW",
|
|
};
|
|
|
|
private static StatisticsTable Of(IReadOnlyList<Qso> log, string row = "Band", string column = "Mode") =>
|
|
StatisticsTable.Of(StatisticsPivot.Of(
|
|
log,
|
|
StatisticsFields.Find(StatisticsFields.Rows, row),
|
|
StatisticsFields.Find(StatisticsFields.Columns, column),
|
|
Start));
|
|
|
|
[Fact]
|
|
public void HeadsTheCountsWithTheColumnValuesAndEndsWithTotAndAccum()
|
|
{
|
|
StatisticsTable table = Of([Contact(14_030), Contact(7_030, Modes.Usb)]);
|
|
|
|
Assert.Equal(["Band", "CW", "USB", "Tot", "Accum"], table.Headings);
|
|
Assert.Equal(1, table.LabelColumns);
|
|
}
|
|
|
|
[Fact]
|
|
public void PutsTheTotalLineLast()
|
|
{
|
|
StatisticsTable table = Of([Contact(14_030), Contact(14_040), Contact(7_030)]);
|
|
|
|
Assert.Equal(["40M", "1", "1", "1"], table.Rows[0]);
|
|
Assert.Equal(["20M", "2", "2", "3"], table.Rows[1]);
|
|
Assert.Equal(["Total", "3", "3", "3"], table.Rows[^1]);
|
|
}
|
|
|
|
[Fact]
|
|
public void LinesTheColumnsUpUnderTheirHeadings()
|
|
{
|
|
string text = Of([Contact(14_030), Contact(3_530, Modes.Usb), Contact(3_540, Modes.Usb)]).ToText();
|
|
|
|
Assert.Equal(
|
|
"""
|
|
Band CW USB Tot Accum
|
|
80M 2 2 2
|
|
20M 1 1 3
|
|
Total 1 2 3 3
|
|
""",
|
|
text.TrimEnd('\n'));
|
|
}
|
|
|
|
[Fact]
|
|
public void KeepsTheTwoLabelColumnsOfAFieldThatHasThem()
|
|
{
|
|
StatisticsTable table = Of([Contact(14_030, minute: 5), Contact(14_040, minute: 70)], row: "Hour");
|
|
|
|
Assert.Equal(2, table.LabelColumns);
|
|
Assert.Equal(["Day", "Hr", "CW", "Tot", "Accum"], table.Headings);
|
|
Assert.Equal(["2026-01-01", "00", "1", "1", "1"], table.Rows[0]);
|
|
Assert.Equal(["Total", "", "2", "2", "2"], table.Rows[^1]);
|
|
}
|
|
|
|
[Fact]
|
|
public void LeavesNoSpacesHangingOffTheEndOfALine()
|
|
{
|
|
string text = Of([Contact(14_030)]).ToText();
|
|
|
|
Assert.All(text.Split('\n'), line => Assert.Equal(line.TrimEnd(), line));
|
|
}
|
|
}
|