using OpenNest.BestFit; using OpenNest.Engine; using OpenNest.Engine.BestFit; using OpenNest.Geometry; using OpenNest.Shapes; namespace OpenNest.Tests.BestFit; [Collection(nameof(FillCacheCollection))] public class BestFitCacheStoreTests { private const double Spacing = 0.25; private static Drawing MakeDrawing() => new TShape { Width = 10, Height = 8 }.GetDrawing(); private static BestFitResult MakeResult(Drawing drawing, bool keep, string reason = "Valid", List hullAngles = null) => new() { Candidate = new PairCandidate { Drawing = drawing, Part1Rotation = 0.5, Part2Rotation = System.Math.PI, Part2Offset = new Vector(3.25, -1.5), StrategyIndex = 2, TestNumber = 7, Spacing = Spacing, }, RotatedArea = 90, BoundingWidth = 12, BoundingHeight = 7.5, OptimalRotation = 0.1, Keep = keep, Reason = reason, TrueArea = 70, HullAngles = hullAngles, }; [Fact] public void Export_ReturnsOnlyRequestedPlateKeysAndKeptResults() { BestFitCache.Clear(); var drawing = MakeDrawing(); BestFitCache.Populate(drawing, 60, 40, Spacing, new() { MakeResult(drawing, keep: true, hullAngles: new() { 0.25 }), MakeResult(drawing, keep: false, reason: "Too wide"), }); BestFitCache.Populate(drawing, 14, 30, Spacing, new() { MakeResult(drawing, keep: true) }); var sets = BestFitCacheStore.Shared.Export( drawing, new HashSet<(double, double, double)> { (60, 40, Spacing), (99, 99, Spacing) }); var set = Assert.Single(sets); Assert.Equal((60.0, 40.0, Spacing), (set.PlateWidth, set.PlateHeight, set.Spacing)); var result = Assert.Single(set.Results); Assert.Equal( new SavedPairResult(0.5, System.Math.PI, 3.25, -1.5, 2, 7, Spacing, 90, 12, 7.5, 0.1, true, "Valid", 70, result.HullAngles), result); Assert.Equal(new[] { 0.25 }, result.HullAngles); } [Fact] public void Export_DrawingWithoutCacheEntry_ReturnsNoSets() { BestFitCache.Clear(); var sets = BestFitCacheStore.Shared.Export( MakeDrawing(), new HashSet<(double, double, double)> { (60, 40, Spacing) }); Assert.Empty(sets); } [Fact] public void Import_PopulatesCacheWithCandidatesOnACanonicalCopyOfTheDrawing() { BestFitCache.Clear(); var drawing = MakeDrawing(); var saved = new SavedPairResult(0.5, System.Math.PI, 3.25, -1.5, 2, 7, Spacing, 90, 12, 7.5, 0.1, true, "Valid", 70, new[] { 0.25, -0.5 }); BestFitCacheStore.Shared.Import(drawing, new[] { new SavedPairSet(60, 40, Spacing, new[] { saved }) }); var restored = Assert.Single(BestFitCache.GetAllForDrawing(drawing)); Assert.Equal((60.0, 40.0, Spacing), restored.Key); var result = Assert.Single(restored.Value); Assert.NotSame(drawing, result.Candidate.Drawing); Assert.Same(drawing, CanonicalFrame.SourceOf(result.Candidate.Drawing)); Assert.Equal(0.0, result.Candidate.Drawing.Source.Angle); Assert.Equal(0.5, result.Candidate.Part1Rotation); Assert.Equal(System.Math.PI, result.Candidate.Part2Rotation); Assert.Equal(new Vector(3.25, -1.5), result.Candidate.Part2Offset); Assert.Equal(2, result.Candidate.StrategyIndex); Assert.Equal(7, result.Candidate.TestNumber); Assert.Equal(Spacing, result.Candidate.Spacing); Assert.Equal(90, result.RotatedArea); Assert.Equal(12, result.BoundingWidth); Assert.Equal(7.5, result.BoundingHeight); Assert.Equal(0.1, result.OptimalRotation); Assert.True(result.Keep); Assert.Equal("Valid", result.Reason); Assert.Equal(70, result.TrueArea); Assert.Equal(new[] { 0.25, -0.5 }, result.HullAngles); } [Fact] public void Import_ExistingSetForTheSameKey_IsKept() { BestFitCache.Clear(); var drawing = MakeDrawing(); var existing = new List { MakeResult(drawing, keep: true) }; BestFitCache.Populate(drawing, 60, 40, Spacing, existing); var saved = new SavedPairResult(0, 0, 1, 1, 0, 1, Spacing, 5, 1, 5, 0, true, "Valid", 4, new double[0]); BestFitCacheStore.Shared.Import(drawing, new[] { new SavedPairSet(60, 40, Spacing, new[] { saved }) }); Assert.Same(existing, BestFitCache.GetAllForDrawing(drawing)[(60, 40, Spacing)]); } [Fact] public void Import_EmptySet_AddsNothing() { BestFitCache.Clear(); var drawing = MakeDrawing(); BestFitCacheStore.Shared.Import(drawing, new[] { new SavedPairSet(60, 40, Spacing, new SavedPairResult[0]) }); Assert.Empty(BestFitCache.GetAllForDrawing(drawing)); } }