mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-24 10:34:26 +08:00
Move whiteboard persistence to file storage
Switch whiteboard note storage from legacy DB rows to per-note JSON files and add migration support. Update WhiteboardNoteSnapshot schema (version bump, viewport, canvas, expires, PathSvgData) and change IWhiteboardNotePersistenceService.SaveNote to return bool to surface write failures (e.g. read-only files). Implement file-based WhiteboardNotePersistenceService with legacy DB migration/cleanup, retention handling, and logging. Add comprehensive unit tests for persistence, stroke path builder, SVG import and viewport helper. Also add ThirdParty/DotNetCampus.InkCanvas project and reference it in the main csproj, and bump PostHog package to 2.6.0.
This commit is contained in:
77
LanMountainDesktop.Tests/WhiteboardStrokePathBuilderTests.cs
Normal file
77
LanMountainDesktop.Tests/WhiteboardStrokePathBuilderTests.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using DotNetCampus.Inking.Primitive;
|
||||
using LanMountainDesktop.Views.Components;
|
||||
using Xunit;
|
||||
|
||||
namespace LanMountainDesktop.Tests;
|
||||
|
||||
public sealed class WhiteboardStrokePathBuilderTests
|
||||
{
|
||||
[Fact]
|
||||
public void BuildPath_WithEmptyPointList_ReturnsEmptyPath()
|
||||
{
|
||||
using var path = WhiteboardStrokePathBuilder.BuildPath(Array.Empty<InkStylusPoint>(), inkThickness: 3d);
|
||||
|
||||
Assert.True(path.IsEmpty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildPath_WithSinglePoint_CreatesVisibleStroke()
|
||||
{
|
||||
using var path = WhiteboardStrokePathBuilder.BuildPath(
|
||||
[CreatePoint(24, 32)],
|
||||
inkThickness: 6d);
|
||||
|
||||
Assert.False(path.IsEmpty);
|
||||
Assert.True(path.Bounds.Width >= 5.5f);
|
||||
Assert.True(path.Bounds.Height >= 5.5f);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildPath_WithMultiplePoints_CreatesFilledStroke()
|
||||
{
|
||||
using var path = WhiteboardStrokePathBuilder.BuildPath(
|
||||
[
|
||||
CreatePoint(10, 10),
|
||||
CreatePoint(30, 18),
|
||||
CreatePoint(52, 14)
|
||||
],
|
||||
inkThickness: 4d);
|
||||
|
||||
Assert.False(path.IsEmpty);
|
||||
Assert.True(path.Bounds.Width > 40f);
|
||||
Assert.True(path.Bounds.Height > 4f);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildPath_WithThickerStroke_ExpandsStrokeBounds()
|
||||
{
|
||||
var points = new[]
|
||||
{
|
||||
CreatePoint(10, 10),
|
||||
CreatePoint(80, 10)
|
||||
};
|
||||
|
||||
using var thinPath = WhiteboardStrokePathBuilder.BuildPath(points, inkThickness: 1d);
|
||||
using var thickPath = WhiteboardStrokePathBuilder.BuildPath(points, inkThickness: 8d);
|
||||
|
||||
Assert.True(thickPath.Bounds.Height > thinPath.Bounds.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildPath_WithNonFinitePoints_UsesRemainingFinitePoints()
|
||||
{
|
||||
using var path = WhiteboardStrokePathBuilder.BuildPath(
|
||||
[
|
||||
CreatePoint(double.NaN, 10),
|
||||
CreatePoint(20, 20)
|
||||
],
|
||||
inkThickness: 4d);
|
||||
|
||||
Assert.False(path.IsEmpty);
|
||||
}
|
||||
|
||||
private static InkStylusPoint CreatePoint(double x, double y)
|
||||
{
|
||||
return new InkStylusPoint(x, y, pressure: 1f);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user