Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace CompilerOptions.Fsc

open Xunit
open FSharp.Test.Compiler

/// Tests for compiler options parser error handling across many options
module ParserErrors =

// =================================================================
// Missing argument — options that require a parameter (error 224)
// =================================================================

[<Theory>]
[<InlineData("--out")>]
[<InlineData("--doc")>]
[<InlineData("--keyfile")>]
[<InlineData("--platform")>]
[<InlineData("--win32icon")>]
[<InlineData("--win32res")>]
[<InlineData("--win32manifest")>]
[<InlineData("--resource")>]
[<InlineData("--linkresource")>]
[<InlineData("--baseaddress")>]
[<InlineData("--pdb")>]
[<InlineData("--lib")>]
[<InlineData("--codepage")>]
[<InlineData("--sourcelink")>]
[<InlineData("--subsystemversion")>]
[<InlineData("--checksumalgorithm")>]
[<InlineData("--define")>]
[<InlineData("--warn")>]
[<InlineData("--maxerrors")>]
let ``options requiring a parameter produce error 224 when missing`` (option: string) =
Fs """module M"""
|> withOptions [option]
|> compile
|> shouldFail
|> withErrorCode 224
|> withDiagnosticMessageMatches "Option requires parameter"
|> ignore

// =================================================================
// Invalid integer argument — options expecting int get a non-integer
// =================================================================

[<Theory>]
[<InlineData("--maxerrors:xyz")>]
[<InlineData("--codepage:abc")>]
let ``int options with non-integer argument produce error 241`` (option: string) =
Fs """module M"""
|> withOptions [option]
|> compile
|> shouldFail
|> withErrorCode 241
|> withDiagnosticMessageMatches "is not a valid integer argument"
|> ignore

// =================================================================
// Invalid warn level — out of valid range 0-5
// =================================================================

[<Fact>]
let ``warn with negative level produces error 1050`` () =
Fs """module M"""
|> withOptions ["--warn:-1"]
|> compile
|> shouldFail
|> withErrorCode 1050
|> withDiagnosticMessageMatches "Invalid warning level"
|> ignore

// =================================================================
// Invalid target value
// =================================================================

[<Fact>]
let ``target with unrecognized value produces error 1048`` () =
Fs """module M"""
|> withOptions ["--target:dll"]
|> compile
|> shouldFail
|> withErrorCode 1048
|> withDiagnosticMessageMatches "Unrecognized target"
|> ignore

// =================================================================
// Invalid checksum algorithm
// =================================================================

[<Fact>]
let ``checksumalgorithm with unsupported algorithm produces error 1065`` () =
Fs """module M"""
|> withOptions ["--checksumalgorithm:MD5"]
|> compile
|> shouldFail
|> withErrorCode 1065
|> withDiagnosticMessageMatches "Algorithm.*is not supported"
|> ignore

// =================================================================
// Unrecognized option (error 243)
// =================================================================

[<Theory>]
[<InlineData("--nonexistent")>]
[<InlineData("--Optimize")>] // case-sensitive: --optimize (parsed as --optimize+) works, --Optimize does not
[<InlineData("---debug")>]
let ``unrecognized options produce error 243`` (option: string) =
Fs """module M"""
|> withOptions [option]
|> compile
|> shouldFail
|> withErrorCode 243
|> withDiagnosticMessageMatches "Unrecognized option"
|> ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace CompilerOptions.Fsc

open Xunit
open FSharp.Test.Compiler

/// Smoke tests for compiler options that have no dedicated test coverage
module UncoveredOptions =

// =================================================================
// Switch options (+/-) — verify parser accepts both polarities
// =================================================================

[<Theory>]
[<InlineData("--realsig+")>]
[<InlineData("--realsig-")>]
[<InlineData("--compressmetadata+")>]
[<InlineData("--compressmetadata-")>]
[<InlineData("--checknulls+")>]
[<InlineData("--checknulls-")>]
[<InlineData("--strict-indentation+")>]
[<InlineData("--strict-indentation-")>]
[<InlineData("--quotations-debug+")>]
[<InlineData("--quotations-debug-")>]
[<InlineData("--tailcalls+")>]
[<InlineData("--tailcalls-")>]
[<InlineData("--deterministic+")>]
[<InlineData("--deterministic-")>]
let ``switch options are accepted by the parser`` (option: string) =
Fs """module M"""
|> withOptions [option]
|> ignoreWarnings
|> typecheck
|> shouldSucceed
|> ignore

// =================================================================
// Unit options (no argument) — verify parser accepts them
// =================================================================

[<Theory>]
[<InlineData("--nooptimizationdata")>]
[<InlineData("--nointerfacedata")>]
[<InlineData("--nocopyfsharpcore")>]
[<InlineData("--nowin32manifest")>]
[<InlineData("--allsigs")>] // typecheck only — compile would write .fsi files
[<InlineData("--utf8output")>]
[<InlineData("--fullpaths")>]
let ``unit options are accepted by the parser`` (option: string) =
Fs """module M"""
|> withOptions [option]
|> ignoreWarnings
|> typecheck
|> shouldSucceed
|> ignore

// =================================================================
// String options with valid values — verify parser + compilation
// =================================================================

[<Theory>]
[<InlineData("SHA1")>]
[<InlineData("SHA256")>]
let ``checksumalgorithm with valid algorithm is accepted`` (algorithm: string) =
Fs """module M"""
|> withOptions [$"--checksumalgorithm:{algorithm}"]
|> compile
|> shouldSucceed
|> ignore

[<Theory>]
[<InlineData("--target:exe")>]
[<InlineData("--target:winexe")>]
[<InlineData("--target:library")>]
[<InlineData("--target:module")>]
let ``target with valid values is accepted`` (option: string) =
Fs """module M"""
|> withOptions [option]
|> ignoreWarnings
|> compile
|> shouldSucceed
|> ignore

// =================================================================
// Compilation modes
// =================================================================

[<Fact>]
let ``parseonly does not report type errors`` () =
Fs """let x: int = "not an int" """
|> asExe
|> withOptions ["--parseonly"]
|> ignoreWarnings
|> compile
|> shouldSucceed
|> ignore

// =================================================================
// Diagnostic format options
// =================================================================

[<Fact>]
let ``maxerrors with valid value is accepted`` () =
Fs """module M"""
|> withOptions ["--maxerrors:10"]
|> compile
|> shouldSucceed
|> ignore
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,8 @@
<Compile Include="CompilerOptions\fsc\sourceFiles.fs" />
<Compile Include="CompilerOptions\Fsc\FscCliTests.fs" />
<Compile Include="CompilerOptions\Fsc\Removed.fs" />
<Compile Include="CompilerOptions\Fsc\ParserErrors.fs" />
<Compile Include="CompilerOptions\Fsc\UncoveredOptions.fs" />
<Compile Include="CompilerOptions\Fsc\responsefile\responsefile.fs" />
<Compile Include="CompilerOptions\fsc\standalone\standalone.fs" />
<Compile Include="CompilerOptions\fsc\dumpAllCommandLineOptions\dumpAllCommandLineOptions.fs" />
Expand Down
Loading