{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import Language.Gemini (GeminiDocument, GeminiLine (..), decodeGemini, encodeGemini)
import Data.Text.Lazy (Text)
import qualified Data.Text.Lazy as TL
import Hedgehog (Gen, PropertyT, forAll, (===))
import Hedgehog.Gen (alphaNum, choice, frequency, list, sample, text, unicode)
import qualified Hedgehog.Gen as G
import Hedgehog.Range (constant, singleton)
import Test.Hspec (Spec, describe, hspec, it, shouldBe)
import Test.Hspec.Hedgehog (hedgehog)
main :: IO ()
main = hspec $ do
encodeDecodeTrip
encodeDecodeTrip :: Spec
encodeDecodeTrip = do
describe "Convertion" $ do
it "Hello, world!" $ decodeGemini False (encodeGemini helloWorld) `shouldBe` helloWorld
it "Hello, world! Text." $ encodeGemini (decodeGemini False helloWorldT) `shouldBe` helloWorldT
it "Lorum ipsum." $ decodeGemini False (encodeGemini lorumIpsum) `shouldBe` lorumIpsum
it "Lorum ipsum. Text." $ encodeGemini (decodeGemini False lorumIpsumT) `shouldBe` lorumIpsumT
it "Gemini random trip" geminiTrip
helloWorld :: GeminiDocument
helloWorld =
[ LH1 "Hello, World!"
, LPre
[ "main :: IO ()"
, "main = putStrLn \"Welcome, geminicules!\""
]
]
helloWorldT :: Text
helloWorldT = "# Hello, World!\r\n```\r\nmain :: IO ()\r\nmain = putStrLn \"Welcome, geminiks!\"\r\n```"
lorumIpsum :: GeminiDocument
lorumIpsum =
[ LH1 "Lorem ipsum dolor sit amet"
, LH2 "consectetur adipiscing elit"
, LH3 "sed do eiusmod tempor incididunt"
, LLink "gemini://geminispace.info" (Just "ut labore et dolore magna aliqua.")
, LPre
[ "Ut enim ad minim veniam"
, "quis nostrud exercitation ullamco laboris nisi"
, "ut aliquip ex ea commodo consequat."
]
, LText "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
, LItem "Excepteur sint occaecat cupidatat non proident,"
, LItem "sunt in culpa qui officia deserunt mollit anim id est laborum."
, LQuote "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
]
lorumIpsumT :: Text
lorumIpsumT ="# Lorem ipsum dolor sit amet\r\n## consectetur adipiscing elit\r\n### sed do eiusmod tempor incididunt\r\n=> gemini://geminispace.info ut labore et dolore magna aliqua.\r\n```\r\nUt enim ad minim veniam\r\nquis nostrud exercitation ullamco laboris nisi\r\nut aliquip ex ea commodo consequat.\r\n```\r\nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\r\n* Excepteur sint occaecat cupidatat non proident,\r\n* sunt in culpa qui officia deserunt mollit anim id est laborum.\r\n> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
space :: Gen Char
space = G.constant ' '
txt :: Gen Text
txt = do
-- It not tripped with empty text.
notSpaceChar <- TL.fromStrict <$> text (singleton 1) alphaNum
anyText <- TL.fromStrict <$> text (constant 0 20) char
pure $ TL.append notSpaceChar anyText
where
char = frequency [(90, alphaNum), (10, space)]
textUnicode :: Gen Text
textUnicode = TL.fromStrict <$> (text (constant 1 20) char)
where
char = frequency [(90, unicode), (10, space)]
lText :: Gen GeminiLine
lText = LText <$> txt
lLink :: Gen GeminiLine
lLink = do
link <- txt
desc <- txt
pure $ LLink link (Just desc)
lPre :: Gen GeminiLine
lPre = do
pre <- list (constant 0 10) txt
pure $ LPre pre
lItem :: Gen GeminiLine
lItem = LItem <$> txt
lQuote :: Gen GeminiLine
lQuote = LQuote <$> txt
lh1 :: Gen GeminiLine
lh1 = LH1 <$> txt
lh2 :: Gen GeminiLine
lh2 = LH1 <$> txt
lh3 :: Gen GeminiLine
lh3 = LH1 <$> txt
geminiTrip :: PropertyT IO ()
geminiTrip = hedgehog $ do
let line = choice
[ lh1
, lh2
, lh3
, lQuote
, lItem
, lPre
{-
LLink not trips. Consider add encodeGeminiLenient to return spaces.
Or better rename current encodeGemini to encodeGeminiEscapeSpace
decodeGemini False $ encodeGemini $ [LLink "d d l" Nothing]
[LLink "d+d+l" Nothing]
-}
-- , lLink
, lText
]
doc <- forAll $ list (constant 1 50) line
decodeGemini False (encodeGemini doc) === doc