Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace FSharp.Compiler.ComponentTests.CompilerOptions.fsc

open Xunit
open FSharp.Test
open FSharp.Test.Compiler
open System
open System.IO

module help_options =

// ReqENU SOURCE=dummy.fsx COMPILE_ONLY=1 PRECMD="\$FSC_PIPE >help40.txt -? 2>&1" POSTCMD="\$FSI_PIPE --nologo --quiet --exec ..\\..\\..\\comparer.fsx help40.txt help40.437.1033.bsl" # -?
[<Fact>]
let ``Help - variant 1``() =
FSharp ""
|> asExe
|> withBufferWidth 120
|> withOptions ["-?"]
|> compile
|> verifyOutputWithBaseline (Path.Combine(__SOURCE_DIRECTORY__, "compiler_help_output.bsl"))
|> shouldSucceed

// ReqENU SOURCE=dummy.fsx COMPILE_ONLY=1 PRECMD="\$FSC_PIPE >help40.txt /? 2>&1" POSTCMD="\$FSI_PIPE --nologo --quiet --exec ..\\..\\..\\comparer.fsx help40.txt help40.437.1033.bsl" # --help
[<Fact>]
let ``Help - variant 2``() =
FSharp ""
|> asExe
|> withBufferWidth 120
|> withOptions ["/?"]
|> compile
|> verifyOutputWithBaseline (Path.Combine(__SOURCE_DIRECTORY__, "compiler_help_output.bsl"))
|> shouldSucceed

// ReqENU SOURCE=dummy.fsx COMPILE_ONLY=1 PRECMD="\$FSC_PIPE >help40.txt --help 2>&1" POSTCMD="\$FSI_PIPE --nologo --quiet --exec ..\\..\\..\\comparer.fsx help40.txt help40.437.1033.bsl" # /?
[<Fact>]
let ``Help - variant 3``() =
FSharp ""
|> asExe
|> withBufferWidth 120
|> withOptions ["--help"]
|> compile
|> verifyOutputWithBaseline (Path.Combine(__SOURCE_DIRECTORY__, "compiler_help_output.bsl"))
|> shouldSucceed
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,17 @@ module times =

[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"error_01.fs"|])>]
let ``times - to console`` compilation =
let oldConsole = Console.Out
let sw = new StringWriter()
Console.SetOut(sw)
use _ = {new IDisposable with
member this.Dispose() = Console.SetOut(oldConsole) }

compilation
|> asFsx
|> withBufferWidth 120
|> withOptions ["--times"]
|> ignoreWarnings
|> compile
|> shouldSucceed
|> ignore<CompilationResult>

let consoleContents = sw.ToString()
Assert.Contains("Parse inputs",consoleContents)
Assert.Contains("Typecheck",consoleContents)
Assert.Contains("GC0",consoleContents)
Assert.Contains("Duration",consoleContents)
|> verifyOutputContains [|
"Parse inputs"
"Typecheck"
"GC0"
"Duration"|]


[<Theory(Skip="Flaky in CI due to file being locked, disabling for now until file closure is resolved."); Directory(__SOURCE_DIRECTORY__, Includes=[|"error_01.fs"|])>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
<Compile Include="CompilerOptions\fsc\codepage\codepage.fs" />
<Compile Include="CompilerOptions\fsc\debug.fs" />
<Compile Include="CompilerOptions\fsc\langversion.fs" />
<Compile Include="CompilerOptions\fsc\misc\misc.fs" />
<Compile Include="CompilerOptions\fsc\noframework\noframework.fs" />
<Compile Include="CompilerOptions\fsc\platform\platform.fs" />
<Compile Include="CompilerOptions\fsc\times\times.fs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ open System.Threading
open FSharp.Compiler.Interactive.Shell
open FSharp.Compiler.DependencyManager
open FSharp.Compiler.Diagnostics
open FSharp.Test.ScriptHelpers
open FSharp.DependencyManager.Nuget
open FSharp.Test.ScriptHelpers
open FSharp.Test.Utilities

open Internal.Utilities

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ open System.Threading
open System.Threading.Tasks
open FSharp.Compiler.Interactive.Shell
open FSharp.Test.ScriptHelpers
open FSharp.Test.Utilities

open Xunit

Expand Down
84 changes: 74 additions & 10 deletions tests/FSharp.Test.Utilities/Compiler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ module rec Compiler =
Name: string option
IgnoreWarnings: bool
References: CompilationUnit list
TargetFramework: TargetFramework }
TargetFramework: TargetFramework
}

