I have a domain entity called a "Booking Window" that has a Start Date and End Date, and defines a period in which a Member can make a Booking.? The business is a mobile car wash, and Members can book a wash every 14 days.
I have a means of establishing the first Booking Window - at the point of the Member signing up.? Now I feel like the next most useful function is one that finds all Booking Windows closing "today" and makes new ones.
So I wrote a test like this (kinda pseudo coded)
test("nothing to do when no booking windows at all", async () => {
? ? const client = stubGraphQlClientContainingNothing()
? ? const clock = new FixedClock(new Date())
? ? const windows = await makeTodaysBookingWindows(client, clock)
? ? expect(windows).toHaveLength(0)
})
and my function was just
export async function makeTodaysBookingWindows(client: GraphQlClient, clock: Clock): Promise<BookingWindow[]> {
? ? return []
?
}
Then I decided I needed a test of the case that had bookings, but none ending today:
test("nothing to do when no booking windows end today", async () => {
? ? const client = stubGraphQlClientContaining(bookingWindowEnding(tomorrow()))
? ? const clock = new FixedClock(new Date())
? ? const windows = await makeTodaysBookingWindows(client, clock)
? ? expect(windows).toHaveLength(0)
?
})
and the same function implementation allowed this to pass.
Now I decided I need to do a real case, of one Booking Window ending today:
test("create a new booking window when one expires today", async () => {
? ? const client = stubGraphQlClientContaining(bookingWindowEnding(today()))
? ? const clock = new FixedClock(new Date())
? ? const windows = await makeTodaysBookingWindows(client, clock)
? ? expect(windows).toHaveLength(1)
? ? expect(window[0].startDate).toBe(today())
? ? expect(window[0].endDate).toBe(today() + 14 days)
?
})
and that forced me to make some production code.
Now I am left thinking, what next?? The code I wrote to make the above test pass does not loop, so I need to cover the case where there are many Booking Windows ending today, so I write this:
test("create a new booking window for every window ending today", async () => {
? ? const client = stubGraphQlClientContaining(bookingWindowEnding(today()), bookingWindowEnding(today()))
? ? const clock = new FixedClock(new Date())
? ? const windows = await makeTodaysBookingWindows(client, clock)
? ? expect(windows).toHaveLength(2)
? ? expect(window[0].startDate).toBe(today())
? ? expect(window[0].endDate).toBe(today() + 14 days)
? ? expect(window[1].startDate).toBe(today())
? ? expect(window[1].endDate).toBe(today() + 14 days)
?
})
Now I probably have the production function I need, but the "create a new booking window when one expires today" test case is now irrelevant, so I guess the right thing to do is remove it.
Anyway, thats enough to communicate my approach to this function.? It doesn't "feel" great, so I'd appreciate knowing how others would approach this.
Thanks!