diff --git a/Sources/Terminal/AngouriMath.Terminal.Lib/AngouriMath.Terminal.Lib.fsproj b/Sources/Terminal/AngouriMath.Terminal.Lib/AngouriMath.Terminal.Lib.fsproj index 6faadc314..7a35cb087 100644 --- a/Sources/Terminal/AngouriMath.Terminal.Lib/AngouriMath.Terminal.Lib.fsproj +++ b/Sources/Terminal/AngouriMath.Terminal.Lib/AngouriMath.Terminal.Lib.fsproj @@ -22,6 +22,26 @@ https://github.com/asc-community/AngouriMath/issues/542 --> false + + + $(NoWarn);NU1608 diff --git a/Sources/Terminal/AngouriMath.Terminal/AngouriMath.Terminal.fsproj b/Sources/Terminal/AngouriMath.Terminal/AngouriMath.Terminal.fsproj index 28e902cd5..96abe3fd5 100644 --- a/Sources/Terminal/AngouriMath.Terminal/AngouriMath.Terminal.fsproj +++ b/Sources/Terminal/AngouriMath.Terminal/AngouriMath.Terminal.fsproj @@ -14,6 +14,13 @@ F#-based command line interface for symbolic algebra library AngouriMath $(PackageTags), cli, terminal + + + $(NoWarn);NU1608 diff --git a/Sources/Tests/TerminalUnitTests/CompilerServiceWorksTest.fs b/Sources/Tests/TerminalUnitTests/CompilerServiceWorksTest.fs new file mode 100644 index 000000000..2af0c233b --- /dev/null +++ b/Sources/Tests/TerminalUnitTests/CompilerServiceWorksTest.fs @@ -0,0 +1,84 @@ +/// The Terminal bundles FSharp.Compiler.Service beside an FSharp.Core two majors above the one +/// it declares it needs, and NU1608 has said so on every publish since 2.3.0. This is what +/// settles whether that matters: the pair is asked to compile F#, and told to. +/// https://github.com/asc-community/AngouriMath/issues/1100 +module AngouriMath.Terminal.CompilerServiceWorksTest + +open Xunit +open AngouriMath.Terminal.Lib.FSharpInteractive +open AngouriMath.Terminal.Lib.PreRunCode +open AngouriMath.Terminal.Lib.Consts + +/// A kernel with nothing loaded into it, so what is under test is the compiler rather than +/// AngouriMath's own bindings. The Terminal opens AggressiveOperators over the top, which +/// deliberately rebinds the comparison operators to build expressions — that is the tool's whole +/// point and it is not what this asks about. +let private bareKernel () = + match createKernel () with + | Result.Error _ -> + Assert.True(false, "the kernel did not load at all") + raise (System.Exception()) + | Result.Ok kernel -> kernel + +let private evaluates (code: string) (expected: string) = + match execute (bareKernel ()) code with + | ExecutionResult.PlainTextSuccess actual -> Assert.Equal(expected, actual) + | other -> + Assert.True(false, $"expected {expected}, and the kernel answered {other}") + +/// Each of these is a language feature the compiler service has to implement rather than a +/// value the parser can fold, so a mismatched FSharp.Core would show here rather than in +/// arithmetic. Sixteen of sixteen pass on the shipped pair. +[] +// Inference and generics. +[ n * 2) 5", "20")>] +[] +// Type definitions of every shape. +[] +[ n | B -> 0", "7")>] +[] +[] type m\nlet d = 5.0\nfloat d", "5")>] +// Computation expressions and the library that backs them. +[ Async.RunSynchronously", "2")>] +[ Seq.filter (fun x -> x % 7 = 0) |> Seq.length", "14")>] +[ i * i ] |> List.sum", "385")>] +// Pattern matching, including one the compiler generates code for. +[ \"e\" | Odd -> \"o\"", "e")>] +[ List.map (fun (a,b) -> a + b)", "[3; 7]")>] +[ 0 then Some x else None\nOption.defaultValue 0 (f 5)", "5")>] +// Recursion, formatting, interpolation, and an object expression over an interface. +[] +[] +[] +[ with member _.CompareTo o = 0 }\nc.CompareTo 1", "0")>] +let ``The compiler service compiles F#`` (code: string) (expected: string) = + evaluates code expected + +/// And it still refuses what it should, with a position — a compiler that accepted everything +/// would pass the theory above and be useless. +[] +[] +[] +let ``The compiler service reports errors`` (code: string) (expected: string) = + match execute (bareKernel ()) code with + | ExecutionResult.Error message -> + Assert.Contains(expected, message) + // A position, not just a complaint: the Terminal shows these to whoever typed them. + Assert.Contains("input.fsx (1,", message) + | other -> + Assert.True(false, $"expected an error and the kernel answered {other}") + +/// The pairing the warning is about, doing the work the Terminal exists for. +[] +[] +[] +[] +let ``AngouriMath works through the compiler service`` (code: string) (expected: string) = + let kernel = bareKernel () + match enableAngouriMath kernel with + | ExecutionResult.Error reason -> Assert.True(false, $"AngouriMath did not load: {reason}") + | _ -> () + match execute kernel code with + | ExecutionResult.LatexSuccess (_, actual) -> Assert.Equal(expected, actual) + | ExecutionResult.PlainTextSuccess actual -> Assert.Equal(expected, actual) + | other -> Assert.True(false, $"expected {expected}, and the kernel answered {other}") diff --git a/Sources/Tests/TerminalUnitTests/TerminalUnitTests.fsproj b/Sources/Tests/TerminalUnitTests/TerminalUnitTests.fsproj index 96627fbd0..1a3855286 100644 --- a/Sources/Tests/TerminalUnitTests/TerminalUnitTests.fsproj +++ b/Sources/Tests/TerminalUnitTests/TerminalUnitTests.fsproj @@ -9,6 +9,7 @@ +