mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-12-23 17:53:35 +03:00
479 lines
17 KiB
Elm
479 lines
17 KiB
Elm
|
module Tests.NoInconsistentAliases exposing (all)
|
||
|
|
||
|
import NoInconsistentAliases as Rule exposing (rule)
|
||
|
import Review.Test
|
||
|
import Test exposing (Test, describe, test)
|
||
|
|
||
|
|
||
|
all : Test
|
||
|
all =
|
||
|
describe "NoInconsistentAliases"
|
||
|
[ describe "preferred aliases" preferredAliasTests
|
||
|
, describe "noMissingAliases" noMissingAliasesTests
|
||
|
]
|
||
|
|
||
|
|
||
|
noMissingAliasesTests : List Test
|
||
|
noMissingAliasesTests =
|
||
|
[ test "reports missing alias when one should be used" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Page exposing (view)
|
||
|
import Html
|
||
|
import Html.Attributes
|
||
|
view = Html.div [ Html.Attributes.class "container" ] []
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Html.Attributes", "Attr" )
|
||
|
]
|
||
|
|> Rule.noMissingAliases
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ missingAliasError "Attr" "Html.Attributes"
|
||
|
|> Review.Test.atExactly { start = { row = 4, column = 8 }, end = { row = 4, column = 23 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module Page exposing (view)
|
||
|
import Html
|
||
|
import Html.Attributes as Attr
|
||
|
view = Html.div [ Attr.class "container" ] []
|
||
|
"""
|
||
|
]
|
||
|
, test "does not report missing aliases when not used" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Page exposing (view)
|
||
|
import Html
|
||
|
import Html.Attributes exposing (class)
|
||
|
view = Html.div [ class "container" ] []
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Html.Attributes", "Attr" )
|
||
|
]
|
||
|
|> Rule.noMissingAliases
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectNoErrors
|
||
|
, test "does not report missing aliases when the option is not set" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Page exposing (view)
|
||
|
import Html
|
||
|
import Html.Attributes
|
||
|
view = Html.div [ Html.Attributes.class "container" ] []
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Html.Attributes", "Attr" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectNoErrors
|
||
|
]
|
||
|
|
||
|
|
||
|
preferredAliasTests : List Test
|
||
|
preferredAliasTests =
|
||
|
[ test "reports incorrect aliases" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Html
|
||
|
import Html.Attributes as A
|
||
|
main = Html.div [ A.class "container" ] []
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Html.Attributes", "Attr" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ incorrectAliasError "Attr" "Html.Attributes" "A"
|
||
|
|> Review.Test.atExactly { start = { row = 4, column = 27 }, end = { row = 4, column = 28 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Html
|
||
|
import Html.Attributes as Attr
|
||
|
main = Html.div [ Attr.class "container" ] []
|
||
|
"""
|
||
|
]
|
||
|
, test "fixes incorrect aliases in a function signature" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Json.Encode as E
|
||
|
import Page
|
||
|
main : Program E.Value Page.Model Page.Msg
|
||
|
main =
|
||
|
Page.program
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Json.Encode", "Encode" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ incorrectAliasError "Encode" "Json.Encode" "E"
|
||
|
|> Review.Test.atExactly { start = { row = 3, column = 23 }, end = { row = 3, column = 24 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Json.Encode as Encode
|
||
|
import Page
|
||
|
main : Program Encode.Value Page.Model Page.Msg
|
||
|
main =
|
||
|
Page.program
|
||
|
"""
|
||
|
]
|
||
|
, test "fixes incorrect aliases in a type alias" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Json.Encode as E
|
||
|
import Page
|
||
|
type alias JsonValue = E.Value
|
||
|
main : Program JsonValue Page.Model Page.Msg
|
||
|
main =
|
||
|
Page.program
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Json.Encode", "Encode" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ incorrectAliasError "Encode" "Json.Encode" "E"
|
||
|
|> Review.Test.atExactly { start = { row = 3, column = 23 }, end = { row = 3, column = 24 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Json.Encode as Encode
|
||
|
import Page
|
||
|
type alias JsonValue = Encode.Value
|
||
|
main : Program JsonValue Page.Model Page.Msg
|
||
|
main =
|
||
|
Page.program
|
||
|
"""
|
||
|
]
|
||
|
, test "fixes incorrect aliases in a custom type constructor" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Json.Encode as E
|
||
|
import Page
|
||
|
type JsonValue = JsonValue E.Value
|
||
|
main = Page.main
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Json.Encode", "Encode" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ incorrectAliasError "Encode" "Json.Encode" "E"
|
||
|
|> Review.Test.atExactly { start = { row = 3, column = 23 }, end = { row = 3, column = 24 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Json.Encode as Encode
|
||
|
import Page
|
||
|
type JsonValue = JsonValue Encode.Value
|
||
|
main = Page.main
|
||
|
"""
|
||
|
]
|
||
|
, test "fixes incorrect aliases in case expressions" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Visitor exposing (expressionVisitor)
|
||
|
import Elm.Syntax.Expression as ESE
|
||
|
import Elm.Syntax.Node as ESN
|
||
|
expressionVisitor : ESN.Node ESE.Expression -> List (Error {})
|
||
|
expressionVisitor node =
|
||
|
case ESN.value node of
|
||
|
ESE.FunctionOrValue _ _ ->
|
||
|
[]
|
||
|
_ ->
|
||
|
[]
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Elm.Syntax.Expression", "Expression" )
|
||
|
, ( "Elm.Syntax.Node", "Node" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ incorrectAliasError "Expression" "Elm.Syntax.Expression" "ESE"
|
||
|
|> Review.Test.atExactly { start = { row = 3, column = 33 }, end = { row = 3, column = 36 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module Visitor exposing (expressionVisitor)
|
||
|
import Elm.Syntax.Expression as Expression
|
||
|
import Elm.Syntax.Node as ESN
|
||
|
expressionVisitor : ESN.Node Expression.Expression -> List (Error {})
|
||
|
expressionVisitor node =
|
||
|
case ESN.value node of
|
||
|
Expression.FunctionOrValue _ _ ->
|
||
|
[]
|
||
|
_ ->
|
||
|
[]
|
||
|
"""
|
||
|
, incorrectAliasError "Node" "Elm.Syntax.Node" "ESN"
|
||
|
|> Review.Test.atExactly { start = { row = 4, column = 27 }, end = { row = 4, column = 30 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module Visitor exposing (expressionVisitor)
|
||
|
import Elm.Syntax.Expression as ESE
|
||
|
import Elm.Syntax.Node as Node
|
||
|
expressionVisitor : Node.Node ESE.Expression -> List (Error {})
|
||
|
expressionVisitor node =
|
||
|
case Node.value node of
|
||
|
ESE.FunctionOrValue _ _ ->
|
||
|
[]
|
||
|
_ ->
|
||
|
[]
|
||
|
"""
|
||
|
]
|
||
|
, test "fixes incorrect aliases in function arguments" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Visitor exposing (getRange)
|
||
|
import Elm.Syntax.Node as ESN
|
||
|
getRange ((ESN.Node range _) as node) = range
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Elm.Syntax.Node", "Node" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ incorrectAliasError "Node" "Elm.Syntax.Node" "ESN"
|
||
|
|> Review.Test.atExactly { start = { row = 3, column = 27 }, end = { row = 3, column = 30 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module Visitor exposing (getRange)
|
||
|
import Elm.Syntax.Node as Node
|
||
|
getRange ((Node.Node range _) as node) = range
|
||
|
"""
|
||
|
]
|
||
|
, test "fixes incorrect aliases in let blocks" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Visitor exposing (shiftRange)
|
||
|
import Elm.Syntax.Node as ESN
|
||
|
shiftRange : ( ESN.Node String, Int ) -> { node : ESN.Node String } -> { a | node : ESN.Node String } -> Range
|
||
|
shiftRange input _ _ =
|
||
|
let
|
||
|
asList : ( ESN.Node, Int ) -> List ESN.Node
|
||
|
asList ( node, _ ) = [ node ]
|
||
|
( ESN.Node range1 value1, length1 ) = input
|
||
|
[ ESN.Node range2 value2 ] = asList input
|
||
|
ESN.Node range3 value3 :: [] = asList input
|
||
|
in
|
||
|
range
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Elm.Syntax.Node", "Node" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ incorrectAliasError "Node" "Elm.Syntax.Node" "ESN"
|
||
|
|> Review.Test.atExactly { start = { row = 3, column = 27 }, end = { row = 3, column = 30 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module Visitor exposing (shiftRange)
|
||
|
import Elm.Syntax.Node as Node
|
||
|
shiftRange : ( Node.Node String, Int ) -> { node : Node.Node String } -> { a | node : Node.Node String } -> Range
|
||
|
shiftRange input _ _ =
|
||
|
let
|
||
|
asList : ( Node.Node, Int ) -> List Node.Node
|
||
|
asList ( node, _ ) = [ node ]
|
||
|
( Node.Node range1 value1, length1 ) = input
|
||
|
[ Node.Node range2 value2 ] = asList input
|
||
|
Node.Node range3 value3 :: [] = asList input
|
||
|
in
|
||
|
range
|
||
|
"""
|
||
|
]
|
||
|
, test "fixes incorrect aliases in a lambda function" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module NoCode exposing (visitor)
|
||
|
import Elm.Syntax.Node as ESN
|
||
|
import Review.Rule as Review
|
||
|
visitor : List (ESN.Node String) -> List (Review.Error {})
|
||
|
visitor list =
|
||
|
List.map (\\ESN.Node range value -> Review.error value) list
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Elm.Syntax.Node", "Node" )
|
||
|
, ( "Review.Rule", "Rule" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ incorrectAliasError "Node" "Elm.Syntax.Node" "ESN"
|
||
|
|> Review.Test.atExactly { start = { row = 3, column = 27 }, end = { row = 3, column = 30 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module NoCode exposing (visitor)
|
||
|
import Elm.Syntax.Node as Node
|
||
|
import Review.Rule as Review
|
||
|
visitor : List (Node.Node String) -> List (Review.Error {})
|
||
|
visitor list =
|
||
|
List.map (\\Node.Node range value -> Review.error value) list
|
||
|
"""
|
||
|
, incorrectAliasError "Rule" "Review.Rule" "Review"
|
||
|
|> Review.Test.atExactly { start = { row = 4, column = 23 }, end = { row = 4, column = 29 } }
|
||
|
|> Review.Test.whenFixed
|
||
|
"""
|
||
|
module NoCode exposing (visitor)
|
||
|
import Elm.Syntax.Node as ESN
|
||
|
import Review.Rule as Rule
|
||
|
visitor : List (ESN.Node String) -> List (Rule.Error {})
|
||
|
visitor list =
|
||
|
List.map (\\ESN.Node range value -> Rule.error value) list
|
||
|
"""
|
||
|
]
|
||
|
, test "does not offer a fix when there's an alias collision" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Page exposing (view)
|
||
|
import Html.Attributes as A
|
||
|
import Svg.Attributes as Attr
|
||
|
view = div [ A.class "container" ] []
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Html.Attributes", "Attr" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ aliasCollisionError "Attr" "Html.Attributes" "A" "Svg.Attributes"
|
||
|
|> Review.Test.atExactly { start = { row = 3, column = 27 }, end = { row = 3, column = 28 } }
|
||
|
]
|
||
|
, test "does not offer a fix when there's a module collision" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Page exposing (view)
|
||
|
import Html.Attributes as A
|
||
|
import Attr
|
||
|
view = div [ A.class "container" ] []
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Html.Attributes", "Attr" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectErrors
|
||
|
[ aliasCollisionError "Attr" "Html.Attributes" "A" "Attr"
|
||
|
|> Review.Test.atExactly { start = { row = 3, column = 27 }, end = { row = 3, column = 28 } }
|
||
|
]
|
||
|
, test "does not report when there's a collision with another preferred alias" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Page exposing (view)
|
||
|
import Html.Attributes as A
|
||
|
import Svg.Attributes as Attr
|
||
|
view = div [ A.class "container" ] []
|
||
|
"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Html.Attributes", "Attr" )
|
||
|
, ( "Svg.Attributes", "Attr" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectNoErrors
|
||
|
, test "does not report modules imported with no alias" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Html.Attributes
|
||
|
main = 1"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Html.Attributes", "Attr" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectNoErrors
|
||
|
, test "does not report modules with the correct alias" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Html.Attributes as Attr
|
||
|
main = 1"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Html.Attributes", "Attr" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectNoErrors
|
||
|
, test "does not report modules with no preferred alias" <|
|
||
|
\_ ->
|
||
|
"""
|
||
|
module Main exposing (main)
|
||
|
import Json.Encode as E
|
||
|
main = 1"""
|
||
|
|> Review.Test.run
|
||
|
(Rule.config
|
||
|
[ ( "Html.Attributes", "Attr" )
|
||
|
]
|
||
|
|> rule
|
||
|
)
|
||
|
|> Review.Test.expectNoErrors
|
||
|
]
|
||
|
|
||
|
|
||
|
incorrectAliasError : String -> String -> String -> Review.Test.ExpectedError
|
||
|
incorrectAliasError expectedAlias moduleName wrongAlias =
|
||
|
Review.Test.error
|
||
|
{ message = "Incorrect alias `" ++ wrongAlias ++ "` for module `" ++ moduleName ++ "`."
|
||
|
, details =
|
||
|
[ "This import does not use your preferred alias `" ++ expectedAlias ++ "` for `" ++ moduleName ++ "`."
|
||
|
, "You should update the alias to be consistent with the rest of the project. Remember to change all references to the alias in this module too."
|
||
|
]
|
||
|
, under = wrongAlias
|
||
|
}
|
||
|
|
||
|
|
||
|
aliasCollisionError : String -> String -> String -> String -> Review.Test.ExpectedError
|
||
|
aliasCollisionError expectedAlias moduleName wrongAlias collisionName =
|
||
|
Review.Test.error
|
||
|
{ message = "Incorrect alias `" ++ wrongAlias ++ "` for module `" ++ moduleName ++ "`."
|
||
|
, details =
|
||
|
[ "This import does not use your preferred alias `" ++ expectedAlias ++ "` for `" ++ moduleName ++ "`."
|
||
|
, "Your preferred alias has already been taken by `" ++ collisionName ++ "`."
|
||
|
, "You should change the alias for both modules to be consistent with the rest of the project. Remember to change all references to the alias in this module too."
|
||
|
]
|
||
|
, under = wrongAlias
|
||
|
}
|
||
|
|
||
|
|
||
|
missingAliasError : String -> String -> Review.Test.ExpectedError
|
||
|
missingAliasError expectedAlias moduleName =
|
||
|
Review.Test.error
|
||
|
{ message = "Expected alias `" ++ expectedAlias ++ "` missing for module `" ++ moduleName ++ "`."
|
||
|
, details =
|
||
|
[ "This import does not use your preferred alias `" ++ expectedAlias ++ "` for `" ++ moduleName ++ "`."
|
||
|
, "You should update the alias to be consistent with the rest of the project. Remember to change all references to the alias in this module too."
|
||
|
]
|
||
|
, under = moduleName
|
||
|
}
|