# Test Suite Coverage

# Test Suite Coverage

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [test/benchmark/bulk-benchmark.test.ts](test/benchmark/bulk-benchmark.test.ts)
- [test/dal-timeout.test.ts](test/dal-timeout.test.ts)
- [test/dal.test.ts](test/dal.test.ts)
- [test/repository-bulk.test.ts](test/repository-bulk.test.ts)
- [test/repository-crud.test.ts](test/repository-crud.test.ts)
- [test/repository-negative.test.ts](test/repository-negative.test.ts)
- [test/repository-streaming.test.ts](test/repository-streaming.test.ts)
- [test/repository-types.test.ts](test/repository-types.test.ts)

</details>



The `@primebrick/dal-pg` test suite is designed to ensure the reliability of the Data Access Layer (DAL) across various operational scenarios, including standard CRUD, high-volume bulk operations, complex type mappings, and resource management under stress. The suite utilizes **Vitest** for test execution and requires a live PostgreSQL instance (configured via `DATABASE_URL`) to perform integration testing against real database behaviors [test/dal.test.ts:31-34]().

## Core Test Files and Coverage

### 1. Repository CRUD and Finders
**File:** `test/repository-crud.test.ts`
This file covers the fundamental data access patterns of the `Repository` class using `SimpleTestEntity` [test/repository-crud.test.ts:4-12]().

*   **Write Lifecycle:** Verifies that `add` correctly inserts rows, returns them with `RETURNING *`, and automatically stamps audit fields (`created_by`, `version`, etc.) [test/repository-crud.test.ts:32-62]().
*   **Finder Logic:** Validates `findById`, `findByUUID`, and `find` (with DSL filters) [test/repository-crud.test.ts:72-142]().
*   **Soft-Delete Visibility:** Tests `findAll` behavior regarding the `deletedRecords` option (`EXCLUDED`, `INCLUDED`, `ONLY`) to ensure soft-deleted records are filtered correctly by default [test/repository-crud.test.ts:164-195]().
*   **Pagination:** Ensures `findByPage` correctly utilizes window functions to return both the data subset and the `total_records` count [test/repository-crud.test.ts:199-201]().

### 2. Bulk Operations
**File:** `test/repository-bulk.test.ts`
Focuses on high-efficiency write methods and the internal batching logic [test/repository-bulk.test.ts:12-14]().

*   **addMany:** Validates auto-batching when row counts exceed internal limits and ensures all rows receive audit stamps [test/repository-bulk.test.ts:32-79]().
*   **upsertMany:** Tests the `INSERT ON CONFLICT` logic, verifying that existing rows have their `version` incremented while new rows are created [test/repository-bulk.test.ts:97-136]().
*   **updateMany:** Exercises the **TEMP TABLE strategy**. It verifies that the DAL creates a temporary table, populates it, and performs a single join-based `UPDATE` [test/repository-bulk.test.ts:181-202]().
*   **deleteMany:** Validates bulk soft-deletion using the `ANY()` array operator [test/repository-bulk.test.ts:148-169]().

### 3. Type Mapping Matrix
**File:** `test/repository-types.test.ts`
Ensures parity between JavaScript types and PostgreSQL OIDs [test/repository-types.test.ts:12-14]().

| JS Type | PG Type | Test Coverage |
| :--- | :--- | :--- |
| `number` | `INTEGER` | Round-trips, negative values, and zero [test/repository-types.test.ts:31-99](). |
| `bigint` | `BIGINT` | Verified via native `BigInt` and `INT8` parser registration [test/repository-types.test.ts:103-150](). |
| `boolean` | `BOOLEAN` | Round-trips for `true`/`false` [test/repository-types.test.ts:153-197](). |
| `string` | `VARCHAR` / `TEXT` | UTF-8 support and null handling [test/repository-types.test.ts:201-223](). |
| `Date` | `TIMESTAMPTZ` | Precision and timezone preservation. |

### 4. Streaming and AsyncIterables
**File:** `test/repository-streaming.test.ts`
Validates the integration with `pg-query-stream` [test/repository-streaming.test.ts:12-14]().

*   **Memory Efficiency:** Verifies that `findAll` with `stream: true` returns an `AsyncIterable` rather than an array [test/repository-streaming.test.ts:30-46]().
*   **Consumption:** Ensures large result sets (e.g., 100+ rows) can be iterated without buffering the entire set into Node.js memory [test/repository-streaming.test.ts:71-91]().

### 5. Negative Paths and Error Handling
**File:** `test/repository-negative.test.ts`
Ensures the DAL fails gracefully and provides actionable error codes [test/repository-negative.test.ts:18-21]().

*   **NotFoundError:** Thrown when primary keys or UUIDs do not exist [test/repository-negative.test.ts:42-63]().
*   **ValidationError:** Thrown for empty insert/update payloads or invalid pagination parameters (e.g., page 0) [test/repository-negative.test.ts:115-174]().
*   **UnknownColumnError:** Triggered when an entity object contains properties not decorated as columns [test/repository-negative.test.ts:177-200]().
*   **Silent Failures:** Confirms that bulk operations with empty arrays return `[]` instead of throwing [test/repository-negative.test.ts:204-225]().

### 6. Dal Gateway and Lifecycle
**File:** `test/dal.test.ts`
Tests the `Dal` singleton, pool management, and session initialization [test/dal.test.ts:19-25]().

