Organize the NoUnusedVariable rule tests

This commit is contained in:
Jeroen Engels 2019-07-24 18:58:56 +02:00
parent 7912badedd
commit 2800e084e9

View File

@ -10,8 +10,25 @@ testRule =
Lint.Test.run rule Lint.Test.run rule
tests : List Test all : Test
tests = all =
describe "NoUnusedVariables"
[ describe "Top-level variables" topLevelVariablesTests
, describe "let..in" letInTests
, describe "Top-level variables used inside a let..in" topLevelVariablesUsedInLetInTests
, describe "Record updates" recordUpdateTests
, describe "Function parameters" functionParameterTests
, describe "Imports" importTests
, describe "Pattern matching variables" patternMatchingVariablesTests
, describe "Defined types" typeTests
, describe "Opaque Types" opaqueTypeTests
, describe "Operators" operatorTests
, describe "Ports" portTests
]
topLevelVariablesTests : List Test
topLevelVariablesTests =
[ test "should not report exposed top-level variables" <| [ test "should not report exposed top-level variables" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a)
@ -93,7 +110,24 @@ c = 3"""
, under = "c" , under = "c"
} }
] ]
, test "should report unused variables from let declarations" <| , test "should report unused variable even if a homonym from a module is used" <|
\() ->
testRule """module A exposing (a)
href = 1
a = Html.Styled.Attributes.href"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Variable `href` is not used"
, under = "href"
}
|> Lint.Test.atExactly { start = { row = 2, column = 1 }, end = { row = 2, column = 5 } }
]
]
letInTests : List Test
letInTests =
[ test "should report unused variables from let declarations" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a)
a = let b = 1 a = let b = 1
@ -118,7 +152,7 @@ a = let b = 1
] ]
, test "should report unused functions from let even if they are exposed by name" <| , test "should report unused functions from let even if they are exposed by name" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a, b)
a = let b param = 1 a = let b param = 1
in 2""" in 2"""
|> Lint.Test.expectErrors |> Lint.Test.expectErrors
@ -126,6 +160,7 @@ a = let b param = 1
{ message = "Variable `b` is not used" { message = "Variable `b` is not used"
, under = "b" , under = "b"
} }
|> Lint.Test.atExactly { start = { row = 2, column = 9 }, end = { row = 2, column = 10 } }
] ]
, test "should report unused variables from let even if everything is exposed" <| , test "should report unused variables from let even if everything is exposed" <|
\() -> \() ->
@ -138,34 +173,50 @@ a = let b = 1
, under = "b" , under = "b"
} }
] ]
, test "should not report top-level variables used inside a let expression" <| , test "should not report variables from let declarations that are used in the expression" <|
\() ->
testRule """module A exposing (a)
a = let c = 1
in c"""
|> Lint.Test.expectNoErrors
]
topLevelVariablesUsedInLetInTests : List Test
topLevelVariablesUsedInLetInTests =
[ test "should not report top-level variables used inside a let expression" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a)
b = 1 b = 1
a = let c = 1 a = let c = 1
in b + c""" in b + c"""
|> Lint.Test.expectNoErrors |> Lint.Test.expectNoErrors
, test "should not report top-level variables used inside let declarations" <| , test "should not report top-level variables used inside let declarations" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a)
b = 1 b = 1
a = let c = b a = let c = b
in c""" in c"""
|> Lint.Test.expectNoErrors |> Lint.Test.expectNoErrors
, test "should not report top-level variables used in nested lets" <| , test "should not report top-level variables used in nested lets" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a)
b = 1 b = 1
a = let a = let
c = b c = b
d = let d = let
e = 1 e = 1
in in
b + c + e b + c + e
in in
d""" d"""
|> Lint.Test.expectNoErrors |> Lint.Test.expectNoErrors
, test "should not report variables used in a record update expression's value to be updated" <| ]
recordUpdateTests : List Test
recordUpdateTests =
[ test "should not report variables used in a record update expression's value to be updated" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a)
b = { c = 1 } b = { c = 1 }
@ -192,18 +243,22 @@ a = { b | c = 3 }"""
} }
|> Lint.Test.atExactly { start = { row = 3, column = 1 }, end = { row = 3, column = 2 } } |> Lint.Test.atExactly { start = { row = 3, column = 1 }, end = { row = 3, column = 2 } }
] ]
, test "should not report variables from let declarations that are used in the expression" <| ]
\() ->
testRule """module A exposing (a)
a = let c = 1 functionParameterTests : List Test
in c""" functionParameterTests =
|> Lint.Test.expectNoErrors [ test "should not report unused function parameters" <|
, test "should not report unused function parameters" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a)
a n = 1""" a n = 1"""
|> Lint.Test.expectNoErrors |> Lint.Test.expectNoErrors
, test "should report unused imported functions" <| ]
importTests : List Test
importTests =
[ test "should report unused imported functions" <|
\() -> \() ->
testRule """module A exposing (b) testRule """module A exposing (b)
import Foo exposing (a)""" import Foo exposing (a)"""
@ -231,165 +286,6 @@ import Foo exposing (C, a, b)"""
, under = "b" , under = "b"
} }
] ]
, test "should not report unused pattern matching parameters" <|
\() ->
testRule """module A exposing (a)
a = case thing of
Foo b c -> []"""
|> Lint.Test.expectNoErrors
-- Should B and C be reported if they are not used? Probably.
, test "should report unused custom type declarations" <|
\() ->
testRule """module A exposing (a)
type A = B | C"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Type `A` is not used"
, under = "A"
}
|> Lint.Test.atExactly { start = { row = 2, column = 6 }, end = { row = 2, column = 7 } }
]
, test "should report unused type aliases declarations" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Type `A` is not used"
, under = "A"
}
|> Lint.Test.atExactly { start = { row = 2, column = 12 }, end = { row = 2, column = 13 } }
]
, test "should not report type used in a signature" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : A
a = {a = 1}"""
|> Lint.Test.expectNoErrors
, test "should not report type used in a signature with multiple arguments" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : String -> A
a str = {a = str}"""
|> Lint.Test.expectNoErrors
, test "should not report type used in a signature with parameterized types (as generic type)" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : A B
a = []"""
|> Lint.Test.expectNoErrors
, test "should not report type used in a signature with parameterized types (as parameter)" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : List A
a = []"""
|> Lint.Test.expectNoErrors
, test "should not report type used in a signature with a record" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : { c: A }
a str = {c = str}"""
|> Lint.Test.expectNoErrors
, test "should not report type used in a signature with a generic record" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : { r | c: A }
a str = {c = str}"""
|> Lint.Test.expectNoErrors
, test "should not report type used in a custom type constructor definition" <|
\() ->
testRule """module A exposing (ExposedType)
type A = B
type ExposedType = Something A
"""
|> Lint.Test.expectNoErrors
, test "should not report a type of which a constructor is used" <|
\() ->
testRule """module A exposing (b)
type A = B | C | D
b = B
"""
|> Lint.Test.expectNoErrors
, test "should not report a type of which a constructor is used even if it was defined afterwards" <|
\() ->
testRule """module A exposing (b)
b = B
type A = B | C | D
"""
|> Lint.Test.expectNoErrors
, test "should not report type used in type signature inside a let-in" <|
\() ->
testRule """module A exposing (a)
type A = A
a = let
b : A
b = 1
in
b
"""
|> Lint.Test.expectNoErrors
, test "should not report type used in a type alias field" <|
\() ->
testRule """module A exposing (ExposedType)
type A = B | C
type alias ExposedType = { a : A }
"""
|> Lint.Test.expectNoErrors
, test "should not report type used in a type alias field's arguments " <|
\() ->
testRule """module A exposing (ExposedType)
type A = B | C
type alias ExposedType = { a : Maybe A }
"""
|> Lint.Test.expectNoErrors
, test "should not report type if it's exposed" <|
\() ->
testRule """module A exposing (A)
type A a = B a"""
|> Lint.Test.expectNoErrors
, test "should not report custom type if it's exposed with its sub-types" <|
\() ->
testRule """module A exposing (A(..))
type A = B | C | D"""
|> Lint.Test.expectNoErrors
, test "should report unused variable even if it's present in a generic type" <|
\() ->
testRule """module A exposing (A)
a = 1
type A a = B a"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Variable `a` is not used"
, under = "a"
}
|> Lint.Test.atExactly { start = { row = 2, column = 1 }, end = { row = 2, column = 2 } }
]
, test "should report unused variable even if it's present in a generic record type" <|
\() ->
testRule """module A exposing (a)
r = 1
a : { r | c: A }
a str = {c = str}"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Variable `r` is not used"
, under = "r"
}
|> Lint.Test.atExactly { start = { row = 2, column = 1 }, end = { row = 2, column = 2 } }
]
, test "should report unused operator import" <| , test "should report unused operator import" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a)
@ -400,36 +296,6 @@ import Parser exposing ((</>))"""
, under = "(</>)" , under = "(</>)"
} }
] ]
, test "should not report used operator (infix)" <|
\() ->
testRule """module A exposing (a)
import Parser exposing ((</>))
a = 1 </> 2"""
|> Lint.Test.expectNoErrors
, test "should not report used operator (prefix)" <|
\() ->
testRule """module A exposing (a)
import Parser exposing ((</>))
a = (</>) 2"""
|> Lint.Test.expectNoErrors
, test "should report unused opaque types" <|
\() ->
testRule """module A exposing (a)
type A = A Int"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Type `A` is not used"
, under = "A"
}
|> Lint.Test.atExactly { start = { row = 2, column = 6 }, end = { row = 2, column = 7 } }
]
, test "should not report used opaque types" <|
\() ->
testRule """module A exposing (a)
type A = A Int
a : A
a = 1"""
|> Lint.Test.expectNoErrors
, test "should report unused import" <| , test "should report unused import" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a)
@ -455,18 +321,6 @@ import Html.Styled.Attributes"""
testRule """module A exposing (a) testRule """module A exposing (a)
import Html.Styled.Attributes exposing (..)""" import Html.Styled.Attributes exposing (..)"""
|> Lint.Test.expectNoErrors |> Lint.Test.expectNoErrors
, test "should report unused variable even if a homonym from a module is used" <|
\() ->
testRule """module A exposing (a)
href = 1
a = Html.Styled.Attributes.href"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Variable `href` is not used"
, under = "href"
}
|> Lint.Test.atExactly { start = { row = 2, column = 1 }, end = { row = 2, column = 5 } }
]
, test "should not report used import (function access)" <| , test "should not report used import (function access)" <|
\() -> \() ->
testRule """module A exposing (a) testRule """module A exposing (a)
@ -504,7 +358,291 @@ import B exposing (C(..))
a : D a : D
a = 1""" a = 1"""
|> Lint.Test.expectNoErrors |> Lint.Test.expectNoErrors
, test "should not report types that are used in ports" <| ]
patternMatchingVariablesTests : List Test
patternMatchingVariablesTests =
[ test "should not report unused pattern matching parameters" <|
\() ->
testRule """module A exposing (a)
a = case thing of
Foo b c -> []"""
|> Lint.Test.expectNoErrors
]
typeTests : List Test
typeTests =
[ test "should report unused custom type declarations" <|
\() ->
testRule """module A exposing (a)
type A = B | C"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Type `A` is not used"
, under = "A"
}
|> Lint.Test.atExactly { start = { row = 2, column = 6 }, end = { row = 2, column = 7 } }
]
, test "should not report unused custom type constructors" <|
-- This is handled by the `NoUnusedTypeConstructors` rule
\() ->
testRule """module A exposing (A)
type A = B | C"""
|> Lint.Test.expectNoErrors
, test "should report unused type aliases declarations" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Type `A` is not used"
, under = "A"
}
|> Lint.Test.atExactly { start = { row = 2, column = 12 }, end = { row = 2, column = 13 } }
]
, test "should not report type alias used in a signature" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : A
a = {a = 1}"""
|> Lint.Test.expectNoErrors
, test "should not report type alias used in a signature with multiple arguments" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : String -> A
a str = {a = str}"""
|> Lint.Test.expectNoErrors
, test "should not report custom type used in a signature" <|
\() ->
testRule """module A exposing (a)
type A = B | C
a : A
a = {a = 1}"""
|> Lint.Test.expectNoErrors
, test "should not report custom type used in a signature with multiple arguments" <|
\() ->
testRule """module A exposing (a)
type A = B | C
a : String -> A
a str = {a = str}"""
|> Lint.Test.expectNoErrors
, test "should not report parameterized custom type used in a signature" <|
\() ->
testRule """module A exposing (a)
type CustomMaybe a = B a | C a
a : CustomMaybe D
a = []"""
|> Lint.Test.expectNoErrors
, test "should not report type alias used in a signature with parameterized types (as parameter)" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : List A
a = []"""
|> Lint.Test.expectNoErrors
, test "should not report custom type used in a signature with parameterized types (as parameter)" <|
\() ->
testRule """module A exposing (a)
type A = B | C
a : List A
a = []"""
|> Lint.Test.expectNoErrors
, test "should not report type alias used in a signature with a record" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : { c: A }
a str = {c = str}"""
|> Lint.Test.expectNoErrors
, test "should not report custom type used in a signature with a record" <|
\() ->
testRule """module A exposing (a)
type A = B | C
a : { c: A }
a str = {c = str}"""
|> Lint.Test.expectNoErrors
, test "should not report type alias used in a signature with a generic record" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a : { r | c: A }
a str = {c = str}"""
|> Lint.Test.expectNoErrors
, test "should not report custom type used in a signature with a generic record" <|
\() ->
testRule """module A exposing (a)
type A = B | C
a : { r | c: A }
a str = {c = str}"""
|> Lint.Test.expectNoErrors
, test "should not report type alias used in a custom type constructor definition" <|
\() ->
testRule """module A exposing (ExposedType)
type alias A = { a : B }
type ExposedType = Something A
"""
|> Lint.Test.expectNoErrors
, test "should not report custom type used in a custom type constructor definition" <|
\() ->
testRule """module A exposing (ExposedType)
type A = B
type ExposedType = Something A
"""
|> Lint.Test.expectNoErrors
, test "should not report custom type of which a constructor is used" <|
\() ->
testRule """module A exposing (b)
type A = B | C | D
b = B
"""
|> Lint.Test.expectNoErrors
, test "should not report custom type of which a constructor is used even if it was defined afterwards" <|
\() ->
testRule """module A exposing (b)
b = B
type A = B | C | D
"""
|> Lint.Test.expectNoErrors
, test "should not report type alias used in type signature inside a let..in" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }
a = let
b : A
b = 1
in
b
"""
|> Lint.Test.expectNoErrors
, test "should not report custom type used in type signature inside a let..in" <|
\() ->
testRule """module A exposing (a)
type A = A
a = let
b : A
b = 1
in
b
"""
|> Lint.Test.expectNoErrors
, test "should not report type alias used in a type alias field" <|
\() ->
testRule """module A exposing (ExposedType)
type alias A = { a : B }
type alias ExposedType = { a : A }
"""
|> Lint.Test.expectNoErrors
, test "should not report custom type used in a type alias field" <|
\() ->
testRule """module A exposing (ExposedType)
type A = B | C
type alias ExposedType = { a : A }
"""
|> Lint.Test.expectNoErrors
, test "should not report type alias used in a type alias field's arguments " <|
\() ->
testRule """module A exposing (ExposedType)
type alias A = { a : B }
type alias ExposedType = { a : Maybe A }
"""
|> Lint.Test.expectNoErrors
, test "should not report custom type used in a type alias field's arguments " <|
\() ->
testRule """module A exposing (ExposedType)
type A = B | C
type alias ExposedType = { a : Maybe A }
"""
|> Lint.Test.expectNoErrors
, test "should not report type alias if it's exposed" <|
\() ->
testRule """module A exposing (A)
type alias A = { a : B }"""
|> Lint.Test.expectNoErrors
, test "should not report custom type if it's exposed" <|
\() ->
testRule """module A exposing (A)
type A a = B a"""
|> Lint.Test.expectNoErrors
, test "should not report custom type if it's exposed with its sub-types" <|
\() ->
testRule """module A exposing (A(..))
type A = B | C | D"""
|> Lint.Test.expectNoErrors
, test "should report unused variable even if it's named like a custom type parameter" <|
\() ->
testRule """module A exposing (A)
a = 1
type A a = B a"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Variable `a` is not used"
, under = "a"
}
|> Lint.Test.atExactly { start = { row = 2, column = 1 }, end = { row = 2, column = 2 } }
]
, test "should report unused variable even if it's present in a generic record type" <|
\() ->
testRule """module A exposing (a)
r = 1
a : { r | c: A }
a str = {c = str}"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Variable `r` is not used"
, under = "r"
}
|> Lint.Test.atExactly { start = { row = 2, column = 1 }, end = { row = 2, column = 2 } }
]
]
opaqueTypeTests : List Test
opaqueTypeTests =
[ test "should report unused opaque types" <|
\() ->
testRule """module A exposing (a)
type A = A Int"""
|> Lint.Test.expectErrors
[ Lint.Test.error
{ message = "Type `A` is not used"
, under = "A"
}
|> Lint.Test.atExactly { start = { row = 2, column = 6 }, end = { row = 2, column = 7 } }
]
, test "should not report used opaque types" <|
\() ->
testRule """module A exposing (a)
type A = A Int
a : A
a = 1"""
|> Lint.Test.expectNoErrors
]
operatorTests : List Test
operatorTests =
[ test "should not report used operator (infix)" <|
\() ->
testRule """module A exposing (a)
import Parser exposing ((</>))
a = 1 </> 2"""
|> Lint.Test.expectNoErrors
, test "should not report used operator (prefix)" <|
\() ->
testRule """module A exposing (a)
import Parser exposing ((</>))
a = (</>) 2"""
|> Lint.Test.expectNoErrors
]
portTests : List Test
portTests =
[ test "should not report types that are used in ports" <|
\() -> \() ->
testRule """module A exposing (output, input) testRule """module A exposing (output, input)
import Json.Decode import Json.Decode
@ -535,8 +673,3 @@ port output : Json.Encode.Value -> Cmd msg"""
} }
] ]
] ]
all : Test
all =
describe "NoUnusedVariables" tests