packages feed

seihou-cli-0.16.0.0: test/Seihou/CLI/TextLayoutSpec.hs

module Seihou.CLI.TextLayoutSpec (tests) where

import Data.Text qualified as T
import Seihou.CLI.TextLayout (truncateForSummary, wrapParagraphs)
import Test.Hspec
import Test.Tasty
import Test.Tasty.Hspec (testSpec)

tests :: IO TestTree
tests = testSpec "Seihou.CLI.TextLayout" spec

spec :: Spec
spec = do
  describe "truncateForSummary" $ do
    it "keeps text that already fits" $
      truncateForSummary 20 "short text" `shouldBe` "short text"

    it "cuts long text to exactly the width, ending in an ellipsis" $ do
      let result = truncateForSummary 10 "abcdefghijklmnopqrstuvwxyz"
      result `shouldBe` "abcdefghi…"
      T.length result `shouldBe` 10

    it "collapses newlines and whitespace runs to single spaces" $
      truncateForSummary 40 "one\n  two\t\tthree\n\nfour" `shouldBe` "one two three four"

    it "strips a trailing space before the ellipsis" $
      truncateForSummary 7 "hello world" `shouldBe` "hello…"

  describe "wrapParagraphs" $ do
    let prose =
          "Claude skill for creating, implementing, and managing execution plans \
          \(ExecPlans) — self-contained design documents that guide implementation \
          \of features and system changes."

    it "never returns a line longer than the width" $ do
      let ls = wrapParagraphs 20 (T.replicate 30 "word and ")
      ls `shouldSatisfy` (not . null)
      ls `shouldSatisfy` all ((<= 20) . T.length)

    it "fills lines greedily word by word" $
      wrapParagraphs 72 prose
        `shouldBe` [ "Claude skill for creating, implementing, and managing execution plans",
                     "(ExecPlans) — self-contained design documents that guide implementation",
                     "of features and system changes."
                   ]

    it "keeps a word longer than the width whole, on its own line" $ do
      let url = "https://example.com/" <> T.replicate 40 "x"
      wrapParagraphs 20 ("see " <> url <> " now")
        `shouldBe` ["see", url, "now"]

    it "collapses whitespace inside a paragraph" $
      wrapParagraphs 40 "one\ntwo   three\n\tfour" `shouldBe` ["one two three four"]

    it "preserves a paragraph break as one empty line" $
      wrapParagraphs 40 "first paragraph\n\n\n  \nsecond paragraph"
        `shouldBe` ["first paragraph", "", "second paragraph"]

    it "returns no lines for blank input" $ do
      wrapParagraphs 40 "" `shouldBe` []
      wrapParagraphs 40 "  \n\t\n  " `shouldBe` []