mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-12-23 09:42:49 +03:00
279 lines
13 KiB
Elm
279 lines
13 KiB
Elm
module NoUnsafeRegexFromLiteralTest exposing (all)
|
|
|
|
import Elm.Project
|
|
import Expect exposing (Expectation)
|
|
import Json.Decode as Decode
|
|
import NoUnsafeRegexFromLiteral exposing (rule)
|
|
import Review.Project as Project exposing (Project)
|
|
import Review.Test
|
|
import Test exposing (Test, describe, test)
|
|
|
|
|
|
helpersRegexSourceCode : String
|
|
helpersRegexSourceCode =
|
|
"""module SomeModule.Regex exposing (fromLiteralFunc)
|
|
import Regex exposing (Regex)
|
|
fromLiteralFunc : String -> Regex
|
|
fromLiteralFunc = something
|
|
"""
|
|
|
|
|
|
configuration : { unsafeFunction : String, moduleAlias : Maybe String }
|
|
configuration =
|
|
{ unsafeFunction = "SomeModule.Regex.fromLiteralFunc"
|
|
, moduleAlias = Just "RegexUtil"
|
|
}
|
|
|
|
|
|
expectErrors : List Review.Test.ExpectedError -> Review.Test.ReviewResult -> Expectation
|
|
expectErrors expectedErrors =
|
|
Review.Test.expectErrorsForModules [ ( "A", expectedErrors ) ]
|
|
|
|
|
|
all : Test
|
|
all =
|
|
describe "NoUnsafeRegexFromLiteral"
|
|
[ test "should not report calls to target function with a valid literal regex" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import SomeModule.Regex
|
|
a = SomeModule.Regex.fromLiteralFunc "^abc$"
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> Review.Test.expectNoErrors
|
|
, test "should report calls to target function with an invalid literal regex" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import SomeModule.Regex
|
|
a = SomeModule.Regex.fromLiteralFunc "^ab($cd"
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> expectErrors
|
|
[ Review.Test.error
|
|
{ message = "SomeModule.Regex.fromLiteralFunc needs to be called with a valid regex."
|
|
, details =
|
|
[ "This function serves to give you more guarantees about creating regular expressions, but if the argument is dynamic or too complex, I won't be able to tell you."
|
|
, "Note that if you are using a triple-quote string, elm-syntax has a bug where it mis-parses the string and this could be a false report. Switch to using a single-quote string and everything should be fine."
|
|
]
|
|
, under = """SomeModule.Regex.fromLiteralFunc "^ab($cd\""""
|
|
}
|
|
]
|
|
, test "should not report calls to target function with an valid literal regex containing back-slashes" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import SomeModule.Regex
|
|
a = SomeModule.Regex.fromLiteralFunc "\\\\s"
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> Review.Test.expectNoErrors
|
|
, test "should report calls to target function with a non-literal value" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import SomeModule.Regex
|
|
a = SomeModule.Regex.fromLiteralFunc dynamicValue
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> expectErrors
|
|
[ Review.Test.error
|
|
{ message = "SomeModule.Regex.fromLiteralFunc needs to be called with a static string literal."
|
|
, details =
|
|
[ "This function serves to give you more guarantees about creating regular expressions, but if the argument is dynamic or too complex, I won't be able to tell you."
|
|
, "Either make the argument static or use Regex.fromString instead."
|
|
]
|
|
, under = "SomeModule.Regex.fromLiteralFunc dynamicValue"
|
|
}
|
|
]
|
|
, test "should report invalid calls if the function is called through a module alias" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import SomeModule.Regex as R
|
|
a = R.fromLiteralFunc dynamicValue
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> expectErrors
|
|
[ Review.Test.error
|
|
{ message = "SomeModule.Regex.fromLiteralFunc needs to be called with a static string literal."
|
|
, details =
|
|
[ "This function serves to give you more guarantees about creating regular expressions, but if the argument is dynamic or too complex, I won't be able to tell you."
|
|
, "Either make the argument static or use Regex.fromString instead."
|
|
]
|
|
, under = "R.fromLiteralFunc dynamicValue"
|
|
}
|
|
]
|
|
, test "should report invalid calls if the function is called through a direct import" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import SomeModule.Regex exposing (fromLiteralFunc)
|
|
a = fromLiteralFunc dynamicValue
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> expectErrors
|
|
[ Review.Test.error
|
|
{ message = "SomeModule.Regex.fromLiteralFunc needs to be called with a static string literal."
|
|
, details =
|
|
[ "This function serves to give you more guarantees about creating regular expressions, but if the argument is dynamic or too complex, I won't be able to tell you."
|
|
, "Either make the argument static or use Regex.fromString instead."
|
|
]
|
|
, under = "fromLiteralFunc dynamicValue"
|
|
}
|
|
]
|
|
, test "should report invalid calls if the function is called through an import that exposes all" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import SomeModule.Regex exposing (..)
|
|
a = fromLiteralFunc dynamicValue
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> expectErrors
|
|
[ Review.Test.error
|
|
{ message = "SomeModule.Regex.fromLiteralFunc needs to be called with a static string literal."
|
|
, details =
|
|
[ "This function serves to give you more guarantees about creating regular expressions, but if the argument is dynamic or too complex, I won't be able to tell you."
|
|
, "Either make the argument static or use Regex.fromString instead."
|
|
]
|
|
, under = "fromLiteralFunc dynamicValue"
|
|
}
|
|
]
|
|
, test "should not report invalid calls if the function was not imported" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import SomeModule.Regex
|
|
a = fromLiteralFunc dynamicValue
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> Review.Test.expectNoErrors
|
|
, test "should report when function is used is used in a non 'function call' context" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import SomeModule.Regex
|
|
fromLiteralAlias = SomeModule.Regex.fromLiteralFunc
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> expectErrors
|
|
[ Review.Test.error
|
|
{ message = "SomeModule.Regex.fromLiteralFunc must be called directly."
|
|
, details =
|
|
[ "This function serves to give you more guarantees about creating regular expressions, but I can't determine how it is used if you do something else than calling it directly."
|
|
]
|
|
, under = "SomeModule.Regex.fromLiteralFunc"
|
|
}
|
|
]
|
|
, test "should report a global error when the target function could not be found in the project" <|
|
|
\_ ->
|
|
"""module A exposing (..)
|
|
import SomeModule.Regex
|
|
a = SomeModule.Regex.fromLiteralFunc "^abc$"
|
|
"""
|
|
|> Review.Test.runWithProjectData project (rule configuration)
|
|
|> Review.Test.expectGlobalErrors
|
|
[ { message = "Could not find SomeModule.Regex.fromLiteralFunc"
|
|
, details =
|
|
[ "I want to provide guarantees on the use of this function, but I can't find it. It is likely that it was renamed, which prevents me from giving you these guarantees."
|
|
, "You should rename it back or update this rule to the new name. If you do not use the function anymore, remove the rule."
|
|
]
|
|
}
|
|
]
|
|
, test "should not report native Regex.fromString with a non-literal string" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import Regex
|
|
a = Regex.fromString value
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> Review.Test.expectNoErrors
|
|
, test "should report native Regex.fromString with a literal string (with a preferred module alias)" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import Regex
|
|
a = Regex.fromString "(abc|"
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule configuration)
|
|
|> Review.Test.expectErrorsForModules
|
|
[ ( "A"
|
|
, [ Review.Test.error
|
|
{ message = "Use `RegexUtil.fromLiteralFunc` instead"
|
|
, details =
|
|
[ "By using `RegexUtil.fromLiteralFunc`, I can make sure that the regex you generated was valid."
|
|
, " import SomeModule.Regex as RegexUtil\n myRegex = RegexUtil.fromLiteralFunc \"(abc|def)\""
|
|
]
|
|
, under = "Regex.fromString"
|
|
}
|
|
]
|
|
)
|
|
]
|
|
, test "should report native Regex.fromString with a literal string (without a preferred module alias)" <|
|
|
\_ ->
|
|
[ """module A exposing (..)
|
|
import Regex
|
|
a = Regex.fromString "(abc|"
|
|
""", helpersRegexSourceCode ]
|
|
|> Review.Test.runOnModulesWithProjectData project (rule { configuration | moduleAlias = Nothing })
|
|
|> Review.Test.expectErrorsForModules
|
|
[ ( "A"
|
|
, [ Review.Test.error
|
|
{ message = "Use `SomeModule.Regex.fromLiteralFunc` instead"
|
|
, details =
|
|
[ "By using `SomeModule.Regex.fromLiteralFunc`, I can make sure that the regex you generated was valid."
|
|
, " import SomeModule.Regex\n myRegex = SomeModule.Regex.fromLiteralFunc \"(abc|def)\""
|
|
]
|
|
, under = "Regex.fromString"
|
|
}
|
|
]
|
|
)
|
|
]
|
|
, test "should report a configuration error when module name is invalid" <|
|
|
\_ ->
|
|
rule
|
|
{ unsafeFunction = "invalid name"
|
|
, moduleAlias = Nothing
|
|
}
|
|
|> Review.Test.expectConfigurationError
|
|
{ message = "invalid name is not a valid function name"
|
|
, details = [ "Some details" ]
|
|
}
|
|
]
|
|
|
|
|
|
|
|
-- PROJECT DATA
|
|
|
|
|
|
project : Project
|
|
project =
|
|
Project.new
|
|
|> Project.addElmJson (createElmJson applicationElmJson)
|
|
|
|
|
|
createElmJson : String -> { path : String, raw : String, project : Elm.Project.Project }
|
|
createElmJson rawElmJson =
|
|
case Decode.decodeString Elm.Project.decoder rawElmJson of
|
|
Ok elmJson ->
|
|
{ path = "elm.json"
|
|
, raw = rawElmJson
|
|
, project = elmJson
|
|
}
|
|
|
|
Err _ ->
|
|
Debug.todo "Invalid elm.json supplied to test"
|
|
|
|
|
|
applicationElmJson : String
|
|
applicationElmJson =
|
|
"""{
|
|
"type": "application",
|
|
"source-directories": [
|
|
"src"
|
|
],
|
|
"elm-version": "0.19.1",
|
|
"dependencies": {
|
|
"direct": {
|
|
"elm/core": "1.0.0"
|
|
},
|
|
"indirect": {}
|
|
},
|
|
"test-dependencies": {
|
|
"direct": {},
|
|
"indirect": {}
|
|
}
|
|
}"""
|