Files
photocli/internal/manifest/sqlite/adapter_test.go
T
Ein Anderssono c9ac014473
pipeline / test (push) Has been cancelled
pipeline / build (push) Has been cancelled
v0.10.0: ports and adapters refactor
- Extract shared manifest types into internal/manifest/types leaf package.
- Extract SQLite adapter into internal/manifest/sqlite.
- Extract JSONL adapter into internal/manifest/jsonl.
- Isolate modernc.org/sqlite import to sqlite/adapter.go.
- Add adapter-backed registry with manifest.Default.
- Adapter-agnostic ConvertManifest in types/.
- MemoryAdapter for in-memory manifest testing.
- CLI uses manifest.Default registry directly.
- SQLite LogWriter type assertion moved into SQLiteAdapter.
- Manifest interface includes Entries(); EntryReader removed.
- No behavior changes. 100% coverage across all 6 packages.
2026-06-15 08:27:38 +02:00

291 lines
5.3 KiB
Go

package sqlite
import (
"database/sql"
"fmt"
"path/filepath"
"testing"
_ "modernc.org/sqlite"
"gitea.k3s.k0.nu/tools/photocli/internal/manifest/types"
)
func TestAdapter(t *testing.T) {
a := Adapter{}
if a.Format() != types.FormatSQLite {
t.Fatal("expected SQLite format")
}
if len(a.Aliases()) != 2 {
t.Fatal("expected 2 aliases")
}
dir := t.TempDir()
if a.Path(dir) != Path(dir) {
t.Fatal("expected path match")
}
if a.Exists(dir) {
t.Fatal("expected not to exist in empty dir")
}
m, err := a.Open(dir)
if err != nil {
t.Fatal(err)
}
m.Close()
w, err := a.OpenLogWriter(nil, dir)
if err != nil {
t.Fatal(err)
}
w.Close()
}
func TestAdapterOpenLogWriterSQLite(t *testing.T) {
dir := t.TempDir()
m, err := Load(dir)
if err != nil {
t.Fatal(err)
}
if err := m.OpenAppend(); err != nil {
t.Fatal(err)
}
defer m.Close()
w, err := Adapter{}.OpenLogWriter(m, dir)
if err != nil {
t.Fatal(err)
}
defer w.Close()
if _, ok := w.(*LogWriter); !ok {
t.Fatalf("expected sqlite log writer, got %T", w)
}
}
func TestStoreLoadEmpty(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
if m == nil {
t.Fatal("expected non-nil store")
}
m.Close()
}
func TestStoreLoadNonexistent(t *testing.T) {
m, err := Load("/nonexistent/path")
if err != nil {
t.Fatal(err)
}
if m == nil {
t.Fatal("expected non-nil store")
}
m.Close()
}
func TestStoreAddHasSaveClose(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
if err := m.OpenAppend(); err != nil {
t.Fatal(err)
}
m.Add("sid1", "sfile.jpg", 99, "azure")
if !m.Has("sid1") {
t.Fatal("expected Has to return true")
}
if m.Has("nope") {
t.Fatal("expected Has to return false")
}
if err := m.Save(); err != nil {
t.Fatal(err)
}
m.Close()
}
func TestStoreRoundTrip(t *testing.T) {
dir := t.TempDir()
m, err := Load(dir)
if err != nil {
t.Fatal(err)
}
if err := m.OpenAppend(); err != nil {
t.Fatal(err)
}
m.Add("rid1", "rfile1.jpg", 10, "aws")
m.Add("rid2", "rfile2.jpg", 20, "gcs")
if err := m.Save(); err != nil {
t.Fatal(err)
}
m.Close()
m2, err := Load(dir)
if err != nil {
t.Fatal(err)
}
if err := m2.OpenAppend(); err != nil {
t.Fatal(err)
}
defer m2.Close()
if !m2.Has("rid1") {
t.Fatal("expected rid1 after reload")
}
if !m2.Has("rid2") {
t.Fatal("expected rid2 after reload")
}
}
func TestStoreEntries(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
if err := m.OpenAppend(); err != nil {
t.Fatal(err)
}
defer m.Close()
m.Add("se1", "sf1.jpg", 1, "sc1")
m.Add("se2", "sf2.jpg", 2, "sc2")
entries := m.Entries()
if len(entries) != 2 {
t.Fatalf("expected 2 entries, got %d", len(entries))
}
}
func TestStoreCloseIdempotent(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
if err := m.OpenAppend(); err != nil {
t.Fatal(err)
}
m.Close()
m.Close()
}
func TestStoreOpenAppendIdempotent(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
if err := m.OpenAppend(); err != nil {
t.Fatal(err)
}
if err := m.OpenAppend(); err != nil {
t.Fatal(err)
}
m.Close()
}
func TestStoreManifestFormat(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
if m.ManifestFormat() != types.FormatSQLite {
t.Fatal("expected SQLite format")
}
}
func TestStoreSave(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
if err := m.Save(); err != nil {
t.Fatal(err)
}
}
func TestStoreOpenAppendCreateDir(t *testing.T) {
dir := t.TempDir()
subdir := filepath.Join(dir, "subdir")
m, err := Load(subdir)
if err != nil {
t.Fatal(err)
}
if err := m.OpenAppend(); err != nil {
t.Fatal(err)
}
m.Close()
}
func TestStoreCloseWithoutOpen(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
m.Close()
}
func TestStoreEntriesWithoutOpen(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
entries := m.Entries()
if entries != nil {
t.Errorf("Entries without open should return nil, got %v", entries)
}
}
func TestStoreHasWithoutOpen(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
if m.Has("x") {
t.Fatal("Has should return false without open")
}
}
func TestStoreAddEntryWithoutOpen(t *testing.T) {
m, err := Load(t.TempDir())
if err != nil {
t.Fatal(err)
}
m.AddEntry(types.Entry{ID: "x", Filename: "f.jpg"})
}
func TestSetOpener(t *testing.T) {
old := SetOpener(func(driverName, dataSourceName string) (*sql.DB, error) {
return nil, fmt.Errorf("test")
})
if old != nil {
t.Fatal("expected nil old opener")
}
restore := SetOpener(old)
if restore == nil {
t.Fatal("expected non-nil restore")
}
SetOpener(nil)
}
func TestFileExists(t *testing.T) {
dir := t.TempDir()
if FileExists(dir) {
t.Fatal("expected false for directory")
}
if FileExists("/nonexistent/file") {
t.Fatal("expected false for nonexistent")
}
}
func TestLogWriterClose(t *testing.T) {
w := &LogWriter{}
w.Close()
}
func TestOpenerWithOverride(t *testing.T) {
SetOpener(func(driverName, dataSourceName string) (*sql.DB, error) {
return nil, nil
})
if opener() == nil {
t.Fatal("expected override")
}
SetOpener(nil)
}
func TestLogWriterCloseDirect(t *testing.T) {
(&LogWriter{}).Close()
}