From f617b94fad0d36027516a74efa8b32dbbc1ef776 Mon Sep 17 00:00:00 2001 From: Sam Hatoum Date: Wed, 13 May 2020 21:07:22 -0400 Subject: [PATCH] refactor: renames branches and collections to files and filetrees --- .github/workflows/workflow.yml | 7 ++-- src/domain/branch/Branch.spec.ts | 28 --------------- src/domain/branch/BranchCommandHandlers.ts | 19 ----------- src/domain/file/File.spec.ts | 28 +++++++++++++++ src/domain/{branch/Branch.ts => file/File.ts} | 12 +++---- src/domain/file/FileCommandHandlers.ts | 19 +++++++++++ .../FileCommands.ts} | 4 +-- .../BranchEvents.ts => file/FileEvents.ts} | 4 +-- src/es-cqrs/GivenWhenThen.ts | 14 ++++---- src/projections/Collection.spec.ts | 30 ---------------- src/projections/Collection.ts | 17 ---------- src/projections/FileTree.spec.ts | 34 +++++++++++++++++++ src/projections/FileTree.ts | 17 ++++++++++ 13 files changed, 119 insertions(+), 114 deletions(-) delete mode 100644 src/domain/branch/Branch.spec.ts delete mode 100644 src/domain/branch/BranchCommandHandlers.ts create mode 100644 src/domain/file/File.spec.ts rename src/domain/{branch/Branch.ts => file/File.ts} (58%) create mode 100644 src/domain/file/FileCommandHandlers.ts rename src/domain/{branch/BranchCommands.ts => file/FileCommands.ts} (77%) rename src/domain/{branch/BranchEvents.ts => file/FileEvents.ts} (77%) delete mode 100644 src/projections/Collection.spec.ts delete mode 100644 src/projections/Collection.ts create mode 100644 src/projections/FileTree.spec.ts create mode 100644 src/projections/FileTree.ts diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 5e48a14..ae8c92a 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -14,10 +14,9 @@ jobs: with: coverageLocations: | ${{github.workspace}}/coverage/jest/lcov.info:lcov - ${{github.workspace}}/coverage/cucumber/lcov.info:lcov debug: true - - name: Release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +# - name: Release +# env: +# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # NPM_TOKEN: ${{ secrets.NPM_TOKEN }} # run: npx semantic-release diff --git a/src/domain/branch/Branch.spec.ts b/src/domain/branch/Branch.spec.ts deleted file mode 100644 index f2f6e58..0000000 --- a/src/domain/branch/Branch.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {GivenWhenThen} from '../../es-cqrs/GivenWhenThen' -import {guid} from '../../es-cqrs/Guid' -import {Branch} from './Branch' -import {RenameBranch} from './BranchCommands' -import {BranchCreated, BranchRenamed} from './BranchEvents' -import {MissingParameterError} from '../../es-cqrs/Errors' - -const GWT = GivenWhenThen(Branch, __dirname) - -test('Rename branch', () => - GWT((Given, When, Then) => { - const branchId = guid() - - Given(new BranchCreated(branchId, 'foo')) - When(new RenameBranch(branchId, 'bar', 1)) - Then(new BranchRenamed(branchId, 'bar')) - })) - -test('Rename branch fail', () => - GWT((Given, When, Then) => { - const branchId = guid() - - Given(new BranchCreated(branchId, 'foo')) - When(new RenameBranch(branchId, '', 1)) - expect((): void => { - Then(new BranchRenamed(branchId, 'bar')) - }).toThrow(MissingParameterError) - })) diff --git a/src/domain/branch/BranchCommandHandlers.ts b/src/domain/branch/BranchCommandHandlers.ts deleted file mode 100644 index a509584..0000000 --- a/src/domain/branch/BranchCommandHandlers.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {IRepository} from '../../es-cqrs/Repository' -import {Branch} from './Branch' -import {CreateBranch, RenameBranch} from './BranchCommands' -import {guid} from '../../es-cqrs/Guid' - -export class BranchCommandHandlers { - constructor(private _repository: IRepository) {} - - handleCreateBranch(command: CreateBranch): void { - const branch = new Branch(guid(), command.name) - this._repository.save(branch, -1) - } - - handleRenameBranch(command: RenameBranch): void { - const branch = this._repository.getById(command.aggregateId) - branch.rename(command.name) - this._repository.save(branch, command.expectedAggregateVersion) - } -} diff --git a/src/domain/file/File.spec.ts b/src/domain/file/File.spec.ts new file mode 100644 index 0000000..23067b4 --- /dev/null +++ b/src/domain/file/File.spec.ts @@ -0,0 +1,28 @@ +import {GivenWhenThen} from '../../es-cqrs/GivenWhenThen' +import {guid} from '../../es-cqrs/Guid' +import {File} from './File' +import {RenameFile} from './FileCommands' +import {FileCreated, FileRenamed} from './FileEvents' +import {MissingParameterError} from '../../es-cqrs/Errors' + +const GWT = GivenWhenThen(`${__dirname}/File`) + +test('Rename file', () => + GWT((Given, When, Then) => { + const fileId = guid() + + Given(new FileCreated(fileId, 'foo')) + When(new RenameFile(fileId, 'bar', 1)) + Then(new FileRenamed(fileId, 'bar')) + })) + +test('Rename file fail', () => + GWT((Given, When, Then) => { + const fileId = guid() + + Given(new FileCreated(fileId, 'foo')) + When(new RenameFile(fileId, '', 1)) + expect((): void => { + Then(new FileRenamed(fileId, 'bar')) + }).toThrow(MissingParameterError) + })) diff --git a/src/domain/branch/Branch.ts b/src/domain/file/File.ts similarity index 58% rename from src/domain/branch/Branch.ts rename to src/domain/file/File.ts index 0d0ea84..b6801cf 100644 --- a/src/domain/branch/Branch.ts +++ b/src/domain/file/File.ts @@ -1,27 +1,27 @@ import {AggregateRoot} from '../../es-cqrs/AggregateRoot' -import {BranchCreated, BranchRenamed} from './BranchEvents' +import {FileCreated, FileRenamed} from './FileEvents' import {MissingParameterError} from '../../es-cqrs/Errors' -export class Branch extends AggregateRoot { +export class File extends AggregateRoot { private name: string constructor(guid: string, name: string) { super() - this.applyChange(new BranchCreated(guid, name)) + this.applyChange(new FileCreated(guid, name)) } - applyBranchCreated(event: BranchCreated): void { + applyFileCreated(event: FileCreated): void { this._id = event.aggregateId this.name = event.name } - applyBranchRenamed(event: BranchRenamed): void { + applyFileRenamed(event: FileRenamed): void { this._id = event.aggregateId this.name = event.name } rename(name: string): void { if (!name) throw new MissingParameterError('Must provide a name') - this.applyChange(new BranchRenamed(this._id, name)) + this.applyChange(new FileRenamed(this._id, name)) } } diff --git a/src/domain/file/FileCommandHandlers.ts b/src/domain/file/FileCommandHandlers.ts new file mode 100644 index 0000000..d990823 --- /dev/null +++ b/src/domain/file/FileCommandHandlers.ts @@ -0,0 +1,19 @@ +import {IRepository} from '../../es-cqrs/Repository' +import {File} from './File' +import {CreateFile, RenameFile} from './FileCommands' +import {guid} from '../../es-cqrs/Guid' + +export class FileCommandHandlers { + constructor(private _repository: IRepository) {} + + handleCreateFile(command: CreateFile): void { + const file = new File(guid(), command.name) + this._repository.save(file, -1) + } + + handleRenameFile(command: RenameFile): void { + const file = this._repository.getById(command.aggregateId) + file.rename(command.name) + this._repository.save(file, command.expectedAggregateVersion) + } +} diff --git a/src/domain/branch/BranchCommands.ts b/src/domain/file/FileCommands.ts similarity index 77% rename from src/domain/branch/BranchCommands.ts rename to src/domain/file/FileCommands.ts index 0a9ed04..1ba051c 100644 --- a/src/domain/branch/BranchCommands.ts +++ b/src/domain/file/FileCommands.ts @@ -1,12 +1,12 @@ import {Command} from '../../es-cqrs/Command' -export class CreateBranch extends Command { +export class CreateFile extends Command { constructor(public readonly name: string) { super(-1) } } -export class RenameBranch extends Command { +export class RenameFile extends Command { constructor( public readonly aggregateId: string, public readonly name: string, diff --git a/src/domain/branch/BranchEvents.ts b/src/domain/file/FileEvents.ts similarity index 77% rename from src/domain/branch/BranchEvents.ts rename to src/domain/file/FileEvents.ts index d819bbc..d252271 100644 --- a/src/domain/branch/BranchEvents.ts +++ b/src/domain/file/FileEvents.ts @@ -1,6 +1,6 @@ import {Event} from '../../es-cqrs/Event' -export class BranchCreated extends Event { +export class FileCreated extends Event { constructor( public readonly aggregateId: string, public readonly name: string @@ -9,7 +9,7 @@ export class BranchCreated extends Event { } } -export class BranchRenamed extends Event { +export class FileRenamed extends Event { constructor( public readonly aggregateId: string, public readonly name: string diff --git a/src/es-cqrs/GivenWhenThen.ts b/src/es-cqrs/GivenWhenThen.ts index 91361a5..c95fdd6 100644 --- a/src/es-cqrs/GivenWhenThen.ts +++ b/src/es-cqrs/GivenWhenThen.ts @@ -5,21 +5,23 @@ import {MessageBus} from './MessageBus' import {EventStore} from './EventStore' import {Repository} from './Repository' -export function GivenWhenThen(aggregate: T, dirname: string): Function { - console.log(dirname) +export function GivenWhenThen(aggregatePath: string): Function { return (cb: Function): Function => { + const dir = aggregatePath.substring(0, aggregatePath.lastIndexOf('/')) // eslint-disable-next-line @typescript-eslint/no-explicit-any function req(moduleName, extract = false): any { if (extract) // eslint-disable-next-line global-require,import/no-dynamic-require - return require(`${dirname}/${moduleName}`)[`${moduleName}`] + return require(`${dir}/${moduleName}`)[`${moduleName}`] // eslint-disable-next-line global-require,import/no-dynamic-require - return require(`${dirname}/${moduleName}`) + return require(`${dir}/${moduleName}`) } // eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore - const aggregateName = aggregate.name + const aggregateName = aggregatePath.substring( + aggregatePath.lastIndexOf('/') + 1 + ) const Aggregate = req(aggregateName, true) const AggregateCommandHandlers = req( @@ -27,7 +29,7 @@ export function GivenWhenThen(aggregate: T, dirname: string): Function { true ) // eslint-disable-next-line @typescript-eslint/no-var-requires,global-require,import/no-dynamic-require - const AggregateCommands = require(`${dirname}/${aggregateName}Commands`) + const AggregateCommands = require(`${dir}/${aggregateName}Commands`) const messageBus = new MessageBus() const eventStore = new EventStore(messageBus) diff --git a/src/projections/Collection.spec.ts b/src/projections/Collection.spec.ts deleted file mode 100644 index 4a1f23b..0000000 --- a/src/projections/Collection.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {GivenWhenThen} from '../es-cqrs/GivenWhenThen' -import {Branch} from '../domain/branch/Branch' -import {BranchCreated, BranchRenamed} from '../domain/branch/BranchEvents' -import {Collection} from './Collection' - -const GWT = GivenWhenThen(Branch, `${__dirname}/../domain/branch`) - -test('Collection Projection', () => - GWT((Given, When, Then, messageBus) => { - const collection = new Collection(messageBus) - - Given(new BranchCreated('1234', 'foo'), new BranchCreated('5678', 'bar')) - - expect(collection.branches['1234'].name).toEqual('foo') - expect(collection.branches['5678'].name).toEqual('bar') - })) - -test('Collection Projection', () => - GWT((Given, When, Then, messageBus) => { - const collection = new Collection(messageBus) - - Given( - new BranchCreated('1234', 'foo'), - new BranchCreated('5678', 'bar'), - new BranchRenamed('5678', 'baz') - ) - - expect(collection.branches['1234'].name).toEqual('foo') - expect(collection.branches['5678'].name).toEqual('baz') - })) diff --git a/src/projections/Collection.ts b/src/projections/Collection.ts deleted file mode 100644 index 4f6b91f..0000000 --- a/src/projections/Collection.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {IMessageBus} from '../es-cqrs/IMessageBus' -import {BranchCreated, BranchRenamed} from '../domain/branch/BranchEvents' - -export class Collection { - public branches = {} - - constructor(private messageBus: IMessageBus) { - messageBus.registerEventHandler(BranchCreated, (e) => { - const event = e as BranchCreated - this.branches[event.aggregateId] = event - }) - messageBus.registerEventHandler(BranchRenamed, (e) => { - const event = e as BranchRenamed - this.branches[event.aggregateId].name = event.name - }) - } -} diff --git a/src/projections/FileTree.spec.ts b/src/projections/FileTree.spec.ts new file mode 100644 index 0000000..888ab23 --- /dev/null +++ b/src/projections/FileTree.spec.ts @@ -0,0 +1,34 @@ +import {GivenWhenThen} from '../es-cqrs/GivenWhenThen' +import {FileCreated, FileRenamed} from '../domain/file/FileEvents' +import {FileTree} from './FileTree' + +const GWT = GivenWhenThen(`${__dirname}/../domain/file/File`) + +test('FileTree Projection', () => + GWT((Given, When, Then, messageBus) => { + const fileTree = new FileTree(messageBus) + + Given( + new FileCreated('1234', 'foo'), + new FileCreated('2345', 'bar'), + new FileCreated('3456', 'baz') + ) + + expect(fileTree.files['1234'].name).toEqual('foo') + expect(fileTree.files['2345'].name).toEqual('bar') + expect(fileTree.files['3456'].name).toEqual('baz') + })) + +test('FileTree Projection', () => + GWT((Given, When, Then, messageBus) => { + const fileTree = new FileTree(messageBus) + + Given( + new FileCreated('1234', 'foo'), + new FileCreated('5678', 'bar'), + new FileRenamed('5678', 'baz') + ) + + expect(fileTree.files['1234'].name).toEqual('foo') + expect(fileTree.files['5678'].name).toEqual('baz') + })) diff --git a/src/projections/FileTree.ts b/src/projections/FileTree.ts new file mode 100644 index 0000000..32e7e52 --- /dev/null +++ b/src/projections/FileTree.ts @@ -0,0 +1,17 @@ +import {IMessageBus} from '../es-cqrs/IMessageBus' +import {FileCreated, FileRenamed} from '../domain/file/FileEvents' + +export class FileTree { + public files = {} + + constructor(private messageBus: IMessageBus) { + messageBus.registerEventHandler(FileCreated, (e) => { + const event = e as FileCreated + this.files[event.aggregateId] = event + }) + messageBus.registerEventHandler(FileRenamed, (e) => { + const event = e as FileRenamed + this.files[event.aggregateId].name = event.name + }) + } +}