This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is test_factory, a PostgreSQL extension that provides a framework for managing unit test data in databases. It solves the common problem of creating and maintaining test data by providing a system to register test data definitions once and retrieve them efficiently with automatic dependency resolution.
This project uses PGXNtool for build management. Key commands:
make # Build the extension
make install # Install to PostgreSQL
make clean # Clean build artifacts
make distclean # Clean all generated files including META.jsonmake test # Run full test suite (install, then test)
make installcheck # Run tests only (no clean/install)
make results # Update expected test results (only after verifying tests pass!)make tag # Create git tag for current version
make dist # Create distribution zip file
make forcetag # Force recreate tag if it exists
make forcedist # Force tag + distributiontf.register(table_name, test_sets[])- Register test data definitions for a tabletf.get(table_type, set_name)- Retrieve test data, creating it if it doesn't existtf.tap(table_name, set_name)- pgTAP integration wrapper for testing
tfschema: User-facing API (functions, types)_tfschema: Internal implementation (tables, security definer functions)_test_factory_test_dataschema: Cached test data storage- Uses dedicated
test_factory__ownerrole for security isolation
- Role-based access with
test_factory__ownerfor data management - Security definer functions with
search_path=pg_catalog - Proper permission isolation between user and system operations
CREATE TYPE tf.test_set AS (
set_name text, -- Name to reference this test data set
insert_sql text -- SQL command that returns test data rows
);- Registration: Use
tf.register()to define how test data is created - Retrieval: Call
tf.get()to obtain test data (creates on first call) - Caching: Test data is stored permanently for fast subsequent access
- Dependencies: Test sets can reference other test sets via embedded
tf.get()calls
- Test data created once and cached in permanent tables
- Subsequent
tf.get()calls return cached data without recreation - Data remains available even if source tables are modified/truncated
- Dependency resolution handled automatically during creation
sql/test_factory.sqlandsql/test_factory--0.5.0.sql: Main extension code- Complex role management and schema setup with proper cleanup
- Security definer functions for safe cross-schema operations
META.in.json: Template for PGXN metadata (processed toMETA.json)test_factory.control: PostgreSQL extension control fileMakefile: Simple inclusion of pgxntool's build system
- Making Changes: Modify source files in
sql/directory - Testing: Run
make testto ensure all tests pass - Version Updates: Update version in both
META.in.jsonandtest_factory.control - Distribution: Use
make distto create release packages
The extension handles complex bootstrapping during installation:
- Creates temporary role tracking for safe installation
- Sets up three schemas with proper ownership and permissions
- Uses security definer pattern for controlled access to internal functions
- Automatically restores original database role after installation
- Implements dependency resolution through recursive
tf.get()calls
SELECT tf.register(
'customer',
array[
row('base', 'INSERT INTO customer VALUES (DEFAULT, ''Test'', ''User'') RETURNING *')::tf.test_set
]
);SELECT tf.register(
'invoice',
array[
row('base', 'INSERT INTO invoice VALUES (DEFAULT, (tf.get(NULL::customer, ''base'')).customer_id, current_date) RETURNING *')::tf.test_set
]
);-- Gets customer test data, creating it if needed
SELECT * FROM tf.get(NULL::customer, 'base');
-- Gets invoice test data, automatically creating dependent customer data
SELECT * FROM tf.get(NULL::invoice, 'base');