From 7682a1d772e357e8f59d027381e4f27b2834cf48 Mon Sep 17 00:00:00 2001 From: CRIMX Date: Thu, 5 Apr 2018 21:14:31 +0800 Subject: [PATCH] perf(message): change message type to typescript enum --- src/_helpers/__mocks__/browser-api.ts | 39 ++++---- src/_helpers/browser-api.ts | 53 ++++++----- src/background/server.ts | 41 ++++----- src/selection/index.ts | 14 +-- src/typings/message.ts | 37 +++++++- test/specs/_helpers/browser-api.spec.ts | 115 ++++++++++++------------ test/specs/background/server.spec.ts | 17 ++-- test/specs/selection/index.spec.ts | 13 +-- 8 files changed, 190 insertions(+), 139 deletions(-) diff --git a/src/_helpers/__mocks__/browser-api.ts b/src/_helpers/__mocks__/browser-api.ts index 5db544e23..a2ca05151 100644 --- a/src/_helpers/__mocks__/browser-api.ts +++ b/src/_helpers/__mocks__/browser-api.ts @@ -5,6 +5,7 @@ import { Observable } from 'rxjs/Observable' import { fromEventPattern } from 'rxjs/observable/fromEventPattern' import _ from 'lodash' +import { MsgType } from '@/typings/message' /* --------------------------------------- *\ * #Types @@ -28,10 +29,16 @@ export type StorageListenerCb = ( ) => void export interface Message { - type: string + type: number [propName: string]: any } +type onMessageEvent = ( + message: Message, + sender: browser.runtime.MessageSender, + sendResponse: Function +) => Promise | boolean | void + /* --------------------------------------- *\ * #Globals \* --------------------------------------- */ @@ -42,14 +49,14 @@ const noop = () => { /* do nothing */ } * key: {function} user's callback function * values: {Map} listeners, key: message type, values: generated or user's callback functions */ -const messageListeners: Map> = new Map() +const messageListeners: Map> = new Map() /** * For self page messaging * key: {function} user's callback function * values: {Map} listeners, key: message type, values: generated or user's callback functions */ -const messageSelfListeners: Map> = new Map() +const messageSelfListeners: Map> = new Map() /** * key: {function} user's callback function @@ -335,8 +342,8 @@ function _messageSend (self: boolean) { function _messageAddListener (self: boolean) { return jest.fn(messageAddListener) - function messageAddListener (messageType: string, cb: browser.runtime.onMessageEvent): void - function messageAddListener (cb: browser.runtime.onMessageEvent): void + function messageAddListener (messageType: Message['type'], cb: onMessageEvent): void + function messageAddListener (cb: onMessageEvent): void function messageAddListener (...args): void { const allListeners = self ? messageSelfListeners : messageListeners const messageType = args.length === 1 ? undefined : args[0] @@ -346,7 +353,7 @@ function _messageAddListener (self: boolean) { listeners = new Map() allListeners.set(cb, listeners) } - let listener = listeners.get(messageType || '_&_MSG_DEFAULT_&_') + let listener = listeners.get(messageType || MsgType.Default) if (!listener) { listener = ( (message, sender, sendResponse) => { @@ -356,7 +363,7 @@ function _messageAddListener (self: boolean) { } } } - ) as browser.runtime.onMessageEvent + ) as onMessageEvent listeners.set(messageType, listener) } } @@ -365,8 +372,8 @@ function _messageAddListener (self: boolean) { function _messageRemoveListener (self: boolean) { return jest.fn(messageRemoveListener) - function messageRemoveListener (messageType: string, cb: browser.runtime.onMessageEvent): void - function messageRemoveListener (cb: browser.runtime.onMessageEvent): void + function messageRemoveListener (messageType: Message['type'], cb: onMessageEvent): void + function messageRemoveListener (cb: onMessageEvent): void function messageRemoveListener (...args): void { const allListeners = self ? messageSelfListeners : messageListeners const messageType = args.length === 1 ? undefined : args[0] @@ -395,9 +402,9 @@ function _messageCreateStream (self: boolean) { return jest.fn(messageCreateStream) function messageCreateStream (selector?: (...args) => T): Observable - function messageCreateStream (messageType: string, selector?: (...args) => T): Observable + function messageCreateStream (messageType: Message['type'], selector?: (...args) => T): Observable function messageCreateStream (...args) { - let messageType = '' + let messageType: Message['type'] = MsgType.Null let selector = x => x if (typeof args[0] === 'function') { @@ -408,16 +415,16 @@ function _messageCreateStream (self: boolean) { } const obj = _.get(message, self ? 'self' : '') - if (messageType) { + if (messageType !== MsgType.Null) { return fromEventPattern( - handler => obj.addListener(messageType, handler as browser.runtime.onMessageEvent), - handler => obj.removeListener(messageType, handler as browser.runtime.onMessageEvent), + handler => obj.addListener(messageType, handler as onMessageEvent), + handler => obj.removeListener(messageType, handler as onMessageEvent), selector, ) } else { return fromEventPattern( - handler => obj.addListener(handler as browser.runtime.onMessageEvent), - handler => obj.removeListener(handler as browser.runtime.onMessageEvent), + handler => obj.addListener(handler as onMessageEvent), + handler => obj.removeListener(handler as onMessageEvent), selector, ) } diff --git a/src/_helpers/browser-api.ts b/src/_helpers/browser-api.ts index 4f64da613..a06a78fde 100644 --- a/src/_helpers/browser-api.ts +++ b/src/_helpers/browser-api.ts @@ -4,6 +4,7 @@ import { Observable } from 'rxjs/Observable' import { fromEventPattern } from 'rxjs/observable/fromEventPattern' +import { MsgType } from '@/typings/message' /* --------------------------------------- *\ * #Types @@ -27,10 +28,16 @@ export type StorageListenerCb = ( ) => void export interface Message { - type: string + type: number [propName: string]: any } +type onMessageEvent = ( + message: Message, + sender: browser.runtime.MessageSender, + sendResponse: Function +) => Promise | boolean | void + /* --------------------------------------- *\ * #Globals \* --------------------------------------- */ @@ -41,14 +48,14 @@ const noop = () => { /* do nothing */ } * key: {function} user's callback function * values: {Map} listeners, key: message type, values: generated or user's callback functions */ -const messageListeners: Map> = new Map() +const messageListeners: Map> = new Map() /** * For self page messaging * key: {function} user's callback function * values: {Map} listeners, key: message type, values: generated or user's callback functions */ -const messageSelfListeners: Map> = new Map() +const messageSelfListeners: Map> = new Map() /** * key: {function} user's callback function @@ -286,12 +293,12 @@ function messageSendSelf (message: Message): Promise { } return browser.runtime.sendMessage(Object.assign({}, message, { __pageId__: window.pageId, - type: `_&_${message.type}_&_` + type: `[[${message.type}]]` })) } -function messageAddListener (messageType: string, cb: browser.runtime.onMessageEvent): void -function messageAddListener (cb: browser.runtime.onMessageEvent): void +function messageAddListener (messageType: Message['type'], cb: onMessageEvent): void +function messageAddListener (cb: onMessageEvent): void function messageAddListener (this: MessageThis, ...args): void { const allListeners = this.__self__ ? messageSelfListeners : messageListeners const messageType = args.length === 1 ? undefined : args[0] @@ -301,7 +308,7 @@ function messageAddListener (this: MessageThis, ...args): void { listeners = new Map() allListeners.set(cb, listeners) } - let listener = listeners.get(messageType || '_&_MSG_DEFAULT_&_') + let listener = listeners.get(messageType || MsgType.Default) if (!listener) { listener = ( (message, sender, sendResponse) => { @@ -311,14 +318,14 @@ function messageAddListener (this: MessageThis, ...args): void { } } } - ) as browser.runtime.onMessageEvent + ) as onMessageEvent listeners.set(messageType, listener) } return browser.runtime.onMessage.addListener(listener) } -function messageRemoveListener (messageType: string, cb: browser.runtime.onMessageEvent): void -function messageRemoveListener (cb: browser.runtime.onMessageEvent): void +function messageRemoveListener (messageType: Message['type'], cb: onMessageEvent): void +function messageRemoveListener (cb: onMessageEvent): void function messageRemoveListener (this: MessageThis, ...args): void { const allListeners = this.__self__ ? messageSelfListeners : messageListeners const messageType = args.length === 1 ? undefined : args[0] @@ -346,9 +353,9 @@ function messageRemoveListener (this: MessageThis, ...args): void { } function messageCreateStream (selector?: (...args) => T): Observable -function messageCreateStream (messageType: string, selector?: (...args) => T): Observable +function messageCreateStream (messageType: Message['type'], selector?: (...args) => T): Observable function messageCreateStream (this: MessageThis, ...args) { - let messageType = '' + let messageType: Message['type'] = MsgType.Null let selector = x => x if (typeof args[0] === 'function') { @@ -358,28 +365,28 @@ function messageCreateStream (this: MessageThis, ...args) { selector = args[1] } - if (messageType) { + if (messageType !== MsgType.Null) { return fromEventPattern( - handler => this.addListener(messageType, handler as browser.runtime.onMessageEvent), - handler => this.removeListener(messageType, handler as browser.runtime.onMessageEvent), + handler => this.addListener(messageType, handler as onMessageEvent), + handler => this.removeListener(messageType, handler as onMessageEvent), selector, ) } else { return fromEventPattern( - handler => this.addListener(handler as browser.runtime.onMessageEvent), - handler => this.removeListener(handler as browser.runtime.onMessageEvent), + handler => this.addListener(handler as onMessageEvent), + handler => this.removeListener(handler as onMessageEvent), selector, ) } } /** - * Deploy client side + * Deploy page script for self-messaging * This method is called on the first sendMessage */ function initClient (): Promise { if (window.pageId === undefined) { - return browser.runtime.sendMessage({ type: '__PAGE_INFO__' }) + return browser.runtime.sendMessage({ type: MsgType.__PageInfo__ }) .then(({ pageId, faviconURL, pageTitle, pageURL }) => { window.pageId = pageId window.faviconURL = faviconURL @@ -393,18 +400,18 @@ function initClient (): Promise { } /** - * Deploy server side + * Deploy background proxy for self-messaging * This method should be invoked in background script */ function initServer (): void { window.pageId = 'background page' - const selfMsgTester = /^_&_(.+)_&_$/ + const selfMsgTester = /^\[\[(.+)\]\]$/ browser.runtime.onMessage.addListener((message, sender, sendResponse) => { if (!message) { return } switch (message.type) { - case '__PAGE_INFO__': + case MsgType.__PageInfo__: sendResponse(_getPageInfo(sender)) break default: @@ -413,7 +420,7 @@ function initServer (): void { const selfMsg = selfMsgTester.exec(message.type) if (selfMsg) { - message.type = selfMsg[1] + message.type = Number(selfMsg[1]) if (sender.tab && sender.tab.id) { return messageSend(sender.tab.id, message) } else { diff --git a/src/background/server.ts b/src/background/server.ts index 66ed5c070..380c1e8b1 100644 --- a/src/background/server.ts +++ b/src/background/server.ts @@ -2,29 +2,30 @@ import { DictID } from '@/app-config' import { message, openURL } from '@/_helpers/browser-api' import { play } from './audio-manager' import { chsToChz } from '@/_helpers/chs-to-chz' +import { MsgType } from '@/typings/message' -interface MessageOpenUrlWithEscape { - type: 'OPEN_URL' +interface MsgOpenUrlWithEscape { + type: MsgType.OpenURL url: string escape: true text: string } -interface MessageOpenUrlWithoutEscape { - type: 'OPEN_URL' +interface MsgOpenUrlWithoutEscape { + type: MsgType.OpenURL url: string escape?: false } -type MessageOpenUrl = MessageOpenUrlWithoutEscape | MessageOpenUrlWithEscape +type MsgOpenUrl = MsgOpenUrlWithoutEscape | MsgOpenUrlWithEscape -interface MessageAudioPlay { - type: 'AUDIO_PLAY' +interface MsgAudioPlay { + type: MsgType.PlayAudio src: string } -interface MessageFetchDictResult { - type: 'FETCH_DICT_RESULT' +interface MsgFetchDictResult { + type: MsgType.FetchDictResult dict: DictID text: string } @@ -34,18 +35,18 @@ message.self.initServer() // background script as transfer station message.addListener((data, sender: browser.runtime.MessageSender): Promise | undefined => { switch (data.type) { - case 'OPEN_URL': - return createTab(data) - case 'AUDIO_PLAY': - return playAudio(data) - case 'FETCH_DICT_RESULT': - return fetchDictResult(data) - case 'PRELOAD_SELECTION': + case MsgType.OpenURL: + return createTab(data as MsgOpenUrl) + case MsgType.PlayAudio: + return playAudio(data as MsgAudioPlay) + case MsgType.FetchDictResult: + return fetchDictResult(data as MsgFetchDictResult) + case MsgType.PreloadSelection: return preloadSelection() } }) -function createTab (data: MessageOpenUrl): Promise { +function createTab (data: MsgOpenUrl): Promise { return openURL( data.escape ? data.url @@ -55,11 +56,11 @@ function createTab (data: MessageOpenUrl): Promise { ) } -function playAudio (data: MessageAudioPlay): Promise { +function playAudio (data: MsgAudioPlay): Promise { return play(data.src) } -function fetchDictResult (data: MessageFetchDictResult): Promise { +function fetchDictResult (data: MsgFetchDictResult): Promise { let search try { @@ -76,7 +77,7 @@ function preloadSelection (): Promise { return browser.tabs.query({ active: true, currentWindow: true }) .then(tabs => { if (tabs.length > 0 && tabs[0].id != null) { - return message.send(tabs[0].id as number, { type: '__PRELOAD_SELECTION__' }) + return message.send(tabs[0].id as number, { type: MsgType.__PreloadSelection__ }) } }) .then(text => text || '') diff --git a/src/selection/index.ts b/src/selection/index.ts index 367e07e58..2f387f7e8 100644 --- a/src/selection/index.ts +++ b/src/selection/index.ts @@ -3,7 +3,7 @@ import { message, storage } from '@/_helpers/browser-api' import { isContainChinese, isContainEnglish } from '@/_helpers/lang-check' import { createAppConfigStream } from '@/_helpers/config-manager' import * as selection from '@/_helpers/selection' -import { MsgSALADICT_SELECTION, MsgSELECTION } from '@/typings/message' +import { MsgType, MsgSALADICT_SELECTION, MsgSELECTION } from '@/typings/message' import { Observable } from 'rxjs/Observable' import { of } from 'rxjs/observable/of' @@ -12,12 +12,12 @@ import { fromEvent } from 'rxjs/observable/fromEvent' import { merge } from 'rxjs/observable/merge' import { async } from 'rxjs/scheduler/async' -message.addListener('__PRELOAD_SELECTION__', (data, sender, sendResponse) => { +message.addListener(MsgType.__PreloadSelection__, (data, sender, sendResponse) => { sendResponse(selection.getSelectionInfo()) }) window.addEventListener('message', ({ data, source }: { data: MsgSALADICT_SELECTION, source: Window }) => { - if (data.type !== 'SALADICT_SELECTION') { return } + if (data.type !== MsgType.SaladictSelection) { return } // get the souce iframe const iframe = Array.from(document.querySelectorAll('iframe')) @@ -76,7 +76,7 @@ const mouseup$ = fromEvent(window, 'mouseup', true).pipe( ) tripleCtrlPressed$.subscribe(() => { - message.self.send({ type: 'TRIPLE_CTRL' }) + message.self.send({ type: MsgType.TripleCtrl }) }) mouseup$.subscribe(([ evt, config, ctrlKey ]) => { @@ -115,7 +115,7 @@ function sendMessage ( if (window.parent === window) { // top message.self.send({ - type: 'SELECTION', + type: MsgType.Selection, selectionInfo, mouseX: clientX, mouseY: clientY, @@ -124,7 +124,7 @@ function sendMessage ( } else { // post to upper frames/window window.parent.postMessage({ - type: 'SALADICT_SELECTION', + type: MsgType.SaladictSelection, selectionInfo, mouseX: clientX, mouseY: clientY, @@ -136,7 +136,7 @@ function sendMessage ( function sendEmptyMessage () { // empty message message.self.send({ - type: 'SELECTION', + type: MsgType.Selection, selectionInfo: { text: '', context: '', diff --git a/src/typings/message.ts b/src/typings/message.ts index 2446ff656..bbd09e7ff 100644 --- a/src/typings/message.ts +++ b/src/typings/message.ts @@ -2,8 +2,41 @@ import { SelectionInfo } from '@/_helpers/selection' /* tslint:disable:class-name */ +export enum MsgType { + /** Nothing */ + Null, + /** Default */ + Default, + + /** Any type of mouse down */ + Selection, + /** Mouse down with valid selection */ + SaladictSelection, + + /** Ctrl/Command has been hit 3 times */ + TripleCtrl, + + /** Response the pageInfo of a page */ + PageInfo, + + /** Create a tab with the url */ + OpenURL, + /** Play a audio src */ + PlayAudio, + /** Search text with a dictionary and response the result */ + FetchDictResult, + /** Request background proxy for current selection */ + PreloadSelection, + + /** + * Background proxy sends back underlyingly + */ + __PageInfo__, + __PreloadSelection__, +} + export interface MsgSELECTION { - type: 'SELECTION' + type: MsgType.Selection selectionInfo: SelectionInfo mouseX?: number mouseY?: number @@ -11,7 +44,7 @@ export interface MsgSELECTION { } export interface MsgSALADICT_SELECTION { - type: 'SALADICT_SELECTION' + type: MsgType.SaladictSelection selectionInfo: SelectionInfo mouseX: number mouseY: number diff --git a/test/specs/_helpers/browser-api.spec.ts b/test/specs/_helpers/browser-api.spec.ts index 5e24972b5..ebe1b535e 100644 --- a/test/specs/_helpers/browser-api.spec.ts +++ b/test/specs/_helpers/browser-api.spec.ts @@ -1,6 +1,7 @@ import { message, storage, openURL } from '@/_helpers/browser-api' import { AppConfig } from '@/app-config' import { take } from 'rxjs/operators/take' +import { MsgType } from '@/typings/message' describe('Browser API Wapper', () => { beforeEach(() => { @@ -452,7 +453,7 @@ describe('Browser API Wapper', () => { describe('Message', () => { it('message.send', () => { const tabId = 1 - const msg = { type: 'TYPE_1' } + const msg = { type: 1 } message.send(msg) expect(browser.runtime.sendMessage.calledWith(msg)).toBeTruthy() @@ -471,16 +472,16 @@ describe('Browser API Wapper', () => { let cb1Call = 0 let cb2Call = 0 message.addListener(cb1) - message.addListener('MSG_1', cb2) + message.addListener(1, cb2) expect(browser.runtime.onMessage.addListener.calledTwice).toBeTruthy() expect(cb1).toHaveBeenCalledTimes(cb1Call) expect(cb2).toHaveBeenCalledTimes(cb2Call) - browser.runtime.onMessage.dispatch({ type: 'MSG_2' }) + browser.runtime.onMessage.dispatch({ type: 2 }) expect(cb1).toHaveBeenCalledTimes(++cb1Call) expect(cb2).toHaveBeenCalledTimes(cb2Call) - browser.runtime.onMessage.dispatch({ type: 'MSG_1' }) + browser.runtime.onMessage.dispatch({ type: 1 }) expect(cb1).toHaveBeenCalledTimes(++cb1Call) expect(cb2).toHaveBeenCalledTimes(++cb2Call) }) @@ -489,23 +490,23 @@ describe('Browser API Wapper', () => { const cb2 = jest.fn() let cb1Call = 0 let cb2Call = 0 - message.addListener('MSG_1', cb1) - message.addListener('MSG_2', cb2) - browser.runtime.onMessage.dispatch({ type: 'MSG_1' }) + message.addListener(1, cb1) + message.addListener(2, cb2) + browser.runtime.onMessage.dispatch({ type: 1 }) expect(cb1).toHaveBeenCalledTimes(++cb1Call) expect(cb2).toHaveBeenCalledTimes(cb2Call) - message.removeListener('MSG_x', cb1) + message.removeListener(-1, cb1) message.removeListener(cb2) expect(browser.runtime.onMessage.removeListener.calledTwice).toBeTruthy() - browser.runtime.onMessage.dispatch({ type: 'MSG_1' }) - browser.runtime.onMessage.dispatch({ type: 'MSG_2' }) + browser.runtime.onMessage.dispatch({ type: 1 }) + browser.runtime.onMessage.dispatch({ type: 2 }) expect(cb1).toHaveBeenCalledTimes(++cb1Call) expect(cb2).toHaveBeenCalledTimes(cb2Call) - message.removeListener('MSG_1', cb1) - browser.runtime.onMessage.dispatch({ type: 'MSG_1' }) + message.removeListener(1, cb1) + browser.runtime.onMessage.dispatch({ type: 1 }) expect(cb1).toHaveBeenCalledTimes(cb1Call) }) describe('message.createStream', () => { @@ -521,24 +522,24 @@ describe('Browser API Wapper', () => { expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_1' }) + browser.runtime.onMessage.dispatch({ type: 1 }) expect(nextStub).toHaveBeenCalledTimes(1) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - expect(nextStub).toBeCalledWith({ type: 'MSG_1' }) + expect(nextStub).toBeCalledWith({ type: 1 }) - browser.runtime.onMessage.dispatch({ type: 'MSG_2' }) + browser.runtime.onMessage.dispatch({ type: 2 }) expect(nextStub).toHaveBeenCalledTimes(2) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(1) - expect(nextStub).toBeCalledWith({ type: 'MSG_2' }) + expect(nextStub).toBeCalledWith({ type: 2 }) }) it('with message type', () => { const nextStub = jest.fn() const errorStub = jest.fn() const completeStub = jest.fn() - message.createStream('MSG_1') + message.createStream(1) .pipe(take(1)) .subscribe(nextStub, errorStub, completeStub) expect(browser.runtime.onMessage.addListener.calledOnce).toBeTruthy() @@ -546,16 +547,16 @@ describe('Browser API Wapper', () => { expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_2' }) + browser.runtime.onMessage.dispatch({ type: 2 }) expect(nextStub).toHaveBeenCalledTimes(0) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_1' }) + browser.runtime.onMessage.dispatch({ type: 1 }) expect(nextStub).toHaveBeenCalledTimes(1) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(1) - expect(nextStub).toBeCalledWith({ type: 'MSG_1' }) + expect(nextStub).toBeCalledWith({ type: 1 }) }) it('with selector', () => { const nextStub = jest.fn() @@ -569,23 +570,23 @@ describe('Browser API Wapper', () => { expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_2' }) + browser.runtime.onMessage.dispatch({ type: 2 }) expect(nextStub).toHaveBeenCalledTimes(1) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - expect(nextStub).toBeCalledWith('MSG_2') + expect(nextStub).toBeCalledWith(2) - browser.runtime.onMessage.dispatch({ type: 'MSG_1' }) + browser.runtime.onMessage.dispatch({ type: 1 }) expect(nextStub).toHaveBeenCalledTimes(2) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(1) - expect(nextStub).toBeCalledWith('MSG_1') + expect(nextStub).toBeCalledWith(1) }) it('with message type and selector', () => { const nextStub = jest.fn() const errorStub = jest.fn() const completeStub = jest.fn() - message.createStream('MSG_1', x => x.type) + message.createStream(1, x => x.type) .pipe(take(1)) .subscribe(nextStub, errorStub, completeStub) expect(browser.runtime.onMessage.addListener.calledOnce).toBeTruthy() @@ -593,22 +594,22 @@ describe('Browser API Wapper', () => { expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_2' }) + browser.runtime.onMessage.dispatch({ type: 2 }) expect(nextStub).toHaveBeenCalledTimes(0) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_1' }) + browser.runtime.onMessage.dispatch({ type: 1 }) expect(nextStub).toHaveBeenCalledTimes(1) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(1) - expect(nextStub).toBeCalledWith('MSG_1') + expect(nextStub).toBeCalledWith(1) }) }) it('message.self.initClient', () => { browser.runtime.sendMessage - .withArgs({ type: '__PAGE_INFO__' }) + .withArgs({ type: MsgType.__PageInfo__ }) .returns(Promise.resolve({ pageId: 'pageId', faviconURL: 'faviconURL', @@ -617,7 +618,7 @@ describe('Browser API Wapper', () => { })) return message.self.initClient() .then(() => { - expect(browser.runtime.sendMessage.calledWith({ type: '__PAGE_INFO__' })).toBeTruthy() + expect(browser.runtime.sendMessage.calledWith({ type: MsgType.__PageInfo__ })).toBeTruthy() expect(window.pageId).toBe('pageId') expect(window.faviconURL).toBe('faviconURL') expect(window.pageTitle).toBe('pageTitle') @@ -637,7 +638,7 @@ describe('Browser API Wapper', () => { expect(browser.runtime.onMessage.addListener.calledOnce).toBeTruthy() const sendResponse = jest.fn() - browser.runtime.onMessage.dispatch({ type: '__PAGE_INFO__' }, { tab }, sendResponse) + browser.runtime.onMessage.dispatch({ type: MsgType.__PageInfo__ }, { tab }, sendResponse) expect(sendResponse).toBeCalledWith(({ pageId: tab.id, faviconURL: tab.favIconUrl, @@ -651,7 +652,7 @@ describe('Browser API Wapper', () => { expect(browser.runtime.onMessage.addListener.calledOnce).toBeTruthy() const sendResponse = jest.fn() - browser.runtime.onMessage.dispatch({ type: '__PAGE_INFO__' }, {}, sendResponse) + browser.runtime.onMessage.dispatch({ type: MsgType.__PageInfo__ }, {}, sendResponse) expect(sendResponse).toBeCalledWith( expect.objectContaining({ pageId: 'popup', @@ -663,21 +664,21 @@ describe('Browser API Wapper', () => { message.self.initServer() expect(browser.runtime.onMessage.addListener.calledOnce).toBeTruthy() - browser.runtime.onMessage.dispatch({ type: '_&_MSG_1_&_', __pageId__: 1 }, {}) - expect(browser.runtime.sendMessage.calledWith({ type: 'MSG_1', __pageId__: 1 })).toBeTruthy() + browser.runtime.onMessage.dispatch({ type: '[[1]]', __pageId__: 1 }, {}) + expect(browser.runtime.sendMessage.calledWith({ type: 1, __pageId__: 1 })).toBeTruthy() - browser.runtime.onMessage.dispatch({ type: '_&_MSG_1_&_', __pageId__: 1 }, { tab }) - expect(browser.tabs.sendMessage.calledWith(tab.id, { type: 'MSG_1', __pageId__: 1 })).toBeTruthy() + browser.runtime.onMessage.dispatch({ type: '[[1]]', __pageId__: 1 }, { tab }) + expect(browser.tabs.sendMessage.calledWith(tab.id, { type: 1, __pageId__: 1 })).toBeTruthy() }) }) it('message.self.send', () => { window.pageId = 1 message.self.send({ - type: 'MSG_1', + type: 1, prop: 'value', }) expect(browser.runtime.sendMessage.calledWith({ - type: '_&_MSG_1_&_', + type: '[[1]]', __pageId__: window.pageId, prop: 'value', })).toBeTruthy() @@ -694,15 +695,15 @@ describe('Browser API Wapper', () => { expect(cb1).toHaveBeenCalledTimes(cb1Call) expect(cb2).toHaveBeenCalledTimes(cb2Call) - browser.runtime.onMessage.dispatch({ type: 'MSG_1', __pageId__: window.pageId }) + browser.runtime.onMessage.dispatch({ type: 1, __pageId__: window.pageId }) expect(cb1).toHaveBeenCalledTimes(++cb1Call) expect(cb2).toHaveBeenCalledTimes(cb2Call) - browser.runtime.onMessage.dispatch({ type: 'MSG_1' }) + browser.runtime.onMessage.dispatch({ type: 1 }) expect(cb1).toHaveBeenCalledTimes(cb1Call) expect(cb2).toHaveBeenCalledTimes(++cb2Call) - browser.runtime.onMessage.dispatch({ type: 'MSG_1', __pageId__: window.pageId + 2 }) + browser.runtime.onMessage.dispatch({ type: 1, __pageId__: window.pageId + 2 }) expect(cb1).toHaveBeenCalledTimes(cb1Call) expect(cb2).toHaveBeenCalledTimes(cb2Call) }) @@ -734,17 +735,17 @@ describe('Browser API Wapper', () => { expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_1', __pageId__: window.pageId }) + browser.runtime.onMessage.dispatch({ type: 1, __pageId__: window.pageId }) expect(nextStub).toHaveBeenCalledTimes(1) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - expect(nextStub).toBeCalledWith({ type: 'MSG_1', __pageId__: window.pageId }) + expect(nextStub).toBeCalledWith({ type: 1, __pageId__: window.pageId }) - browser.runtime.onMessage.dispatch({ type: 'MSG_2', __pageId__: window.pageId }) + browser.runtime.onMessage.dispatch({ type: 2, __pageId__: window.pageId }) expect(nextStub).toHaveBeenCalledTimes(2) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(1) - expect(nextStub).toBeCalledWith({ type: 'MSG_2', __pageId__: window.pageId }) + expect(nextStub).toBeCalledWith({ type: 2, __pageId__: window.pageId }) }) it('with message type', () => { @@ -752,7 +753,7 @@ describe('Browser API Wapper', () => { const nextStub = jest.fn() const errorStub = jest.fn() const completeStub = jest.fn() - message.self.createStream('MSG_1') + message.self.createStream(1) .pipe(take(1)) .subscribe(nextStub, errorStub, completeStub) expect(browser.runtime.onMessage.addListener.calledOnce).toBeTruthy() @@ -760,16 +761,16 @@ describe('Browser API Wapper', () => { expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_2', __pageId__: window.pageId }) + browser.runtime.onMessage.dispatch({ type: 2, __pageId__: window.pageId }) expect(nextStub).toHaveBeenCalledTimes(0) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_1', __pageId__: window.pageId }) + browser.runtime.onMessage.dispatch({ type: 1, __pageId__: window.pageId }) expect(nextStub).toHaveBeenCalledTimes(1) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(1) - expect(nextStub).toBeCalledWith({ type: 'MSG_1', __pageId__: window.pageId }) + expect(nextStub).toBeCalledWith({ type: 1, __pageId__: window.pageId }) }) it('with selector', () => { window.pageId = 1 @@ -784,24 +785,24 @@ describe('Browser API Wapper', () => { expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_2', __pageId__: window.pageId }) + browser.runtime.onMessage.dispatch({ type: 2, __pageId__: window.pageId }) expect(nextStub).toHaveBeenCalledTimes(1) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - expect(nextStub).toBeCalledWith('MSG_2') + expect(nextStub).toBeCalledWith(2) - browser.runtime.onMessage.dispatch({ type: 'MSG_1', __pageId__: window.pageId }) + browser.runtime.onMessage.dispatch({ type: 1, __pageId__: window.pageId }) expect(nextStub).toHaveBeenCalledTimes(2) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(1) - expect(nextStub).toBeCalledWith('MSG_1') + expect(nextStub).toBeCalledWith(1) }) it('with message type and selector', () => { window.pageId = 1 const nextStub = jest.fn() const errorStub = jest.fn() const completeStub = jest.fn() - message.self.createStream('MSG_1', x => x.type) + message.self.createStream(1, x => x.type) .pipe(take(1)) .subscribe(nextStub, errorStub, completeStub) expect(browser.runtime.onMessage.addListener.calledOnce).toBeTruthy() @@ -809,16 +810,16 @@ describe('Browser API Wapper', () => { expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_2', __pageId__: window.pageId }) + browser.runtime.onMessage.dispatch({ type: 2, __pageId__: window.pageId }) expect(nextStub).toHaveBeenCalledTimes(0) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(0) - browser.runtime.onMessage.dispatch({ type: 'MSG_1', __pageId__: window.pageId }) + browser.runtime.onMessage.dispatch({ type: 1, __pageId__: window.pageId }) expect(nextStub).toHaveBeenCalledTimes(1) expect(errorStub).toHaveBeenCalledTimes(0) expect(completeStub).toHaveBeenCalledTimes(1) - expect(nextStub).toBeCalledWith('MSG_1') + expect(nextStub).toBeCalledWith(1) }) }) }) diff --git a/test/specs/background/server.spec.ts b/test/specs/background/server.spec.ts index aa0452551..30a51a337 100644 --- a/test/specs/background/server.spec.ts +++ b/test/specs/background/server.spec.ts @@ -1,6 +1,7 @@ import { appConfigFactory, AppConfig } from '@/app-config' import * as browserWrap from '@/_helpers/browser-api' import sinon from 'sinon' +import { MsgType } from '@/typings/message' describe('Server', () => { const chsToChz = jest.fn() @@ -57,7 +58,7 @@ describe('Server', () => { describe('Create Tab', () => { it('called with escape', () => { browser.runtime.onMessage.dispatch({ - type: 'OPEN_URL', + type: MsgType.OpenURL, url: 'https://test.com/%s%z', escape: true, text: 'test', @@ -70,7 +71,7 @@ describe('Server', () => { it('called without escape', () => { browser.runtime.onMessage.dispatch({ - type: 'OPEN_URL', + type: MsgType.OpenURL, url: 'https://test.com/', text: 'test', }) @@ -82,7 +83,7 @@ describe('Server', () => { it('Audio Play', () => { browser.runtime.onMessage.dispatch({ - type: 'AUDIO_PLAY', + type: MsgType.PlayAudio, src: 'https://test.com/a.mp3', }) expect(play).toHaveBeenCalledTimes(1) @@ -95,7 +96,7 @@ describe('Server', () => { const rejectStub = jest.fn() browser.runtime.onMessage['_listeners'].forEach(f => f({ - type: 'FETCH_DICT_RESULT', + type: MsgType.FetchDictResult, text: 'test', }) .then(resolveStub, rejectStub) @@ -110,7 +111,7 @@ describe('Server', () => { it('should search text', () => { browser.runtime.onMessage.dispatch({ - type: 'FETCH_DICT_RESULT', + type: MsgType.FetchDictResult, dict: 'bing', text: 'test', }) @@ -125,16 +126,16 @@ describe('Server', () => { const queryStub = jest.fn(() => Promise.resolve([{ id: 100 }])) browser.tabs.query.callsFake(queryStub) browser.tabs.sendMessage.callsFake(() => 'test') - browser.runtime.onMessage.dispatch({ type: 'PRELOAD_SELECTION' }) + browser.runtime.onMessage.dispatch({ type: MsgType.PreloadSelection }) browser.runtime.onMessage['_listeners'].forEach(f => - f({ type: 'PRELOAD_SELECTION' }) + f({ type: MsgType.PreloadSelection }) .then(resolveStub, rejectStub) ) setTimeout(() => { expect(resolveStub).toHaveBeenCalledTimes(1) expect(resolveStub).toHaveBeenCalledWith('test') expect(rejectStub).toHaveBeenCalledTimes(0) - expect(browser.tabs.sendMessage.calledWith(100, { type: '__PRELOAD_SELECTION__' })).toBeTruthy() + expect(browser.tabs.sendMessage.calledWith(100, { type: MsgType.__PreloadSelection__ })).toBeTruthy() done() }, 0) }) diff --git a/test/specs/selection/index.spec.ts b/test/specs/selection/index.spec.ts index 0d78ee6e6..b1c1f8a6b 100644 --- a/test/specs/selection/index.spec.ts +++ b/test/specs/selection/index.spec.ts @@ -4,6 +4,7 @@ import * as BrowserApiMock from '@/_helpers/__mocks__/browser-api' import { SelectionMock } from '@/_helpers/__mocks__/selection' import * as ConfigManagerMock from '@/_helpers/__mocks__/config-manager' import '@/selection' +import { MsgType } from '@/typings/message' jest.mock('@/_helpers/browser-api') jest.mock('@/_helpers/config-manager') @@ -20,7 +21,7 @@ const { dispatchAppConfigEvent }: { dispatchAppConfigEvent: typeof ConfigManagerMock.dispatchAppConfigEvent } = require('@/_helpers/config-manager') -describe('Selection', () => { +describe('Message Selection', () => { beforeEach(() => { browser.flush() window.name = '' @@ -42,7 +43,7 @@ describe('Selection', () => { setTimeout(() => { expect(message.self.send).toHaveBeenCalledTimes(1) expect(message.self.send).toBeCalledWith({ - type: 'SELECTION', + type: MsgType.Selection, selectionInfo: expect.objectContaining({ text: '' }), }) done() @@ -64,7 +65,7 @@ describe('Selection', () => { setTimeout(() => { expect(message.self.send).toHaveBeenCalledTimes(1) expect(message.self.send).toBeCalledWith({ - type: 'SELECTION', + type: MsgType.Selection, selectionInfo: expect.objectContaining({ text: '' }), }) done() @@ -88,7 +89,7 @@ describe('Selection', () => { setTimeout(() => { expect(message.self.send).toHaveBeenCalledTimes(1) expect(message.self.send).toBeCalledWith({ - type: 'SELECTION', + type: MsgType.Selection, selectionInfo: expect.objectContaining({ text: '' }), }) done() @@ -105,7 +106,7 @@ describe('Selection', () => { setTimeout(() => { expect(message.self.send).toHaveBeenCalledTimes(1) expect(message.self.send).toBeCalledWith({ - type: 'SELECTION', + type: MsgType.Selection, mouseX: 10, mouseY: 10, ctrlKey: false, @@ -235,7 +236,7 @@ describe('Selection', () => { } setTimeout(() => { expect(message.self.send).toHaveBeenCalledTimes(1) - expect(message.self.send).toBeCalledWith({ type: 'TRIPLE_CTRL' }) + expect(message.self.send).toBeCalledWith({ type: MsgType.TripleCtrl }) done() }, 510) })