Skip to content

Commit 67e228e

Browse files
committed
Add FSI options tests and wire up CLI test infrastructure
Add runFsiProcess/runFscProcess subprocess helpers to Compiler.fs and include the existing CLI test files (FsiCliTests.fs, FscCliTests.fs, CliProcessTests.fs) in the project build. Add 19 new tests covering --quiet, --exec, --use, --load, --gui, --readline, --quotations-debug, --shadowcopyreferences, --nologo, and error cases for unknown options and invalid --warn levels. Contributes to #13878
1 parent 6479611 commit 67e228e

3 files changed

Lines changed: 201 additions & 2 deletions

File tree

tests/FSharp.Compiler.ComponentTests/CompilerOptions/Fsc/FscCliTests.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module FscCliTests =
3434
/// Original: SOURCE="E_MissingSourceFile02.fs X:\doesnotexist.fs"
3535
/// Expected: //<Expects id="FS0225" status="error">Source file ['"].+['"] could not be found</Expects>
3636
/// CLI Test: FSC with non-existent absolute path (Windows-style)
37-
[<FactForWINDOWS>]
37+
[<FactForDESKTOP>]
3838
let ``fsc missing source file - absolute Windows path reports FS0225`` () =
3939
let result = runFscProcess ["X:\\doesnotexist.fs"]
4040
Assert.NotEqual(0, result.ExitCode)
@@ -54,7 +54,7 @@ module FscCliTests =
5454
/// Original: SOURCE="E_MissingSourceFile03.fs \\qwerty\y\doesnotexist.fs"
5555
/// Expected: //<Expects id="FS0225" status="error">Source file ['"].+['"] could not be found</Expects>
5656
/// CLI Test: FSC with non-existent UNC path
57-
[<FactForWINDOWS>]
57+
[<FactForDESKTOP>]
5858
let ``fsc missing source file - UNC path reports FS0225`` () =
5959
let result = runFscProcess ["\\\\qwerty\\y\\doesnotexist.fs"]
6060
Assert.NotEqual(0, result.ExitCode)

tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsi/FsiCliTests.fs

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace CompilerOptions.Fsi
44

