|
2 | 2 |
|
3 | 3 | namespace CompilerOptions.Fsi |
4 | 4 |
|
| 5 | +open System |
| 6 | +open System.IO |
5 | 7 | open Xunit |
6 | 8 | open FSharp.Test |
7 | 9 | open FSharp.Test.Compiler |
@@ -110,3 +112,197 @@ module FsiCliTests = |
110 | 112 | // FSI should report error for unrecognized option |
111 | 113 | Assert.NotEqual(0, result.ExitCode) |
112 | 114 | Assert.Contains("Unrecognized option: '--subsystemversion'", result.StdErr) |
| 115 | + |
| 116 | + // ============================================================================ |
| 117 | + // --quiet option tests |
| 118 | + // ============================================================================ |
| 119 | + |
| 120 | + /// CLI Test: --quiet suppresses the banner |
| 121 | + [<Fact>] |
| 122 | + let ``fsi quiet - suppresses banner`` () = |
| 123 | + let result = runFsiProcess ["--quiet"; "--exec"; "--nologo"] |
| 124 | + Assert.Equal(0, result.ExitCode) |
| 125 | + Assert.DoesNotContain("Microsoft (R) F# Interactive", result.StdOut) |
| 126 | + |
| 127 | + /// In-process test: --quiet suppresses feedback output but expressions still evaluate |
| 128 | + [<Fact>] |
| 129 | + let ``fsi quiet - expressions evaluate correctly`` () = |
| 130 | + Fsx """let x = 1 + 1""" |
| 131 | + |> withOptions ["--quiet"] |
| 132 | + |> runFsi |
| 133 | + |> shouldSucceed |
| 134 | + |
| 135 | + // ============================================================================ |
| 136 | + // --exec option tests |
| 137 | + // ============================================================================ |
| 138 | + |
| 139 | + /// CLI Test: --exec causes FSI to exit after evaluating (no interactive prompt) |
| 140 | + [<Fact>] |
| 141 | + let ``fsi exec - exits after evaluating script`` () = |
| 142 | + let tmpFile = Path.Combine(Path.GetTempPath(), $"fsi_exec_test_{Guid.NewGuid()}.fsx") |
| 143 | + try |
| 144 | + File.WriteAllText(tmpFile, "printfn \"hello from exec\"") |
| 145 | + let result = runFsiProcess ["--exec"; "--nologo"; tmpFile] |
| 146 | + Assert.Equal(0, result.ExitCode) |
| 147 | + Assert.Contains("hello from exec", result.StdOut) |
| 148 | + finally |
| 149 | + try File.Delete(tmpFile) with _ -> () |
| 150 | + |
| 151 | + // ============================================================================ |
| 152 | + // --use option tests |
| 153 | + // ============================================================================ |
| 154 | + |
| 155 | + /// CLI Test: --use:file.fsx loads and executes a script file |
| 156 | + [<Fact>] |
| 157 | + let ``fsi use - loads and executes script file`` () = |
| 158 | + let tmpFile = Path.Combine(Path.GetTempPath(), $"fsi_use_test_{Guid.NewGuid()}.fsx") |
| 159 | + try |
| 160 | + File.WriteAllText(tmpFile, "printfn \"loaded via use\"") |
| 161 | + let result = runFsiProcess ["--nologo"; "--exec"; $"--use:{tmpFile}"] |
| 162 | + Assert.Equal(0, result.ExitCode) |
| 163 | + Assert.Contains("loaded via use", result.StdOut) |
| 164 | + finally |
| 165 | + try File.Delete(tmpFile) with _ -> () |
| 166 | + |
| 167 | + /// CLI Test: --use with nonexistent file produces error |
| 168 | + [<Fact>] |
| 169 | + let ``fsi use - nonexistent file produces error`` () = |
| 170 | + let result = runFsiProcess ["--exec"; "--use:nonexistent_file_xyz.fsx"] |
| 171 | + Assert.NotEqual(0, result.ExitCode) |
| 172 | + |
| 173 | + // ============================================================================ |
| 174 | + // --load option tests |
| 175 | + // ============================================================================ |
| 176 | + |
| 177 | + /// CLI Test: --load:file.fsx loads a file (definitions available) |
| 178 | + [<Fact>] |
| 179 | + let ``fsi load - loads file definitions`` () = |
| 180 | + let tmpFile = Path.Combine(Path.GetTempPath(), $"fsi_load_test_{Guid.NewGuid()}.fsx") |
| 181 | + try |
| 182 | + File.WriteAllText(tmpFile, "let loadedValue = 42") |
| 183 | + let result = runFsiProcess ["--nologo"; "--exec"; $"--load:{tmpFile}"] |
| 184 | + Assert.Equal(0, result.ExitCode) |
| 185 | + finally |
| 186 | + try File.Delete(tmpFile) with _ -> () |
| 187 | + |
| 188 | + /// CLI Test: --load with nonexistent file produces error |
| 189 | + [<Fact>] |
| 190 | + let ``fsi load - nonexistent file produces error`` () = |
| 191 | + let result = runFsiProcess ["--exec"; "--load:nonexistent_file_xyz.fsx"] |
| 192 | + Assert.NotEqual(0, result.ExitCode) |
| 193 | + |
| 194 | + // ============================================================================ |
| 195 | + // --gui option tests (switch: +/-) |
| 196 | + // ============================================================================ |
| 197 | + |
| 198 | + /// CLI Test: --gui- is accepted without error |
| 199 | + [<Fact>] |
| 200 | + let ``fsi gui - gui minus accepted`` () = |
| 201 | + Fsx """1+1""" |
| 202 | + |> withOptions ["--gui-"] |
| 203 | + |> runFsi |
| 204 | + |> shouldSucceed |
| 205 | + |
| 206 | + /// CLI Test: --gui+ is accepted without error |
| 207 | + [<Fact>] |
| 208 | + let ``fsi gui - gui plus accepted`` () = |
| 209 | + Fsx """1+1""" |
| 210 | + |> withOptions ["--gui+"] |
| 211 | + |> runFsi |
| 212 | + |> shouldSucceed |
| 213 | + |
| 214 | + // ============================================================================ |
| 215 | + // --readline option tests (switch: +/-) |
| 216 | + // ============================================================================ |
| 217 | + |
| 218 | + /// CLI Test: --readline- is accepted without error |
| 219 | + [<Fact>] |
| 220 | + let ``fsi readline - readline minus accepted`` () = |
| 221 | + Fsx """1+1""" |
| 222 | + |> withOptions ["--readline-"] |
| 223 | + |> runFsi |
| 224 | + |> shouldSucceed |
| 225 | + |
| 226 | + /// CLI Test: --readline+ is accepted without error |
| 227 | + [<Fact>] |
| 228 | + let ``fsi readline - readline plus accepted`` () = |
| 229 | + Fsx """1+1""" |
| 230 | + |> withOptions ["--readline+"] |
| 231 | + |> runFsi |
| 232 | + |> shouldSucceed |
| 233 | + |
| 234 | + // ============================================================================ |
| 235 | + // --quotations-debug option tests (switch: +/-) |
| 236 | + // ============================================================================ |
| 237 | + |
| 238 | + /// CLI Test: --quotations-debug+ is accepted without error |
| 239 | + [<Fact>] |
| 240 | + let ``fsi quotations-debug - plus accepted`` () = |
| 241 | + Fsx """1+1""" |
| 242 | + |> withOptions ["--quotations-debug+"] |
| 243 | + |> runFsi |
| 244 | + |> shouldSucceed |
| 245 | + |
| 246 | + /// CLI Test: --quotations-debug- is accepted without error |
| 247 | + [<Fact>] |
| 248 | + let ``fsi quotations-debug - minus accepted`` () = |
| 249 | + Fsx """1+1""" |
| 250 | + |> withOptions ["--quotations-debug-"] |
| 251 | + |> runFsi |
| 252 | + |> shouldSucceed |
| 253 | + |
| 254 | + // ============================================================================ |
| 255 | + // --shadowcopyreferences option tests (switch: +/-) |
| 256 | + // ============================================================================ |
| 257 | + |
| 258 | + /// CLI Test: --shadowcopyreferences+ is accepted without error |
| 259 | + [<Fact>] |
| 260 | + let ``fsi shadowcopyreferences - plus accepted`` () = |
| 261 | + Fsx """1+1""" |
| 262 | + |> withOptions ["--shadowcopyreferences+"] |
| 263 | + |> runFsi |
| 264 | + |> shouldSucceed |
| 265 | + |
| 266 | + /// CLI Test: --shadowcopyreferences- is accepted without error |
| 267 | + [<Fact>] |
| 268 | + let ``fsi shadowcopyreferences - minus accepted`` () = |
| 269 | + Fsx """1+1""" |
| 270 | + |> withOptions ["--shadowcopyreferences-"] |
| 271 | + |> runFsi |
| 272 | + |> shouldSucceed |
| 273 | + |
| 274 | + // ============================================================================ |
| 275 | + // --nologo option tests |
| 276 | + // ============================================================================ |
| 277 | + |
| 278 | + /// CLI Test: --nologo suppresses the banner |
| 279 | + [<Fact>] |
| 280 | + let ``fsi nologo - suppresses banner in subprocess`` () = |
| 281 | + let result = runFsiProcess ["--nologo"; "--exec"] |
| 282 | + Assert.Equal(0, result.ExitCode) |
| 283 | + Assert.DoesNotContain("Microsoft (R) F# Interactive", result.StdOut) |
| 284 | + |
| 285 | + /// In-process test: FSI without --nologo shows the banner |
| 286 | + [<Fact>] |
| 287 | + let ``fsi nologo - without nologo shows banner`` () = |
| 288 | + Fsx """1+1""" |
| 289 | + |> runFsi |
| 290 | + |> shouldSucceed |
| 291 | + |> withStdOutContains "Microsoft" |
| 292 | + |
| 293 | + // ============================================================================ |
| 294 | + // Additional error case tests |
| 295 | + // ============================================================================ |
| 296 | + |
| 297 | + /// CLI Test: completely unknown option produces FS0243 |
| 298 | + [<Fact>] |
| 299 | + let ``fsi error - unknown option produces FS0243`` () = |
| 300 | + let result = runFsiProcess ["--not-a-real-option"] |
| 301 | + Assert.NotEqual(0, result.ExitCode) |
| 302 | + Assert.Contains("Unrecognized option: '--not-a-real-option'", result.StdErr) |
| 303 | + |
| 304 | + /// CLI Test: --warn with invalid level produces error |
| 305 | + [<Fact>] |
| 306 | + let ``fsi error - invalid warn level produces error`` () = |
| 307 | + let result = runFsiProcess ["--warn:invalid"; "--exec"] |
| 308 | + Assert.NotEqual(0, result.ExitCode) |
0 commit comments