🔧 Review.Documentation.CodeSnippet.check checks your small code examples in the readme, module headers and declaration comments for valid syntax, matching types and correctness.

To check this, it generates tests from these code snippets (If you know elm-verify-examples, you also know how this works. This rule has only a few extras like checking for types or actually getting errors for invalid syntax.)

module Dict.Extra exposing (keySet)

{-| `Dict.keys` but returning a `Set` instead of a `List`.

    import Dict
    import Set

    Dict.fromList [ ( 0, "A" ), ( 1, "B" ), ( 2, "C" ) ]
        |> Dict.Extra.keySet
    --> Set.fromList [ 0, 1, 2 ]

-}
keySet = ...

which will generate a test with

Dict.fromList [ ( 0, "A" ), ( 1, "B" ), ( 2, "C" ) ]
    |> Dict.Extra.keySet
    |> Expect.equal (Set.fromList [ 0, 1, 2 ])

why?

Finding broken or incorrect examples in the documentation is confusing and frustrating to new users. At the same time, these examples quickly get out of sync with your API. Now, how do you find all the places where things changed for your examples? The compiler certainly doesn't check them which makes it easy to miss some

setup

  • elm install lue-bird/elm-review-documentation-code-snippet
    
    then add the rule to your review/src/ReviewConfig.elm
    import Review.Rule
    import Review.Documentation.CodeSnippet
    
    config : List Review.Rule.Rule
    config =
        [ Review.Documentation.CodeSnippet.check
        ]
    or if you don't want to install it, yet
    elm-review --template lue-bird/elm-review-documentation-code-snippet/example
    
  • add a minimal tests/DocumentationCodeSnippetTest.elm which the rule can overwrite. Something like
    module DocumentationCodeSnippetTest exposing (tests)
    tests =
        tests
    You can add this file to .gitignore.

I suggest running it in the background

elm-review --rules Review.Documentation.CodeSnippet --watch --fix-all-without-prompt

while from time to time keeping an eye on possible reported syntax errors and failing/non-compiling generated tests.

thanks

  • Christoph Hermann (stoeffel) for elm-verify-examples which established the core ideas and syntax in a nice command line tool
  • dillonkearns for elm-markdown of which parts are used as a base for finding code blocks
  • Rupert Smith for elm-syntax-dsl which can pretty print a whole elm file and is compatible with elm-syntax
  • miniBill for elm-fast-dict

what could we add in the future?

  • fuzzy check syntax. Something like
    --* xs is list unit
    List.take 3 xs |> List.length
    --> Basics.maximum 3 (xs |> List.length)
    
    --* xs, ys is list unit
    List.map2 Tuple.pair xs ys |> List.length
    --> Basics.minimum (xs |> List.length) (ys |> List.length)
    where list unit is interpreted as Fuzz.list (Fuzz.constant ())
  • compare imports with used module names and automatically add missing imports as a fix
  • ✨ your idea