Skip to content

Commit

Permalink
VS Unit test case
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinRansom committed Dec 18, 2019
1 parent d68942f commit 74d04d8
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/fsharp/CompileOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2321,6 +2321,7 @@ type TcConfigBuilder =
isInvalidationSupported = isInvalidationSupported
copyFSharpCore = defaultCopyFSharpCore
tryGetMetadataSnapshot = tryGetMetadataSnapshot
useFsiAuxLib = isInteractive
}

member tcConfigB.ResolveSourceFile(m, nm, pathLoadedFrom) =
Expand Down
2 changes: 1 addition & 1 deletion src/fsharp/service/IncrementalBuild.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1731,7 +1731,7 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
defaultFSharpBinariesDir,
implicitIncludeDir=projectDirectory,
reduceMemoryUsage=ReduceMemoryFlag.Yes,
isInteractive=false,
isInteractive=useScriptResolutionRules,
isInvalidationSupported=true,
defaultCopyFSharpCore=CopyFSharpCoreFlag.No,
tryGetMetadataSnapshot=tryGetMetadataSnapshot)
Expand Down
2 changes: 1 addition & 1 deletion tests/service/ExprTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1060,7 +1060,7 @@ let ``Test Operator Declarations for Byte`` () =
"let testByteToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,43--54,53)";
"let testByteToCharOperator(e1) = Operators.ToChar<Microsoft.FSharp.Core.byte> (e1) @ (55,43--55,50)";
"let testByteToStringOperator(e1) = let matchValue: Microsoft.FSharp.Core.obj = Operators.Box<Microsoft.FSharp.Core.byte> (e1) in match (if Operators.op_Equality<Microsoft.FSharp.Core.obj> (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... @ (56,43--56,52)";
]
]

testOperators "Byte" "byte" excludedTests expectedUnoptimized expectedOptimized

Expand Down
136 changes: 136 additions & 0 deletions vsintegration/tests/UnitTests/FsxCompletionProviderTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@

// To run the tests in this file:
//
// Technique 1: Compile VisualFSharp.UnitTests.dll and run it as a set of unit tests
//
// Technique 2:
//
// Enable some tests in the #if EXE section at the end of the file,
// then compile this file as an EXE that has InternalsVisibleTo access into the
// appropriate DLLs. This can be the quickest way to get turnaround on updating the tests
// and capturing large amounts of structured output.
(*
cd Debug\net40\bin
.\fsc.exe --define:EXE -r:.\Microsoft.Build.Utilities.Core.dll -o VisualFSharp.UnitTests.exe -g --optimize- -r .\FSharp.Compiler.Private.dll -r .\FSharp.Editor.dll -r nunit.framework.dll ..\..\..\tests\service\FsUnit.fs ..\..\..\tests\service\Common.fs /delaysign /keyfile:..\..\..\src\fsharp\msft.pubkey ..\..\..\vsintegration\tests\UnitTests\FsxCompletionProviderTests.fs
.\VisualFSharp.UnitTests.exe
*)
// Technique 3:
//
// Use F# Interactive. This only works for FSharp.Compiler.Service.dll which has a public API

// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
module Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn.FsxCompletionProviderTests

open System
open System.Linq

open NUnit.Framework

open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Completion
open Microsoft.CodeAnalysis.Text
open Microsoft.VisualStudio.FSharp.Editor

open FSharp.Compiler.SourceCodeServices
open UnitTests.TestLib.LanguageService

let filePath = "C:\\test.fsx"
let internal projectOptions = {
ProjectFileName = "C:\\test.fsproj"
ProjectId = None
SourceFiles = [| filePath |]
ReferencedProjects = [| |]
OtherOptions = [| |]
IsIncompleteTypeCheckEnvironment = true
UseScriptResolutionRules = true
LoadTime = DateTime.MaxValue
OriginalLoadReferences = []
UnresolvedReferences = None
ExtraProjectInfo = None
Stamp = None
}

let formatCompletions(completions : string seq) =
"\n\t" + String.Join("\n\t", completions)

