aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/background/mock/MockFindClient.ts23
-rw-r--r--test/background/mock/MockFindRepository.ts5
-rw-r--r--test/background/mock/MockFramePresenter.ts7
-rw-r--r--test/background/operators/impls/FindNextOperator.test.ts231
-rw-r--r--test/background/operators/impls/FindPrevOperator.test.ts233
-rw-r--r--test/background/operators/impls/TabOperatorFactoryChain.test.ts12
-rw-r--r--test/background/repositories/FindRepository.test.ts3
-rw-r--r--test/background/usecases/FindUseCase.test.ts121
-rw-r--r--test/background/usecases/StartFindUseCase.test.ts180
9 files changed, 532 insertions, 283 deletions
diff --git a/test/background/mock/MockFindClient.ts b/test/background/mock/MockFindClient.ts
index bd25a27..dd6d8f3 100644
--- a/test/background/mock/MockFindClient.ts
+++ b/test/background/mock/MockFindClient.ts
@@ -1,24 +1,23 @@
-import FindClient, {
- FindResult,
-} from "../../../src/background/clients/FindClient";
+import FindClient from "../../../src/background/clients/FindClient";
export default class MockFindClient implements FindClient {
- highlightAll(): Promise<void> {
- throw new Error("not implemented");
- }
-
- removeHighlights(): Promise<void> {
+ findNext(
+ _tabId: number,
+ _frameId: number,
+ _keyword: string
+ ): Promise<boolean> {
throw new Error("not implemented");
}
- selectKeyword(
+ findPrev(
_tabId: number,
- _rangeData: browser.find.RangeData
- ): Promise<void> {
+ _frameId: number,
+ _keyword: string
+ ): Promise<boolean> {
throw new Error("not implemented");
}
- startFind(_keyword: string): Promise<FindResult> {
+ clearSelection(_tabId: number, _frameId: number): Promise<void> {
throw new Error("not implemented");
}
}
diff --git a/test/background/mock/MockFindRepository.ts b/test/background/mock/MockFindRepository.ts
index af552c8..d5151f8 100644
--- a/test/background/mock/MockFindRepository.ts
+++ b/test/background/mock/MockFindRepository.ts
@@ -23,4 +23,9 @@ export default class MockFindRepository implements FindRepository {
this.localStates[tabId] = state;
return Promise.resolve();
}
+
+ deleteLocalState(tabId: number): Promise<void> {
+ delete this.localStates[tabId];
+ return Promise.resolve();
+ }
}
diff --git a/test/background/mock/MockFramePresenter.ts b/test/background/mock/MockFramePresenter.ts
new file mode 100644
index 0000000..d688780
--- /dev/null
+++ b/test/background/mock/MockFramePresenter.ts
@@ -0,0 +1,7 @@
+import FramePresenter from "../../../src/background/presenters/FramePresenter";
+
+export default class MockFramePresenter implements FramePresenter {
+ getAllFrameIds(): Promise<number[]> {
+ throw new Error("not implemented");
+ }
+}
diff --git a/test/background/operators/impls/FindNextOperator.test.ts b/test/background/operators/impls/FindNextOperator.test.ts
index 20208ae..0bee3f5 100644
--- a/test/background/operators/impls/FindNextOperator.test.ts
+++ b/test/background/operators/impls/FindNextOperator.test.ts
@@ -1,90 +1,179 @@
-import sinon from "sinon";
+import * as sinon from "sinon";
import MockTabPresenter from "../../mock/MockTabPresenter";
import FindNextOperator from "../../../../src/background/operators/impls/FindNextOperator";
-import { FindState } from "../../../../src/background/repositories/FindRepository";
import MockFindRepository from "../../mock/MockFindRepository";
import MockFindClient from "../../mock/MockFindClient";
+import MockConsoleClient from "../../mock/MockConsoleClient";
+import MockFramePresenter from "../../mock/MockFramePresenter";
describe("FindNextOperator", () => {
+ const keyword = "hello";
+ const frameIds = [0, 100, 101];
+
+ const tabPresenter = new MockTabPresenter();
+ const findRepository = new MockFindRepository();
+ const findClient = new MockFindClient();
+ const consoleClient = new MockConsoleClient();
+ const framePresenter = new MockFramePresenter();
+ const sut = new FindNextOperator(
+ tabPresenter,
+ findRepository,
+ findClient,
+ consoleClient,
+ framePresenter
+ );
+
+ let currentTabId: number;
+
+ beforeEach(async () => {
+ sinon.restore();
+
+ const currentTab = await tabPresenter.create("https://example.com/", {
+ active: true,
+ });
+ currentTabId = currentTab.id!;
+ });
+
describe("#run", () => {
- it("throws an error on no previous keywords", async () => {
- const tabPresenter = new MockTabPresenter();
- const findRepository = new MockFindRepository();
- const findClient = new MockFindClient();
- await tabPresenter.create("https://example.com/");
-
- const sut = new FindNextOperator(
- tabPresenter,
- findRepository,
- findClient
+ it("shows errors if no previous keywords", async () => {
+ sinon
+ .stub(findRepository, "getLocalState")
+ .returns(Promise.resolve(undefined));
+
+ const mock = sinon.mock(consoleClient);
+ mock
+ .expects("showError")
+ .withArgs(currentTabId, "No previous search keywords");
+
+ await sut.run();
+
+ mock.verify();
+ });
+
+ it("continues a search on the same frame", async () => {
+ sinon.stub(findRepository, "getLocalState").returns(
+ Promise.resolve({
+ keyword,
+ frameIds,
+ framePos: 1,
+ })
);
- try {
- await sut.run();
- } catch (e) {
- return;
- }
- throw new Error("unexpected reach");
+
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 100, keyword)
+ .returns(Promise.resolve(true));
+
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { keyword, frameIds, framePos: 1 });
+
+ await sut.run();
+
+ mockFindRepository.verify();
+ mockFindClient.verify();
});
- it("select a next next", async () => {
- const tabPresenter = new MockTabPresenter();
- const findRepository = new MockFindRepository();
- const findClient = new MockFindClient();
- const currentTab = await tabPresenter.create("https://example.com/");
-
- const state: FindState = {
- keyword: "Hello, world",
- rangeData: [
- {
- framePos: 0,
- startOffset: 0,
- endOffset: 10,
- startTextNodePos: 0,
- endTextNodePos: 0,
- text: "Hello, world",
- },
- {
- framePos: 1,
- startOffset: 0,
- endOffset: 10,
- startTextNodePos: 1,
- endTextNodePos: 1,
- text: "Hello, world",
- },
- {
- framePos: 2,
- startOffset: 2,
- endOffset: 10,
- startTextNodePos: 1,
- endTextNodePos: 1,
- text: "Hello, world",
- },
- ],
- highlightPosition: 0,
- };
-
- await findRepository.setLocalState(currentTab.id!, state);
- const mock = sinon.mock(findClient);
- mock
- .expects("selectKeyword")
- .withArgs(currentTab?.id, state.rangeData[1]);
- mock
- .expects("selectKeyword")
- .withArgs(currentTab?.id, state.rangeData[2]);
- mock
- .expects("selectKeyword")
- .withArgs(currentTab?.id, state.rangeData[0]);
- const sut = new FindNextOperator(
- tabPresenter,
- findRepository,
- findClient
+ it("continues a search on next frame", async () => {
+ sinon.stub(findRepository, "getLocalState").returns(
+ Promise.resolve({
+ keyword,
+ frameIds,
+ framePos: 1,
+ })
);
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 100, keyword)
+ .returns(Promise.resolve(false));
+ mockFindClient
+ .expects("clearSelection")
+ .withArgs(currentTabId, 100)
+ .returns(Promise.resolve());
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 101, keyword)
+ .returns(Promise.resolve(true));
+
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { keyword, frameIds, framePos: 2 });
+
await sut.run();
+
+ mockFindRepository.verify();
+ mockFindClient.verify();
+ });
+
+ it("exercise a wrap-search", async () => {
+ sinon.stub(findRepository, "getLocalState").returns(
+ Promise.resolve({
+ keyword,
+ frameIds,
+ framePos: 2,
+ })
+ );
+
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 101, keyword)
+ .returns(Promise.resolve(false));
+ mockFindClient
+ .expects("clearSelection")
+ .withArgs(currentTabId, 101)
+ .returns(Promise.resolve());
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 0, keyword)
+ .returns(Promise.resolve(true));
+
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { keyword, frameIds, framePos: 0 });
+
await sut.run();
+
+ mockFindRepository.verify();
+ mockFindClient.verify();
+ });
+
+ it("starts a search with last keywords", async () => {
+ sinon
+ .stub(findRepository, "getLocalState")
+ .returns(Promise.resolve(undefined));
+ sinon
+ .stub(findRepository, "getGlobalKeyword")
+ .returns(Promise.resolve(keyword));
+ sinon
+ .stub(framePresenter, "getAllFrameIds")
+ .returns(Promise.resolve(frameIds));
+ sinon.stub(consoleClient, "showInfo").returns(Promise.resolve());
+
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 0);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 100);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 101);
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 0, keyword)
+ .returns(Promise.resolve(true));
+
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { keyword, frameIds, framePos: 0 });
+
await sut.run();
- mock.verify();
+ mockFindRepository.verify();
+ mockFindClient.verify();
});
});
});
diff --git a/test/background/operators/impls/FindPrevOperator.test.ts b/test/background/operators/impls/FindPrevOperator.test.ts
index 409c26d..ebac0dc 100644
--- a/test/background/operators/impls/FindPrevOperator.test.ts
+++ b/test/background/operators/impls/FindPrevOperator.test.ts
@@ -1,90 +1,179 @@
-import sinon from "sinon";
+import * as sinon from "sinon";
import MockTabPresenter from "../../mock/MockTabPresenter";
-import FindNextOperator from "../../../../src/background/operators/impls/FindNextOperator";
-import { FindState } from "../../../../src/background/repositories/FindRepository";
+import FindPrevOperator from "../../../../src/background/operators/impls/FindPrevOperator";
import MockFindRepository from "../../mock/MockFindRepository";
import MockFindClient from "../../mock/MockFindClient";
+import MockConsoleClient from "../../mock/MockConsoleClient";
+import MockFramePresenter from "../../mock/MockFramePresenter";
describe("FindPrevOperator", () => {
+ const keyword = "hello";
+ const frameIds = [0, 100, 101];
+
+ const tabPresenter = new MockTabPresenter();
+ const findRepository = new MockFindRepository();
+ const findClient = new MockFindClient();
+ const consoleClient = new MockConsoleClient();
+ const framePresenter = new MockFramePresenter();
+ const sut = new FindPrevOperator(
+ tabPresenter,
+ findRepository,
+ findClient,
+ consoleClient,
+ framePresenter
+ );
+
+ let currentTabId: number;
+
+ beforeEach(async () => {
+ sinon.restore();
+
+ const currentTab = await tabPresenter.create("https://example.com/", {
+ active: true,
+ });
+ currentTabId = currentTab.id!;
+ });
+
describe("#run", () => {
- it("throws an error on no previous keywords", async () => {
- const tabPresenter = new MockTabPresenter();
- const findRepository = new MockFindRepository();
- const findClient = new MockFindClient();
- await tabPresenter.create("https://example.com/");
-
- const sut = new FindNextOperator(
- tabPresenter,
- findRepository,
- findClient
+ it("shows errors if no previous keywords", async () => {
+ sinon
+ .stub(findRepository, "getLocalState")
+ .returns(Promise.resolve(undefined));
+
+ const mock = sinon.mock(consoleClient);
+ mock
+ .expects("showError")
+ .withArgs(currentTabId, "No previous search keywords");
+
+ await sut.run();
+
+ mock.verify();
+ });
+
+ it("continues a search on the same frame", async () => {
+ sinon.stub(findRepository, "getLocalState").returns(
+ Promise.resolve({
+ keyword,
+ frameIds,
+ framePos: 1,
+ })
);
- try {
- await sut.run();
- } catch (e) {
- return;
- }
- throw new Error("unexpected reach");
+
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient
+ .expects("findPrev")
+ .withArgs(currentTabId, 100, keyword)
+ .returns(Promise.resolve(true));
+
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { keyword, frameIds, framePos: 1 });
+
+ await sut.run();
+
+ mockFindRepository.verify();
+ mockFindClient.verify();
});
- it("select a next next", async () => {
- const tabPresenter = new MockTabPresenter();
- const findRepository = new MockFindRepository();
- const findClient = new MockFindClient();
- const currentTab = await tabPresenter.create("https://example.com/");
-
- const state: FindState = {
- keyword: "Hello, world",
- rangeData: [
- {
- framePos: 0,
- startOffset: 0,
- endOffset: 10,
- startTextNodePos: 0,
- endTextNodePos: 0,
- text: "Hello, world",
- },
- {
- framePos: 1,
- startOffset: 0,
- endOffset: 10,
- startTextNodePos: 1,
- endTextNodePos: 1,
- text: "Hello, world",
- },
- {
- framePos: 2,
- startOffset: 2,
- endOffset: 10,
- startTextNodePos: 1,
- endTextNodePos: 1,
- text: "Hello, world",
- },
- ],
- highlightPosition: 1,
- };
-
- await findRepository.setLocalState(currentTab.id!, state);
- const mock = sinon.mock(findClient);
- mock
- .expects("selectKeyword")
- .withArgs(currentTab?.id, state.rangeData[0]);
- mock
- .expects("selectKeyword")
- .withArgs(currentTab?.id, state.rangeData[2]);
- mock
- .expects("selectKeyword")
- .withArgs(currentTab?.id, state.rangeData[1]);
- const sut = new FindNextOperator(
- tabPresenter,
- findRepository,
- findClient
+ it("continues a search on next frame", async () => {
+ sinon.stub(findRepository, "getLocalState").returns(
+ Promise.resolve({
+ keyword,
+ frameIds,
+ framePos: 1,
+ })
);
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient
+ .expects("findPrev")
+ .withArgs(currentTabId, 100, keyword)
+ .returns(Promise.resolve(false));
+ mockFindClient
+ .expects("clearSelection")
+ .withArgs(currentTabId, 100)
+ .returns(Promise.resolve());
+ mockFindClient
+ .expects("findPrev")
+ .withArgs(currentTabId, 0, keyword)
+ .returns(Promise.resolve(true));
+
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { keyword, frameIds, framePos: 0 });
+
await sut.run();
+
+ mockFindRepository.verify();
+ mockFindClient.verify();
+ });
+
+ it("exercise a wrap-search", async () => {
+ sinon.stub(findRepository, "getLocalState").returns(
+ Promise.resolve({
+ keyword,
+ frameIds,
+ framePos: 0,
+ })
+ );
+
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient
+ .expects("findPrev")
+ .withArgs(currentTabId, 0, keyword)
+ .returns(Promise.resolve(false));
+ mockFindClient
+ .expects("clearSelection")
+ .withArgs(currentTabId, 0)
+ .returns(Promise.resolve());
+ mockFindClient
+ .expects("findPrev")
+ .withArgs(currentTabId, 101, keyword)
+ .returns(Promise.resolve(true));
+
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { keyword, frameIds, framePos: 2 });
+
await sut.run();
+
+ mockFindRepository.verify();
+ mockFindClient.verify();
+ });
+
+ it("starts a search with last keywords", async () => {
+ sinon
+ .stub(findRepository, "getLocalState")
+ .returns(Promise.resolve(undefined));
+ sinon
+ .stub(findRepository, "getGlobalKeyword")
+ .returns(Promise.resolve(keyword));
+ sinon
+ .stub(framePresenter, "getAllFrameIds")
+ .returns(Promise.resolve(frameIds));
+ sinon.stub(consoleClient, "showInfo").returns(Promise.resolve());
+
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 0);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 100);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 101);
+ mockFindClient
+ .expects("findPrev")
+ .withArgs(currentTabId, 101, keyword)
+ .returns(Promise.resolve(true));
+
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { keyword, frameIds, framePos: 2 });
+
await sut.run();
- mock.verify();
+ mockFindRepository.verify();
+ mockFindClient.verify();
});
});
});
diff --git a/test/background/operators/impls/TabOperatorFactoryChain.test.ts b/test/background/operators/impls/TabOperatorFactoryChain.test.ts
index 7ab5de0..a777973 100644
--- a/test/background/operators/impls/TabOperatorFactoryChain.test.ts
+++ b/test/background/operators/impls/TabOperatorFactoryChain.test.ts
@@ -44,12 +44,12 @@ describe("TabOperatorFactoryChain", () => {
expect(sut.create({ type: operations.TAB_FIRST })).to.be.instanceOf(
SelectFirstTabOperator
);
- expect(
- sut.create({ type: operations.TAB_LAST, newTab: false })
- ).to.be.instanceOf(SelectLastTabOperator);
- expect(
- sut.create({ type: operations.TAB_PREV_SEL, newTab: false })
- ).to.be.instanceOf(SelectPreviousSelectedTabOperator);
+ expect(sut.create({ type: operations.TAB_LAST })).to.be.instanceOf(
+ SelectLastTabOperator
+ );
+ expect(sut.create({ type: operations.TAB_PREV_SEL })).to.be.instanceOf(
+ SelectPreviousSelectedTabOperator
+ );
expect(
sut.create({ type: operations.TAB_RELOAD, cache: false })
).to.be.instanceOf(ReloadTabOperator);
diff --git a/test/background/repositories/FindRepository.test.ts b/test/background/repositories/FindRepository.test.ts
index ecb0fed..a08dc6d 100644
--- a/test/background/repositories/FindRepository.test.ts
+++ b/test/background/repositories/FindRepository.test.ts
@@ -25,7 +25,8 @@ describe("background/repositories/FindRepositoryImpl", () => {
await sut.setLocalState(10, {
keyword: "Hello, world",
- frameId: 20,
+ frameIds: [20, 21],
+ framePos: 0,
});
const state = await sut.getLocalState(10);
diff --git a/test/background/usecases/FindUseCase.test.ts b/test/background/usecases/FindUseCase.test.ts
deleted file mode 100644
index eef211b..0000000
--- a/test/background/usecases/FindUseCase.test.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-import "reflect-metadata";
-import sinon from "sinon";
-import FindClient from "../../../src/background/clients/FindClient";
-import StartFindUseCase from "../../../src/background/usecases/StartFindUseCase";
-import FindRepository from "../../../src/background/repositories/FindRepository";
-import { expect } from "chai";
-import MockFindClient from "../mock/MockFindClient";
-import MockFindRepository from "../mock/MockFindRepository";
-
-describe("FindUseCase", () => {
- let findClient: FindClient;
- let findRepository: FindRepository;
- let sut: StartFindUseCase;
-
- const rangeData = (count: number): browser.find.RangeData[] => {
- const data = {
- text: "Hello, world",
- framePos: 0,
- startTextNodePos: 0,
- endTextNodePos: 0,
- startOffset: 0,
- endOffset: 0,
- };
- return Array(count).fill(data);
- };
-
- beforeEach(() => {
- findClient = new MockFindClient();
- findRepository = new MockFindRepository();
- sut = new StartFindUseCase(findClient, findRepository);
- });
-
- describe("startFind", function () {
- context("with a search keyword", () => {
- it("starts find and store last used keyword", async () => {
- const startFind = sinon
- .stub(findClient, "startFind")
- .returns(Promise.resolve({ count: 10, rangeData: rangeData(10) }));
- const highlightAll = sinon
- .mock(findClient)
- .expects("highlightAll")
- .once();
- const selectKeyword = sinon
- .mock(findClient)
- .expects("selectKeyword")
- .once();
-
- await sut.startFind(10, "Hello, world");
-
- expect(startFind.calledWith("Hello, world")).to.be.true;
- expect(await findRepository.getGlobalKeyword()).to.equals(
- "Hello, world"
- );
- expect((await findRepository.getLocalState(10))?.keyword).to.equal(
- "Hello, world"
- );
- highlightAll.verify();
- selectKeyword.verify();
- });
-
- it("throws an error if no matched", (done) => {
- sinon
- .stub(findClient, "startFind")
- .returns(Promise.resolve({ count: 0, rangeData: [] }));
-
- sut.startFind(10, "Hello, world").catch((e) => {
- expect(e).instanceof(Error);
- done();
- });
- });
- });
-
- context("without a search keyword", () => {
- it("starts find with last used keyword in the tab", async () => {
- const startFind = sinon
- .stub(findClient, "startFind")
- .returns(Promise.resolve({ count: 10, rangeData: rangeData(10) }));
- await findRepository.setLocalState(10, {
- keyword: "Hello, world",
- rangeData: rangeData(10),
- highlightPosition: 0,
- });
- const highlightAll = sinon
- .mock(findClient)
- .expects("highlightAll")
- .once();
- const selectKeyword = sinon
- .mock(findClient)
- .expects("selectKeyword")
- .once();
-
- await sut.startFind(10, undefined);
-
- expect(startFind.calledWith("Hello, world")).to.be.true;
- highlightAll.verify();
- selectKeyword.verify();
- });
-
- it("starts find with last used keyword in global", async () => {
- const startFind = sinon
- .stub(findClient, "startFind")
- .returns(Promise.resolve({ count: 10, rangeData: rangeData(10) }));
- await findRepository.setGlobalKeyword("Hello, world");
- const highlightAll = sinon
- .mock(findClient)
- .expects("highlightAll")
- .once();
- const selectKeyword = sinon
- .mock(findClient)
- .expects("selectKeyword")
- .once();
-
- await sut.startFind(10, undefined);
-
- expect(startFind.calledWith("Hello, world")).to.be.true;
- highlightAll.verify();
- selectKeyword.verify();
- });
- });
- });
-});
diff --git a/test/background/usecases/StartFindUseCase.test.ts b/test/background/usecases/StartFindUseCase.test.ts
new file mode 100644
index 0000000..22ff9a5
--- /dev/null
+++ b/test/background/usecases/StartFindUseCase.test.ts
@@ -0,0 +1,180 @@
+import * as sinon from "sinon";
+import MockFindClient from "../mock/MockFindClient";
+import MockFindRepository from "../mock/MockFindRepository";
+import MockConsoleClient from "../mock/MockConsoleClient";
+import MockFramePresenter from "../mock/MockFramePresenter";
+import StartFindUseCase from "../../../src/background/usecases/StartFindUseCase";
+
+describe("StartFindUseCase", () => {
+ const currentTabId = 100;
+ const frameIds = [0, 100, 101];
+ const keyword = "hello";
+
+ const findClient = new MockFindClient();
+ const findRepository = new MockFindRepository();
+ const consoleClient = new MockConsoleClient();
+ const framePresenter = new MockFramePresenter();
+ const sut = new StartFindUseCase(
+ findClient,
+ findRepository,
+ consoleClient,
+ framePresenter
+ );
+
+ beforeEach(async () => {
+ sinon.restore();
+
+ sinon
+ .stub(framePresenter, "getAllFrameIds")
+ .returns(Promise.resolve(frameIds));
+ });
+
+ describe("startFind", () => {
+ it("starts a find with a keyword", async () => {
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 0);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 100);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 101);
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 0, keyword)
+ .returns(Promise.resolve(false));
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 100, keyword)
+ .returns(Promise.resolve(true));
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { frameIds, framePos: 1, keyword });
+ const mockConsoleClient = sinon.mock(consoleClient);
+ mockConsoleClient
+ .expects("showInfo")
+ .withArgs(currentTabId, "Pattern found: " + keyword);
+
+ await sut.startFind(currentTabId, keyword);
+
+ mockFindClient.verify();
+ mockFindRepository.verify();
+ mockConsoleClient.verify();
+ });
+
+ it("starts a find with last local state", async () => {
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 0);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 100);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 101);
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 0, keyword)
+ .returns(Promise.resolve(false));
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 100, keyword)
+ .returns(Promise.resolve(true));
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("getLocalState")
+ .withArgs(currentTabId)
+ .returns(Promise.resolve({ keyword, frameIds, framePos: 0 }));
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { frameIds, framePos: 1, keyword });
+ const mockConsoleClient = sinon.mock(consoleClient);
+ mockConsoleClient
+ .expects("showInfo")
+ .withArgs(currentTabId, "Pattern found: " + keyword);
+
+ await sut.startFind(currentTabId, undefined);
+
+ mockFindClient.verify();
+ mockFindRepository.verify();
+ mockConsoleClient.verify();
+ });
+
+ it("starts a find with last global state", async () => {
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 0);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 100);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 101);
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 0, keyword)
+ .returns(Promise.resolve(false));
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 100, keyword)
+ .returns(Promise.resolve(true));
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository
+ .expects("getLocalState")
+ .withArgs(currentTabId)
+ .returns(Promise.resolve(undefined));
+ mockFindRepository
+ .expects("getGlobalKeyword")
+ .returns(Promise.resolve(keyword));
+ mockFindRepository
+ .expects("setLocalState")
+ .withArgs(currentTabId, { frameIds, framePos: 1, keyword });
+ const mockConsoleClient = sinon.mock(consoleClient);
+ mockConsoleClient
+ .expects("showInfo")
+ .withArgs(currentTabId, "Pattern found: " + keyword);
+
+ await sut.startFind(currentTabId, undefined);
+
+ mockFindClient.verify();
+ mockFindRepository.verify();
+ mockConsoleClient.verify();
+ });
+
+ it("shows an error when pattern not found", async () => {
+ const mockFindClient = sinon.mock(findClient);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 0);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 100);
+ mockFindClient.expects("clearSelection").withArgs(currentTabId, 101);
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 0, keyword)
+ .returns(Promise.resolve(false));
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 100, keyword)
+ .returns(Promise.resolve(false));
+ mockFindClient
+ .expects("findNext")
+ .withArgs(currentTabId, 101, keyword)
+ .returns(Promise.resolve(false));
+ const mockFindRepository = sinon.mock(findRepository);
+ mockFindRepository.expects("setLocalState").never();
+ const mockConsoleClient = sinon.mock(consoleClient);
+ mockConsoleClient
+ .expects("showError")
+ .withArgs(currentTabId, "Pattern not found: " + keyword);
+
+ await sut.startFind(currentTabId, keyword);
+
+ mockFindClient.verify();
+ mockFindRepository.verify();
+ mockConsoleClient.verify();
+ });
+
+ it("shows an error when no last keywords", async () => {
+ sinon
+ .stub(findRepository, "getLocalState")
+ .returns(Promise.resolve(undefined));
+ sinon
+ .stub(findRepository, "getGlobalKeyword")
+ .returns(Promise.resolve(undefined));
+
+ const mockConsoleClient = sinon.mock(consoleClient);
+ mockConsoleClient
+ .expects("showError")
+ .withArgs(currentTabId, "No previous search keywords");
+
+ await sut.startFind(currentTabId, undefined);
+
+ mockConsoleClient.verify();
+ });
+ });
+});