member this.CreateOutputDirectory() =
match this.OutputDirectory with
Expand Down Expand Up @@ -395,6 +396,9 @@ module rec Compiler =
| FS fs -> FS { fs with OutputDirectory = Some (DirectoryInfo(path)) }
| _ -> failwith "withOutputDirectory is only supported on F#"

let withBufferWidth (width: int)(cUnit: CompilationUnit) : CompilationUnit =
withOptionsHelper [ $"--bufferwidth:{width}" ] "withBufferWidth is only supported on F#" cUnit

let withDefines (defines: string list) (cUnit: CompilationUnit) : CompilationUnit =
withOptionsHelper (defines |> List.map(fun define -> $"--define:{define}")) "withDefines is only supported on F#" cUnit

Expand Down Expand Up @@ -582,18 +586,22 @@ module rec Compiler =

let private compileFSharpCompilation compilation ignoreWarnings (cUnit: CompilationUnit) : CompilationResult =

let ((err: FSharpDiagnostic[], outputFilePath: string), deps) = CompilerAssert.CompileRaw(compilation, ignoreWarnings)
use redirect = new RedirectConsole()
let ((err: FSharpDiagnostic[], rc: int, outputFilePath: string), deps) =
CompilerAssert.CompileRaw(compilation, ignoreWarnings)

// Create and stash the console output
let diagnostics = err |> fromFSharpDiagnostic

let result =
{ OutputPath = None
Dependencies = deps
Adjust = 0
PerFileErrors = diagnostics
Diagnostics = diagnostics |> List.map snd
Output = None
Compilation = cUnit }
let result = {
OutputPath = None
Dependencies = deps
Adjust = 0
PerFileErrors = diagnostics
Diagnostics = diagnostics |> List.map snd
Output = Some (RunOutput.ExecutionOutput { ExitCode = rc; StdOut = redirect.Output(); StdErr = redirect.ErrorOutput() })
Compilation = cUnit
}

let (errors, warnings) = partitionErrors result.Diagnostics

Expand Down Expand Up @@ -1021,6 +1029,62 @@ module rec Compiler =

let verifyBaselines = verifyBaseline >> verifyILBaseline

let normalizeNewlines output =
let regex = new Regex("(\r\n|\r|\n)", RegexOptions.Singleline ||| RegexOptions.ExplicitCapture)
let result = regex.Replace(output, System.Environment.NewLine)
result

let regexStrip output pattern flags =
let regex = new Regex(pattern, flags)
let result = regex.Replace(output, "")
result

let stripEnvironment output =
let pattern = @"(---------------------------------------------------------------(\r\n|\r|\n)).*(\n---------------------------------------------------------------(\r\n|\r|\n))"
let result = regexStrip output pattern (RegexOptions.Singleline ||| RegexOptions.ExplicitCapture)
result

let stripVersion output =
let pattern = @"(Microsoft \(R\) (.*) version (.*) F# (.*))"
let result = regexStrip output pattern (RegexOptions.Multiline ||| RegexOptions.ExplicitCapture)
result

let getOutput (cResult: CompilationResult) : string option =
let result =
match cResult with
| CompilationResult.Failure f -> failwith $"Build failure: {f}"
| CompilationResult.Success output ->
match output.Output with
| Some (EvalOutput _) -> None
| Some (ExecutionOutput eo) ->
match eo.StdOut with
| null -> None
| output -> Some (stripVersion (stripEnvironment (normalizeNewlines output)))
| None -> None
result

