Skip to content

Instantly share code, notes, and snippets.

@dsci
Created July 15, 2019 18:40
Show Gist options
  • Select an option

  • Save dsci/73d3d184ad3fe33154b0fe3f1e0cddc9 to your computer and use it in GitHub Desktop.

Select an option

Save dsci/73d3d184ad3fe33154b0fe3f1e0cddc9 to your computer and use it in GitHub Desktop.

Revisions

  1. dsci created this gist Jul 15, 2019.
    103 changes: 103 additions & 0 deletions duck.spec.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,103 @@
    import { expect } from 'chai';
    import 'mocha';

    import {
    FlyWithWings,
    FlyNoWay,
    Quack,
    MuteQuack,
    Duck,
    DuckWithAlternativeConstructor
    } from './duck';

    describe('Duck Behaviours', () => {

    describe('Fly behaviour', () => {
    it('should fly', () => {
    const duckBehaviour = new FlyWithWings();
    expect(duckBehaviour.fly()).to.eq("I can fly");
    });
    });

    describe('Quack behaviour', () => {
    it('should quack', () => {
    const duckBehaviour = new Quack();
    expect(duckBehaviour.quack()).to.eq("Quack");
    });
    })

    describe('No fly behaviour', () => {
    it('should not fly', () => {
    const duckBehaviour = new FlyNoWay();
    expect(duckBehaviour.fly()).to.eq("I can't fly");
    });
    });

    describe('No quack behaviour', () => {
    it('should not quack', () => {
    const duckBehaviour = new MuteQuack();
    expect(duckBehaviour.quack()).to.eq("-silence-");
    });
    });

    });

    describe('A duck that is', () => {
    const newBornDuck = new Duck();
    describe('a newly born duck', ()=> {

    it("can't fly", () => {
    expect(newBornDuck.performFly()).to.eq("I can't fly");
    });

    it("can't quack", () => {
    expect(newBornDuck.performQuack()).to.eq("-silence-");
    })
    });

    describe('A grownn duck', ()=> {
    const grownDuck = new Duck();

    before(()=> {
    grownDuck.quackBehaviour = new Quack();
    grownDuck.flyBehaviour = new FlyWithWings();
    });

    it("can fly", () => {
    expect(grownDuck.performFly()).to.eq("I can fly");
    });

    it("can quack", () => {
    expect(grownDuck.performQuack()).to.eq("Quack");
    });
    });

    describe('A grown duck who got the strategies passed in the constructor', ()=> {
    const grownDuck = new Duck(new FlyWithWings(),
    new Quack())

    it("can fly", () => {
    expect(grownDuck.performFly()).to.eq("I can fly");
    });

    it("can quack", () => {
    expect(grownDuck.performQuack()).to.eq("Quack");
    })
    });

    describe('An old duck who got the strategies passed in the constructor', ()=> {
    const duckBehaviour = {
    quackBehaviour: new Quack()
    };
    const grownDuck = new DuckWithAlternativeConstructor(duckBehaviour);

    it("can't fly", () => {
    expect(grownDuck.performFly()).to.eq("I can't fly");
    });

    it("can quack", () => {
    expect(grownDuck.performQuack()).to.eq("Quack");
    })
    });
    });

    80 changes: 80 additions & 0 deletions duck.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@
    interface IFlyBehaviour {
    fly(): string
    }

    interface IQuackBehaviour {
    quack(): string
    }

    interface IDuck {
    performFly(): string;
    performQuack(): string;
    }

    export class FlyWithWings implements IFlyBehaviour {
    public fly(): string {
    return 'I can fly';
    }
    }

    export class FlyNoWay implements IFlyBehaviour {
    public fly(): string {
    return "I can't fly";
    }
    }

    export class Quack implements IQuackBehaviour {
    public quack(): string {
    return "Quack";
    }
    }

    export class MuteQuack implements IQuackBehaviour {
    public quack(): string {
    return "-silence-";
    }
    }

    export class Duck implements IDuck{
    constructor(private _flyBehaviour: IFlyBehaviour = new FlyNoWay(),
    private _quackBehaviour: IQuackBehaviour = new MuteQuack()) {
    }

    public performFly(): string {
    return this._flyBehaviour.fly();
    }

    public performQuack(): string {
    return this._quackBehaviour.quack();
    }

    public set quackBehaviour(behaviour: IQuackBehaviour) {
    this._quackBehaviour = behaviour;
    }

    public set flyBehaviour(behaviour: IFlyBehaviour) {
    this._flyBehaviour = behaviour;
    }
    }

    interface IDuckBehaviour {
    quackBehaviour?: IQuackBehaviour
    flyBehaviour?: IFlyBehaviour
    }

    export class DuckWithAlternativeConstructor implements IDuck {

    public flyBehaviour: IFlyBehaviour = new FlyNoWay();
    public quackBehaviour: IQuackBehaviour = new MuteQuack();

    constructor(behaviour?: IDuckBehaviour) {
    if (behaviour) Object.assign(this, behaviour);
    }
    public performFly(): string {
    return this.flyBehaviour.fly();
    }

    public performQuack(): string {
    return this.quackBehaviour.quack();
    }
    }