Message History
Everything your code sends to the mock bus is recorded. MessageHistory is the engine behind world.then, and it’s available directly for custom checks or debugging.
Access it through the world:
What gets recorded
The mock bus logs four kinds of interactions:
Action | Method on bus | What appears in history |
|---|---|---|
Fire generic message |
| The message instance |
Fire callback |
| The callback message instance and the result |
Execute an executor |
| The executor instance |
Subscribe |
| Increment of the subscription counter for that type |
Subscriptions are stored as simple counters, not as a list of observer objects.
Messages, callbacks, and executors are stored in collections grouped by their class (the constructor used as key).
API overview
history.messages(type)
Returns a HistoryCollection<T> containing all messages of the given type. type is the constructor function of a PostboyGenericMessage, PostboyCallbackMessage, or PostboyExecutor.
The returned collection provides lazy views — you can inspect it multiple times, and it will reflect any new messages that were added after your first call.
history.subs(type)
Returns the total number of subscriptions (sub and once combined) made to the given message type.
history.reset()
Clears all recorded messages and subscription counters.
Normally you don’t need to call this manually — world.dispose() triggers it for you.
Only use reset() if you want to start a fresh recording within the same test.
HistoryCollection<T> in detail
HistoryCollection<T> is the container for all messages of a single type.
It exposes a familiar array‑like interface plus a few predicate helpers.
Properties
first— the earliest message sent, ornullif empty.last— the most recent message sent, ornullif empty.all— a defensive shallow copy of all messages. Modifying the returned array does not affect the real history.length— how many messages are currently stored.
Predicate checks
has(predicate: (item: T) => boolean): boolean
Returns true if at least one message satisfies the predicate.
hasItem(item: T): boolean
Checks for the presence of an exact object reference.
Modifying the collection
add(item: T): void
Manually append a message to the collection. Rarely needed; mostly used internally by the mock bus.
clear(): void
Remove all messages of this type only, leaving other types untouched.
Again, usually unnecessary because world.dispose() resets the whole history.
Typical use cases for direct history access
world.then covers most common assertions, but sometimes you need the raw data.
Verify exact order of multiple messages
const all = world.history.messages(MyEvent).all; should().string(all[0].step).equal('start'); should().string(all[1].step).equal('finish');Check properties of a specific message
const third = world.history.messages(MyEvent).all[2]; should().number(third.payload.id).equals(expectedId);Combine history with custom logic
const successful = world.history.messages(MyEvent).all.filter(e => e.ok); should().array(successful).length(3);Inspect subscription counts
should().number(world.history.subs(MyEvent)).greaterOrEqual(1);
Internal structure
Each message type gets its own HistoryCollection, created on first access. Subscription counters are stored separately.
Cleanup: don’t forget dispose()
world.dispose() calls history.reset() internally, clearing everything. Manual calls to reset() or clear() are safe but rarely needed in a well‑structured test suite that follows beforeEach/afterEach.
Now you have the full picture of how history works. Combine it with then and waiter for flexible, precise test assertions.