filetest

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package filetest is the conformance suite for contracts.Service, a Storage in memory that the suite runs against, and a fake Service that passes it.

It exists because an interface is justified by a passing fake and not by a second production implementation (AGENTS.md rule 8). RunService is the specification written as executable cases; the real service and the fake both run it.

Index

Constants

View Source
const Limit = 1 << 10

Limit is the largest upload the suite's implementations accept. It is small so that a case can go past it without allocating anything worth mentioning.

Variables

This section is empty.

Functions

func RunService

func RunService(t *testing.T, h Harness)

RunService is the conformance suite. Every implementation of contracts.Service passes it, or it is not one.

Types

type Fake

type Fake struct {
	// contains filtered or unexported fields
}

Fake is contracts.Service over a map of rows and whatever Storage it is given: the same rules, no database, no transaction. A consumer that wants to test what it does when a file is uploaded takes one of these and a Memory.

It ignores the transaction it is handed, and that is the honest limit of it: it cannot tell a caller that a write did not commit, because nothing here commits. What it does keep is the order the real service keeps — bytes first, row second, and the bytes removed again when the row is refused — because that order is the whole design and a fake that got it wrong would let a consumer test against a module that does not exist.

func NewFake

func NewFake(storage contracts.Storage, max int64) *Fake

NewFake returns a file module over storage, accepting uploads up to max.

func (*Fake) Delete

func (f *Fake) Delete(_ context.Context, _ db.Tx[db.Tenant], id uuid.UUID) (*contracts.File, error)

Delete mirrors internal.Service.Delete: the row goes and the bytes do not.

func (*Fake) Open

func (f *Fake) Open(ctx context.Context, _ db.Tx[db.Tenant], id uuid.UUID, anonymous bool) (*contracts.File, io.ReadCloser, error)

Open mirrors internal.Service.Open.

func (*Fake) Published

func (f *Fake) Published() []string

Published is the names of the events the fake would have emitted.

func (*Fake) Upload

func (f *Fake) Upload(ctx context.Context, open contracts.Tx, up contracts.Upload) (*contracts.File, error)

Upload mirrors internal.Service.Upload, including the order: the bytes are stored before the transaction is asked for, because a body arrives at the client's pace and nothing may be open while it does.

type Fixture

type Fixture struct {
	Ctx     context.Context
	Tx      db.Tx[db.Tenant]
	Service contracts.Service
	// Storage is the same store the Service was built on, for the cases about
	// what is left behind: an upload that was refused, and a delete that has
	// not been handled yet.
	Storage contracts.Storage
	// Keys is every key the storage currently holds, which is the one question
	// contracts.Storage does not answer and the only way to see an orphan.
	Keys func() []string
	// Published is the events the implementation has published, in order.
	Published func() []string
}

Fixture is one case's world: a Service, the transaction its commands take, and the storage behind it, so a case can check that the bytes went where the row says they did.

type Harness

type Harness func(t *testing.T, run func(Fixture))

Harness builds one Fixture and calls run with it.

type Memory

type Memory struct {
	// contains filtered or unexported fields
}

Memory is contracts.Storage over a map, for a consumer — and for the conformance suite — that wants a file module without a disk. It keeps the same promises the disk one does: a key that already exists is refused, a key with nothing at it is not an error to delete, and Get answers ErrNoBlob.

func NewMemory

func NewMemory() *Memory

NewMemory returns an empty store.

func (*Memory) Delete

func (m *Memory) Delete(_ context.Context, key string) error

Delete removes the bytes, and a key with nothing at it is not an error.

func (*Memory) Get

func (m *Memory) Get(_ context.Context, key string) (io.ReadCloser, error)

Get opens the bytes, or ErrNoBlob.

func (*Memory) Keys

func (m *Memory) Keys() []string

Keys is every key the store holds, sorted. It is the one question contracts.Storage does not answer, and the only way a test can see an orphan.

func (*Memory) Put

func (m *Memory) Put(_ context.Context, key string, r io.Reader, _ int64) error

Put reads everything and keeps it. size is ignored, as it is on disk.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL