packages feed

fluent-lint-1.0.0: app/Lint.hs

module Lint where

import Control.Monad (unless, when)
import Data.Foldable (for_)
import Data.Map.Strict qualified as Map
import Data.Set qualified as Set
import Document (Document (..))
import Document qualified
import Effectful (Eff, (:>))
import Effectful.Hspec (Hspec, expectationFailure, it, pendingWith, shouldBe)
import Prelude

-- | A syntax error fails the file, which is then not compared with the reference.
strict :: (Hspec :> es) => Maybe Document -> Document -> Eff es ()
strict reference document@Document{errors} = do
    it "parses" . unless (null errors) . expectationFailure $ Document.renderErrors document
    when (null errors) . for_ reference $ flip matches document

-- | A syntax error is a warning, and the file is still compared with the reference.
lenient :: (Hspec :> es) => Maybe Document -> Document -> Eff es ()
lenient reference document@Document{errors} = do
    it "parses" . unless (null errors) . pendingWith $ Document.renderErrors document
    for_ reference $ flip matches document

-- | Checks that the file has the messages and attributes of the reference.
matches :: (Hspec :> es) => Document -> Document -> Eff es ()
matches reference document = do
    it "has every expected message" $
        Map.keys (reference.messages `Map.difference` document.messages)
            `shouldBe` []
    it "has no unexpected messages" $
        Map.keys (document.messages `Map.difference` reference.messages)
            `shouldBe` []
    it "has every expected attribute" $
        [ name <> "." <> attribute
        | (name, missing) <-
            Map.toList $ Map.intersectionWith Set.difference reference.messages document.messages
        , attribute <- Set.toList missing
        ]
            `shouldBe` []