UNPKG

@hexadrop/command

Version:

Hexagonal architecture utils library

189 lines (149 loc) 4.82 kB
import Either from '@hexadrop/either'; import DomainError from '@hexadrop/error'; import { beforeEach, describe, expect, test } from 'bun:test'; import type { CommandBusCallback, CommandHandler } from './bus'; import Command from './command'; import { CommandNotRegisteredError } from './error'; import InMemoryCommandHandlers from './in-memory.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'); } } class Command5 extends Command { static override COMMAND_NAME = 'Command5'; constructor() { super(Command5.COMMAND_NAME, 'id'); } } class Command6 extends Command { static override COMMAND_NAME = 'Command6'; constructor() { super(Command6.COMMAND_NAME, 'id'); } } class Service { async hello(): Promise<string> { return await Promise.resolve('world'); } } class Command1Handler implements CommandHandler<Command1> { constructor(private readonly service: Service) {} async run(): Promise<Either<DomainError, void>> { await this.service.hello(); return Either.right(); } } class Command23Handler implements CommandHandler<Command2 | Command3> { run(): Either<DomainError, void> { return Either.right(); } } class Command4Handler implements CommandHandler<Command4> { constructor(private readonly service: Service) {} async run(): Promise<Either<DomainError, void>> { await this.service.hello(); return Either.right(); } } describe('InMemoryCommandHandlers', () => { let c1: Command; let c2: Command; let c3: Command; let c4: Command; let c5: Command; let c6: Command; let svc: Service; let expectedCommand1Handler: CommandHandler; let expectedCommand23Handler: CommandHandler; let expectedCommand4Handler: CommandHandler; let expectedCommand56Handler: CommandBusCallback; let info: InMemoryCommandHandlers; beforeEach(() => { c1 = new Command1(); c2 = new Command2(); c3 = new Command3(); c4 = new Command4(); c5 = new Command5(); c6 = new Command6(); svc = new Service(); expectedCommand1Handler = new Command1Handler(svc); expectedCommand23Handler = new Command23Handler(); expectedCommand4Handler = new Command4Handler(svc); expectedCommand56Handler = function expectedCommand56Handler(): Either<DomainError, void> { return Either.right(); }; info = new InMemoryCommandHandlers(); info.register(Command1, expectedCommand1Handler); info.register(Command2, expectedCommand23Handler); info.register(Command3, expectedCommand23Handler); }); 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(); expect(h4).toBe(h3); }); 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` ); }); }); describe('register()', () => { test('should register a non previous registered command handler', () => { info.register(Command4, expectedCommand4Handler); info.register(Command5, expectedCommand56Handler); info.register(Command6, expectedCommand56Handler); const h4 = info.search(c4); expect(h4).toBeDefined(); const h5 = info.search(c5); expect(h5).toBeDefined(); expect(h5).toStrictEqual(expectedCommand56Handler); const h6 = info.search(c6); expect(h6).toBeDefined(); expect(h6).toStrictEqual(expectedCommand56Handler); }); test('should register a previous registered command handler', () => { info.register(Command1, expectedCommand4Handler); const h4 = info.search(c1); expect(h4).toBeDefined(); }); }); describe('unregister()', () => { test('should unregister a previous registered command handler', () => { const h3 = info.search(c3); expect(h3).toBeDefined(); info.unregister(Command3); expect(() => info.search(c3)).toThrow(new CommandNotRegisteredError(Command3.COMMAND_NAME)); }); }); });