testutil

package
v0.6.1 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2025 License: MIT Imports: 11 Imported by: 0

README

Testing Infrastructure

This package provides testing utilities for ModFetch that work without network connectivity.

Overview

The testutil package provides:

  • Mock HTTP servers with canned responses
  • In-memory SQLite database for testing
  • Test fixture loading helpers
  • Mock HTTP round trippers
  • Temporary file/directory helpers

Usage

Creating a Test Database
func TestSomething(t *testing.T) {
    db := testutil.TestDB(t)
    // Use db for testing
    // Automatically cleaned up when test completes
}
Mock HTTP Server
func TestHTTPFetcher(t *testing.T) {
    server := testutil.NewMockHTTPServer()
    defer server.Close()

    // Add canned responses
    server.AddJSONResponse("/api/models/123", 200, `{"id": 123, "name": "test"}`)

    // Use server.URL in your tests
    client := &http.Client{}
    resp, err := client.Get(server.URL + "/api/models/123")
    // ... assertions
}
Loading Fixtures
func TestWithFixture(t *testing.T) {
    json := testutil.LoadFixture(t, "huggingface_model.json")
    // Use fixture data in tests
}
Mock Round Tripper
func TestHTTPClient(t *testing.T) {
    mock := testutil.NewMockRoundTripper()
    mock.AddStringResponse("https://api.example.com/model", 200, `{"result": "ok"}`)

    client := &http.Client{Transport: mock}
    // Use client

    // Verify requests
    mock.AssertRequestMade(t, "https://api.example.com/model")
}

Test Fixtures

Fixtures are stored in testdata/fixtures/ and include:

  • huggingface_model.json - Sample HuggingFace API response
  • civitai_model.json - Sample CivitAI API response

Add new fixtures as needed for additional test cases.

Running Tests

The test infrastructure is designed to work without network connectivity. All external API calls are mocked with canned responses.

# Run all tests
go test ./...

# Run tests for specific package
go test ./internal/metadata/...

# Run with verbose output
go test -v ./internal/state/...

# Run specific test
go test -run TestDB_UpsertMetadata ./internal/state/...

Best Practices

  1. Always use testutil.TestDB() for database tests - it creates an in-memory database that's automatically cleaned up
  2. Use fixtures for API responses - keeps tests maintainable and realistic
  3. Mock HTTP transports - don't make real network calls in tests
  4. Use t.Helper() in utility functions - improves error reporting
  5. Clean up resources - use t.Cleanup() for deferred cleanup

Coverage

Current test coverage includes:

Metadata Package
  • ✅ HuggingFace fetcher with mocked API responses
  • ✅ CivitAI fetcher with mocked API responses
  • ✅ Model type inference from filenames and tags
  • ✅ Quantization extraction from filenames
  • ✅ URL pattern matching
  • ✅ Error handling for API failures
State Package
  • ✅ Metadata CRUD operations (create, read, update, delete)
  • ✅ Filtering by source, type, rating, tags, favorites
  • ✅ Full-text search across metadata fields
  • ✅ Usage tracking (times_used, last_used)
  • ✅ Tag JSON serialization/deserialization
  • ✅ Timestamp handling

Future Test Coverage Needed

  • Batch package tests
  • Downloader package tests with mock HTTP servers
  • TUI model tests (unit tests for state transitions)
  • Integration tests for full download flow
  • Resolver package tests
  • Config loading and validation tests
  • Metrics package tests

Documentation

Index

Constants

View Source
const MaxAPIRetries = 3

MaxAPIRetries is the default number of retries for flaky external API calls

Variables

This section is empty.

Functions

func Int64Ptr

func Int64Ptr(i int64) *int64

Int64Ptr returns a pointer to an int64

func IntPtr

func IntPtr(i int) *int

IntPtr returns a pointer to an int

func LoadFixture

func LoadFixture(t *testing.T, name string) string

LoadFixture loads a test fixture file

func RetryOnAPIError

func RetryOnAPIError(t *testing.T, maxRetries int, operation func() error, operationName string)

RetryOnAPIError retries an operation when it encounters API-related errors This is useful for flaky external API integration tests (e.g., CivitAI, HuggingFace) Uses exponential backoff between retries (1s, 2s, 4s) Returns error if all retries fail with non-API errors, or skips test if API is unavailable

func StringPtr

func StringPtr(s string) *string

StringPtr returns a pointer to a string (useful for optional fields)

func TempDir

func TempDir(t *testing.T) string

TempDir creates a temporary directory for testing

func TempFile

func TempFile(t *testing.T, name, content string) string

TempFile creates a temporary file with content

func TestDB

func TestDB(t *testing.T) *state.DB

TestDB creates an in-memory SQLite database for testing

func TryLoadFixture

func TryLoadFixture(name string) string

TryLoadFixture attempts to load a fixture, returns empty string if not found

Types

type MockHTTPServer

type MockHTTPServer struct {
	*httptest.Server
	Responses map[string]MockResponse
}

MockHTTPServer creates a test HTTP server that serves canned responses from fixtures

func NewMockHTTPServer

func NewMockHTTPServer() *MockHTTPServer

NewMockHTTPServer creates a new mock HTTP server

func (*MockHTTPServer) AddJSONResponse

func (ms *MockHTTPServer) AddJSONResponse(path string, statusCode int, body string)

AddJSONResponse adds a JSON response for a specific path

func (*MockHTTPServer) AddResponse

func (ms *MockHTTPServer) AddResponse(path string, response MockResponse)

AddResponse adds a canned response for a specific path

type MockResponse

type MockResponse struct {
	StatusCode int
	Body       string
	Headers    map[string]string
}

MockResponse represents a canned HTTP response

type MockRoundTripper

type MockRoundTripper struct {
	Responses map[string]*http.Response
	Requests  []*http.Request
}

MockRoundTripper implements http.RoundTripper for testing

func NewMockRoundTripper

func NewMockRoundTripper() *MockRoundTripper

NewMockRoundTripper creates a new mock round tripper

func (*MockRoundTripper) AddStringResponse

func (m *MockRoundTripper) AddStringResponse(url string, statusCode int, body string)

AddStringResponse adds a simple string response

func (*MockRoundTripper) AssertRequestMade

func (m *MockRoundTripper) AssertRequestMade(t *testing.T, url string)

AssertRequestMade checks if a request was made to a specific URL

func (*MockRoundTripper) RoundTrip

func (m *MockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper

Jump to

Keyboard shortcuts

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