parent
e76ca380f7
commit
bacf83a320
16 changed files with 223 additions and 196 deletions
@ -1,28 +0,0 @@ |
|||||||
import * as actions from './index'; |
|
||||||
import * as operations from '../../shared/operations'; |
|
||||||
import * as messages from '../../shared/messages'; |
|
||||||
import Settings, { Keymaps } from '../../shared/Settings'; |
|
||||||
|
|
||||||
const reservedKeymaps: Keymaps = { |
|
||||||
'<Esc>': { type: operations.CANCEL }, |
|
||||||
'<C-[>': { type: operations.CANCEL }, |
|
||||||
}; |
|
||||||
|
|
||||||
const set = (settings: Settings): actions.SettingAction => { |
|
||||||
return { |
|
||||||
type: actions.SETTING_SET, |
|
||||||
settings: { |
|
||||||
...settings, |
|
||||||
keymaps: { ...settings.keymaps, ...reservedKeymaps }, |
|
||||||
} |
|
||||||
}; |
|
||||||
}; |
|
||||||
|
|
||||||
const load = async(): Promise<actions.SettingAction> => { |
|
||||||
let settings = await browser.runtime.sendMessage({ |
|
||||||
type: messages.SETTINGS_QUERY, |
|
||||||
}); |
|
||||||
return set(settings); |
|
||||||
}; |
|
||||||
|
|
||||||
export { set, load }; |
|
@ -0,0 +1,17 @@ |
|||||||
|
import Settings from '../../shared/Settings'; |
||||||
|
import * as messages from '../../shared/messages'; |
||||||
|
|
||||||
|
export default interface SettingClient { |
||||||
|
load(): Promise<Settings>; |
||||||
|
|
||||||
|
// eslint-disable-next-line semi
|
||||||
|
} |
||||||
|
|
||||||
|
export class SettingClientImpl { |
||||||
|
async load(): Promise<Settings> { |
||||||
|
let settings = await browser.runtime.sendMessage({ |
||||||
|
type: messages.SETTINGS_QUERY, |
||||||
|
}); |
||||||
|
return settings as Settings; |
||||||
|
} |
||||||
|
} |
@ -1,40 +0,0 @@ |
|||||||
import * as actions from '../actions'; |
|
||||||
import * as keyUtils from '../../shared/utils/keys'; |
|
||||||
import * as operations from '../../shared/operations'; |
|
||||||
import { Search, Properties, DefaultSetting } from '../../shared/Settings'; |
|
||||||
|
|
||||||
export interface State { |
|
||||||
keymaps: { key: keyUtils.Key[], op: operations.Operation }[]; |
|
||||||
search: Search; |
|
||||||
properties: Properties; |
|
||||||
} |
|
||||||
|
|
||||||
// defaultState does not refer due to the state is load from
|
|
||||||
// background on load.
|
|
||||||
const defaultState: State = { |
|
||||||
keymaps: [], |
|
||||||
search: DefaultSetting.search, |
|
||||||
properties: DefaultSetting.properties, |
|
||||||
}; |
|
||||||
|
|
||||||
export default function reducer( |
|
||||||
state: State = defaultState, |
|
||||||
action: actions.SettingAction, |
|
||||||
): State { |
|
||||||
switch (action.type) { |
|
||||||
case actions.SETTING_SET: |
|
||||||
return { |
|
||||||
keymaps: Object.entries(action.settings.keymaps).map((entry) => { |
|
||||||
return { |
|
||||||
key: keyUtils.fromMapKeys(entry[0]), |
|
||||||
op: entry[1], |
|
||||||
}; |
|
||||||
}), |
|
||||||
properties: action.settings.properties, |
|
||||||
search: action.settings.search, |
|
||||||
}; |
|
||||||
default: |
|
||||||
return state; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -0,0 +1,22 @@ |
|||||||
|
import Settings, { DefaultSetting } from '../../shared/Settings'; |
||||||
|
|
||||||
|
let current: Settings = DefaultSetting; |
||||||
|
|
||||||
|
export default interface SettingRepository { |
||||||
|
set(setting: Settings): void; |
||||||
|
|
||||||
|
get(): Settings; |
||||||
|
|
||||||
|
// eslint-disable-next-line semi
|
||||||
|
} |
||||||
|
|
||||||
|
export class SettingRepositoryImpl implements SettingRepository { |
||||||
|
set(setting: Settings): void { |
||||||
|
current = setting; |
||||||
|
} |
||||||
|
|
||||||
|
get(): Settings { |
||||||
|
return current; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
import SettingRepository, { SettingRepositoryImpl } |
||||||
|
from '../repositories/SettingRepository'; |
||||||
|
import SettingClient, { SettingClientImpl } from '../client/SettingClient'; |
||||||
|
import Settings from '../../shared/Settings'; |
||||||
|
|
||||||
|
export default class SettingUseCase { |
||||||
|
private repository: SettingRepository; |
||||||
|
|
||||||
|
private client: SettingClient; |
||||||
|
|
||||||
|
constructor({ |
||||||
|
repository = new SettingRepositoryImpl(), |
||||||
|
client = new SettingClientImpl(), |
||||||
|
} = {}) { |
||||||
|
this.repository = repository; |
||||||
|
this.client = client; |
||||||
|
} |
||||||
|
|
||||||
|
async reload(): Promise<Settings> { |
||||||
|
let settings = await this.client.load(); |
||||||
|
this.repository.set(settings); |
||||||
|
return settings; |
||||||
|
} |
||||||
|
} |
@ -1,43 +0,0 @@ |
|||||||
import * as actions from 'content/actions'; |
|
||||||
import * as settingActions from 'content/actions/setting'; |
|
||||||
|
|
||||||
describe("setting actions", () => { |
|
||||||
describe("set", () => { |
|
||||||
it('create SETTING_SET action', () => { |
|
||||||
let action = settingActions.set({ |
|
||||||
keymaps: { |
|
||||||
'dd': 'remove current tab', |
|
||||||
'z<C-A>': 'increment', |
|
||||||
}, |
|
||||||
search: { |
|
||||||
default: "google", |
|
||||||
engines: { |
|
||||||
google: 'https://google.com/search?q={}', |
|
||||||
} |
|
||||||
}, |
|
||||||
properties: { |
|
||||||
hintchars: 'abcd1234', |
|
||||||
}, |
|
||||||
blacklist: [], |
|
||||||
}); |
|
||||||
expect(action.type).to.equal(actions.SETTING_SET); |
|
||||||
expect(action.settings.properties.hintchars).to.equal('abcd1234'); |
|
||||||
}); |
|
||||||
|
|
||||||
it('overrides cancel keys', () => { |
|
||||||
let action = settingActions.set({ |
|
||||||
keymaps: { |
|
||||||
"k": { "type": "scroll.vertically", "count": -1 }, |
|
||||||
"j": { "type": "scroll.vertically", "count": 1 }, |
|
||||||
} |
|
||||||
}); |
|
||||||
let keymaps = action.settings.keymaps; |
|
||||||
expect(action.settings.keymaps).to.deep.equals({ |
|
||||||
"k": { type: "scroll.vertically", count: -1 }, |
|
||||||
"j": { type: "scroll.vertically", count: 1 }, |
|
||||||
'<Esc>': { type: 'cancel' }, |
|
||||||
'<C-[>': { type: 'cancel' }, |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,31 +0,0 @@ |
|||||||
import * as actions from 'content/actions'; |
|
||||||
import settingReducer from 'content/reducers/setting'; |
|
||||||
|
|
||||||
describe("content setting reducer", () => { |
|
||||||
it('return the initial state', () => { |
|
||||||
let state = settingReducer(undefined, {}); |
|
||||||
expect(state.keymaps).to.be.empty; |
|
||||||
}); |
|
||||||
|
|
||||||
it('return next state for SETTING_SET', () => { |
|
||||||
let newSettings = { red: 'apple', yellow: 'banana' }; |
|
||||||
let action = { |
|
||||||
type: actions.SETTING_SET, |
|
||||||
settings: { |
|
||||||
keymaps: { |
|
||||||
"zz": { type: "zoom.neutral" }, |
|
||||||
"<S-Esc>": { "type": "addon.toggle.enabled" } |
|
||||||
}, |
|
||||||
"blacklist": [] |
|
||||||
} |
|
||||||
} |
|
||||||
let state = settingReducer(undefined, action); |
|
||||||
expect(state.keymaps).to.have.deep.all.members([ |
|
||||||
{ key: [{ key: 'z', shiftKey: false, ctrlKey: false, altKey: false, metaKey: false }, |
|
||||||
{ key: 'z', shiftKey: false, ctrlKey: false, altKey: false, metaKey: false }], |
|
||||||
op: { type: 'zoom.neutral' }}, |
|
||||||
{ key: [{ key: 'Esc', shiftKey: true, ctrlKey: false, altKey: false, metaKey: false }], |
|
||||||
op: { type: 'addon.toggle.enabled' }}, |
|
||||||
]); |
|
||||||
}); |
|
||||||
}); |
|
@ -0,0 +1,30 @@ |
|||||||
|
import { SettingRepositoryImpl } from '../../../src/content/repositories/SettingRepository'; |
||||||
|
import { expect } from 'chai'; |
||||||
|
|
||||||
|
describe('SettingRepositoryImpl', () => { |
||||||
|
it('updates and gets current value', () => { |
||||||
|
let sut = new SettingRepositoryImpl(); |
||||||
|
|
||||||
|
let settings = { |
||||||
|
keymaps: {}, |
||||||
|
search: { |
||||||
|
default: 'google', |
||||||
|
engines: { |
||||||
|
google: 'https://google.com/?q={}', |
||||||
|
} |
||||||
|
}, |
||||||
|
properties: { |
||||||
|
hintchars: 'abcd1234', |
||||||
|
smoothscroll: false, |
||||||
|
complete: 'sbh', |
||||||
|
}, |
||||||
|
blacklist: [], |
||||||
|
} |
||||||
|
|
||||||
|
sut.set(settings); |
||||||
|
|
||||||
|
let actual = sut.get(); |
||||||
|
expect(actual.properties.hintchars).to.equal('abcd1234'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
@ -0,0 +1,71 @@ |
|||||||
|
import SettingRepository from '../../../src/content/repositories/SettingRepository'; |
||||||
|
import SettingClient from '../../../src/content/client/SettingClient'; |
||||||
|
import SettingUseCase from '../../../src/content/usecases/SettingUseCase'; |
||||||
|
import Settings, { DefaultSetting } from '../../../src/shared/Settings'; |
||||||
|
import { expect } from 'chai'; |
||||||
|
|
||||||
|
class MockSettingRepository implements SettingRepository { |
||||||
|
private current: Settings; |
||||||
|
|
||||||
|
constructor() { |
||||||
|
this.current = DefaultSetting; |
||||||
|
} |
||||||
|
|
||||||
|
set(settings: Settings): void { |
||||||
|
this.current= settings; |
||||||
|
} |
||||||
|
|
||||||
|
get(): Settings { |
||||||
|
return this.current; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class MockSettingClient implements SettingClient { |
||||||
|
private data: Settings; |
||||||
|
|
||||||
|
constructor(data: Settings) { |
||||||
|
this.data = data; |
||||||
|
} |
||||||
|
|
||||||
|
load(): Promise<Settings> { |
||||||
|
return Promise.resolve(this.data); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
describe('AddonEnabledUseCase', () => { |
||||||
|
let repository: MockSettingRepository; |
||||||
|
let client: MockSettingClient; |
||||||
|
let sut: SettingUseCase; |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
let testSettings = { |
||||||
|
keymaps: {}, |
||||||
|
search: { |
||||||
|
default: 'google', |
||||||
|
engines: { |
||||||
|
google: 'https://google.com/?q={}', |
||||||
|
} |
||||||
|
}, |
||||||
|
properties: { |
||||||
|
hintchars: 'abcd1234', |
||||||
|
smoothscroll: false, |
||||||
|
complete: 'sbh', |
||||||
|
}, |
||||||
|
blacklist: [], |
||||||
|
}; |
||||||
|
|
||||||
|
repository = new MockSettingRepository(); |
||||||
|
client = new MockSettingClient(testSettings); |
||||||
|
sut = new SettingUseCase({ repository, client }); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('#reload', () => { |
||||||
|
it('loads settings and store to repository', async() => { |
||||||
|
let settings = await sut.reload(); |
||||||
|
expect(settings.properties.hintchars).to.equal('abcd1234'); |
||||||
|
|
||||||
|
let saved = repository.get(); |
||||||
|
expect(saved.properties.hintchars).to.equal('abcd1234'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
Reference in new issue