mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-11-23 23:05:35 +03:00
Add DefaultPatternPosition rule
This commit is contained in:
parent
fb59dfc294
commit
2b3a3e5a88
@ -18,6 +18,7 @@ You can read the slides for my [presentation](http://slides.com/jeroenengels/elm
|
||||
|
||||
## Rules
|
||||
|
||||
- [DefaultPatternPosition](rules/DefaultPatternPosition.md) - Enforce the default pattern to always appear first or last.
|
||||
- [NoConstantCondition](rules/NoConstantCondition.md) - Forbid the use of expressions in an If condition whose value are always the same.
|
||||
- [NoDebug](rules/NoDebug.md) - Forbid the use of `Debug` before it goes into production.
|
||||
- [NoDuplicateImports](rules/NoDuplicateImports.md) - Forbid importing the same module several times in a file.
|
||||
|
@ -9,6 +9,7 @@
|
||||
],
|
||||
"exposed-modules": [],
|
||||
"dependencies": {
|
||||
"elm-community/list-extra": "5.0.1 <= v < 6.0.0",
|
||||
"elm-lang/core": "5.0.0 <= v < 6.0.0",
|
||||
"elm-lang/html": "2.0.0 <= v < 3.0.0",
|
||||
"jfmengels/elm-ast": "1.0.1 <= v < 2.0.0"
|
||||
|
@ -14,6 +14,7 @@ import Regex exposing (regex, escape)
|
||||
|
||||
-- Rules
|
||||
|
||||
import DefaultPatternPosition
|
||||
import NoConstantCondition
|
||||
import NoDebug
|
||||
import NoDuplicateImports
|
||||
@ -32,7 +33,8 @@ type Msg
|
||||
|
||||
rules : List (String -> List Types.Error)
|
||||
rules =
|
||||
[ NoConstantCondition.rule
|
||||
[ DefaultPatternPosition.rule { position = DefaultPatternPosition.Last }
|
||||
, NoConstantCondition.rule
|
||||
, NoDebug.rule
|
||||
, NoDuplicateImports.rule
|
||||
, NoExposingEverything.rule
|
||||
|
@ -10,6 +10,7 @@
|
||||
],
|
||||
"exposed-modules": [],
|
||||
"dependencies": {
|
||||
"elm-community/list-extra": "5.0.1 <= v < 6.0.0",
|
||||
"elm-lang/core": "5.0.0 <= v < 6.0.0",
|
||||
"elm-lang/html": "2.0.0 <= v < 3.0.0",
|
||||
"jfmengels/elm-ast": "1.0.0 <= v < 2.0.0"
|
||||
|
94
rules/DefaultPatternPosition.elm
Normal file
94
rules/DefaultPatternPosition.elm
Normal file
@ -0,0 +1,94 @@
|
||||
module DefaultPatternPosition exposing (rule, PatternPosition(..))
|
||||
|
||||
import Ast.Expression exposing (..)
|
||||
import Html.Attributes exposing (pattern)
|
||||
import Lint exposing (doNothing, lint)
|
||||
import List.Extra exposing (findIndex)
|
||||
import Regex
|
||||
import Set exposing (Set)
|
||||
import Types exposing (Direction(..), Error, LintRule)
|
||||
|
||||
|
||||
type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
type PatternPosition
|
||||
= First
|
||||
| Last
|
||||
|
||||
|
||||
type alias Configuration =
|
||||
{ position : PatternPosition
|
||||
}
|
||||
|
||||
|
||||
rule : Configuration -> String -> List Error
|
||||
rule config input =
|
||||
lint input (implementation config)
|
||||
|
||||
|
||||
implementation : Configuration -> LintRule Context
|
||||
implementation configuration =
|
||||
{ statementFn = doNothing
|
||||
, typeFn = doNothing
|
||||
, expressionFn = expressionFn configuration
|
||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
||||
, initialContext = Context
|
||||
}
|
||||
|
||||
|
||||
error : String -> Error
|
||||
error =
|
||||
Error "DefaultPatternPosition"
|
||||
|
||||
|
||||
{-| TODO Share this in a util file, already defined in NoUselessPatternMatching
|
||||
-}
|
||||
isVariable : String -> Bool
|
||||
isVariable =
|
||||
Regex.contains (Regex.regex "^[_a-z][\\w\\d]*$")
|
||||
|
||||
|
||||
isDefaultPattern : ( Expression, Expression ) -> Bool
|
||||
isDefaultPattern pattern =
|
||||
case Tuple.first pattern of
|
||||
Variable names ->
|
||||
if isVariable (String.join "." names) then
|
||||
True
|
||||
else
|
||||
False
|
||||
|
||||
_ ->
|
||||
False
|
||||
|
||||
|
||||
findDefaultPattern : List ( Expression, Expression ) -> Maybe Int
|
||||
findDefaultPattern =
|
||||
findIndex isDefaultPattern
|
||||
|
||||
|
||||
expressionFn : Configuration -> Context -> Direction Expression -> ( List Error, Context )
|
||||
expressionFn config ctx node =
|
||||
case node of
|
||||
Enter (Case expr patterns) ->
|
||||
case findDefaultPattern patterns of
|
||||
Nothing ->
|
||||
( [], ctx )
|
||||
|
||||
Just index ->
|
||||
case config.position of
|
||||
First ->
|
||||
if index /= 0 then
|
||||
( [ error "Expected default pattern to appear first in the list of patterns" ], ctx )
|
||||
else
|
||||
( [], ctx )
|
||||
|
||||
Last ->
|
||||
if index /= (List.length patterns) - 1 then
|
||||
( [ error "Expected default pattern to appear last in the list of patterns" ], ctx )
|
||||
else
|
||||
( [], ctx )
|
||||
|
||||
_ ->
|
||||
( [], ctx )
|
91
tests/DefaultPatternPositionTest.elm
Normal file
91
tests/DefaultPatternPositionTest.elm
Normal file
@ -0,0 +1,91 @@
|
||||
port module DefaultPatternPositionTest exposing (all)
|
||||
|
||||
import Expect
|
||||
import Test exposing (describe, test, Test)
|
||||
import DefaultPatternPosition exposing (rule, PatternPosition(First, Last))
|
||||
import Types exposing (Error)
|
||||
|
||||
|
||||
error : String -> Error
|
||||
error position =
|
||||
Error "DefaultPatternPosition" ("Expected default pattern to appear " ++ position ++ " in the list of patterns")
|
||||
|
||||
|
||||
tests : List Test
|
||||
tests =
|
||||
[ test "should not report when default pattern is at the expected position (first)" <|
|
||||
\() ->
|
||||
"""a = case b of
|
||||
_ -> 1
|
||||
Bar -> 1
|
||||
Foo -> 1
|
||||
"""
|
||||
|> rule { position = First }
|
||||
|> Expect.equal []
|
||||
, test "should not report when default pattern is at the expected position (last)" <|
|
||||
\() ->
|
||||
"""a = case b of
|
||||
Foo -> 1
|
||||
Bar -> 1
|
||||
_ -> 1
|
||||
"""
|
||||
|> rule { position = Last }
|
||||
|> Expect.equal []
|
||||
, test "should not report when there is no default pattern (first)" <|
|
||||
\() ->
|
||||
"""a = case b of
|
||||
Foo -> 1
|
||||
Bar -> 1
|
||||
"""
|
||||
|> rule { position = First }
|
||||
|> Expect.equal []
|
||||
, test "should not report when there is no default pattern (last)" <|
|
||||
\() ->
|
||||
"""a = case b of
|
||||
Foo -> 1
|
||||
Bar -> 1
|
||||
"""
|
||||
|> rule { position = Last }
|
||||
|> Expect.equal []
|
||||
, test "should report an error when the default pattern is not at the expected position (first) (opposite expected position)" <|
|
||||
\() ->
|
||||
"""a = case b of
|
||||
Foo -> 1
|
||||
Bar -> 1
|
||||
_ -> 1
|
||||
"""
|
||||
|> rule { position = First }
|
||||
|> Expect.equal [ error "first" ]
|
||||
, test "should report an error when the default pattern is not at the expected position (first) (somewhere in the middle)" <|
|
||||
\() ->
|
||||
"""a = case b of
|
||||
Foo -> 1
|
||||
_ -> 1
|
||||
Bar -> 1
|
||||
"""
|
||||
|> rule { position = First }
|
||||
|> Expect.equal [ error "first" ]
|
||||
, test "should report an error when the default pattern is not at the expected position (last) (opposite expected position)" <|
|
||||
\() ->
|
||||
"""a = case b of
|
||||
_ -> 1
|
||||
Foo -> 1
|
||||
Bar -> 1
|
||||
"""
|
||||
|> rule { position = Last }
|
||||
|> Expect.equal [ error "last" ]
|
||||
, test "should report an error when the default pattern is not at the expected position (last) (somewhere in the middle)" <|
|
||||
\() ->
|
||||
"""a = case b of
|
||||
Foo -> 1
|
||||
_ -> 1
|
||||
Bar -> 1
|
||||
"""
|
||||
|> rule { position = Last }
|
||||
|> Expect.equal [ error "last" ]
|
||||
]
|
||||
|
||||
|
||||
all : Test
|
||||
all =
|
||||
describe "DefaultPatternPosition" tests
|
@ -3,6 +3,7 @@ port module Tests exposing (..)
|
||||
import Test exposing (describe, Test)
|
||||
import Test.Runner.Node exposing (run)
|
||||
import Json.Encode exposing (Value)
|
||||
import DefaultPatternPositionTest
|
||||
import NoConstantConditionTest
|
||||
import NoDebugTest
|
||||
import NoDuplicateImportsTest
|
||||
@ -25,7 +26,8 @@ port emit : ( String, Value ) -> Cmd msg
|
||||
all : Test
|
||||
all =
|
||||
describe "Visitors"
|
||||
[ NoConstantConditionTest.all
|
||||
[ DefaultPatternPositionTest.all
|
||||
, NoConstantConditionTest.all
|
||||
, NoDebugTest.all
|
||||
, NoDuplicateImportsTest.all
|
||||
, NoImportingEverythingTest.all
|
||||
|
@ -11,6 +11,7 @@
|
||||
"exposed-modules": [],
|
||||
"dependencies": {
|
||||
"elm-community/elm-test": "3.1.0 <= v < 4.0.0",
|
||||
"elm-community/list-extra": "5.0.1 <= v < 6.0.0",
|
||||
"elm-lang/core": "5.0.0 <= v < 6.0.0",
|
||||
"elm-lang/html": "2.0.0 <= v < 3.0.0",
|
||||
"jfmengels/elm-ast": "1.0.1 <= v < 2.0.0",
|
||||
|
Loading…
Reference in New Issue
Block a user