let verifyOutput (expected: string) (cResult: CompilationResult) : CompilationResult =
match getOutput cResult with
| None -> cResult
| Some actual ->
let expected = stripVersion (normalizeNewlines expected)
if expected <> actual then
failwith $"""Output does not match expected: ------------{Environment.NewLine}{expected}{Environment.NewLine}Actual: ------------{Environment.NewLine}{actual}{Environment.NewLine}"""
else
cResult

let verifyOutputWithBaseline path =
verifyOutput (File.ReadAllText(path).Replace(@"\r\n", Environment.NewLine))

let verifyOutputContains (expected: string array) (cResult: CompilationResult) : CompilationResult =
match getOutput cResult with
| None -> cResult
| Some actual ->
for item in expected do
if not(actual.Contains(item)) then
failwith $"""Output does not match expected: ------------{Environment.NewLine}{item}{Environment.NewLine}Actual: ------------{Environment.NewLine}{actual}{Environment.NewLine}"""
cResult

type ImportScope = { Kind: ImportDefinitionKind; Name: string }

type PdbVerificationOption =
Expand Down
25 changes: 12 additions & 13 deletions tests/FSharp.Test.Utilities/CompilerAssert.fs
Original file line number Diff line number Diff line change
Expand Up @@ -342,14 +342,13 @@ module rec CompilerAssertHelpers =
yield "-o:" + outputFilePath
yield (if isExe then "--target:exe" else "--target:library")
yield! (defaultProjectOptions targetFramework).OtherOptions
// yield! TargetFrameworkUtil.getFileReferences targetFramework
yield! options
|]

// Generate a response file, purely for diagnostic reasons.
File.WriteAllLines(Path.ChangeExtension(outputFilePath, ".rsp"), args)
let errors, _ = checker.Compile args |> Async.RunImmediate
errors, outputFilePath
let errors, rc = checker.Compile args |> Async.RunImmediate
errors, rc, outputFilePath

let compileDisposable (outputDirectory:DirectoryInfo) isExe options targetFramework nameOpt (sources:SourceCodeFileKind list) =
let disposeFile path =
Expand Down Expand Up @@ -461,11 +460,11 @@ module rec CompilerAssertHelpers =
let tmp = Path.Combine(outputPath.FullName, Path.ChangeExtension(fileName, ".dll"))
disposals.Add({ new IDisposable with member _.Dispose() = File.Delete tmp })
cmpl.EmitAsFile tmp
(([||], tmp), []), false)
(([||], 0, tmp), []), false)

let compilationRefs =
compiledRefs
|> List.map (fun (((errors, outputFilePath), _), staticLink) ->
|> List.map (fun (((errors, _, outputFilePath), _), staticLink) ->
assertErrors 0 ignoreWarnings errors [||]
let rOption = "-r:" + outputFilePath
if staticLink then
Expand All @@ -483,7 +482,7 @@ module rec CompilerAssertHelpers =

compilationRefs, deps

let compileCompilationAux outputDirectory (disposals: ResizeArray<IDisposable>) ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * string) * string list =
let compileCompilationAux outputDirectory (disposals: ResizeArray<IDisposable>) ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * int * string) * string list =

let compilationRefs, deps = evaluateReferences outputDirectory disposals ignoreWarnings cmpl
let isExe, sources, options, targetFramework, name =
Expand Down Expand Up @@ -595,7 +594,7 @@ open CompilerAssertHelpers
type CompilerAssert private () =

static let compileExeAndRunWithOptions options (source: SourceCodeFileKind) =
compile true options source (fun (errors, outputExe) ->
compile true options source (fun (errors, _, outputExe) ->

if errors.Length > 0 then
Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors)
Expand All @@ -604,7 +603,7 @@ type CompilerAssert private () =
)

