Skip to content

Instantly share code, notes, and snippets.

@marijn
Last active June 28, 2016 21:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marijn/3b1199047cd551c222b21a338e751c45 to your computer and use it in GitHub Desktop.
Save marijn/3b1199047cd551c222b21a338e751c45 to your computer and use it in GitHub Desktop.
Attempt to build a projection of arriving guests based on the events from the Projections Explained workshop.
const GuestBookedAppointment = "GuestBookedAppointment";
const GuestRescheduledAppointment = "GuestRescheduledAppointment";
const GuestSwappedAppointmentForFeelgoodPackage = "GuestSwappedAppointmentForFeelgoodPackage";
const GuestCanceledAppointment = "GuestCanceledAppointment";
const SubsidiaryCanceledAppointment = "SubsidiaryCanceledAppointment";
class GuestsArriving {
constructor(day, subsidiary, arrivals) {
this.day = day;
this.subsidiary = subsidiary;
this.arrivals = arrivals;
}
equals(anotherGuestsArrivingModel) {
return anotherGuestsArrivingModel instanceof GuestsArriving
&& this.day == anotherGuestsArrivingModel.day
&& this.subsidiary == anotherGuestsArrivingModel.subsidiary
&& this.arrivals.equals(anotherGuestsArrivingModel.arrivals);
}
withAdditionalArrival(scheduledArrival) {
this.arrivals.arrivals.push(scheduledArrival);
return this;
}
}
class Arrivals {
constructor(arrivals) {
this.arrivals = arrivals;
}
equals(anotherListOfArrivals) {
return anotherListOfArrivals instanceof Arrivals
&& anotherListOfArrivals.arrivals.length == this.arrivals.length
&& this.containsSameArrivalsAs(anotherListOfArrivals);
}
containsSameArrivalsAs(anotherListOfArrivals) {
let containsSameArrivals = true;
for (let i = 0, numberOfArrivals = this.arrivals.length; i < numberOfArrivals && containsSameArrivals; i++) {
containsSameArrivals = this.arrivals[i].equals(anotherListOfArrivals.arrivals[i]);
}
return containsSameArrivals;
}
}
class ScheduledArrival {
constructor(guest, expectedTimeOfArrival, hasBeenCanceledBySubsidiary) {
this.guest = guest;
this.expectedTimeOfArrival = expectedTimeOfArrival;
this.hasBeenCanceledBySubsidiary = hasBeenCanceledBySubsidiary;
}
equals(anotherArrival) {
return anotherArrival instanceof ScheduledArrival
&& this.guest == anotherArrival.guest
&& this.expectedTimeOfArrival == anotherArrival.expectedTimeOfArrival
&& this.hasBeenCanceledBySubsidiary == anotherArrival.hasBeenCanceledBySubsidiary;
}
}
class GuestsArrivingProjector {
static generateKey(day, idOfSubsidiary) {
return `${day}#${idOfSubsidiary}`;
}
constructor() {
this.records = {};
}
projectAll(events) {
events.forEach((event) => {
switch (event.message) {
case GuestBookedAppointment:
this.whenGuestBookedAppointment(event);
break;
default:
// intentionally ignore
}
});
}
totalCount() {
return Object.keys(this.records).length;
}
ofDayAndSubsidiary(day, idOfSubsidiary) {
var key = GuestsArrivingProjector.generateKey(day, idOfSubsidiary);
// TODO: SorryNoRecordCouldBeFound
return this.records[key];
}
whenGuestBookedAppointment(anEvent) {
let key = GuestsArrivingProjector.generateKey(anEvent.dateOfAppointment, anEvent.subsidiaryId);
let record = this.ofDayAndSubsidiary(anEvent.dateOfAppointment, anEvent.subsidiaryId);
if (record) {
this.records[key] = record.withAdditionalArrival(new ScheduledArrival(anEvent.guestId, anEvent.timeOfAppointment, false));
} else {
this.records[key] = new GuestsArriving(
anEvent.dateOfAppointment,
anEvent.subsidiaryId,
new Arrivals([new ScheduledArrival(anEvent.guestId, anEvent.timeOfAppointment, false)])
);
}
return this.records[key];
}
}
function testEqualityOfGuestsArriving () {
assertThat(
new GuestsArriving('2016-12-06', 'bonaficio', new Arrivals([])).equals(new GuestsArriving('2016-12-06', 'bonaficio', new Arrivals([])))
);
}
function testEqualityOfArrivals () {
assertThat(
new Arrivals([]).equals(new Arrivals([]))
);
}
function testEqualityOfScheduledArrival () {
assertThat(
new ScheduledArrival('Arne', '12:15', false).equals(new ScheduledArrival('Arne', '12:15', false))
);
}
function testProjectionOfGuestBookedAppointment() {
let projector = new GuestsArrivingProjector();
let given = [
{
message: GuestBookedAppointment,
appointmentId: 123,
guestId: 456,
dateOfAppointment: "2016-12-06",
timeOfAppointment: "20:30",
feelgoodPackageId: 789,
subsidiaryId: 1
}
];
projector.projectAll(given);
assertThat(projector.totalCount() == 1);
assertThat(projector.ofDayAndSubsidiary('2016-12-06', 1).equals(new GuestsArriving("2016-12-06", 1, new Arrivals([new ScheduledArrival(456, '20:30', false)]))));
let additionalGiven = [
{
message: GuestBookedAppointment,
appointmentId: 123123,
guestId: 456456,
dateOfAppointment: "2016-12-06",
timeOfAppointment: "18:30",
feelgoodPackageId: 789789,
subsidiaryId: 1
}
];
projector.projectAll(additionalGiven);
assertThat(projector.totalCount() == 1);
assertThat(projector.ofDayAndSubsidiary('2016-12-06', 1).equals(new GuestsArriving("2016-12-06", 1, new Arrivals([new ScheduledArrival(456, '20:30', false), new ScheduledArrival(456456, '18:30', false)]))));
}
function testAll() {
testEqualityOfGuestsArriving();
testEqualityOfArrivals();
testEqualityOfScheduledArrival();
testProjectionOfGuestBookedAppointment();
}
function assertThat(aCondition) {
return aCondition
? console.log(aCondition)
: console.error(aCondition);
}
testAll();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment