diff --git a/typescript/ExtractAndOverrideFactoryMethod/deps.ts b/typescript/ExtractAndOverrideFactoryMethod/deps.ts new file mode 100644 index 0000000..f529cf5 --- /dev/null +++ b/typescript/ExtractAndOverrideFactoryMethod/deps.ts @@ -0,0 +1 @@ +export * as testing from 'https://deno.land/std@0.103.0/testing/asserts.ts'; diff --git a/typescript/ExtractAndOverrideFactoryMethod/index.test.ts b/typescript/ExtractAndOverrideFactoryMethod/index.test.ts new file mode 100644 index 0000000..59ba751 --- /dev/null +++ b/typescript/ExtractAndOverrideFactoryMethod/index.test.ts @@ -0,0 +1,32 @@ +import { testing } from './deps.ts'; +import { App } from './index.ts'; + +const { assertEquals } = testing; + +namespace RunTime { + export class PaymentGateway extends App.PaymentGateway { + public getLedger(): App.PaymentLedger { + return this.ledger; + } + } + + export class PaymentGatewayTest { + public regression(): void { + const paymentGateway = new RunTime.PaymentGateway(); + paymentGateway.makePayment('Me', 'You', 100, 'AUD'); + const lodgedPayment = paymentGateway.getLedger().getPayment(0); + + Deno.test('must return the payer name', (): void => { + assertEquals('Me', lodgedPayment.getPayer().getName()); + }); + Deno.test('must return the payee name', (): void => { + assertEquals('You', lodgedPayment.getPayee().getName()); + }); + Deno.test('must return the cents', (): void => { + assertEquals(100, lodgedPayment.getCents()); + }); + } + } +} + +new RunTime.PaymentGatewayTest().regression(); diff --git a/typescript/ExtractAndOverrideFactoryMethod/index.ts b/typescript/ExtractAndOverrideFactoryMethod/index.ts new file mode 100644 index 0000000..d4c0f66 --- /dev/null +++ b/typescript/ExtractAndOverrideFactoryMethod/index.ts @@ -0,0 +1,107 @@ +export namespace App { + class User { + private name: string; + + constructor(name: string) { + this.name = name; + } + + public getName() { + return this.name; + } + } + + class UserRepository { + constructor() {} + + public findByName(name: string) { + return new User(name); + } + } + + class Payment { + private payer: User; + private payee: User; + private cents: number; + + constructor(payer: User, payee: User, cents: number) { + this.payer = payer; + this.payee = payee; + this.cents = cents; + } + + public getPayer(): User { + return this.payer; + } + + public getPayee(): User { + return this.payee; + } + + public getCents(): number { + return this.cents; + } + } + + export class PaymentLedger { + private ledger: Payment[] = []; + + constructor(dBConnection: Library.DBConnection) {} + + public lodge(payment: Payment) { + this.ledger.push(payment); + } + + public getPayment(paymentNumber: number): Payment { + return this.ledger[paymentNumber]; + } + } + + export class PaymentGateway { + private dbConnection: Library.DBConnection; + private repository: UserRepository; + public ledger: PaymentLedger; + + /** + * This hard-coded initialization inside the constructor is the issue we're trying to solve + * + * @memberof PaymentGateway + */ + constructor() { + this.dbConnection = new Library.DBConnection(); + this.repository = new UserRepository(); + this.ledger = new PaymentLedger(this.dbConnection); + } + + /** + * Challenge: + * - Add a currency argument to this method with an appropriate test. + * - Do not use the UserRepository or PaymentLedger to test this class (that would + * take far too long to setup!!) + * - The currency in use before this change was AUD. + * + * @param {string} fromName + * @param {string} toName + * @param {number} cents + * @memberof PaymentGateway + */ + public makePayment(fromName: string, toName: string, cents: number): void { + const fromUser = this.repository.findByName(fromName); + const toUser = this.repository.findByName(toName); + const payment = new Payment(fromUser, toUser, cents); + this.ledger.lodge(payment); + } + } +} + +namespace Library { + export class DBConnection { + public executeCommand(query: string): void { + // ... + } + public executeQuery(query: string): any[] { + // ... + return []; + } + } +} diff --git a/typescript/README.md b/typescript/README.md new file mode 100644 index 0000000..16b59b3 --- /dev/null +++ b/typescript/README.md @@ -0,0 +1,26 @@ +# Extract And Override Factory Method + +## Install + +The only requirement needed to run the code is [Dene](https://deno.land/) + +Homebrew (Mac): + +```bash +$ brew install deno +``` + +Other options can be found at [here](https://deno.land/manual@v1.12.1/getting_started/installation) + +## Run the test + +```bash +# Run all tests in the current directory and all sub-directories +deno test + +# Run all tests in the ExtractAndOverrideFactoryMethod directory +deno test ./ExtractAndOverrideFactoryMethod/ + +# Run just my_test.ts +deno test my_test.ts +```