qm-interpolated-string 0.2.1.0 → 0.3.0.0
raw patch · 19 files changed
+1706/−445 lines, 19 files
Files
- CHANGELOG.md +30/−0
- README.md +42/−1
- qm-interpolated-string.cabal +2/−1
- src/Text/InterpolatedString/QM.hs +51/−0
- src/Text/InterpolatedString/QM/Internal/Parsers.hs +6/−10
- src/Text/InterpolatedString/QM/Internal/Parsers/Helpers.hs +31/−30
- src/Text/InterpolatedString/QM/Internal/Parsers/TH.hs +38/−5
- test/LineBreaks/CRLF/QM/Spec.hs +104/−32
- test/LineBreaks/CRLF/QMB/Spec.hs +133/−31
- test/LineBreaks/CRLF/QMS/Spec.hs +128/−31
- test/LineBreaks/CRLF/QN/Spec.hs +127/−35
- test/LineBreaks/CRLF/QNB/Spec.hs +130/−35
- test/LineBreaks/CRLF/QNS/Spec.hs +131/−35
- test/QM/Spec.hs +104/−32
- test/QMB/Spec.hs +133/−31
- test/QMS/Spec.hs +128/−31
- test/QN/Spec.hs +127/−35
- test/QNB/Spec.hs +130/−35
- test/QNS/Spec.hs +131/−35
CHANGELOG.md view
@@ -1,3 +1,33 @@+## <a name="v0.3.0.0"></a>0.3.0.0++* Testing on GHC 8.2.2+* More tests to cover more usage scenarios+* Ability to use `}` inside an interpolation block by escaping it++### **WARNING!** Breaking changes++* `\r` characters are no longer pre-removed.++ Up to [v0.2.1.0](#v0.2.1.0) all `\r` characters were pre-removed. When you+ compile your code with GHC you can use either *LF* or *CRLF* for line-breaks+ but not *CR* alone. When I changed handling of interpolation blocks (see+ below) I needed to get contents of interpolations blocks without **any**+ modifications, so I replaced pre-removing all *CR*s with explicit handling of+ *CRLF* in patterns. If your code ever was depending on `\r` symbols appearing+ alone inside quoters (that I can't even imagine) it could break your code.+ But it will probably never happen, I'm just noticing it here.++* Fix for interpolation blocks parsing.++ Once I noticed that `[qm|{"\n"}|]` compiles to `"n"`, I considered this as a+ bug, I also realized that interpolation blocks aren't interpreted as a bare+ haskell code as I was expecting. My bad, I've missed that, haven't written+ enought tests to cover such scenarios, it migrated from original+ *interpolatedstring-perl6* package. So I had to fix this mistake,+ notwithstanding it can break your code when you update the library. Now+ everything inside interpolation blocks is taken as bare haskell code as+ possible.+ ## <a name="v0.2.1.0"></a>0.2.1.0 * Support GHC 7.4.1
README.md view
@@ -126,6 +126,27 @@ | s | Replaces line breaks with spaces | qms, qns | ``` +## About interpolation blocks++Along with all specifics of any of the quoters (which supports interpolation+blocks, which has `m` in their names) interpolation blocks work different. When+curly bracket (`{`) opens everything inside until it closes (by `}`) is parsed+as bare as possible to be given to+[haskell-src-meta](http://hackage.haskell.org/package/haskell-src-meta)+without any modifications, to be parsed as bare haskell code.++But you might need use curly brackets inside an interpolation block. I don't+think it would be a good idea, because complicated logic there may cause code+readability issues, but if you're sure you need it then you get it. You just+need to escape closing bracket to prevent interpolation block from closing, like+this: `\}`. I know it could parsed and opening curly brackets inside could be+used to prevent closing by next `}` symbol, but I chose do it this way to+prevent any unobvious tricky behavior (e.g. consider `}` appear inside a string,+`[qm|foo {'x':'}':"y"} bar|]`, how that should be handled?). So I've decided to+not make parser to be very smart, just to follow simple logic. You just need to+explicitly escape every `}` symbol inside that isn't closer of an interpolation+block (you could find an example below).+ ## About escaping ### Symbols that can be escaped@@ -149,6 +170,10 @@ this list it is interpreted just as backslash symbol, keep in mind that `\\\` (without any of symbols from this list after) and `\\\\` are producing same result - `\\`)+ 7. `\}` - closing bracket inside an interpolation block+ (it works **only** inside opened interpolation block)+ to prevent interpolation block from closing+ (useful to escape records modification) ### Escaping examples @@ -221,10 +246,26 @@ [qnb| foo {1+2} |] -- Result: "foo {1+2}" ``` +That's how you update some record inside interpolation block+(you need to escape closing bracket):++```haskell+{-# LANGUAGE QuasiQuotes #-}+import Text.InterpolatedString.QM (qm)+data Foo = Foo {bar :: Int, baz :: Int} deriving Show+main = let foo = Foo 10 20 in putStrLn [qm| Foo is: {foo {baz = 30\}} |]+-- Foo is: Foo {bar = 10, baz = 30}+```++## Wanna make a contribution or maintain your own fork?++You can find some info for developers on+[wiki pages](https://github.com/unclechu/haskell-qm-interpolated-string/wiki).+ ## Author [Viacheslav Lotsmanov](https://github.com/unclechu) ## License -[The Unlicense](./LICENSE)+[The Unlicense](LICENSE)
qm-interpolated-string.cabal view
@@ -1,5 +1,5 @@ name: qm-interpolated-string-version: 0.2.1.0+version: 0.3.0.0 synopsis: Implementation of interpolated multiline strings description: Implementation of interpolated multiline strings that ignores indentation and trailing whitespaces@@ -19,6 +19,7 @@ , GHC == 7.10.1 , GHC == 7.10.2 , GHC == 8.0.2+ , GHC == 8.2.2 source-repository head type: git
src/Text/InterpolatedString/QM.hs view
@@ -68,6 +68,18 @@ -- baz |] -- "foo\\nbar\\nbaz" -- @ --+-- Keep in mind that this example:+--+-- @+-- ['qmb'|+-- foo+-- bar+-- |]+-- @+--+-- Won't produce @"foo\\nbar\\n"@ nor @"\\nfor\\nbar\\n"@ but @"foo\\nbar"@, it+-- means it separates "between" the lines not by edges.+-- qmb :: QuasiQuoter qmb = QuasiQuoter Parsers.qmb (error "Cannot use 'qmb' as a pattern")@@ -83,6 +95,19 @@ -- {'b':'a':'r':""} -- baz |] -- "foo\\n{'b':'a':'r':\\"\\"}\\nbaz" -- @+--+-- Keep in mind that this example:+--+-- @+-- ['qnb'|+-- foo+-- bar+-- |]+-- @+--+-- Won't produce @"foo\\nbar\\n"@ nor @"\\nfor\\nbar\\n"@ but @"foo\\nbar"@, it+-- means it separates "between" the lines not by edges.+-- qnb :: QuasiQuoter qnb = QuasiQuoter Parsers.qnb (error "Cannot use 'qnb' as a pattern")@@ -97,6 +122,19 @@ -- {'b':'a':'r':""} -- baz |] -- "foo bar baz" -- @+--+-- Keep in mind that this example:+--+-- @+-- ['qms'|+-- foo+-- bar+-- |]+-- @+--+-- Won't produce @"foo bar "@ nor @" for bar "@ but @"foo bar"@, it+-- means it separates "between" the lines not by edges.+-- qms :: QuasiQuoter qms = QuasiQuoter Parsers.qms (error "Cannot use 'qms' as a pattern")@@ -113,6 +151,19 @@ -- {'b':'a':'r':""} -- baz |] -- "foo {'b':'a':'r':\\"\\"} baz" -- @+--+-- Keep in mind that this example:+--+-- @+-- ['qns'|+-- foo+-- bar+-- |]+-- @+--+-- Won't produce @"foo bar "@ nor @" for bar "@ but @"foo bar"@, it+-- means it separates "between" the lines not by edges.+-- qns :: QuasiQuoter qns = QuasiQuoter Parsers.qns (error "Cannot use 'qns' as a pattern")
src/Text/InterpolatedString/QM/Internal/Parsers.hs view
@@ -23,12 +23,12 @@ ) import Text.InterpolatedString.QM.Internal.Parsers.Helpers- ( unQX+ ( unQX -- For code generated by template , clearIndentAtStart- , clearIndentAtSOF- , clearIndentTillEOF+ , clearIndentAtSOF -- For code generated by template+ , clearIndentTillEOF -- For code generated by template , clearFirstQXXLineBreak- , clearLastQXXLineBreak+ , clearLastQXXLineBreak -- For code generated by template , makeExpr ) @@ -43,12 +43,12 @@ -- With interpolation blocks (line breaks and indentation are ignored) qm :: String -> TH.ExpQ-qm = makeExpr . parseQM "" . clearIndentAtStart . filter (/= '\r')+qm = makeExpr . parseQM "" . clearIndentAtStart -- No interpolation block (line breaks and indentation are ignored) qn :: String -> TH.ExpQ-qn = makeExpr . parseQN "" . clearIndentAtStart . filter (/= '\r')+qn = makeExpr . parseQN "" . clearIndentAtStart -- With interpolation blocks (line breaks are kept, indentation is ignored)@@ -57,7 +57,6 @@ . parseQMB "" . clearFirstQXXLineBreak . clearIndentAtStart- . filter (/= '\r') -- No interpolation block (line breaks are kept, indentation is ignored)@@ -66,7 +65,6 @@ . parseQNB "" . clearFirstQXXLineBreak . clearIndentAtStart- . filter (/= '\r') -- With interpolation blocks@@ -76,7 +74,6 @@ . parseQMS "" . clearFirstQXXLineBreak . clearIndentAtStart- . filter (/= '\r') -- No interpolation block@@ -86,4 +83,3 @@ . parseQNS "" . clearFirstQXXLineBreak . clearIndentAtStart- . filter (/= '\r')
src/Text/InterpolatedString/QM/Internal/Parsers/Helpers.hs view
@@ -38,71 +38,72 @@ ) -class QQ a string where- toQQ :: a -> string--instance IsString s => QQ s s where- toQQ = id--instance (ShowQ a, IsString s) => QQ a s where- toQQ = fromString . showQ+class QQ a string where toQQ :: a -> string+instance IsString s => QQ s s where toQQ = id+instance (ShowQ a, IsString s) => QQ a s where toQQ = fromString . showQ -- Parser for interpolation block unQX :: Parser -> Parser-unQX _ a "" = [Literal (reverse a)]-unQX f a ('\\':x:xs) = unQX f (x:a) xs-unQX f a ("\\") = unQX f ('\\':a) ""-unQX f a ('}':xs) = AntiQuote (reverse a) : f "" xs-unQX f a (x:xs) = unQX f (x:a) xs+unQX _ a "" = [Literal (reverse a)] -- Error, block isn't closed+unQX f a ('\\':'}':xs) = unQX f ('}':a) xs+unQX f a ('}':xs) = AntiQuote (reverse a) : f "" xs+unQX f a (x:xs) = unQX f (x:a) xs clearIndentAtSOF :: String -> Maybe String-clearIndentAtSOF "" = Nothing+clearIndentAtSOF "" = Nothing+clearIndentAtSOF ('\r':'\n':xs) = clearIndentAtSOF $ '\n' : xs clearIndentAtSOF s@(x:xs) | x == '\n' && hasChanges = Just processed | otherwise = Nothing where processed = '\n' : cutOff xs hasChanges = processed /= s - cutOff "" = ""+ cutOff "" = "" cutOff z@(y:ys) | y `elem` "\t " = cutOff ys | otherwise = z clearIndentTillEOF :: String -> Maybe String-clearIndentTillEOF "" = Nothing+clearIndentTillEOF "" = Nothing clearIndentTillEOF s@(x:_) | x `elem` "\t " = cutOff s | otherwise = Nothing - where cutOff "" = Just ""- cutOff z@('\n':_) = Just z+ where cutOff "" = Just ""+ cutOff ('\r':'\n':xs) = cutOff $ '\n' : xs+ cutOff z@('\n':_) = Just z cutOff (y:ys) | y `elem` "\t " = cutOff ys | otherwise = Nothing clearLastQXXLineBreak :: String -> Bool -- Cannot really be empty (matched in `parseQMB`)-clearLastQXXLineBreak "" = False-clearLastQXXLineBreak (x:xs) | x `elem` "\t\n " = f xs+clearLastQXXLineBreak "" = False+clearLastQXXLineBreak ('\r':'\n':xs) = clearLastQXXLineBreak $ '\n' : xs+clearLastQXXLineBreak (x:xs) | x `elem` "\t \n" = f xs | otherwise = False - where f "" = True- f (y:ys) | y `elem` "\t\n " = f ys+ where f "" = True+ f ('\r':'\n':ys) = f $ '\n' : ys+ f (y:ys) | y `elem` "\t \n" = f ys | otherwise = False clearFirstQXXLineBreak :: String -> String-clearFirstQXXLineBreak "" = ""-clearFirstQXXLineBreak s@(x:xs) | x `elem` "\t\n " = cutOff xs+clearFirstQXXLineBreak "" = ""+clearFirstQXXLineBreak ('\r':'\n':xs) = clearFirstQXXLineBreak $ '\n' : xs+clearFirstQXXLineBreak s@(x:xs) | x `elem` "\t \n" = cutOff xs | otherwise = s- where cutOff "" = ""- cutOff c@(y:ys) | y `elem` "\t\n " = cutOff ys++ where cutOff "" = ""+ cutOff ('\r':'\n':ys) = cutOff $ '\n' : ys+ cutOff c@(y:ys) | y `elem` "\t \n" = cutOff ys | otherwise = c clearIndentAtStart :: String -> String-clearIndentAtStart "" = ""+clearIndentAtStart "" = "" clearIndentAtStart s@(x:xs) | x `elem` "\t " = clearIndentAtStart xs | otherwise = s @@ -116,8 +117,8 @@ where reify :: String -> TH.Q TH.Exp reify s = case parseExp s of #if MIN_VERSION_template_haskell(2,8,0)- Left e -> TH.reportError e >> [| mempty |]+ Left err -> TH.reportError err >> [| mempty |] #else- Left e -> TH.report True e >> [| mempty |]+ Left err -> TH.report True err >> [| mempty |] #endif- Right e -> return e+ Right expr -> return expr
src/Text/InterpolatedString/QM/Internal/Parsers/TH.hs view
@@ -1,7 +1,6 @@ -- Fork of: https://github.com/audreyt/interpolatedstring-perl6/blob/63d91a83eb5e48740c87570a8c7fd4668afE6832/src/Text/InterpolatedString/Perl6.hs -- Author of the 'interpolatedstring-perl6' package: Audrey Tang -{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE PackageImports #-} {-# LANGUAGE ViewPatterns #-} @@ -62,17 +61,51 @@ decls = - map (uncurry f) $- map (\x -> case x of C (_, y, z) -> (y, z) ; D y -> y ) $- filter (\x -> case x of C (y, _, _) -> y ; D _ -> True)+ let+ -- Filtering truthy conditional patterns,+ -- collecting declarative+ -- and applying `f`.+ reducer x acc = case x of+ C (True, pat, body) -> f pat body : acc+ D ( pat, body) -> f pat body : acc+ _ -> acc -- Skipping - [ D ( ListP []+ in++ -- All patterns here are prefixed with "a" (`aE`) accumulator.+ --+ -- Means:+ -- ```+ -- D ( consP [varP "x", varP "xs"]+ -- , apps [fE, consE [varE "x", aE], varE "xs"]+ -- )+ -- ```+ -- will be for example:+ -- ```+ -- parseQM a (x:xs) = parseQM (x:a) xs+ -- ```+ foldr reducer [] [++ D ( ListP [] , ListE [apps [conE "Literal", apps [varE "reverse", aE]]] ) , C ( lineBreaks `elem` [KeepLineBreaks, ReplaceLineBreaksWithSpaces] , ViewP (varE "clearLastQXXLineBreak") $ conP "True" [] , apps [fE, aE, strE ""]+ )++ -- Cutting '\r' symbols off.+ -- Doing it here (also in '.Helpers' module) to prevent touching+ -- anything inside interpolation block, to make it be just pure+ -- untouched haskell code, with minimal specific details (such as+ -- ability to escape close bracket `\}` to prevent interpolation block+ -- from closing.+ , D ( consP [varP "x", chrP '\r', chrP '\n', varP "xs"]+ , apps [fE, aE, consE [varE "x", chrE '\n', varE "xs"]]+ )+ , D ( consP [chrP '\r', chrP '\n', varP "xs"]+ , apps [fE, aE, consE [chrE '\n', varE "xs"]] ) , D ( consP [chrP '\\', chrP '\\', varP "xs"]
test/LineBreaks/CRLF/QM/Spec.hs view
@@ -1,4 +1,7 @@ -- This file automatically generated by generate-cr-and-crlf-tests.sh (do not modify!) +-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test! +{-# OPTIONS_GHC -fno-warn-tabs #-} + {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -9,7 +12,16 @@ -- local imports import "qm-interpolated-string" Text.InterpolatedString.QM (qm) +newtype TestFoo = TestFoo {testBar :: Int} deriving (Show) +newtype TestFoo2 = TestFoo2 {test1 :: TestFoo} deriving (Show) +testFoo :: TestFoo +testFoo = TestFoo 42 + +testFoo2 :: TestFoo2 +testFoo2 = TestFoo2 testFoo + + spec :: Spec spec = do @@ -36,30 +48,94 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qm| {1+2} \{3+4} |] `shouldBe` "3 {3+4}" + it "Empty string" $ [qm| |] `shouldBe` "" + it "Type annotation in interpolation block" $ [qm|{10 :: Float}|] `shouldBe` "10.0" - it "Escaping interpolation symbols inside interpolation block" $ do - [qm|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz" - [qm|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz" + describe "Escaping" $ do - it "Example from generated docs" $ [qm| foo {'b':'a':'r':""} - \ baz |] `shouldBe` "foo bar baz" + it "Escaping interpolation symbols inside interpolation block" $ do + [qm|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz" + [qm|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz" - it "Escaping backslashes" $ do [qm| foo\bar |] `shouldBe` "foo\\bar" - [qm| foo\\bar |] `shouldBe` "foo\\bar" - [qm| foo\\\bar |] `shouldBe` "foo\\\\bar" - [qm| foo\\\\bar |] `shouldBe` "foo\\\\bar" + it "Escaping backslashes" $ do [qm| foo\bar |] `shouldBe` "foo\\bar" + [qm| foo\\bar |] `shouldBe` "foo\\bar" + [qm| foo\\\bar |] `shouldBe` "foo\\\\bar" + [qm| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qm| |] `shouldBe` "" + it "Escaping space by slash at EOL after space" $ + [qm| foo \ + bar |] `shouldBe` "foo bar" - it "Escaping space by slash at EOL after space" $ - [qm| foo \ - bar |] `shouldBe` "foo bar" + it "Escaped spaces at the edges" $ do [qm| foo\ |] `shouldBe` "foo " + [qm|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qm| foo\ |] `shouldBe` "foo " - [qm|\ foo |] `shouldBe` " foo" + it "Escaping backslash itself when it makes sense" $ do + [qm| foo\nbar |] `shouldBe` "foo\nbar" + [qm| foo\\nbar |] `shouldBe` "foo\\nbar" + [qm| foo\tbar |] `shouldBe` "foo\tbar" + [qm| foo\\tbar |] `shouldBe` "foo\\tbar" + [qm| foo\ bar |] `shouldBe` "foo\tbar" + [qm| foo\\ bar |] `shouldBe` "foo\\\tbar" + [qm| foo\ bar |] `shouldBe` "foo bar" + [qm| foo\\ bar |] `shouldBe` "foo\\ bar" + [qm| foo\ + bar |] `shouldBe` "foobar" + [qm| foo\\ + bar |] `shouldBe` "foo\\bar" + + describe "Escaping inside interpolation blocks" $ do + + it "Line-breaks must be interpreted as just haskell code" $ do + [qm| {'\n'} |] `shouldBe` "\n" + [qm| {"foo\nbar"} |] `shouldBe` "foo\nbar" + [qm| {"foo\\nbar"} |] `shouldBe` "foo\\nbar" + [qm| {"foo\\\nbar"} |] `shouldBe` "foo\\\nbar" + [qm| {"foo\\\\nbar"} |] `shouldBe` "foo\\\\nbar" + + it "Escaping for multiline strings" $ do + [qm| {"foo\ + \bar\ + \baz"} |] `shouldBe` "foobarbaz" + [qm| {"foo \ + \bar\ + \ baz"} |] `shouldBe` "foo bar baz" + [qm| x \ + {"foo \ + \bar\ + \ baz"} \ + y |] `shouldBe` "x foo bar baz y" + + it "Escaping of close-bracket '}'" $ do + [qm| { testFoo {testBar = 9000\} } |] + `shouldBe` show testFoo {testBar = 9000} + [qm| foo{ testFoo {testBar = 9000\} }bar |] + `shouldBe` "foo" ++ show testFoo {testBar = 9000} ++ "bar" + [qm|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|] + `shouldBe` "foo" ++ show testFoo2 {test1 = TestFoo 9000} ++ "bar" + [qm| foo { testFoo2 { + test1 = (test1 testFoo2) + { testBar = 9000 \} + \} + } bar |] + `shouldBe` "foo " ++ show testFoo2 {test1 = TestFoo 9000} ++ " bar" + [qm| {"\}"} |] `shouldBe` "}" + [qm| {"\\\}"} |] `shouldBe` "\\}" + [qm| {123}} |] `shouldBe` "123}" + + it "When interpolation block is escaped\ + \ everything must be interpreted as usual" $ do + [qm| \{ foo\nbar\\baz\} } |] `shouldBe` "{ foo\nbar\\baz\\} }" + [qm| \{ foo\ + bar } |] `shouldBe` "{ foobar }" + + it "Tabs characters in string inside interpolation block" $ do + [qm| {"foo\t\tbar" } |] `shouldBe` "foo\t\tbar" + [qm| {"foo bar" } |] `shouldBe` "foo\t\tbar" + [qm| {"foo\\t\tbar"} |] `shouldBe` "foo\\t\tbar" + describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do @@ -100,6 +176,12 @@ describe "New README examples" $ do + it "First example" $ + [qm| Hello, + world! + Pi is {floor pi}.{floor $ (pi - 3) * 100}… |] + `shouldBe` "Hello,world!Pi is 3.14…" + it "Simple usage example" $ do let title = "Testing" text = "Some testing text" @@ -118,7 +200,7 @@ `shouldBe` "you can escape spaces when you need them" - it "Indentation and line breaks are ignored" $ + it "Indentation and line breaks are ignored" $ [qm| indentation and li ne bre @@ -141,21 +223,11 @@ it "Interpolation" $ [qm| foo {1+2} |] `shouldBe` "foo 3" - it "Haddock example" $ + it "Haddock example" $ do [qm| foo {'b':'a':'r':""} \ baz |] `shouldBe` "foo bar baz" - - it "Escaping backslash itself when it makes sense" $ do - [qm| foo\nbar |] `shouldBe` "foo\nbar" - [qm| foo\\nbar |] `shouldBe` "foo\\nbar" - [qm| foo\tbar |] `shouldBe` "foo\tbar" - [qm| foo\\tbar |] `shouldBe` "foo\\tbar" - [qm| foo\ bar |] `shouldBe` "foo\tbar" - [qm| foo\\ bar |] `shouldBe` "foo\\\tbar" - [qm| foo\ bar |] `shouldBe` "foo bar" - [qm| foo\\ bar |] `shouldBe` "foo\\ bar" - - [qm| foo\ - bar |] `shouldBe` "foobar" - [qm| foo\\ - bar |] `shouldBe` "foo\\bar" + [qm| foo + \ {'b':'a':'r':""} + \ baz |] `shouldBe` "foo bar baz" + [qm| foo {'b':'a':'r':""} + baz |] `shouldBe` "foo barbaz"
test/LineBreaks/CRLF/QMB/Spec.hs view
@@ -1,4 +1,7 @@ -- This file automatically generated by generate-cr-and-crlf-tests.sh (do not modify!) +-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test! +{-# OPTIONS_GHC -fno-warn-tabs #-} + {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -9,7 +12,16 @@ -- local imports import "qm-interpolated-string" Text.InterpolatedString.QM (qmb) +newtype TestFoo = TestFoo {testBar :: Int} deriving (Show) +newtype TestFoo2 = TestFoo2 {test1 :: TestFoo} deriving (Show) +testFoo :: TestFoo +testFoo = TestFoo 42 + +testFoo2 :: TestFoo2 +testFoo2 = TestFoo2 testFoo + + spec :: Spec spec = do @@ -57,30 +69,95 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qmb| {1+2} \{3+4} |] `shouldBe` "3 {3+4}" + it "Empty string" $ [qmb| |] `shouldBe` "" + it "Type annotation in interpolation block" $ [qmb|{10 :: Float}|] `shouldBe` "10.0" - it "Escaping interpolation symbols inside interpolation block" $ do - [qmb|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz" - [qmb|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz" + describe "Escaping" $ do - it "Example from generated docs" $ [qmb| foo {'b':'a':'r':""} - \ baz |] `shouldBe` "foo bar\n baz" + it "Escaping interpolation symbols inside interpolation block" $ do + [qmb|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz" + [qmb|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz" - it "Escaping backslashes" $ do [qmb| foo\bar |] `shouldBe` "foo\\bar" - [qmb| foo\\bar |] `shouldBe` "foo\\bar" - [qmb| foo\\\bar |] `shouldBe` "foo\\\\bar" - [qmb| foo\\\\bar |] `shouldBe` "foo\\\\bar" + it "Escaping backslashes" $ do [qmb| foo\bar |] `shouldBe` "foo\\bar" + [qmb| foo\\bar |] `shouldBe` "foo\\bar" + [qmb| foo\\\bar |] `shouldBe` "foo\\\\bar" + [qmb| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qmb| |] `shouldBe` "" + it "Escaping space by backslash at EOL after space\ + \ (line break is cutted off)" $ + [qmb| foo \ + bar |] `shouldBe` "foo bar" - it "Escaping space by backslash at EOL after space (line break is cutted off)" $ - [qmb| foo \ - bar |] `shouldBe` "foo bar" + it "Escaped spaces at the edges" $ do [qmb| foo\ |] `shouldBe` "foo " + [qmb|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qmb| foo\ |] `shouldBe` "foo " - [qmb|\ foo |] `shouldBe` " foo" + it "Escaping backslash itself when it makes sense" $ do + [qmb| foo\nbar |] `shouldBe` "foo\nbar" + [qmb| foo\\nbar |] `shouldBe` "foo\\nbar" + [qmb| foo\tbar |] `shouldBe` "foo\tbar" + [qmb| foo\\tbar |] `shouldBe` "foo\\tbar" + [qmb| foo\ bar |] `shouldBe` "foo\tbar" + [qmb| foo\\ bar |] `shouldBe` "foo\\\tbar" + [qmb| foo\ bar |] `shouldBe` "foo bar" + [qmb| foo\\ bar |] `shouldBe` "foo\\ bar" + [qmb| foo\ + bar |] `shouldBe` "foobar" + [qmb| foo\\ + bar |] `shouldBe` "foo\\\nbar" + + describe "Escaping inside interpolation blocks" $ do + + it "Line-breaks must be interpreted as just haskell code" $ do + [qmb| {'\n'} |] `shouldBe` "\n" + [qmb| {"foo\nbar"} |] `shouldBe` "foo\nbar" + [qmb| {"foo\\nbar"} |] `shouldBe` "foo\\nbar" + [qmb| {"foo\\\nbar"} |] `shouldBe` "foo\\\nbar" + [qmb| {"foo\\\\nbar"} |] `shouldBe` "foo\\\\nbar" + + it "Escaping for multiline strings" $ do + [qmb| {"foo\ + \bar\ + \baz"} |] `shouldBe` "foobarbaz" + [qmb| {"foo \ + \bar\ + \ baz"} |] `shouldBe` "foo bar baz" + [qmb| x \ + {"foo \ + \bar\ + \ baz"} \ + y |] `shouldBe` "x foo bar baz y" + + it "Escaping of close-bracket '}'" $ do + [qmb| { testFoo {testBar = 9000\} } |] + `shouldBe` show testFoo {testBar = 9000} + [qmb| foo{ testFoo {testBar = 9000\} }bar |] + `shouldBe` "foo" ++ show testFoo {testBar = 9000} ++ "bar" + [qmb|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|] + `shouldBe` "foo" ++ show testFoo2 {test1 = TestFoo 9000} ++ "bar" + [qmb| foo { testFoo2 { + test1 = (test1 testFoo2) + { testBar = 9000 \} + \} + } bar |] + `shouldBe` "foo " ++ show testFoo2 {test1 = TestFoo 9000} ++ " bar" + [qmb| {"\}"} |] `shouldBe` "}" + [qmb| {"\\\}"} |] `shouldBe` "\\}" + [qmb| {123}} |] `shouldBe` "123}" + + it "When interpolation block is escaped\ + \ everything must be interpreted as usual" $ do + [qmb| \{ foo\nbar\\baz\} } |] `shouldBe` "{ foo\nbar\\baz\\} }" + [qmb| \{ foo\ + bar } |] `shouldBe` "{ foobar }" + + it "Tabs characters in string inside interpolation block" $ do + [qmb| {"foo\t\tbar" } |] `shouldBe` "foo\t\tbar" + [qmb| {"foo bar" } |] `shouldBe` "foo\t\tbar" + [qmb| {"foo\\t\tbar"} |] `shouldBe` "foo\\t\tbar" + describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do @@ -121,6 +198,12 @@ describe "New README examples" $ do + it "First example" $ + [qmb| Hello, + world! + Pi is {floor pi}.{floor $ (pi - 3) * 100}… |] + `shouldBe` "Hello,\nworld!\nPi is 3.14…" + it "Simple usage example" $ do let title = "Testing" text = "Some testing text" @@ -133,24 +216,43 @@ `shouldBe` "<article>\n<h1>Testing</h1>\n<p>Some testing text</p>\n</article>" + it "Can escape spaces" $ + [qmb| you can escape spaces + \ when you need them |] + `shouldBe` + "you can escape spaces\n when you need them" + + -- By 'not really' it means that it just copied from `QM` and shows what + -- happens with the same input if you use it with this quoter. + it "Indentation and line breaks are ignored (not really)" $ + [qmb| + indentation and li + ne bre + aks are i + gno + red + (not really) + |] + `shouldBe` "indentation and li\nne bre\naks are i\ngno\nred\n(not really)" + + it "Escaping indentation or line breaks" $ + [qmb| \ You can escape indentation or\n + line breaks when you need them! \ |] + `shouldBe` + " You can escape indentation or\n\nline breaks when you need them! " + + it "Interpolation blocks can be escaped too" $ + [qmb| Interpolation blocks can be escaped too: {1+2} \{3+4} |] + `shouldBe` + "Interpolation blocks can be escaped too: 3 {3+4}" + it "Interpolation" $ [qmb| foo {1+2} |] `shouldBe` "foo 3" - it "Haddock example" $ + it "Haddock example" $ do + [qmb| foo {'b':'a':'r':""} + baz |] `shouldBe` "foo bar\nbaz" [qmb| foo {'b':'a':'r':""} baz |] `shouldBe` "foo\nbar\nbaz" - - it "Escaping backslash itself when it makes sense" $ do - [qmb| foo\nbar |] `shouldBe` "foo\nbar" - [qmb| foo\\nbar |] `shouldBe` "foo\\nbar" - [qmb| foo\tbar |] `shouldBe` "foo\tbar" - [qmb| foo\\tbar |] `shouldBe` "foo\\tbar" - [qmb| foo\ bar |] `shouldBe` "foo\tbar" - [qmb| foo\\ bar |] `shouldBe` "foo\\\tbar" - [qmb| foo\ bar |] `shouldBe` "foo bar" - [qmb| foo\\ bar |] `shouldBe` "foo\\ bar" - - [qmb| foo\ - bar |] `shouldBe` "foobar" - [qmb| foo\\ - bar |] `shouldBe` "foo\\\nbar" + [qmb| foo {'b':'a':'r':""} + \ baz |] `shouldBe` "foo bar\n baz"
test/LineBreaks/CRLF/QMS/Spec.hs view
@@ -1,4 +1,7 @@ -- This file automatically generated by generate-cr-and-crlf-tests.sh (do not modify!) +-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test! +{-# OPTIONS_GHC -fno-warn-tabs #-} + {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -9,7 +12,16 @@ -- local imports import "qm-interpolated-string" Text.InterpolatedString.QM (qms) +newtype TestFoo = TestFoo {testBar :: Int} deriving (Show) +newtype TestFoo2 = TestFoo2 {test1 :: TestFoo} deriving (Show) +testFoo :: TestFoo +testFoo = TestFoo 42 + +testFoo2 :: TestFoo2 +testFoo2 = TestFoo2 testFoo + + spec :: Spec spec = do @@ -57,30 +69,95 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qms| {1+2} \{3+4} |] `shouldBe` "3 {3+4}" + it "Empty string" $ [qms| |] `shouldBe` "" + it "Type annotation in interpolation block" $ [qms|{10 :: Float}|] `shouldBe` "10.0" - it "Escaping interpolation symbols inside interpolation block" $ do - [qms|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz" - [qms|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz" + describe "Escaping" $ do - it "Example from generated docs" $ [qms| foo {'b':'a':'r':""} - \ baz |] `shouldBe` "foo bar baz" + it "Escaping interpolation symbols inside interpolation block" $ do + [qms|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz" + [qms|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz" - it "Escaping backslashes" $ do [qms| foo\bar |] `shouldBe` "foo\\bar" - [qms| foo\\bar |] `shouldBe` "foo\\bar" - [qms| foo\\\bar |] `shouldBe` "foo\\\\bar" - [qms| foo\\\\bar |] `shouldBe` "foo\\\\bar" + it "Escaping backslashes" $ do [qms| foo\bar |] `shouldBe` "foo\\bar" + [qms| foo\\bar |] `shouldBe` "foo\\bar" + [qms| foo\\\bar |] `shouldBe` "foo\\\\bar" + [qms| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qms| |] `shouldBe` "" + it "Escaping space by backslash at EOL after space\ + \ (line break is cutted off)" $ + [qms| foo \ + bar |] `shouldBe` "foo bar" - it "Escaping space by backslash at EOL after space (line break is cutted off)" $ - [qms| foo \ - bar |] `shouldBe` "foo bar" + it "Escaped spaces at the edges" $ do [qms| foo\ |] `shouldBe` "foo " + [qms|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qms| foo\ |] `shouldBe` "foo " - [qms|\ foo |] `shouldBe` " foo" + it "Escaping backslash itself when it makes sense" $ do + [qms| foo\nbar |] `shouldBe` "foo\nbar" + [qms| foo\\nbar |] `shouldBe` "foo\\nbar" + [qms| foo\tbar |] `shouldBe` "foo\tbar" + [qms| foo\\tbar |] `shouldBe` "foo\\tbar" + [qms| foo\ bar |] `shouldBe` "foo\tbar" + [qms| foo\\ bar |] `shouldBe` "foo\\\tbar" + [qms| foo\ bar |] `shouldBe` "foo bar" + [qms| foo\\ bar |] `shouldBe` "foo\\ bar" + [qms| foo\ + bar |] `shouldBe` "foobar" + [qms| foo\\ + bar |] `shouldBe` "foo\\ bar" + + describe "Escaping inside interpolation blocks" $ do + + it "Line-breaks must be interpreted as just haskell code" $ do + [qms| {'\n'} |] `shouldBe` "\n" + [qms| {"foo\nbar"} |] `shouldBe` "foo\nbar" + [qms| {"foo\\nbar"} |] `shouldBe` "foo\\nbar" + [qms| {"foo\\\nbar"} |] `shouldBe` "foo\\\nbar" + [qms| {"foo\\\\nbar"} |] `shouldBe` "foo\\\\nbar" + + it "Escaping for multiline strings" $ do + [qms| {"foo\ + \bar\ + \baz"} |] `shouldBe` "foobarbaz" + [qms| {"foo \ + \bar\ + \ baz"} |] `shouldBe` "foo bar baz" + [qms| x \ + {"foo \ + \bar\ + \ baz"} \ + y |] `shouldBe` "x foo bar baz y" + + it "Escaping of close-bracket '}'" $ do + [qms| { testFoo {testBar = 9000\} } |] + `shouldBe` show testFoo {testBar = 9000} + [qms| foo{ testFoo {testBar = 9000\} }bar |] + `shouldBe` "foo" ++ show testFoo {testBar = 9000} ++ "bar" + [qms|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|] + `shouldBe` "foo" ++ show testFoo2 {test1 = TestFoo 9000} ++ "bar" + [qms| foo { testFoo2 { + test1 = (test1 testFoo2) + { testBar = 9000 \} + \} + } bar |] + `shouldBe` "foo " ++ show testFoo2 {test1 = TestFoo 9000} ++ " bar" + [qms| {"\}"} |] `shouldBe` "}" + [qms| {"\\\}"} |] `shouldBe` "\\}" + [qms| {123}} |] `shouldBe` "123}" + + it "When interpolation block is escaped\ + \ everything must be interpreted as usual" $ do + [qms| \{ foo\nbar\\baz\} } |] `shouldBe` "{ foo\nbar\\baz\\} }" + [qms| \{ foo\ + bar } |] `shouldBe` "{ foobar }" + + it "Tabs characters in string inside interpolation block" $ do + [qms| {"foo\t\tbar" } |] `shouldBe` "foo\t\tbar" + [qms| {"foo bar" } |] `shouldBe` "foo\t\tbar" + [qms| {"foo\\t\tbar"} |] `shouldBe` "foo\\t\tbar" + describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do @@ -139,24 +216,44 @@ `shouldBe` "<article> <h1>Testing</h1> <p>Some testing text</p> </article>" + it "Can escape spaces" $ + [qms| you can escape spaces + \ when you need them |] + `shouldBe` + "you can escape spaces when you need them" + + -- By 'not really' it means that it just copied from `QM` and shows what + -- happens with the same input if you use it with this quoter. + it "Indentation and line breaks are ignored (not really)" $ + [qms| + indentation and li + ne bre + aks are i + gno + red + (not really) + |] + `shouldBe` "indentation and li ne bre aks are i gno red (not really)" + + it "Escaping indentation or line breaks" $ + [qms| \ You can escape indentation or\n + line breaks when you need them! \ |] + `shouldBe` + " You can escape indentation or\n line breaks when you need them! " + + it "Interpolation blocks can be escaped too" $ + [qms| Interpolation blocks can be escaped too: {1+2} \{3+4} |] + `shouldBe` + "Interpolation blocks can be escaped too: 3 {3+4}" + it "Interpolation" $ [qms| foo {1+2} |] `shouldBe` "foo 3" - it "Haddock example" $ + it "Haddock example" $ do + [qms| foo {'b':'a':'r':""} + baz |] `shouldBe` "foo bar baz" [qms| foo {'b':'a':'r':""} baz |] `shouldBe` "foo bar baz" - - it "Escaping backslash itself when it makes sense" $ do - [qms| foo\nbar |] `shouldBe` "foo\nbar" - [qms| foo\\nbar |] `shouldBe` "foo\\nbar" - [qms| foo\tbar |] `shouldBe` "foo\tbar" - [qms| foo\\tbar |] `shouldBe` "foo\\tbar" - [qms| foo\ bar |] `shouldBe` "foo\tbar" - [qms| foo\\ bar |] `shouldBe` "foo\\\tbar" - [qms| foo\ bar |] `shouldBe` "foo bar" - [qms| foo\\ bar |] `shouldBe` "foo\\ bar" - - [qms| foo\ - bar |] `shouldBe` "foobar" - [qms| foo\\ - bar |] `shouldBe` "foo\\ bar" + -- Double-space with escaping + [qms| foo {'b':'a':'r':""} + \ baz |] `shouldBe` "foo bar baz"
test/LineBreaks/CRLF/QN/Spec.hs view
@@ -1,4 +1,7 @@ -- This file automatically generated by generate-cr-and-crlf-tests.sh (do not modify!) +-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test! +{-# OPTIONS_GHC -fno-warn-tabs #-} + {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -36,34 +39,100 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qn| {1+2} \{3+4} |] `shouldBe` "{1+2} \\{3+4}" - it "Example of `qn` QuasiQuoter" $ - [qn| foo {1+2} |] `shouldBe` "foo {1+2}" + it "Empty string" $ [qn| |] `shouldBe` "" it "Type annotation in interpolation block" $ [qn|{10 :: Float}|] `shouldBe` "{10 :: Float}" - it "Escaping interpolation symbols inside interpolation block" $ do - [qn|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz" - [qn|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz" + describe "Escaping" $ do - it "Example from generated docs" $ - [qn| foo {'b':'a':'r':""} - \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz" + it "Escaping interpolation symbols inside interpolation block" $ do + [qn|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz" + [qn|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz" - it "Escaping backslashes" $ do [qn| foo\bar |] `shouldBe` "foo\\bar" - [qn| foo\\bar |] `shouldBe` "foo\\bar" - [qn| foo\\\bar |] `shouldBe` "foo\\\\bar" - [qn| foo\\\\bar |] `shouldBe` "foo\\\\bar" + it "Escaping backslashes" $ do [qn| foo\bar |] `shouldBe` "foo\\bar" + [qn| foo\\bar |] `shouldBe` "foo\\bar" + [qn| foo\\\bar |] `shouldBe` "foo\\\\bar" + [qn| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qn| |] `shouldBe` "" + it "Escaping space by slash at EOL after space" $ + [qn| foo \ + bar |] `shouldBe` "foo bar" - it "Escaping space by slash at EOL after space" $ - [qn| foo \ - bar |] `shouldBe` "foo bar" + it "Escaped spaces at the edges" $ do [qn| foo\ |] `shouldBe` "foo " + [qn|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qn| foo\ |] `shouldBe` "foo " - [qn|\ foo |] `shouldBe` " foo" + it "Escaping backslash itself when it makes sense" $ do + [qn| foo\nbar |] `shouldBe` "foo\nbar" + [qn| foo\\nbar |] `shouldBe` "foo\\nbar" + [qn| foo\tbar |] `shouldBe` "foo\tbar" + [qn| foo\\tbar |] `shouldBe` "foo\\tbar" + [qn| foo\ bar |] `shouldBe` "foo\tbar" + [qn| foo\\ bar |] `shouldBe` "foo\\\tbar" + [qn| foo\ bar |] `shouldBe` "foo bar" + [qn| foo\\ bar |] `shouldBe` "foo\\ bar" + [qn| foo\ + bar |] `shouldBe` "foobar" + [qn| foo\\ + bar |] `shouldBe` "foo\\bar" + + -- By 'not really' it means we just shows here what happens with examples + -- for QM when we use them with QN quoter. + describe "Escaping inside interpolation blocks (not really!)" $ do + + it "Line-breaks must be interpreted as just haskell code\ + \ (not really!)" $ do + [qn| {'\n'} |] `shouldBe` "{'\n'}" + [qn| {"foo\nbar"} |] `shouldBe` "{\"foo\nbar\"}" + [qn| {"foo\\nbar"} |] `shouldBe` "{\"foo\\nbar\"}" + [qn| {"foo\\\nbar"} |] `shouldBe` "{\"foo\\\nbar\"}" + [qn| {"foo\\\\nbar"} |] `shouldBe` "{\"foo\\\\nbar\"}" + + it "Escaping for multiline strings" $ do + [qn| {"foo\ + \bar\ + \baz"} |] `shouldBe` "{\"foo\\bar\\baz\"}" + [qn| {"foo \ + \bar\ + \ baz"} |] `shouldBe` "{\"foo \\bar baz\"}" + [qn| x \ + {"foo \ + \bar\ + \ baz"} \ + y |] `shouldBe` "x {\"foo \\bar baz\"} y" + + it "Escaping of close-bracket '}'" $ do + [qn| { testFoo {testBar = 9000\} } |] + `shouldBe` "{ testFoo {testBar = 9000\\} }" + [qn| foo{ testFoo {testBar = 9000\} }bar |] + `shouldBe` "foo{ testFoo {testBar = 9000\\} }bar" + [qn|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|] + `shouldBe` + "foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\\}\\}}bar" + [qn| foo { testFoo2 { + test1 = (test1 testFoo2) + { testBar = 9000 \} + \} + } bar |] + `shouldBe` "foo { testFoo2 {test1 = (test1 testFoo2)\ + \{ testBar = 9000 \\}\\}} bar" + [qn| {"\}"} |] `shouldBe` "{\"\\}\"}" + [qn| {"\\\}"} |] `shouldBe` "{\"\\\\}\"}" + [qn| {123}} |] `shouldBe` "{123}}" + + it "When interpolation block is escaped\ + \ everything must be interpreted as usual (not really)" $ do + [qn| \{ foo\nbar\\baz\} } |] `shouldBe` "\\{ foo\nbar\\baz\\} }" + [qn| \{ foo\ + bar } |] `shouldBe` "\\{ foobar }" + + it "Tabs characters in string inside interpolation block\ + \ (not really!)" $ do + [qn| {"foo\t\tbar" } |] `shouldBe` "{\"foo\t\tbar\" }" + [qn| {"foo bar" } |] `shouldBe` "{\"foo\t\tbar\" }" + [qn| {"foo\\t\tbar"} |] `shouldBe` "{\"foo\\t\tbar\"}" + describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do @@ -104,7 +173,13 @@ describe "New README examples" $ do - it "Simple usage example" $ do + it "First example" $ + [qn| Hello, + world! + Pi is {floor pi}.{floor $ (pi - 3) * 100}… |] + `shouldBe` "Hello,world!Pi is {floor pi}.{floor $ (pi - 3) * 100}…" + + it "Simple usage example" $ [qn| <article> <h1>{title}</h1> @@ -112,23 +187,40 @@ </article> |] `shouldBe` "<article><h1>{title}</h1><p>{text}</p></article>" + it "Can escape spaces" $ + [qn| you can escape spaces + \ when you need them |] + `shouldBe` + "you can escape spaces when you need them" + + it "Indentation and line breaks are ignored" $ + [qn| + indentation and li + ne bre + aks are i + gno + red + |] + `shouldBe` "indentation and line breaks are ignored" + + it "Escaping indentation or line breaks" $ + [qn| \ You can escape indentation or\n + line breaks when you need them! \ |] + `shouldBe` + " You can escape indentation or\nline breaks when you need them! " + + it "Interpolation blocks can be escaped too" $ + [qn| Interpolation blocks can be escaped too: {1+2} \{3+4} |] + `shouldBe` + "Interpolation blocks can be escaped too: {1+2} \\{3+4}" + it "Interpolation" $ [qn| foo {1+2} |] `shouldBe` "foo {1+2}" - it "Haddock example" $ + it "Haddock example" $ do [qn| foo {'b':'a':'r':""} \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz" - - it "Escaping backslash itself when it makes sense" $ do - [qn| foo\nbar |] `shouldBe` "foo\nbar" - [qn| foo\\nbar |] `shouldBe` "foo\\nbar" - [qn| foo\tbar |] `shouldBe` "foo\tbar" - [qn| foo\\tbar |] `shouldBe` "foo\\tbar" - [qn| foo\ bar |] `shouldBe` "foo\tbar" - [qn| foo\\ bar |] `shouldBe` "foo\\\tbar" - [qn| foo\ bar |] `shouldBe` "foo bar" - [qn| foo\\ bar |] `shouldBe` "foo\\ bar" - - [qn| foo\ - bar |] `shouldBe` "foobar" - [qn| foo\\ - bar |] `shouldBe` "foo\\bar" + [qn| foo + \ {'b':'a':'r':""} + \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz" + [qn| foo {'b':'a':'r':""} + baz |] `shouldBe` "foo {'b':'a':'r':\"\"}baz"
test/LineBreaks/CRLF/QNB/Spec.hs view
@@ -1,4 +1,7 @@ -- This file automatically generated by generate-cr-and-crlf-tests.sh (do not modify!) +-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test! +{-# OPTIONS_GHC -fno-warn-tabs #-} + {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -57,34 +60,101 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qnb| {1+2} \{3+4} |] `shouldBe` "{1+2} \\{3+4}" - it "Example of `qnb` QuasiQuoter" $ - [qnb| foo {1+2} |] `shouldBe` "foo {1+2}" + it "Empty string" $ [qnb| |] `shouldBe` "" it "Type annotation in interpolation block" $ [qnb|{10 :: Float}|] `shouldBe` "{10 :: Float}" - it "Escaping interpolation symbols inside interpolation block" $ do - [qnb|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz" - [qnb|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz" + describe "Escaping" $ do - it "Example from generated docs (double-space)" $ - [qnb| foo {'b':'a':'r':""} - \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"}\n baz" + it "Escaping interpolation symbols inside interpolation block" $ do + [qnb|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz" + [qnb|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz" - it "Escaping backslashes" $ do [qnb| foo\bar |] `shouldBe` "foo\\bar" - [qnb| foo\\bar |] `shouldBe` "foo\\bar" - [qnb| foo\\\bar |] `shouldBe` "foo\\\\bar" - [qnb| foo\\\\bar |] `shouldBe` "foo\\\\bar" + it "Escaping backslashes" $ do [qnb| foo\bar |] `shouldBe` "foo\\bar" + [qnb| foo\\bar |] `shouldBe` "foo\\bar" + [qnb| foo\\\bar |] `shouldBe` "foo\\\\bar" + [qnb| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qnb| |] `shouldBe` "" + it "Escaping space by backslash at EOL after space\ + \ (line break is cutted off)" $ + [qnb| foo \ + bar |] `shouldBe` "foo bar" - it "Escaping space by backslash at EOL after space (line break is cutted off)" $ - [qnb| foo \ - bar |] `shouldBe` "foo bar" + it "Escaped spaces at the edges" $ do [qnb| foo\ |] `shouldBe` "foo " + [qnb|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qnb| foo\ |] `shouldBe` "foo " - [qnb|\ foo |] `shouldBe` " foo" + it "Escaping backslash itself when it makes sense" $ do + [qnb| foo\nbar |] `shouldBe` "foo\nbar" + [qnb| foo\\nbar |] `shouldBe` "foo\\nbar" + [qnb| foo\tbar |] `shouldBe` "foo\tbar" + [qnb| foo\\tbar |] `shouldBe` "foo\\tbar" + [qnb| foo\ bar |] `shouldBe` "foo\tbar" + [qnb| foo\\ bar |] `shouldBe` "foo\\\tbar" + [qnb| foo\ bar |] `shouldBe` "foo bar" + [qnb| foo\\ bar |] `shouldBe` "foo\\ bar" + [qnb| foo\ + bar |] `shouldBe` "foobar" + [qnb| foo\\ + bar |] `shouldBe` "foo\\\nbar" + + -- By 'not really' it means we just shows here what happens with examples + -- for QMB when we use them with QNB quoter. + describe "Escaping inside interpolation blocks (not really!)" $ do + + it "Line-breaks must be interpreted as just haskell code\ + \ (not really!)" $ do + [qnb| {'\n'} |] `shouldBe` "{'\n'}" + [qnb| {"foo\nbar"} |] `shouldBe` "{\"foo\nbar\"}" + [qnb| {"foo\\nbar"} |] `shouldBe` "{\"foo\\nbar\"}" + [qnb| {"foo\\\nbar"} |] `shouldBe` "{\"foo\\\nbar\"}" + [qnb| {"foo\\\\nbar"} |] `shouldBe` "{\"foo\\\\nbar\"}" + + it "Escaping for multiline strings" $ do + [qnb| {"foo\ + \bar\ + \baz"} |] `shouldBe` "{\"foo\\bar\\baz\"}" + [qnb| {"foo \ + \bar\ + \ baz"} |] `shouldBe` "{\"foo \\bar baz\"}" + [qnb| x \ + {"foo \ + \bar\ + \ baz"} \ + y |] `shouldBe` "x {\"foo \\bar baz\"} y" + + it "Escaping of close-bracket '}'" $ do + [qnb| { testFoo {testBar = 9000\} } |] + `shouldBe` "{ testFoo {testBar = 9000\\} }" + [qnb| foo{ testFoo {testBar = 9000\} }bar |] + `shouldBe` "foo{ testFoo {testBar = 9000\\} }bar" + [qnb|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|] + `shouldBe` + "foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\\}\\}}bar" + [qnb| foo { testFoo2 { + test1 = (test1 testFoo2) + { testBar = 9000 \} + \} + } bar |] + `shouldBe` "foo { testFoo2 {\ntest1 = (test1 testFoo2)\n\ + \{ testBar = 9000 \\}\n\\}\n} bar" + [qnb| {"\}"} |] `shouldBe` "{\"\\}\"}" + [qnb| {"\\\}"} |] `shouldBe` "{\"\\\\}\"}" + [qnb| {123}} |] `shouldBe` "{123}}" + + it "When interpolation block is escaped\ + \ everything must be interpreted as usual (not really)" $ do + [qnb| \{ foo\nbar\\baz\} } |] `shouldBe` "\\{ foo\nbar\\baz\\} }" + [qnb| \{ foo\ + bar } |] `shouldBe` "\\{ foobar }" + + it "Tabs characters in string inside interpolation block\ + \ (not really)" $ do + [qnb| {"foo\t\tbar" } |] `shouldBe` "{\"foo\t\tbar\" }" + [qnb| {"foo bar" } |] `shouldBe` "{\"foo\t\tbar\" }" + [qnb| {"foo\\t\tbar"} |] `shouldBe` "{\"foo\\t\tbar\"}" + describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do @@ -125,7 +195,13 @@ describe "New README examples" $ do - it "Simple usage example" $ do + it "First example" $ + [qnb| Hello, + world! + Pi is {floor pi}.{floor $ (pi - 3) * 100}… |] + `shouldBe` "Hello,\nworld!\nPi is {floor pi}.{floor $ (pi - 3) * 100}…" + + it "Simple usage example" $ [qnb| <article> <h1>{title}</h1> @@ -135,24 +211,43 @@ `shouldBe` "<article>\n<h1>{title}</h1>\n<p>{text}</p>\n</article>" + it "Can escape spaces" $ + [qnb| you can escape spaces + \ when you need them |] + `shouldBe` + "you can escape spaces\n when you need them" + + -- By 'not really' it means that it just copied from `QM` and shows what + -- happens with the same input if you use it with this quoter. + it "Indentation and line breaks are ignored (not really)" $ + [qnb| + indentation and li + ne bre + aks are i + gno + red + (not really) + |] + `shouldBe` "indentation and li\nne bre\naks are i\ngno\nred\n(not really)" + + it "Escaping indentation or line breaks" $ + [qnb| \ You can escape indentation or\n + line breaks when you need them! \ |] + `shouldBe` + " You can escape indentation or\n\nline breaks when you need them! " + + it "Interpolation blocks can be escaped too" $ + [qnb| Interpolation blocks can be escaped too: {1+2} \{3+4} |] + `shouldBe` + "Interpolation blocks can be escaped too: {1+2} \\{3+4}" + it "Interpolation" $ [qnb| foo {1+2} |] `shouldBe` "foo {1+2}" - it "Haddock example" $ + it "Haddock example" $ do + [qnb| foo {'b':'a':'r':""} + baz |] `shouldBe` "foo {'b':'a':'r':\"\"}\nbaz" [qnb| foo {'b':'a':'r':""} baz |] `shouldBe` "foo\n{'b':'a':'r':\"\"}\nbaz" - - it "Escaping backslash itself when it makes sense" $ do - [qnb| foo\nbar |] `shouldBe` "foo\nbar" - [qnb| foo\\nbar |] `shouldBe` "foo\\nbar" - [qnb| foo\tbar |] `shouldBe` "foo\tbar" - [qnb| foo\\tbar |] `shouldBe` "foo\\tbar" - [qnb| foo\ bar |] `shouldBe` "foo\tbar" - [qnb| foo\\ bar |] `shouldBe` "foo\\\tbar" - [qnb| foo\ bar |] `shouldBe` "foo bar" - [qnb| foo\\ bar |] `shouldBe` "foo\\ bar" - - [qnb| foo\ - bar |] `shouldBe` "foobar" - [qnb| foo\\ - bar |] `shouldBe` "foo\\\nbar" + [qnb| foo {'b':'a':'r':""} + \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"}\n baz"
test/LineBreaks/CRLF/QNS/Spec.hs view
@@ -1,4 +1,7 @@ -- This file automatically generated by generate-cr-and-crlf-tests.sh (do not modify!) +-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test! +{-# OPTIONS_GHC -fno-warn-tabs #-} + {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -57,34 +60,101 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qns| {1+2} \{3+4} |] `shouldBe` "{1+2} \\{3+4}" - it "Example of `qns` QuasiQuoter" $ - [qns| foo {1+2} |] `shouldBe` "foo {1+2}" + it "Empty string" $ [qns| |] `shouldBe` "" it "Type annotation in interpolation block" $ [qns|{10 :: Float}|] `shouldBe` "{10 :: Float}" - it "Escaping interpolation symbols inside interpolation block" $ do - [qns|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz" - [qns|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz" + describe "Escaping" $ do - it "Example from generated docs (double-space)" $ - [qns| foo {'b':'a':'r':""} - \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz" + it "Escaping interpolation symbols inside interpolation block" $ do + [qns|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz" + [qns|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz" - it "Escaping backslashes" $ do [qns| foo\bar |] `shouldBe` "foo\\bar" - [qns| foo\\bar |] `shouldBe` "foo\\bar" - [qns| foo\\\bar |] `shouldBe` "foo\\\\bar" - [qns| foo\\\\bar |] `shouldBe` "foo\\\\bar" + it "Escaping backslashes" $ do [qns| foo\bar |] `shouldBe` "foo\\bar" + [qns| foo\\bar |] `shouldBe` "foo\\bar" + [qns| foo\\\bar |] `shouldBe` "foo\\\\bar" + [qns| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qns| |] `shouldBe` "" + it "Escaping space by backslash at EOL after space\ + \ (line break is cutted off)" $ + [qns| foo \ + bar |] `shouldBe` "foo bar" - it "Escaping space by backslash at EOL after space (line break is cutted off)" $ - [qns| foo \ - bar |] `shouldBe` "foo bar" + it "Escaped spaces at the edges" $ do [qns| foo\ |] `shouldBe` "foo " + [qns|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qns| foo\ |] `shouldBe` "foo " - [qns|\ foo |] `shouldBe` " foo" + it "Escaping backslash itself when it makes sense" $ do + [qns| foo\nbar |] `shouldBe` "foo\nbar" + [qns| foo\\nbar |] `shouldBe` "foo\\nbar" + [qns| foo\tbar |] `shouldBe` "foo\tbar" + [qns| foo\\tbar |] `shouldBe` "foo\\tbar" + [qns| foo\ bar |] `shouldBe` "foo\tbar" + [qns| foo\\ bar |] `shouldBe` "foo\\\tbar" + [qns| foo\ bar |] `shouldBe` "foo bar" + [qns| foo\\ bar |] `shouldBe` "foo\\ bar" + [qns| foo\ + bar |] `shouldBe` "foobar" + [qns| foo\\ + bar |] `shouldBe` "foo\\ bar" + + -- By 'not really' it means we just shows here what happens with examples + -- for QMS when we use them with QNS quoter. + describe "Escaping inside interpolation blocks (not really!)" $ do + + it "Line-breaks must be interpreted as just haskell code\ + \ (not really!)" $ do + [qns| {'\n'} |] `shouldBe` "{'\n'}" + [qns| {"foo\nbar"} |] `shouldBe` "{\"foo\nbar\"}" + [qns| {"foo\\nbar"} |] `shouldBe` "{\"foo\\nbar\"}" + [qns| {"foo\\\nbar"} |] `shouldBe` "{\"foo\\\nbar\"}" + [qns| {"foo\\\\nbar"} |] `shouldBe` "{\"foo\\\\nbar\"}" + + it "Escaping for multiline strings" $ do + [qns| {"foo\ + \bar\ + \baz"} |] `shouldBe` "{\"foo\\bar\\baz\"}" + [qns| {"foo \ + \bar\ + \ baz"} |] `shouldBe` "{\"foo \\bar baz\"}" + [qns| x \ + {"foo \ + \bar\ + \ baz"} \ + y |] `shouldBe` "x {\"foo \\bar baz\"} y" + + it "Escaping of close-bracket '}'" $ do + [qns| { testFoo {testBar = 9000\} } |] + `shouldBe` "{ testFoo {testBar = 9000\\} }" + [qns| foo{ testFoo {testBar = 9000\} }bar |] + `shouldBe` "foo{ testFoo {testBar = 9000\\} }bar" + [qns|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|] + `shouldBe` + "foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\\}\\}}bar" + [qns| foo { testFoo2 { + test1 = (test1 testFoo2) + { testBar = 9000 \} + \} + } bar |] + `shouldBe` "foo { testFoo2 { test1 = (test1 testFoo2)\ + \ { testBar = 9000 \\} \\} } bar" + [qns| {"\}"} |] `shouldBe` "{\"\\}\"}" + [qns| {"\\\}"} |] `shouldBe` "{\"\\\\}\"}" + [qns| {123}} |] `shouldBe` "{123}}" + + it "When interpolation block is escaped\ + \ everything must be interpreted as usual (not really)" $ do + [qns| \{ foo\nbar\\baz\} } |] `shouldBe` "\\{ foo\nbar\\baz\\} }" + [qns| \{ foo\ + bar } |] `shouldBe` "\\{ foobar }" + + it "Tabs characters in string inside interpolation block\ + \ (not really)" $ do + [qns| {"foo\t\tbar" } |] `shouldBe` "{\"foo\t\tbar\" }" + [qns| {"foo bar" } |] `shouldBe` "{\"foo\t\tbar\" }" + [qns| {"foo\\t\tbar"} |] `shouldBe` "{\"foo\\t\tbar\"}" + describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do @@ -125,7 +195,13 @@ describe "New README examples" $ do - it "Simple usage example" $ do + it "First example" $ + [qns| Hello, + world! + Pi is {floor pi}.{floor $ (pi - 3) * 100}… |] + `shouldBe` "Hello, world! Pi is {floor pi}.{floor $ (pi - 3) * 100}…" + + it "Simple usage example" $ [qns| <article> <h1>{title}</h1> @@ -135,24 +211,44 @@ `shouldBe` "<article> <h1>{title}</h1> <p>{text}</p> </article>" + it "Can escape spaces" $ + [qns| you can escape spaces + \ when you need them |] + `shouldBe` + "you can escape spaces when you need them" + + -- By 'not really' it means that it just copied from `QM` and shows what + -- happens with the same input if you use it with this quoter. + it "Indentation and line breaks are ignored (not really)" $ + [qns| + indentation and li + ne bre + aks are i + gno + red + (not really) + |] + `shouldBe` "indentation and li ne bre aks are i gno red (not really)" + + it "Escaping indentation or line breaks" $ + [qns| \ You can escape indentation or\n + line breaks when you need them! \ |] + `shouldBe` + " You can escape indentation or\n line breaks when you need them! " + + it "Interpolation blocks can be escaped too" $ + [qns| Interpolation blocks can be escaped too: {1+2} \{3+4} |] + `shouldBe` + "Interpolation blocks can be escaped too: {1+2} \\{3+4}" + it "Interpolation" $ [qns| foo {1+2} |] `shouldBe` "foo {1+2}" - it "Haddock example" $ + it "Haddock example" $ do + [qns| foo {'b':'a':'r':""} + baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz" [qns| foo {'b':'a':'r':""} baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz" - - it "Escaping backslash itself when it makes sense" $ do - [qns| foo\nbar |] `shouldBe` "foo\nbar" - [qns| foo\\nbar |] `shouldBe` "foo\\nbar" - [qns| foo\tbar |] `shouldBe` "foo\tbar" - [qns| foo\\tbar |] `shouldBe` "foo\\tbar" - [qns| foo\ bar |] `shouldBe` "foo\tbar" - [qns| foo\\ bar |] `shouldBe` "foo\\\tbar" - [qns| foo\ bar |] `shouldBe` "foo bar" - [qns| foo\\ bar |] `shouldBe` "foo\\ bar" - - [qns| foo\ - bar |] `shouldBe` "foobar" - [qns| foo\\ - bar |] `shouldBe` "foo\\ bar" + -- Double-space with escaping + [qns| foo {'b':'a':'r':""} + \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz"
test/QM/Spec.hs view
@@ -1,3 +1,6 @@+-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test!+{-# OPTIONS_GHC -fno-warn-tabs #-}+ {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -8,7 +11,16 @@ -- local imports import "qm-interpolated-string" Text.InterpolatedString.QM (qm) +newtype TestFoo = TestFoo {testBar :: Int} deriving (Show)+newtype TestFoo2 = TestFoo2 {test1 :: TestFoo} deriving (Show) +testFoo :: TestFoo+testFoo = TestFoo 42++testFoo2 :: TestFoo2+testFoo2 = TestFoo2 testFoo++ spec :: Spec spec = do @@ -35,30 +47,94 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qm| {1+2} \{3+4} |] `shouldBe` "3 {3+4}" + it "Empty string" $ [qm| |] `shouldBe` ""+ it "Type annotation in interpolation block" $ [qm|{10 :: Float}|] `shouldBe` "10.0" - it "Escaping interpolation symbols inside interpolation block" $ do- [qm|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz"- [qm|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz"+ describe "Escaping" $ do - it "Example from generated docs" $ [qm| foo {'b':'a':'r':""}- \ baz |] `shouldBe` "foo bar baz"+ it "Escaping interpolation symbols inside interpolation block" $ do+ [qm|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz"+ [qm|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz" - it "Escaping backslashes" $ do [qm| foo\bar |] `shouldBe` "foo\\bar"- [qm| foo\\bar |] `shouldBe` "foo\\bar"- [qm| foo\\\bar |] `shouldBe` "foo\\\\bar"- [qm| foo\\\\bar |] `shouldBe` "foo\\\\bar"+ it "Escaping backslashes" $ do [qm| foo\bar |] `shouldBe` "foo\\bar"+ [qm| foo\\bar |] `shouldBe` "foo\\bar"+ [qm| foo\\\bar |] `shouldBe` "foo\\\\bar"+ [qm| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qm| |] `shouldBe` ""+ it "Escaping space by slash at EOL after space" $+ [qm| foo \+ bar |] `shouldBe` "foo bar" - it "Escaping space by slash at EOL after space" $- [qm| foo \- bar |] `shouldBe` "foo bar"+ it "Escaped spaces at the edges" $ do [qm| foo\ |] `shouldBe` "foo "+ [qm|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qm| foo\ |] `shouldBe` "foo "- [qm|\ foo |] `shouldBe` " foo"+ it "Escaping backslash itself when it makes sense" $ do+ [qm| foo\nbar |] `shouldBe` "foo\nbar"+ [qm| foo\\nbar |] `shouldBe` "foo\\nbar"+ [qm| foo\tbar |] `shouldBe` "foo\tbar"+ [qm| foo\\tbar |] `shouldBe` "foo\\tbar"+ [qm| foo\ bar |] `shouldBe` "foo\tbar"+ [qm| foo\\ bar |] `shouldBe` "foo\\\tbar"+ [qm| foo\ bar |] `shouldBe` "foo bar"+ [qm| foo\\ bar |] `shouldBe` "foo\\ bar" + [qm| foo\+ bar |] `shouldBe` "foobar"+ [qm| foo\\+ bar |] `shouldBe` "foo\\bar"++ describe "Escaping inside interpolation blocks" $ do++ it "Line-breaks must be interpreted as just haskell code" $ do+ [qm| {'\n'} |] `shouldBe` "\n"+ [qm| {"foo\nbar"} |] `shouldBe` "foo\nbar"+ [qm| {"foo\\nbar"} |] `shouldBe` "foo\\nbar"+ [qm| {"foo\\\nbar"} |] `shouldBe` "foo\\\nbar"+ [qm| {"foo\\\\nbar"} |] `shouldBe` "foo\\\\nbar"++ it "Escaping for multiline strings" $ do+ [qm| {"foo\+ \bar\+ \baz"} |] `shouldBe` "foobarbaz"+ [qm| {"foo \+ \bar\+ \ baz"} |] `shouldBe` "foo bar baz"+ [qm| x \+ {"foo \+ \bar\+ \ baz"} \+ y |] `shouldBe` "x foo bar baz y"++ it "Escaping of close-bracket '}'" $ do+ [qm| { testFoo {testBar = 9000\} } |]+ `shouldBe` show testFoo {testBar = 9000}+ [qm| foo{ testFoo {testBar = 9000\} }bar |]+ `shouldBe` "foo" ++ show testFoo {testBar = 9000} ++ "bar"+ [qm|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|]+ `shouldBe` "foo" ++ show testFoo2 {test1 = TestFoo 9000} ++ "bar"+ [qm| foo { testFoo2 {+ test1 = (test1 testFoo2)+ { testBar = 9000 \}+ \}+ } bar |]+ `shouldBe` "foo " ++ show testFoo2 {test1 = TestFoo 9000} ++ " bar"+ [qm| {"\}"} |] `shouldBe` "}"+ [qm| {"\\\}"} |] `shouldBe` "\\}"+ [qm| {123}} |] `shouldBe` "123}"++ it "When interpolation block is escaped\+ \ everything must be interpreted as usual" $ do+ [qm| \{ foo\nbar\\baz\} } |] `shouldBe` "{ foo\nbar\\baz\\} }"+ [qm| \{ foo\+ bar } |] `shouldBe` "{ foobar }"++ it "Tabs characters in string inside interpolation block" $ do+ [qm| {"foo\t\tbar" } |] `shouldBe` "foo\t\tbar"+ [qm| {"foo bar" } |] `shouldBe` "foo\t\tbar"+ [qm| {"foo\\t\tbar"} |] `shouldBe` "foo\\t\tbar"+ describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do@@ -99,6 +175,12 @@ describe "New README examples" $ do + it "First example" $+ [qm| Hello,+ world!+ Pi is {floor pi}.{floor $ (pi - 3) * 100}… |]+ `shouldBe` "Hello,world!Pi is 3.14…"+ it "Simple usage example" $ do let title = "Testing" text = "Some testing text"@@ -117,7 +199,7 @@ `shouldBe` "you can escape spaces when you need them" - it "Indentation and line breaks are ignored" $ + it "Indentation and line breaks are ignored" $ [qm| indentation and li ne bre@@ -140,21 +222,11 @@ it "Interpolation" $ [qm| foo {1+2} |] `shouldBe` "foo 3" - it "Haddock example" $+ it "Haddock example" $ do [qm| foo {'b':'a':'r':""} \ baz |] `shouldBe` "foo bar baz"-- it "Escaping backslash itself when it makes sense" $ do- [qm| foo\nbar |] `shouldBe` "foo\nbar"- [qm| foo\\nbar |] `shouldBe` "foo\\nbar"- [qm| foo\tbar |] `shouldBe` "foo\tbar"- [qm| foo\\tbar |] `shouldBe` "foo\\tbar"- [qm| foo\ bar |] `shouldBe` "foo\tbar"- [qm| foo\\ bar |] `shouldBe` "foo\\\tbar"- [qm| foo\ bar |] `shouldBe` "foo bar"- [qm| foo\\ bar |] `shouldBe` "foo\\ bar"-- [qm| foo\- bar |] `shouldBe` "foobar"- [qm| foo\\- bar |] `shouldBe` "foo\\bar"+ [qm| foo+ \ {'b':'a':'r':""}+ \ baz |] `shouldBe` "foo bar baz"+ [qm| foo {'b':'a':'r':""}+ baz |] `shouldBe` "foo barbaz"
test/QMB/Spec.hs view
@@ -1,3 +1,6 @@+-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test!+{-# OPTIONS_GHC -fno-warn-tabs #-}+ {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -8,7 +11,16 @@ -- local imports import "qm-interpolated-string" Text.InterpolatedString.QM (qmb) +newtype TestFoo = TestFoo {testBar :: Int} deriving (Show)+newtype TestFoo2 = TestFoo2 {test1 :: TestFoo} deriving (Show) +testFoo :: TestFoo+testFoo = TestFoo 42++testFoo2 :: TestFoo2+testFoo2 = TestFoo2 testFoo++ spec :: Spec spec = do @@ -56,30 +68,95 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qmb| {1+2} \{3+4} |] `shouldBe` "3 {3+4}" + it "Empty string" $ [qmb| |] `shouldBe` ""+ it "Type annotation in interpolation block" $ [qmb|{10 :: Float}|] `shouldBe` "10.0" - it "Escaping interpolation symbols inside interpolation block" $ do- [qmb|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz"- [qmb|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz"+ describe "Escaping" $ do - it "Example from generated docs" $ [qmb| foo {'b':'a':'r':""}- \ baz |] `shouldBe` "foo bar\n baz"+ it "Escaping interpolation symbols inside interpolation block" $ do+ [qmb|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz"+ [qmb|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz" - it "Escaping backslashes" $ do [qmb| foo\bar |] `shouldBe` "foo\\bar"- [qmb| foo\\bar |] `shouldBe` "foo\\bar"- [qmb| foo\\\bar |] `shouldBe` "foo\\\\bar"- [qmb| foo\\\\bar |] `shouldBe` "foo\\\\bar"+ it "Escaping backslashes" $ do [qmb| foo\bar |] `shouldBe` "foo\\bar"+ [qmb| foo\\bar |] `shouldBe` "foo\\bar"+ [qmb| foo\\\bar |] `shouldBe` "foo\\\\bar"+ [qmb| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qmb| |] `shouldBe` ""+ it "Escaping space by backslash at EOL after space\+ \ (line break is cutted off)" $+ [qmb| foo \+ bar |] `shouldBe` "foo bar" - it "Escaping space by backslash at EOL after space (line break is cutted off)" $- [qmb| foo \- bar |] `shouldBe` "foo bar"+ it "Escaped spaces at the edges" $ do [qmb| foo\ |] `shouldBe` "foo "+ [qmb|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qmb| foo\ |] `shouldBe` "foo "- [qmb|\ foo |] `shouldBe` " foo"+ it "Escaping backslash itself when it makes sense" $ do+ [qmb| foo\nbar |] `shouldBe` "foo\nbar"+ [qmb| foo\\nbar |] `shouldBe` "foo\\nbar"+ [qmb| foo\tbar |] `shouldBe` "foo\tbar"+ [qmb| foo\\tbar |] `shouldBe` "foo\\tbar"+ [qmb| foo\ bar |] `shouldBe` "foo\tbar"+ [qmb| foo\\ bar |] `shouldBe` "foo\\\tbar"+ [qmb| foo\ bar |] `shouldBe` "foo bar"+ [qmb| foo\\ bar |] `shouldBe` "foo\\ bar" + [qmb| foo\+ bar |] `shouldBe` "foobar"+ [qmb| foo\\+ bar |] `shouldBe` "foo\\\nbar"++ describe "Escaping inside interpolation blocks" $ do++ it "Line-breaks must be interpreted as just haskell code" $ do+ [qmb| {'\n'} |] `shouldBe` "\n"+ [qmb| {"foo\nbar"} |] `shouldBe` "foo\nbar"+ [qmb| {"foo\\nbar"} |] `shouldBe` "foo\\nbar"+ [qmb| {"foo\\\nbar"} |] `shouldBe` "foo\\\nbar"+ [qmb| {"foo\\\\nbar"} |] `shouldBe` "foo\\\\nbar"++ it "Escaping for multiline strings" $ do+ [qmb| {"foo\+ \bar\+ \baz"} |] `shouldBe` "foobarbaz"+ [qmb| {"foo \+ \bar\+ \ baz"} |] `shouldBe` "foo bar baz"+ [qmb| x \+ {"foo \+ \bar\+ \ baz"} \+ y |] `shouldBe` "x foo bar baz y"++ it "Escaping of close-bracket '}'" $ do+ [qmb| { testFoo {testBar = 9000\} } |]+ `shouldBe` show testFoo {testBar = 9000}+ [qmb| foo{ testFoo {testBar = 9000\} }bar |]+ `shouldBe` "foo" ++ show testFoo {testBar = 9000} ++ "bar"+ [qmb|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|]+ `shouldBe` "foo" ++ show testFoo2 {test1 = TestFoo 9000} ++ "bar"+ [qmb| foo { testFoo2 {+ test1 = (test1 testFoo2)+ { testBar = 9000 \}+ \}+ } bar |]+ `shouldBe` "foo " ++ show testFoo2 {test1 = TestFoo 9000} ++ " bar"+ [qmb| {"\}"} |] `shouldBe` "}"+ [qmb| {"\\\}"} |] `shouldBe` "\\}"+ [qmb| {123}} |] `shouldBe` "123}"++ it "When interpolation block is escaped\+ \ everything must be interpreted as usual" $ do+ [qmb| \{ foo\nbar\\baz\} } |] `shouldBe` "{ foo\nbar\\baz\\} }"+ [qmb| \{ foo\+ bar } |] `shouldBe` "{ foobar }"++ it "Tabs characters in string inside interpolation block" $ do+ [qmb| {"foo\t\tbar" } |] `shouldBe` "foo\t\tbar"+ [qmb| {"foo bar" } |] `shouldBe` "foo\t\tbar"+ [qmb| {"foo\\t\tbar"} |] `shouldBe` "foo\\t\tbar"+ describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do@@ -120,6 +197,12 @@ describe "New README examples" $ do + it "First example" $+ [qmb| Hello,+ world!+ Pi is {floor pi}.{floor $ (pi - 3) * 100}… |]+ `shouldBe` "Hello,\nworld!\nPi is 3.14…"+ it "Simple usage example" $ do let title = "Testing" text = "Some testing text"@@ -132,24 +215,43 @@ `shouldBe` "<article>\n<h1>Testing</h1>\n<p>Some testing text</p>\n</article>" + it "Can escape spaces" $+ [qmb| you can escape spaces+ \ when you need them |]+ `shouldBe`+ "you can escape spaces\n when you need them"++ -- By 'not really' it means that it just copied from `QM` and shows what+ -- happens with the same input if you use it with this quoter.+ it "Indentation and line breaks are ignored (not really)" $+ [qmb|+ indentation and li+ ne bre+ aks are i+ gno+ red+ (not really)+ |]+ `shouldBe` "indentation and li\nne bre\naks are i\ngno\nred\n(not really)"++ it "Escaping indentation or line breaks" $+ [qmb| \ You can escape indentation or\n+ line breaks when you need them! \ |]+ `shouldBe`+ " You can escape indentation or\n\nline breaks when you need them! "++ it "Interpolation blocks can be escaped too" $+ [qmb| Interpolation blocks can be escaped too: {1+2} \{3+4} |]+ `shouldBe`+ "Interpolation blocks can be escaped too: 3 {3+4}"+ it "Interpolation" $ [qmb| foo {1+2} |] `shouldBe` "foo 3" - it "Haddock example" $+ it "Haddock example" $ do+ [qmb| foo {'b':'a':'r':""}+ baz |] `shouldBe` "foo bar\nbaz" [qmb| foo {'b':'a':'r':""} baz |] `shouldBe` "foo\nbar\nbaz"-- it "Escaping backslash itself when it makes sense" $ do- [qmb| foo\nbar |] `shouldBe` "foo\nbar"- [qmb| foo\\nbar |] `shouldBe` "foo\\nbar"- [qmb| foo\tbar |] `shouldBe` "foo\tbar"- [qmb| foo\\tbar |] `shouldBe` "foo\\tbar"- [qmb| foo\ bar |] `shouldBe` "foo\tbar"- [qmb| foo\\ bar |] `shouldBe` "foo\\\tbar"- [qmb| foo\ bar |] `shouldBe` "foo bar"- [qmb| foo\\ bar |] `shouldBe` "foo\\ bar"-- [qmb| foo\- bar |] `shouldBe` "foobar"- [qmb| foo\\- bar |] `shouldBe` "foo\\\nbar"+ [qmb| foo {'b':'a':'r':""}+ \ baz |] `shouldBe` "foo bar\n baz"
test/QMS/Spec.hs view
@@ -1,3 +1,6 @@+-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test!+{-# OPTIONS_GHC -fno-warn-tabs #-}+ {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -8,7 +11,16 @@ -- local imports import "qm-interpolated-string" Text.InterpolatedString.QM (qms) +newtype TestFoo = TestFoo {testBar :: Int} deriving (Show)+newtype TestFoo2 = TestFoo2 {test1 :: TestFoo} deriving (Show) +testFoo :: TestFoo+testFoo = TestFoo 42++testFoo2 :: TestFoo2+testFoo2 = TestFoo2 testFoo++ spec :: Spec spec = do @@ -56,30 +68,95 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qms| {1+2} \{3+4} |] `shouldBe` "3 {3+4}" + it "Empty string" $ [qms| |] `shouldBe` ""+ it "Type annotation in interpolation block" $ [qms|{10 :: Float}|] `shouldBe` "10.0" - it "Escaping interpolation symbols inside interpolation block" $ do- [qms|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz"- [qms|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz"+ describe "Escaping" $ do - it "Example from generated docs" $ [qms| foo {'b':'a':'r':""}- \ baz |] `shouldBe` "foo bar baz"+ it "Escaping interpolation symbols inside interpolation block" $ do+ [qms|foo {"b{a{r"} baz|] `shouldBe` "foo b{a{r baz"+ [qms|foo {"b\}a\}r"} baz|] `shouldBe` "foo b}a}r baz" - it "Escaping backslashes" $ do [qms| foo\bar |] `shouldBe` "foo\\bar"- [qms| foo\\bar |] `shouldBe` "foo\\bar"- [qms| foo\\\bar |] `shouldBe` "foo\\\\bar"- [qms| foo\\\\bar |] `shouldBe` "foo\\\\bar"+ it "Escaping backslashes" $ do [qms| foo\bar |] `shouldBe` "foo\\bar"+ [qms| foo\\bar |] `shouldBe` "foo\\bar"+ [qms| foo\\\bar |] `shouldBe` "foo\\\\bar"+ [qms| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qms| |] `shouldBe` ""+ it "Escaping space by backslash at EOL after space\+ \ (line break is cutted off)" $+ [qms| foo \+ bar |] `shouldBe` "foo bar" - it "Escaping space by backslash at EOL after space (line break is cutted off)" $- [qms| foo \- bar |] `shouldBe` "foo bar"+ it "Escaped spaces at the edges" $ do [qms| foo\ |] `shouldBe` "foo "+ [qms|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qms| foo\ |] `shouldBe` "foo "- [qms|\ foo |] `shouldBe` " foo"+ it "Escaping backslash itself when it makes sense" $ do+ [qms| foo\nbar |] `shouldBe` "foo\nbar"+ [qms| foo\\nbar |] `shouldBe` "foo\\nbar"+ [qms| foo\tbar |] `shouldBe` "foo\tbar"+ [qms| foo\\tbar |] `shouldBe` "foo\\tbar"+ [qms| foo\ bar |] `shouldBe` "foo\tbar"+ [qms| foo\\ bar |] `shouldBe` "foo\\\tbar"+ [qms| foo\ bar |] `shouldBe` "foo bar"+ [qms| foo\\ bar |] `shouldBe` "foo\\ bar" + [qms| foo\+ bar |] `shouldBe` "foobar"+ [qms| foo\\+ bar |] `shouldBe` "foo\\ bar"++ describe "Escaping inside interpolation blocks" $ do++ it "Line-breaks must be interpreted as just haskell code" $ do+ [qms| {'\n'} |] `shouldBe` "\n"+ [qms| {"foo\nbar"} |] `shouldBe` "foo\nbar"+ [qms| {"foo\\nbar"} |] `shouldBe` "foo\\nbar"+ [qms| {"foo\\\nbar"} |] `shouldBe` "foo\\\nbar"+ [qms| {"foo\\\\nbar"} |] `shouldBe` "foo\\\\nbar"++ it "Escaping for multiline strings" $ do+ [qms| {"foo\+ \bar\+ \baz"} |] `shouldBe` "foobarbaz"+ [qms| {"foo \+ \bar\+ \ baz"} |] `shouldBe` "foo bar baz"+ [qms| x \+ {"foo \+ \bar\+ \ baz"} \+ y |] `shouldBe` "x foo bar baz y"++ it "Escaping of close-bracket '}'" $ do+ [qms| { testFoo {testBar = 9000\} } |]+ `shouldBe` show testFoo {testBar = 9000}+ [qms| foo{ testFoo {testBar = 9000\} }bar |]+ `shouldBe` "foo" ++ show testFoo {testBar = 9000} ++ "bar"+ [qms|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|]+ `shouldBe` "foo" ++ show testFoo2 {test1 = TestFoo 9000} ++ "bar"+ [qms| foo { testFoo2 {+ test1 = (test1 testFoo2)+ { testBar = 9000 \}+ \}+ } bar |]+ `shouldBe` "foo " ++ show testFoo2 {test1 = TestFoo 9000} ++ " bar"+ [qms| {"\}"} |] `shouldBe` "}"+ [qms| {"\\\}"} |] `shouldBe` "\\}"+ [qms| {123}} |] `shouldBe` "123}"++ it "When interpolation block is escaped\+ \ everything must be interpreted as usual" $ do+ [qms| \{ foo\nbar\\baz\} } |] `shouldBe` "{ foo\nbar\\baz\\} }"+ [qms| \{ foo\+ bar } |] `shouldBe` "{ foobar }"++ it "Tabs characters in string inside interpolation block" $ do+ [qms| {"foo\t\tbar" } |] `shouldBe` "foo\t\tbar"+ [qms| {"foo bar" } |] `shouldBe` "foo\t\tbar"+ [qms| {"foo\\t\tbar"} |] `shouldBe` "foo\\t\tbar"+ describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do@@ -138,24 +215,44 @@ `shouldBe` "<article> <h1>Testing</h1> <p>Some testing text</p> </article>" + it "Can escape spaces" $+ [qms| you can escape spaces+ \ when you need them |]+ `shouldBe`+ "you can escape spaces when you need them"++ -- By 'not really' it means that it just copied from `QM` and shows what+ -- happens with the same input if you use it with this quoter.+ it "Indentation and line breaks are ignored (not really)" $+ [qms|+ indentation and li+ ne bre+ aks are i+ gno+ red+ (not really)+ |]+ `shouldBe` "indentation and li ne bre aks are i gno red (not really)"++ it "Escaping indentation or line breaks" $+ [qms| \ You can escape indentation or\n+ line breaks when you need them! \ |]+ `shouldBe`+ " You can escape indentation or\n line breaks when you need them! "++ it "Interpolation blocks can be escaped too" $+ [qms| Interpolation blocks can be escaped too: {1+2} \{3+4} |]+ `shouldBe`+ "Interpolation blocks can be escaped too: 3 {3+4}"+ it "Interpolation" $ [qms| foo {1+2} |] `shouldBe` "foo 3" - it "Haddock example" $+ it "Haddock example" $ do+ [qms| foo {'b':'a':'r':""}+ baz |] `shouldBe` "foo bar baz" [qms| foo {'b':'a':'r':""} baz |] `shouldBe` "foo bar baz"-- it "Escaping backslash itself when it makes sense" $ do- [qms| foo\nbar |] `shouldBe` "foo\nbar"- [qms| foo\\nbar |] `shouldBe` "foo\\nbar"- [qms| foo\tbar |] `shouldBe` "foo\tbar"- [qms| foo\\tbar |] `shouldBe` "foo\\tbar"- [qms| foo\ bar |] `shouldBe` "foo\tbar"- [qms| foo\\ bar |] `shouldBe` "foo\\\tbar"- [qms| foo\ bar |] `shouldBe` "foo bar"- [qms| foo\\ bar |] `shouldBe` "foo\\ bar"-- [qms| foo\- bar |] `shouldBe` "foobar"- [qms| foo\\- bar |] `shouldBe` "foo\\ bar"+ -- Double-space with escaping+ [qms| foo {'b':'a':'r':""}+ \ baz |] `shouldBe` "foo bar baz"
test/QN/Spec.hs view
@@ -1,3 +1,6 @@+-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test!+{-# OPTIONS_GHC -fno-warn-tabs #-}+ {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -35,34 +38,100 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qn| {1+2} \{3+4} |] `shouldBe` "{1+2} \\{3+4}" - it "Example of `qn` QuasiQuoter" $- [qn| foo {1+2} |] `shouldBe` "foo {1+2}"+ it "Empty string" $ [qn| |] `shouldBe` "" it "Type annotation in interpolation block" $ [qn|{10 :: Float}|] `shouldBe` "{10 :: Float}" - it "Escaping interpolation symbols inside interpolation block" $ do- [qn|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz"- [qn|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz"+ describe "Escaping" $ do - it "Example from generated docs" $- [qn| foo {'b':'a':'r':""}- \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz"+ it "Escaping interpolation symbols inside interpolation block" $ do+ [qn|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz"+ [qn|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz" - it "Escaping backslashes" $ do [qn| foo\bar |] `shouldBe` "foo\\bar"- [qn| foo\\bar |] `shouldBe` "foo\\bar"- [qn| foo\\\bar |] `shouldBe` "foo\\\\bar"- [qn| foo\\\\bar |] `shouldBe` "foo\\\\bar"+ it "Escaping backslashes" $ do [qn| foo\bar |] `shouldBe` "foo\\bar"+ [qn| foo\\bar |] `shouldBe` "foo\\bar"+ [qn| foo\\\bar |] `shouldBe` "foo\\\\bar"+ [qn| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qn| |] `shouldBe` ""+ it "Escaping space by slash at EOL after space" $+ [qn| foo \+ bar |] `shouldBe` "foo bar" - it "Escaping space by slash at EOL after space" $- [qn| foo \- bar |] `shouldBe` "foo bar"+ it "Escaped spaces at the edges" $ do [qn| foo\ |] `shouldBe` "foo "+ [qn|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qn| foo\ |] `shouldBe` "foo "- [qn|\ foo |] `shouldBe` " foo"+ it "Escaping backslash itself when it makes sense" $ do+ [qn| foo\nbar |] `shouldBe` "foo\nbar"+ [qn| foo\\nbar |] `shouldBe` "foo\\nbar"+ [qn| foo\tbar |] `shouldBe` "foo\tbar"+ [qn| foo\\tbar |] `shouldBe` "foo\\tbar"+ [qn| foo\ bar |] `shouldBe` "foo\tbar"+ [qn| foo\\ bar |] `shouldBe` "foo\\\tbar"+ [qn| foo\ bar |] `shouldBe` "foo bar"+ [qn| foo\\ bar |] `shouldBe` "foo\\ bar" + [qn| foo\+ bar |] `shouldBe` "foobar"+ [qn| foo\\+ bar |] `shouldBe` "foo\\bar"++ -- By 'not really' it means we just shows here what happens with examples+ -- for QM when we use them with QN quoter.+ describe "Escaping inside interpolation blocks (not really!)" $ do++ it "Line-breaks must be interpreted as just haskell code\+ \ (not really!)" $ do+ [qn| {'\n'} |] `shouldBe` "{'\n'}"+ [qn| {"foo\nbar"} |] `shouldBe` "{\"foo\nbar\"}"+ [qn| {"foo\\nbar"} |] `shouldBe` "{\"foo\\nbar\"}"+ [qn| {"foo\\\nbar"} |] `shouldBe` "{\"foo\\\nbar\"}"+ [qn| {"foo\\\\nbar"} |] `shouldBe` "{\"foo\\\\nbar\"}"++ it "Escaping for multiline strings" $ do+ [qn| {"foo\+ \bar\+ \baz"} |] `shouldBe` "{\"foo\\bar\\baz\"}"+ [qn| {"foo \+ \bar\+ \ baz"} |] `shouldBe` "{\"foo \\bar baz\"}"+ [qn| x \+ {"foo \+ \bar\+ \ baz"} \+ y |] `shouldBe` "x {\"foo \\bar baz\"} y"++ it "Escaping of close-bracket '}'" $ do+ [qn| { testFoo {testBar = 9000\} } |]+ `shouldBe` "{ testFoo {testBar = 9000\\} }"+ [qn| foo{ testFoo {testBar = 9000\} }bar |]+ `shouldBe` "foo{ testFoo {testBar = 9000\\} }bar"+ [qn|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|]+ `shouldBe`+ "foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\\}\\}}bar"+ [qn| foo { testFoo2 {+ test1 = (test1 testFoo2)+ { testBar = 9000 \}+ \}+ } bar |]+ `shouldBe` "foo { testFoo2 {test1 = (test1 testFoo2)\+ \{ testBar = 9000 \\}\\}} bar"+ [qn| {"\}"} |] `shouldBe` "{\"\\}\"}"+ [qn| {"\\\}"} |] `shouldBe` "{\"\\\\}\"}"+ [qn| {123}} |] `shouldBe` "{123}}"++ it "When interpolation block is escaped\+ \ everything must be interpreted as usual (not really)" $ do+ [qn| \{ foo\nbar\\baz\} } |] `shouldBe` "\\{ foo\nbar\\baz\\} }"+ [qn| \{ foo\+ bar } |] `shouldBe` "\\{ foobar }"++ it "Tabs characters in string inside interpolation block\+ \ (not really!)" $ do+ [qn| {"foo\t\tbar" } |] `shouldBe` "{\"foo\t\tbar\" }"+ [qn| {"foo bar" } |] `shouldBe` "{\"foo\t\tbar\" }"+ [qn| {"foo\\t\tbar"} |] `shouldBe` "{\"foo\\t\tbar\"}"+ describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do@@ -103,7 +172,13 @@ describe "New README examples" $ do - it "Simple usage example" $ do+ it "First example" $+ [qn| Hello,+ world!+ Pi is {floor pi}.{floor $ (pi - 3) * 100}… |]+ `shouldBe` "Hello,world!Pi is {floor pi}.{floor $ (pi - 3) * 100}…"++ it "Simple usage example" $ [qn| <article> <h1>{title}</h1>@@ -111,23 +186,40 @@ </article> |] `shouldBe` "<article><h1>{title}</h1><p>{text}</p></article>" + it "Can escape spaces" $+ [qn| you can escape spaces+ \ when you need them |]+ `shouldBe`+ "you can escape spaces when you need them"++ it "Indentation and line breaks are ignored" $+ [qn|+ indentation and li+ ne bre+ aks are i+ gno+ red+ |]+ `shouldBe` "indentation and line breaks are ignored"++ it "Escaping indentation or line breaks" $+ [qn| \ You can escape indentation or\n+ line breaks when you need them! \ |]+ `shouldBe`+ " You can escape indentation or\nline breaks when you need them! "++ it "Interpolation blocks can be escaped too" $+ [qn| Interpolation blocks can be escaped too: {1+2} \{3+4} |]+ `shouldBe`+ "Interpolation blocks can be escaped too: {1+2} \\{3+4}"+ it "Interpolation" $ [qn| foo {1+2} |] `shouldBe` "foo {1+2}" - it "Haddock example" $+ it "Haddock example" $ do [qn| foo {'b':'a':'r':""} \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz"-- it "Escaping backslash itself when it makes sense" $ do- [qn| foo\nbar |] `shouldBe` "foo\nbar"- [qn| foo\\nbar |] `shouldBe` "foo\\nbar"- [qn| foo\tbar |] `shouldBe` "foo\tbar"- [qn| foo\\tbar |] `shouldBe` "foo\\tbar"- [qn| foo\ bar |] `shouldBe` "foo\tbar"- [qn| foo\\ bar |] `shouldBe` "foo\\\tbar"- [qn| foo\ bar |] `shouldBe` "foo bar"- [qn| foo\\ bar |] `shouldBe` "foo\\ bar"-- [qn| foo\- bar |] `shouldBe` "foobar"- [qn| foo\\- bar |] `shouldBe` "foo\\bar"+ [qn| foo+ \ {'b':'a':'r':""}+ \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz"+ [qn| foo {'b':'a':'r':""}+ baz |] `shouldBe` "foo {'b':'a':'r':\"\"}baz"
test/QNB/Spec.hs view
@@ -1,3 +1,6 @@+-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test!+{-# OPTIONS_GHC -fno-warn-tabs #-}+ {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -56,34 +59,101 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qnb| {1+2} \{3+4} |] `shouldBe` "{1+2} \\{3+4}" - it "Example of `qnb` QuasiQuoter" $- [qnb| foo {1+2} |] `shouldBe` "foo {1+2}"+ it "Empty string" $ [qnb| |] `shouldBe` "" it "Type annotation in interpolation block" $ [qnb|{10 :: Float}|] `shouldBe` "{10 :: Float}" - it "Escaping interpolation symbols inside interpolation block" $ do- [qnb|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz"- [qnb|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz"+ describe "Escaping" $ do - it "Example from generated docs (double-space)" $- [qnb| foo {'b':'a':'r':""}- \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"}\n baz"+ it "Escaping interpolation symbols inside interpolation block" $ do+ [qnb|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz"+ [qnb|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz" - it "Escaping backslashes" $ do [qnb| foo\bar |] `shouldBe` "foo\\bar"- [qnb| foo\\bar |] `shouldBe` "foo\\bar"- [qnb| foo\\\bar |] `shouldBe` "foo\\\\bar"- [qnb| foo\\\\bar |] `shouldBe` "foo\\\\bar"+ it "Escaping backslashes" $ do [qnb| foo\bar |] `shouldBe` "foo\\bar"+ [qnb| foo\\bar |] `shouldBe` "foo\\bar"+ [qnb| foo\\\bar |] `shouldBe` "foo\\\\bar"+ [qnb| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qnb| |] `shouldBe` ""+ it "Escaping space by backslash at EOL after space\+ \ (line break is cutted off)" $+ [qnb| foo \+ bar |] `shouldBe` "foo bar" - it "Escaping space by backslash at EOL after space (line break is cutted off)" $- [qnb| foo \- bar |] `shouldBe` "foo bar"+ it "Escaped spaces at the edges" $ do [qnb| foo\ |] `shouldBe` "foo "+ [qnb|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qnb| foo\ |] `shouldBe` "foo "- [qnb|\ foo |] `shouldBe` " foo"+ it "Escaping backslash itself when it makes sense" $ do+ [qnb| foo\nbar |] `shouldBe` "foo\nbar"+ [qnb| foo\\nbar |] `shouldBe` "foo\\nbar"+ [qnb| foo\tbar |] `shouldBe` "foo\tbar"+ [qnb| foo\\tbar |] `shouldBe` "foo\\tbar"+ [qnb| foo\ bar |] `shouldBe` "foo\tbar"+ [qnb| foo\\ bar |] `shouldBe` "foo\\\tbar"+ [qnb| foo\ bar |] `shouldBe` "foo bar"+ [qnb| foo\\ bar |] `shouldBe` "foo\\ bar" + [qnb| foo\+ bar |] `shouldBe` "foobar"+ [qnb| foo\\+ bar |] `shouldBe` "foo\\\nbar"++ -- By 'not really' it means we just shows here what happens with examples+ -- for QMB when we use them with QNB quoter.+ describe "Escaping inside interpolation blocks (not really!)" $ do++ it "Line-breaks must be interpreted as just haskell code\+ \ (not really!)" $ do+ [qnb| {'\n'} |] `shouldBe` "{'\n'}"+ [qnb| {"foo\nbar"} |] `shouldBe` "{\"foo\nbar\"}"+ [qnb| {"foo\\nbar"} |] `shouldBe` "{\"foo\\nbar\"}"+ [qnb| {"foo\\\nbar"} |] `shouldBe` "{\"foo\\\nbar\"}"+ [qnb| {"foo\\\\nbar"} |] `shouldBe` "{\"foo\\\\nbar\"}"++ it "Escaping for multiline strings" $ do+ [qnb| {"foo\+ \bar\+ \baz"} |] `shouldBe` "{\"foo\\bar\\baz\"}"+ [qnb| {"foo \+ \bar\+ \ baz"} |] `shouldBe` "{\"foo \\bar baz\"}"+ [qnb| x \+ {"foo \+ \bar\+ \ baz"} \+ y |] `shouldBe` "x {\"foo \\bar baz\"} y"++ it "Escaping of close-bracket '}'" $ do+ [qnb| { testFoo {testBar = 9000\} } |]+ `shouldBe` "{ testFoo {testBar = 9000\\} }"+ [qnb| foo{ testFoo {testBar = 9000\} }bar |]+ `shouldBe` "foo{ testFoo {testBar = 9000\\} }bar"+ [qnb|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|]+ `shouldBe`+ "foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\\}\\}}bar"+ [qnb| foo { testFoo2 {+ test1 = (test1 testFoo2)+ { testBar = 9000 \}+ \}+ } bar |]+ `shouldBe` "foo { testFoo2 {\ntest1 = (test1 testFoo2)\n\+ \{ testBar = 9000 \\}\n\\}\n} bar"+ [qnb| {"\}"} |] `shouldBe` "{\"\\}\"}"+ [qnb| {"\\\}"} |] `shouldBe` "{\"\\\\}\"}"+ [qnb| {123}} |] `shouldBe` "{123}}"++ it "When interpolation block is escaped\+ \ everything must be interpreted as usual (not really)" $ do+ [qnb| \{ foo\nbar\\baz\} } |] `shouldBe` "\\{ foo\nbar\\baz\\} }"+ [qnb| \{ foo\+ bar } |] `shouldBe` "\\{ foobar }"++ it "Tabs characters in string inside interpolation block\+ \ (not really)" $ do+ [qnb| {"foo\t\tbar" } |] `shouldBe` "{\"foo\t\tbar\" }"+ [qnb| {"foo bar" } |] `shouldBe` "{\"foo\t\tbar\" }"+ [qnb| {"foo\\t\tbar"} |] `shouldBe` "{\"foo\\t\tbar\"}"+ describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do@@ -124,7 +194,13 @@ describe "New README examples" $ do - it "Simple usage example" $ do+ it "First example" $+ [qnb| Hello,+ world!+ Pi is {floor pi}.{floor $ (pi - 3) * 100}… |]+ `shouldBe` "Hello,\nworld!\nPi is {floor pi}.{floor $ (pi - 3) * 100}…"++ it "Simple usage example" $ [qnb| <article> <h1>{title}</h1>@@ -134,24 +210,43 @@ `shouldBe` "<article>\n<h1>{title}</h1>\n<p>{text}</p>\n</article>" + it "Can escape spaces" $+ [qnb| you can escape spaces+ \ when you need them |]+ `shouldBe`+ "you can escape spaces\n when you need them"++ -- By 'not really' it means that it just copied from `QM` and shows what+ -- happens with the same input if you use it with this quoter.+ it "Indentation and line breaks are ignored (not really)" $+ [qnb|+ indentation and li+ ne bre+ aks are i+ gno+ red+ (not really)+ |]+ `shouldBe` "indentation and li\nne bre\naks are i\ngno\nred\n(not really)"++ it "Escaping indentation or line breaks" $+ [qnb| \ You can escape indentation or\n+ line breaks when you need them! \ |]+ `shouldBe`+ " You can escape indentation or\n\nline breaks when you need them! "++ it "Interpolation blocks can be escaped too" $+ [qnb| Interpolation blocks can be escaped too: {1+2} \{3+4} |]+ `shouldBe`+ "Interpolation blocks can be escaped too: {1+2} \\{3+4}"+ it "Interpolation" $ [qnb| foo {1+2} |] `shouldBe` "foo {1+2}" - it "Haddock example" $+ it "Haddock example" $ do+ [qnb| foo {'b':'a':'r':""}+ baz |] `shouldBe` "foo {'b':'a':'r':\"\"}\nbaz" [qnb| foo {'b':'a':'r':""} baz |] `shouldBe` "foo\n{'b':'a':'r':\"\"}\nbaz"-- it "Escaping backslash itself when it makes sense" $ do- [qnb| foo\nbar |] `shouldBe` "foo\nbar"- [qnb| foo\\nbar |] `shouldBe` "foo\\nbar"- [qnb| foo\tbar |] `shouldBe` "foo\tbar"- [qnb| foo\\tbar |] `shouldBe` "foo\\tbar"- [qnb| foo\ bar |] `shouldBe` "foo\tbar"- [qnb| foo\\ bar |] `shouldBe` "foo\\\tbar"- [qnb| foo\ bar |] `shouldBe` "foo bar"- [qnb| foo\\ bar |] `shouldBe` "foo\\ bar"-- [qnb| foo\- bar |] `shouldBe` "foobar"- [qnb| foo\\- bar |] `shouldBe` "foo\\\nbar"+ [qnb| foo {'b':'a':'r':""}+ \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"}\n baz"
test/QNS/Spec.hs view
@@ -1,3 +1,6 @@+-- WARNING! Do not remove trailing whitespace or tabs, it's part of the test!+{-# OPTIONS_GHC -fno-warn-tabs #-}+ {-# LANGUAGE PackageImports #-} {-# LANGUAGE QuasiQuotes #-} @@ -56,34 +59,101 @@ it "Fourth (escaping interpolation blocks to show them as text)" $ [qns| {1+2} \{3+4} |] `shouldBe` "{1+2} \\{3+4}" - it "Example of `qns` QuasiQuoter" $- [qns| foo {1+2} |] `shouldBe` "foo {1+2}"+ it "Empty string" $ [qns| |] `shouldBe` "" it "Type annotation in interpolation block" $ [qns|{10 :: Float}|] `shouldBe` "{10 :: Float}" - it "Escaping interpolation symbols inside interpolation block" $ do- [qns|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz"- [qns|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz"+ describe "Escaping" $ do - it "Example from generated docs (double-space)" $- [qns| foo {'b':'a':'r':""}- \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz"+ it "Escaping interpolation symbols inside interpolation block" $ do+ [qns|foo {"b{a{r"} baz|] `shouldBe` "foo {\"b{a{r\"} baz"+ [qns|foo {"b\}a\}r"} baz|] `shouldBe` "foo {\"b\\}a\\}r\"} baz" - it "Escaping backslashes" $ do [qns| foo\bar |] `shouldBe` "foo\\bar"- [qns| foo\\bar |] `shouldBe` "foo\\bar"- [qns| foo\\\bar |] `shouldBe` "foo\\\\bar"- [qns| foo\\\\bar |] `shouldBe` "foo\\\\bar"+ it "Escaping backslashes" $ do [qns| foo\bar |] `shouldBe` "foo\\bar"+ [qns| foo\\bar |] `shouldBe` "foo\\bar"+ [qns| foo\\\bar |] `shouldBe` "foo\\\\bar"+ [qns| foo\\\\bar |] `shouldBe` "foo\\\\bar" - it "Empty string" $ [qns| |] `shouldBe` ""+ it "Escaping space by backslash at EOL after space\+ \ (line break is cutted off)" $+ [qns| foo \+ bar |] `shouldBe` "foo bar" - it "Escaping space by backslash at EOL after space (line break is cutted off)" $- [qns| foo \- bar |] `shouldBe` "foo bar"+ it "Escaped spaces at the edges" $ do [qns| foo\ |] `shouldBe` "foo "+ [qns|\ foo |] `shouldBe` " foo" - it "Escaped spaces at the edges" $ do [qns| foo\ |] `shouldBe` "foo "- [qns|\ foo |] `shouldBe` " foo"+ it "Escaping backslash itself when it makes sense" $ do+ [qns| foo\nbar |] `shouldBe` "foo\nbar"+ [qns| foo\\nbar |] `shouldBe` "foo\\nbar"+ [qns| foo\tbar |] `shouldBe` "foo\tbar"+ [qns| foo\\tbar |] `shouldBe` "foo\\tbar"+ [qns| foo\ bar |] `shouldBe` "foo\tbar"+ [qns| foo\\ bar |] `shouldBe` "foo\\\tbar"+ [qns| foo\ bar |] `shouldBe` "foo bar"+ [qns| foo\\ bar |] `shouldBe` "foo\\ bar" + [qns| foo\+ bar |] `shouldBe` "foobar"+ [qns| foo\\+ bar |] `shouldBe` "foo\\ bar"++ -- By 'not really' it means we just shows here what happens with examples+ -- for QMS when we use them with QNS quoter.+ describe "Escaping inside interpolation blocks (not really!)" $ do++ it "Line-breaks must be interpreted as just haskell code\+ \ (not really!)" $ do+ [qns| {'\n'} |] `shouldBe` "{'\n'}"+ [qns| {"foo\nbar"} |] `shouldBe` "{\"foo\nbar\"}"+ [qns| {"foo\\nbar"} |] `shouldBe` "{\"foo\\nbar\"}"+ [qns| {"foo\\\nbar"} |] `shouldBe` "{\"foo\\\nbar\"}"+ [qns| {"foo\\\\nbar"} |] `shouldBe` "{\"foo\\\\nbar\"}"++ it "Escaping for multiline strings" $ do+ [qns| {"foo\+ \bar\+ \baz"} |] `shouldBe` "{\"foo\\bar\\baz\"}"+ [qns| {"foo \+ \bar\+ \ baz"} |] `shouldBe` "{\"foo \\bar baz\"}"+ [qns| x \+ {"foo \+ \bar\+ \ baz"} \+ y |] `shouldBe` "x {\"foo \\bar baz\"} y"++ it "Escaping of close-bracket '}'" $ do+ [qns| { testFoo {testBar = 9000\} } |]+ `shouldBe` "{ testFoo {testBar = 9000\\} }"+ [qns| foo{ testFoo {testBar = 9000\} }bar |]+ `shouldBe` "foo{ testFoo {testBar = 9000\\} }bar"+ [qns|foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\}\}}bar|]+ `shouldBe`+ "foo{testFoo2 {test1 = (test1 testFoo2) {testBar = 9000\\}\\}}bar"+ [qns| foo { testFoo2 {+ test1 = (test1 testFoo2)+ { testBar = 9000 \}+ \}+ } bar |]+ `shouldBe` "foo { testFoo2 { test1 = (test1 testFoo2)\+ \ { testBar = 9000 \\} \\} } bar"+ [qns| {"\}"} |] `shouldBe` "{\"\\}\"}"+ [qns| {"\\\}"} |] `shouldBe` "{\"\\\\}\"}"+ [qns| {123}} |] `shouldBe` "{123}}"++ it "When interpolation block is escaped\+ \ everything must be interpreted as usual (not really)" $ do+ [qns| \{ foo\nbar\\baz\} } |] `shouldBe` "\\{ foo\nbar\\baz\\} }"+ [qns| \{ foo\+ bar } |] `shouldBe` "\\{ foobar }"++ it "Tabs characters in string inside interpolation block\+ \ (not really)" $ do+ [qns| {"foo\t\tbar" } |] `shouldBe` "{\"foo\t\tbar\" }"+ [qns| {"foo bar" } |] `shouldBe` "{\"foo\t\tbar\" }"+ [qns| {"foo\\t\tbar"} |] `shouldBe` "{\"foo\\t\tbar\"}"+ describe "Tabs as indentation" $ do it "Tabs is only indentation at left side" $ do@@ -124,7 +194,13 @@ describe "New README examples" $ do - it "Simple usage example" $ do+ it "First example" $+ [qns| Hello,+ world!+ Pi is {floor pi}.{floor $ (pi - 3) * 100}… |]+ `shouldBe` "Hello, world! Pi is {floor pi}.{floor $ (pi - 3) * 100}…"++ it "Simple usage example" $ [qns| <article> <h1>{title}</h1>@@ -134,24 +210,44 @@ `shouldBe` "<article> <h1>{title}</h1> <p>{text}</p> </article>" + it "Can escape spaces" $+ [qns| you can escape spaces+ \ when you need them |]+ `shouldBe`+ "you can escape spaces when you need them"++ -- By 'not really' it means that it just copied from `QM` and shows what+ -- happens with the same input if you use it with this quoter.+ it "Indentation and line breaks are ignored (not really)" $+ [qns|+ indentation and li+ ne bre+ aks are i+ gno+ red+ (not really)+ |]+ `shouldBe` "indentation and li ne bre aks are i gno red (not really)"++ it "Escaping indentation or line breaks" $+ [qns| \ You can escape indentation or\n+ line breaks when you need them! \ |]+ `shouldBe`+ " You can escape indentation or\n line breaks when you need them! "++ it "Interpolation blocks can be escaped too" $+ [qns| Interpolation blocks can be escaped too: {1+2} \{3+4} |]+ `shouldBe`+ "Interpolation blocks can be escaped too: {1+2} \\{3+4}"+ it "Interpolation" $ [qns| foo {1+2} |] `shouldBe` "foo {1+2}" - it "Haddock example" $+ it "Haddock example" $ do+ [qns| foo {'b':'a':'r':""}+ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz" [qns| foo {'b':'a':'r':""} baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz"-- it "Escaping backslash itself when it makes sense" $ do- [qns| foo\nbar |] `shouldBe` "foo\nbar"- [qns| foo\\nbar |] `shouldBe` "foo\\nbar"- [qns| foo\tbar |] `shouldBe` "foo\tbar"- [qns| foo\\tbar |] `shouldBe` "foo\\tbar"- [qns| foo\ bar |] `shouldBe` "foo\tbar"- [qns| foo\\ bar |] `shouldBe` "foo\\\tbar"- [qns| foo\ bar |] `shouldBe` "foo bar"- [qns| foo\\ bar |] `shouldBe` "foo\\ bar"-- [qns| foo\- bar |] `shouldBe` "foobar"- [qns| foo\\- bar |] `shouldBe` "foo\\ bar"+ -- Double-space with escaping+ [qns| foo {'b':'a':'r':""}+ \ baz |] `shouldBe` "foo {'b':'a':'r':\"\"} baz"