aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shared/SettingData.ts22
-rw-r--r--src/shared/Settings.ts44
-rw-r--r--src/shared/settings/Search.ts76
-rw-r--r--src/shared/urls.ts4
-rw-r--r--test/content/repositories/SettingRepository.test.ts5
-rw-r--r--test/shared/SettingData.test.ts19
-rw-r--r--test/shared/Settings.test.ts66
-rw-r--r--test/shared/settings/Search.test.ts68
-rw-r--r--test/shared/urls.test.ts8
9 files changed, 182 insertions, 130 deletions
diff --git a/src/shared/SettingData.ts b/src/shared/SettingData.ts
index eb83b75..6605c80 100644
--- a/src/shared/SettingData.ts
+++ b/src/shared/SettingData.ts
@@ -1,6 +1,7 @@
import * as operations from './operations';
import Settings, * as settings from './Settings';
import Keymaps from './settings/Keymaps';
+import Search from './settings/Search';
export class FormKeymaps {
private data: {[op: string]: string};
@@ -71,15 +72,12 @@ export class FormSearch {
this.engines = engines;
}
- toSearchSettings(): settings.Search {
- return {
- default: this.default,
- engines: this.engines.reduce(
- (o: {[key: string]: string}, [name, url]) => {
- o[name] = url;
- return o;
- }, {}),
- };
+ toSearchSettings(): Search {
+ let engines: { [name: string]: string } = {};
+ for (let entry of this.engines) {
+ engines[entry[0]] = entry[1];
+ }
+ return new Search(this.default, engines);
}
toJSON(): {
@@ -102,12 +100,12 @@ export class FormSearch {
return new FormSearch(o.default, o.engines);
}
- static fromSearch(search: settings.Search): FormSearch {
+ static fromSearch(search: Search): FormSearch {
let engines = Object.entries(search.engines).reduce(
(o: string[][], [name, url]) => {
return o.concat([[name, url]]);
}, []);
- return new FormSearch(search.default, engines);
+ return new FormSearch(search.defaultEngine, engines);
}
}
@@ -200,7 +198,7 @@ export class FormSettings {
toSettings(): Settings {
return settings.valueOf({
keymaps: this.keymaps.toKeymaps().toJSON(),
- search: this.search.toSearchSettings(),
+ search: this.search.toSearchSettings().toJSON(),
properties: this.properties,
blacklist: this.blacklist,
});
diff --git a/src/shared/Settings.ts b/src/shared/Settings.ts
index 3014abc..e2bb3f4 100644
--- a/src/shared/Settings.ts
+++ b/src/shared/Settings.ts
@@ -1,10 +1,6 @@
import * as PropertyDefs from './property-defs';
import Keymaps from './settings/Keymaps';
-
-export interface Search {
- default: string;
- engines: { [key: string]: string };
-}
+import Search from './settings/Search';
export interface Properties {
hintchars: string;
@@ -19,36 +15,6 @@ export default interface Settings {
blacklist: string[];
}
-export const searchValueOf = (o: any): Search => {
- if (typeof o.default !== 'string') {
- throw new TypeError('string field "default" not set"');
- }
- for (let name of Object.keys(o.engines)) {
- if ((/\s/).test(name)) {
- throw new TypeError(
- `While space in the search engine not allowed: "${name}"`);
- }
- let url = o.engines[name];
- if (typeof url !== 'string') {
- throw new TypeError('"engines" not an object of string');
- }
- let matches = url.match(/{}/g);
- if (matches === null) {
- throw new TypeError(`No {}-placeholders in URL of "${name}"`);
- } else if (matches.length > 1) {
- throw new TypeError(`Multiple {}-placeholders in URL of "${name}"`);
- }
-
- }
- if (!Object.prototype.hasOwnProperty.call(o.engines, o.default)) {
- throw new TypeError(`Default engine "${o.default}" not found`);
- }
- return {
- default: o.default as string,
- engines: { ...o.engines },
- };
-};
-
export const propertiesValueOf = (o: any): Properties => {
let defNames = new Set(PropertyDefs.defs.map(def => def.name));
let unknownName = Object.keys(o).find(name => !defNames.has(name));
@@ -90,7 +56,7 @@ export const valueOf = (o: any): Settings => {
settings.keymaps = Keymaps.fromJSON(o.keymaps);
break;
case 'search':
- settings.search = searchValueOf(o.search);
+ settings.search = Search.fromJSON(o.search);
break;
case 'properties':
settings.properties = propertiesValueOf(o.properties);
@@ -108,7 +74,7 @@ export const valueOf = (o: any): Settings => {
export const toJSON = (settings: Settings): any => {
return {
keymaps: settings.keymaps.toJSON(),
- search: settings.search,
+ search: settings.search.toJSON(),
properties: settings.properties,
blacklist: settings.blacklist,
};
@@ -179,7 +145,7 @@ export const DefaultSetting: Settings = {
'.': { 'type': 'repeat.last' },
'<S-Esc>': { 'type': 'addon.toggle.enabled' }
}),
- search: {
+ search: Search.fromJSON({
default: 'google',
engines: {
'google': 'https://google.com/search?q={}',
@@ -189,7 +155,7 @@ export const DefaultSetting: Settings = {
'twitter': 'https://twitter.com/search?q={}',
'wikipedia': 'https://en.wikipedia.org/w/index.php?search={}'
}
- },
+ }),
properties: {
hintchars: 'abcdefghijklmnopqrstuvwxyz',
smoothscroll: false,
diff --git a/src/shared/settings/Search.ts b/src/shared/settings/Search.ts
new file mode 100644
index 0000000..4580236
--- /dev/null
+++ b/src/shared/settings/Search.ts
@@ -0,0 +1,76 @@
+type Entries = { [name: string]: string };
+
+export type SearchJSON = {
+ default: string;
+ engines: { [key: string]: string };
+};
+
+export default class Search {
+ constructor(
+ public defaultEngine: string,
+ public engines: Entries,
+ ) {
+ }
+
+ static fromJSON(json: any): Search {
+ let defaultEngine = Search.getStringField(json, 'default');
+ let engines = Search.getObjectField(json, 'engines');
+
+ for (let [name, url] of Object.entries(engines)) {
+ if ((/\s/).test(name)) {
+ throw new TypeError(
+ `While space in the search engine not allowed: "${name}"`);
+ }
+ if (typeof url !== 'string') {
+ throw new TypeError(
+ `Invalid type of value in filed "engines": ${JSON.stringify(json)}`);
+ }
+ let matches = url.match(/{}/g);
+ if (matches === null) {
+ throw new TypeError(`No {}-placeholders in URL of "${name}"`);
+ } else if (matches.length > 1) {
+ throw new TypeError(`Multiple {}-placeholders in URL of "${name}"`);
+ }
+ }
+
+ if (!Object.keys(engines).includes(defaultEngine)) {
+ throw new TypeError(`Default engine "${defaultEngine}" not found`);
+ }
+
+ return new Search(
+ json.default as string,
+ json.engines,
+ );
+ }
+
+ toJSON(): SearchJSON {
+ return {
+ default: this.defaultEngine,
+ engines: this.engines,
+ };
+ }
+
+ private static getStringField(json: any, name: string): string {
+ if (!Object.prototype.hasOwnProperty.call(json, name)) {
+ throw new TypeError(
+ `missing field "${name}" on search: ${JSON.stringify(json)}`);
+ }
+ if (typeof json[name] !== 'string') {
+ throw new TypeError(
+ `invalid type of filed "${name}" on search: ${JSON.stringify(json)}`);
+ }
+ return json[name];
+ }
+
+ private static getObjectField(json: any, name: string): Object {
+ if (!Object.prototype.hasOwnProperty.call(json, name)) {
+ throw new TypeError(
+ `missing field "${name}" on search: ${JSON.stringify(json)}`);
+ }
+ if (typeof json[name] !== 'object' || json[name] === null) {
+ throw new TypeError(
+ `invalid type of filed "${name}" on search: ${JSON.stringify(json)}`);
+ }
+ return json[name];
+ }
+}
diff --git a/src/shared/urls.ts b/src/shared/urls.ts
index bbdb1ea..64ea4f2 100644
--- a/src/shared/urls.ts
+++ b/src/shared/urls.ts
@@ -1,4 +1,4 @@
-import { Search } from './Settings';
+import Search from './settings/Search';
const trimStart = (str: string): string => {
// NOTE String.trimStart is available on Firefox 61
@@ -19,7 +19,7 @@ const searchUrl = (keywords: string, search: Search): string => {
if (keywords.includes('.') && !keywords.includes(' ')) {
return 'http://' + keywords;
}
- let template = search.engines[search.default];
+ let template = search.engines[search.defaultEngine];
let query = keywords;
let first = trimStart(keywords).split(' ')[0];
diff --git a/test/content/repositories/SettingRepository.test.ts b/test/content/repositories/SettingRepository.test.ts
index 457ca4c..363fcec 100644
--- a/test/content/repositories/SettingRepository.test.ts
+++ b/test/content/repositories/SettingRepository.test.ts
@@ -1,6 +1,7 @@
import { SettingRepositoryImpl } from '../../../src/content/repositories/SettingRepository';
import { expect } from 'chai';
import Keymaps from '../../../src/shared/settings/Keymaps';
+import Search from '../../../src/shared/settings/Search';
describe('SettingRepositoryImpl', () => {
it('updates and gets current value', () => {
@@ -8,12 +9,12 @@ describe('SettingRepositoryImpl', () => {
let settings = {
keymaps: Keymaps.fromJSON({}),
- search: {
+ search: Search.fromJSON({
default: 'google',
engines: {
google: 'https://google.com/?q={}',
}
- },
+ }),
properties: {
hintchars: 'abcd1234',
smoothscroll: false,
diff --git a/test/shared/SettingData.test.ts b/test/shared/SettingData.test.ts
index 9567f76..f8995d9 100644
--- a/test/shared/SettingData.test.ts
+++ b/test/shared/SettingData.test.ts
@@ -4,6 +4,7 @@ import SettingData, {
import Settings from '../../src/shared/Settings';
import { expect } from 'chai';
import Keymaps from '../../src/shared/settings/Keymaps';
+import Search from '../../src/shared/settings/Search';
describe('shared/SettingData', () => {
describe('FormKeymaps', () => {
@@ -60,7 +61,7 @@ describe('shared/SettingData', () => {
let settings = JSONTextSettings.fromText(o).toSettings();
expect({
keymaps: settings.keymaps.toJSON(),
- search: settings.search,
+ search: settings.search.toJSON(),
properties: settings.properties,
blacklist: settings.blacklist,
}).to.deep.equal(JSON.parse(o));
@@ -71,12 +72,12 @@ describe('shared/SettingData', () => {
it('create from a Settings and create a JSON string', () => {
let o = {
keymaps: Keymaps.fromJSON({}),
- search: {
+ search: Search.fromJSON({
default: "google",
engines: {
google: "https://google.com/search?q={}",
},
- },
+ }),
properties: {
hintchars: "abcdefghijklmnopqrstuvwxyz",
smoothscroll: false,
@@ -88,7 +89,7 @@ describe('shared/SettingData', () => {
let json = JSONTextSettings.fromSettings(o).toJSONText();
expect(JSON.parse(json)).to.deep.equal({
keymaps: o.keymaps.toJSON(),
- search: o.search,
+ search: o.search.toJSON(),
properties: o.properties,
blacklist: o.blacklist,
});
@@ -121,7 +122,7 @@ describe('shared/SettingData', () => {
let settings = FormSettings.valueOf(data).toSettings();
expect({
keymaps: settings.keymaps.toJSON(),
- search: settings.search,
+ search: settings.search.toJSON(),
properties: settings.properties,
blacklist: settings.blacklist,
}).to.deep.equal({
@@ -152,12 +153,12 @@ describe('shared/SettingData', () => {
'j': { type: 'scroll.vertically', count: 1 },
'0': { type: 'scroll.home' },
}),
- search: {
+ search: Search.fromJSON({
default: "google",
engines: {
"google": "https://google.com/search?q={}"
}
- },
+ }),
properties: {
hintchars: "abcdefghijklmnopqrstuvwxyz",
smoothscroll: false,
@@ -278,7 +279,7 @@ describe('shared/SettingData', () => {
};
let settings = SettingData.valueOf(data).toSettings();
- expect(settings.search.default).to.equal('google');
+ expect(settings.search.defaultEngine).to.equal('google');
});
it('parse object from form source', () => {
@@ -302,7 +303,7 @@ describe('shared/SettingData', () => {
};
let settings = SettingData.valueOf(data).toSettings();
- expect(settings.search.default).to.equal('yahoo');
+ expect(settings.search.defaultEngine).to.equal('yahoo');
});
});
});
diff --git a/test/shared/Settings.test.ts b/test/shared/Settings.test.ts
index 9faf9d1..ed791a1 100644
--- a/test/shared/Settings.test.ts
+++ b/test/shared/Settings.test.ts
@@ -1,67 +1,7 @@
import * as settings from '../../src/shared/Settings';
-import {expect} from 'chai';
+import { expect } from 'chai';
describe('Settings', () => {
- describe('#searchValueOf', () => {
- it('returns search settings by valid settings', () => {
- let search = settings.searchValueOf({
- default: "google",
- engines: {
- "google": "https://google.com/search?q={}",
- "yahoo": "https://search.yahoo.com/search?p={}",
- }
- });
-
- expect(search).to.deep.equal({
- default: "google",
- engines: {
- "google": "https://google.com/search?q={}",
- "yahoo": "https://search.yahoo.com/search?p={}",
- }
- });
- });
-
- it('throws a TypeError by invalid settings', () => {
- expect(() => settings.searchValueOf(null)).to.throw(TypeError);
- expect(() => settings.searchValueOf({})).to.throw(TypeError);
- expect(() => settings.searchValueOf([])).to.throw(TypeError);
- expect(() => settings.searchValueOf({
- default: 123,
- engines: {}
- })).to.throw(TypeError);
- expect(() => settings.searchValueOf({
- default: "google",
- engines: {
- "google": 123456,
- }
- })).to.throw(TypeError);
- expect(() => settings.searchValueOf({
- default: "wikipedia",
- engines: {
- "google": "https://google.com/search?q={}",
- "yahoo": "https://search.yahoo.com/search?p={}",
- }
- })).to.throw(TypeError);
- expect(() => settings.searchValueOf({
- default: "g o o g l e",
- engines: {
- "g o o g l e": "https://google.com/search?q={}",
- }
- })).to.throw(TypeError);
- expect(() => settings.searchValueOf({
- default: "google",
- engines: {
- "google": "https://google.com/search",
- }
- })).to.throw(TypeError);
- expect(() => settings.searchValueOf({
- default: "google",
- engines: {
- "google": "https://google.com/search?q={}&r={}",
- }
- })).to.throw(TypeError);
- });
- });
describe('#propertiesValueOf', () => {
it('returns with default properties by empty settings', () => {
@@ -129,7 +69,7 @@ describe('Settings', () => {
expect({
keymaps: x.keymaps.toJSON(),
- search: x.search,
+ search: x.search.toJSON(),
properties: x.properties,
blacklist: x.blacklist,
}).to.deep.equal({
@@ -153,7 +93,7 @@ describe('Settings', () => {
let value = settings.valueOf({});
expect(value.keymaps.toJSON()).to.not.be.empty;
expect(value.properties).to.not.be.empty;
- expect(value.search.default).to.be.a('string');
+ expect(value.search.defaultEngine).to.be.a('string');
expect(value.search.engines).to.be.an('object');
expect(value.blacklist).to.be.empty;
});
diff --git a/test/shared/settings/Search.test.ts b/test/shared/settings/Search.test.ts
new file mode 100644
index 0000000..7c9134d
--- /dev/null
+++ b/test/shared/settings/Search.test.ts
@@ -0,0 +1,68 @@
+import Search from '../../../src/shared/settings/Search';
+import { expect } from 'chai';
+
+describe('Search', () => {
+ it('returns search settings by valid settings', () => {
+ let search = Search.fromJSON({
+ default: 'google',
+ engines: {
+ 'google': 'https://google.com/search?q={}',
+ 'yahoo': 'https://search.yahoo.com/search?p={}',
+ }
+ });
+
+ expect(search.defaultEngine).to.equal('google')
+ expect(search.engines).to.deep.equals({
+ 'google': 'https://google.com/search?q={}',
+ 'yahoo': 'https://search.yahoo.com/search?p={}',
+ });
+ expect(search.toJSON()).to.deep.equal({
+ default: 'google',
+ engines: {
+ 'google': 'https://google.com/search?q={}',
+ 'yahoo': 'https://search.yahoo.com/search?p={}',
+ }
+ });
+ });
+
+ it('throws a TypeError by invalid settings', () => {
+ expect(() => Search.fromJSON(null)).to.throw(TypeError);
+ expect(() => Search.fromJSON({})).to.throw(TypeError);
+ expect(() => Search.fromJSON([])).to.throw(TypeError);
+ expect(() => Search.fromJSON({
+ default: 123,
+ engines: {}
+ })).to.throw(TypeError);
+ expect(() => Search.fromJSON({
+ default: 'google',
+ engines: {
+ 'google': 123456,
+ }
+ })).to.throw(TypeError);
+ expect(() => Search.fromJSON({
+ default: 'wikipedia',
+ engines: {
+ 'google': 'https://google.com/search?q={}',
+ 'yahoo': 'https://search.yahoo.com/search?p={}',
+ }
+ })).to.throw(TypeError);
+ expect(() => Search.fromJSON({
+ default: 'g o o g l e',
+ engines: {
+ 'g o o g l e': 'https://google.com/search?q={}',
+ }
+ })).to.throw(TypeError);
+ expect(() => Search.fromJSON({
+ default: 'google',
+ engines: {
+ 'google': 'https://google.com/search',
+ }
+ })).to.throw(TypeError);
+ expect(() => Search.fromJSON({
+ default: 'google',
+ engines: {
+ 'google': 'https://google.com/search?q={}&r={}',
+ }
+ })).to.throw(TypeError);
+ });
+});
diff --git a/test/shared/urls.test.ts b/test/shared/urls.test.ts
index f2950b6..3a3eea6 100644
--- a/test/shared/urls.test.ts
+++ b/test/shared/urls.test.ts
@@ -1,14 +1,16 @@
-import * as parsers from 'shared/urls';
+import * as parsers from '../../src/shared/urls';
+import { expect } from 'chai';
+import Search from '../../src/shared/settings/Search';
describe("shared/commands/parsers", () => {
describe('#searchUrl', () => {
- const config = {
+ const config = Search.fromJSON({
default: 'google',
engines: {
google: 'https://google.com/search?q={}',
yahoo: 'https://yahoo.com/search?q={}',
}
- };
+ });
it('convertes search url', () => {
expect(parsers.searchUrl('google.com', config))