diff --git a/CSharpMath.sln b/CSharpMath.sln index 8cece7438..64cc08b58 100644 --- a/CSharpMath.sln +++ b/CSharpMath.sln @@ -92,6 +92,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Extended.Svg.Test EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpMath.Editor Test Checker", "CSharpMath.Editor.TestChecker\CSharpMath.Editor Test Checker.csproj", "{C60126CE-A71D-4D11-A4A8-A45B67312E98}" EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "TestsInFSharp", "TestsInFSharp\TestsInFSharp.fsproj", "{65492AC6-8B98-42FF-AAA1-1DBDC050A25F}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution CSharpMath.Apple\CSharpMath.Apple.projitems*{11d4e6c7-c8e2-449c-a1e7-18bbbce4e6f3}*SharedItemsImports = 4 @@ -1626,6 +1628,66 @@ Global {C60126CE-A71D-4D11-A4A8-A45B67312E98}.Release-iOS|x64.Build.0 = Release|Any CPU {C60126CE-A71D-4D11-A4A8-A45B67312E98}.Release-iOS|x86.ActiveCfg = Release|Any CPU {C60126CE-A71D-4D11-A4A8-A45B67312E98}.Release-iOS|x86.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|ARM.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|iPhone.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|x64.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|x64.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|x86.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.AppStore|x86.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|ARM.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|ARM.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|iPhone.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|x64.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|x64.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|x86.ActiveCfg = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Debug|x86.Build.0 = Debug|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|Any CPU.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|ARM.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|ARM.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|iPhone.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|iPhone.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|x64.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|x64.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|x86.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release|x86.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|Any CPU.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|Any CPU.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|ARM.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|ARM.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|iPhone.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|iPhone.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|iPhoneSimulator.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|iPhoneSimulator.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|x64.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|x64.Build.0 = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|x86.ActiveCfg = Release|Any CPU + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F}.Release-iOS|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1663,6 +1725,7 @@ Global {A51854AA-4645-4596-B0F5-CB8BDBDDCDC5} = {74FBDC58-E93A-4DCE-B83F-AA936EE57B31} {D5821772-5060-4C71-9D71-5A36FBC5BF4A} = {74FBDC58-E93A-4DCE-B83F-AA936EE57B31} {C60126CE-A71D-4D11-A4A8-A45B67312E98} = {E7CDDECF-B87B-4114-932B-D3FB5E8302F8} + {65492AC6-8B98-42FF-AAA1-1DBDC050A25F} = {125C1FE9-F684-4E87-A9EF-969FD1E2D726} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3C9A56A6-4EA3-4228-B064-E4789B282032} diff --git a/TestsInFSharp/Program.fs b/TestsInFSharp/Program.fs new file mode 100644 index 000000000..0695f84c6 --- /dev/null +++ b/TestsInFSharp/Program.fs @@ -0,0 +1 @@ +module Program = let [] main _ = 0 diff --git a/TestsInFSharp/TestsInFSharp.fsproj b/TestsInFSharp/TestsInFSharp.fsproj new file mode 100644 index 000000000..adb0fa697 --- /dev/null +++ b/TestsInFSharp/TestsInFSharp.fsproj @@ -0,0 +1,27 @@ + + + + netcoreapp3.0 + + false + false + + + + + + + + + + + + + + + + + + + + diff --git a/TestsInFSharp/UnitTest1.fs b/TestsInFSharp/UnitTest1.fs new file mode 100644 index 000000000..fbd8b9b11 --- /dev/null +++ b/TestsInFSharp/UnitTest1.fs @@ -0,0 +1,85 @@ +module TestEditor.RandomKeyboardInputsTest + +open NUnit.Framework + +open CSharpMath.Editor + +let private mathKeyboardInputs = + [| MathKeyboardInput.A + MathKeyboardInput.B + MathKeyboardInput.C + MathKeyboardInput.Alpha + MathKeyboardInput.Sine + MathKeyboardInput.ArcCotangent + MathKeyboardInput.Subscript + MathKeyboardInput.Power + MathKeyboardInput.Left + MathKeyboardInput.Right + MathKeyboardInput.Up + MathKeyboardInput.Down + MathKeyboardInput.Equals + MathKeyboardInput.Plus + MathKeyboardInput.Minus + MathKeyboardInput.Divide + MathKeyboardInput.LeftRoundBracket + MathKeyboardInput.RightRoundBracket + MathKeyboardInput.BothRoundBrackets + |] + +// can use Hedgehog or FSCheck instead for random testing + +let private getRandomMathKeyboardInput = + let r = System.Random() + let n = mathKeyboardInputs.Length + fun () -> mathKeyboardInputs.[r.Next(n)] + +/// adds 100 random keypresses to a MathKeyboard and gets LaTeX and checks that there is no crash +let private test100keypresses() = + let keyboard = CSharpMath.Rendering.MathKeyboard() + let mutable reverseInputs:MathKeyboardInput list = [] + try + for _ = 1 to 100 do + let ki = getRandomMathKeyboardInput() + reverseInputs <- ki::reverseInputs + ki |> keyboard.KeyPress + keyboard.LaTeX |> ignore + Ok() + with _ -> + Error(reverseInputs |> List.rev) + +let private tryList(kl:MathKeyboardInput list) = + let keyboard = CSharpMath.Rendering.MathKeyboard() + for ki in kl do + ki |> keyboard.KeyPress + keyboard.LaTeX |> ignore + +// kl gives an error; this finds a shortest sublist that gives an error +let rec private findShortening(kl:MathKeyboardInput list) = + let isError(kl:MathKeyboardInput list) = + try + tryList kl + false + with _ -> true + let reductions = + List.init kl.Length (fun i -> + kl.[0 .. i-1] @ kl.[i+1 .. kl.Length-1]) + match reductions |> List.tryFind isError with + | None -> kl + | Some sl -> findShortening sl + +[] +let ``random inputs don't crash editor``() = + let results = + List.init 1000 (fun _ -> test100keypresses()) + let shortestError = + results + |> List.choose (function Ok _ -> None | Error e -> Some e) + |> List.sortBy (fun inputs -> inputs.Length) + match shortestError with + | [] -> () + | kl::_ -> + let shortestSublist = + findShortening kl + try + tryList shortestSublist + with ex -> failwithf "Exeption: %s inputs: %A" ex.Message shortestSublist \ No newline at end of file