Add functions to be able to test multi rules

This commit is contained in:
Jeroen Engels 2020-01-03 17:12:43 +01:00
parent 93d4e0817d
commit 8fa9ab49a1
2 changed files with 124 additions and 29 deletions

View File

@ -1,6 +1,6 @@
module Review.Test exposing module Review.Test exposing
( ReviewResult, run, runWithProjectData ( ReviewResult, run, runWithProjectData, runMulti, runMultiWithProjectData
, ExpectedError, expectErrors, expectNoErrors, error, atExactly, whenFixed , ExpectedError, expectErrors, expectErrorsForFiles, expectNoErrors, error, atExactly, whenFixed
) )
{-| Module that helps you test your rules, using [`elm-test`](https://package.elm-lang.org/packages/elm-explorations/test/latest/). {-| Module that helps you test your rules, using [`elm-test`](https://package.elm-lang.org/packages/elm-explorations/test/latest/).
@ -95,12 +95,12 @@ for this module.
# Running tests # Running tests
@docs ReviewResult, run, runWithProjectData @docs ReviewResult, run, runWithProjectData, runMulti, runMultiWithProjectData
# Making assertions # Making assertions
@docs ExpectedError, expectErrors, expectNoErrors, error, atExactly, whenFixed @docs ExpectedError, expectErrors, expectErrorsForFiles, expectNoErrors, error, atExactly, whenFixed
-} -}
@ -127,7 +127,7 @@ type ReviewResult
type alias CodeInspector = type alias CodeInspector =
{ source : String { file : File.ParsedFile
, getCodeAtLocation : Range -> Maybe String , getCodeAtLocation : Range -> Maybe String
, checkIfLocationIsAmbiguous : Error -> String -> Expectation , checkIfLocationIsAmbiguous : Error -> String -> Expectation
} }
@ -220,12 +220,29 @@ interested in project related details, then you should use [`run`](#run) instead
-} -}
runWithProjectData : Project -> Rule -> String -> ReviewResult runWithProjectData : Project -> Rule -> String -> ReviewResult
runWithProjectData project rule originalSource = runWithProjectData project rule source =
let runMultiWithProjectData project rule [ source ]
sources : List String
sources =
[ originalSource ] codeInspectorForSource : File.ParsedFile -> CodeInspector
in codeInspectorForSource file =
{ file = file
, getCodeAtLocation = getCodeAtLocationInSourceCode file.source
, checkIfLocationIsAmbiguous = checkIfLocationIsAmbiguousInSourceCode file.source
}
{-| TODO documentation
-}
runMulti : Rule -> List String -> ReviewResult
runMulti rule sources =
runMultiWithProjectData Project.new rule sources
{-| TODO documentation
-}
runMultiWithProjectData : Project -> Rule -> List String -> ReviewResult
runMultiWithProjectData project rule sources =
case parseSources sources of case parseSources sources of
Ok parsedFiles -> Ok parsedFiles ->
let let
@ -235,16 +252,15 @@ runWithProjectData project rule originalSource =
|> Tuple.first |> Tuple.first
in in
-- TODO Fail if modules have the same module name -- TODO Fail if modules have the same module name
List.map2 List.map
(\source parsedFile -> (\parsedFile ->
{ inspector = codeInspectorForSource source { inspector = codeInspectorForSource parsedFile
, errors = , errors =
errors errors
|> List.filter (\error_ -> Rule.errorFilePath error_ == parsedFile.path) |> List.filter (\error_ -> Rule.errorFilePath error_ == parsedFile.path)
|> List.sortWith compareErrorPositions |> List.sortWith compareErrorPositions
} }
) )
sources
parsedFiles parsedFiles
|> SuccessfulRun |> SuccessfulRun
@ -253,14 +269,6 @@ runWithProjectData project rule originalSource =
ParseFailure ParseFailure
codeInspectorForSource : String -> CodeInspector
codeInspectorForSource source =
{ source = source
, getCodeAtLocation = getCodeAtLocationInSourceCode source
, checkIfLocationIsAmbiguous = checkIfLocationIsAmbiguousInSourceCode source
}
parseSources : List String -> Result Error (List File.ParsedFile) parseSources : List String -> Result Error (List File.ParsedFile)
parseSources sources = parseSources sources =
sources sources
@ -402,19 +410,28 @@ an error at the end of the source code.
-} -}
expectErrors : List ExpectedError -> ReviewResult -> Expectation expectErrors : List ExpectedError -> ReviewResult -> Expectation
expectErrors expectedErrors reviewResult = expectErrors expectedErrors reviewResult =
expectErrorsForFiles [ expectedErrors ] reviewResult
{-| TODO Documentation
-}
expectErrorsForFiles : List (List ExpectedError) -> ReviewResult -> Expectation
expectErrorsForFiles expectedErrorsList reviewResult =
case reviewResult of case reviewResult of
ParseFailure -> ParseFailure ->
Expect.fail ErrorMessage.parsingFailure Expect.fail ErrorMessage.parsingFailure
SuccessfulRun runResults -> SuccessfulRun runResults ->
-- TODO Add expectation that we have only one file -- TODO Add expectation that we have as many elements in expectedErrorsList as runResults
runResults List.map2
|> List.map (\{ inspector, errors } () -> checkAllErrorsMatch inspector expectedErrors errors) (\{ inspector, errors } expectedErrors () ->
checkAllErrorsMatch inspector expectedErrors errors
)
runResults
expectedErrorsList
|> (\expectations -> Expect.all expectations ()) |> (\expectations -> Expect.all expectations ())
{-| Create an expectation for an error. {-| Create an expectation for an error.
`message` should be the message you're expecting to be shown to the user. `message` should be the message you're expecting to be shown to the user.
@ -684,7 +701,7 @@ checkFixesAreCorrect codeInspector error_ ((ExpectedError expectedError_) as exp
|> Expect.fail |> Expect.fail
( Just expectedFixedSource, Just fixes ) -> ( Just expectedFixedSource, Just fixes ) ->
case Fix.fix fixes codeInspector.source of case Fix.fix fixes codeInspector.file.source of
Fix.Successful fixedSource -> Fix.Successful fixedSource ->
(fixedSource == expectedFixedSource) (fixedSource == expectedFixedSource)
|> Expect.true (ErrorMessage.fixedCodeMismatch fixedSource expectedFixedSource error_) |> Expect.true (ErrorMessage.fixedCodeMismatch fixedSource expectedFixedSource error_)

View File

@ -0,0 +1,78 @@
module NoUnusedModulesTest exposing (all)
import Dependencies
import Elm.Project
import Elm.Type as Type
import Elm.Version
import NoUnusedModules exposing (rule)
import Review.Project as Project exposing (Project)
import Review.Test exposing (ReviewResult)
import Test exposing (Test, describe, test)
application : Project
application =
Project.new
|> Project.withElmJson applicationElmJson
applicationElmJson : Elm.Project.Project
applicationElmJson =
Elm.Project.Application
{ elm = Elm.Version.one
, dirs = []
, depsDirect = []
, depsIndirect = []
, testDepsDirect = []
, testDepsIndirect = []
}
details : List String
details =
[ "This module is never used. You may want to remove it to keep your project clean, and maybe detect some unused code in your project."
]
tests : List Test
tests =
[ test "should not report a module when all modules are used" <|
\() ->
[ """
module A exposing (..)
import B
main = text ""
"""
, """
module B exposing (..)
"""
]
|> Review.Test.runMultiWithProjectData application rule
|> Review.Test.expectNoErrors
, test "should report a module when it is never used" <|
\() ->
[ """
module A exposing (..)
main = text ""
"""
, """
module B exposing (..)
"""
]
|> Review.Test.runMultiWithProjectData application rule
|> Review.Test.expectErrorsForFiles
[ []
, [ Review.Test.error
{ message = "Module `B` is never used."
, details = details
, under = "B"
}
|> Review.Test.atExactly { start = { row = 2, column = 8 }, end = { row = 2, column = 9 } }
]
]
]
all : Test
all =
describe "NoUnusedModules" tests