tomland-1.3.3.3: test/Test/Toml/Parser/Toml.hs
{-# LANGUAGE PatternSynonyms #-}
module Test.Toml.Parser.Toml
( tomlSpecs
) where
import Data.List.NonEmpty (NonEmpty ((:|)))
import Data.Text (Text)
import Test.Hspec (Spec, describe, it, xit)
import Test.Toml.Parser.Common (day2, failOn, parseToml, tomlFailOn)
import Toml.Parser.Item (keyValP)
import Toml.Type.Edsl (empty, mkToml, table, tableArray, (=:))
import Toml.Type.Key (pattern (:||))
import Toml.Type.TOML (TOML (..))
import Toml.Type.Value (Value (..))
import qualified Data.List.NonEmpty as NE
import qualified Data.Text as T
tomlSpecs :: Spec
tomlSpecs = do
describe "Key/values" $ do
it "can parse key/value pairs" $ do
parseToml "x='abcdef'" $ mkToml ("x" =: "abcdef")
parseToml "x= 1" $ mkToml ("x" =: 1)
parseToml "x =5.2" $ mkToml ("x" =: Double 5.2)
parseToml "x = true" $ mkToml ("x" =: Bool True)
parseToml "x= [1, 2, 3]" $ mkToml ("x" =: Array [1, 2, 3])
parseToml "x =1920-12-10" $ mkToml ("x" =: Day day2)
it "ignores white spaces around key names and values" $ do
let toml = mkToml ("x" =: 1)
parseToml "x=1 " toml
parseToml "x= 1" toml
parseToml "x =1" toml
parseToml "x\t= 1 " toml
parseToml "\"x\" = 1" $ mkToml ("\"x\"" =: 1)
xit "fails if the key, equals sign, and value are not on the same line" $ do
failOn keyValP "x\n=\n1"
failOn keyValP "x=\n1"
failOn keyValP "\"x\"\n=\n1"
it "works if the value is broken over multiple lines" $
parseToml "x=[1, \n2\n]" $ mkToml ("x" =: Array [1, 2])
it "fails if the value is not specified" $
tomlFailOn "x="
describe "tables" $ do
it "can parse a TOML table" $ do
let t = mkToml $
table "table" $ do
"key1" =: "some string"
"key2" =: 123
parseToml "[table] \n key1 = \"some string\"\nkey2 = 123" t
it "can parse an empty TOML table" $
parseToml "[table]" $ mkToml (table "table" empty)
it "can parse a table with subarrays" $ do
let t = mkToml $
table "table" $
tableArray "array" ("key1" =: "some string" :| ["key2" =: 123])
parseToml "[table] \n [[table.array]] \nkey1 = \"some string\"\n \
\[[table.array]] \nkey2 = 123" t
it "can parse a TOML inline table" $
parseToml "table={key1 = \"some string\", key2 = 123}" $
mkToml $
table "table" $ do
"key1" =: "some string"
"key2" =: 123
it "can parse an empty inline TOML table" $
parseToml "table = {}" $ mkToml (table "table" empty)
it "can parse a table followed by an inline table" $
parseToml "[table1] \n key1 = \"some string\" \n table2 = {key2 = 123}" $
mkToml $
table "table1" $ do
"key1" =: "some string"
table "table2" $ "key2" =: 123
it "can parse an empty table followed by an inline table" $
parseToml "[table1] \n table2 = {key2 = 123}" $
mkToml $
table "table1" $
table "table2" $
"key2" =: 123
it "allows the name of the table to be any valid TOML key" $ do
parseToml "dog.\"tater.man\"={}" $ mkToml $ table ("dog" :|| ["\"tater.man\""]) empty
parseToml "j.\"ʞ\".'l'={}" $ mkToml $ table "j.\"ʞ\".'l'" empty
describe "array of tables" $ do
it "can parse an empty array" $
parseToml "[[array]]" $ mkToml $ tableArray "array" (empty :| [])
it "can parse an array of key/values" $ do
let array = mkToml $
tableArray "array" $
"key1" =: "some string" :|
["key2" =: 123]
parseToml "[[array]]\n key1 = \"some string\"\n \
\[[array]]\n key2 = 123" array
it "can parse an array of tables" $ do
let table1 = table "table1" ("key1" =: "some string")
table2 = table "table2" ("key2" =: 123)
array = mkToml $ tableArray "array" $ table1 :| [table2]
parseToml "[[array]]\n[array.table1] \n key1 = \"some string\"\n \
\[[array]]\n[array.table2] \n key2 = 123" array
it "can parse an array of array" $ do
let arr = tableArray "subarray" ("key1" =: "some string" :| ["key2" =: 123])
array = mkToml $ tableArray "array" (arr :| [])
parseToml "[[array]] \n [[array.subarray]] \nkey1 = \"some string\"\n \
\[[array.subarray]] \nkey2 = 123" array
it "can parse an array of arrays" $ do
let
arr1 = tableArray "table-1" ("key1" =: Text "some string" :| [])
arr2 = tableArray "table-2" ("key2" =: Integer 123 :| [])
array = mkToml $ tableArray "array" $ (arr1 >> arr2) :| []
parseToml "[[array]]\n [[array.table-1]] \nkey1 = \"some string\"\n \
\[[array.table-2]] \nkey2 = 123" array
it "can parse very large arrays" $ do
let array = mkToml $ tableArray "array" $ NE.fromList $ replicate 1000 empty
parseToml (mconcat $ replicate 1000 "[[array]]\n") array
it "can parse an inline array of tables" $ do
let array = mkToml $ tableArray "table" $ NE.fromList ["key1" =: "some string", "key2" =: 123]
parseToml "table = [{key1 = \"some string\"}, {key2 = 123}]" array
describe "TOML" $ do
it "can parse TOML files" $
parseToml tomlStr1 toml1
it "can parse mix of tables and arrays" $
parseToml tomlStr2 toml2
where
tomlStr1, tomlStr2 :: Text
tomlStr1 = T.unlines
[ " # This is a TOML document.\n\n"
, "title = \"TOML Example\" # Comment \n\n"
, "[owner]\n"
, " name = \"Tom Preston-Werner\" "
, " enabled = true # First class dates"
]
tomlStr2 = T.unlines
[ "[[array1]]\n key1 = \"some string\" \n"
, ""
, "[table1] \n key2 = 123 \n"
, "[[array2]]\n key3 = 3.14 \n"
, " [table2] \n key4 = true"
]
toml1, toml2 :: TOML
toml1 = mkToml $ do
"title" =: "TOML Example"
table "owner" $ do
"name" =: "Tom Preston-Werner"
"enabled" =: Bool True
toml2 = mkToml $ do
tableArray "array1" $
"key1" =: "some string" :| []
table "table1" $ "key2" =: 123
tableArray "array2" $
"key3" =: Double 3.14 :| []
table "table2" $ "key4" =: Bool True