duckdb-ffi-0.1.4.1: test/ValidityMaskTest.hs
{-# LANGUAGE BlockArguments #-}
module ValidityMaskTest (tests) where
import Control.Monad (void)
import Database.DuckDB.FFI
import Foreign.C.Types (CBool (..))
import Foreign.Ptr (nullPtr)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (assertBool, testCase, (@?=))
import Utils (setAllValid, withLogicalType, withVector)
-- | Entry point for validity-mask focused tests.
tests :: TestTree
tests =
testGroup
"Validity Mask Functions"
[ validityRowHelpers
, validitySetOperations
]
validityRowHelpers :: TestTree
validityRowHelpers =
testCase "row validity helpers reflect changes" $ do
withIntegerVector 4 \vec -> do
void (c_duckdb_vector_ensure_validity_writable vec)
mask <- c_duckdb_vector_get_validity vec
assertBool "validity pointer should not be null" (mask /= nullPtr)
setAllValid mask 4
toBool (c_duckdb_validity_row_is_valid mask 2) >>= (@?= True)
c_duckdb_validity_set_row_invalid mask 2
toBool (c_duckdb_validity_row_is_valid mask 2) >>= (@?= False)
c_duckdb_validity_set_row_valid mask 2
toBool (c_duckdb_validity_row_is_valid mask 2) >>= (@?= True)
validitySetOperations :: TestTree
validitySetOperations =
testCase "set_row_validity toggles state based on CBool" $ do
withIntegerVector 3 \vec -> do
void (c_duckdb_vector_ensure_validity_writable vec)
mask <- c_duckdb_vector_get_validity vec
setAllValid mask 3
c_duckdb_validity_set_row_validity mask 1 (CBool 0)
toBool (c_duckdb_validity_row_is_valid mask 1) >>= (@?= False)
c_duckdb_validity_set_row_validity mask 1 (CBool 1)
toBool (c_duckdb_validity_row_is_valid mask 1) >>= (@?= True)
-- Helpers -------------------------------------------------------------------
withIntegerVector :: DuckDBIdx -> (DuckDBVector -> IO a) -> IO a
withIntegerVector capacity action =
withLogicalType (c_duckdb_create_logical_type DuckDBTypeInteger) \intType ->
withVector (c_duckdb_create_vector intType capacity) action
toBool :: IO CBool -> IO Bool
toBool action = do
CBool v <- action
pure (v /= 0)