Files
orville-sqlite/test/Test/FieldDefinition.hs
T

96 lines
3.5 KiB
Haskell

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module Test.FieldDefinition where
import qualified Data.ByteString as BS
import Data.Int (Int64)
import qualified Data.Text as T
import Test.Hspec
import qualified Database.SQLite3 as SQLite3
import Orville.SQLite
fieldDefinitionTests :: Spec
fieldDefinitionTests = do
describe "integerField" $ do
it "roundtrips encode/decode" $ do
let fd = integerField "count"
let val = 42 :: Int64
fieldFromSqlValue (fieldToSqlValue val fd) fd `shouldBe` Right val
it "encodes to SQLInteger" $ do
let fd = integerField "count"
fieldToSqlValue 99 fd `shouldBe` SQLite3.SQLInteger 99
it "decodes from SQLInteger" $ do
let fd = integerField "count"
fieldFromSqlValue (SQLite3.SQLInteger 99) fd `shouldBe` Right 99
describe "textField" $ do
it "roundtrips encode/decode" $ do
let fd = textField "name"
let val = "Hello" :: T.Text
fieldFromSqlValue (fieldToSqlValue val fd) fd `shouldBe` Right val
it "encodes to SQLText" $ do
let fd = textField "name"
fieldToSqlValue "test" fd `shouldBe` SQLite3.SQLText "test"
it "decodes from SQLText" $ do
let fd = textField "name"
fieldFromSqlValue (SQLite3.SQLText "decoded") fd `shouldBe` Right ("decoded" :: T.Text)
describe "realField" $ do
it "roundtrips encode/decode" $ do
let fd = realField "price"
let val = 3.14 :: Double
fieldFromSqlValue (fieldToSqlValue val fd) fd `shouldBe` Right val
it "encodes to SQLFloat" $ do
let fd = realField "price"
fieldToSqlValue 2.718 fd `shouldBe` SQLite3.SQLFloat 2.718
describe "blobField" $ do
it "roundtrips encode/decode" $ do
let fd = blobField "data"
let val = "binary\0stuff" :: BS.ByteString
fieldFromSqlValue (fieldToSqlValue val fd) fd `shouldBe` Right val
describe "nullableField" $ do
it "is marked as nullable" $ do
let fd = nullableField (integerField "opt")
fieldIsNullable fd `shouldBe` True
it "retains the column name" $ do
let fd = nullableField (textField "notes")
fieldColumnName fd `shouldBe` "notes"
describe "convertField" $ do
it "converts between types" $ do
let fd = integerField "count"
let converted = convertField show (read @Int64) fd :: FieldDefinition 'NotNull String
fieldFromSqlValue (SQLite3.SQLInteger 123) converted `shouldBe` Right "123"
describe "fieldColumnName" $ do
it "returns the column name for non-null field" $ do
fieldColumnName (integerField "my_col") `shouldBe` "my_col"
it "returns the column name for nullable field" $ do
fieldColumnName (nullableField (textField "opt_col")) `shouldBe` "opt_col"
describe "fieldSqlTypeName" $ do
it "returns INTEGER for integerField" $ do
fieldSqlTypeName (integerField "x") `shouldBe` "INTEGER"
it "returns TEXT for textField" $ do
fieldSqlTypeName (textField "x") `shouldBe` "TEXT"
it "returns REAL for realField" $ do
fieldSqlTypeName (realField "x") `shouldBe` "REAL"
it "returns BLOB for blobField" $ do
fieldSqlTypeName (blobField "x") `shouldBe` "BLOB"