96 lines
3.5 KiB
Haskell
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"
|