Skip to content

Commit 0b91207

Browse files
techiedesuT-Gro
andauthored
Add compiler options parser tests (#13878) (#19554)
ParserErrors.fs — horizontal error handling coverage: missing arguments (error 224), invalid integer arguments (error 241), out-of-range warn level (error 1050), unrecognized target (error 1048), unsupported checksum algorithm (error 1065), unrecognized options (error 243). UncoveredOptions.fs — smoke tests for options without dedicated coverage: switch options (+/-), unit options, valid string values, compilation modes, diagnostic options. Co-authored-by: Tomas Grosup <Tomas.Grosup@gmail.com>
1 parent 6e6833a commit 0b91207

3 files changed

Lines changed: 228 additions & 0 deletions

File tree

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespace CompilerOptions.Fsc
4+
5+
open Xunit
6+
open FSharp.Test.Compiler
7+
8+
/// Tests for compiler options parser error handling across many options
9+
module ParserErrors =
10+
11+
// =================================================================
12+
// Missing argument — options that require a parameter (error 224)
13+
// =================================================================
14+
15+
[<Theory>]
16+
[<InlineData("--out")>]
17+
[<InlineData("--doc")>]
18+
[<InlineData("--keyfile")>]
19+
[<InlineData("--platform")>]
20+
[<InlineData("--win32icon")>]
21+
[<InlineData("--win32res")>]
22+
[<InlineData("--win32manifest")>]
23+
[<InlineData("--resource")>]
24+
[<InlineData("--linkresource")>]
25+
[<InlineData("--baseaddress")>]
26+
[<InlineData("--pdb")>]
27+
[<InlineData("--lib")>]
28+
[<InlineData("--codepage")>]
29+
[<InlineData("--sourcelink")>]
30+
[<InlineData("--subsystemversion")>]
31+
[<InlineData("--checksumalgorithm")>]
32+
[<InlineData("--define")>]
33+
[<InlineData("--warn")>]
34+
[<InlineData("--maxerrors")>]
35+
let ``options requiring a parameter produce error 224 when missing`` (option: string) =
36+
Fs """module M"""
37+
|> withOptions [option]
38+
|> compile
39+
|> shouldFail
40+
|> withErrorCode 224
41+
|> withDiagnosticMessageMatches "Option requires parameter"
42+
|> ignore
43+
44+
// =================================================================
45+
// Invalid integer argument — options expecting int get a non-integer
46+
// =================================================================
47+
48+
[<Theory>]
49+
[<InlineData("--maxerrors:xyz")>]
50+
[<InlineData("--codepage:abc")>]
51+
let ``int options with non-integer argument produce error 241`` (option: string) =
52+
Fs """module M"""
53+
|> withOptions [option]
54+
|> compile
55+
|> shouldFail
56+
|> withErrorCode 241
57+
|> withDiagnosticMessageMatches "is not a valid integer argument"
58+
|> ignore
59+
60+
// =================================================================
61+
// Invalid warn level — out of valid range 0-5
62+
// =================================================================
63+
64+
[<Fact>]
65+
let ``warn with negative level produces error 1050`` () =
66+
Fs """module M"""
67+
|> withOptions ["--warn:-1"]
68+
|> compile
69+
|> shouldFail
70+
|> withErrorCode 1050
71+
|> withDiagnosticMessageMatches "Invalid warning level"
72+
|> ignore
73+
74+
// =================================================================
75+
// Invalid target value
76+
// =================================================================
77+
78+
[<Fact>]
79+
let ``target with unrecognized value produces error 1048`` () =
80+
Fs """module M"""
81+
|> withOptions ["--target:dll"]
82+
|> compile
83+
|> shouldFail
84+
|> withErrorCode 1048
85+
|> withDiagnosticMessageMatches "Unrecognized target"
86+
|> ignore
87+
88+
// =================================================================
89+
// Invalid checksum algorithm
90+
// =================================================================
91+
92+
[<Fact>]
93+
let ``checksumalgorithm with unsupported algorithm produces error 1065`` () =
94+
Fs """module M"""
95+
|> withOptions ["--checksumalgorithm:MD5"]
96+
|> compile
97+
|> shouldFail
98+
|> withErrorCode 1065
99+
|> withDiagnosticMessageMatches "Algorithm.*is not supported"
100+
|> ignore
101+
102+
// =================================================================
103+
// Unrecognized option (error 243)
104+
// =================================================================
105+
106+
[<Theory>]
107+
[<InlineData("--nonexistent")>]
108+
[<InlineData("--Optimize")>] // case-sensitive: --optimize (parsed as --optimize+) works, --Optimize does not
109+
[<InlineData("---debug")>]
110+
let ``unrecognized options produce error 243`` (option: string) =
111+
Fs """module M"""
112+
|> withOptions [option]
113+
|> compile
114+
|> shouldFail
115+
|> withErrorCode 243
116+
|> withDiagnosticMessageMatches "Unrecognized option"
117+
|> ignore
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespace CompilerOptions.Fsc
4+
5+
open Xunit
6+
open FSharp.Test.Compiler
7+
8+
/// Smoke tests for compiler options that have no dedicated test coverage
9+
module UncoveredOptions =
10+
11+
// =================================================================
12+
// Switch options (+/-) — verify parser accepts both polarities
13+
// =================================================================
14+
15+
[<Theory>]
16+
[<InlineData("--realsig+")>]
17+
[<InlineData("--realsig-")>]
18+
[<InlineData("--compressmetadata+")>]
19+
[<InlineData("--compressmetadata-")>]
20+
[<InlineData("--checknulls+")>]
21+
[<InlineData("--checknulls-")>]
22+
[<InlineData("--strict-indentation+")>]
23+
[<InlineData("--strict-indentation-")>]
24+
[<InlineData("--quotations-debug+")>]
25+
[<InlineData("--quotations-debug-")>]
26+
[<InlineData("--tailcalls+")>]
27+
[<InlineData("--tailcalls-")>]
28+
[<InlineData("--deterministic+")>]
29+
[<InlineData("--deterministic-")>]
30+
let ``switch options are accepted by the parser`` (option: string) =
31+
Fs """module M"""
32+
|> withOptions [option]
33+
|> ignoreWarnings
34+
|> typecheck
35+
|> shouldSucceed
36+
|> ignore
37+
38+
// =================================================================
39+
// Unit options (no argument) — verify parser accepts them
40+
// =================================================================
41+
42+
[<Theory>]
43+
[<InlineData("--nooptimizationdata")>]
44+
[<InlineData("--nointerfacedata")>]
45+
[<InlineData("--nocopyfsharpcore")>]
46+
[<InlineData("--nowin32manifest")>]
47+
[<InlineData("--allsigs")>] // typecheck only — compile would write .fsi files
48+
[<InlineData("--utf8output")>]
49+
[<InlineData("--fullpaths")>]
50+
let ``unit options are accepted by the parser`` (option: string) =
51+
Fs """module M"""
52+
|> withOptions [option]
53+
|> ignoreWarnings
54+
|> typecheck
55+
|> shouldSucceed
56+
|> ignore
57+
58+
// =================================================================
59+
// String options with valid values — verify parser + compilation
60+
// =================================================================
61+
62+
[<Theory>]
63+
[<InlineData("SHA1")>]
64+
[<InlineData("SHA256")>]
65+
let ``checksumalgorithm with valid algorithm is accepted`` (algorithm: string) =
66+
Fs """module M"""
67+
|> withOptions [$"--checksumalgorithm:{algorithm}"]
68+
|> compile
69+
|> shouldSucceed
70+
|> ignore
71+
72+
[<Theory>]
73+
[<InlineData("--target:exe")>]
74+
[<InlineData("--target:winexe")>]
75+
[<InlineData("--target:library")>]
76+
[<InlineData("--target:module")>]
77+
let ``target with valid values is accepted`` (option: string) =
78+
Fs """module M"""
79+
|> withOptions [option]
80+
|> ignoreWarnings
81+
|> compile
82+
|> shouldSucceed
83+
|> ignore
84+
85+
// =================================================================
86+
// Compilation modes
87+
// =================================================================
88+
89+
[<Fact>]
90+
let ``parseonly does not report type errors`` () =
91+
Fs """let x: int = "not an int" """
92+
|> asExe
93+
|> withOptions ["--parseonly"]
94+
|> ignoreWarnings
95+
|> compile
96+
|> shouldSucceed
97+
|> ignore
98+
99+
// =================================================================
100+
// Diagnostic format options
101+
// =================================================================
102+
103+
[<Fact>]
104+
let ``maxerrors with valid value is accepted`` () =
105+
Fs """module M"""
106+
|> withOptions ["--maxerrors:10"]
107+
|> compile
108+
|> shouldSucceed
109+
|> ignore

tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@
418418
<Compile Include="CompilerOptions\fsc\sourceFiles.fs" />
419419
<Compile Include="CompilerOptions\Fsc\FscCliTests.fs" />
420420
<Compile Include="CompilerOptions\Fsc\Removed.fs" />
421+
<Compile Include="CompilerOptions\Fsc\ParserErrors.fs" />
422+
<Compile Include="CompilerOptions\Fsc\UncoveredOptions.fs" />
421423
<Compile Include="CompilerOptions\Fsc\responsefile\responsefile.fs" />
422424
<Compile Include="CompilerOptions\fsc\standalone\standalone.fs" />
423425
<Compile Include="CompilerOptions\fsc\dumpAllCommandLineOptions\dumpAllCommandLineOptions.fs" />

0 commit comments

Comments
 (0)