let VerifyCompletionList(fileContents: string, marker: string, expected: string list, unexpected: string list) =
let caretPosition = fileContents.IndexOf(marker) + marker.Length
let results =
FSharpCompletionProvider.ProvideCompletionsAsyncAux(checker, SourceText.From(fileContents), caretPosition, projectOptions, filePath, 0, (fun _ -> []), LanguageServicePerformanceOptions.Default, IntelliSenseOptions.Default)
|> Async.RunSynchronously
|> Option.defaultValue (ResizeArray())
|> Seq.map(fun result -> result.DisplayText)

let expectedFound =
expected
|> Seq.filter results.Contains

let expectedNotFound =
expected
|> Seq.filter (expectedFound.Contains >> not)

let unexpectedNotFound =
unexpected
|> Seq.filter (results.Contains >> not)

let unexpectedFound =
unexpected
|> Seq.filter (unexpectedNotFound.Contains >> not)

// If either of these are true, then the test fails.
let hasExpectedNotFound = not (Seq.isEmpty expectedNotFound)
let hasUnexpectedFound = not (Seq.isEmpty unexpectedFound)

if hasExpectedNotFound || hasUnexpectedFound then
let expectedNotFoundMsg =
if hasExpectedNotFound then
sprintf "\nExpected completions not found:%s\n" (formatCompletions expectedNotFound)
else
String.Empty

let unexpectedFoundMsg =
if hasUnexpectedFound then
sprintf "\nUnexpected completions found:%s\n" (formatCompletions unexpectedFound)
else
String.Empty

let completionsMsg = sprintf "\nin Completions:%s" (formatCompletions results)

let msg = sprintf "%s%s%s" expectedNotFoundMsg unexpectedFoundMsg completionsMsg

Assert.Fail(msg)

let VerifyCompletionListExactly(fileContents: string, marker: string, expected: string list) =
let caretPosition = fileContents.IndexOf(marker) + marker.Length

let actual =
let x = FSharpCompletionProvider.ProvideCompletionsAsyncAux(checker, SourceText.From(fileContents), caretPosition, projectOptions, filePath, 0, (fun _ -> []), LanguageServicePerformanceOptions.Default, IntelliSenseOptions.Default)
|> Async.RunSynchronously
x |> Option.defaultValue (ResizeArray())
|> Seq.toList
// sort items as Roslyn do - by `SortText`
|> List.sortBy (fun x -> x.SortText)

let actualNames = actual |> List.map (fun x -> x.DisplayText)

if actualNames <> expected then
Assert.Fail(sprintf "Expected:\n%s,\nbut was:\n%s\nactual with sort text:\n%s"
(String.Join("; ", expected |> List.map (sprintf "\"%s\"")))
(String.Join("; ", actualNames |> List.map (sprintf "\"%s\"")))
(String.Join("\n", actual |> List.map (fun x -> sprintf "%s => %s" x.DisplayText x.SortText))))

[<Test>]
let ShouldTriggerCompletionInFsxFile() =
let fileContents = """
fsi.
"""
let expected = ["CommandLineArgs"; "EventLoop"; "FloatingPointFormat"; "FormatProvider"; "PrintDepth";
"PrintLength"; "PrintSize"; "PrintWidth"; "ShowDeclarationValues"; "ShowIEnumerable";
"ShowProperties"; "AddPrinter"; "AddPrintTransformer"; "Equals"; "GetHashCode";
"GetType"; "ToString"; ]
VerifyCompletionListExactly(fileContents, "fsi.", expected)


#if EXE
ShouldTriggerCompletionInFsxFile()
#endif
3 changes: 3 additions & 0 deletions vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@
<Compile Include="CompletionProviderTests.fs">
<Link>Roslyn\CompletionProviderTests.fs</Link>
</Compile>
<Compile Include="FsxCompletionProviderTests.fs">
<Link>Roslyn\FsxCompletionProviderTests.fs</Link>
</Compile>
<Compile Include="SignatureHelpProviderTests.fs">
<Link>Roslyn\SignatureHelpProviderTests.fs</Link>
</Compile>
Expand Down

0 comments on commit 74d04d8

Please sign in to comment.