aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShin'ya UEOKA <ueokande@i-beam.org>2019-10-05 02:06:02 +0000
committerShin'ya UEOKA <ueokande@i-beam.org>2019-10-06 12:58:59 +0000
commit574692551a27ea56660bf2061daeaa0d34beaff4 (patch)
tree414a7f1de8dfb24af45d7e392b72549bc67ad48a
parent2116ac90a6dfdb0910d7ad2896f70a052aa635cc (diff)
Make Properties class
-rw-r--r--src/background/repositories/SettingRepository.ts4
-rw-r--r--src/background/usecases/CompletionsUseCase.ts4
-rw-r--r--src/background/usecases/parsers.ts4
-rw-r--r--src/settings/components/form/PropertiesForm.tsx6
-rw-r--r--src/settings/components/index.tsx13
-rw-r--r--src/shared/SettingData.ts15
-rw-r--r--src/shared/Settings.ts37
-rw-r--r--src/shared/properties.ts50
-rw-r--r--src/shared/property-defs.ts56
-rw-r--r--src/shared/settings/Properties.ts110
-rw-r--r--test/settings/components/form/PropertiesForm.test.tsx4
-rw-r--r--test/shared/SettingData.test.ts15
-rw-r--r--test/shared/Settings.test.ts31
-rw-r--r--test/shared/properties.test.js18
-rw-r--r--test/shared/property-defs.test.js18
-rw-r--r--test/shared/settings/Properties.test.ts30
16 files changed, 179 insertions, 236 deletions
diff --git a/src/background/repositories/SettingRepository.ts b/src/background/repositories/SettingRepository.ts
index c7a0e84..a11b65f 100644
--- a/src/background/repositories/SettingRepository.ts
+++ b/src/background/repositories/SettingRepository.ts
@@ -1,7 +1,7 @@
import { injectable } from 'tsyringe';
import MemoryStorage from '../infrastructures/MemoryStorage';
import Settings, { valueOf, toJSON } from '../../shared/Settings';
-import * as PropertyDefs from '../../shared/property-defs';
+import Properties from '../../shared/settings/Properties';
const CACHED_SETTING_KEY = 'setting';
@@ -26,7 +26,7 @@ export default class SettingRepository {
async setProperty(
name: string, value: string | number | boolean,
): Promise<void> {
- let def = PropertyDefs.defs.find(d => name === d.name);
+ let def = Properties.def(name);
if (!def) {
throw new Error('unknown property: ' + name);
}
diff --git a/src/background/usecases/CompletionsUseCase.ts b/src/background/usecases/CompletionsUseCase.ts
index 8cd4f32..bfff1e6 100644
--- a/src/background/usecases/CompletionsUseCase.ts
+++ b/src/background/usecases/CompletionsUseCase.ts
@@ -5,7 +5,7 @@ import CompletionsRepository from '../repositories/CompletionsRepository';
import * as filters from './filters';
import SettingRepository from '../repositories/SettingRepository';
import TabPresenter from '../presenters/TabPresenter';
-import * as PropertyDefs from '../../shared/property-defs';
+import Properties from '../../shared/settings/Properties';
const COMPLETION_ITEM_LIMIT = 10;
@@ -129,7 +129,7 @@ export default class CompletionsUseCase {
}
querySet(name: string, keywords: string): Promise<CompletionGroup[]> {
- let items = PropertyDefs.defs.map((def) => {
+ let items = Properties.defs().map((def) => {
if (def.type === 'boolean') {
return [
{
diff --git a/src/background/usecases/parsers.ts b/src/background/usecases/parsers.ts
index 6135fd8..e8a1149 100644
--- a/src/background/usecases/parsers.ts
+++ b/src/background/usecases/parsers.ts
@@ -1,4 +1,4 @@
-import * as PropertyDefs from '../../shared//property-defs';
+import Properties from '../../shared/settings/Properties';
const mustNumber = (v: any): number => {
let num = Number(v);
@@ -16,7 +16,7 @@ const parseSetOption = (
value = !key.startsWith('no');
key = value ? key : key.slice(2);
}
- let def = PropertyDefs.defs.find(d => d.name === key);
+ let def = Properties.def(key);
if (!def) {
throw new Error('Unknown property: ' + key);
}
diff --git a/src/settings/components/form/PropertiesForm.tsx b/src/settings/components/form/PropertiesForm.tsx
index ee98b7e..db8c8e5 100644
--- a/src/settings/components/form/PropertiesForm.tsx
+++ b/src/settings/components/form/PropertiesForm.tsx
@@ -18,7 +18,7 @@ class PropertiesForm extends React.Component<Props> {
render() {
let types = this.props.types;
- let value = this.props.value;
+ let values = this.props.value;
return <div className='form-properties-form'>
{
@@ -46,10 +46,10 @@ class PropertiesForm extends React.Component<Props> {
<span className='column-name'>{name}</span>
<input type={inputType} name={name}
className='column-input'
- value={value[name] ? value[name] : ''}
+ value={values[name] ? values[name] : ''}
onChange={onChange}
onBlur={this.props.onBlur}
- checked={value[name]}
+ checked={values[name]}
/>
</label>
</div>;
diff --git a/src/settings/components/index.tsx b/src/settings/components/index.tsx
index ada6efb..e86d765 100644
--- a/src/settings/components/index.tsx
+++ b/src/settings/components/index.tsx
@@ -8,11 +8,11 @@ import BlacklistForm from './form/BlacklistForm';
import PropertiesForm from './form/PropertiesForm';
import * as settingActions from '../../settings/actions/setting';
import SettingData, {
- JSONTextSettings, FormKeymaps, FormSearch, FormSettings,
+ FormKeymaps, FormSearch, FormSettings, JSONTextSettings,
} from '../../shared/SettingData';
import { State as AppState } from '../reducers/setting';
import * as settings from '../../shared/Settings';
-import * as PropertyDefs from '../../shared/property-defs';
+import Properties from '../../shared/settings/Properties';
const DO_YOU_WANT_TO_CONTINUE =
'Some settings in JSON can be lost when migrating. ' +
@@ -33,11 +33,6 @@ class SettingsComponent extends React.Component<Props> {
}
renderFormFields(form: any) {
- let types = PropertyDefs.defs.reduce(
- (o: {[key: string]: string}, def) => {
- o[def.name] = def.type;
- return o;
- }, {});
return <div>
<fieldset>
<legend>Keybindings</legend>
@@ -66,7 +61,7 @@ class SettingsComponent extends React.Component<Props> {
<fieldset>
<legend>Properties</legend>
<PropertiesForm
- types={types}
+ types={Properties.types()}
value={form.properties}
onChange={this.bindPropertiesForm.bind(this)}
onBlur={this.save.bind(this)}
@@ -157,7 +152,7 @@ class SettingsComponent extends React.Component<Props> {
let data = new SettingData({
source: this.props.source,
form: (this.props.form as FormSettings).buildWithProperties(
- settings.propertiesValueOf(value)),
+ Properties.fromJSON(value))
});
this.props.dispatch(settingActions.set(data));
}
diff --git a/src/shared/SettingData.ts b/src/shared/SettingData.ts
index 6605c80..aa4e382 100644
--- a/src/shared/SettingData.ts
+++ b/src/shared/SettingData.ts
@@ -2,6 +2,7 @@ import * as operations from './operations';
import Settings, * as settings from './Settings';
import Keymaps from './settings/Keymaps';
import Search from './settings/Search';
+import Properties from './settings/Properties';
export class FormKeymaps {
private data: {[op: string]: string};
@@ -143,14 +144,14 @@ export class FormSettings {
private search: FormSearch;
- private properties: settings.Properties;
+ private properties: Properties;
private blacklist: string[];
constructor(
keymaps: FormKeymaps,
search: FormSearch,
- properties: settings.Properties,
+ properties: Properties,
blacklist: string[],
) {
this.keymaps = keymaps;
@@ -177,7 +178,7 @@ export class FormSettings {
);
}
- buildWithProperties(props: settings.Properties): FormSettings {
+ buildWithProperties(props: Properties): FormSettings {
return new FormSettings(
this.keymaps,
this.search,
@@ -199,7 +200,7 @@ export class FormSettings {
return settings.valueOf({
keymaps: this.keymaps.toKeymaps().toJSON(),
search: this.search.toSearchSettings().toJSON(),
- properties: this.properties,
+ properties: this.properties.toJSON(),
blacklist: this.blacklist,
});
}
@@ -207,13 +208,13 @@ export class FormSettings {
toJSON(): {
keymaps: ReturnType<FormKeymaps['toJSON']>;
search: ReturnType<FormSearch['toJSON']>;
- properties: settings.Properties;
+ properties: ReturnType<Properties['toJSON']>;
blacklist: string[];
} {
return {
keymaps: this.keymaps.toJSON(),
search: this.search.toJSON(),
- properties: this.properties,
+ properties: this.properties.toJSON(),
blacklist: this.blacklist,
};
}
@@ -227,7 +228,7 @@ export class FormSettings {
return new FormSettings(
FormKeymaps.valueOf(o.keymaps),
FormSearch.valueOf(o.search),
- settings.propertiesValueOf(o.properties),
+ Properties.fromJSON(o.properties),
settings.blacklistValueOf(o.blacklist),
);
}
diff --git a/src/shared/Settings.ts b/src/shared/Settings.ts
index e2bb3f4..6250aae 100644
--- a/src/shared/Settings.ts
+++ b/src/shared/Settings.ts
@@ -1,12 +1,6 @@
-import * as PropertyDefs from './property-defs';
import Keymaps from './settings/Keymaps';
import Search from './settings/Search';
-
-export interface Properties {
- hintchars: string;
- smoothscroll: boolean;
- complete: string;
-}
+import Properties from './settings/Properties';
export default interface Settings {
keymaps: Keymaps;
@@ -15,27 +9,6 @@ export default interface Settings {
blacklist: string[];
}
-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));
- if (unknownName) {
- throw new TypeError(`Unknown property name: "${unknownName}"`);
- }
-
- for (let def of PropertyDefs.defs) {
- if (!Object.prototype.hasOwnProperty.call(o, def.name)) {
- continue;
- }
- if (typeof o[def.name] !== def.type) {
- throw new TypeError(`property "${def.name}" is not ${def.type}`);
- }
- }
- return {
- ...PropertyDefs.defaultValues,
- ...o,
- };
-};
-
export const blacklistValueOf = (o: any): string[] => {
if (!Array.isArray(o)) {
throw new TypeError(`"blacklist" is not an array of string`);
@@ -59,7 +32,7 @@ export const valueOf = (o: any): Settings => {
settings.search = Search.fromJSON(o.search);
break;
case 'properties':
- settings.properties = propertiesValueOf(o.properties);
+ settings.properties = Properties.fromJSON(o.properties);
break;
case 'blacklist':
settings.blacklist = blacklistValueOf(o.blacklist);
@@ -75,7 +48,7 @@ export const toJSON = (settings: Settings): any => {
return {
keymaps: settings.keymaps.toJSON(),
search: settings.search.toJSON(),
- properties: settings.properties,
+ properties: settings.properties.toJSON(),
blacklist: settings.blacklist,
};
};
@@ -156,10 +129,10 @@ export const DefaultSetting: Settings = {
'wikipedia': 'https://en.wikipedia.org/w/index.php?search={}'
}
}),
- properties: {
+ properties: Properties.fromJSON({
hintchars: 'abcdefghijklmnopqrstuvwxyz',
smoothscroll: false,
complete: 'sbh'
- },
+ }),
blacklist: []
};
diff --git a/src/shared/properties.ts b/src/shared/properties.ts
deleted file mode 100644
index 6315030..0000000
--- a/src/shared/properties.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-export type Type = string | number | boolean;
-
-export class Def {
- private name0: string;
-
- private description0: string;
-
- private defaultValue0: Type;
-
- constructor(
- name: string,
- description: string,
- defaultValue: Type,
- ) {
- this.name0 = name;
- this.description0 = description;
- this.defaultValue0 = defaultValue;
- }
-
- public get name(): string {
- return this.name0;
- }
-
- public get defaultValue(): Type {
- return this.defaultValue0;
- }
-
- public get description(): Type {
- return this.description0;
- }
-
- public get type(): string {
- return typeof this.defaultValue;
- }
-}
-
-export const defs: Def[] = [
- new Def(
- 'hintchars',
- 'hint characters on follow mode',
- 'abcdefghijklmnopqrstuvwxyz'),
- new Def(
- 'smoothscroll',
- 'smooth scroll',
- false),
- new Def(
- 'complete',
- 'which are completed at the open page',
- 'sbh'),
-];
diff --git a/src/shared/property-defs.ts b/src/shared/property-defs.ts
deleted file mode 100644
index fec9f80..0000000
--- a/src/shared/property-defs.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-export type Type = string | number | boolean;
-
-export class Def {
- private name0: string;
-
- private description0: string;
-
- private defaultValue0: Type;
-
- constructor(
- name: string,
- description: string,
- defaultValue: Type,
- ) {
- this.name0 = name;
- this.description0 = description;
- this.defaultValue0 = defaultValue;
- }
-
- public get name(): string {
- return this.name0;
- }
-
- public get defaultValue(): Type {
- return this.defaultValue0;
- }
-
- public get description(): Type {
- return this.description0;
- }
-
- public get type(): string {
- return typeof this.defaultValue;
- }
-}
-
-export const defs: Def[] = [
- new Def(
- 'hintchars',
- 'hint characters on follow mode',
- 'abcdefghijklmnopqrstuvwxyz'),
- new Def(
- 'smoothscroll',
- 'smooth scroll',
- false),
- new Def(
- 'complete',
- 'which are completed at the open page',
- 'sbh'),
-];
-
-export const defaultValues = {
- hintchars: 'abcdefghijklmnopqrstuvwxyz',
- smoothscroll: false,
- complete: 'sbh',
-};
diff --git a/src/shared/settings/Properties.ts b/src/shared/settings/Properties.ts
new file mode 100644
index 0000000..1bc4c7f
--- /dev/null
+++ b/src/shared/settings/Properties.ts
@@ -0,0 +1,110 @@
+export type PropertiesJSON = {
+ hintchars?: string;
+ smoothscroll?: boolean;
+ complete?: string;
+};
+
+export type PropertyTypes = {
+ hintchars: string;
+ smoothscroll: string;
+ complete: string;
+};
+
+type PropertyName = 'hintchars' | 'smoothscroll' | 'complete';
+
+type PropertyDef = {
+ name: PropertyName;
+ description: string;
+ defaultValue: string | number | boolean;
+ type: 'string' | 'number' | 'boolean';
+};
+
+const defs: PropertyDef[] = [
+ {
+ name: 'hintchars',
+ description: 'hint characters on follow mode',
+ defaultValue: 'abcdefghijklmnopqrstuvwxyz',
+ type: 'string',
+ }, {
+ name: 'smoothscroll',
+ description: 'smooth scroll',
+ defaultValue: false,
+ type: 'boolean',
+ }, {
+ name: 'complete',
+ description: 'which are completed at the open page',
+ defaultValue: 'sbh',
+ type: 'string',
+ }
+];
+
+const defaultValues = {
+ hintchars: 'abcdefghijklmnopqrstuvwxyz',
+ smoothscroll: false,
+ complete: 'sbh',
+};
+
+export default class Properties {
+ public hintchars: string;
+
+ public smoothscroll: boolean;
+
+ public complete: string;
+
+ constructor({
+ hintchars,
+ smoothscroll,
+ complete,
+ }: {
+ hintchars?: string;
+ smoothscroll?: boolean;
+ complete?: string;
+ }) {
+ this.hintchars = hintchars || defaultValues.hintchars;
+ this.smoothscroll = smoothscroll || defaultValues.smoothscroll;
+ this.complete = complete || defaultValues.complete;
+ }
+
+ static fromJSON(json: any): Properties {
+ let defNames: Set<string> = new Set(defs.map(def => def.name));
+ let unknownName = Object.keys(json).find(name => !defNames.has(name));
+ if (unknownName) {
+ throw new TypeError(`Unknown property name: "${unknownName}"`);
+ }
+
+ for (let def of defs) {
+ if (!Object.prototype.hasOwnProperty.call(json, def.name)) {
+ continue;
+ }
+ if (typeof json[def.name] !== def.type) {
+ throw new TypeError(
+ `property "${def.name}" is not ${def.type}`);
+ }
+ }
+ return new Properties(json);
+ }
+
+ static types(): PropertyTypes {
+ return {
+ hintchars: 'string',
+ smoothscroll: 'boolean',
+ complete: 'string',
+ };
+ }
+
+ static def(name: string): PropertyDef | undefined {
+ return defs.find(p => p.name === name);
+ }
+
+ static defs(): PropertyDef[] {
+ return defs;
+ }
+
+ toJSON(): PropertiesJSON {
+ return {
+ hintchars: this.hintchars,
+ smoothscroll: this.smoothscroll,
+ complete: this.complete,
+ };
+ }
+}
diff --git a/test/settings/components/form/PropertiesForm.test.tsx b/test/settings/components/form/PropertiesForm.test.tsx
index 80f60d2..0e33cc8 100644
--- a/test/settings/components/form/PropertiesForm.test.tsx
+++ b/test/settings/components/form/PropertiesForm.test.tsx
@@ -13,14 +13,14 @@ describe("settings/form/PropertiesForm", () => {
mybool: 'boolean',
empty: 'string',
}
- let value = {
+ let values = {
mystr: 'abc',
mynum: 123,
mybool: true,
};
let root = ReactTestRenderer.create(
- <PropertiesForm types={types} value={value} />,
+ <PropertiesForm types={types} value={values} />,
).root
let input = root.findByProps({ name: 'mystr' });
diff --git a/test/shared/SettingData.test.ts b/test/shared/SettingData.test.ts
index f8995d9..b5bf70e 100644
--- a/test/shared/SettingData.test.ts
+++ b/test/shared/SettingData.test.ts
@@ -5,6 +5,7 @@ import Settings from '../../src/shared/Settings';
import { expect } from 'chai';
import Keymaps from '../../src/shared/settings/Keymaps';
import Search from '../../src/shared/settings/Search';
+import Properties from '../../src/shared/settings/Properties';
describe('shared/SettingData', () => {
describe('FormKeymaps', () => {
@@ -62,7 +63,7 @@ describe('shared/SettingData', () => {
expect({
keymaps: settings.keymaps.toJSON(),
search: settings.search.toJSON(),
- properties: settings.properties,
+ properties: settings.properties.toJSON(),
blacklist: settings.blacklist,
}).to.deep.equal(JSON.parse(o));
});
@@ -78,11 +79,11 @@ describe('shared/SettingData', () => {
google: "https://google.com/search?q={}",
},
}),
- properties: {
+ properties: Properties.fromJSON({
hintchars: "abcdefghijklmnopqrstuvwxyz",
smoothscroll: false,
complete: "sbh"
- },
+ }),
blacklist: [],
};
@@ -90,7 +91,7 @@ describe('shared/SettingData', () => {
expect(JSON.parse(json)).to.deep.equal({
keymaps: o.keymaps.toJSON(),
search: o.search.toJSON(),
- properties: o.properties,
+ properties: o.properties.toJSON(),
blacklist: o.blacklist,
});
});
@@ -123,7 +124,7 @@ describe('shared/SettingData', () => {
expect({
keymaps: settings.keymaps.toJSON(),
search: settings.search.toJSON(),
- properties: settings.properties,
+ properties: settings.properties.toJSON(),
blacklist: settings.blacklist,
}).to.deep.equal({
keymaps: {
@@ -159,11 +160,11 @@ describe('shared/SettingData', () => {
"google": "https://google.com/search?q={}"
}
}),
- properties: {
+ properties: Properties.fromJSON({
hintchars: "abcdefghijklmnopqrstuvwxyz",
smoothscroll: false,
complete: "sbh"
- },
+ }),
blacklist: []
};
diff --git a/test/shared/Settings.test.ts b/test/shared/Settings.test.ts
index ed791a1..6360bab 100644
--- a/test/shared/Settings.test.ts
+++ b/test/shared/Settings.test.ts
@@ -1,33 +1,8 @@
import * as settings from '../../src/shared/Settings';
-import { expect } from 'chai';
+import {expect} from 'chai';
describe('Settings', () => {
- describe('#propertiesValueOf', () => {
- it('returns with default properties by empty settings', () => {
- let props = settings.propertiesValueOf({});
- expect(props).to.deep.equal({
- hintchars: "abcdefghijklmnopqrstuvwxyz",
- smoothscroll: false,
- complete: "sbh"
- })
- });
-
- it('returns properties by valid settings', () => {
- let props = settings.propertiesValueOf({
- hintchars: "abcdefgh",
- smoothscroll: false,
- complete: "sbh"
- });
-
- expect(props).to.deep.equal({
- hintchars: "abcdefgh",
- smoothscroll: false,
- complete: "sbh"
- });
- });
- });
-
describe('#blacklistValueOf', () => {
it('returns empty array by empty settings', () => {
let blacklist = settings.blacklistValueOf([]);
@@ -70,7 +45,7 @@ describe('Settings', () => {
expect({
keymaps: x.keymaps.toJSON(),
search: x.search.toJSON(),
- properties: x.properties,
+ properties: x.properties.toJSON(),
blacklist: x.blacklist,
}).to.deep.equal({
keymaps: {},
@@ -92,7 +67,7 @@ describe('Settings', () => {
it('sets default settings', () => {
let value = settings.valueOf({});
expect(value.keymaps.toJSON()).to.not.be.empty;
- expect(value.properties).to.not.be.empty;
+ expect(value.properties.toJSON()).to.not.be.empty;
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/properties.test.js b/test/shared/properties.test.js
deleted file mode 100644
index 37903d8..0000000
--- a/test/shared/properties.test.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as settings from 'shared/settings';
-
-describe('properties', () => {
- describe('Def class', () => {
- it('returns property definitions', () => {
- let def = new proerties.Def(
- 'smoothscroll',
- 'smooth scroll',
- false);
-
- expect(def.name).to.equal('smoothscroll');
- expect(def.describe).to.equal('smooth scroll');
- expect(def.defaultValue).to.equal(false);
- expect(def.type).to.equal('boolean');
- });
- });
-});
-
diff --git a/test/shared/property-defs.test.js b/test/shared/property-defs.test.js
deleted file mode 100644
index 37903d8..0000000
--- a/test/shared/property-defs.test.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as settings from 'shared/settings';
-
-describe('properties', () => {
- describe('Def class', () => {
- it('returns property definitions', () => {
- let def = new proerties.Def(
- 'smoothscroll',
- 'smooth scroll',
- false);
-
- expect(def.name).to.equal('smoothscroll');
- expect(def.describe).to.equal('smooth scroll');
- expect(def.defaultValue).to.equal(false);
- expect(def.type).to.equal('boolean');
- });
- });
-});
-
diff --git a/test/shared/settings/Properties.test.ts b/test/shared/settings/Properties.test.ts
new file mode 100644
index 0000000..609a565
--- /dev/null
+++ b/test/shared/settings/Properties.test.ts
@@ -0,0 +1,30 @@
+import Properties from '../../../src/shared/settings/Properties';
+import { expect } from 'chai';
+
+describe('Properties', () => {
+ describe('#propertiesValueOf', () => {
+ it('returns with default properties by empty settings', () => {
+ let props = Properties.fromJSON({});
+ expect(props).to.deep.equal({
+ hintchars: "abcdefghijklmnopqrstuvwxyz",
+ smoothscroll: false,
+ complete: "sbh"
+ })
+ });
+
+ it('returns properties by valid settings', () => {
+ let props = Properties.fromJSON({
+ hintchars: "abcdefgh",
+ smoothscroll: false,
+ complete: "sbh"
+ });
+
+ expect(props).to.deep.equal({
+ hintchars: "abcdefgh",
+ smoothscroll: false,
+ complete: "sbh"
+ });
+ });
+ });
+});
+