UNPKG

@hexadrop/command

Version:

Hexagonal architecture utils library

86 lines (77 loc) 3.36 kB
import Either from '@hexadrop/either'; import DomainError from '@hexadrop/error'; import { expect, jest } from 'bun:test'; import type CommandBus from './bus'; import type Command from './command'; /** * @class BunMockCommandBus * @implements CommandBus * @description Class representing a mock command bus for testing in Bun. */ export default class BunMockCommandBus implements CommandBus { /** * @property {Mock} dispatchSpy - A mock function for the dispatch method. */ readonly dispatchSpy = jest.fn((..._commands: Command[]) => Promise.resolve(Either.right<DomainError>())); /** * This is a private static method that extracts data from a command. * It omits the 'commandId' property from the command object and returns the remaining properties. * If no command is provided, it returns an empty object. * * @template CommandType - A type that extends the Command interface. * @param {CommandType} command - The command object from which to extract data. This is optional. * @returns {Omit<CommandType, 'commandId'> | {}} - An object that contains the properties of the command object, excluding 'commandId'. If no command is provided, an empty object is returned. */ private static getDataFromCommand<CommandType extends Command>( command?: CommandType ): Omit<CommandType, 'commandId'> | Record<string, never> { if (!command) { return {}; } const { commandId: _c, ...attributes } = command; return attributes; } /** * @method assertDispatchedCommands * @description Method to assert that specific commands were dispatched. * @param {...Command[]} expectedCommands - The expected dispatched commands. */ assertDispatchedCommands(...expectedCommands: Command[]): void { expect(this.dispatchSpy).toHaveBeenCalled(); const commandsArray = this.dispatchSpy.mock.calls.flat(); expect(commandsArray.length).toEqual(expectedCommands.length); expect(commandsArray.map(command => BunMockCommandBus.getDataFromCommand(command))).toStrictEqual( expectedCommands.map(command => BunMockCommandBus.getDataFromCommand(command)) ); } /** * @method assertLastDispatchedCommand * @description Method to assert that a specific command was the last one dispatched. * @param {Command} expectedCommand - The expected last dispatched command. */ assertLastDispatchedCommand(expectedCommand: Command): void { expect(this.dispatchSpy).toHaveBeenCalled(); const commandsArray = this.dispatchSpy.mock.calls.at(-1) ?? []; const command = commandsArray[0]; expect(command).toBeDefined(); expect(BunMockCommandBus.getDataFromCommand(command)).toStrictEqual( BunMockCommandBus.getDataFromCommand(expectedCommand) ); } /** * @method assertNotDispatchedCommand * @description Method to assert that no command was dispatched. */ assertNotDispatchedCommand(): void { expect(this.dispatchSpy).not.toHaveBeenCalled(); } /** * @method dispatch * @description Method to dispatch a command. * @param {Command} command - The command to be dispatched. * @returns {Either<DomainError, void> | Promise<Either<DomainError, void>>} - The result of the command dispatch. */ dispatch(command: Command): Either<DomainError, void> | Promise<Either<DomainError, void>> { return this.dispatchSpy(command) as Either<DomainError, void> | Promise<Either<DomainError, void>>; } }