elm-review/tests/NoUselessSubscriptions.elm
2020-09-23 08:11:51 +02:00

107 lines
3.0 KiB
Elm

module NoUselessSubscriptions exposing (rule)
{-|
@docs rule
-}
import Elm.Syntax.Declaration as Declaration exposing (Declaration)
import Elm.Syntax.Expression as Expression
import Elm.Syntax.Node as Node exposing (Node(..))
import Review.Rule as Rule exposing (Error, Rule)
{-| Reports `subscriptions` functions that never return a subscription.
In my opinion, this is often a sign of premature architectural work, where you
set up an `init`, `view`, `update` and `subscriptions` functions. I think
it is better to define them as they are needed, to avoid adding upfront complexity
that turn out to be unnecessary later.
config =
[ NoUselessSubscriptions.rule
]
## Fail
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
## Success
main =
Browser.element
{ init = init
, update = update
, subscriptions = \_ -> Sub.none
, view = view
}
## Try it out
You can try this rule out by running the following command:
```bash
elm-review --template jfmengels/elm-review-the-elm-architecture/example --rules NoUselessSubscriptions
```
-}
rule : Rule
rule =
Rule.newModuleRuleSchema "NoUselessSubscriptions" ()
|> Rule.withSimpleDeclarationVisitor declarationVisitor
|> Rule.fromModuleRuleSchema
declarationVisitor : Node Declaration -> List (Error {})
declarationVisitor declaration =
case Node.value declaration of
Declaration.FunctionDeclaration function ->
if
(function.declaration
|> Node.value
|> .name
|> Node.value
)
== "subscriptions"
then
case Node.value function.declaration |> .expression |> Node.value of
Expression.FunctionOrValue [ "Sub" ] "none" ->
[ error function
]
Expression.Application [ Node _ (Expression.FunctionOrValue [] "always"), Node _ (Expression.FunctionOrValue [ "Sub" ] "none") ] ->
[ error function
]
Expression.Application [ Node _ (Expression.FunctionOrValue [ "Basics" ] "always"), Node _ (Expression.FunctionOrValue [ "Sub" ] "none") ] ->
[ error function
]
Expression.Application [ Node _ (Expression.FunctionOrValue [ "Sub" ] "batch"), Node _ (Expression.ListExpr []) ] ->
[ error function
]
_ ->
[]
else
[]
_ ->
[]
error : Expression.Function -> Error {}
error function =
Rule.error
{ message = "The `subscription` function never returns any subscriptions"
, details = [ "The `subscription` function never returns any subscriptions. You might as well remove it." ]
}
(Node.value function.declaration |> .expression |> Node.range)