content: {-# LANGUAGE OverloadedStrings #-}
  {- |
     Module      : Tests.Readers.Org.Block.Table
     Copyright   : © 2014-2024 Albert Krewinkel
     License     : GNU GPL, version 2 or above
  
     Maintainer  : Albert Krewinkel <albert+pandoc@tarleb.com>
     Stability   : alpha
     Portability : portable
  
  Test parsing of org tables.
  -}
  module Tests.Readers.Org.Block.Table (tests) where
  
  import Test.Tasty (TestTree)
  import Tests.Helpers ((=?>))
  import Tests.Readers.Org.Shared ((=:), spcSep)
  import Text.Pandoc.Builder
  import qualified Data.Text as T
  
  simpleTable' :: Int
               -> [Blocks]
               -> [[Blocks]]
               -> Blocks
  simpleTable' n = simpleTable'' emptyCaption $ replicate n (AlignDefault, ColWidthDefault)
  
  simpleTable'' :: Caption -> [ColSpec] -> [Blocks] -> [[Blocks]] -> Blocks
  simpleTable'' = simpleTableWith'' (mempty, [], [])
  
  simpleTableWith'' :: Attr -> Caption -> [ColSpec] -> [Blocks] -> [[Blocks]] -> Blocks
  simpleTableWith'' attr capt spec headers rows
    = tableWith attr
                capt
                spec
                (TableHead nullAttr $ toHeaderRow headers)
                [TableBody nullAttr 0 [] $ map toRow rows]
                (TableFoot nullAttr [])
    where
      toRow = Row nullAttr . map simpleCell
      toHeaderRow l = [toRow l | not (null l)]
  
  tests :: [TestTree]
  tests =
    [ "Single cell table" =:
        "|Test|" =?>
        simpleTable' 1 mempty [[plain "Test"]]
  
    , "Multi cell table" =:
        "| One | Two |" =?>
         simpleTable' 2 mempty [ [ plain "One", plain "Two" ] ]
  
    , "Multi line table" =:
        T.unlines [ "| One   |"
                  , "| Two   |"
                  , "| Three |"
                  ] =?>
         simpleTable' 1 mempty
                      [ [ plain "One" ]
                      , [ plain "Two" ]
                      , [ plain "Three" ]
                      ]
  
    , "Empty table" =:
        "||" =?>
        simpleTable' 1 mempty [[mempty]]
  
    , "Glider Table" =:
        T.unlines [ "| 1 | 0 | 0 |"
                  , "| 0 | 1 | 1 |"
                  , "| 1 | 1 | 0 |"
                  ] =?>
        simpleTable' 3 mempty
                     [ [ plain "1", plain "0", plain "0" ]
                     , [ plain "0", plain "1", plain "1" ]
                     , [ plain "1", plain "1", plain "0" ]
                     ]
  
    , "Table between Paragraphs" =:
        T.unlines [ "Before"
                  , "| One | Two |"
                  , "After"
                  ] =?>
        mconcat [ para "Before"
                , simpleTable' 2 mempty [ [ plain "One", plain "Two" ] ]
                , para "After"
                ]
  
    , "Table with Header" =:
        T.unlines [ "| Species      | Status       |"
                  , "|--------------+--------------|"
                  , "| cervisiae    | domesticated |"
                  , "| paradoxus    | wild         |"
                  ] =?>
        simpleTable [ plain "Species", plain "Status" ]
                    [ [ plain "cervisiae", plain "domesticated" ]
                    , [ plain "paradoxus", plain "wild" ]
                    ]
  
    , "Table with final hline" =:
        T.unlines [ "| cervisiae    | domesticated |"
                  , "| paradoxus    | wild         |"
                  , "|--------------+--------------|"
                  ] =?>
        simpleTable' 2 mempty
              [ [ plain "cervisiae", plain "domesticated" ]
               , [ plain "paradoxus", plain "wild" ]
              ]
  
    , "Table in a box" =:
        T.unlines [ "|---------|---------|"
                  , "| static  | Haskell |"
                  , "| dynamic | Lisp    |"
                  , "|---------+---------|"
                  ] =?>
        simpleTable' 2 mempty
              [ [ plain "static", plain "Haskell" ]
              , [ plain "dynamic", plain "Lisp" ]
              ]
  
    , "Table with empty cells" =:
        "|||c|" =?>
        simpleTable' 3 mempty [[mempty, mempty, plain "c"]]
  
    , "Table with empty rows" =:
        T.unlines [ "| first  |"
                  , "|        |"
                  , "| third  |"
                  ] =?>
        simpleTable' 1 mempty [[plain "first"], [mempty], [plain "third"]]
  
    , "Table with alignment row" =:
        T.unlines [ "| Numbers | Text | More |"
                  , "| <c>     | <r>  |      |"
                  , "| 1       | One  | foo  |"
                  , "| 2       | Two  | bar  |"
                  ] =?>
        simpleTable''
          emptyCaption
          (zip
            [AlignCenter, AlignRight, AlignDefault]
            [ColWidthDefault, ColWidthDefault, ColWidthDefault])
          []
          [ [ plain "Numbers", plain "Text", plain "More" ]
          , [ plain "1"      , plain "One" , plain "foo"  ]
          , [ plain "2"      , plain "Two" , plain "bar"  ]
          ]
  
    , "Pipe within text doesn't start a table" =:
        "Ceci n'est pas une | pipe " =?>
        para (spcSep [ "Ceci", "n'est", "pas", "une", "|", "pipe" ])
  
    , "Missing pipe at end of row" =:
        "|incomplete-but-valid" =?>
        simpleTable' 1 mempty [ [ plain "incomplete-but-valid" ] ]
  
    , "Table with differing row lengths" =:
        T.unlines [ "| Numbers | Text "
                  , "|-"
                  , "| <c>     | <r>  |"
                  , "| 1       | One  | foo  |"
                  , "| 2"
                  ] =?>
        simpleTable''
          emptyCaption
          (zip [AlignCenter, AlignRight] [ColWidthDefault, ColWidthDefault])
          [ plain "Numbers", plain "Text" ]
          [ [ plain "1" , plain "One" , plain "foo" ]
          , [ plain "2" ]
          ]
  
    , "Table with caption" =:
        T.unlines [ "#+caption: Hitchhiker's Multiplication Table"
                  , "| x |  6 |"
                  , "| 9 | 42 |"
                  ] =?>
        simpleTable''
          (simpleCaption $ plain "Hitchhiker's Multiplication Table")
          [(AlignDefault, ColWidthDefault), (AlignDefault, ColWidthDefault)]
          []
          [ [ plain "x", plain "6" ]
          , [ plain "9", plain "42" ]
          ]
  
    , "named table" =:
        T.unlines [ "#+name: x-marks-the-spot"
                  , "| x |"
                  ] =?>
        simpleTableWith'' ("x-marks-the-spot", mempty, mempty)
                          emptyCaption
                          (replicate 1 (AlignDefault, ColWidthDefault))
                          mempty
                          [ [ plain "x" ] ]
    ]
  