From 6731dddcee77bf5d781c210f0860d84e6e6354fe Mon Sep 17 00:00:00 2001 From: Charles Roddie Date: Fri, 8 Nov 2019 10:12:07 +0000 Subject: [PATCH 1/6] Add mathkeyboard test using random inputs --- CSharpMath.sln | 65 +++++++++++++++++++++++++++++- TestsInFSharp/Program.fs | 1 + TestsInFSharp/TestsInFSharp.fsproj | 27 +++++++++++++ TestsInFSharp/UnitTest1.fs | 52 ++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 TestsInFSharp/Program.fs create mode 100644 TestsInFSharp/TestsInFSharp.fsproj create mode 100644 TestsInFSharp/UnitTest1.fs diff --git a/CSharpMath.sln b/CSharpMath.sln index 32e56b5bf..64cc08b58 100644 --- a/CSharpMath.sln +++ b/CSharpMath.sln @@ -90,7 +90,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Extended.Svg", "S EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Extended.Svg.Tests", "SkiaSharp.Extended\SkiaSharp.Extended.Svg\tests\SkiaSharp.Extended.Svg.Tests.csproj", "{D5821772-5060-4C71-9D71-5A36FBC5BF4A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpMath.Editor Test Checker", "CSharpMath.Editor.TestChecker\CSharpMath.Editor Test Checker.csproj", "{C60126CE-A71D-4D11-A4A8-A45B67312E98}" +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 @@ -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..9f2c076b1 --- /dev/null +++ b/TestsInFSharp/UnitTest1.fs @@ -0,0 +1,52 @@ +module TestsInFSharp + +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 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 test100keypresses() = + let keyboard = CSharpMath.Rendering.MathKeyboard() + let mutable reverseInputs:MathKeyboardInput list = [] + for _ = 1 to 100 do + let ki = getRandomMathKeyboardInput() + reverseInputs <- ki::reverseInputs + try + getRandomMathKeyboardInput() |> keyboard.KeyPress + keyboard.LaTeX |> ignore + with _ -> + failwith <| sprintf "KeyboardInputs: %A" (reverseInputs |> List.rev) + +[] +let ``random inputs don't crash editor``() = + for i = 1 to 1000 do + test100keypresses() \ No newline at end of file From 0c467269257b1ab7e70df46a0289a090e3b3f5e4 Mon Sep 17 00:00:00 2001 From: Charles Roddie Date: Fri, 8 Nov 2019 10:26:25 +0000 Subject: [PATCH 2/6] display exception --- TestsInFSharp/UnitTest1.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TestsInFSharp/UnitTest1.fs b/TestsInFSharp/UnitTest1.fs index 9f2c076b1..79c8091ad 100644 --- a/TestsInFSharp/UnitTest1.fs +++ b/TestsInFSharp/UnitTest1.fs @@ -43,8 +43,8 @@ let test100keypresses() = try getRandomMathKeyboardInput() |> keyboard.KeyPress keyboard.LaTeX |> ignore - with _ -> - failwith <| sprintf "KeyboardInputs: %A" (reverseInputs |> List.rev) + with e -> + failwithf "Exception: %s KeyboardInputs: %A" e.Message (reverseInputs |> List.rev) [] let ``random inputs don't crash editor``() = From 92f40151f149f65d05c6b4e193d545f4ea247eb3 Mon Sep 17 00:00:00 2001 From: Charles Roddie Date: Fri, 8 Nov 2019 10:34:35 +0000 Subject: [PATCH 3/6] get shortest error --- TestsInFSharp/UnitTest1.fs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/TestsInFSharp/UnitTest1.fs b/TestsInFSharp/UnitTest1.fs index 79c8091ad..22d3cdae5 100644 --- a/TestsInFSharp/UnitTest1.fs +++ b/TestsInFSharp/UnitTest1.fs @@ -37,6 +37,7 @@ let getRandomMathKeyboardInput = let test100keypresses() = let keyboard = CSharpMath.Rendering.MathKeyboard() let mutable reverseInputs:MathKeyboardInput list = [] + let mutable result = Ok() for _ = 1 to 100 do let ki = getRandomMathKeyboardInput() reverseInputs <- ki::reverseInputs @@ -44,9 +45,19 @@ let test100keypresses() = getRandomMathKeyboardInput() |> keyboard.KeyPress keyboard.LaTeX |> ignore with e -> - failwithf "Exception: %s KeyboardInputs: %A" e.Message (reverseInputs |> List.rev) + result <- + Error(e.Message, reverseInputs |> List.rev) + result [] let ``random inputs don't crash editor``() = - for i = 1 to 1000 do - test100keypresses() \ No newline at end of file + 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 + | [] -> () + | (ex, inputs)::_ -> + failwithf "Exeption: %s inputs: %A" ex inputs \ No newline at end of file From f9efa624b87a58b176056f9f1814168aed30cf31 Mon Sep 17 00:00:00 2001 From: Charles Roddie Date: Fri, 8 Nov 2019 10:37:18 +0000 Subject: [PATCH 4/6] fix mistake --- TestsInFSharp/UnitTest1.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TestsInFSharp/UnitTest1.fs b/TestsInFSharp/UnitTest1.fs index 22d3cdae5..7c435666e 100644 --- a/TestsInFSharp/UnitTest1.fs +++ b/TestsInFSharp/UnitTest1.fs @@ -42,7 +42,7 @@ let test100keypresses() = let ki = getRandomMathKeyboardInput() reverseInputs <- ki::reverseInputs try - getRandomMathKeyboardInput() |> keyboard.KeyPress + ki |> keyboard.KeyPress keyboard.LaTeX |> ignore with e -> result <- From dc571141c40cc59ec5057df2eaebc411e211385f Mon Sep 17 00:00:00 2001 From: Charles Roddie Date: Fri, 8 Nov 2019 10:57:35 +0000 Subject: [PATCH 5/6] find shortest --- TestsInFSharp/UnitTest1.fs | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/TestsInFSharp/UnitTest1.fs b/TestsInFSharp/UnitTest1.fs index 7c435666e..e91027877 100644 --- a/TestsInFSharp/UnitTest1.fs +++ b/TestsInFSharp/UnitTest1.fs @@ -1,4 +1,4 @@ -module TestsInFSharp +module TestEditor.RandomKeyboardInputsTest open NUnit.Framework @@ -28,13 +28,13 @@ let private mathKeyboardInputs = // can use Hedgehog or FSCheck instead for random testing -let getRandomMathKeyboardInput = +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 test100keypresses() = +let private test100keypresses() = let keyboard = CSharpMath.Rendering.MathKeyboard() let mutable reverseInputs:MathKeyboardInput list = [] let mutable result = Ok() @@ -46,9 +46,29 @@ let test100keypresses() = keyboard.LaTeX |> ignore with e -> result <- - Error(e.Message, reverseInputs |> List.rev) + Error(reverseInputs |> List.rev) result +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 = @@ -56,8 +76,12 @@ let ``random inputs don't crash editor``() = let shortestError = results |> List.choose (function Ok _ -> None | Error e -> Some e) - |> List.sortBy (fun (_, inputs) -> inputs.Length) + |> List.sortBy (fun inputs -> inputs.Length) match shortestError with | [] -> () - | (ex, inputs)::_ -> - failwithf "Exeption: %s inputs: %A" ex inputs \ No newline at end of file + | kl::_ -> + let shortestSublist = + findShortening kl + try + tryList shortestSublist + with ex -> failwithf "Exeption: %s inputs: %A" ex.Message shortestSublist \ No newline at end of file From b7a304659b520d50101c826715c4dedfa1ed6b71 Mon Sep 17 00:00:00 2001 From: Charles Roddie Date: Fri, 8 Nov 2019 11:10:13 +0000 Subject: [PATCH 6/6] tidy --- TestsInFSharp/UnitTest1.fs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/TestsInFSharp/UnitTest1.fs b/TestsInFSharp/UnitTest1.fs index e91027877..fbd8b9b11 100644 --- a/TestsInFSharp/UnitTest1.fs +++ b/TestsInFSharp/UnitTest1.fs @@ -37,17 +37,15 @@ let private getRandomMathKeyboardInput = let private test100keypresses() = let keyboard = CSharpMath.Rendering.MathKeyboard() let mutable reverseInputs:MathKeyboardInput list = [] - let mutable result = Ok() - for _ = 1 to 100 do - let ki = getRandomMathKeyboardInput() - reverseInputs <- ki::reverseInputs - try + try + for _ = 1 to 100 do + let ki = getRandomMathKeyboardInput() + reverseInputs <- ki::reverseInputs ki |> keyboard.KeyPress keyboard.LaTeX |> ignore - with e -> - result <- - Error(reverseInputs |> List.rev) - result + Ok() + with _ -> + Error(reverseInputs |> List.rev) let private tryList(kl:MathKeyboardInput list) = let keyboard = CSharpMath.Rendering.MathKeyboard()