-
Notifications
You must be signed in to change notification settings - Fork 790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
move some error and warning tests to NUnit #7244
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -217,3 +217,23 @@ module CompilerAssert = | |
Assert.AreEqual(expectedErrorMessage, errorMessage) | ||
) | ||
|
||
let ParseWithErrors (source: string) expectedParseErrors = | ||
lock gate <| fun () -> | ||
let parseResults, _ = checker.ParseAndCheckFileInProject("test.fs", 0, SourceText.ofString source, defaultProjectOptions) |> Async.RunSynchronously | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just confirming that I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree with @cartermp , see if you can use ParseFile. |
||
|
||
Assert.True(parseResults.ParseHadErrors) | ||
|
||
let errors = | ||
parseResults.Errors | ||
|> Array.distinctBy (fun e -> e.Severity, e.ErrorNumber, e.StartLineAlternate, e.StartColumn, e.EndLineAlternate, e.EndColumn, e.Message) | ||
|
||
Assert.AreEqual(Array.length expectedParseErrors, errors.Length, sprintf "Type check errors: %A" parseResults.Errors) | ||
|
||
Array.zip errors expectedParseErrors | ||
|> Array.iter (fun (info, expectedError) -> | ||
let (expectedServerity: FSharpErrorSeverity, expectedErrorNumber: int, expectedErrorRange: int * int * int * int, expectedErrorMsg: string) = expectedError | ||
Assert.AreEqual(expectedServerity, info.Severity) | ||
Assert.AreEqual(expectedErrorNumber, info.ErrorNumber, "expectedErrorNumber") | ||
Assert.AreEqual(expectedErrorRange, (info.StartLineAlternate, info.StartColumn + 1, info.EndLineAlternate, info.EndColumn + 1), "expectedErrorRange") | ||
Assert.AreEqual(expectedErrorMsg, info.Message, "expectedErrorMsg") | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. | ||
|
||
namespace FSharp.Compiler.UnitTests | ||
|
||
open NUnit.Framework | ||
open FSharp.Compiler.SourceCodeServices | ||
|
||
[<TestFixture>] | ||
module ``Errors assigning to mutable objects`` = | ||
|
||
[<Test>] | ||
let ``Assign to immutable error``() = | ||
CompilerAssert.TypeCheckSingleError | ||
""" | ||
let x = 10 | ||
x <- 20 | ||
|
||
exit 0 | ||
""" | ||
FSharpErrorSeverity.Error | ||
27 | ||
(3, 1, 3, 8) | ||
"This value is not mutable. Consider using the mutable keyword, e.g. 'let mutable x = expression'." |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. | ||
|
||
namespace FSharp.Compiler.UnitTests | ||
|
||
open NUnit.Framework | ||
open FSharp.Compiler.SourceCodeServices | ||
|
||
[<TestFixture>] | ||
module NameResolution = | ||
|
||
[<Test>] | ||
let ``Field not in record``() = | ||
CompilerAssert.TypeCheckSingleError | ||
""" | ||
type A = { Hello:string; World:string } | ||
type B = { Size:int; Height:int } | ||
type C = { Wheels:int } | ||
type D = { Size:int; Height:int; Walls:int } | ||
type E = { Unknown:string } | ||
type F = { Wallis:int; Size:int; Height:int; } | ||
|
||
let r:F = { Size=3; Height=4; Wall=1 } | ||
|
||
exit 0 | ||
""" | ||
FSharpErrorSeverity.Error | ||
1129 | ||
(9, 31, 9, 35) | ||
"The record type 'F' does not contain a label 'Wall'." | ||
|
||
[<Test>] | ||
let ``Record field proposal``() = | ||
CompilerAssert.TypeCheckSingleError | ||
""" | ||
type A = { Hello:string; World:string } | ||
type B = { Size:int; Height:int } | ||
type C = { Wheels:int } | ||
type D = { Size:int; Height:int; Walls:int } | ||
type E = { Unknown:string } | ||
type F = { Wallis:int; Size:int; Height:int; } | ||
|
||
let r = { Size=3; Height=4; Wall=1 } | ||
|
||
exit 0 | ||
""" | ||
FSharpErrorSeverity.Error | ||
39 | ||
(9, 29, 9, 33) | ||
"The record label 'Wall' is not defined." | ||
|
||
|
||
[<Test>] | ||
let ``Global qualifier after dot``() = | ||
CompilerAssert.ParseWithErrors | ||
""" | ||
let x = global.System.String.Empty.global.System.String.Empty | ||
|
||
exit 0 | ||
""" | ||
[| FSharpErrorSeverity.Error, 1126, (2, 36, 2, 42), "'global' may only be used as the first name in a qualified path" |] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. | ||
|
||
namespace FSharp.Compiler.UnitTests | ||
|
||
open NUnit.Framework | ||
open FSharp.Compiler.SourceCodeServices | ||
|
||
[<TestFixture>] | ||
module ``Warnings assigning to mutable and immutable objects`` = | ||
|
||
[<Test>] | ||
let ``Unused compare with immutable when assignment might be intended``() = | ||
CompilerAssert.TypeCheckSingleError | ||
""" | ||
let x = 10 | ||
let y = "hello" | ||
|
||
let changeX() = | ||
x = 20 | ||
y = "test" | ||
|
||
exit 0 | ||
""" | ||
FSharpErrorSeverity.Warning | ||
20 | ||
(6, 5, 6, 11) | ||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then mark the value 'mutable' and use the '<-' operator e.g. 'x <- expression'." | ||
|
||
[<Test>] | ||
let ``Unused compare with mutable when assignment might be intended``() = | ||
CompilerAssert.TypeCheckSingleError | ||
""" | ||
let mutable x = 10 | ||
let y = "hello" | ||
|
||
let changeX() = | ||
x = 20 | ||
y = "test" | ||
|
||
exit 0 | ||
""" | ||
FSharpErrorSeverity.Warning | ||
20 | ||
(6, 5, 6, 11) | ||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to mutate a value, then use the '<-' operator e.g. 'x <- expression'." | ||
|
||
[<Test>] | ||
let ``Unused comparison of property in dotnet object when assignment might be intended``() = | ||
CompilerAssert.TypeCheckSingleError | ||
""" | ||
open System | ||
|
||
let z = new System.Timers.Timer() | ||
let y = "hello" | ||
|
||
let changeProperty() = | ||
z.Enabled = true | ||
y = "test" | ||
|
||
exit 0 | ||
""" | ||
FSharpErrorSeverity.Warning | ||
20 | ||
(8, 5, 8, 21) | ||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'z.Enabled <- expression'." | ||
|
||
[<Test>] | ||
let ``Unused comparison of property when assignment might be intended ``() = | ||
CompilerAssert.TypeCheckSingleError | ||
""" | ||
type MyClass(property1 : int) = | ||
member val Property1 = property1 | ||
member val Property2 = "" with get, set | ||
|
||
let x = MyClass(1) | ||
let y = "hello" | ||
|
||
let changeProperty() = | ||
x.Property2 = "20" | ||
y = "test" | ||
|
||
exit 0 | ||
""" | ||
FSharpErrorSeverity.Warning | ||
20 | ||
(10, 5, 10, 23) | ||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to set a value to a property, then use the '<-' operator e.g. 'x.Property2 <- expression'." | ||
|
||
[<Test>] | ||
let ``Don't warn if assignment to property without setter ``() = | ||
CompilerAssert.TypeCheckSingleError | ||
""" | ||
type MyClass(property1 : int) = | ||
member val Property2 = "" with get | ||
|
||
let x = MyClass(1) | ||
let y = "hello" | ||
|
||
let changeProperty() = | ||
x.Property2 = "22" | ||
y = "test" | ||
|
||
exit 0 | ||
""" | ||
FSharpErrorSeverity.Warning | ||
20 | ||
(9, 5, 9, 23) | ||
"The result of this equality expression has type 'bool' and is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'." |
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use
ParseFile
then this may not be necessary, since all parsing operations are thread-safeThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I just got back and tried it out (with
FSharpParsingOptions.Default
as the fsharp parser opts, which I hope is OK). I'll back out the test dupes @KevinRansom's comment and sort the merge issues and hopefully all will be grand