@@ -8,6 +8,7 @@
88module Data.YamlSpec (main, spec) where
99
1010import qualified Text.Libyaml as Y
11+import qualified Data.ByteString as BS
1112import qualified Data.ByteString.Char8 as B8
1213import Data.Int (Int64)
1314
@@ -55,6 +56,13 @@ shouldDecode bs expected = do
5556 actual <- D.decodeThrow bs
5657 actual `shouldBe` expected
5758
59+testEncodeWith :: Y.FormatOptions -> [Y.Event] -> IO BS.ByteString
60+testEncodeWith opts es = runConduitRes (CL.sourceList events .| Y.encodeWith opts)
61+ where
62+ events =
63+ [Y.EventStreamStart, Y.EventDocumentStart] ++ es ++
64+ [Y.EventDocumentEnd, Y.EventStreamEnd]
65+
5866main :: IO ()
5967main = hspec spec
6068
@@ -205,6 +213,103 @@ spec = do
205213 go "12.3015e+02" (1230.15 :: Scientific)
206214 go "1230.15" (1230.15 :: Scientific)
207215
216+ describe "Text.Libyaml with default tag rendering" $ do
217+ let enc = testEncodeWith Y.defaultFormatOptions
218+ it "elides custom sequence tags" $
219+ enc taggedSequence `shouldReturn` "[]\n"
220+ it "elides custom mapping tags" $
221+ enc taggedMapping `shouldReturn` "{}\n"
222+ it "elides default sequence tags" $
223+ enc defaultTaggedSequence `shouldReturn` "[]\n"
224+ it "elides default mapping tags" $
225+ enc defaultTaggedMapping `shouldReturn` "{}\n"
226+ it "handles NoTag on sequences" $
227+ enc untaggedSequence `shouldReturn` "[]\n"
228+ it "handles NoTag on mappings" $
229+ enc untaggedMapping `shouldReturn` "{}\n"
230+ it "handles mixed tag usages but elides all mapping and sequence tags" $
231+ enc mixedTagSampleA `shouldReturn` "- {}\n"
232+ it "in combination of tags, anchors and styles, outputs only the scalar tags" $
233+ enc mixedTagSampleB `shouldReturn` "&a\n&b !<bar> foo: &c [&d !!null '']\n"
234+ it "outputs tags when double quoted" $
235+ enc [Y.EventScalar "foo" Y.StrTag Y.DoubleQuoted Nothing] `shouldReturn` "!!str \"foo\"\n"
236+ it "outputs tags when single quoted" $
237+ enc [Y.EventScalar "foo" Y.StrTag Y.SingleQuoted Nothing] `shouldReturn` "!!str 'foo'\n"
238+ it "outputs tags on literal text" $
239+ enc [Y.EventScalar "foo" Y.StrTag Y.Literal Nothing] `shouldReturn` "!!str |-\n foo\n"
240+ it "outputs tags on folded text" $
241+ enc [Y.EventScalar "foo" Y.StrTag Y.Folded Nothing] `shouldReturn` "!!str >-\n foo\n"
242+ describe "Text.Libyaml with all tags on" $ do
243+ let enc = testEncodeWith $ Y.setTagRendering Y.renderAllTags Y.defaultFormatOptions
244+ it "will output custom sequence tags" $
245+ enc taggedSequence `shouldReturn` "!foo []\n"
246+ it "will output custom mapping tags" $
247+ enc taggedMapping `shouldReturn` "!foo {}\n"
248+ it "will output default sequence tags" $
249+ enc defaultTaggedSequence `shouldReturn` "!!seq []\n"
250+ it "will output default mapping tags" $
251+ enc defaultTaggedMapping `shouldReturn` "!!map {}\n"
252+ it "handles NoTag on sequences" $
253+ enc untaggedSequence `shouldReturn` "[]\n"
254+ it "handles NoTag on mappings" $
255+ enc untaggedMapping `shouldReturn` "{}\n"
256+ it "handles mixed tag usages outputting all mapping and sequence tags" $
257+ enc mixedTagSampleA `shouldReturn` "- !foo {}\n"
258+ it "in combination of tags, anchors and styles, outputs all the tags" $
259+ enc mixedTagSampleB `shouldReturn` "&a\n&b !<bar> foo: &c !baz [&d !!null '']\n"
260+ it "outputs plain tags" $
261+ enc [Y.EventScalar "foo" Y.StrTag Y.Plain Nothing] `shouldReturn` "!!str foo\n"
262+ it "respects PlainNoTag tags" $
263+ enc [Y.EventScalar "foo" Y.StrTag Y.PlainNoTag Nothing] `shouldReturn` "foo\n"
264+ describe "Text.Libyaml with uri tags on" $ do
265+ let enc = testEncodeWith $ Y.setTagRendering Y.renderUriTags Y.defaultFormatOptions
266+ it "will output custom sequence tags" $
267+ enc taggedSequence `shouldReturn` "!foo []\n"
268+ it "will output custom mapping tags" $
269+ enc taggedMapping `shouldReturn` "!foo {}\n"
270+ it "will output default sequence tags" $
271+ enc defaultTaggedSequence `shouldReturn` "[]\n"
272+ it "will output default mapping tags" $
273+ enc defaultTaggedMapping `shouldReturn` "{}\n"
274+ it "handles NoTag on sequences" $
275+ enc untaggedSequence `shouldReturn` "[]\n"
276+ it "handles NoTag on mappings" $
277+ enc untaggedMapping `shouldReturn` "{}\n"
278+ it "handles mixed tag usages outputting all mapping and sequence tags" $
279+ enc mixedTagSampleA `shouldReturn` "- !foo {}\n"
280+ it "in combination of tags, anchors and styles, outputs all the tags" $
281+ enc mixedTagSampleB `shouldReturn` "&a\n&b !<bar> foo: &c !baz [&d '']\n"
282+ describe "Text.Libyaml with tags off" $ do
283+ let enc = testEncodeWith $ Y.setTagRendering Y.renderNoTags Y.defaultFormatOptions
284+ it "outputs plain tags" $
285+ enc [Y.EventScalar "foo" Y.StrTag Y.Plain Nothing] `shouldReturn` "foo\n"
286+ it "respects PlainNoTag tags" $
287+ enc [Y.EventScalar "foo" Y.StrTag Y.PlainNoTag Nothing] `shouldReturn` "foo\n"
288+ it "elides tags when double quoted" $
289+ enc [Y.EventScalar "foo" Y.StrTag Y.DoubleQuoted Nothing] `shouldReturn` "\"foo\"\n"
290+ it "elides tags when single quoted" $
291+ enc [Y.EventScalar "foo" Y.StrTag Y.SingleQuoted Nothing] `shouldReturn` "'foo'\n"
292+ it "elides tags on literal text" $
293+ enc [Y.EventScalar "foo" Y.StrTag Y.Literal Nothing] `shouldReturn` "|-\n foo\n"
294+ it "elides tags on folded text" $
295+ enc [Y.EventScalar "foo" Y.StrTag Y.Folded Nothing] `shouldReturn` ">-\n foo\n"
296+ describe "Text.Libyaml with only UriTags set to render " $ do
297+ let enc =
298+ testEncodeWith $
299+ Y.setTagRendering Y.renderUriTags $ Y.defaultFormatOptions
300+ it "outputs only UriTags" $
301+ enc
302+ [ Y.EventSequenceStart Y.NoTag Y.FlowSequence Nothing
303+ , Y.EventScalar "foo" Y.StrTag Y.DoubleQuoted Nothing
304+ , Y.EventScalar "99" Y.IntTag Y.Plain Nothing
305+ , Y.EventScalar "99.99" Y.FloatTag Y.Plain Nothing
306+ , Y.EventScalar "bar" Y.NoTag Y.Plain Nothing
307+ , Y.EventScalar "foo" (Y.UriTag "!foo") Y.DoubleQuoted Nothing
308+ , Y.EventScalar "foo" (Y.UriTag "!foo") Y.Plain Nothing
309+ , Y.EventSequenceEnd
310+ ] `shouldReturn`
311+ "[\"foo\", 99, 99.99, bar, !foo \"foo\", !foo foo]\n"
312+
208313specialStrings :: [T.Text]
209314specialStrings =
210315 [ "fo\"o"
@@ -622,3 +727,50 @@ caseTruncatesFiles = withSystemTempFile "truncate.yaml" $ \fp h -> do
622727 D.encodeFile fp val
623728 res <- D.decodeFileEither fp
624729 either (Left . show) Right res `shouldBe` Right val
730+
731+
732+taggedSequence :: [Y.Event]
733+taggedSequence =
734+ [ Y.EventSequenceStart (Y.UriTag "!foo") Y.FlowSequence Nothing
735+ , Y.EventSequenceEnd
736+ ]
737+
738+taggedMapping :: [Y.Event]
739+taggedMapping =
740+ [ Y.EventMappingStart (Y.UriTag "!foo") Y.FlowMapping Nothing
741+ , Y.EventMappingEnd
742+ ]
743+
744+defaultTaggedSequence :: [Y.Event]
745+defaultTaggedSequence =
746+ [Y.EventSequenceStart Y.SeqTag Y.FlowSequence Nothing, Y.EventSequenceEnd]
747+
748+defaultTaggedMapping :: [Y.Event]
749+defaultTaggedMapping =
750+ [Y.EventMappingStart Y.MapTag Y.FlowMapping Nothing, Y.EventMappingEnd]
751+
752+untaggedSequence :: [Y.Event]
753+untaggedSequence =
754+ [Y.EventSequenceStart Y.NoTag Y.FlowSequence Nothing, Y.EventSequenceEnd]
755+
756+untaggedMapping :: [Y.Event]
757+untaggedMapping =
758+ [Y.EventMappingStart Y.NoTag Y.FlowMapping Nothing, Y.EventMappingEnd]
759+
760+mixedTagSampleA :: [Y.Event]
761+mixedTagSampleA =
762+ [ Y.EventSequenceStart Y.NoTag Y.BlockSequence Nothing
763+ , Y.EventMappingStart (Y.UriTag "!foo") Y.FlowMapping Nothing
764+ , Y.EventMappingEnd
765+ , Y.EventSequenceEnd
766+ ]
767+
768+mixedTagSampleB :: [Y.Event]
769+mixedTagSampleB =
770+ [ Y.EventMappingStart Y.NoTag Y.BlockMapping (Just "a")
771+ , Y.EventScalar "foo" (Y.UriTag "bar") Y.Plain (Just "b")
772+ , Y.EventSequenceStart (Y.UriTag "!baz") Y.FlowSequence (Just "c")
773+ , Y.EventScalar "" Y.NullTag Y.Plain (Just "d")
774+ , Y.EventSequenceEnd
775+ , Y.EventMappingEnd
776+ ]