@event-driven-io/emmett-testcontainers 0.43.0-beta.12 → 0.43.0-beta.14

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 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) |