Add tests for Scope

This commit is contained in:
Jeroen Engels 2019-11-23 21:43:18 +01:00
parent 85bda9c1c9
commit f6b5b0c4c3
4 changed files with 168 additions and 20 deletions

View File

@ -68,6 +68,9 @@ initialContext =
Context
{ scopes = Nonempty.fromElement Dict.empty
, importAliases = Dict.empty
-- TODO Add elm/core's prelude
-- https://package.elm-lang.org/packages/elm/core/latest
, importedFunctionOrTypes = Dict.empty
, dependencies = Dict.empty
}

31
tests/Dependencies.elm Normal file
View File

@ -0,0 +1,31 @@
module Dependencies exposing (elmHtml)
import Elm.Docs
import Elm.Type as Type
elmHtml : { packageName : String, modules : List Elm.Docs.Module }
elmHtml =
{ packageName = "elm/html"
, modules =
[ { name = "Html"
, comment = ""
, unions = []
, aliases = []
, values =
[ { name = "button"
, comment = ""
, tipe =
-- List.List (Html.Attribute msg) ->
Type.Lambda (Type.Type "List.List" [ Type.Type "Html.Attribute" [ Type.Var "msg" ] ])
-- List.List (Html.Html msg) ->
(Type.Lambda (Type.Type "List.List" [ Type.Type "Html.Html" [ Type.Var "msg" ] ])
-- Html.Html msg
(Type.Type "Html.Html" [ Type.Var "msg" ])
)
}
]
, binops = []
}
]
}

View File

@ -1,5 +1,6 @@
module NoHtmlButtonTest exposing (all)
import Dependencies
import Elm.Type as Type
import NoHtmlButton exposing (rule)
import Review.Project as Project exposing (Project)
@ -17,26 +18,7 @@ testRule string =
projectWithHtmlDependency : Project
projectWithHtmlDependency =
Project.new
|> Project.withDependency
{ packageName = "elm/html"
, modules =
[ { name = "Html"
, comment = ""
, unions = []
, aliases = []
, values =
[ { name = "button"
, comment = ""
, tipe =
-- "List.List (Html.Attribute msg) -> List.List (Html.Html msg) -> Html.Html msg"
Type.Lambda (Type.Type "List.List" [ Type.Type "Html.Attribute" [ Type.Var "msg" ] ])
(Type.Lambda (Type.Type "List.List" [ Type.Type "Html.Html" [ Type.Var "msg" ] ]) (Type.Type "Html.Html" [ Type.Var "msg" ]))
}
]
, binops = []
}
]
}
|> Project.withDependency Dependencies.elmHtml
testRuleWithHtmlDependency : String -> ReviewResult

132
tests/ScopeTest.elm Normal file
View File

@ -0,0 +1,132 @@
module ScopeTest exposing (all)
import Dependencies
import Elm.Syntax.Declaration exposing (Declaration)
import Elm.Syntax.Expression as Expression exposing (Expression)
import Elm.Syntax.Node as Node exposing (Node)
import Review.Project as Project exposing (Project)
import Review.Rule as Rule exposing (Rule)
import Review.Test exposing (ReviewResult)
import Scope
import Test exposing (Test, test)
type alias Context =
{ scope : Scope.Context
, text : String
}
project : Project
project =
Project.new
|> Project.withDependency Dependencies.elmHtml
testRule : Rule -> String -> ReviewResult
testRule rule string =
"module A exposing (..)\n\n"
++ string
|> Review.Test.runWithProjectData project rule
baseRule : Rule.Schema Rule.ForLookingAtASingleFile { hasAtLeastOneVisitor : () } Context
baseRule =
Rule.newSchema "TestRule"
|> Rule.withInitialContext initialContext
|> Scope.addVisitors
{ setter = \scope context -> { context | scope = scope }
, getter = .scope
}
initialContext : Context
initialContext =
{ scope = Scope.initialContext
, text = ""
}
all : Test
all =
Test.describe "Scope"
[ Test.describe "Scope.realFunctionOrType"
[ test "should indicate that module from which a function or value comes from" <|
\() ->
let
rule : Rule
rule =
baseRule
|> Rule.withExpressionVisitor expressionVisitor
|> Rule.withFinalEvaluation finalEvaluation
|> Rule.fromSchema
expressionVisitor : Node Expression -> Rule.Direction -> Context -> ( List Rule.Error, Context )
expressionVisitor node direction context =
case ( direction, Node.value node ) of
( Rule.OnEnter, Expression.FunctionOrValue moduleName name ) ->
let
nameInCode : String
nameInCode =
case moduleName of
[] ->
"<nothing>." ++ name
_ ->
String.join "." moduleName ++ "." ++ name
realName : String
realName =
case Scope.realFunctionOrType moduleName name context.scope of
( [], name_ ) ->
"<nothing>." ++ name_
( moduleName_, name_ ) ->
String.join "." moduleName_ ++ "." ++ name_
in
( [], { context | text = context.text ++ "\n" ++ nameInCode ++ " -> " ++ realName } )
_ ->
( [], context )
finalEvaluation : Context -> List Rule.Error
finalEvaluation context =
[ Rule.error { message = context.text, details = [ "details" ] }
{ start = { row = 1, column = 1 }
, end = { row = 1, column = 7 }
}
]
in
testRule rule """
import Bar as Baz exposing (baz)
import Foo
import Foo.Bar
import Html exposing (..)
import Http exposing (get)
a = b
Foo.bar
Foo.Bar
Baz.foo
baz
button
Http.get
get
"""
|> Review.Test.expectErrors
[ Review.Test.error
{ message = """
<nothing>.b -> <nothing>.b
Foo.bar -> Foo.bar
Foo.Bar -> Foo.Bar
Baz.foo -> Bar.foo
<nothing>.baz -> Bar.baz
<nothing>.button -> Html.button
Http.get -> Http.get
<nothing>.get -> Http.get"""
, details = [ "details" ]
, under = "module"
}
]
]
]