5+
open System
6+
open System.IO
57
open Xunit
68
open FSharp.Test
79
open FSharp.Test.Compiler
@@ -67,3 +69,197 @@ module FsiCliTests =
6769
let result = runFsiProcess [option]
6870
Assert.NotEqual(0, result.ExitCode)
6971
Assert.Contains(expectedError, result.StdErr)
72+
73+
// ============================================================================
74+
// --quiet option tests
75+
// ============================================================================
76+
77+
/// CLI Test: --quiet suppresses the banner
78+
[<Fact>]
79+
let ``fsi quiet - suppresses banner`` () =
80+
let result = runFsiProcess ["--quiet"; "--exec"; "--nologo"]
81+
Assert.Equal(0, result.ExitCode)
82+
Assert.DoesNotContain("Microsoft (R) F# Interactive", result.StdOut)
83+
84+
/// In-process test: --quiet suppresses feedback output but expressions still evaluate
85+
[<Fact>]
86+
let ``fsi quiet - expressions evaluate correctly`` () =
87+
Fsx """let x = 1 + 1"""
88+
|> withOptions ["--quiet"]
89+
|> runFsi
90+
|> shouldSucceed
91+
92+
// ============================================================================
93+
// --exec option tests
94+
// ============================================================================
95+
96+
/// CLI Test: --exec causes FSI to exit after evaluating (no interactive prompt)
97+
[<Fact>]
98+
let ``fsi exec - exits after evaluating script`` () =
99+
let tmpFile = Path.Combine(Path.GetTempPath(), $"fsi_exec_test_{Guid.NewGuid()}.fsx")
100+
try
101+
File.WriteAllText(tmpFile, "printfn \"hello from exec\"")
102+
let result = runFsiProcess ["--exec"; "--nologo"; tmpFile]
103+
Assert.Equal(0, result.ExitCode)
104+
Assert.Contains("hello from exec", result.StdOut)
105+
finally
106+
try File.Delete(tmpFile) with _ -> ()
107+
108+
// ============================================================================
109+
// --use option tests
110+
// ============================================================================
111+
112+
/// CLI Test: --use:file.fsx loads and executes a script file
113+
[<Fact>]
114+
let ``fsi use - loads and executes script file`` () =
115+
let tmpFile = Path.Combine(Path.GetTempPath(), $"fsi_use_test_{Guid.NewGuid()}.fsx")
116+
try
117+
File.WriteAllText(tmpFile, "printfn \"loaded via use\"")
118+
let result = runFsiProcess ["--nologo"; "--exec"; $"--use:{tmpFile}"]
119+
Assert.Equal(0, result.ExitCode)
120+
Assert.Contains("loaded via use", result.StdOut)
121+
finally
122+
try File.Delete(tmpFile) with _ -> ()
123+
124+
/// CLI Test: --use with nonexistent file produces error
125+
[<Fact>]
126+
let ``fsi use - nonexistent file produces error`` () =
127+
let result = runFsiProcess ["--exec"; "--use:nonexistent_file_xyz.fsx"]
128+
Assert.NotEqual(0, result.ExitCode)
129+
130+
// ============================================================================
131+
// --load option tests
132+
// ============================================================================
133+
134+
/// CLI Test: --load:file.fsx loads a file (definitions available)
135+
[<Fact>]
136+
let ``fsi load - loads file definitions`` () =
137+
let tmpFile = Path.Combine(Path.GetTempPath(), $"fsi_load_test_{Guid.NewGuid()}.fsx")
138+
try
139+
File.WriteAllText(tmpFile, "let loadedValue = 42")
140+
let result = runFsiProcess ["--nologo"; "--exec"; $"--load:{tmpFile}"]
141+
Assert.Equal(0, result.ExitCode)
142+
finally
143+
try File.Delete(tmpFile) with _ -> ()
144+
145+
/// CLI Test: --load with nonexistent file produces error
146+
[<Fact>]
147+
let ``fsi load - nonexistent file produces error`` () =
148+
let result = runFsiProcess ["--exec"; "--load:nonexistent_file_xyz.fsx"]
149+
Assert.NotEqual(0, result.ExitCode)
150+
151+
// ============================================================================
152+
// --gui option tests (switch: +/-)
153+
// ============================================================================
154+
155+
/// CLI Test: --gui- is accepted without error
156+
[<Fact>]
157+
let ``fsi gui - gui minus accepted`` () =
158+
Fsx """1+1"""
159+
|> withOptions ["--gui-"]
160+
|> runFsi
161+
|> shouldSucceed
162+
163+
/// CLI Test: --gui+ is accepted without error
164+
[<Fact>]
165+
let ``fsi gui - gui plus accepted`` () =
166+
Fsx """1+1"""
167+
|> withOptions ["--gui+"]
168+
|> runFsi
169+
|> shouldSucceed
170+
171+
// ============================================================================
172+
// --readline option tests (switch: +/-)
173+
// ============================================================================
174+
175+
/// CLI Test: --readline- is accepted without error
176+
[<Fact>]
177+
let ``fsi readline - readline minus accepted`` () =
178+
Fsx """1+1"""
179+
|> withOptions ["--readline-"]
180+
|> runFsi
181+
|> shouldSucceed
182+
183+
/// CLI Test: --readline+ is accepted without error
184+
[<Fact>]
185+
let ``fsi readline - readline plus accepted`` () =
186+
Fsx """1+1"""
187+
|> withOptions ["--readline+"]
188+
|> runFsi
189+
|> shouldSucceed
190+
191+
// ============================================================================
192+
// --quotations-debug option tests (switch: +/-)
193+
// ============================================================================
194+
195+
/// CLI Test: --quotations-debug+ is accepted without error
196+
[<Fact>]
197+
let ``fsi quotations-debug - plus accepted`` () =
198+
Fsx """1+1"""
199+
|> withOptions ["--quotations-debug+"]
200+
|> runFsi
201+
|> shouldSucceed
202+
203+
/// CLI Test: --quotations-debug- is accepted without error
204+
[<Fact>]
205+
let ``fsi quotations-debug - minus accepted`` () =
206+
Fsx """1+1"""
207+
|> withOptions ["--quotations-debug-"]
208+
|> runFsi
209+
|> shouldSucceed
210+
211+
// ============================================================================
212+
// --shadowcopyreferences option tests (switch: +/-)
213+
// ============================================================================
214+
215+
/// CLI Test: --shadowcopyreferences+ is accepted without error
216+
[<Fact>]
217+
let ``fsi shadowcopyreferences - plus accepted`` () =
218+
Fsx """1+1"""
219+
|> withOptions ["--shadowcopyreferences+"]
220+
|> runFsi
221+
|> shouldSucceed
222+
223+
/// CLI Test: --shadowcopyreferences- is accepted without error
224+
[<Fact>]
225+
let ``fsi shadowcopyreferences - minus accepted`` () =
226+
Fsx """1+1"""
227+
|> withOptions ["--shadowcopyreferences-"]
228+
|> runFsi
229+
|> shouldSucceed
230+
231+
// ============================================================================
232+
// --nologo option tests
233+
// ============================================================================
234+
235+
/// CLI Test: --nologo suppresses the banner
236+
[<Fact>]
237+
let ``fsi nologo - suppresses banner in subprocess`` () =
238+
let result = runFsiProcess ["--nologo"; "--exec"]
239+
Assert.Equal(0, result.ExitCode)
240+
Assert.DoesNotContain("Microsoft (R) F# Interactive", result.StdOut)
241+
242+
/// In-process test: FSI without --nologo shows the banner
243+
[<Fact>]
244+
let ``fsi nologo - without nologo shows banner`` () =
245+
Fsx """1+1"""
246+
|> runFsi
247+
|> shouldSucceed
248+
|> withStdOutContains "Microsoft"
249+
250+
// ============================================================================
251+
// Additional error case tests
252+
// ============================================================================
253+
254+
/// CLI Test: completely unknown option produces FS0243
255+
[<Fact>]
256+
let ``fsi error - unknown option produces FS0243`` () =
257+
let result = runFsiProcess ["--not-a-real-option"]
258+
Assert.NotEqual(0, result.ExitCode)
259+
Assert.Contains("Unrecognized option: '--not-a-real-option'", result.StdErr)
260+
261+
/// CLI Test: --warn with invalid level produces error
262+
[<Fact>]
263+
let ``fsi error - invalid warn level produces error`` () =
264+
let result = runFsiProcess ["--warn:invalid"; "--exec"]
265+
Assert.NotEqual(0, result.ExitCode)

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,9 @@
430430
<Compile Include="CompilerOptions\fsi\FsiCliTests.fs" />
431431
<Compile Include="CompilerOptions\fsi\Nologo.fs" />
432432
<Compile Include="CompilerOptions\fsi\Langversion.fs" />
433+
<Compile Include="CompilerOptions\fsc\FscCliTests.fs" />
434+
<Compile Include="CompilerOptions\fsi\FsiCliTests.fs" />
435+
<Compile Include="CompilerOptions\CliProcessTests.fs" />
433436
<Compile Include="CompilerService\RangeModule.fs" />
434437
<Compile Include="CompilerService\Caches.fs" />
435438
<Compile Include="CompilerService\LruCache.fs" />

0 commit comments

Comments
 (0)