diff --git a/src/Aardvark.Rendering.sln b/src/Aardvark.Rendering.sln index 671237317..85ae42b76 100644 --- a/src/Aardvark.Rendering.sln +++ b/src/Aardvark.Rendering.sln @@ -227,13 +227,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\global.json = ..\global.json ..\paket.dependencies = ..\paket.dependencies ..\paket.lock = ..\paket.lock + ..\.github\workflows\publish.yml = ..\.github\workflows\publish.yml ..\README.md = ..\README.md ..\RELEASE_NOTES.md = ..\RELEASE_NOTES.md - ..\.github\workflows\publish.yml = ..\.github\workflows\publish.yml EndProjectSection EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Aardvark.Rendering.Text.Tests", "Tests\Aardvark.Rendering.Text.Tests\Aardvark.Rendering.Text.Tests.fsproj", "{EDDBAF72-43C6-48BB-91FB-A639AA299293}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -624,10 +622,6 @@ Global {DD9808AD-AEB3-4E90-A70C-E398CADE55FF}.Debug|Any CPU.Build.0 = Debug|Any CPU {DD9808AD-AEB3-4E90-A70C-E398CADE55FF}.Release|Any CPU.ActiveCfg = Release|Any CPU {DD9808AD-AEB3-4E90-A70C-E398CADE55FF}.Release|Any CPU.Build.0 = Release|Any CPU - {EDDBAF72-43C6-48BB-91FB-A639AA299293}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EDDBAF72-43C6-48BB-91FB-A639AA299293}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EDDBAF72-43C6-48BB-91FB-A639AA299293}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EDDBAF72-43C6-48BB-91FB-A639AA299293}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -719,7 +713,6 @@ Global {159213C5-ECA5-48B6-BDCF-D75BAE733E80} = {5E3312C4-1B3C-4D41-964C-C3A3E01DA966} {6DFA9CC5-3C57-44FC-A989-F1DC5097C2DB} = {29CA9CA1-CC31-4B5D-8DB0-2FEA748C09D8} {DD9808AD-AEB3-4E90-A70C-E398CADE55FF} = {29CA9CA1-CC31-4B5D-8DB0-2FEA748C09D8} - {EDDBAF72-43C6-48BB-91FB-A639AA299293} = {80F74456-D82F-4D38-83FE-362EFD0C2FCB} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C41172B9-09C3-4327-8CE2-CB47CBAA29AC} diff --git a/src/Tests/Aardvark.Rendering.Tests/Aardvark.Rendering.Tests.fsproj b/src/Tests/Aardvark.Rendering.Tests/Aardvark.Rendering.Tests.fsproj index 8a4af38d4..82b66c020 100644 --- a/src/Tests/Aardvark.Rendering.Tests/Aardvark.Rendering.Tests.fsproj +++ b/src/Tests/Aardvark.Rendering.Tests/Aardvark.Rendering.Tests.fsproj @@ -78,6 +78,7 @@ + diff --git a/src/Tests/Aardvark.Rendering.Tests/Tests/Other/PathSegmentTests.fs b/src/Tests/Aardvark.Rendering.Tests/Tests/Other/PathSegmentTests.fs new file mode 100644 index 000000000..9a27b2cf8 --- /dev/null +++ b/src/Tests/Aardvark.Rendering.Tests/Tests/Other/PathSegmentTests.fs @@ -0,0 +1,255 @@ +namespace Aardvark.Rendering.Tests + +open Expecto +open Aardvark.Base +open Aardvark.Rendering.Text +open FsCheck + +open ExpectoOverrides + +module ``PathSegment Tests`` = + + [] + let smartConstructors = + testList "Text.PathSegment" [ + testProperty "tryLine degenerate" <| fun (p1 : V2d) -> + let line = PathSegment.tryLine p1 p1 + Expect.isNone line "impossible to create degenerate line" + + testProperty "tryBezier2 line" <| fun (p0 : V2d) (p2 : V2d) (ZeroOne t) -> + let p1 = lerp p0 p2 t + match PathSegment.tryBezier2 p0 p1 p2 with + | Some (Line(a,b)) -> + Expect.equal a p0 "line start" + Expect.equal b p2 "line end" + | None -> + Expect.equal p0 p2 "degenerate bezier2" + | Some other -> + failwithf "degenerate bezier2 should be a line but is: %A" other + + testProperty "tryBezier2 degenerate" <| fun (p0 : V2d) -> + let bezier2 = PathSegment.tryBezier2 p0 p0 p0 + Expect.isNone bezier2 "impossible to create degenerate bezier2" + + testProperty "tryArcSegment line" <| fun (p0 : V2d) (p2 : V2d) (ZeroOne t) -> + let p1 = lerp p0 p2 t + match PathSegment.tryArcSegment p0 p1 p2 with + | Some (Line(a,b)) -> + Expect.equal a p0 "line start" + Expect.equal b p2 "line end" + | None -> + Expect.equal p0 p2 "degenerate arc" + | Some other -> + failwithf "degenerate arc should be a line but is: %A" other + + testProperty "tryArcSegment degenerate" <| fun (p0 : V2d) -> + let arc = PathSegment.tryArcSegment p0 p0 p0 + Expect.isNone arc "impossible to create degenerate arc" + + testProperty "tryBezier3 with bezier2 points" <| fun (p0 : V2d) (p1 : V2d) (p2 : V2d) -> + let a = lerp p0 p1 (2.0 / 3.0) + let b = lerp p1 p2 (1.0 / 3.0) + + match PathSegment.tryBezier3 p0 a b p2 with + | Some (Line(a, b)) -> + Expect.equal a p0 "start" + Expect.equal b p2 "end" + | None -> + Expect.equal p0 p1 "degenerate bezier3" + Expect.equal p0 p2 "degenerate bezier3" + | Some (Bezier2(a,b,c)) -> + Expect.equal a p0 "start" + Expect.approxEquals b p1 1E-13 "control" + Expect.equal c p2 "end" + | Some other -> + failwithf "degenerate bezier3 should be a bezier2 but is: %A" other + + testProperty "tryBezier3 with line points" <| fun (p0 : V2d) (p3 : V2d) (ZeroOne t1) (ZeroOne t2) -> + + let p1 = lerp p0 p3 (min t1 t2) + let p2 = lerp p0 p3 (max t1 t2) + + match PathSegment.tryBezier3 p0 p1 p2 p3 with + | Some (Line(a, b)) -> + Expect.equal a p0 "start" + Expect.equal b p3 "end" + | None -> + Expect.approxEquals p0 p1 1E-14 "degenerate bezier3" + | Some other -> + failwithf "degenerate bezier3 should be a line but is: %A" other + + testProperty "tryBezier3 degenerate" <| fun (p0 : V2d) -> + let arc = PathSegment.tryBezier3 p0 p0 p0 p0 + Expect.isNone arc "impossible to create degenerate arc" + + testProperty "line degenerate" <| fun (p1 : V2d) -> + let line = try Some (PathSegment.line p1 p1) with _ -> None + Expect.isNone line "impossible to create degenerate line" + + testProperty "bezier2 line" <| fun (p0 : V2d) (p2 : V2d) (ZeroOne t) -> + let p1 = lerp p0 p2 t + + let segment = try Some (PathSegment.bezier2 p0 p1 p2) with _ -> None + + match segment with + | Some (Line(a,b)) -> + Expect.equal a p0 "line start" + Expect.equal b p2 "line end" + | None -> + Expect.equal p0 p2 "degenerate bezier2" + | Some other -> + failwithf "degenerate bezier2 should be a line but is: %A" other + + testProperty "bezier2 degenerate" <| fun (p0 : V2d) -> + let bezier2 = try Some (PathSegment.bezier2 p0 p0 p0) with _ -> None + Expect.isNone bezier2 "impossible to create degenerate bezier2" + + testProperty "arcSegment line" <| fun (p0 : V2d) (p2 : V2d) (ZeroOne t) -> + let p1 = lerp p0 p2 t + let segment = try Some (PathSegment.arcSegment p0 p1 p2) with _ -> None + match segment with + | Some (Line(a,b)) -> + Expect.equal a p0 "line start" + Expect.equal b p2 "line end" + | None -> + Expect.equal p0 p2 "degenerate arc" + | Some other -> + failwithf "degenerate arc should be a line but is: %A" other + + testProperty "arcSegment degenerate" <| fun (p0 : V2d) -> + let arc = try Some (PathSegment.arcSegment p0 p0 p0) with _ -> None + Expect.isNone arc "impossible to create degenerate arc" + + testProperty "bezier3 with bezier2 points" <| fun (p0 : V2d) (p1 : V2d) (p2 : V2d) -> + let a = lerp p0 p1 (2.0 / 3.0) + let b = lerp p1 p2 (1.0 / 3.0) + + let segment = try Some (PathSegment.bezier3 p0 a b p2) with _ -> None + match segment with + | Some (Line(a, b)) -> + Expect.equal a p0 "start" + Expect.equal b p2 "end" + | None -> + Expect.equal p0 p1 "degenerate bezier3" + Expect.equal p0 p2 "degenerate bezier3" + | Some (Bezier2(a,b,c)) -> + Expect.equal a p0 "start" + Expect.approxEquals b p1 1E-13 "control" + Expect.equal c p2 "end" + | Some other -> + failwithf "degenerate bezier3 should be a bezier2 but is: %A" other + + testProperty "bezier3 with line points" <| fun (p0 : V2d) (p3 : V2d) (ZeroOne t1) (ZeroOne t2) -> + + let p1 = lerp p0 p3 (min t1 t2) + let p2 = lerp p0 p3 (max t1 t2) + + let segment = try Some (PathSegment.bezier3 p0 p1 p2 p3) with _ -> None + match segment with + | Some (Line(a, b)) -> + Expect.equal a p0 "start" + Expect.equal b p3 "end" + | None -> + Expect.approxEquals p0 p1 1E-14 "degenerate bezier3" + | Some other -> + failwithf "degenerate bezier3 should be a line but is: %A" other + + testProperty "bezier3 degenerate" <| fun (p0 : V2d) -> + let arc = try Some (PathSegment.bezier3 p0 p0 p0 p0) with _ -> None + Expect.isNone arc "impossible to create degenerate arc" + + + + + ] + + [] + let splitMerge = + testList "Text.PathSegment" [ + testProperty "split at 0" <| fun (seg : PathSegment) -> + let (l, r) = PathSegment.split 0.0 seg + Expect.isNone l "left part should be empty" + Expect.equal r (Some seg) "right part should be entire segment" + + testProperty "split at 1" <| fun (seg : PathSegment) -> + let (l, r) = PathSegment.split 1.0 seg + Expect.isNone r "right part should be empty" + Expect.equal l (Some seg) "left part should be entire segment" + + testProperty "tryGetT" <| fun (seg : PathSegment) (ZeroOne t) -> + let pt = PathSegment.point t seg + match PathSegment.tryGetT 1E-7 pt seg with + | Some res -> + Expect.approxEquals res t 1E-8 "tryGetT" + | None -> + failwithf "could not get t for: %A (%A)" t pt + + testProperty "withT0" <| fun (seg : PathSegment) (ZeroOne t) -> + let t = min t 0.95 + let sub = PathSegment.withT0 t seg + Expect.isSome sub "sub should exist" + let sub = sub.Value + + Expect.approxEquals (PathSegment.point t seg) (PathSegment.startPoint sub) 1E-8 "split point equal" + Expect.approxEquals (PathSegment.tangent t seg) (PathSegment.tangent 0.0 sub) 1E-5 "split tangent equal" + Expect.relativeApproxEquals (PathSegment.curvature t seg) (PathSegment.curvature 0.0 sub) 1E-6 "split curvature equal" + Expect.relativeApproxEquals (PathSegment.curvatureDerivative t seg) (PathSegment.curvatureDerivative 0.0 sub) 1E-6 "split curvature derivative equal" + + testProperty "withT1" <| fun (seg : PathSegment) (ZeroOne t) -> + let t = max t 0.05 + let sub = PathSegment.withT1 t seg + Expect.isSome sub "sub should exist" + let sub = sub.Value + + Expect.approxEquals (PathSegment.point t seg) (PathSegment.endPoint sub) 1E-8 "split point equal" + Expect.approxEquals (PathSegment.tangent t seg) (PathSegment.tangent 1.0 sub) 1E-5 "split tangent equal" + Expect.relativeApproxEquals (PathSegment.curvature t seg) (PathSegment.curvature 1.0 sub) 1E-6 "split curvature equal" + Expect.relativeApproxEquals (PathSegment.curvatureDerivative t seg) (PathSegment.curvatureDerivative 1.0 sub) 1E-6 "split curvature derivative equal" + + + + testProperty "split" <| fun (seg : PathSegment) (ZeroOne t) (NonEmptyArray(tests : ZeroOne[]))-> + let t = clamp 1E-2 (1.0 - 1E-2) t + let (l, r) = PathSegment.split t seg + + + Expect.isSome l "left part should exist" + Expect.isSome r "right part should exist" + + match l with + | Some l -> + match r with + | Some r -> + Expect.equal (PathSegment.endPoint l) (PathSegment.startPoint r) "split point equal" + Expect.approxEquals (PathSegment.tangent 1.0 l) (PathSegment.tangent 0.0 r) 1E-5 "split tangent equal" + Expect.relativeApproxEquals (PathSegment.curvature 1.0 l) (PathSegment.curvature 0.0 r) 1E-6 "split curvature equal" + Expect.relativeApproxEquals (PathSegment.curvatureDerivative 1.0 l) (PathSegment.curvatureDerivative 0.0 r) 1E-6 "split curvature derivative equal" + + for (ZeroOne tt) in tests do + let pt = PathSegment.point tt seg + + let tl = PathSegment.tryGetT 1E-7 pt l |> Option.map (fun t -> PathSegment.point t l) + let tr = PathSegment.tryGetT 1E-7 pt r |> Option.map (fun t -> PathSegment.point t r) + + match tl with + | Some pl -> Expect.approxEquals pl pt 1E-7 "point on left part" + | None -> + match tr with + | Some pr -> Expect.approxEquals pr pt 1E-7 "point on left part" + | None -> failwith "different curves" + + + | None -> + () + //Expect.equal l seg "split at end" + | None -> + match r with + | Some r -> + () + //Expect.equal r seg "split at start" + | None -> + failwith "should be impossible (both split parts empty)" + + + + ] \ No newline at end of file diff --git a/src/Tests/Aardvark.Rendering.Tests/Tests/Utilities.fs b/src/Tests/Aardvark.Rendering.Tests/Tests/Utilities.fs index 7e9474081..c98e9b2e4 100644 --- a/src/Tests/Aardvark.Rendering.Tests/Tests/Utilities.fs +++ b/src/Tests/Aardvark.Rendering.Tests/Tests/Utilities.fs @@ -282,6 +282,66 @@ module PixData = [] module ``Expecto Extensions`` = + open Aardvark.Rendering.Text + open FsCheck + + type ZeroOne = ZeroOne of float + + type Generators() = + static member V2d = + { new Arbitrary() with + override x.Generator = + gen { + let! (NormalFloat a) = Arb.generate + let! (NormalFloat b)= Arb.generate + return V2d(a,b) + } + } + + static member ZeroOne = + { new Arbitrary() with + override x.Generator = + gen { + let! (NormalFloat a) = Arb.generate + return ZeroOne (abs a % 1.0) + } + } + + static member PathSegment = + { new Arbitrary() with + override x.Generator = + gen { + let! kind = Gen.elements [0;1;2;3] + + match kind with + | 0 -> + let! p0 = Arb.generate + let! p1 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8))) + return PathSegment.line p0 p1 + | 1 -> + let! p0 = Arb.generate + let! p1 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8))) + let! p2 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8)) && not (Fun.ApproximateEquals(p, p1, 1E-8))) + return PathSegment.bezier2 p0 p1 p2 + | 2 -> + let! center = Arb.generate + let! a0 = Arb.generate + let! a1 = Arb.generate |> Gen.filter (fun p -> not (Fun.IsTiny(Vec.AngleBetween(Vec.normalize a0, Vec.normalize p), 1E-5))) + + let! (NormalFloat alpha0) = Arb.generate + let! (NormalFloat dAlpha) = Arb.generate + + let dAlpha = dAlpha % Constant.PiHalf + + return PathSegment.arc alpha0 dAlpha (Ellipse2d(center, a0, a1)) + | _ -> + let! p0 = Arb.generate + let! p1 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8))) + let! p2 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8)) && not (Fun.ApproximateEquals(p, p1, 1E-8))) + let! p3 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8)) && not (Fun.ApproximateEquals(p, p1, 1E-8)) && not (Fun.ApproximateEquals(p, p2, 1E-8))) + return PathSegment.bezier3 p0 p1 p2 p3 + } + } module Expect = @@ -293,6 +353,35 @@ module ``Expecto Extensions`` = Expect.floatClose accuracy actual.Z expected.Z message Expect.floatClose accuracy actual.W expected.W message + let inline approxEqualAux< ^a, ^b when (^a or ^b) : (static member ApproximateEquals : ^a * ^a * float -> bool)> (foo : ^ b) (a : 'a) (b : 'a) (eps : float) = + (((^a or ^b) : (static member ApproximateEquals : ^a * ^a * float -> bool) (a, b, eps))) + + let inline approxEquals a b eps msg = + if not (approxEqualAux Unchecked.defaultof a b eps) then + Expect.equal a b msg + + let inline relativeApproxEquals (a : float) (b : float) eps msg = + let scale = max (abs a) (abs b) + if not (Fun.IsTiny(scale, eps)) then + let ra = a / scale + let rb = b / scale + + if not (Fun.ApproximateEquals(ra, rb, eps)) then + Expect.equal a b msg + + module ExpectoOverrides = + + let private config = + { + FsCheckConfig.defaultConfig with + arbitrary = [ typeof ] @ FsCheckConfig.defaultConfig.arbitrary + maxTest = 100000 + } + + let testProperty a b = + testPropertyWithConfig config a b + + // Utility to run Expecto tests synchronously in the current thread. // Prints a summary at the end. let runTestsSynchronously (stopOnFail : bool) (tests : Test) = diff --git a/src/Tests/Aardvark.Rendering.Text.Tests/Aardvark.Rendering.Text.Tests.fsproj b/src/Tests/Aardvark.Rendering.Text.Tests/Aardvark.Rendering.Text.Tests.fsproj deleted file mode 100644 index 63d99ba93..000000000 --- a/src/Tests/Aardvark.Rendering.Text.Tests/Aardvark.Rendering.Text.Tests.fsproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - net6.0 - false - Exe - true - $(MSBuildThisFileDirectory)\test.runsettings - 3389;3390;3395 - - - ..\..\..\bin\Debug\ - DEBUG;TRACE - - - ..\..\..\bin\Release\ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Tests/Aardvark.Rendering.Text.Tests/Common.fs b/src/Tests/Aardvark.Rendering.Text.Tests/Common.fs deleted file mode 100644 index 423478a69..000000000 --- a/src/Tests/Aardvark.Rendering.Text.Tests/Common.fs +++ /dev/null @@ -1,100 +0,0 @@ -namespace Expecto - - -open Expecto -open Aardvark.Base -open Aardvark.Rendering.Text -open FsCheck -open FsCheck.TypeClass - -type ZeroOne = ZeroOne of float - -type Generators() = - static member V2d = - { new Arbitrary() with - override x.Generator = - gen { - let! (NormalFloat a) = Arb.generate - let! (NormalFloat b)= Arb.generate - return V2d(a,b) - } - } - - static member ZeroOne = - { new Arbitrary() with - override x.Generator = - gen { - let! (NormalFloat a) = Arb.generate - return ZeroOne (abs a % 1.0) - } - } - - static member PathSegment = - { new Arbitrary() with - override x.Generator = - gen { - let! kind = Gen.elements [0;1;2;3] - - match kind with - | 0 -> - let! p0 = Arb.generate - let! p1 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8))) - return PathSegment.line p0 p1 - | 1 -> - let! p0 = Arb.generate - let! p1 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8))) - let! p2 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8)) && not (Fun.ApproximateEquals(p, p1, 1E-8))) - return PathSegment.bezier2 p0 p1 p2 - | 2 -> - let! center = Arb.generate - let! a0 = Arb.generate - let! a1 = Arb.generate |> Gen.filter (fun p -> not (Fun.IsTiny(Vec.AngleBetween(Vec.normalize a0, Vec.normalize p), 1E-5))) - - let! (NormalFloat alpha0) = Arb.generate - let! (NormalFloat dAlpha) = Arb.generate - - let dAlpha = dAlpha % Constant.PiHalf - - return PathSegment.arc alpha0 dAlpha (Ellipse2d(center, a0, a1)) - | _ -> - let! p0 = Arb.generate - let! p1 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8))) - let! p2 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8)) && not (Fun.ApproximateEquals(p, p1, 1E-8))) - let! p3 = Arb.generate |> Gen.filter (fun p -> not (Fun.ApproximateEquals(p, p0, 1E-8)) && not (Fun.ApproximateEquals(p, p1, 1E-8)) && not (Fun.ApproximateEquals(p, p2, 1E-8))) - return PathSegment.bezier3 p0 p1 p2 p3 - } - } -module Expect = - let inline approxEqualAux< ^a, ^b when (^a or ^b) : (static member ApproximateEquals : ^a * ^a * float -> bool)> (foo : ^ b) (a : 'a) (b : 'a) (eps : float) = - (((^a or ^b) : (static member ApproximateEquals : ^a * ^a * float -> bool) (a, b, eps))) - - - let inline approxEquals a b eps msg = - if not (approxEqualAux Unchecked.defaultof a b eps) then - Expect.equal a b msg - - let inline relativeApproxEquals (a : float) (b : float) eps msg = - - let scale = max (abs a) (abs b) - if not (Fun.IsTiny(scale, eps)) then - let ra = a / scale - let rb = b / scale - - if not (Fun.ApproximateEquals(ra, rb, eps)) then - Expect.equal a b msg - - - -[] -module ExpectoOverrides = - - let config = - { - FsCheckConfig.defaultConfig with - arbitrary = [ typeof ] - maxTest = 100000 - } - - - let testProperty a b = - testPropertyWithConfig config a b diff --git a/src/Tests/Aardvark.Rendering.Text.Tests/PathSegment.fs b/src/Tests/Aardvark.Rendering.Text.Tests/PathSegment.fs deleted file mode 100644 index 7ce4c78d3..000000000 --- a/src/Tests/Aardvark.Rendering.Text.Tests/PathSegment.fs +++ /dev/null @@ -1,251 +0,0 @@ -module Aardvark.Rendering.Text.Tests.PathSegment - -open Expecto -open Aardvark.Base -open Aardvark.Rendering.Text -open FsCheck - -[] -let smartConstructors = - testList "PathSegment" [ - testProperty "tryLine degenerate" <| fun (p1 : V2d) -> - let line = PathSegment.tryLine p1 p1 - Expect.isNone line "impossible to create degenerate line" - - testProperty "tryBezier2 line" <| fun (p0 : V2d) (p2 : V2d) (ZeroOne t) -> - let p1 = lerp p0 p2 t - match PathSegment.tryBezier2 p0 p1 p2 with - | Some (Line(a,b)) -> - Expect.equal a p0 "line start" - Expect.equal b p2 "line end" - | None -> - Expect.equal p0 p2 "degenerate bezier2" - | Some other -> - failwithf "degenerate bezier2 should be a line but is: %A" other - - testProperty "tryBezier2 degenerate" <| fun (p0 : V2d) -> - let bezier2 = PathSegment.tryBezier2 p0 p0 p0 - Expect.isNone bezier2 "impossible to create degenerate bezier2" - - testProperty "tryArcSegment line" <| fun (p0 : V2d) (p2 : V2d) (ZeroOne t) -> - let p1 = lerp p0 p2 t - match PathSegment.tryArcSegment p0 p1 p2 with - | Some (Line(a,b)) -> - Expect.equal a p0 "line start" - Expect.equal b p2 "line end" - | None -> - Expect.equal p0 p2 "degenerate arc" - | Some other -> - failwithf "degenerate arc should be a line but is: %A" other - - testProperty "tryArcSegment degenerate" <| fun (p0 : V2d) -> - let arc = PathSegment.tryArcSegment p0 p0 p0 - Expect.isNone arc "impossible to create degenerate arc" - - testProperty "tryBezier3 with bezier2 points" <| fun (p0 : V2d) (p1 : V2d) (p2 : V2d) -> - let a = lerp p0 p1 (2.0 / 3.0) - let b = lerp p1 p2 (1.0 / 3.0) - - match PathSegment.tryBezier3 p0 a b p2 with - | Some (Line(a, b)) -> - Expect.equal a p0 "start" - Expect.equal b p2 "end" - | None -> - Expect.equal p0 p1 "degenerate bezier3" - Expect.equal p0 p2 "degenerate bezier3" - | Some (Bezier2(a,b,c)) -> - Expect.equal a p0 "start" - Expect.approxEquals b p1 1E-13 "control" - Expect.equal c p2 "end" - | Some other -> - failwithf "degenerate bezier3 should be a bezier2 but is: %A" other - - testProperty "tryBezier3 with line points" <| fun (p0 : V2d) (p3 : V2d) (ZeroOne t1) (ZeroOne t2) -> - - let p1 = lerp p0 p3 (min t1 t2) - let p2 = lerp p0 p3 (max t1 t2) - - match PathSegment.tryBezier3 p0 p1 p2 p3 with - | Some (Line(a, b)) -> - Expect.equal a p0 "start" - Expect.equal b p3 "end" - | None -> - Expect.approxEquals p0 p1 1E-14 "degenerate bezier3" - | Some other -> - failwithf "degenerate bezier3 should be a line but is: %A" other - - testProperty "tryBezier3 degenerate" <| fun (p0 : V2d) -> - let arc = PathSegment.tryBezier3 p0 p0 p0 p0 - Expect.isNone arc "impossible to create degenerate arc" - - testProperty "line degenerate" <| fun (p1 : V2d) -> - let line = try Some (PathSegment.line p1 p1) with _ -> None - Expect.isNone line "impossible to create degenerate line" - - testProperty "bezier2 line" <| fun (p0 : V2d) (p2 : V2d) (ZeroOne t) -> - let p1 = lerp p0 p2 t - - let segment = try Some (PathSegment.bezier2 p0 p1 p2) with _ -> None - - match segment with - | Some (Line(a,b)) -> - Expect.equal a p0 "line start" - Expect.equal b p2 "line end" - | None -> - Expect.equal p0 p2 "degenerate bezier2" - | Some other -> - failwithf "degenerate bezier2 should be a line but is: %A" other - - testProperty "bezier2 degenerate" <| fun (p0 : V2d) -> - let bezier2 = try Some (PathSegment.bezier2 p0 p0 p0) with _ -> None - Expect.isNone bezier2 "impossible to create degenerate bezier2" - - testProperty "arcSegment line" <| fun (p0 : V2d) (p2 : V2d) (ZeroOne t) -> - let p1 = lerp p0 p2 t - let segment = try Some (PathSegment.arcSegment p0 p1 p2) with _ -> None - match segment with - | Some (Line(a,b)) -> - Expect.equal a p0 "line start" - Expect.equal b p2 "line end" - | None -> - Expect.equal p0 p2 "degenerate arc" - | Some other -> - failwithf "degenerate arc should be a line but is: %A" other - - testProperty "arcSegment degenerate" <| fun (p0 : V2d) -> - let arc = try Some (PathSegment.arcSegment p0 p0 p0) with _ -> None - Expect.isNone arc "impossible to create degenerate arc" - - testProperty "bezier3 with bezier2 points" <| fun (p0 : V2d) (p1 : V2d) (p2 : V2d) -> - let a = lerp p0 p1 (2.0 / 3.0) - let b = lerp p1 p2 (1.0 / 3.0) - - let segment = try Some (PathSegment.bezier3 p0 a b p2) with _ -> None - match segment with - | Some (Line(a, b)) -> - Expect.equal a p0 "start" - Expect.equal b p2 "end" - | None -> - Expect.equal p0 p1 "degenerate bezier3" - Expect.equal p0 p2 "degenerate bezier3" - | Some (Bezier2(a,b,c)) -> - Expect.equal a p0 "start" - Expect.approxEquals b p1 1E-13 "control" - Expect.equal c p2 "end" - | Some other -> - failwithf "degenerate bezier3 should be a bezier2 but is: %A" other - - testProperty "bezier3 with line points" <| fun (p0 : V2d) (p3 : V2d) (ZeroOne t1) (ZeroOne t2) -> - - let p1 = lerp p0 p3 (min t1 t2) - let p2 = lerp p0 p3 (max t1 t2) - - let segment = try Some (PathSegment.bezier3 p0 p1 p2 p3) with _ -> None - match segment with - | Some (Line(a, b)) -> - Expect.equal a p0 "start" - Expect.equal b p3 "end" - | None -> - Expect.approxEquals p0 p1 1E-14 "degenerate bezier3" - | Some other -> - failwithf "degenerate bezier3 should be a line but is: %A" other - - testProperty "bezier3 degenerate" <| fun (p0 : V2d) -> - let arc = try Some (PathSegment.bezier3 p0 p0 p0 p0) with _ -> None - Expect.isNone arc "impossible to create degenerate arc" - - - - - ] - -[] -let splitMerge = - testList "PathSegment" [ - testProperty "split at 0" <| fun (seg : PathSegment) -> - let (l, r) = PathSegment.split 0.0 seg - Expect.isNone l "left part should be empty" - Expect.equal r (Some seg) "right part should be entire segment" - - testProperty "split at 1" <| fun (seg : PathSegment) -> - let (l, r) = PathSegment.split 1.0 seg - Expect.isNone r "right part should be empty" - Expect.equal l (Some seg) "left part should be entire segment" - - testProperty "tryGetT" <| fun (seg : PathSegment) (ZeroOne t) -> - let pt = PathSegment.point t seg - match PathSegment.tryGetT 1E-7 pt seg with - | Some res -> - Expect.approxEquals res t 1E-8 "tryGetT" - | None -> - failwithf "could not get t for: %A (%A)" t pt - - testProperty "withT0" <| fun (seg : PathSegment) (ZeroOne t) -> - let t = min t 0.95 - let sub = PathSegment.withT0 t seg - Expect.isSome sub "sub should exist" - let sub = sub.Value - - Expect.approxEquals (PathSegment.point t seg) (PathSegment.startPoint sub) 1E-8 "split point equal" - Expect.approxEquals (PathSegment.tangent t seg) (PathSegment.tangent 0.0 sub) 1E-5 "split tangent equal" - Expect.relativeApproxEquals (PathSegment.curvature t seg) (PathSegment.curvature 0.0 sub) 1E-6 "split curvature equal" - Expect.relativeApproxEquals (PathSegment.curvatureDerivative t seg) (PathSegment.curvatureDerivative 0.0 sub) 1E-6 "split curvature derivative equal" - - testProperty "withT1" <| fun (seg : PathSegment) (ZeroOne t) -> - let t = max t 0.05 - let sub = PathSegment.withT1 t seg - Expect.isSome sub "sub should exist" - let sub = sub.Value - - Expect.approxEquals (PathSegment.point t seg) (PathSegment.endPoint sub) 1E-8 "split point equal" - Expect.approxEquals (PathSegment.tangent t seg) (PathSegment.tangent 1.0 sub) 1E-5 "split tangent equal" - Expect.relativeApproxEquals (PathSegment.curvature t seg) (PathSegment.curvature 1.0 sub) 1E-6 "split curvature equal" - Expect.relativeApproxEquals (PathSegment.curvatureDerivative t seg) (PathSegment.curvatureDerivative 1.0 sub) 1E-6 "split curvature derivative equal" - - - - testProperty "split" <| fun (seg : PathSegment) (ZeroOne t) (NonEmptyArray(tests : ZeroOne[]))-> - let t = clamp 1E-2 (1.0 - 1E-2) t - let (l, r) = PathSegment.split t seg - - - Expect.isSome l "left part should exist" - Expect.isSome r "right part should exist" - - match l with - | Some l -> - match r with - | Some r -> - Expect.equal (PathSegment.endPoint l) (PathSegment.startPoint r) "split point equal" - Expect.approxEquals (PathSegment.tangent 1.0 l) (PathSegment.tangent 0.0 r) 1E-5 "split tangent equal" - Expect.relativeApproxEquals (PathSegment.curvature 1.0 l) (PathSegment.curvature 0.0 r) 1E-6 "split curvature equal" - Expect.relativeApproxEquals (PathSegment.curvatureDerivative 1.0 l) (PathSegment.curvatureDerivative 0.0 r) 1E-6 "split curvature derivative equal" - - for (ZeroOne tt) in tests do - let pt = PathSegment.point tt seg - - let tl = PathSegment.tryGetT 1E-7 pt l |> Option.map (fun t -> PathSegment.point t l) - let tr = PathSegment.tryGetT 1E-7 pt r |> Option.map (fun t -> PathSegment.point t r) - - match tl with - | Some pl -> Expect.approxEquals pl pt 1E-7 "point on left part" - | None -> - match tr with - | Some pr -> Expect.approxEquals pr pt 1E-7 "point on left part" - | None -> failwith "different curves" - - - | None -> - () - //Expect.equal l seg "split at end" - | None -> - match r with - | Some r -> - () - //Expect.equal r seg "split at start" - | None -> - failwith "should be impossible (both split parts empty)" - - - - ] \ No newline at end of file diff --git a/src/Tests/Aardvark.Rendering.Text.Tests/Program.fs b/src/Tests/Aardvark.Rendering.Text.Tests/Program.fs deleted file mode 100644 index c8c69c3c9..000000000 --- a/src/Tests/Aardvark.Rendering.Text.Tests/Program.fs +++ /dev/null @@ -1,10 +0,0 @@ -open Expecto -open Expecto.Impl - -[] -let main args = - let cfg : ExpectoConfig = { ExpectoConfig.defaultConfig with runInParallel = false } - runTests cfg Aardvark.Rendering.Text.Tests.PathSegment.splitMerge |> ignore - //runTestsWithCLIArgs [] args Aardvark.Rendering.Text.Tests.PathSegment.splitMerge |> ignore - - 0 diff --git a/src/Tests/Aardvark.Rendering.Text.Tests/paket.references b/src/Tests/Aardvark.Rendering.Text.Tests/paket.references deleted file mode 100644 index 0f465a26f..000000000 --- a/src/Tests/Aardvark.Rendering.Text.Tests/paket.references +++ /dev/null @@ -1,10 +0,0 @@ -Aardvark.Build - -group Test - FSharp.Core - Expecto - Expecto.FsCheck - Expecto.Hopac - BenchmarkDotNet - YoloDev.Expecto.TestSdk - Microsoft.NET.Test.Sdk \ No newline at end of file diff --git a/src/Tests/Aardvark.Rendering.Text.Tests/test.runsettings b/src/Tests/Aardvark.Rendering.Text.Tests/test.runsettings deleted file mode 100644 index a2610ff99..000000000 --- a/src/Tests/Aardvark.Rendering.Text.Tests/test.runsettings +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - detailed - - - - - - False - - \ No newline at end of file