UNPKG

@hexadrop/command

Version:

Hexagonal architecture utils library

119 lines (93 loc) 2.88 kB
import '@abraham/reflection'; import Either from '@hexadrop/either'; import DomainError from '@hexadrop/error'; import { beforeEach, describe, expect, test } from 'bun:test'; import { ContainerBuilder, Service as ServiceDecorator } from 'diod'; import type { CommandHandler } from './bus'; import Command from './command'; import CommandHandlerDecorator from './decorator'; import { CommandNotRegisteredError } from './error'; import IoCCommandHandlers from './ioc.command-handlers'; class Command1 extends Command { static override COMMAND_NAME = 'Command1'; constructor() { super(Command1.COMMAND_NAME, 'id'); } } class Command2 extends Command { static override COMMAND_NAME = 'Command2'; constructor() { super(Command2.COMMAND_NAME, 'id'); } } class Command3 extends Command { static override COMMAND_NAME = 'Command3'; constructor() { super(Command3.COMMAND_NAME, 'id'); } } class Command4 extends Command { static override COMMAND_NAME = 'Command4'; constructor() { super(Command4.COMMAND_NAME, 'id'); } } @ServiceDecorator() class Service { async hello(): Promise<string> { return await Promise.resolve('world'); } } @CommandHandlerDecorator(Command1) class Command1Handler implements CommandHandler<Command1> { constructor(private readonly service: Service) {} async run(): Promise<Either<DomainError, void>> { await this.service.hello(); return Either.right(); } } @CommandHandlerDecorator(Command2, Command3) class Command23Handler implements CommandHandler<Command2 | Command3> { run(): Either<DomainError, void> { return Either.right(); } } describe('IoCCommandHandlers', () => { let c1: Command; let c2: Command; let c3: Command; let c4: Command; let info: IoCCommandHandlers; beforeEach(() => { c1 = new Command1(); c2 = new Command2(); c3 = new Command3(); c4 = new Command4(); const builder = new ContainerBuilder(); builder.registerAndUse(Service); builder.registerAndUse(Command1Handler); builder.registerAndUse(Command23Handler); const container = builder.build(); info = new IoCCommandHandlers(container); }); describe('search()', () => { test('should return a registered command handler', () => { const h1 = info.search(c1); expect(h1).toBeDefined(); const h2 = info.search(c2); expect(h2).toBeDefined(); const h3 = info.search(c3); expect(h3).toBeDefined(); const h4 = info.search(Command3); expect(h4).toBeDefined(); }); test('should throw and error if command handler is not registered', () => { const expectedError = new CommandNotRegisteredError(Command4.COMMAND_NAME); expect(() => info.search(c4)).toThrow(expectedError); expect(() => info.search(Command4)).toThrow(expectedError); expect(expectedError.message).toBe( `The command '${Command4.COMMAND_NAME}' hasn't a command handler associated` ); }); }); });