diff options
author | Shin'ya Ueoka <ueokande@i-beam.org> | 2020-08-12 21:01:02 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-12 21:01:02 +0900 |
commit | bf6762f0c0c47a20b6a3e722711fafc6611793a9 (patch) | |
tree | 67bfdcee88c8fb2bc19277e58684dcf5d2d03be4 | |
parent | 6f7f501c699c53eb63ce5576cf2464ecf4cfe162 (diff) | |
parent | 7e8c99d43a402b9e025a710a00879d557ac5b071 (diff) |
Merge pull request #798 from ueokande/eslint
Improve eslint
28 files changed, 112 insertions, 129 deletions
@@ -7,9 +7,11 @@ }, "extends": [ + "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react/recommended", - "plugin:prettier/recommended" + "plugin:prettier/recommended", + "prettier/react" ], "plugins": [ "@typescript-eslint", @@ -23,16 +25,16 @@ "jsx": true } }, + "settings": { + "react": { + "version": "detect" + } + }, "rules": { - "@typescript-eslint/ban-types": "off", - "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-extra-non-null-assertion": "off", - "@typescript-eslint/no-namespace": "off", "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], - "@typescript-eslint/no-use-before-define": "off" + "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }] } } diff --git a/e2e/follow.test.ts b/e2e/follow.test.ts index 5fb6c58..90f9a59 100644 --- a/e2e/follow.test.ts +++ b/e2e/follow.test.ts @@ -164,7 +164,7 @@ describe("follow test", () => { await page.sendKeys("a"); const tagName = (await webdriver.executeScript( - () => document.activeElement!!.tagName + () => document.activeElement!.tagName )) as string; assert.strictEqual(tagName.toLowerCase(), "input"); }); @@ -188,7 +188,7 @@ describe("follow test", () => { await page.sendKeys("a"); const tagName = (await webdriver.executeScript( - () => document.activeElement!!.tagName + () => document.activeElement!.tagName )) as string; assert.strictEqual(tagName.toLowerCase(), "input"); }); diff --git a/e2e/lib/Console.ts b/e2e/lib/Console.ts index 0bae2f7..2c128d1 100644 --- a/e2e/lib/Console.ts +++ b/e2e/lib/Console.ts @@ -62,12 +62,12 @@ export class Console { const objs = []; for (const li of Array.from(items)) { if (li.classList.contains("vimvixen-console-completion-title")) { - objs.push({ type: "title", text: li.textContent!!.trim() }); - } else if ("vimvixen-console-completion-item") { + objs.push({ type: "title", text: li.textContent!.trim() }); + } else if (li.classList.contains("vimvixen-console-completion-item")) { const highlight = li.classList.contains( "vimvixen-completion-selected" ); - objs.push({ type: "item", text: li.textContent!!.trim(), highlight }); + objs.push({ type: "item", text: li.textContent!.trim(), highlight }); } else { throw new Error(`unexpected class: ${li.className}`); } diff --git a/e2e/lib/JSONOptionPage.ts b/e2e/lib/JSONOptionPage.ts index 1c2db5b..0f2b0a7 100644 --- a/e2e/lib/JSONOptionPage.ts +++ b/e2e/lib/JSONOptionPage.ts @@ -15,7 +15,7 @@ export default class JSONOptionPage { ); await textarea.sendKeys(" "); await this.webdriver.executeScript(() => - document.querySelector("textarea")!!.blur() + document.querySelector("textarea")!.blur() ); } diff --git a/e2e/lib/TestServer.ts b/e2e/lib/TestServer.ts index e0c711b..dc86ba2 100644 --- a/e2e/lib/TestServer.ts +++ b/e2e/lib/TestServer.ts @@ -41,7 +41,7 @@ export default class TestServer { this.http = http.createServer(this.app); return new Promise((resolve) => { - this.http!!.listen(this.port, this.address, () => { + this.http!.listen(this.port, this.address, () => { resolve(); }); }); @@ -52,7 +52,7 @@ export default class TestServer { return Promise.resolve(); } return new Promise((resolve) => { - this.http!!.close(() => { + this.http!.close(() => { this.http = undefined; resolve(); }); diff --git a/e2e/mark.test.ts b/e2e/mark.test.ts index d7ec26c..0f09d82 100644 --- a/e2e/mark.test.ts +++ b/e2e/mark.test.ts @@ -86,7 +86,7 @@ describe("mark test", () => { handles = await webdriver.getAllWindowHandles(); assert.strictEqual(handles.length, 2); }); - await webdriver.switchTo().window(handles!![0]); + await webdriver.switchTo().window(handles![0]); page = await Page.navigateTo(webdriver, server.url("/#second")); await page.sendKeys("'", "A"); diff --git a/e2e/repeat_n_times.test.ts b/e2e/repeat_n_times.test.ts index 303aa34..5a9b172 100644 --- a/e2e/repeat_n_times.test.ts +++ b/e2e/repeat_n_times.test.ts @@ -23,8 +23,6 @@ describe("tab test", () => { webdriver = lanthan.getWebDriver(); browser = lanthan.getWebExtBrowser(); await server.start(); - - browser = browser; }); after(async () => { diff --git a/src/@types/browser/index.d.ts b/src/@types/browser/index.d.ts new file mode 100644 index 0000000..14acfe0 --- /dev/null +++ b/src/@types/browser/index.d.ts @@ -0,0 +1,13 @@ +// NOTE: window.find is not standard API +// https://developer.mozilla.org/en-US/docs/Web/API/Window/find +interface Window { + find( + aString: string, + aCaseSensitive?: boolean, + aBackwards?: boolean, + aWrapAround?: boolean, + aWholeWord?: boolean, + aSearchInFrames?: boolean, + aShowDialog?: boolean + ): boolean; +} diff --git a/src/@types/web-ext-api/index.d.ts b/src/@types/web-ext-api/index.d.ts new file mode 100644 index 0000000..7eed334 --- /dev/null +++ b/src/@types/web-ext-api/index.d.ts @@ -0,0 +1,14 @@ +declare namespace browser.browserSettings.homepageOverride { + type BrowserSettings = { + value: string; + levelOfControl: LevelOfControlType; + }; + + type LevelOfControlType = + | "not_controllable" + | "controlled_by_other_extensions" + | "controllable_by_this_extension" + | "controlled_by_this_extension"; + + function get(param: { [key: string]: string }): Promise<BrowserSettings>; +} diff --git a/src/background/completion/impl/BookmarkRepositoryImpl.ts b/src/background/completion/impl/BookmarkRepositoryImpl.ts index 2bc779d..ed6c5a6 100644 --- a/src/background/completion/impl/BookmarkRepositoryImpl.ts +++ b/src/background/completion/impl/BookmarkRepositoryImpl.ts @@ -23,7 +23,7 @@ export default class CachedBookmarkRepository implements BookmarkRepository { .filter((item) => { let url = undefined; try { - url = new URL(item.url!!); + url = new URL(item.url!); } catch (e) { return false; } @@ -31,8 +31,8 @@ export default class CachedBookmarkRepository implements BookmarkRepository { }) .slice(0, COMPLETION_ITEM_LIMIT) .map((item) => ({ - title: item.title!!, - url: item.url!!, + title: item.title!, + url: item.url!, })); } @@ -41,7 +41,7 @@ export default class CachedBookmarkRepository implements BookmarkRepository { return query.split(" ").every((keyword) => { return ( item.title.toLowerCase().includes(keyword.toLowerCase()) || - item.url!!.includes(keyword) + item.url!.includes(keyword) ); }); }); diff --git a/src/background/completion/impl/HistoryRepositoryImpl.ts b/src/background/completion/impl/HistoryRepositoryImpl.ts index b1992a4..3bf064e 100644 --- a/src/background/completion/impl/HistoryRepositoryImpl.ts +++ b/src/background/completion/impl/HistoryRepositoryImpl.ts @@ -36,8 +36,8 @@ export default class CachedHistoryRepository implements HistoryRepository { .sort((x, y) => Number(y.visitCount) - Number(x.visitCount)) .slice(0, COMPLETION_ITEM_LIMIT) .map((item) => ({ - title: item.title!!, - url: item.url!!, + title: item.title!, + url: item.url!, })); } @@ -59,8 +59,8 @@ export default class CachedHistoryRepository implements HistoryRepository { return items.filter((item) => { return query.split(" ").every((keyword) => { return ( - item.title!!.toLowerCase().includes(keyword.toLowerCase()) || - item.url!!.includes(keyword) + item.title!.toLowerCase().includes(keyword.toLowerCase()) || + item.url!.includes(keyword) ); }); }); diff --git a/src/background/completion/impl/TabRepositoryImpl.ts b/src/background/completion/impl/TabRepositoryImpl.ts index 5e33e5a..a279bd4 100644 --- a/src/background/completion/impl/TabRepositoryImpl.ts +++ b/src/background/completion/impl/TabRepositoryImpl.ts @@ -30,10 +30,10 @@ export default class TabRepositoryImpl implements TabRepository { private static toEntity(tab: browser.tabs.Tab): Tab { return { - id: tab.id!!, - url: tab.url!!, + id: tab.id!, + url: tab.url!, active: tab.active, - title: tab.title!!, + title: tab.title!, faviconUrl: tab.favIconUrl, index: tab.index, }; diff --git a/src/background/presenters/TabPresenter.ts b/src/background/presenters/TabPresenter.ts index 09cfa23..2f8f5d9 100644 --- a/src/background/presenters/TabPresenter.ts +++ b/src/background/presenters/TabPresenter.ts @@ -8,7 +8,17 @@ type Tab = browser.tabs.Tab; export default interface TabPresenter { open(url: string, tabId?: number): Promise<Tab>; - create(url: string, opts?: object): Promise<Tab>; + create( + url: string, + opts?: { + active?: boolean; + cookieStoreId?: string; + index?: number; + openerTabId?: number; + pinned?: boolean; + windowId?: number; + } + ): Promise<Tab>; getCurrent(): Promise<Tab>; @@ -44,7 +54,17 @@ export class TabPresenterImpl implements TabPresenter { return browser.tabs.update(tabId, { url }); } - create(url: string, opts?: object): Promise<Tab> { + create( + url: string, + opts?: { + active?: boolean; + cookieStoreId?: string; + index?: number; + openerTabId?: number; + pinned?: boolean; + windowId?: number; + } + ): Promise<Tab> { return browser.tabs.create({ url, ...opts }); } diff --git a/src/background/repositories/BrowserSettingRepository.ts b/src/background/repositories/BrowserSettingRepository.ts index 20013f4..e24874b 100644 --- a/src/background/repositories/BrowserSettingRepository.ts +++ b/src/background/repositories/BrowserSettingRepository.ts @@ -1,21 +1,6 @@ import { injectable } from "tsyringe"; import * as urls from "../../shared/urls"; -declare namespace browser.browserSettings.homepageOverride { - type BrowserSettings = { - value: string; - levelOfControl: LevelOfControlType; - }; - - type LevelOfControlType = - | "not_controllable" - | "controlled_by_other_extensions" - | "controllable_by_this_extension" - | "controlled_by_this_extension"; - - function get(param: object): Promise<BrowserSettings>; -} - @injectable() export default class BrowserSettingRepository { async getHomepageUrls(): Promise<string[]> { diff --git a/src/background/usecases/NavigateUseCase.ts b/src/background/usecases/NavigateUseCase.ts index 2e887e7..974606c 100644 --- a/src/background/usecases/NavigateUseCase.ts +++ b/src/background/usecases/NavigateUseCase.ts @@ -11,27 +11,27 @@ export default class NavigateUseCase { async openHistoryNext(): Promise<void> { const tab = await this.tabPresenter.getCurrent(); - await this.navigateClient.historyNext(tab.id!!); + await this.navigateClient.historyNext(tab.id!); } async openHistoryPrev(): Promise<void> { const tab = await this.tabPresenter.getCurrent(); - await this.navigateClient.historyPrev(tab.id!!); + await this.navigateClient.historyPrev(tab.id!); } async openLinkNext(): Promise<void> { const tab = await this.tabPresenter.getCurrent(); - await this.navigateClient.linkNext(tab.id!!); + await this.navigateClient.linkNext(tab.id!); } async openLinkPrev(): Promise<void> { const tab = await this.tabPresenter.getCurrent(); - await this.navigateClient.linkPrev(tab.id!!); + await this.navigateClient.linkPrev(tab.id!); } async openParent(): Promise<void> { const tab = await this.tabPresenter.getCurrent(); - const url = new URL(tab.url!!); + const url = new URL(tab.url!); if (url.hash.length > 0) { url.hash = ""; } else if (url.search.length > 0) { @@ -50,7 +50,7 @@ export default class NavigateUseCase { async openRoot(): Promise<void> { const tab = await this.tabPresenter.getCurrent(); - const url = new URL(tab.url!!); + const url = new URL(tab.url!); await this.tabPresenter.open(url.origin); } } diff --git a/src/background/usecases/SettingUseCase.ts b/src/background/usecases/SettingUseCase.ts index ccee227..34c1f3a 100644 --- a/src/background/usecases/SettingUseCase.ts +++ b/src/background/usecases/SettingUseCase.ts @@ -36,7 +36,7 @@ export default class SettingUseCase { this.showUnableToLoad(e); value = DefaultSettingData.toSettings(); } - await this.cachedSettingRepository.update(value!!); + await this.cachedSettingRepository.update(value!); return value; } diff --git a/src/content/presenters/FindPresenter.ts b/src/content/presenters/FindPresenter.ts index 117142c..b25190c 100644 --- a/src/content/presenters/FindPresenter.ts +++ b/src/content/presenters/FindPresenter.ts @@ -4,26 +4,6 @@ export default interface FindPresenter { clearSelection(): void; } -// window.find(aString, aCaseSensitive, aBackwards, aWrapAround, -// aWholeWord, aSearchInFrames); -// -// NOTE: window.find is not standard API -// https://developer.mozilla.org/en-US/docs/Web/API/Window/find -interface MyWindow extends Window { - find( - aString: string, - aCaseSensitive?: boolean, - aBackwards?: boolean, - aWrapAround?: boolean, - aWholeWord?: boolean, - aSearchInFrames?: boolean, - aShowDialog?: boolean - ): boolean; -} - -// eslint-disable-next-line no-var, vars-on-top, init-declarations -declare var window: MyWindow; - export class FindPresenterImpl implements FindPresenter { find(keyword: string, backwards: boolean): boolean { const caseSensitive = false; diff --git a/src/content/repositories/ClipboardRepository.ts b/src/content/repositories/ClipboardRepository.ts index a700543..20e7367 100644 --- a/src/content/repositories/ClipboardRepository.ts +++ b/src/content/repositories/ClipboardRepository.ts @@ -15,7 +15,7 @@ export class ClipboardRepositoryImpl { textarea.focus(); const ok = window.document.execCommand("paste"); - const value = textarea.textContent!!; + const value = textarea.textContent!; textarea.remove(); if (!ok) { diff --git a/src/content/usecases/FollowMasterUseCase.ts b/src/content/usecases/FollowMasterUseCase.ts index 329f05a..88c682e 100644 --- a/src/content/usecases/FollowMasterUseCase.ts +++ b/src/content/usecases/FollowMasterUseCase.ts @@ -47,7 +47,7 @@ export default class FollowMasterUseCase { for (let i = 0; i < frameElements.length; ++i) { const ele = frameElements[i] as HTMLFrameElement | HTMLIFrameElement; const { left: frameX, top: frameY } = ele.getBoundingClientRect(); - const client = this.followSlaveClientFactory.create(ele.contentWindow!!); + const client = this.followSlaveClientFactory.create(ele.contentWindow!); client.requestHintCount( { width: viewWidth, height: viewHeight }, { x: frameX, y: frameY } @@ -59,7 +59,7 @@ export default class FollowMasterUseCase { createSlaveHints(count: number, sender: Window): void { const produced = []; for (let i = 0; i < count; ++i) { - const tag = this.producer!!.produce(); + const tag = this.producer!.produce(); produced.push(tag); this.followMasterRepository.addTag(tag); } diff --git a/src/settings/components/index.tsx b/src/settings/components/index.tsx index 5793a8f..9d71cac 100644 --- a/src/settings/components/index.tsx +++ b/src/settings/components/index.tsx @@ -106,9 +106,9 @@ class SettingsComponent extends React.Component<Props> { let fields = null; const disabled = this.props.error.length > 0; if (this.props.source === "form") { - fields = this.renderFormFields(this.props.form!!); + fields = this.renderFormFields(this.props.form!); } else if (this.props.source === "json") { - fields = this.renderJsonFields(this.props.json!!, this.props.error); + fields = this.renderJsonFields(this.props.json!, this.props.error); } return ( <div> diff --git a/src/shared/Command.ts b/src/shared/Command.ts index 05b8b83..70347bf 100644 --- a/src/shared/Command.ts +++ b/src/shared/Command.ts @@ -13,32 +13,3 @@ export enum Command { Set = "set", Help = "help", } - -export namespace Command { - export function members(): Command[] { - return [ - Command.Open, - Command.TabOpen, - Command.WindowOpen, - Command.Buffer, - Command.BufferDelete, - Command.BufferDeleteForce, - Command.BuffersDelete, - Command.BuffersDeleteForce, - Command.AddBookmark, - Command.Quit, - Command.QuitAll, - Command.Set, - Command.Help, - ]; - } - - export function valueOf(value: string): Command { - const map = new Map(members().map((cmd) => [cmd.toString(), cmd])); - const cmd = map.get(value); - if (!cmd) { - throw new Error(`unknown command '${value}`); - } - return cmd; - } -} diff --git a/src/shared/settings/Settings.ts b/src/shared/settings/Settings.ts index 6f178ea..f37fbf0 100644 --- a/src/shared/settings/Settings.ts +++ b/src/shared/settings/Settings.ts @@ -43,7 +43,7 @@ export default class Settings { const valid = validate(json); if (!valid) { const message = (validate as any) - .errors!!.map((err: Ajv.ErrorObject) => { + .errors!.map((err: Ajv.ErrorObject) => { return `'${err.dataPath}' ${err.message}`; }) .join("; "); diff --git a/test/background/completion/TabCompletionUseCase.test.ts b/test/background/completion/TabCompletionUseCase.test.ts index d8aa385..e1a88a2 100644 --- a/test/background/completion/TabCompletionUseCase.test.ts +++ b/test/background/completion/TabCompletionUseCase.test.ts @@ -18,7 +18,7 @@ class MockTabRepository implements TabRepositoryImpl { } class MockTabPresenter implements TabPresenter { - create(_url: string, _opts?: object): Promise<browser.tabs.Tab> { + create(_url: string, _opts?: unknown): Promise<browser.tabs.Tab> { throw new Error("not implemented"); } diff --git a/test/background/repositories/Mark.test.ts b/test/background/repositories/Mark.test.ts index 5cee5b6..3b054e5 100644 --- a/test/background/repositories/Mark.test.ts +++ b/test/background/repositories/Mark.test.ts @@ -13,13 +13,13 @@ describe("background/repositories/mark", () => { await repository.setMark("A", mark); - let got = (await repository.getMark("A"))!!; + let got = (await repository.getMark("A"))!; expect(got.tabId).to.equal(1); expect(got.url).to.equal("http://example.com"); expect(got.x).to.equal(10); expect(got.y).to.equal(30); - got = (await repository.getMark("B"))!!; + got = (await repository.getMark("B"))!; expect(got).to.be.undefined; }); }); diff --git a/test/background/usecases/NavigateUseCase.test.ts b/test/background/usecases/NavigateUseCase.test.ts index 7263627..086d6cd 100644 --- a/test/background/usecases/NavigateUseCase.test.ts +++ b/test/background/usecases/NavigateUseCase.test.ts @@ -5,7 +5,7 @@ import NavigateClient from "../../../src/background/clients/NavigateClient"; import * as sinon from "sinon"; class MockTabPresenter implements TabPresenter { - create(_url: string, _opts?: object): Promise<browser.tabs.Tab> { + create(_url: string, _opts?: unknown): Promise<browser.tabs.Tab> { throw new Error("not implemented"); } diff --git a/test/content/presenters/Hint.test.ts b/test/content/presenters/Hint.test.ts index f961f88..1a7c868 100644 --- a/test/content/presenters/Hint.test.ts +++ b/test/content/presenters/Hint.test.ts @@ -13,17 +13,17 @@ describe("Hint", () => { describe("#constructor", () => { it("creates a hint element with tag name", () => { - const link = document.getElementById("test-link")!!; + const link = document.getElementById("test-link")!; new Hint(link, "abc"); const elem = document.querySelector(".vimvixen-hint"); - expect(elem!!.textContent!!.trim()).to.be.equal("abc"); + expect(elem!.textContent!.trim()).to.be.equal("abc"); }); }); describe("#show", () => { it("shows an element", () => { - const link = document.getElementById("test-link")!!; + const link = document.getElementById("test-link")!; const hint = new Hint(link, "abc"); hint.hide(); hint.show(); @@ -46,10 +46,10 @@ describe("Hint", () => { describe("#remove", () => { it("removes an element", () => { - const link = document.getElementById("test-link")!!; + const link = document.getElementById("test-link")!; const hint = new Hint(link, "abc"); - const elem = document.querySelector(".vimvixen-hint")!!; + const elem = document.querySelector(".vimvixen-hint")!; expect(elem.parentElement).to.not.be.null; hint.remove(); expect(elem.parentElement).to.be.null; diff --git a/test/settings/components/ui/input.test.tsx b/test/settings/components/ui/input.test.tsx index 191bfed..d244d8f 100644 --- a/test/settings/components/ui/input.test.tsx +++ b/test/settings/components/ui/input.test.tsx @@ -25,8 +25,8 @@ describe("settings/ui/Input", () => { ); }); - const label = document.querySelector("label")!!; - const input = document.querySelector("input")!!; + const label = document.querySelector("label")!; + const input = document.querySelector("input")!; expect(label.textContent).to.contain("myfield"); expect(input.type).to.contain("text"); expect(input.name).to.contain("myname"); @@ -50,7 +50,7 @@ describe("settings/ui/Input", () => { ); }); - const input = document.querySelector("input")!!; + const input = document.querySelector("input")!; input.value = "newvalue"; ReactTestUtils.Simulate.change(input); }); @@ -65,8 +65,8 @@ describe("settings/ui/Input", () => { ); }); - const label = document.querySelector("label")!!; - const input = document.querySelector("input")!!; + const label = document.querySelector("label")!; + const input = document.querySelector("input")!; expect(label.textContent).to.contain("myfield"); expect(input.type).to.contain("radio"); expect(input.name).to.contain("myname"); @@ -111,9 +111,9 @@ describe("settings/ui/Input", () => { ); }); - const label = document.querySelector("label")!!; - const textarea = document.querySelector("textarea")!!; - const error = document.querySelector(".settings-ui-input-error")!!; + const label = document.querySelector("label")!; + const textarea = document.querySelector("textarea")!; + const error = document.querySelector(".settings-ui-input-error")!; expect(label.textContent).to.contain("myfield"); expect(textarea.nodeName).to.contain("TEXTAREA"); expect(textarea.name).to.contain("myname"); @@ -138,7 +138,7 @@ describe("settings/ui/Input", () => { ); }); - const input = document.querySelector("textarea")!!; + const input = document.querySelector("textarea")!; input.value = "newvalue"; ReactTestUtils.Simulate.change(input); }); diff --git a/test/settings/reducers/setting.test.ts b/test/settings/reducers/setting.test.ts index 99c4c80..34e76e2 100644 --- a/test/settings/reducers/setting.test.ts +++ b/test/settings/reducers/setting.test.ts @@ -24,7 +24,7 @@ describe("settings setting reducer", () => { }; const state = settingReducer(undefined, action); expect(state.source).to.equal("json"); - expect(state.json!!.toJSONText()).to.equal('{ "key": "value" }'); + expect(state.json!.toJSONText()).to.equal('{ "key": "value" }'); expect(state.form).to.deep.equal(action.form); }); @@ -36,7 +36,7 @@ describe("settings setting reducer", () => { }; const state = settingReducer(undefined, action); expect(state.error).to.equal("bad value"); - expect(state.json!!.toJSONText()).to.equal("{}"); + expect(state.json!.toJSONText()).to.equal("{}"); }); it("return next state for SETTING_SWITCH_TO_FORM", () => { @@ -55,7 +55,7 @@ describe("settings setting reducer", () => { json: JSONTextSettings.fromText("{}"), }; const state = settingReducer(undefined, action); - expect(state.json!!.toJSONText()).to.equal("{}"); + expect(state.json!.toJSONText()).to.equal("{}"); expect(state.source).to.equal(SettingSource.JSON); }); }); |