@@ -648,6 +648,44 @@ spec = before setupConn do
648648 p `shouldEqual` "file"
649649 SQLite.close conn # liftEffect
650650
651+ it "empty batch returns empty array" \conn -> do
652+ results <- SQLite.batch SQLite.Write [] conn
653+ Array.length results `shouldEqual` 0
654+
655+ it "txClosed reflects transaction state" \_ -> do
656+ conn <- withTempDb
657+ SQLite.executeSimple (SQLite.SQL (createTableDDL @UsersTable)) conn # void
658+ txn <- SQLite.begin conn
659+ before_ <- SQLite.txClosed txn # liftEffect
660+ before_ `shouldEqual` false
661+ SQLite.commit txn
662+ after_ <- SQLite.txClosed txn # liftEffect
663+ after_ `shouldEqual` true
664+ SQLite.close conn # liftEffect
665+
666+ it "Maybe SQLiteValue passes null for Nothing" \conn -> do
667+ SQLite.executeSimple (SQLite.SQL (createTableDDL @UsersTable)) conn # void
668+ SQLite.execute
669+ (SQLite.SQL "INSERT INTO users (name, email, age) VALUES (?1, ?2, ?3)")
670+ [ SQLite.toSQLiteValue "Alice"
671+ , SQLite.toSQLiteValue "a@b.com"
672+ , SQLite.toSQLiteValue (Nothing :: Maybe Int)
673+ ]
674+ conn # void
675+ rows <- runQuery conn {} (from usersTable # selectAll)
676+ let ages = map (_.age) (rows :: Array { id :: Int, name :: String, email :: String, age :: Maybe Int })
677+ ages `shouldEqual` [Nothing]
678+
679+ it "SQLiteBool as SQLiteValue" \conn -> do
680+ SQLite.executeSimple (SQLite.SQL (createTableDDL @ConfigTable)) conn # void
681+ SQLite.execute
682+ (SQLite.SQL "INSERT INTO config (active) VALUES (?1)")
683+ [ SQLite.toSQLiteValue (SQLiteBool false) ]
684+ conn # void
685+ rows <- runQuery conn {} (from (Proxy :: Proxy ConfigTable) # selectAll)
686+ let actives = map (\r -> r.active) (rows :: Array { id :: Int, active :: SQLiteBool, role :: String, score :: Int })
687+ actives `shouldEqual` [SQLiteBool false]
688+
651689 describe "DDL RANDOM ROWID" do
652690 it "generates DDL with RANDOM ROWID suffix" \_ -> do
653691 let result = createTableDDL @RandomRowIdTable