Mock functions

Loading "Mock Functions"
We have an Emitter implementation that can add listeners to events and call those listeners whenever a matching event is emitted. This behavior is achieved by implementing two core methods on the emitter: .on() and .emit():
/**
 * Add listener for the given event.
 *
 * @example
 * const emitter = new Emitter<{ foo: [number] }>()
 * emitter.on('foo', (data) => console.log(data))
 */
public on<Event extends keyof EventMap>(
  event: Event,
  listener: (...args: EventMap[Event]) => void,
): this {
  const prevListeners = this.listeners.get(event) || []
  const nextListeners = prevListeners.concat(listener)
  this.listeners.set(event, nextListeners)
  return this
}
/**
 * Emit an event. This invokes all the listeners
 * assigned for that event.
 * @return {boolean} True if the emitted event has listeners.
 *
 * @example
 * const emitter = new Emitter<{ foo: [number] }>()
 * emitter.emit('foo', 123)
 */
public emit<Event extends keyof EventMap>(
  event: Event,
  ...data: EventMap[Event]
): boolean {
  const listeners = this.listeners.get(event) || []
  for (const listener of listeners) {
    listener.apply(this, data)
  }
  return listeners.length > 0
}
Here's how this emitter is used in our application:
// The owner of the emitter describes which events it can handle.
// This keeps the communication type-safe!
const emitter = new Emitter<{ login: [User] }>()

// The consumers then attach listeners to events...
emitter.on('login', (user) => {})

// ...and emit events when needed.
emitter.emit('login', currentUser)
We have a single intention behind the Emitter class:
When event X is emitted, call all the listeners for that event.
One of the ways to write such a test is to make the event listener perform a side effect and assert on the result of that side effect.
const emitter = new Emitter<{ hello: [string]}>()
let isListenerCalled = false

emitter.on('hello', (firstName) => {
  isListenerCalled = true
})
emitter.emit('hello', 'John')

expect(isListenerCalled).toBe(true)
If the value of the isListenerCalled variable changes to true, we assume that the hello event listener has been called.
It may seem like we are covering the intention here but in reality, we are not. All we are testing here is that isListenerCalled becomes true at some point. The test will pass even if the initial value for the variable is set to true by mistake, and fail if we forget to update it even if the listener has indeed been called correctly.
In other words, in this test, we are testing what the listener does, not if it gets called. The fact of it getting called becomes an implicit assertion. Such assertions are tremendously useful but the main intention we are testing must always be clear and explicit.
πŸ‘¨β€πŸ’Ό Your task in this exercise is to write a proper test for the listener being called, using the vi.fn() utility from Vitest. Verify your solution by running npm test.