/* tslint:disable:no-unused-variable */ /* tslint:disable:no-unused-expression */ /* tslint:disable:max-classes-per-file */ /* tslint:disable:prefer-function-over-method */ import { expect } from 'chai'; import { suite, test } from 'mocha-typescript'; import { HistoryDemo } from '../../demo/design-patterns/history'; import { _enablePropertyHistory, _onceDisablePropertyHistory, _propertyHistory, HistoryMember, PropertyHistory, PropertyHistoryEntry } from '../../src/design-patterns/history'; @suite class HistoryTest { @test public 'add history entry'(): void { let ph = new PropertyHistory(); expect(ph.entries).to.be.not.undefined; expect(ph.entries).has.length(0); expect(ph.currentPos).to.be.equal(-1); ph.add(new PropertyHistoryEntry('name', 'test')); expect(ph.currentPos).to.be.equal(0); expect(ph.entries).has.length(1); expect(ph.entries[ 0 ]).is.instanceof(PropertyHistoryEntry); ph.add(new PropertyHistoryEntry('name', 'test2')); ph.add(new PropertyHistoryEntry('name', 'test3')); expect(ph.currentPos).to.be.equal(2); expect(ph.entries).has.length(3); ph.previous(); ph.add(new PropertyHistoryEntry('name', 'test4')); expect(ph.hasNext()).to.be.false; expect(ph.currentPos).to.be.equal(2); expect(ph.entries).has.length(3); } @test public 'clean all history entries'(): void { let ph = new PropertyHistory(); ph.add(new PropertyHistoryEntry('name', 'test')); ph.add(new PropertyHistoryEntry('name', 'test2')); expect(ph.entries).has.length(2); ph.clean(); expect(ph.entries).has.length(0); } @test public 'get previous history entry'(): void { const ph = new PropertyHistory(); expect(ph.hasPrevious()).to.be.false; expect(() => ph.previous()).to.throw('Cannot get previous history entry. There is not any entry in the history!'); ph.add(new PropertyHistoryEntry('name', 'test')); expect(ph.hasPrevious()).to.be.true; ph.add(new PropertyHistoryEntry('name', 'test2')); expect(ph.currentPos).to.be.equal(1); const previous = ph.previous(); expect(previous).to.be.not.undefined; expect(previous).to.be.instanceof(PropertyHistoryEntry); expect(ph.currentPos).to.be.equal(0); expect(ph.entries).has.length(2); expect(ph.hasPrevious()).to.be.true; expect(previous.value).to.be.equal('test'); expect(previous.memberName).to.be.equal('name'); ph.previous(); expect(ph.currentPos).to.be.equal(-1); expect(ph.entries).has.length(2); expect(ph.hasPrevious()).to.be.false; expect(() => ph.previous()).to.be.throw('Cannot get previous history entry. Current pos is less or equal then 0!'); } @test public 'get next history entry'(): void { const ph = new PropertyHistory(); expect(ph.hasNext()).to.be.false; expect(() => ph.next()).to.throw('Cannot get next history entry. There is not any entry in the history!'); ph.add(new PropertyHistoryEntry('name', 'test')); expect(ph.hasNext()).to.be.false; expect(() => ph.next()).to.be.throw('Cannot get next history entry. ' + 'Current pos is equals then max pos of the history entry array!'); ph.add(new PropertyHistoryEntry('name', 'test2')); expect(ph.hasNext()).to.be.false; ph.previous(); expect(ph.currentPos).to.be.equal(0); expect(ph.hasNext()).to.be.true; const next = ph.next(); expect(next).to.be.not.undefined; expect(next).to.be.instanceof(PropertyHistoryEntry); expect(ph.currentPos).to.be.equal(1); expect(ph.entries).has.length(2); expect(ph.hasNext()).to.be.false; expect(() => ph.next()).to.be.throw('Cannot get next history entry. ' + 'Current pos is equals then max pos of the history entry array!'); expect(next.value).to.be.equal('test2'); expect(next.memberName).to.be.equal('name'); } @test public 'constrcution test'(): void { const historyObj = new HistoryDemo(); expect(historyObj).is.instanceof(HistoryDemo); expect(historyObj).has.ownProperty(_propertyHistory); expect(historyObj).has.ownProperty(_enablePropertyHistory); expect(historyObj).has.ownProperty(_onceDisablePropertyHistory); expect(historyObj[ _propertyHistory ]).is.instanceof(PropertyHistory); } @test public 'one undo'(): void { const history = new HistoryDemo(); expect(history.member).to.be.undefined; history.member = 'init'; expect(history.member).to.be.equal('init', 'normal set'); history.member = 'post-init'; expect(history.member).to.be.equal('post-init', 'normal set'); history.undo(); expect(history.member).to.be.equal('init', 'undo once'); } @test public 'one redo'(): void { const history = new HistoryDemo(); expect(history.member).to.be.undefined; history.member = 'init'; expect(history.member).to.be.equal('init', 'normal set'); history.member = 'post-init'; expect(history.member).to.be.equal('post-init', 'normal set'); history.undo(); expect(history.member).to.be.equal('init', 'undo once'); history.redo(); expect(history.member).to.be.equal('post-init', 'redo once'); } @test public '20 undo'(): void { const history = new HistoryDemo(); expect(history.member).to.be.undefined; history.member = 'init'; const times = 20; for (let i = 0; i < times; i++) { history.member = `post-init${i}`; } for (let i = 0; i < times; i++) { history.undo(); } expect(history.member).to.be.equal('init', 'undo 20 times'); } @test public '20 redo'(): void { const history = new HistoryDemo(); expect(history.member).to.be.undefined; history.member = 'init'; const times = 20; for (let i = 0; i < times; i++) { history.member = `post-init${i}`; } for (let i = 0; i < times; i++) { history.undo(); } for (let i = 0; i < times; i++) { history.redo(); } expect(history.member).to.be.equal(`post-init${times - 1}`, 'undo and redo 20 times'); } @test public 'clear history'(): void { const history = new HistoryDemo(); expect(history.member).to.be.undefined; history.member = 'init'; history.member = 'post-init'; history.cleanHistory(); history.undo(); expect(history.member).to.be.equal('post-init', 'try undo once after cleanHistory'); } @test public 'errors'(): void { expect(() => new HistoryDemoWithoutClassDecorator().member = 'test').to.throw(_propertyHistory); expect(() => { const hd = new HistoryDemo(); hd[ _propertyHistory ] = 0; hd.member = 'test'; }).to.throw(_propertyHistory); expect(() => { const hd = new HistoryDemo(); delete hd[ _onceDisablePropertyHistory ]; hd.member = 'test'; }).to.throw(_onceDisablePropertyHistory); expect(() => { const hd = new HistoryDemo(); delete hd[ _enablePropertyHistory ]; hd.member = 'test'; }).to.throw(_enablePropertyHistory); } } class HistoryDemoWithoutClassDecorator { public get member(): string { return this._member; } @HistoryMember('_member') public set member(value: string) { this._member = value; } private _member: string; }