102 lines
3.6 KiB
C#
102 lines
3.6 KiB
C#
|
|
using SSPCTester.Devices.Interfaces;
|
||
|
|
using SSPCTester.Logic.Models;
|
||
|
|
using SSPCTester.Logic.Report;
|
||
|
|
using SSPCTester.Logic.Storage;
|
||
|
|
|
||
|
|
namespace SSPCTester.Tests;
|
||
|
|
|
||
|
|
public sealed class WaveformStoreTests
|
||
|
|
{
|
||
|
|
[Fact]
|
||
|
|
public async Task SaveThenLoad_RestoresCurveDataAndChannels()
|
||
|
|
{
|
||
|
|
string folder = Path.Combine(Path.GetTempPath(), "SSPCTester-waveform-" + Guid.NewGuid().ToString("N"));
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var project = new Project { FolderPath = folder };
|
||
|
|
var curve = new CurveData
|
||
|
|
{
|
||
|
|
SampleRateHz = 100_000,
|
||
|
|
TriggerSampleIndex = 2,
|
||
|
|
TriggerTimeSec = 0.00002,
|
||
|
|
Voltage = new[] { 0.0, 3.5, 10.0, 22.0 },
|
||
|
|
Current = new[] { 0.0, 0.1, 0.4, 0.8 },
|
||
|
|
EngineeringChannels = new[]
|
||
|
|
{
|
||
|
|
new CurveChannelData(0, DaqChannelRole.OutputVoltage, "Vout", "V", 2, 0, new[] { 0.0, 3.5, 10.0, 22.0 }),
|
||
|
|
new CurveChannelData(1, DaqChannelRole.OutputCurrent, "Iout", "A", 1, 0, new[] { 0.0, 0.1, 0.4, 0.8 })
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
string? path = await WaveformStore.SaveAsync(project, 1, "on", curve);
|
||
|
|
var loaded = await WaveformStore.LoadAsync(project, path);
|
||
|
|
|
||
|
|
Assert.NotNull(path);
|
||
|
|
Assert.NotNull(loaded);
|
||
|
|
Assert.Equal(curve.SampleRateHz, loaded.SampleRateHz);
|
||
|
|
Assert.Equal(curve.TriggerSampleIndex, loaded.TriggerSampleIndex);
|
||
|
|
Assert.Equal(curve.TriggerTimeSec, loaded.TriggerTimeSec, 8);
|
||
|
|
Assert.Equal(curve.Voltage, loaded.Voltage, new ApproximateDoubleComparer());
|
||
|
|
Assert.Equal(curve.Current!, loaded.Current!, new ApproximateDoubleComparer());
|
||
|
|
Assert.Contains(loaded.EngineeringChannels, x => x.Role == DaqChannelRole.OutputVoltage);
|
||
|
|
Assert.Contains(loaded.EngineeringChannels, x => x.Role == DaqChannelRole.OutputCurrent);
|
||
|
|
}
|
||
|
|
finally
|
||
|
|
{
|
||
|
|
if (Directory.Exists(folder)) Directory.Delete(folder, true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task Load_ReturnsNull_WhenPathIsMissing()
|
||
|
|
{
|
||
|
|
var project = new Project { FolderPath = Path.GetTempPath() };
|
||
|
|
|
||
|
|
var loaded = await WaveformStore.LoadAsync(project, "curves/missing.json");
|
||
|
|
|
||
|
|
Assert.Null(loaded);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public void CurveImageRenderer_RendersPngFromLoadedCurves()
|
||
|
|
{
|
||
|
|
var rising = MakeCurve(true);
|
||
|
|
var falling = MakeCurve(false);
|
||
|
|
|
||
|
|
byte[] png = CurveImageRenderer.RenderChannel(3, rising, falling);
|
||
|
|
|
||
|
|
Assert.True(png.Length > 1_000);
|
||
|
|
Assert.Equal(new byte[] { 0x89, 0x50, 0x4E, 0x47 }, png[..4]);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static CurveData MakeCurve(bool rising)
|
||
|
|
{
|
||
|
|
const int sampleRate = 100_000;
|
||
|
|
const int count = 200;
|
||
|
|
var voltage = new double[count];
|
||
|
|
for (int i = 0; i < count; i++)
|
||
|
|
{
|
||
|
|
double ratio = i / (double)(count - 1);
|
||
|
|
voltage[i] = rising ? 28 * ratio : 28 * (1 - ratio);
|
||
|
|
}
|
||
|
|
|
||
|
|
return new CurveData
|
||
|
|
{
|
||
|
|
SampleRateHz = sampleRate,
|
||
|
|
TriggerSampleIndex = 50,
|
||
|
|
TriggerTimeSec = 50.0 / sampleRate,
|
||
|
|
Voltage = voltage,
|
||
|
|
EngineeringChannels = new[]
|
||
|
|
{
|
||
|
|
new CurveChannelData(0, DaqChannelRole.OutputVoltage, "Vout", "V", 1, 0, voltage)
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
private sealed class ApproximateDoubleComparer : IEqualityComparer<double>
|
||
|
|
{
|
||
|
|
public bool Equals(double x, double y) => Math.Abs(x - y) < 1e-6;
|
||
|
|
public int GetHashCode(double obj) => 0;
|
||
|
|
}
|
||
|
|
}
|