packages feed

mdoc-0.1.0.0: test/Mdoc/Parse/MdocLineSpec.hs

-- |
--
-- Module      : Mdoc.Parse.MdocLineSpec
-- Copyright   : (c) 2026 Patrick Brisbin
-- License     : AGPL-3
-- Maintainer  : pbrisbin@gmail.com
-- Stability   : experimental
-- Portability : POSIX
module Mdoc.Parse.MdocLineSpec (spec) where

import Mdoc.Prelude

import Mdoc.Interpolation
import Mdoc.MacroArg
import Mdoc.MacroName
import Mdoc.MdocLine
import Mdoc.Parse
import Mdoc.Parse.MdocLine
import Mdoc.Test.Parse
import Test.Hspec

spec :: Spec
spec = do
  describe "parseMdocLine" $ do
    it "parses comments with whitespace" $ do
      parseTest (parseMdocLine <* eol <* eof) [".\\\" Example mdoc"]
        $ Comment "Example mdoc"

    it "parses comments without whitespace" $ do
      parseTest (parseMdocLine <* eol <* eof) [".\\\"Example mdoc"]
        $ Comment "Example mdoc"

    it "parses standalone dots" $ do
      parseTest (parseMdocLine <* eol <* eof) ["."] $ TextLine "."

    it "parses cross-references with trailing space" $ do
      parseTest (parseMdocLine <* eol <* eof) [".Xr rcup 1 "]
        $ MacroLine Xr ["rcup", "1"]

    it "doesn't misinterpret callables that are part of words" $ do
      parseTest (parseMdocLine <* eol <* eof) [".An Archy Bunker"]
        $ MacroLine An ["Archy", "Bunker"]

    it "handles quoted arguments" $ do
      parseTest
        (parseMdocLine <* eol <* eof)
        [".An \"Joe Smith\" Aq Mt jsmith@gmail.com"]
        $ MacroLine An [Quoted "Joe Smith", Callable Aq, Callable Mt, "jsmith@gmail.com"]

    it "handles quoted arguments with escapes" $ do
      parseTest (parseMdocLine <* eol <* eof) [".Nm \"xkbcli\\-interactive\\-x11\""]
        $ MacroLine Nm [Quoted "xkbcli\\-interactive\\-x11"]

    it "handles puncuation after quotes" $ do
      parseTest
        (parseMdocLine <* eol <* eof)
        [".Po including \"pax restricted\", the default tar format for"]
        $ MacroLine
          Po
          [ "including"
          , QuotedComma "pax restricted"
          , "the"
          , "default"
          , "tar"
          , "format"
          , "for"
          ]

    for_
      [ ("name", Name)
      , ("synopsis", Synopsis)
      , ("description", Description)
      ]
      $ \(t, i) ->
        it ("parses " <> unpack t <> " as a line interpolation") $ do
          parseTest (parseMdocLine <* eol <* eof) ["{{" <> t <> "}}"]
            $ InterpolatedLine i

    for_
      [ ("docTitle", DocTitle)
      , ("docSection", DocSection)
      ]
      $ \(t, i) ->
        it ("parses " <> unpack t <> " as an arg interpolation") $ do
          parseTest (parseMdocLine <* eol <* eof) [".Cm Ar {{" <> t <> "}} . foo"]
            $ MacroLine Cm [Callable Ar, InterpolatedArg i, ".", "foo"]