Files
dcf/pkg/dcf/dcf_test.go
T
clawbot acb108a82e get cards with GetStores and GetStore, read them through fs.FS (closes #4)
GetStores replaces GetDCFStores: it takes a context, has no count
argument and returns a plain slice. GetStore returns the one mounted
card, or ErrNoStore or ErrMultipleStores.

Each Object keeps the fs.FS its card was read through, and Hash reads
through it, so tests can use fstest.MapFS. A cancelled context stops
the read before the next directory. Library errors wrap with %w.

Model: opus-5-5
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
2026-11-03 20:54:19 +01:00

156 lines
3.4 KiB
Go

package dcf_test
import (
"context"
"errors"
"io/fs"
"testing"
"sneak.berlin/go/dcf/pkg/dcf"
)
const cardRoot = "/mnt/card"
// newStore returns a store holding two images and one video of known sizes.
func newStore() *dcf.Store {
return &dcf.Store{
RootDirectory: cardRoot,
Images: []*dcf.Image{
{Object: dcf.Object{Size: 2000}},
{Object: dcf.Object{Size: 500}},
},
Videos: []*dcf.Video{
{Object: dcf.Object{Size: 9000}},
},
}
}
func TestObjectFullFilePath(t *testing.T) {
t.Parallel()
object := dcf.Object{
DCFStoreRoot: cardRoot,
Path: "DCIM/100MSDCF/DSC00001.ARW",
}
want := cardRoot + "/DCIM/100MSDCF/DSC00001.ARW"
if got := object.FullFilePath(); got != want {
t.Fatalf("FullFilePath() = %q, want %q", got, want)
}
}
func TestStoreCounts(t *testing.T) {
t.Parallel()
store := newStore()
if got := store.ImagesCount(); got != 2 {
t.Errorf("ImagesCount() = %d, want 2", got)
}
if got := store.VideosCount(); got != 1 {
t.Errorf("VideosCount() = %d, want 1", got)
}
}
func TestStoreSizes(t *testing.T) {
t.Parallel()
store := newStore()
if got := store.TotalImageSize(); got != 2500 {
t.Errorf("TotalImageSize() = %d, want 2500", got)
}
if got := store.TotalVideoSize(); got != 9000 {
t.Errorf("TotalVideoSize() = %d, want 9000", got)
}
if got := store.TotalSize(); got != 11500 {
t.Errorf("TotalSize() = %d, want 11500", got)
}
}
func TestStoreString(t *testing.T) {
t.Parallel()
want := "Store{RootDirectory: /mnt/card, Images: 2, Videos: 1, " +
"TotalSize: 12 kB}"
if got := newStore().String(); got != want {
t.Fatalf("String() = %q, want %q", got, want)
}
}
func TestStoreStringShowsNegativeTotalAsZero(t *testing.T) {
t.Parallel()
store := dcf.Store{
RootDirectory: cardRoot,
Images: []*dcf.Image{{Object: dcf.Object{Size: -1}}},
}
want := "Store{RootDirectory: /mnt/card, Images: 1, Videos: 0, " +
"TotalSize: 0 B}"
if got := store.String(); got != want {
t.Fatalf("String() = %q, want %q", got, want)
}
}
func TestImageString(t *testing.T) {
t.Parallel()
image := dcf.Image{Object: dcf.Object{
Path: "DCIM/100MSDCF/DSC00001.ARW",
Size: 2000,
Extension: ".ARW",
}}
want := "Image{Path: DCIM/100MSDCF/DSC00001.ARW, Size: 2000, Extension: .ARW}"
if got := image.String(); got != want {
t.Fatalf("String() = %q, want %q", got, want)
}
}
func TestVideoString(t *testing.T) {
t.Parallel()
video := dcf.Video{Object: dcf.Object{
Path: "PRIVATE/M4ROOT/CLIP/C0001.MP4",
Size: 9000,
Extension: ".MP4",
}}
want := "Video{Path: PRIVATE/M4ROOT/CLIP/C0001.MP4, Size: 9000, Extension: .MP4}"
if got := video.String(); got != want {
t.Fatalf("String() = %q, want %q", got, want)
}
}
func TestObjectHashOfObjectBuiltByHandReturnsError(t *testing.T) {
t.Parallel()
object := dcf.Object{DCFStoreRoot: cardRoot, Path: "a.jpg"}
_, err := object.Hash()
if !errors.Is(err, fs.ErrInvalid) {
t.Fatalf("Hash() error = %v, want %v", err, fs.ErrInvalid)
}
}
func TestGetStoresAndGetStoreReturnCancellation(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithCancel(t.Context())
cancel()
_, err := dcf.GetStores(ctx)
if !errors.Is(err, context.Canceled) {
t.Errorf("GetStores error = %v, want %v", err, context.Canceled)
}
_, err = dcf.GetStore(ctx)
if !errors.Is(err, context.Canceled) {
t.Errorf("GetStore error = %v, want %v", err, context.Canceled)
}
}