@woltz/rich-domain 0.2.2 → 1.1.0
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/CHANGELOG.md +23 -75
- package/LICENSE +20 -20
- package/README.md +37 -20
- package/dist/base-entity.d.ts +2 -2
- package/dist/base-entity.d.ts.map +1 -1
- package/dist/base-entity.js +6 -4
- package/dist/base-entity.js.map +1 -1
- package/dist/criteria.d.ts +5 -11
- package/dist/criteria.d.ts.map +1 -1
- package/dist/criteria.js +4 -3
- package/dist/criteria.js.map +1 -1
- package/dist/deep-proxy.d.ts +3 -1
- package/dist/deep-proxy.d.ts.map +1 -1
- package/dist/deep-proxy.js +116 -29
- package/dist/deep-proxy.js.map +1 -1
- package/dist/domain-event-bus.d.ts +5 -6
- package/dist/domain-event-bus.d.ts.map +1 -1
- package/dist/domain-event-bus.js +3 -11
- package/dist/domain-event-bus.js.map +1 -1
- package/dist/domain-event.d.ts +1 -31
- package/dist/domain-event.d.ts.map +1 -1
- package/dist/domain-event.js +2 -1
- package/dist/domain-event.js.map +1 -1
- package/dist/entity.d.ts +2 -2
- package/dist/entity.js +1 -1
- package/dist/exceptions.d.ts +251 -0
- package/dist/exceptions.d.ts.map +1 -0
- package/dist/exceptions.js +321 -0
- package/dist/exceptions.js.map +1 -0
- package/dist/id.d.ts +3 -3
- package/dist/id.d.ts.map +1 -1
- package/dist/id.js +15 -4
- package/dist/id.js.map +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -8
- package/dist/index.js.map +1 -1
- package/dist/paginated-result.d.ts.map +1 -1
- package/dist/paginated-result.js +12 -1
- package/dist/paginated-result.js.map +1 -1
- package/dist/repository/index.d.ts +2 -39
- package/dist/repository/index.d.ts.map +1 -1
- package/dist/repository/index.js +2 -39
- package/dist/repository/index.js.map +1 -1
- package/dist/repository/unit-of-work.d.ts +0 -11
- package/dist/repository/unit-of-work.d.ts.map +1 -1
- package/dist/repository/unit-of-work.js +0 -35
- package/dist/repository/unit-of-work.js.map +1 -1
- package/dist/types/criteria.d.ts +6 -2
- package/dist/types/criteria.d.ts.map +1 -1
- package/dist/types/criteria.js +1 -1
- package/dist/types/criteria.js.map +1 -1
- package/dist/types/domain-event.d.ts +32 -0
- package/dist/types/domain-event.d.ts.map +1 -0
- package/dist/types/domain-event.js +2 -0
- package/dist/types/domain-event.js.map +1 -0
- package/dist/types/domain.d.ts +2 -2
- package/dist/types/domain.d.ts.map +1 -1
- package/dist/types/history-tracker.d.ts +1 -1
- package/dist/types/history-tracker.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/value-object.d.ts +1 -1
- package/dist/value-object.d.ts.map +1 -1
- package/dist/value-object.js +2 -5
- package/dist/value-object.js.map +1 -1
- package/eslint.config.js +3 -3
- package/jest.config.js +1 -1
- package/package.json +14 -20
- package/src/base-entity.ts +6 -5
- package/src/criteria.ts +11 -11
- package/src/deep-proxy.ts +447 -339
- package/src/domain-event-bus.ts +152 -166
- package/src/domain-event.ts +53 -90
- package/src/entity.ts +16 -16
- package/src/exceptions.ts +435 -0
- package/src/id.ts +107 -94
- package/src/index.ts +26 -9
- package/src/paginated-result.ts +14 -1
- package/src/repository/index.ts +2 -44
- package/src/repository/unit-of-work.ts +1 -44
- package/src/types/criteria.ts +7 -2
- package/src/types/domain-event.ts +38 -0
- package/src/types/domain.ts +2 -3
- package/src/types/history-tracker.ts +1 -1
- package/src/types/index.ts +1 -0
- package/src/validation-error.ts +97 -97
- package/src/value-object.ts +3 -6
- package/tests/criteria.test.ts +8 -0
- package/tests/domain-events.test.ts +431 -445
- package/tests/entity-validation.test.ts +2 -2
- package/tests/entity.test.ts +33 -33
- package/tests/history-tracker.spec.ts +57 -17
- package/tests/id.test.ts +341 -341
- package/tests/repository.test.ts +8 -4
- package/tests/to-json.test.ts +103 -91
- package/tests/utils.ts +254 -151
- package/tests/value-object-validation.test.ts +0 -9
- package/tests/value-objects.test.ts +52 -52
- package/tsconfig.json +2 -24
- package/.github/workflows/ci.yml +0 -40
- package/.husky/commit-msg +0 -1
- package/.husky/pre-commit +0 -1
- package/.vscode/settings.json +0 -3
- package/commitlint.config.js +0 -23
- package/dist/filtering.d.ts +0 -107
- package/dist/filtering.d.ts.map +0 -1
- package/dist/filtering.js +0 -202
- package/dist/filtering.js.map +0 -1
- package/dist/ordering.d.ts +0 -93
- package/dist/ordering.d.ts.map +0 -1
- package/dist/ordering.js +0 -154
- package/dist/ordering.js.map +0 -1
- package/dist/pagination.d.ts +0 -218
- package/dist/pagination.d.ts.map +0 -1
- package/dist/pagination.js +0 -281
- package/dist/pagination.js.map +0 -1
- package/dist/repository/in-memory-repository.d.ts +0 -50
- package/dist/repository/in-memory-repository.d.ts.map +0 -1
- package/dist/repository/in-memory-repository.js +0 -93
- package/dist/repository/in-memory-repository.js.map +0 -1
- package/dist/repository/mapper.d.ts +0 -56
- package/dist/repository/mapper.d.ts.map +0 -1
- package/dist/repository/mapper.js +0 -15
- package/dist/repository/mapper.js.map +0 -1
- package/dist/repository/types.d.ts +0 -87
- package/dist/repository/types.d.ts.map +0 -1
- package/dist/repository/types.js +0 -6
- package/dist/repository/types.js.map +0 -1
- package/dist/repository.d.ts +0 -2
- package/dist/repository.d.ts.map +0 -1
- package/dist/repository.js +0 -21
- package/dist/repository.js.map +0 -1
- package/dist/specification.d.ts +0 -102
- package/dist/specification.d.ts.map +0 -1
- package/dist/specification.js +0 -187
- package/dist/specification.js.map +0 -1
- package/dist/types/repository.d.ts +0 -43
- package/dist/types/repository.d.ts.map +0 -1
- package/dist/types/repository.js +0 -2
- package/dist/types/repository.js.map +0 -1
- package/dist/types.d.ts +0 -88
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -12
- package/dist/types.js.map +0 -1
- package/src/repository/in-memory-repository.ts +0 -116
package/tests/id.test.ts
CHANGED
|
@@ -1,341 +1,341 @@
|
|
|
1
|
-
import { Id } from
|
|
2
|
-
import { Address, Post, User } from
|
|
3
|
-
|
|
4
|
-
// ============================================================================
|
|
5
|
-
// Id Class Tests
|
|
6
|
-
// ============================================================================
|
|
7
|
-
|
|
8
|
-
describe(
|
|
9
|
-
describe(
|
|
10
|
-
it(
|
|
11
|
-
const id = new Id();
|
|
12
|
-
|
|
13
|
-
expect(id.value).toBeDefined();
|
|
14
|
-
expect(typeof id.value).toBe(
|
|
15
|
-
expect(id.value.length).toBeGreaterThan(0);
|
|
16
|
-
// UUID v4 format check
|
|
17
|
-
expect(id.value).toMatch(
|
|
18
|
-
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
|
|
19
|
-
);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it(
|
|
23
|
-
const id = new Id();
|
|
24
|
-
|
|
25
|
-
expect(id.isNew).toBe(true);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it(
|
|
29
|
-
const existingId =
|
|
30
|
-
const id = new Id(existingId);
|
|
31
|
-
|
|
32
|
-
expect(id.value).toBe(existingId);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it(
|
|
36
|
-
const id = new Id(
|
|
37
|
-
|
|
38
|
-
expect(id.isNew).toBe(false);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it(
|
|
42
|
-
const id1 = new Id();
|
|
43
|
-
const id2 = new Id();
|
|
44
|
-
const id3 = new Id();
|
|
45
|
-
|
|
46
|
-
expect(id1.value).not.toBe(id2.value);
|
|
47
|
-
expect(id2.value).not.toBe(id3.value);
|
|
48
|
-
expect(id1.value).not.toBe(id3.value);
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe(
|
|
53
|
-
it(
|
|
54
|
-
const id = Id.create();
|
|
55
|
-
|
|
56
|
-
expect(id.isNew).toBe(true);
|
|
57
|
-
expect(id.value).toBeDefined();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it(
|
|
61
|
-
const id = Id.from(
|
|
62
|
-
|
|
63
|
-
expect(id.isNew).toBe(false);
|
|
64
|
-
expect(id.value).toBe(
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describe(
|
|
69
|
-
it(
|
|
70
|
-
const id = new Id(
|
|
71
|
-
|
|
72
|
-
expect(id.toString()).toBe(
|
|
73
|
-
expect(String(id)).toBe(
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it(
|
|
77
|
-
const id = new Id(
|
|
78
|
-
|
|
79
|
-
expect(id.toJSON()).toBe(
|
|
80
|
-
expect(JSON.stringify(id)).toBe('"test-id"');
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
describe(
|
|
85
|
-
it(
|
|
86
|
-
const id1 = new Id(
|
|
87
|
-
const id2 = new Id(
|
|
88
|
-
const id3 = new Id(
|
|
89
|
-
|
|
90
|
-
expect(id1.equals(id2)).toBe(true);
|
|
91
|
-
expect(id1.equals(id3)).toBe(false);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it(
|
|
95
|
-
const id = new Id(
|
|
96
|
-
|
|
97
|
-
expect(id.equals(
|
|
98
|
-
expect(id.equals(
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// ============================================================================
|
|
104
|
-
// Entity with Id Tests
|
|
105
|
-
// ============================================================================
|
|
106
|
-
|
|
107
|
-
describe(
|
|
108
|
-
describe(
|
|
109
|
-
it(
|
|
110
|
-
const post = new Post({
|
|
111
|
-
id: new Id(), // No value = new
|
|
112
|
-
title:
|
|
113
|
-
content:
|
|
114
|
-
likes: 0,
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
expect(post.isNew).toBe(true);
|
|
118
|
-
expect(post.id.isNew).toBe(true);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it(
|
|
122
|
-
const post1 = new Post({
|
|
123
|
-
id: new Id(),
|
|
124
|
-
title:
|
|
125
|
-
content:
|
|
126
|
-
likes: 0,
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
const post2 = new Post({
|
|
130
|
-
id: new Id(),
|
|
131
|
-
title:
|
|
132
|
-
content:
|
|
133
|
-
likes: 0,
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
expect(post1.id.value).not.toBe(post2.id.value);
|
|
137
|
-
expect(post1.isNew).toBe(true);
|
|
138
|
-
expect(post2.isNew).toBe(true);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it(
|
|
142
|
-
const post = new Post({
|
|
143
|
-
id: Id.create(),
|
|
144
|
-
title:
|
|
145
|
-
content:
|
|
146
|
-
likes: 0,
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
expect(post.isNew).toBe(true);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
describe(
|
|
154
|
-
it(
|
|
155
|
-
const post = new Post({
|
|
156
|
-
id: new Id(
|
|
157
|
-
title:
|
|
158
|
-
content:
|
|
159
|
-
likes: 10,
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
expect(post.isNew).toBe(false);
|
|
163
|
-
expect(post.id.isNew).toBe(false);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it(
|
|
167
|
-
const post = new Post({
|
|
168
|
-
id: Id.from(
|
|
169
|
-
title:
|
|
170
|
-
content:
|
|
171
|
-
likes: 10,
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
expect(post.isNew).toBe(false);
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
describe(
|
|
179
|
-
it(
|
|
180
|
-
const post = new Post({
|
|
181
|
-
id: new Id(
|
|
182
|
-
title:
|
|
183
|
-
content:
|
|
184
|
-
likes: 5,
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
const json = post.toJson();
|
|
188
|
-
|
|
189
|
-
expect(json.id).toBe(
|
|
190
|
-
expect(typeof json.id).toBe(
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
describe(
|
|
195
|
-
it(
|
|
196
|
-
const user = new User({
|
|
197
|
-
id: new Id(
|
|
198
|
-
name:
|
|
199
|
-
email:
|
|
200
|
-
posts: [],
|
|
201
|
-
address: new Address({
|
|
202
|
-
street:
|
|
203
|
-
city:
|
|
204
|
-
zipCode:
|
|
205
|
-
}),
|
|
206
|
-
comments: [],
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
user.subscribe({
|
|
210
|
-
posts: {
|
|
211
|
-
onChange: ({ toCreate, toDelete }) => {
|
|
212
|
-
expect(toCreate).toHaveLength(2);
|
|
213
|
-
expect(toDelete).toHaveLength(0);
|
|
214
|
-
done();
|
|
215
|
-
},
|
|
216
|
-
},
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
user.addManyPosts([
|
|
220
|
-
new Post({
|
|
221
|
-
id: new Id(),
|
|
222
|
-
title:
|
|
223
|
-
content:
|
|
224
|
-
likes: 0,
|
|
225
|
-
}),
|
|
226
|
-
new Post({
|
|
227
|
-
id: new Id(),
|
|
228
|
-
title:
|
|
229
|
-
content:
|
|
230
|
-
likes: 0,
|
|
231
|
-
}),
|
|
232
|
-
]);
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
it(
|
|
236
|
-
const postId = new Id(
|
|
237
|
-
|
|
238
|
-
const user = new User({
|
|
239
|
-
id: new Id(
|
|
240
|
-
name:
|
|
241
|
-
email:
|
|
242
|
-
posts: [
|
|
243
|
-
new Post({
|
|
244
|
-
id: postId,
|
|
245
|
-
title:
|
|
246
|
-
content:
|
|
247
|
-
likes: 0,
|
|
248
|
-
}),
|
|
249
|
-
],
|
|
250
|
-
address: new Address({
|
|
251
|
-
street:
|
|
252
|
-
city:
|
|
253
|
-
zipCode:
|
|
254
|
-
}),
|
|
255
|
-
comments: [],
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
user.subscribe({
|
|
259
|
-
posts: {
|
|
260
|
-
onChange: ({ toCreate, toDelete }) => {
|
|
261
|
-
expect(toCreate).toHaveLength(0);
|
|
262
|
-
expect(toDelete).toHaveLength(1);
|
|
263
|
-
expect(toDelete[0].id.value).toBe(postId.value);
|
|
264
|
-
done();
|
|
265
|
-
},
|
|
266
|
-
},
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
user.removePostById(postId.value);
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
// ============================================================================
|
|
275
|
-
// Aggregate with Id Tests
|
|
276
|
-
// ============================================================================
|
|
277
|
-
|
|
278
|
-
describe(
|
|
279
|
-
it(
|
|
280
|
-
const user = new User({
|
|
281
|
-
id: new Id(),
|
|
282
|
-
name:
|
|
283
|
-
email:
|
|
284
|
-
posts: [],
|
|
285
|
-
address: new Address({
|
|
286
|
-
street:
|
|
287
|
-
city:
|
|
288
|
-
zipCode:
|
|
289
|
-
}),
|
|
290
|
-
comments: [],
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
expect(user.isNew).toBe(true);
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
it(
|
|
297
|
-
const user = new User({
|
|
298
|
-
id: new Id(
|
|
299
|
-
name:
|
|
300
|
-
email:
|
|
301
|
-
posts: [],
|
|
302
|
-
address: new Address({
|
|
303
|
-
street:
|
|
304
|
-
city:
|
|
305
|
-
zipCode:
|
|
306
|
-
}),
|
|
307
|
-
comments: [],
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
expect(user.isNew).toBe(false);
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
it(
|
|
314
|
-
const user = new User({
|
|
315
|
-
id: new Id(
|
|
316
|
-
name:
|
|
317
|
-
email:
|
|
318
|
-
posts: [
|
|
319
|
-
new Post({
|
|
320
|
-
id: new Id(
|
|
321
|
-
title:
|
|
322
|
-
content:
|
|
323
|
-
likes: 0,
|
|
324
|
-
}),
|
|
325
|
-
],
|
|
326
|
-
comments: [],
|
|
327
|
-
address: new Address({
|
|
328
|
-
street:
|
|
329
|
-
city:
|
|
330
|
-
zipCode:
|
|
331
|
-
}),
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
const json = user.toJson();
|
|
335
|
-
|
|
336
|
-
expect(json.id).toBe(
|
|
337
|
-
expect(json.posts[0].id).toBe(
|
|
338
|
-
expect(typeof json.id).toBe(
|
|
339
|
-
expect(typeof json.posts[0].id).toBe(
|
|
340
|
-
});
|
|
341
|
-
});
|
|
1
|
+
import { Id } from "../src";
|
|
2
|
+
import { Address, Post, User } from "./utils";
|
|
3
|
+
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// Id Class Tests
|
|
6
|
+
// ============================================================================
|
|
7
|
+
|
|
8
|
+
describe("Id Class", () => {
|
|
9
|
+
describe("Construction", () => {
|
|
10
|
+
it("should generate UUID when no value provided", () => {
|
|
11
|
+
const id = new Id();
|
|
12
|
+
|
|
13
|
+
expect(id.value).toBeDefined();
|
|
14
|
+
expect(typeof id.value).toBe("string");
|
|
15
|
+
expect(id.value.length).toBeGreaterThan(0);
|
|
16
|
+
// UUID v4 format check
|
|
17
|
+
expect(id.value).toMatch(
|
|
18
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should mark as new when no value provided", () => {
|
|
23
|
+
const id = new Id();
|
|
24
|
+
|
|
25
|
+
expect(id.isNew()).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should use provided value", () => {
|
|
29
|
+
const existingId = "550e8400-e29b-41d4-a716-446655440000";
|
|
30
|
+
const id = new Id(existingId);
|
|
31
|
+
|
|
32
|
+
expect(id.value).toBe(existingId);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should mark as NOT new when value provided", () => {
|
|
36
|
+
const id = new Id("existing-id");
|
|
37
|
+
|
|
38
|
+
expect(id.isNew()).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should generate unique IDs", () => {
|
|
42
|
+
const id1 = new Id();
|
|
43
|
+
const id2 = new Id();
|
|
44
|
+
const id3 = new Id();
|
|
45
|
+
|
|
46
|
+
expect(id1.value).not.toBe(id2.value);
|
|
47
|
+
expect(id2.value).not.toBe(id3.value);
|
|
48
|
+
expect(id1.value).not.toBe(id3.value);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe("Static Methods", () => {
|
|
53
|
+
it("should create new Id with Id.create()", () => {
|
|
54
|
+
const id = Id.create();
|
|
55
|
+
|
|
56
|
+
expect(id.isNew()).toBe(true);
|
|
57
|
+
expect(id.value).toBeDefined();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should create existing Id with Id.from()", () => {
|
|
61
|
+
const id = Id.from("existing-id");
|
|
62
|
+
|
|
63
|
+
expect(id.isNew()).toBe(false);
|
|
64
|
+
expect(id.value).toBe("existing-id");
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe("String Conversion", () => {
|
|
69
|
+
it("should convert to string with toString()", () => {
|
|
70
|
+
const id = new Id("test-id");
|
|
71
|
+
|
|
72
|
+
expect(id.toString()).toBe("test-id");
|
|
73
|
+
expect(String(id)).toBe("test-id");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("should convert to JSON", () => {
|
|
77
|
+
const id = new Id("test-id");
|
|
78
|
+
|
|
79
|
+
expect(id.toJSON()).toBe("test-id");
|
|
80
|
+
expect(JSON.stringify(id)).toBe('"test-id"');
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe("Equality", () => {
|
|
85
|
+
it("should compare with another Id", () => {
|
|
86
|
+
const id1 = new Id("same-id");
|
|
87
|
+
const id2 = new Id("same-id");
|
|
88
|
+
const id3 = new Id("different-id");
|
|
89
|
+
|
|
90
|
+
expect(id1.equals(id2)).toBe(true);
|
|
91
|
+
expect(id1.equals(id3)).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("should compare with string", () => {
|
|
95
|
+
const id = new Id("test-id");
|
|
96
|
+
|
|
97
|
+
expect(id.equals("test-id")).toBe(true);
|
|
98
|
+
expect(id.equals("other-id")).toBe(false);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// ============================================================================
|
|
104
|
+
// Entity with Id Tests
|
|
105
|
+
// ============================================================================
|
|
106
|
+
|
|
107
|
+
describe("Entity with Id Class", () => {
|
|
108
|
+
describe("New Entity", () => {
|
|
109
|
+
it("should be new when Id is auto-generated", () => {
|
|
110
|
+
const post = new Post({
|
|
111
|
+
id: new Id(), // No value = new
|
|
112
|
+
title: "New Post",
|
|
113
|
+
content: "Content",
|
|
114
|
+
likes: 0,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
expect(post.isNew()).toBe(true);
|
|
118
|
+
expect(post.id.isNew()).toBe(true);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("should auto-generate unique IDs", () => {
|
|
122
|
+
const post1 = new Post({
|
|
123
|
+
id: new Id(),
|
|
124
|
+
title: "Post 1",
|
|
125
|
+
content: "Content",
|
|
126
|
+
likes: 0,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const post2 = new Post({
|
|
130
|
+
id: new Id(),
|
|
131
|
+
title: "Post 2",
|
|
132
|
+
content: "Content",
|
|
133
|
+
likes: 0,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
expect(post1.id.value).not.toBe(post2.id.value);
|
|
137
|
+
expect(post1.isNew()).toBe(true);
|
|
138
|
+
expect(post2.isNew()).toBe(true);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("should work with Id.create()", () => {
|
|
142
|
+
const post = new Post({
|
|
143
|
+
id: Id.create(),
|
|
144
|
+
title: "New Post",
|
|
145
|
+
content: "Content",
|
|
146
|
+
likes: 0,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
expect(post.isNew()).toBe(true);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe("Existing Entity", () => {
|
|
154
|
+
it("should NOT be new when Id value is provided", () => {
|
|
155
|
+
const post = new Post({
|
|
156
|
+
id: new Id("existing-post-id"), // Value provided = not new
|
|
157
|
+
title: "Existing Post",
|
|
158
|
+
content: "Content",
|
|
159
|
+
likes: 10,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
expect(post.isNew()).toBe(false);
|
|
163
|
+
expect(post.id.isNew()).toBe(false);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("should work with Id.from()", () => {
|
|
167
|
+
const post = new Post({
|
|
168
|
+
id: Id.from("existing-post-id"),
|
|
169
|
+
title: "Existing Post",
|
|
170
|
+
content: "Content",
|
|
171
|
+
likes: 10,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
expect(post.isNew()).toBe(false);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
describe("toJson()", () => {
|
|
179
|
+
it("should serialize Id to string", () => {
|
|
180
|
+
const post = new Post({
|
|
181
|
+
id: new Id("post-123"),
|
|
182
|
+
title: "Test Post",
|
|
183
|
+
content: "Content",
|
|
184
|
+
likes: 5,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
const json = post.toJson();
|
|
188
|
+
|
|
189
|
+
expect(json.id).toBe("post-123");
|
|
190
|
+
expect(typeof json.id).toBe("string");
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
describe("Id Comparison in Arrays", () => {
|
|
195
|
+
it("should detect changes in arrays using Id", (done) => {
|
|
196
|
+
const user = new User({
|
|
197
|
+
id: new Id("user-1"),
|
|
198
|
+
name: "John",
|
|
199
|
+
email: "john@example.com",
|
|
200
|
+
posts: [],
|
|
201
|
+
address: new Address({
|
|
202
|
+
street: "Main St",
|
|
203
|
+
city: "NYC",
|
|
204
|
+
zipCode: "10001",
|
|
205
|
+
}),
|
|
206
|
+
comments: [],
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
user.subscribe({
|
|
210
|
+
posts: {
|
|
211
|
+
onChange: ({ toCreate, toDelete }) => {
|
|
212
|
+
expect(toCreate).toHaveLength(2);
|
|
213
|
+
expect(toDelete).toHaveLength(0);
|
|
214
|
+
done();
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
user.addManyPosts([
|
|
220
|
+
new Post({
|
|
221
|
+
id: new Id(),
|
|
222
|
+
title: "Post 1",
|
|
223
|
+
content: "Content 1",
|
|
224
|
+
likes: 0,
|
|
225
|
+
}),
|
|
226
|
+
new Post({
|
|
227
|
+
id: new Id(),
|
|
228
|
+
title: "Post 2",
|
|
229
|
+
content: "Content 2",
|
|
230
|
+
likes: 0,
|
|
231
|
+
}),
|
|
232
|
+
]);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it("should track deletes correctly with Id", (done) => {
|
|
236
|
+
const postId = new Id("post-to-delete");
|
|
237
|
+
|
|
238
|
+
const user = new User({
|
|
239
|
+
id: new Id("user-1"),
|
|
240
|
+
name: "John",
|
|
241
|
+
email: "john@example.com",
|
|
242
|
+
posts: [
|
|
243
|
+
new Post({
|
|
244
|
+
id: postId,
|
|
245
|
+
title: "Post 1",
|
|
246
|
+
content: "Content 1",
|
|
247
|
+
likes: 0,
|
|
248
|
+
}),
|
|
249
|
+
],
|
|
250
|
+
address: new Address({
|
|
251
|
+
street: "Main St",
|
|
252
|
+
city: "NYC",
|
|
253
|
+
zipCode: "10001",
|
|
254
|
+
}),
|
|
255
|
+
comments: [],
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
user.subscribe({
|
|
259
|
+
posts: {
|
|
260
|
+
onChange: ({ toCreate, toDelete }) => {
|
|
261
|
+
expect(toCreate).toHaveLength(0);
|
|
262
|
+
expect(toDelete).toHaveLength(1);
|
|
263
|
+
expect(toDelete[0].id.value).toBe(postId.value);
|
|
264
|
+
done();
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
user.removePostById(postId.value);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
// ============================================================================
|
|
275
|
+
// Aggregate with Id Tests
|
|
276
|
+
// ============================================================================
|
|
277
|
+
|
|
278
|
+
describe("Aggregate with Id Class", () => {
|
|
279
|
+
it("should be new when Id is auto-generated", () => {
|
|
280
|
+
const user = new User({
|
|
281
|
+
id: new Id(),
|
|
282
|
+
name: "John",
|
|
283
|
+
email: "john@example.com",
|
|
284
|
+
posts: [],
|
|
285
|
+
address: new Address({
|
|
286
|
+
street: "Main St",
|
|
287
|
+
city: "NYC",
|
|
288
|
+
zipCode: "10001",
|
|
289
|
+
}),
|
|
290
|
+
comments: [],
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
expect(user.isNew()).toBe(true);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it("should NOT be new when Id value is provided", () => {
|
|
297
|
+
const user = new User({
|
|
298
|
+
id: new Id("existing-user"),
|
|
299
|
+
name: "John",
|
|
300
|
+
email: "john@example.com",
|
|
301
|
+
posts: [],
|
|
302
|
+
address: new Address({
|
|
303
|
+
street: "Main St",
|
|
304
|
+
city: "NYC",
|
|
305
|
+
zipCode: "10001",
|
|
306
|
+
}),
|
|
307
|
+
comments: [],
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
expect(user.isNew()).toBe(false);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("should serialize Id in nested entities", () => {
|
|
314
|
+
const user = new User({
|
|
315
|
+
id: new Id("user-1"),
|
|
316
|
+
name: "John",
|
|
317
|
+
email: "john@example.com",
|
|
318
|
+
posts: [
|
|
319
|
+
new Post({
|
|
320
|
+
id: new Id("post-1"),
|
|
321
|
+
title: "Post 1",
|
|
322
|
+
content: "Content",
|
|
323
|
+
likes: 0,
|
|
324
|
+
}),
|
|
325
|
+
],
|
|
326
|
+
comments: [],
|
|
327
|
+
address: new Address({
|
|
328
|
+
street: "Main St",
|
|
329
|
+
city: "NYC",
|
|
330
|
+
zipCode: "10001",
|
|
331
|
+
}),
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
const json = user.toJson();
|
|
335
|
+
|
|
336
|
+
expect(json.id).toBe("user-1");
|
|
337
|
+
expect(json.posts[0].id).toBe("post-1");
|
|
338
|
+
expect(typeof json.id).toBe("string");
|
|
339
|
+
expect(typeof json.posts[0].id).toBe("string");
|
|
340
|
+
});
|
|
341
|
+
});
|