96 lines
3.5 KiB
Swift
96 lines
3.5 KiB
Swift
//
|
|
// SQLiteStatementTests.swift
|
|
//
|
|
// Copyright 2026 Brendan Szymanski <hello@bscubed.dev>
|
|
//
|
|
// 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 <https://www.gnu.org/licenses/>.
|
|
//
|
|
// 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)
|
|
}
|
|
}
|