@event-driven-io/emmett-testcontainers 0.43.0-beta.12 → 0.43.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +239 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# @event-driven-io/emmett-testcontainers
|
|
2
|
+
|
|
3
|
+
Testcontainers integration for running EventStoreDB in Docker containers during integration and end-to-end testing.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
This package provides a pre-configured Docker container wrapper for EventStoreDB, enabling isolated database testing without manual infrastructure setup. It handles container lifecycle management, supports both x86 and ARM64 architectures, and offers shared container functionality to optimize test suite performance.
|
|
8
|
+
|
|
9
|
+
## Key Concepts
|
|
10
|
+
|
|
11
|
+
| Concept | Description |
|
|
12
|
+
| -------------------------------- | ---------------------------------------------------------------------------------- |
|
|
13
|
+
| **EventStoreDBContainer** | A configured Docker container wrapper extending Testcontainers' `GenericContainer` |
|
|
14
|
+
| **StartedEventStoreDBContainer** | A running container instance providing connection strings and client access |
|
|
15
|
+
| **Shared Container** | Thread-safe singleton pattern for reusing a single container across multiple tests |
|
|
16
|
+
| **Architecture Detection** | Automatic selection of appropriate Docker image for x86 or ARM64 systems |
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Install the package using your preferred package manager:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm add @event-driven-io/emmett-testcontainers
|
|
24
|
+
# or
|
|
25
|
+
pnpm add @event-driven-io/emmett-testcontainers
|
|
26
|
+
# or
|
|
27
|
+
yarn add @event-driven-io/emmett-testcontainers
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
You also need to install the EventStoreDB client as a peer dependency:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm add @eventstore/db-client
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
### Basic Container Usage
|
|
39
|
+
|
|
40
|
+
Start a container, run your tests, and stop it:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { EventStoreDBContainer } from '@event-driven-io/emmett-testcontainers';
|
|
44
|
+
import { jsonEvent } from '@eventstore/db-client';
|
|
45
|
+
|
|
46
|
+
// Start the container
|
|
47
|
+
const container = await new EventStoreDBContainer().start();
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
// Get a client connected to the container
|
|
51
|
+
const client = container.getClient();
|
|
52
|
+
|
|
53
|
+
// Use the client for your tests
|
|
54
|
+
const result = await client.appendToStream(
|
|
55
|
+
'my-stream',
|
|
56
|
+
jsonEvent({ type: 'UserCreated', data: { userId: '123', name: 'Alice' } }),
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
console.log('Event appended:', result.success);
|
|
60
|
+
} finally {
|
|
61
|
+
// Always stop the container when done
|
|
62
|
+
await container.stop();
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Shared Container for Test Suites
|
|
67
|
+
|
|
68
|
+
For test suites with multiple test files, use the shared container to avoid starting a new container for each test:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import {
|
|
72
|
+
getSharedEventStoreDBTestContainer,
|
|
73
|
+
releaseSharedEventStoreDBTestContainer,
|
|
74
|
+
} from '@event-driven-io/emmett-testcontainers';
|
|
75
|
+
import { describe, it, after } from 'node:test';
|
|
76
|
+
|
|
77
|
+
describe('My Event Store Tests', () => {
|
|
78
|
+
after(async () => {
|
|
79
|
+
// Release the shared container after all tests
|
|
80
|
+
await releaseSharedEventStoreDBTestContainer();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should append events', async () => {
|
|
84
|
+
const container = await getSharedEventStoreDBTestContainer();
|
|
85
|
+
const client = container.getClient();
|
|
86
|
+
|
|
87
|
+
// Your test logic here
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should read events', async () => {
|
|
91
|
+
const container = await getSharedEventStoreDBTestContainer();
|
|
92
|
+
const client = container.getClient();
|
|
93
|
+
|
|
94
|
+
// Your test logic here
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## How-to Guides
|
|
100
|
+
|
|
101
|
+
### Configure Container Options
|
|
102
|
+
|
|
103
|
+
Customize the container behavior using `EventStoreDBContainerOptions`:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import {
|
|
107
|
+
EventStoreDBContainer,
|
|
108
|
+
EVENTSTOREDB_DEFAULT_IMAGE,
|
|
109
|
+
} from '@event-driven-io/emmett-testcontainers';
|
|
110
|
+
|
|
111
|
+
const container = new EventStoreDBContainer(EVENTSTOREDB_DEFAULT_IMAGE, {
|
|
112
|
+
disableProjections: false, // Enable EventStoreDB projections (default: false)
|
|
113
|
+
isSecure: false, // Run without TLS (default: false)
|
|
114
|
+
useFileStorage: true, // Persist data to disk instead of memory
|
|
115
|
+
withReuse: true, // Reuse container across test runs (Testcontainers feature)
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const started = await container.start();
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Use a Custom Docker Image
|
|
122
|
+
|
|
123
|
+
Specify a different EventStoreDB image:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { EventStoreDBContainer } from '@event-driven-io/emmett-testcontainers';
|
|
127
|
+
|
|
128
|
+
const container = new EventStoreDBContainer(
|
|
129
|
+
'eventstore/eventstore:23.10.0-bookworm-slim',
|
|
130
|
+
);
|
|
131
|
+
const started = await container.start();
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Get Connection String for External Clients
|
|
135
|
+
|
|
136
|
+
If you need to connect with your own client configuration:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const container = await new EventStoreDBContainer().start();
|
|
140
|
+
|
|
141
|
+
// Get the connection string with mapped port
|
|
142
|
+
const connectionString = container.getConnectionString();
|
|
143
|
+
// Returns: esdb://localhost:32768?tls=false (port is dynamically mapped)
|
|
144
|
+
|
|
145
|
+
// Use with your own client setup
|
|
146
|
+
import { EventStoreDBClient } from '@eventstore/db-client';
|
|
147
|
+
const client = EventStoreDBClient.connectionString(connectionString);
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Use getEventStoreDBTestClient Helper
|
|
151
|
+
|
|
152
|
+
For simple test setups with optional Testcontainers support:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { getEventStoreDBTestClient } from '@event-driven-io/emmett-testcontainers';
|
|
156
|
+
|
|
157
|
+
// Use Testcontainers
|
|
158
|
+
const client = await getEventStoreDBTestClient(true);
|
|
159
|
+
|
|
160
|
+
// Or connect to a local EventStoreDB instance (localhost:2113)
|
|
161
|
+
const localClient = await getEventStoreDBTestClient(false);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## API Reference
|
|
165
|
+
|
|
166
|
+
### Constants
|
|
167
|
+
|
|
168
|
+
| Constant | Value | Description |
|
|
169
|
+
| ------------------------------ | ------------------------- | -------------------------------------------- |
|
|
170
|
+
| `EVENTSTOREDB_PORT` | `2113` | Default EventStoreDB HTTP/gRPC port |
|
|
171
|
+
| `EVENTSTOREDB_IMAGE_NAME` | `'eventstore/eventstore'` | Docker image name |
|
|
172
|
+
| `EVENTSTOREDB_IMAGE_TAG` | `'24.10.0-bookworm-slim'` | x86 image tag |
|
|
173
|
+
| `EVENTSTOREDB_ARM64_IMAGE_TAG` | `'24.10.0-alpha-arm64v8'` | ARM64 image tag |
|
|
174
|
+
| `EVENTSTOREDB_DEFAULT_IMAGE` | Auto-detected | Full image name based on system architecture |
|
|
175
|
+
|
|
176
|
+
### EventStoreDBContainerOptions
|
|
177
|
+
|
|
178
|
+
Configuration options for the container:
|
|
179
|
+
|
|
180
|
+
| Option | Type | Default | Description |
|
|
181
|
+
| -------------------- | --------- | ------- | --------------------------------------------------- |
|
|
182
|
+
| `disableProjections` | `boolean` | `false` | When `true`, disables EventStoreDB projections |
|
|
183
|
+
| `isSecure` | `boolean` | `false` | When `true`, enables TLS security |
|
|
184
|
+
| `useFileStorage` | `boolean` | `false` | When `true`, uses file storage instead of in-memory |
|
|
185
|
+
| `withReuse` | `boolean` | `false` | When `true`, enables Testcontainers reuse feature |
|
|
186
|
+
|
|
187
|
+
### EventStoreDBContainer
|
|
188
|
+
|
|
189
|
+
Extends Testcontainers' `GenericContainer` with EventStoreDB-specific configuration.
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
class EventStoreDBContainer extends GenericContainer {
|
|
193
|
+
constructor(
|
|
194
|
+
image?: string, // Default: EVENTSTOREDB_DEFAULT_IMAGE
|
|
195
|
+
options?: EventStoreDBContainerOptions, // Default: defaultEventStoreDBContainerOptions
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
start(): Promise<StartedEventStoreDBContainer>;
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### StartedEventStoreDBContainer
|
|
203
|
+
|
|
204
|
+
A running EventStoreDB container with access methods.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
class StartedEventStoreDBContainer extends AbstractStartedContainer {
|
|
208
|
+
getConnectionString(): string; // Returns esdb:// connection string
|
|
209
|
+
getClient(): EventStoreDBClient; // Returns configured client instance
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Shared Container Functions
|
|
214
|
+
|
|
215
|
+
Thread-safe functions for sharing a single container across tests:
|
|
216
|
+
|
|
217
|
+
| Function | Description |
|
|
218
|
+
| ------------------------------------------ | ------------------------------------------------- |
|
|
219
|
+
| `getSharedEventStoreDBTestContainer()` | Gets or creates the shared container instance |
|
|
220
|
+
| `getSharedTestEventStoreDBClient()` | Gets a client from the shared container |
|
|
221
|
+
| `releaseSharedEventStoreDBTestContainer()` | Decrements usage count; stops container when zero |
|
|
222
|
+
|
|
223
|
+
### getEventStoreDBTestClient
|
|
224
|
+
|
|
225
|
+
Helper function for quick test setup:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
function getEventStoreDBTestClient(
|
|
229
|
+
useTestContainers?: boolean, // Default: false
|
|
230
|
+
): Promise<EventStoreDBClient>;
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Dependencies
|
|
234
|
+
|
|
235
|
+
| Package | Purpose |
|
|
236
|
+
| ------------------------- | ------------------------------------------------------------- |
|
|
237
|
+
| `@event-driven-io/emmett` | Provides `InProcessLock` for thread-safe container management |
|
|
238
|
+
| `testcontainers` | Docker container management and lifecycle |
|
|
239
|
+
| `@eventstore/db-client` | EventStoreDB client (peer dependency) |
|