// // SQLiteStatementTests.swift // // Copyright 2026 Brendan Szymanski // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // SPDX-License-Identifier: GPL-3.0-or-later // import Foundation import Testing @testable import LuminateCore @testable import LuminateStore @Suite struct SQLiteStatementTests { @Test("Preparing malformed SQL fails with a non-empty diagnostic") func prepareFailureReportsDiagnostic() throws { let (url, directory) = makeDatabaseURL() defer { try? FileManager.default.removeItem(at: directory) } let database = try SQLiteDatabase(url: url) #expect(throws: PreferenceStoreError.self) { _ = try SQLiteStatement(database: database, sql: "NOT SQL") } do { _ = try SQLiteStatement(database: database, sql: "NOT SQL") Issue.record("Expected malformed SQL to throw") } catch let error as PreferenceStoreError { if case .sqlite(let message) = error { #expect(!message.isEmpty) } else { Issue.record("Expected .sqlite, got \(error)") } } } @Test("Binding past the parameter count fails") func bindOutOfRangeFails() throws { let (url, directory) = makeDatabaseURL() defer { try? FileManager.default.removeItem(at: directory) } let database = try SQLiteDatabase(url: url) let statement = try SQLiteStatement(database: database, sql: "SELECT ?1;") #expect(throws: PreferenceStoreError.self) { try statement.bind(99, text: "x") } } @Test("A constraint violation on step fails") func stepConstraintViolationFails() throws { let (url, directory) = makeDatabaseURL() defer { try? FileManager.default.removeItem(at: directory) } let database = try SQLiteDatabase(url: url) try database.exec("CREATE TABLE t (id INTEGER PRIMARY KEY, v TEXT NOT NULL);") let statement = try SQLiteStatement(database: database, sql: "INSERT INTO t (v) VALUES (NULL);") #expect(throws: PreferenceStoreError.self) { _ = try statement.step() } } @Test("A NULL result column decodes as nil") func nullColumnDecodesAsNil() throws { let (url, directory) = makeDatabaseURL() defer { try? FileManager.default.removeItem(at: directory) } let database = try SQLiteDatabase(url: url) let statement = try SQLiteStatement(database: database, sql: "SELECT NULL;") _ = try statement.step() #expect(statement.preference(at: 0) == nil) } private func makeDatabaseURL() -> (URL, URL) { let directory = FileManager.default.temporaryDirectory .appending(path: "luminate-store-\(UUID().uuidString)", directoryHint: .isDirectory) return (directory.appending(path: "preferences.sqlite"), directory) } }