aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShin'ya Ueoka <ueokande@i-beam.org>2020-03-27 07:23:17 +0900
committerShin'ya Ueoka <ueokande@i-beam.org>2020-03-27 20:47:35 +0900
commita8d78f1286fb3fe456a786b2c0e534d212835560 (patch)
treed42a27548a7f3ad8b71336109dc5b48f95ec554f
parentb2a37b8fc3e273dd71e1e3558c58be8002aa3789 (diff)
Separate repository's interface and its implementation
-rw-r--r--src/background/completion/BookmarkRepository.ts28
-rw-r--r--src/background/completion/CompletionUseCase.ts15
-rw-r--r--src/background/completion/HistoryRepository.ts28
-rw-r--r--src/background/completion/impl/BookmarkRepositoryImpl.ts28
-rw-r--r--src/background/completion/impl/HistoryRepositoryImpl.ts28
-rw-r--r--src/background/completion/impl/filters.ts (renamed from src/background/completion/filters.ts)0
-rw-r--r--src/background/di.ts4
-rw-r--r--src/console/actions/console.ts30
-rw-r--r--src/console/actions/index.ts20
-rw-r--r--test/background/completion/CompletionUseCase.test.ts131
-rw-r--r--test/background/completion/impl/filters.test.ts114
-rw-r--r--test/background/usecases/filters.test.ts113
-rw-r--r--test/console/actions/console.test.ts9
13 files changed, 346 insertions, 202 deletions
diff --git a/src/background/completion/BookmarkRepository.ts b/src/background/completion/BookmarkRepository.ts
index 12f5455..14105c8 100644
--- a/src/background/completion/BookmarkRepository.ts
+++ b/src/background/completion/BookmarkRepository.ts
@@ -1,32 +1,8 @@
-import { injectable } from "tsyringe";
-
export type BookmarkItem = {
title: string
url: string
}
-const COMPLETION_ITEM_LIMIT = 10;
-
-@injectable()
-export default class BookmarkRepository {
- async queryBookmarks(query: string): Promise<BookmarkItem[]> {
- const items = await browser.bookmarks.search({ query });
- return items
- .filter(item => item.title && item.title.length > 0)
- .filter(item => item.type === 'bookmark' && item.url)
- .filter((item) => {
- let url = undefined;
- try {
- url = new URL(item.url!!);
- } catch (e) {
- return false;
- }
- return url.protocol !== 'place:';
- })
- .slice(0, COMPLETION_ITEM_LIMIT)
- .map(item => ({
- title: item.title!!,
- url: item.url!!,
- }));
- }
+export default interface BookmarkRepository {
+ queryBookmarks(query: string): Promise<BookmarkItem[]>;
}
diff --git a/src/background/completion/CompletionUseCase.ts b/src/background/completion/CompletionUseCase.ts
index fd3c279..f7531e7 100644
--- a/src/background/completion/CompletionUseCase.ts
+++ b/src/background/completion/CompletionUseCase.ts
@@ -1,8 +1,8 @@
import { inject, injectable } from "tsyringe";
-import HistoryRepository from "./HistoryRepository";
-import BookmarkRepository from "./BookmarkRepository";
import CachedSettingRepository from "../repositories/CachedSettingRepository";
import CompletionType from "../../shared/CompletionType";
+import BookmarkRepository from "./BookmarkRepository";
+import HistoryRepository from "./HistoryRepository";
export type BookmarkItem = {
title: string
@@ -17,10 +17,9 @@ export type HistoryItem = {
@injectable()
export default class CompletionUseCase {
constructor(
- private bookmarkRepository: BookmarkRepository,
- private historyRepository: HistoryRepository,
- @inject("CachedSettingRepository")
- private cachedSettingRepository: CachedSettingRepository,
+ @inject('BookmarkRepository') private bookmarkRepository: BookmarkRepository,
+ @inject('HistoryRepository') private historyRepository: HistoryRepository,
+ @inject("CachedSettingRepository") private cachedSettingRepository: CachedSettingRepository,
) {
}
@@ -50,11 +49,11 @@ export default class CompletionUseCase {
.filter(key => key.startsWith(query))
}
- requestBookmarks(query: any): Promise<BookmarkItem[]> {
+ requestBookmarks(query: string): Promise<BookmarkItem[]> {
return this.bookmarkRepository.queryBookmarks(query);
}
- async requestHistory(query: string): Promise<HistoryItem[]> {
+ requestHistory(query: string): Promise<HistoryItem[]> {
return this.historyRepository.queryHistories(query);
}
} \ No newline at end of file
diff --git a/src/background/completion/HistoryRepository.ts b/src/background/completion/HistoryRepository.ts
index 1cfaf1b..5eb3a2b 100644
--- a/src/background/completion/HistoryRepository.ts
+++ b/src/background/completion/HistoryRepository.ts
@@ -1,32 +1,8 @@
-import * as filters from "./filters";
-import { injectable } from "tsyringe";
-
export type HistoryItem = {
title: string
url: string
}
-const COMPLETION_ITEM_LIMIT = 10;
-
-@injectable()
-export default class HistoryRepository {
- async queryHistories(keywords: string): Promise<HistoryItem[]> {
- const items = await browser.history.search({
- text: keywords,
- startTime: 0,
- });
-
- return [items]
- .map(filters.filterBlankTitle)
- .map(filters.filterHttp)
- .map(filters.filterByTailingSlash)
- .map(pages => filters.filterByPathname(pages, COMPLETION_ITEM_LIMIT))
- .map(pages => filters.filterByOrigin(pages, COMPLETION_ITEM_LIMIT))[0]
- .sort((x, y) => Number(y.visitCount) - Number(x.visitCount))
- .slice(0, COMPLETION_ITEM_LIMIT)
- .map(item => ({
- title: item.title!!,
- url: item.url!!,
- }))
- }
+export default interface HistoryRepository {
+ queryHistories(keywords: string): Promise<HistoryItem[]>;
}
diff --git a/src/background/completion/impl/BookmarkRepositoryImpl.ts b/src/background/completion/impl/BookmarkRepositoryImpl.ts
new file mode 100644
index 0000000..58df129
--- /dev/null
+++ b/src/background/completion/impl/BookmarkRepositoryImpl.ts
@@ -0,0 +1,28 @@
+import { injectable } from "tsyringe";
+import BookmarkRepository, {BookmarkItem} from "../BookmarkRepository";
+
+const COMPLETION_ITEM_LIMIT = 10;
+
+@injectable()
+export default class BookmarkRepositoryImpl implements BookmarkRepository {
+ async queryBookmarks(query: string): Promise<BookmarkItem[]> {
+ const items = await browser.bookmarks.search({query});
+ return items
+ .filter(item => item.title && item.title.length > 0)
+ .filter(item => item.type === 'bookmark' && item.url)
+ .filter((item) => {
+ let url = undefined;
+ try {
+ url = new URL(item.url!!);
+ } catch (e) {
+ return false;
+ }
+ return url.protocol !== 'place:';
+ })
+ .slice(0, COMPLETION_ITEM_LIMIT)
+ .map(item => ({
+ title: item.title!!,
+ url: item.url!!,
+ }));
+ }
+}
diff --git a/src/background/completion/impl/HistoryRepositoryImpl.ts b/src/background/completion/impl/HistoryRepositoryImpl.ts
new file mode 100644
index 0000000..42691aa
--- /dev/null
+++ b/src/background/completion/impl/HistoryRepositoryImpl.ts
@@ -0,0 +1,28 @@
+import { injectable } from "tsyringe";
+import * as filters from "./filters";
+import HistoryRepository, {HistoryItem} from "../HistoryRepository";
+
+const COMPLETION_ITEM_LIMIT = 10;
+
+@injectable()
+export default class HistoryRepositoryImpl implements HistoryRepository {
+ async queryHistories(keywords: string): Promise<HistoryItem[]> {
+ const items = await browser.history.search({
+ text: keywords,
+ startTime: 0,
+ });
+
+ return [items]
+ .map(filters.filterBlankTitle)
+ .map(filters.filterHttp)
+ .map(filters.filterByTailingSlash)
+ .map(pages => filters.filterByPathname(pages, COMPLETION_ITEM_LIMIT))
+ .map(pages => filters.filterByOrigin(pages, COMPLETION_ITEM_LIMIT))[0]
+ .sort((x, y) => Number(y.visitCount) - Number(x.visitCount))
+ .slice(0, COMPLETION_ITEM_LIMIT)
+ .map(item => ({
+ title: item.title!!,
+ url: item.url!!,
+ }))
+ }
+}
diff --git a/src/background/completion/filters.ts b/src/background/completion/impl/filters.ts
index 98957a7..98957a7 100644
--- a/src/background/completion/filters.ts
+++ b/src/background/completion/impl/filters.ts
diff --git a/src/background/di.ts b/src/background/di.ts
index 9fc230c..0b52e0b 100644
--- a/src/background/di.ts
+++ b/src/background/di.ts
@@ -4,8 +4,12 @@ import { LocalSettingRepository, SyncSettingRepository } from "./repositories/Se
import { NotifierImpl } from "./presenters/Notifier";
import { CachedSettingRepositoryImpl } from "./repositories/CachedSettingRepository";
import { container } from 'tsyringe';
+import HistoryRepositoryImpl from "./completion/impl/HistoryRepositoryImpl";
+import BookmarkRepositoryImpl from "./completion/impl/BookmarkRepositoryImpl";
container.register('LocalSettingRepository', { useValue: LocalSettingRepository });
container.register('SyncSettingRepository', { useClass: SyncSettingRepository });
container.register('CachedSettingRepository', { useClass: CachedSettingRepositoryImpl });
container.register('Notifier', { useClass: NotifierImpl });
+container.register('HistoryRepository', { useClass: HistoryRepositoryImpl });
+container.register('BookmarkRepository', { useClass: BookmarkRepositoryImpl });
diff --git a/src/console/actions/console.ts b/src/console/actions/console.ts
index 99e58f7..f1db941 100644
--- a/src/console/actions/console.ts
+++ b/src/console/actions/console.ts
@@ -27,7 +27,7 @@ const hide = (): actions.ConsoleAction => {
};
};
-const showCommand = async (text: string): Promise<actions.ConsoleAction> => {
+const showCommand = async (text: string): Promise<actions.ShowCommand> => {
const completionTypes = await completionClient.getCompletionTypes();
return {
type: actions.CONSOLE_SHOW_COMMAND,
@@ -36,27 +36,27 @@ const showCommand = async (text: string): Promise<actions.ConsoleAction> => {
};
};
-const showFind = (): actions.ConsoleAction => {
+const showFind = (): actions.ShowFindAction => {
return {
type: actions.CONSOLE_SHOW_FIND,
};
};
-const showError = (text: string): actions.ConsoleAction => {
+const showError = (text: string): actions.ShowErrorAction => {
return {
type: actions.CONSOLE_SHOW_ERROR,
text: text
};
};
-const showInfo = (text: string): actions.ConsoleAction => {
+const showInfo = (text: string): actions.ShowInfoAction => {
return {
type: actions.CONSOLE_SHOW_INFO,
text: text
};
};
-const hideCommand = (): actions.ConsoleAction => {
+const hideCommand = (): actions.HideCommandAction => {
window.top.postMessage(JSON.stringify({
type: messages.CONSOLE_UNFOCUS,
}), '*');
@@ -65,9 +65,7 @@ const hideCommand = (): actions.ConsoleAction => {
};
};
-const enterCommand = async(
- text: string,
-): Promise<actions.ConsoleAction> => {
+const enterCommand = async(text: string): Promise<actions.HideCommandAction> => {
await browser.runtime.sendMessage({
type: messages.CONSOLE_ENTER_COMMAND,
text,
@@ -75,7 +73,7 @@ const enterCommand = async(
return hideCommand();
};
-const enterFind = (text?: string): actions.ConsoleAction => {
+const enterFind = (text?: string): actions.HideCommandAction => {
window.top.postMessage(JSON.stringify({
type: messages.CONSOLE_ENTER_FIND,
text,
@@ -83,14 +81,14 @@ const enterFind = (text?: string): actions.ConsoleAction => {
return hideCommand();
};
-const setConsoleText = (consoleText: string): actions.ConsoleAction => {
+const setConsoleText = (consoleText: string): actions.SetConsoleTextAction => {
return {
type: actions.CONSOLE_SET_CONSOLE_TEXT,
consoleText,
};
};
-const getCommandCompletions = (text: string): actions.ConsoleAction => {
+const getCommandCompletions = (text: string): actions.SetCompletionsAction => {
const items = Object.entries(commandDocs)
.filter(([name]) => name.startsWith(text.trimLeft()))
.map(([name, doc]) => ({
@@ -109,7 +107,9 @@ const getCommandCompletions = (text: string): actions.ConsoleAction => {
}
};
-const getOpenCompletions = async(types: CompletionType[], original: string, command: Command, query: string): Promise<actions.ConsoleAction> => {
+const getOpenCompletions = async(
+ types: CompletionType[], original: string, command: Command, query: string,
+): Promise<actions.SetCompletionsAction> => {
const completions: Completions = [];
for (const type of types) {
switch (type) {
@@ -155,7 +155,7 @@ const getOpenCompletions = async(types: CompletionType[], original: string, comm
};
};
-const getCompletions = async(text: string): Promise<actions.ConsoleAction> => {
+const getCompletions = async(text: string): Promise<actions.SetCompletionsAction> => {
const completions = await browser.runtime.sendMessage({
type: messages.CONSOLE_QUERY_COMPLETIONS,
text,
@@ -167,13 +167,13 @@ const getCompletions = async(text: string): Promise<actions.ConsoleAction> => {
};
};
-const completionNext = (): actions.ConsoleAction => {
+const completionNext = (): actions.CompletionNextAction => {
return {
type: actions.CONSOLE_COMPLETION_NEXT,
};
};
-const completionPrev = (): actions.ConsoleAction => {
+const completionPrev = (): actions.CompletionPrevAction => {
return {
type: actions.CONSOLE_COMPLETION_PREV,
};
diff --git a/src/console/actions/index.ts b/src/console/actions/index.ts
index 8448e04..e292608 100644
--- a/src/console/actions/index.ts
+++ b/src/console/actions/index.ts
@@ -12,50 +12,50 @@ export const CONSOLE_COMPLETION_NEXT = 'console.completion.next';
export const CONSOLE_COMPLETION_PREV = 'console.completion.prev';
export const CONSOLE_SHOW_FIND = 'console.show.find';
-interface HideAction {
+export interface HideAction {
type: typeof CONSOLE_HIDE;
}
-interface ShowCommand {
+export interface ShowCommand {
type: typeof CONSOLE_SHOW_COMMAND;
text: string;
completionTypes: CompletionType[];
}
-interface ShowFindAction {
+export interface ShowFindAction {
type: typeof CONSOLE_SHOW_FIND;
}
-interface ShowErrorAction {
+export interface ShowErrorAction {
type: typeof CONSOLE_SHOW_ERROR;
text: string;
}
-interface ShowInfoAction {
+export interface ShowInfoAction {
type: typeof CONSOLE_SHOW_INFO;
text: string;
}
-interface HideCommandAction {
+export interface HideCommandAction {
type: typeof CONSOLE_HIDE_COMMAND;
}
-interface SetConsoleTextAction {
+export interface SetConsoleTextAction {
type: typeof CONSOLE_SET_CONSOLE_TEXT;
consoleText: string;
}
-interface SetCompletionsAction {
+export interface SetCompletionsAction {
type: typeof CONSOLE_SET_COMPLETIONS;
completions: Completions;
completionSource: string;
}
-interface CompletionNextAction {
+export interface CompletionNextAction {
type: typeof CONSOLE_COMPLETION_NEXT;
}
-interface CompletionPrevAction {
+export interface CompletionPrevAction {
type: typeof CONSOLE_COMPLETION_PREV;
}
diff --git a/test/background/completion/CompletionUseCase.test.ts b/test/background/completion/CompletionUseCase.test.ts
new file mode 100644
index 0000000..0d58e45
--- /dev/null
+++ b/test/background/completion/CompletionUseCase.test.ts
@@ -0,0 +1,131 @@
+import "reflect-metadata";
+import CompletionType from "../../../src/shared/CompletionType";
+import BookmarkRepository, {BookmarkItem} from "../../../src/background/completion/BookmarkRepository";
+import HistoryRepository, {HistoryItem} from "../../../src/background/completion/HistoryRepository";
+import CompletionUseCase from "../../../src/background/completion/CompletionUseCase";
+import CachedSettingRepository from "../../../src/background/repositories/CachedSettingRepository";
+import Settings, {DefaultSetting} from "../../../src/shared/settings/Settings";
+import { expect } from 'chai';
+import sinon from 'sinon';
+import Properties from "../../../src/shared/settings/Properties";
+import Search from "../../../src/shared/settings/Search";
+
+class MockBookmarkRepository implements BookmarkRepository {
+ queryBookmarks(_query: string): Promise<BookmarkItem[]> {
+ throw new Error("not implemented")
+ }
+}
+
+class MockHistoryRepository implements HistoryRepository {
+ queryHistories(_keywords: string): Promise<HistoryItem[]> {
+ throw new Error("not implemented")
+ }
+}
+
+class MockSettingRepository implements CachedSettingRepository {
+ get(): Promise<Settings> {
+ throw new Error("not implemented")
+ }
+
+ setProperty(_name: string, _value: string | number | boolean): Promise<void> {
+ throw new Error("not implemented")
+ }
+
+ update(_value: Settings): Promise<void> {
+ throw new Error("not implemented")
+ }
+}
+
+describe('CompletionUseCase', () => {
+ let bookmarkRepository: MockBookmarkRepository;
+ let historyRepository: MockHistoryRepository;
+ let settingRepository: MockSettingRepository;
+ let sut: CompletionUseCase;
+
+ beforeEach(() => {
+ bookmarkRepository = new MockBookmarkRepository();
+ historyRepository = new MockHistoryRepository();
+ settingRepository = new MockSettingRepository();
+ sut = new CompletionUseCase(bookmarkRepository, historyRepository, settingRepository)
+ });
+
+ describe('#getCompletionTypes', () => {
+ it("returns completion types from the property", async () => {
+ sinon.stub(settingRepository, 'get').returns(Promise.resolve(new Settings({
+ keymaps: DefaultSetting.keymaps,
+ search: DefaultSetting.search,
+ properties: new Properties({ complete: "shb" }),
+ blacklist: DefaultSetting.blacklist,
+ })));
+
+ const items = await sut.getCompletionTypes();
+ expect(items).to.deep.equal([
+ CompletionType.SearchEngines,
+ CompletionType.History,
+ CompletionType.Bookmarks
+ ]);
+ });
+ });
+
+ describe('#requestSearchEngines', () => {
+ it("returns search engines matches by the query", async () => {
+ sinon.stub(settingRepository, 'get').returns(Promise.resolve(new Settings({
+ keymaps: DefaultSetting.keymaps,
+ search: new Search("google", {
+ "google": "https://google.com/search?q={}",
+ "yahoo": "https://search.yahoo.com/search?q={}",
+ "bing": "https://bing.com/search?q={}",
+ "google_ja": "https://google.co.jp/search?q={}",
+ }),
+ properties: DefaultSetting.properties,
+ blacklist: DefaultSetting.blacklist,
+ })));
+
+ expect(await sut.requestSearchEngines("")).to.deep.equal([
+ "google",
+ "yahoo",
+ "bing",
+ "google_ja",
+ ]);
+ expect(await sut.requestSearchEngines("go")).to.deep.equal([
+ "google",
+ "google_ja",
+ ]);
+ expect(await sut.requestSearchEngines("x")).to.be.empty;
+ })
+ });
+
+ describe('#requestBookmarks', () => {
+ it("returns bookmarks from the repository", async() => {
+ sinon.stub(bookmarkRepository, 'queryBookmarks')
+ .withArgs("site").returns(Promise.resolve([
+ { title: "site1", url: "https://site1.example.com" },
+ { title: "site2", url: "https://site2.example.com/" },
+ ]))
+ .withArgs("xyz").returns(Promise.resolve([]));
+
+ expect(await sut.requestBookmarks("site")).to.deep.equal([
+ { title: "site1", url: "https://site1.example.com" },
+ { title: "site2", url: "https://site2.example.com/" },
+ ]);
+ expect(await sut.requestBookmarks("xyz")).to.be.empty;
+ });
+ });
+
+ describe('#requestHistory', () => {
+ it("returns histories from the repository", async() => {
+ sinon.stub(historyRepository, 'queryHistories')
+ .withArgs("site").returns(Promise.resolve([
+ { title: "site1", url: "https://site1.example.com" },
+ { title: "site2", url: "https://site2.example.com/" },
+ ]))
+ .withArgs("xyz").returns(Promise.resolve([]));
+
+ expect(await sut.requestHistory("site")).to.deep.equal([
+ { title: "site1", url: "https://site1.example.com" },
+ { title: "site2", url: "https://site2.example.com/" },
+ ]);
+ expect(await sut.requestHistory("xyz")).to.be.empty;
+ });
+ });
+}); \ No newline at end of file
diff --git a/test/background/completion/impl/filters.test.ts b/test/background/completion/impl/filters.test.ts
new file mode 100644
index 0000000..2b15a9b
--- /dev/null
+++ b/test/background/completion/impl/filters.test.ts
@@ -0,0 +1,114 @@
+import * as filters from '../../../../src/background/completion/impl/filters'
+import { expect } from 'chai';
+
+describe('background/usecases/filters', () => {
+ describe('filterHttp', () => {
+ it('filters http URLs duplicates to https hosts', () => {
+ const pages = [
+ { id: '0', url: 'http://i-beam.org/foo' },
+ { id: '1', url: 'https://i-beam.org/bar' },
+ { id: '2', url: 'http://i-beam.net/hoge' },
+ { id: '3', url: 'http://i-beam.net/fuga' },
+ ];
+ const filtered = filters.filterHttp(pages);
+
+ const urls = filtered.map(x => x.url);
+ expect(urls).to.deep.equal([
+ 'https://i-beam.org/bar', 'http://i-beam.net/hoge', 'http://i-beam.net/fuga'
+ ]);
+ })
+ });
+
+ describe('filterBlankTitle', () => {
+ it('filters blank titles', () => {
+ const pages = [
+ { id: '0', title: 'hello' },
+ { id: '1', title: '' },
+ { id: '2' },
+ ];
+ const filtered = filters.filterBlankTitle(pages);
+
+ expect(filtered).to.deep.equal([{ id: '0', title: 'hello' }]);
+ });
+ });
+
+ describe('filterByTailingSlash', () => {
+ it('filters duplicated pathname on tailing slash', () => {
+ const pages = [
+ { id: '0', url: 'http://i-beam.org/content' },
+ { id: '1', url: 'http://i-beam.org/content/' },
+ { id: '2', url: 'http://i-beam.org/search' },
+ { id: '3', url: 'http://i-beam.org/search?q=apple_banana_cherry' },
+ ];
+ const filtered = filters.filterByTailingSlash(pages);
+
+ const urls = filtered.map(x => x.url);
+ expect(urls).to.deep.equal([
+ 'http://i-beam.org/content',
+ 'http://i-beam.org/search',
+ 'http://i-beam.org/search?q=apple_banana_cherry',
+ ]);
+ });
+ })
+
+ describe('filterByPathname', () => {
+ it('remains items less than minimam length', () => {
+ const pages = [
+ { id: '0', url: 'http://i-beam.org/search?q=apple' },
+ { id: '1', url: 'http://i-beam.org/search?q=apple_banana' },
+ { id: '2', url: 'http://i-beam.org/search?q=apple_banana_cherry' },
+ { id: '3', url: 'http://i-beam.org/request?q=apple' },
+ { id: '4', url: 'http://i-beam.org/request?q=apple_banana' },
+ { id: '5', url: 'http://i-beam.org/request?q=apple_banana_cherry' },
+ ];
+ const filtered = filters.filterByPathname(pages, 10);
+ expect(filtered).to.have.lengthOf(6);
+ });
+
+ it('filters by length of pathname', () => {
+ const pages = [
+ { id: '0', url: 'http://i-beam.org/search?q=apple' },
+ { id: '1', url: 'http://i-beam.org/search?q=apple_banana' },
+ { id: '2', url: 'http://i-beam.org/search?q=apple_banana_cherry' },
+ { id: '3', url: 'http://i-beam.net/search?q=apple' },
+ { id: '4', url: 'http://i-beam.net/search?q=apple_banana' },
+ { id: '5', url: 'http://i-beam.net/search?q=apple_banana_cherry' },
+ ];
+ const filtered = filters.filterByPathname(pages, 0);
+ expect(filtered).to.deep.equal([
+ { id: '0', url: 'http://i-beam.org/search?q=apple' },
+ { id: '3', url: 'http://i-beam.net/search?q=apple' },
+ ]);
+ });
+ });
+
+ describe('filterByOrigin', () => {
+ it('remains items less than minimam length', () => {
+ const pages = [
+ { id: '0', url: 'http://i-beam.org/search?q=apple' },
+ { id: '1', url: 'http://i-beam.org/search?q=apple_banana' },
+ { id: '2', url: 'http://i-beam.org/search?q=apple_banana_cherry' },
+ { id: '3', url: 'http://i-beam.org/request?q=apple' },
+ { id: '4', url: 'http://i-beam.org/request?q=apple_banana' },
+ { id: '5', url: 'http://i-beam.org/request?q=apple_banana_cherry' },
+ ];
+ const filtered = filters.filterByOrigin(pages, 10);
+ expect(filtered).to.have.lengthOf(6);
+ });
+
+ it('filters by length of pathname', () => {
+ const pages = [
+ { id: '0', url: 'http://i-beam.org/search?q=apple' },
+ { id: '1', url: 'http://i-beam.org/search?q=apple_banana' },
+ { id: '2', url: 'http://i-beam.org/search?q=apple_banana_cherry' },
+ { id: '3', url: 'http://i-beam.org/request?q=apple' },
+ { id: '4', url: 'http://i-beam.org/request?q=apple_banana' },
+ { id: '5', url: 'http://i-beam.org/request?q=apple_banana_cherry' },
+ ];
+ const filtered = filters.filterByOrigin(pages, 0);
+ expect(filtered).to.deep.equal([
+ { id: '0', url: 'http://i-beam.org/search?q=apple' },
+ ]);
+ });
+ });
+});
diff --git a/test/background/usecases/filters.test.ts b/test/background/usecases/filters.test.ts
deleted file mode 100644
index 90541ff..0000000
--- a/test/background/usecases/filters.test.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import * as filters from 'background/usecases/filters';
-
-describe("background/usecases/filters", () => {
- describe('filterHttp', () => {
- it('filters http URLs duplicates to https hosts', () => {
- const pages = [
- { url: 'http://i-beam.org/foo' },
- { url: 'https://i-beam.org/bar' },
- { url: 'http://i-beam.net/hoge' },
- { url: 'http://i-beam.net/fuga' },
- ];
- const filtered = filters.filterHttp(pages);
-
- const urls = filtered.map(x => x.url);
- expect(urls).to.deep.equal([
- 'https://i-beam.org/bar', 'http://i-beam.net/hoge', 'http://i-beam.net/fuga'
- ]);
- })
- });
-
- describe('filterBlankTitle', () => {
- it('filters blank titles', () => {
- const pages = [
- { title: 'hello' },
- { title: '' },
- {},
- ];
- const filtered = filters.filterBlankTitle(pages);
-
- expect(filtered).to.deep.equal([{ title: 'hello' }]);
- });
- })
-
- describe('filterByTailingSlash', () => {
- it('filters duplicated pathname on tailing slash', () => {
- const pages = [
- { url: 'http://i-beam.org/content' },
- { url: 'http://i-beam.org/content/' },
- { url: 'http://i-beam.org/search' },
- { url: 'http://i-beam.org/search?q=apple_banana_cherry' },
- ];
- const filtered = filters.filterByTailingSlash(pages);
-
- const urls = filtered.map(x => x.url);
- expect(urls).to.deep.equal([
- 'http://i-beam.org/content',
- 'http://i-beam.org/search',
- 'http://i-beam.org/search?q=apple_banana_cherry',
- ]);
- });
- })
-
- describe('filterByPathname', () => {
- it('remains items less than minimam length', () => {
- const pages = [
- { url: 'http://i-beam.org/search?q=apple' },
- { url: 'http://i-beam.org/search?q=apple_banana' },
- { url: 'http://i-beam.org/search?q=apple_banana_cherry' },
- { url: 'http://i-beam.org/request?q=apple' },
- { url: 'http://i-beam.org/request?q=apple_banana' },
- { url: 'http://i-beam.org/request?q=apple_banana_cherry' },
- ];
- const filtered = filters.filterByPathname(pages, 10);
- expect(filtered).to.have.lengthOf(6);
- });
-
- it('filters by length of pathname', () => {
- const pages = [
- { url: 'http://i-beam.org/search?q=apple' },
- { url: 'http://i-beam.org/search?q=apple_banana' },
- { url: 'http://i-beam.org/search?q=apple_banana_cherry' },
- { url: 'http://i-beam.net/search?q=apple' },
- { url: 'http://i-beam.net/search?q=apple_banana' },
- { url: 'http://i-beam.net/search?q=apple_banana_cherry' },
- ];
- const filtered = filters.filterByPathname(pages, 0);
- expect(filtered).to.deep.equal([
- { url: 'http://i-beam.org/search?q=apple' },
- { url: 'http://i-beam.net/search?q=apple' },
- ]);
- });
- })
-
- describe('filterByOrigin', () => {
- it('remains items less than minimam length', () => {
- const pages = [
- { url: 'http://i-beam.org/search?q=apple' },
- { url: 'http://i-beam.org/search?q=apple_banana' },
- { url: 'http://i-beam.org/search?q=apple_banana_cherry' },
- { url: 'http://i-beam.org/request?q=apple' },
- { url: 'http://i-beam.org/request?q=apple_banana' },
- { url: 'http://i-beam.org/request?q=apple_banana_cherry' },
- ];
- const filtered = filters.filterByOrigin(pages, 10);
- expect(filtered).to.have.lengthOf(6);
- });
-
- it('filters by length of pathname', () => {
- const pages = [
- { url: 'http://i-beam.org/search?q=apple' },
- { url: 'http://i-beam.org/search?q=apple_banana' },
- { url: 'http://i-beam.org/search?q=apple_banana_cherry' },
- { url: 'http://i-beam.org/request?q=apple' },
- { url: 'http://i-beam.org/request?q=apple_banana' },
- { url: 'http://i-beam.org/request?q=apple_banana_cherry' },
- ];
- const filtered = filters.filterByOrigin(pages, 0);
- expect(filtered).to.deep.equal([
- { url: 'http://i-beam.org/search?q=apple' },
- ]);
- });
- })
-});
diff --git a/test/console/actions/console.test.ts b/test/console/actions/console.test.ts
index 583c878..e6567b2 100644
--- a/test/console/actions/console.test.ts
+++ b/test/console/actions/console.test.ts
@@ -1,5 +1,6 @@
-import * as actions from 'console/actions';
-import * as consoleActions from 'console/actions/console';
+import * as actions from '../../../src/console/actions';
+import * as consoleActions from '../../../src/console/actions/console';
+import { expect } from 'chai';
describe("console actions", () => {
describe('hide', () => {
@@ -9,8 +10,8 @@ describe("console actions", () => {
});
});
describe("showCommand", () => {
- it('create CONSOLE_SHOW_COMMAND action', () => {
- const action = consoleActions.showCommand('hello');
+ it('create CONSOLE_SHOW_COMMAND action', async () => {
+ const action = await consoleActions.showCommand('hello');
expect(action.type).to.equal(actions.CONSOLE_SHOW_COMMAND);
expect(action.text).to.equal('hello');
});