import { describe, it, expect, afterAll, vi } from "vitest"; import { configMetadata } from "../../src/ts/config/metadata"; import { __testing } from "../../src/ts/config/testing"; import { setConfig } from "../../src/ts/config/setters"; import { ConfigKey, Config as ConfigType } from "@monkeytype/schemas/configs"; const { replaceConfig, getConfig } = __testing; type TestsByConfig = Partial<{ [K in keyof ConfigType]: (T & { value: ConfigType[K] })[]; }>; describe("ConfigMeta", () => { afterAll(() => { replaceConfig({}); vi.resetModules(); }); it("should have changeRequiresRestart defined", () => { const configsRequiringRestarts = Object.entries(configMetadata) .filter(([_key, value]) => value.changeRequiresRestart) .map(([key]) => key) .sort(); expect(configsRequiringRestarts).toEqual( [ "punctuation", "numbers", "words", "time", "mode", "quoteLength", "language", "difficulty", "minWpmCustomSpeed", "minWpm", "minAcc", "minAccCustom", "minBurst", "minBurstCustomSpeed", "britishEnglish", "funbox", "customLayoutfluid", "strictSpace", "stopOnError", "lazyMode", "layout", "codeUnindentOnBackspace", ].sort(), ); }); it("should have triggerResize defined", () => { const configsWithTriggeResize = Object.entries(configMetadata) .filter(([_key, value]) => value.triggerResize === true) .map(([key]) => key) .sort(); expect(configsWithTriggeResize).toEqual( [ "fontSize", "keymapSize", "maxLineWidth", "tapeMode", "tapeMargin", ].sort(), ); }); describe("overrideValue", () => { const testCases: TestsByConfig<{ given?: Partial; expected: Partial; }> = { punctuation: [ { value: true, expected: { punctuation: true } }, { value: true, given: { mode: "quote" }, expected: { punctuation: false }, }, ], numbers: [ { value: true, expected: { numbers: true } }, { value: true, given: { mode: "quote" }, expected: { numbers: false }, }, ], customLayoutfluid: [ { value: ["qwerty", "qwerty", "qwertz"], expected: { customLayoutfluid: ["qwerty", "qwertz"] }, }, ], customPolyglot: [ { value: ["english", "polish", "english"], expected: { customPolyglot: ["english", "polish"] }, }, ], keymapSize: [ { value: 1, expected: { keymapSize: 1 } }, { value: 1.234, expected: { keymapSize: 1.2 } }, { value: 0.4, expected: { keymapSize: 0.5 } }, { value: 3.6, expected: { keymapSize: 3.5 } }, ], customBackground: [ { value: " https://example.com/test.jpg ", expected: { customBackground: "https://example.com/test.jpg" }, }, ], accountChart: [ { value: ["on", "off", "off", "off"], expected: { accountChart: ["on", "off", "off", "off"] }, }, { value: ["off", "off", "off", "off"], given: { accountChart: ["on", "off", "off", "off"] }, expected: { accountChart: ["off", "on", "off", "off"] }, }, { value: ["off", "off", "on", "on"], given: { accountChart: ["off", "on", "off", "off"] }, expected: { accountChart: ["on", "off", "on", "on"] }, }, ], }; it.for( Object.entries(testCases).flatMap(([key, value]) => value.flatMap((it) => ({ key: key as ConfigKey, ...it })), ), )( `$key value=$value given=$given expect=$expected`, ({ key, value, given, expected }) => { //GIVEN replaceConfig(given ?? {}); //WHEN setConfig(key, value as any); //THEN expect(getConfig()).toMatchObject(expected); }, ); }); describe("isBlocked", () => { const testCases: TestsByConfig<{ given?: Partial; fail?: true; }> = { funbox: [ { value: ["gibberish"], given: { mode: "quote" }, fail: true, }, ], showAllLines: [ { value: true, given: { tapeMode: "off" } }, { value: false, given: { tapeMode: "word" } }, { value: true, given: { tapeMode: "word" }, fail: true }, ], monkey: [{ value: false, given: { liveSpeedStyle: "text" } }], liveSpeedStyle: [ { value: "mini", given: { monkey: true } }, { value: "text", given: { monkey: true } }, ], liveAccStyle: [ { value: "mini", given: { monkey: true } }, { value: "text", given: { monkey: true } }, ], }; it.for( Object.entries(testCases).flatMap(([key, value]) => value.flatMap((it) => ({ key: key as ConfigKey, ...it })), ), )( `$key value=$value given=$given fail=$fail`, ({ key, value, given, fail }) => { //GIVEN replaceConfig(given ?? {}); //WHEN const applied = setConfig(key, value as any); //THEN expect(applied).toEqual(!fail); }, ); }); describe("overrideConfig", () => { const testCases: TestsByConfig<{ given: Partial; expected?: Partial; }> = { mode: [ { value: "time", given: { numbers: true, punctuation: true } }, { value: "custom", given: { numbers: true, punctuation: true }, expected: { numbers: false, punctuation: false }, }, { value: "quote", given: { numbers: true, punctuation: true }, expected: { numbers: false, punctuation: false }, }, { value: "zen", given: { numbers: true, punctuation: true }, expected: { numbers: false, punctuation: false }, }, ], numbers: [{ value: false, given: { mode: "quote" } }], freedomMode: [ { value: false, given: { confidenceMode: "on" }, expected: { confidenceMode: "on" }, }, { value: true, given: { confidenceMode: "on" }, expected: { confidenceMode: "off" }, }, ], stopOnError: [ { value: "off", given: { confidenceMode: "on" }, expected: { confidenceMode: "on" }, }, { value: "word", given: { confidenceMode: "on" }, expected: { confidenceMode: "off" }, }, ], confidenceMode: [ { value: "off", given: { freedomMode: true, stopOnError: "word" }, expected: { freedomMode: true, stopOnError: "word" }, }, { value: "on", given: { freedomMode: true, stopOnError: "word" }, expected: { freedomMode: false, stopOnError: "off" }, }, ], monkey: [ { value: false, given: { liveSpeedStyle: "text", liveAccStyle: "text" }, expected: { liveSpeedStyle: "text", liveAccStyle: "text", }, }, { value: true, given: { liveSpeedStyle: "text", liveAccStyle: "text" }, expected: { liveSpeedStyle: "mini", liveAccStyle: "mini" }, }, ], liveSpeedStyle: [ { value: "mini", given: { monkey: true }, expected: { monkey: true }, }, { value: "text", given: { monkey: true }, expected: { monkey: false }, }, ], liveAccStyle: [ { value: "mini", given: { monkey: true }, expected: { monkey: true }, }, { value: "text", given: { monkey: true }, expected: { monkey: false }, }, ], tapeMode: [ { value: "off", given: { showAllLines: true }, expected: { showAllLines: true }, }, { value: "letter", given: { showAllLines: true }, expected: { showAllLines: false }, }, ], theme: [ { value: "8008", given: { customTheme: true }, expected: { customTheme: false }, }, ], keymapLayout: [ { value: "3l", given: { keymapMode: "react" }, expected: { keymapMode: "react" }, }, { value: "3l", given: { keymapMode: "off" }, expected: { keymapMode: "static" }, }, ], keymapStyle: [ { value: "alice", given: { keymapMode: "react" }, expected: { keymapMode: "react" }, }, { value: "alice", given: { keymapMode: "off" }, expected: { keymapMode: "static" }, }, ], keymapLegendStyle: [ { value: "dynamic", given: { keymapMode: "react" }, expected: { keymapMode: "react" }, }, { value: "dynamic", given: { keymapMode: "off" }, expected: { keymapMode: "static" }, }, ], keymapShowTopRow: [ { value: "always", given: { keymapMode: "react" }, expected: { keymapMode: "react" }, }, { value: "always", given: { keymapMode: "off" }, expected: { keymapMode: "static" }, }, ], keymapSize: [ { value: 2, given: { keymapMode: "react" }, expected: { keymapMode: "react" }, }, { value: 2, given: { keymapMode: "off" }, expected: { keymapMode: "static" }, }, ], }; it.for( Object.entries(testCases).flatMap(([key, value]) => value.flatMap((it) => ({ key: key as ConfigKey, ...it })), ), )( `$key value=$value given=$given expected=$expected`, ({ key, value, given, expected }) => { //GIVEN replaceConfig(given); //WHEN setConfig(key, value as any); //THEN expect(getConfig()).toMatchObject(expected ?? {}); }, ); }); });