*   **Singleton Guard:** Ensures `getDal()` returns a consistent instance and enforces connection string immutability [test/dal.test.ts:23-24]().
*   **Pool Lifecycle:** Tests `close()` re-entrancy, the 10-second graceful shutdown timeout, and post-closure rejection of queries [test/dal.test.ts:77-136]().
*   **onConnect:** Verifies that every new connection executes the session setup (setting `search_path`, `statement_timeout`, and `application_name`) [test/dal.test.ts:140-166]().

### 7. Timeout Management
**File:** `test/dal-timeout.test.ts`
Detailed verification of `statement_timeout` behavior and leakage prevention [test/dal-timeout.test.ts:31-35]().

*   **Per-call Overrides:** Verifies that `timeoutMs` in bulk options or `withClient` successfully emits `SET LOCAL statement_timeout` [test/dal-timeout.test.ts:133-145]().
*   **Leakage Prevention:** Crucial test ensuring that if a client is returned to the pool after a custom timeout, the next consumer sees the *global* default, not the overridden value [test/dal-timeout.test.ts:157-179]().
*   **Execution Abort:** Confirms that `pg_sleep()` calls exceeding the `timeoutMs` are successfully terminated by the database [test/dal-timeout.test.ts:181-193]().

### 8. Performance Benchmarks
**File:** `test/benchmark/bulk-benchmark.test.ts`
Measures throughput at scales of 100, 1K, 10K, and (optionally) 1M rows [test/benchmark/bulk-benchmark.test.ts:98-101]().

*   **Throughput Metrics:** Tracks records-per-second (RPS) for `updateMany` and `upsertMany` across simple and complex (primitive-heavy) tables [test/benchmark/bulk-benchmark.test.ts:66-84]().

## System Interaction Diagrams

### Data Flow: Write Operations and Validation
This diagram maps the flow from a Repository call to the database, highlighting where validation and error entities are triggered.

Title: Repository Write Flow and Error Mapping
```mermaid
graph TD
    subgraph "Natural Language Space"
        UserAction["User attempts to update record"]
        MissingRecord["Record does not exist"]
        InvalidFields["Invalid column names provided"]
    end

    subgraph "Code Entity Space"
        RepoCall["Repository.update()"]
        MetaCheck["getEntityPersistenceMeta()"]
        SqlBuild["buildUpdateQuery()"]
        DalExec["Dal.rawSql()"]
        
        NotFoundErr["NotFoundError (code: 'NOT_FOUND')"]
        UnknownColErr["UnknownColumnError (code: 'UNKNOWN_COLUMN')"]
    end

    UserAction --> RepoCall
    RepoCall --> MetaCheck
    MetaCheck -- "Invalid property" --> UnknownColErr
    RepoCall --> SqlBuild
    SqlBuild --> DalExec
    DalExec -- "0 rows affected" --> NotFoundErr
    MissingRecord -.-> NotFoundErr
    InvalidFields -.-> UnknownColErr
```
Sources: [test/repository-negative.test.ts:76-84](), [test/repository-negative.test.ts:187-200]()

### Connection Lifecycle and Timeout Reset
This diagram illustrates how the `Dal` ensures that `statement_timeout` settings do not leak between different requests.

Title: Connection Pool Timeout Safety
```mermaid
graph TD
    subgraph "Pool Management"
        Pool["pg.Pool"]
        Client["pg.PoolClient"]
    end

    subgraph "Test Scenarios (dal-timeout.test.ts)"
        T1["Test: withClient({timeoutMs: 1000})"]
        T2["Test: subsequent withClient()"]
    end

    T1 -->|Acquire| Client
    Client -->|Exec| SetLocal["SET LOCAL statement_timeout = 1000"]
    T1 -->|Release| Pool
    Pool -->|Reset| ResetCall["SET statement_timeout = default (30000)"]
    
    T2 -->|Acquire| Client
    Client -->|Verify| CheckSetting["SELECT current_setting('statement_timeout')"]
    CheckSetting -- "Returns 30000" --> Success["No Leakage Detected"]
```
Sources: [test/dal-timeout.test.ts:157-179](), [test/dal.test.ts:140-166]()

## Summary of Coverage Files
| File | Focus | Primary Entities |
| :--- | :--- | :--- |
| `repository-crud.test.ts` | Basic Operations | `SimpleTestEntity` |
| `repository-bulk.test.ts` | Batch Processing | `SimpleTestEntity` |
| `repository-types.test.ts` | PG/JS Serialization | `TypeTestEntity` |
| `repository-streaming.test.ts` | Memory Management | `SimpleTestEntity` |
| `repository-negative.test.ts` | Error Paths | All |
| `dal.test.ts` | Pool & Lifecycle | N/A |
| `dal-timeout.test.ts` | Transaction Safety | N/A |
| `bulk-benchmark.test.ts` | Performance | `BenchSimpleEntity`, `BenchPrimitivesEntity` |

Sources: [test/repository-crud.test.ts:1-12](), [test/repository-bulk.test.ts:1-12](), [test/repository-types.test.ts:1-12](), [test/repository-streaming.test.ts:1-12](), [test/repository-negative.test.ts:1-21](), [test/dal.test.ts:1-25](), [test/dal-timeout.test.ts:1-35](), [test/benchmark/bulk-benchmark.test.ts:1-22]()

---
