{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} module OpenAPI.Generate.DocSpec where import GHC.Generics import Language.Haskell.TH import Language.Haskell.TH.PprLib import OpenAPI.Generate.Doc import OpenAPI.Generate.Internal.Util import Test.Hspec import Test.QuickCheck import Test.Validity newtype MultiLineString = MultiLineString String deriving (Eq, Show, Generic) instance Validity MultiLineString instance GenUnchecked MultiLineString where genUnchecked = MultiLineString <$> genListOf ( frequency [(9, genUnchecked :: Gen Char), (1, pure '\n')] ) instance GenValid MultiLineString spec :: Spec spec = do describe "sideBySide" $ do it "should place equally long docs" $ show ( sideBySide ( text "a" $$ text "c" ) (text "b" $$ text "d") ) `shouldBe` show (text "a b" $$ text "c d") it "should indent if right doc is longer" $ show ( sideBySide ( text "a" $$ text "c" ) (text "b" $$ text "d" $$ text "e") ) `shouldBe` show (text "a b" $$ text "c d" $$ text " e") it "should not indent if left doc is longer" $ show ( sideBySide ( text "a" $$ text "c" $$ text "e" ) (text "b" $$ text "d") ) `shouldBe` show (text "a b" $$ text "c d" $$ text "e") it "should have the length of the longer document" $ do let numberOfLinesOfDoc = length . splitOn '\n' . show forAllValid $ \(MultiLineString doc1, MultiLineString doc2) -> numberOfLinesOfDoc ( sideBySide (text doc1) (text doc2) ) == max (numberOfLinesOfDoc $ text doc1) (numberOfLinesOfDoc $ text doc2) describe "generateHaddockComment" $ it "should place every item on a new line and respect newline characters" $ show (generateHaddockComment ["Line 1", "Line 2", "", "Line 3\nLine 4"]) `shouldBe` init ( unlines [ "-- | Line 1", "-- Line 2", "-- ", "-- Line 3", "-- Line 4" ] ) describe "sideComments" $ it "should convert every item to a side comment and replace newlines with spaces" $ show (sideComments ["Line 1", "Line 2", "", "Line 3\nLine 4"]) `shouldBe` init ( unlines [ "-- ^ Line 1", "-- ^ Line 2", "-- ^ ", "-- ^ Line 3 Line 4" ] ) describe "appendDoc" $ it "should append two docs" $ do content <- runQ $ pure (text "a") `appendDoc` pure (text "b") show content `shouldBe` "a\nb" describe "breakOnTokens" $ it "place a line feed before the tokens and add an indentation" $ show ( breakOnTokens [",", "}"] $ text $ init ( unlines [ "foo = {", " a = 123, b = 321,", " c = A", " } deriving Foo" ] ) ) `shouldBe` init ( unlines [ "foo = { a = 123", " , b = 321", " , c = A ", " } deriving Foo" ] ) describe "zipCodeAndComments" $ it "should intertwine code and comments" $ show ( zipCodeAndComments [ "foo = {", " a = 123", " , b = 321", " , c = A ", " } deriving Foo" ] [ "a is foo", "b is bar\nbut remember the line feed", "c is A" ] ) `shouldBe` init ( unlines [ "foo = {", " -- | a is foo", " a = 123", " -- | b is bar", " -- but remember the line feed", " , b = 321", " -- | c is A", " , c = A ", " } deriving Foo" ] )