This repository has been archived by the owner on Apr 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add UnitTests Add Custom Errors Improve Exports and Imports
- Loading branch information
Frank
committed
Oct 27, 2019
1 parent
fa6a2a0
commit 4706af2
Showing
49 changed files
with
1,172 additions
and
766 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './aggregate'; | ||
export * from './aggregateRepository'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { Aggregate } from "../aggregate/aggregate"; | ||
import { BaseEvent } from "../event"; | ||
import { AggregateConfig } from "./aggregate"; | ||
import { createEventStore } from "../index"; | ||
import { InMemoryEventStore } from "../inMemory/eventStore"; | ||
import { Driver } from "../types"; | ||
|
||
class UserWasRegistered extends BaseEvent<{ username: string, password: string }> { | ||
static with(aggregateId, { username, password }) { | ||
return this.occur(aggregateId, { username, password }); | ||
} | ||
|
||
get userId() { | ||
return this.aggregateId; | ||
} | ||
|
||
get username() { | ||
return this.payload.username | ||
} | ||
|
||
get password() { | ||
return this.payload.password | ||
} | ||
} | ||
|
||
class UserNameWasUpdated extends BaseEvent<{ username: string }> { | ||
static with(aggregateId, { username }) { | ||
return this.occur(aggregateId, { username }); | ||
} | ||
|
||
get userId() { | ||
return this.aggregateId; | ||
} | ||
|
||
get username() { | ||
return this._payload.username | ||
} | ||
} | ||
|
||
@AggregateConfig([ | ||
UserWasRegistered, | ||
UserNameWasUpdated | ||
]) | ||
class User extends Aggregate { | ||
userId = ''; | ||
username = ''; | ||
password = ''; | ||
|
||
public static register(userId, username, password) { | ||
const user = new User(); | ||
|
||
user._recordThat(UserWasRegistered.with(userId, { username, password })) | ||
|
||
return user; | ||
} | ||
|
||
public changeUsername(username) { | ||
this._recordThat(UserNameWasUpdated.with(this.userId, { username })) | ||
|
||
return this; | ||
} | ||
|
||
protected _whenUserWasRegistered(event) { | ||
this.userId = event.userId; | ||
this.username = event.username; | ||
this.password = event.password; | ||
} | ||
|
||
protected _whenUserNameWasUpdated(event) { | ||
this.username = event.username; | ||
} | ||
} | ||
|
||
describe('decorator/aggregate', () => { | ||
it('defines all possible events to the User metadata', (done) => { | ||
expect(User.registeredEvents()).toEqual([UserWasRegistered, UserNameWasUpdated]); | ||
|
||
const eventStore = createEventStore({ | ||
driver: Driver.IN_MEMORY, | ||
connectionString: '' | ||
}) as InMemoryEventStore; | ||
|
||
expect(eventStore.eventMap).toEqual({ | ||
[User.name]: User | ||
}); | ||
|
||
done() | ||
}) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { IEventConstructor, IAggregateConstructor } from "../types"; | ||
import { AGGREGATE_CONFIG } from "./constants"; | ||
|
||
const aggregates: IAggregateConstructor[] = []; | ||
|
||
export const aggregateMap = () => aggregates; | ||
|
||
export const AggregateConfig = (events: IEventConstructor[]) => (target: IAggregateConstructor) => { | ||
Reflect.defineMetadata(AGGREGATE_CONFIG, events, target); | ||
|
||
aggregates.push(target) | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const AGGREGATE_CONFIG = 'AGGREGATE_CONFIG'; | ||
export const PROJECTION_CONFIG = 'PROJECTION_CONFIG'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './aggregate'; | ||
export * from './projection'; | ||
export * from './readModelProjection'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import { Aggregate } from "../aggregate/aggregate"; | ||
import { BaseEvent } from "../event"; | ||
import { AggregateConfig } from "./aggregate"; | ||
import { createEventStore } from "../index"; | ||
import { InMemoryEventStore } from "../inMemory/eventStore"; | ||
import { Projection } from "../projection/projection"; | ||
import { ProjectionConfig } from "./projection"; | ||
import { IProjectionConstructor } from "../projection/types"; | ||
import { Driver } from "../types"; | ||
|
||
class UserWasRegistered extends BaseEvent<{ username: string, password: string }> { | ||
static with(aggregateId, { username, password }) { | ||
return this.occur(aggregateId, { username, password }); | ||
} | ||
|
||
get userId() { | ||
return this.aggregateId; | ||
} | ||
|
||
get username() { | ||
return this.payload.username | ||
} | ||
|
||
get password() { | ||
return this.payload.password | ||
} | ||
} | ||
|
||
class UserNameWasUpdated extends BaseEvent<{ username: string }> { | ||
static with(aggregateId, { username }) { | ||
return this.occur(aggregateId, { username }); | ||
} | ||
|
||
get userId() { | ||
return this.aggregateId; | ||
} | ||
|
||
get username() { | ||
return this._payload.username | ||
} | ||
} | ||
|
||
@AggregateConfig([ | ||
UserWasRegistered, | ||
UserNameWasUpdated | ||
]) | ||
class User extends Aggregate { | ||
userId = ''; | ||
username = ''; | ||
password = ''; | ||
|
||
public static register(userId, username, password) { | ||
const user = new User(); | ||
|
||
user._recordThat(UserWasRegistered.with(userId, { username, password })) | ||
|
||
return user; | ||
} | ||
|
||
public changeUsername(username) { | ||
this._recordThat(UserNameWasUpdated.with(this.userId, { username })) | ||
|
||
return this; | ||
} | ||
|
||
protected _whenUserWasRegistered(event) { | ||
this.userId = event.userId; | ||
this.username = event.username; | ||
this.password = event.password; | ||
} | ||
|
||
protected _whenUserNameWasUpdated(event) { | ||
this.username = event.username; | ||
} | ||
} | ||
|
||
@ProjectionConfig('user_list') | ||
class UserListProjection extends Projection<{ [userId: string]: { username: string, id: string, password: string } }> { | ||
async run(keepRunning = false): Promise<Array<{ username: string, id: string, password: string }>> { | ||
await this.projector | ||
.fromStream({ streamName: 'users' }) | ||
.init(() => ({})) | ||
.when({ | ||
[UserWasRegistered.name]: (state, event: UserWasRegistered) => { | ||
state[event.userId] = { id: event.userId, username: event.username, password: event.password }; | ||
|
||
return state; | ||
}, | ||
[UserNameWasUpdated.name]: (state, event: UserNameWasUpdated) => { | ||
state[event.userId].username = event.username; | ||
|
||
return state; | ||
} | ||
}) | ||
.run(keepRunning); | ||
|
||
return Object.values(this.projector.getState() || {}); | ||
} | ||
} | ||
|
||
|
||
describe('decorator/projection', () => { | ||
it('finds decorated projections and add the defined name to the constructor', (done) => { | ||
const eventStore = createEventStore({ | ||
driver: Driver.IN_MEMORY, | ||
connectionString: '' | ||
}) as InMemoryEventStore; | ||
|
||
const projection = eventStore.getProjection<UserListProjection>('user_list'); | ||
|
||
expect(projection).not.toBeNull(); | ||
expect((projection.constructor as IProjectionConstructor).projectionName).toEqual('user_list'); | ||
|
||
done() | ||
}) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { IProjectionConstructor } from "../types"; | ||
|
||
const projections: IProjectionConstructor[] = []; | ||
|
||
export const projectionMap = () => projections; | ||
|
||
export const ProjectionConfig = (name: string) => (target: IProjectionConstructor<any>) => { | ||
target.projectionName = name; | ||
|
||
projections.push(target) | ||
}; |
Oops, something went wrong.