festung-0.9.1.1: tests/Festung/Frontend/ConvertersSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Festung.Frontend.ConvertersSpec (spec) where
import Test.Hspec
import Festung.Frontend.Converters
import qualified Festung.Vault.Persistence as P
import Data.Aeson.Types
import Data.Aeson
import Data.Either
import qualified Data.ByteString.Lazy as BS
import Data.Text.Encoding (encodeUtf8)
import qualified Data.Text as T
import Data.ByteString.Builder (toLazyByteString)
convert :: (Value -> Parser a) -> BS.ByteString -> Either String a
convert p content = parseEither p =<< eitherDecode content
serialize :: (a -> Value) -> a -> BS.ByteString
serialize e = encode . e
integerToByteString :: Integer -> BS.ByteString
integerToByteString = BS.fromStrict . encodeUtf8 . T.pack . show
unlines' :: [BS.ByteString] -> BS.ByteString
unlines' = BS.intercalate "\n"
pendingCustomDecimal :: IO ()
pendingCustomDecimal =
pendingWith "This doesn't work without a custom Value which handles decimal/non-decimal"
spec :: Spec
spec = do
describe "vaultObjectParser" $ do
let convert' = convert vaultObjectParser
it "Parses integer" $ do
convert' "1234" `shouldBe` Right (P.IntValue 1234)
convert' "0" `shouldBe` Right (P.IntValue 0)
it "Validates integers over 64bits" $ do
pendingWith "Not important right now. But needs to be implemented some day™"
let bigInteger = (2 ^ 64 + 1) :: Integer
convert' (integerToByteString bigInteger) `shouldSatisfy` isLeft
it "Parses floats" $ do
convert' "3.14" `shouldBe` Right (P.FloatValue 3.14)
convert' "1E-1" `shouldBe` Right (P.FloatValue 0.1)
it "Parses float without decimals" $ do
pendingCustomDecimal
convert' "1.0" `shouldBe` Right (P.FloatValue 1.0)
convert' "2.0e5" `shouldBe` Right (P.FloatValue 200000)
it "Parses strings" $
convert' "\"Hello\"" `shouldBe` Right (P.StringValue "Hello")
it "Parses unicode (in this case the snowman character)" $
convert' "\"\\u2603\"" `shouldBe` Right (P.StringValue "☃")
it "Parses NULL values" $
convert' "null" `shouldBe` Right P.NullValue
it "Prevents bad data" $ do
convert' "{}" `shouldSatisfy` isLeft
convert' "[]" `shouldSatisfy` isLeft
convert' "{\"foo\": \"bar\"}" `shouldSatisfy` isLeft
convert' "[1, 2, 3.5]" `shouldSatisfy` isLeft
it "Parses blobs" $ do
pending
let expected = P.BlobValue [0xDE, 0xAD, 0xBE, 0xEF]
content = "{\"type\": \"blob\", \"value\": [0xDE, 0xAD, 0xBE, 0xEF]}"
convert' content `shouldBe` Right expected
it "Validates blob data" $ do
pending
convert' "{\"type\": \"blob\", \"value\": [0xFFFF, 0xFF]}" `shouldSatisfy` isLeft
describe "parametersParser" $ do
let convert' = convert parametersParser
it "Parses hereterogeneous lists" $
convert' "[1234, \"Hello\", null]" `shouldBe` Right [ P.IntValue 1234
, P.StringValue "Hello"
, P.NullValue
]
it "Preserves order" $ do
convert' "[7, 8]" `shouldBe` Right [ P.IntValue 7, P.IntValue 8 ]
convert' "[8, 7]" `shouldBe` Right [ P.IntValue 8, P.IntValue 7 ]
it "Parses empty list" $
convert' "[]" `shouldBe` Right []
describe "queryParser" $ do
let convert' = convert queryParser
it "Parses query object" $ do
let content = unlines' [ "{"
, " \"sql\": \"SELECT * FROM table WHERE a = ? AND b = ?\","
, " \"params\": [1, \"string\"]"
, "}"
]
params = [P.IntValue 1, P.StringValue "string"]
sql = "SELECT * FROM table WHERE a = ? AND b = ?"
convert' content `shouldBe` Right (sql, params)
it "Defaults the parameters to empty string" $ do
let content = unlines' [ "{"
, " \"sql\": \"SELECT * FROM table\""
, "}"
]
convert' content `shouldBe` Right ("SELECT * FROM table", [])
describe "vaultObjectEncoder" $ do
let serialize' = serialize vaultObjectEncoder
it "Encodes integer" $
serialize' (P.IntValue 1) `shouldBe` "1"
it "Encodes floats" $
serialize' (P.FloatValue 3.14) `shouldBe` "3.14"
it "Encodes string" $
serialize' (P.StringValue "Hello World") `shouldBe` "\"Hello World\""
it "Preserves the float type for floats without decimals" $ do
pendingCustomDecimal
serialize' (P.FloatValue 1.0) `shouldNotBe` "1"
it "Encodes null" $
serialize' P.NullValue `shouldBe` "null"
describe "rowEncoder" $ do
let serialize' = serialize rowEncoder
it "Preserves order" $ do
serialize' [P.IntValue 1, P.NullValue] `shouldBe` "[1,null]"
serialize' [P.NullValue, P.IntValue 1] `shouldBe` "[null,1]"