static let compileLibraryAndVerifyILWithOptions options (source: SourceCodeFileKind) (f: ILVerifier -> unit) =
compile false options source (fun (errors, outputFilePath) ->
compile false options source (fun (errors, _, outputFilePath) ->
let errors =
errors |> Array.filter (fun x -> x.Severity = FSharpDiagnosticSeverity.Error)
if errors.Length > 0 then
Expand All @@ -616,7 +615,7 @@ type CompilerAssert private () =

static let compileLibraryAndVerifyDebugInfoWithOptions options (expectedFile: string) (source: SourceCodeFileKind) =
let options = [| yield! options; yield"--test:DumpDebugInfo" |]
compile false options source (fun (errors, outputFilePath) ->
compile false options source (fun (errors, _, outputFilePath) ->
let errors =
errors |> Array.filter (fun x -> x.Severity = FSharpDiagnosticSeverity.Error)
if errors.Length > 0 then
Expand Down Expand Up @@ -652,7 +651,7 @@ Updated automatically, please check diffs in your pull request, changes must be

static member CompileWithErrors(cmpl: Compilation, expectedErrors, ?ignoreWarnings) =
let ignoreWarnings = defaultArg ignoreWarnings false
compileCompilation ignoreWarnings cmpl (fun ((errors, _), _) ->
compileCompilation ignoreWarnings cmpl (fun ((errors, _, _), _) ->
assertErrors 0 ignoreWarnings errors expectedErrors)

static member Compile(cmpl: Compilation, ?ignoreWarnings) =
Expand Down Expand Up @@ -681,7 +680,7 @@ Updated automatically, please check diffs in your pull request, changes must be
let beforeExecute = defaultArg beforeExecute copyDependenciesToOutputDir
let newProcess = defaultArg newProcess false
let onOutput = defaultArg onOutput (fun _ -> ())
compileCompilation ignoreWarnings cmpl (fun ((errors, outputFilePath), deps) ->
compileCompilation ignoreWarnings cmpl (fun ((errors, _, outputFilePath), deps) ->
assertErrors 0 ignoreWarnings errors [||]
beforeExecute outputFilePath deps
if newProcess then
Expand Down Expand Up @@ -857,12 +856,12 @@ Updated automatically, please check diffs in your pull request, changes must be
CompilerAssert.TypeCheckWithErrors source [| expectedSeverity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |]

static member CompileExeWithOptions(options, (source: SourceCodeFileKind)) =
compile true options source (fun (errors, _) ->
compile true options source (fun (errors, _, _) ->
if errors.Length > 0 then
Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors))

static member CompileExeWithOptions(options, (source: string)) =
compile true options (SourceCodeFileKind.Create("test.fs", source)) (fun (errors, _) ->
compile true options (SourceCodeFileKind.Create("test.fs", source)) (fun (errors, _, _) ->
if errors.Length > 0 then
Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors))

Expand Down
22 changes: 11 additions & 11 deletions tests/FSharp.Test.Utilities/DirectoryAttribute.fs
Original file line number Diff line number Diff line change
Expand Up @@ -121,23 +121,23 @@ type DirectoryAttribute(dir: string) =
let fsBslSource = readFileOrDefault fsBslFilePath
let ilBslSource = readFileOrDefault ilBslFilePath

{
Source = SourceCodeFileKind.Create(sourceFilePath)
AdditionalSources = []
Baseline =
{ Source = SourceCodeFileKind.Create(sourceFilePath)
AdditionalSources = []
Baseline =
Some
{
SourceFilename = Some sourceFilePath
FSBaseline = { FilePath = fsOutFilePath; BslSource=fsBslFilePath; Content = fsBslSource }
ILBaseline = { FilePath = ilOutFilePath; BslSource=ilBslFilePath ; Content = ilBslSource }
}
Options = []
OutputType = Library
Name = Some filename
IgnoreWarnings = false
References = []
OutputDirectory = outputDirectory
TargetFramework = TargetFramework.Current} |> FS
Options = []
OutputType = Library
Name = Some filename
IgnoreWarnings = false
References = []
OutputDirectory = outputDirectory
TargetFramework = TargetFramework.Current
} |> FS

member _.BaselineSuffix with get() = baselineSuffix and set v = baselineSuffix <- v
member _.Includes with get() = includes and set v = includes <- v
Expand Down
Loading