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

133 lines
5.5 KiB
Haskell

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
module Test.EntityOperations where
import Control.Monad.IO.Class (liftIO)
import Data.Int (Int64)
import Data.Text (Text)
import Test.Hspec
import Orville.SQLite
import Test.Setup
entityOperationsTests :: Spec
entityOperationsTests = do
describe "insertEntity" $ do
it "inserts a row and returns via findEntity" $ do
let p = Person 0 "Alice" "Smith" 30
mAlice <- withFreshDb personTable $ do
insertEntity personTable p
findEntity personTable 1
liftIO $ mAlice `shouldBe` Just (Person 1 "Alice" "Smith" 30)
it "assigns auto-increment ids sequentially" $ do
results <- withFreshDb personTable $ do
insertEntity personTable (Person 0 "A" "One" 20)
insertEntity personTable (Person 0 "B" "Two" 25)
insertEntity personTable (Person 0 "C" "Three" 30)
findAll personTable
liftIO $ map personId results `shouldBe` [1, 2, 3]
it "inserts an entity with explicit PK (non-auto-increment)" $ do
let w = Widget 42 "TestWidget"
mWidget <- withFreshDb widgetTable $ do
insertEntity widgetTable w
findEntity widgetTable 42
liftIO $ mWidget `shouldBe` Just w
it "inserts an entity with a nullable field set to Just" $ do
let t = Task 0 "Buy groceries" (Just 15)
mTask <- withFreshDb taskTable $ do
insertEntity taskTable t
findEntity taskTable 1
liftIO $ mTask `shouldBe` Just (Task 1 "Buy groceries" (Just 15))
it "inserts an entity with a nullable field set to Nothing" $ do
let t = Task 0 "No due date" Nothing
mTask <- withFreshDb taskTable $ do
insertEntity taskTable t
findEntity taskTable 1
liftIO $ mTask `shouldBe` Just (Task 1 "No due date" Nothing)
describe "findEntity" $ do
it "returns Nothing for a non-existent key" $ do
result <-
withFreshDb personTable $
findEntity personTable 999
liftIO $ result `shouldBe` Nothing
it "returns Nothing on an empty table" $ do
result <-
withFreshDb personTable $
findEntity personTable 1
liftIO $ result `shouldBe` Nothing
describe "findAll" $ do
it "returns all inserted rows" $ do
results <- withFreshDb personTable $ do
insertEntity personTable (Person 0 "Alice" "Smith" 30)
insertEntity personTable (Person 0 "Bob" "Jones" 25)
findAll personTable
liftIO $ length results `shouldBe` 2
it "returns empty list on empty table" $ do
results <-
withFreshDb personTable $
findAll personTable
liftIO $ results `shouldBe` []
it "returns rows in insertion order" $ do
results <- withFreshDb personTable $ do
insertEntity personTable (Person 0 "First" "One" 10)
insertEntity personTable (Person 0 "Second" "Two" 20)
insertEntity personTable (Person 0 "Third" "Three" 30)
findAll personTable
liftIO $ map firstName results `shouldBe` ["First", "Second", "Third"]
describe "updateEntity" $ do
it "updates a row and returns via findEntity" $ do
result <- withFreshDb personTable $ do
insertEntity personTable (Person 0 "Alice" "Smith" 30)
updateEntity personTable (Person 1 "Alice" "Jones" 31)
findEntity personTable 1
liftIO $ result `shouldBe` Just (Person 1 "Alice" "Jones" 31)
it "updates a widget with explicit PK" $ do
result <- withFreshDb widgetTable $ do
insertEntity widgetTable (Widget 10 "OldLabel")
updateEntity widgetTable (Widget 10 "NewLabel")
findEntity widgetTable 10
liftIO $ result `shouldBe` Just (Widget 10 "NewLabel")
it "does not affect other rows" $ do
results <- withFreshDb personTable $ do
insertEntity personTable (Person 0 "Alice" "Smith" 30)
insertEntity personTable (Person 0 "Bob" "Jones" 25)
updateEntity personTable (Person 1 "Alice" "Updated" 99)
findAll personTable
liftIO $ map firstName results `shouldBe` ["Alice", "Bob"]
describe "deleteEntity" $ do
it "deletes a row" $ do
result <- withFreshDb personTable $ do
insertEntity personTable (Person 0 "Alice" "Smith" 30)
deleteEntity personTable 1
findEntity personTable 1
liftIO $ result `shouldBe` Nothing
it "does not delete other rows" $ do
results <- withFreshDb personTable $ do
insertEntity personTable (Person 0 "Alice" "Smith" 30)
insertEntity personTable (Person 0 "Bob" "Jones" 25)
deleteEntity personTable 1
findAll personTable
liftIO $ map firstName results `shouldBe` ["Bob"]
it "deleting non-existent key does nothing" $ do
results <- withFreshDb personTable $ do
insertEntity personTable (Person 0 "Alice" "Smith" 30)
deleteEntity personTable 999
findAll personTable
liftIO $ length results `shouldBe` 1