Mark set/jump as a clean architecture
This commit is contained in:
parent
ebfb172520
commit
c6288f19d9
16 changed files with 316 additions and 137 deletions
|
@ -22,14 +22,4 @@ describe('mark actions', () => {
|
|||
expect(action.type).to.equal(actions.MARK_CANCEL);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setLocal', () => {
|
||||
it('create setLocal action', () => {
|
||||
let action = markActions.setLocal('a', 20, 30);
|
||||
expect(action.type).to.equal(actions.MARK_SET_LOCAL);
|
||||
expect(action.key).to.equal('a');
|
||||
expect(action.x).to.equal(20);
|
||||
expect(action.y).to.equal(30);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
26
test/content/mock/MockConsoleClient.ts
Normal file
26
test/content/mock/MockConsoleClient.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import ConsoleClient from '../../../src/content/client/ConsoleClient';
|
||||
|
||||
export default class MockConsoleClient implements ConsoleClient {
|
||||
public isError: boolean;
|
||||
|
||||
public text: string;
|
||||
|
||||
constructor() {
|
||||
this.isError = false;
|
||||
this.text = '';
|
||||
}
|
||||
|
||||
info(text: string): Promise<void> {
|
||||
this.isError = false;
|
||||
this.text = text;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
error(text: string): Promise<void> {
|
||||
this.isError = true;
|
||||
this.text = text;
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
|
47
test/content/mock/MockScrollPresenter.ts
Normal file
47
test/content/mock/MockScrollPresenter.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
import ScrollPresenter, { Point } from '../../../src/content/presenters/ScrollPresenter';
|
||||
|
||||
export default class MockScrollPresenter implements ScrollPresenter {
|
||||
private pos: Point;
|
||||
|
||||
constructor() {
|
||||
this.pos = { x: 0, y: 0 };
|
||||
}
|
||||
|
||||
getScroll(): Point {
|
||||
return this.pos;
|
||||
}
|
||||
|
||||
scrollVertically(amount: number, _smooth: boolean): void {
|
||||
this.pos.y += amount;
|
||||
}
|
||||
|
||||
scrollHorizonally(amount: number, _smooth: boolean): void {
|
||||
this.pos.x += amount;
|
||||
}
|
||||
|
||||
scrollPages(amount: number, _smooth: boolean): void {
|
||||
this.pos.x += amount;
|
||||
}
|
||||
|
||||
scrollTo(x: number, y: number, _smooth: boolean): void {
|
||||
this.pos.x = x;
|
||||
this.pos.y = y;
|
||||
}
|
||||
|
||||
scrollToTop(_smooth: boolean): void {
|
||||
this.pos.y = 0;
|
||||
}
|
||||
|
||||
scrollToBottom(_smooth: boolean): void {
|
||||
this.pos.y = Infinity;
|
||||
}
|
||||
|
||||
scrollToHome(_smooth: boolean): void {
|
||||
this.pos.x = 0;
|
||||
}
|
||||
|
||||
scrollToEnd(_smooth: boolean): void {
|
||||
this.pos.x = Infinity;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ describe("mark reducer", () => {
|
|||
let state = reducer(undefined, {});
|
||||
expect(state.setMode).to.be.false;
|
||||
expect(state.jumpMode).to.be.false;
|
||||
expect(state.marks).to.be.empty;
|
||||
});
|
||||
|
||||
it('starts set mode', () => {
|
||||
|
@ -29,13 +28,4 @@ describe("mark reducer", () => {
|
|||
state = reducer({ jumpMode: true }, action);
|
||||
expect(state.jumpMode).to.be.false;
|
||||
});
|
||||
|
||||
it('stores local mark', () => {
|
||||
let action = { type: actions.MARK_SET_LOCAL, key: 'a', x: 20, y: 30};
|
||||
let state = reducer({ setMode: true }, action);
|
||||
expect(state.setMode).to.be.false;
|
||||
expect(state.marks['a']).to.be.an('object')
|
||||
expect(state.marks['a'].x).to.equal(20)
|
||||
expect(state.marks['a'].y).to.equal(30)
|
||||
});
|
||||
});
|
||||
|
|
13
test/content/repositories/MarkRepository.test.ts
Normal file
13
test/content/repositories/MarkRepository.test.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { MarkRepositoryImpl } from '../../../src/content/repositories/MarkRepository';
|
||||
import { expect } from 'chai';
|
||||
|
||||
describe('MarkRepositoryImpl', () => {
|
||||
it('save and load marks', () => {
|
||||
let sut = new MarkRepositoryImpl();
|
||||
|
||||
sut.set('a', { x: 10, y: 20 });
|
||||
expect(sut.get('a')).to.deep.equal({ x: 10, y: 20 });
|
||||
expect(sut.get('b')).to.be.null;
|
||||
});
|
||||
});
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import FindRepository from '../../../src/content/repositories/FindRepository';
|
||||
import FindPresenter from '../../../src/content/presenters/FindPresenter';
|
||||
import ConsoleClient from '../../../src/content/client/ConsoleClient';
|
||||
import FindClient from '../../../src/content/client/FindClient';
|
||||
import FindUseCase from '../../../src/content/usecases/FindUseCase';
|
||||
import MockConsoleClient from '../mock/MockConsoleClient';
|
||||
import { expect } from 'chai';
|
||||
|
||||
class MockFindRepository implements FindRepository {
|
||||
|
@ -59,29 +59,6 @@ class MockFindClient implements FindClient {
|
|||
}
|
||||
}
|
||||
|
||||
class MockConsoleClient implements ConsoleClient {
|
||||
public isError: boolean;
|
||||
|
||||
public text: string;
|
||||
|
||||
constructor() {
|
||||
this.isError = false;
|
||||
this.text = '';
|
||||
}
|
||||
|
||||
info(text: string): Promise<void> {
|
||||
this.isError = false;
|
||||
this.text = text;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
error(text: string): Promise<void> {
|
||||
this.isError = true;
|
||||
this.text = text;
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
describe('FindUseCase', () => {
|
||||
let repository: MockFindRepository;
|
||||
let presenter: MockFindPresenter;
|
||||
|
|
107
test/content/usecases/MarkUseCase.test.ts
Normal file
107
test/content/usecases/MarkUseCase.test.ts
Normal file
|
@ -0,0 +1,107 @@
|
|||
import MarkRepository from '../../../src/content/repositories/MarkRepository';
|
||||
import MarkUseCase from '../../../src/content/usecases/MarkUseCase';
|
||||
import MarkClient from '../../../src/content/client/MarkClient';
|
||||
import MockConsoleClient from '../mock/MockConsoleClient';
|
||||
import MockScrollPresenter from '../mock/MockScrollPresenter';
|
||||
import Mark from '../../../src/content/domains/Mark';
|
||||
import { expect } from 'chai';
|
||||
|
||||
class MockMarkRepository implements MarkRepository {
|
||||
private current: {[key: string]: Mark};
|
||||
|
||||
constructor() {
|
||||
this.current = {};
|
||||
}
|
||||
|
||||
set(key: string, mark: Mark): void {
|
||||
this.current[key] = mark;
|
||||
}
|
||||
|
||||
get(key: string): Mark | null {
|
||||
return this.current[key];
|
||||
}
|
||||
}
|
||||
|
||||
class MockMarkClient implements MarkClient {
|
||||
public marks: {[key: string]: Mark};
|
||||
public last: string;
|
||||
|
||||
constructor() {
|
||||
this.marks = {};
|
||||
this.last = '';
|
||||
}
|
||||
|
||||
setGloablMark(key: string, mark: Mark): Promise<void> {
|
||||
this.marks[key] = mark;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
jumpGlobalMark(key: string): Promise<void> {
|
||||
this.last = key
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
describe('MarkUseCase', () => {
|
||||
let repository: MockMarkRepository;
|
||||
let client: MockMarkClient;
|
||||
let consoleClient: MockConsoleClient;
|
||||
let scrollPresenter: MockScrollPresenter;
|
||||
let sut: MarkUseCase;
|
||||
|
||||
beforeEach(() => {
|
||||
repository = new MockMarkRepository();
|
||||
client = new MockMarkClient();
|
||||
consoleClient = new MockConsoleClient();
|
||||
scrollPresenter = new MockScrollPresenter();
|
||||
sut = new MarkUseCase({
|
||||
repository, client, consoleClient, scrollPresenter,
|
||||
});
|
||||
});
|
||||
|
||||
describe('#set', () => {
|
||||
it('sets local mark', async() => {
|
||||
scrollPresenter.scrollTo(10, 20, false);
|
||||
|
||||
await sut.set('x');
|
||||
|
||||
expect(repository.get('x')).to.deep.equals({ x: 10, y: 20 });
|
||||
expect(consoleClient.text).to.equal("Set local mark to 'x'");
|
||||
});
|
||||
|
||||
it('sets global mark', async() => {
|
||||
scrollPresenter.scrollTo(30, 40, false);
|
||||
|
||||
await sut.set('Z');
|
||||
|
||||
expect(client.marks['Z']).to.deep.equals({ x: 30, y: 40 });
|
||||
expect(consoleClient.text).to.equal("Set global mark to 'Z'");
|
||||
});
|
||||
});
|
||||
|
||||
describe('#jump', () => {
|
||||
it('jumps to local mark', async() => {
|
||||
repository.set('x', { x: 20, y: 40 });
|
||||
|
||||
await sut.jump('x');
|
||||
|
||||
expect(scrollPresenter.getScroll()).to.deep.equals({ x: 20, y: 40 });
|
||||
});
|
||||
|
||||
it('throws an error when no local marks', () => {
|
||||
return sut.jump('a').then(() => {
|
||||
throw new Error('error');
|
||||
}).catch((e) => {
|
||||
expect(e).to.be.instanceof(Error);
|
||||
})
|
||||
})
|
||||
|
||||
it('jumps to global mark', async() => {
|
||||
client.marks['Z'] = { x: 20, y: 0 };
|
||||
|
||||
await sut.jump('Z');
|
||||
|
||||
expect(client.last).to.equal('Z')
|
||||
});
|
||||
});
|
||||
});
|
Reference in a new issue