c9ac014473
- 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.
291 lines
5.3 KiB
Go
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()
|
|
}
|