aboutsummaryrefslogtreecommitdiff
path: root/haddock-api/test/Haddock/Backends
diff options
context:
space:
mode:
Diffstat (limited to 'haddock-api/test/Haddock/Backends')
-rw-r--r--haddock-api/test/Haddock/Backends/Hyperlinker/ParserSpec.hs98
1 files changed, 98 insertions, 0 deletions
diff --git a/haddock-api/test/Haddock/Backends/Hyperlinker/ParserSpec.hs b/haddock-api/test/Haddock/Backends/Hyperlinker/ParserSpec.hs
new file mode 100644
index 00000000..8cd2690e
--- /dev/null
+++ b/haddock-api/test/Haddock/Backends/Hyperlinker/ParserSpec.hs
@@ -0,0 +1,98 @@
+module Haddock.Backends.Hyperlinker.ParserSpec (main, spec) where
+
+
+import Test.Hspec
+import Test.QuickCheck
+
+import Haddock.Backends.Hyperlinker.Parser
+import Haddock.Backends.Hyperlinker.Types
+
+
+main :: IO ()
+main = hspec spec
+
+
+spec :: Spec
+spec = do
+ describe "parse" parseSpec
+
+
+parseSpec :: Spec
+parseSpec = do
+
+ it "is total" $
+ property $ \src -> length (parse src) `shouldSatisfy` (>= 0)
+
+ it "retains file layout" $
+ property $ \src -> concatMap tkValue (parse src) == src
+
+ context "when parsing single-line comments" $ do
+
+ it "should ignore content until the end of line" $
+ "-- some very simple comment\nidentifier"
+ `shouldParseTo`
+ [TkComment, TkSpace, TkIdentifier]
+
+ it "should allow endline escaping" $
+ "-- first line\\\nsecond line\\\nand another one"
+ `shouldParseTo`
+ [TkComment]
+
+ context "when parsing multi-line comments" $ do
+
+ it "should support nested comments" $
+ "{- comment {- nested -} still comment -} {- next comment -}"
+ `shouldParseTo`
+ [TkComment, TkSpace, TkComment]
+
+ it "should distinguish compiler pragma" $
+ "{- comment -}{-# LANGUAGE GADTs #-}{- comment -}"
+ `shouldParseTo`
+ [TkComment, TkPragma, TkComment]
+
+ it "should recognize preprocessor directives" $ do
+ "\n#define foo bar" `shouldParseTo` [TkSpace, TkCpp]
+ "x # y" `shouldParseTo`
+ [TkIdentifier, TkSpace, TkOperator, TkSpace,TkIdentifier]
+
+ it "should distinguish basic language constructs" $ do
+ "(* 2) <$> (\"abc\", foo)" `shouldParseTo`
+ [ TkSpecial, TkOperator, TkSpace, TkNumber, TkSpecial
+ , TkSpace, TkOperator, TkSpace
+ , TkSpecial, TkString, TkSpecial, TkSpace, TkIdentifier, TkSpecial
+ ]
+ "let foo' = foo in foo' + foo'" `shouldParseTo`
+ [ TkKeyword, TkSpace, TkIdentifier
+ , TkSpace, TkGlyph, TkSpace
+ , TkIdentifier, TkSpace, TkKeyword, TkSpace
+ , TkIdentifier, TkSpace, TkOperator, TkSpace, TkIdentifier
+ ]
+ "square x = y^2 where y = x" `shouldParseTo`
+ [ TkIdentifier, TkSpace, TkIdentifier
+ , TkSpace, TkGlyph, TkSpace
+ , TkIdentifier, TkOperator, TkNumber
+ , TkSpace, TkKeyword, TkSpace
+ , TkIdentifier, TkSpace, TkGlyph, TkSpace, TkIdentifier
+ ]
+
+ it "should parse do-notation syntax" $ do
+ "do { foo <- getLine; putStrLn foo }" `shouldParseTo`
+ [ TkKeyword, TkSpace, TkSpecial, TkSpace
+ , TkIdentifier, TkSpace, TkGlyph, TkSpace
+ , TkIdentifier, TkSpecial, TkSpace
+ , TkIdentifier, TkSpace, TkIdentifier, TkSpace, TkSpecial
+ ]
+
+ unlines
+ [ "do"
+ , " foo <- getLine"
+ , " putStrLn foo"
+ ] `shouldParseTo`
+ [ TkKeyword, TkSpace, TkIdentifier
+ , TkSpace, TkGlyph, TkSpace, TkIdentifier, TkSpace
+ , TkIdentifier, TkSpace, TkIdentifier, TkSpace
+ ]
+
+
+shouldParseTo :: String -> [TokenType] -> Expectation
+str `shouldParseTo` tokens = map tkType (parse str) `shouldBe` tokens