tilia-0.0.1.0: tests/Tilia/Doc/BodySpec.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
-- | Placement, attachment, and the 'Body' class.
module Tilia.Doc.BodySpec (spec) where
import Data.Text (Text)
import Test.Hspec
import Tilia.Doc
import Tilia.Doc.Body
import Tilia.Doc.Combinators
import Tilia.Span
-- | A stand-in for a real body type, enough to exercise the class: one
-- construct that hangs, one that does not, and one that takes its answer
-- from another.
data Toy
= Call Text Text
| Block [Text]
| Apply Toy Toy
instance Body Toy where
printBody = \case
Call f x -> txt f <> space <> txt x
Block ss -> txt "do" <> indent (hardBreak <> sepBy hardBreak (map txt ss))
Apply f x -> printBody f <> space <> printBody x
bodyPlacement = \case
Call _ _ -> Normal
Block _ -> Hanging
Apply _ x -> bodyPlacement x
spec :: Spec
spec = do
describe "attach" $ do
it "hands over the line when hanging" $
out (broken (txt "=" <> attach Hanging (txt "do" <> indent (hardBreak <> txt "s"))))
`shouldBe` "= do\n s\n"
it "breaks and indents when normal" $
out (broken (txt "=" <> attach Normal (txt "f" <> space <> txt "x")))
`shouldBe` "=\n f x\n"
it "stays on one line when flat, either way" $ do
out (flat (txt "=" <> attach Normal (txt "x"))) `shouldBe` "= x\n"
out (flat (txt "=" <> attach Hanging (txt "x"))) `shouldBe` "= x\n"
describe "hangingIfSingleLine" $ do
it "hangs for a single-line span" $
hangingIfSingleLine (mkSpan (1, 1) (1, 9)) `shouldBe` Hanging
it "does not hang for a multi-line span" $
hangingIfSingleLine (mkSpan (1, 1) (2, 9)) `shouldBe` Normal
describe "Body" $ do
it "attaches a hanging body" $
out (broken (txt "=" <> attachBody (Block ["a", "b"])))
`shouldBe` "= do\n a\n b\n"
it "attaches a normal body" $
out (broken (txt "=" <> attachBody (Call "f" "x")))
`shouldBe` "=\n f x\n"
it "propagates placement through an application" $
bodyPlacement (Apply (Call "f" "x") (Block ["a"])) `shouldBe` Hanging
it "stops propagating at a non-hanging tail" $
bodyPlacement (Apply (Block ["a"]) (Call "f" "x")) `shouldBe` Normal
it "propagates through nesting" $
bodyPlacement (Apply (Call "f" "x") (Apply (Call "g" "y") (Block ["a"])))
`shouldBe` Hanging
out :: Doc -> Text
out = printDoc defaultRenderOptions