refactor(config): split config and config-metadata tests (@fehmer) (#6770)

This commit is contained in:
Christian Fehmer 2025-07-22 21:33:18 +02:00 committed by GitHub
parent e357efc435
commit 4f57418b6a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 486 additions and 429 deletions

View file

@ -0,0 +1,278 @@
import { configMetadata } from "../../src/ts/config-metadata";
import * as Config from "../../src/ts/config";
import { ConfigKey, Config as ConfigType } from "@monkeytype/schemas/configs";
const { replaceConfig, getConfig } = Config.__testing;
type TestsByConfig<T> = 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 === true)
.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"].sort()
);
});
describe("overrideValue", () => {
const testCases: TestsByConfig<{
given?: Partial<ConfigType>;
expected: Partial<ConfigType>;
}> = {
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
Config.genericSet(key, value as any);
//THEN
expect(getConfig()).toMatchObject(expected);
}
);
});
describe("isBlocked", () => {
const testCases: TestsByConfig<{
given?: Partial<ConfigType>;
fail?: true;
}> = {
funbox: [
{
value: "gibberish" as any,
given: { mode: "quote" },
fail: true,
},
],
showAllLines: [
{ value: true, given: { tapeMode: "off" } },
{ value: false, given: { tapeMode: "word" } },
{ value: true, given: { tapeMode: "word" }, fail: 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 = Config.genericSet(key, value as any);
//THEN
expect(applied).toEqual(!fail);
}
);
});
describe("overrideConfig", () => {
const testCases: TestsByConfig<{
given: Partial<ConfigType>;
expected?: Partial<ConfigType>;
}> = {
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" },
},
],
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 },
},
],
};
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
Config.genericSet(key, value as any);
//THEN
expect(getConfig()).toMatchObject(expected ?? {});
}
);
});
});

View file

@ -4,7 +4,7 @@ import {
CustomThemeColors,
FunboxName,
ConfigKey,
Config as ConfigType,
CaretStyleSchema,
} from "@monkeytype/schemas/configs";
import { randomBytes } from "crypto";
import { vi } from "vitest";
@ -15,66 +15,60 @@ import * as DB from "../../src/ts/db";
import * as AccountButton from "../../src/ts/elements/account-button";
import * as Notifications from "../../src/ts/elements/notifications";
type TestsByConfig<T> = Partial<{
[K in keyof ConfigType]: (T & { value: ConfigType[K] })[];
}>;
const { configMetadata, replaceConfig, getConfig } = Config.__testing;
const { replaceConfig, getConfig } = Config.__testing;
describe("Config", () => {
const isDevEnvironmentMock = vi.spyOn(Misc, "isDevEnvironment");
beforeEach(() => isDevEnvironmentMock.mockReset());
describe("test with mocks", () => {
const isDevEnvironmentMock = vi.spyOn(Misc, "isDevEnvironment");
const canSetConfigWithCurrentFunboxesMock = vi.spyOn(
FunboxValidation,
"canSetConfigWithCurrentFunboxes"
);
const isConfigValueValidMock = vi.spyOn(
ConfigValidation,
"isConfigValueValid"
);
const dispatchConfigEventMock = vi.spyOn(ConfigEvent, "dispatch");
const dbSaveConfigMock = vi.spyOn(DB, "saveConfig");
const accountButtonLoadingMock = vi.spyOn(AccountButton, "loading");
const notificationAddMock = vi.spyOn(Notifications, "add");
const miscReloadAfterMock = vi.spyOn(Misc, "reloadAfter");
const miscTriggerResizeMock = vi.spyOn(Misc, "triggerResize");
const mocks = [
canSetConfigWithCurrentFunboxesMock,
isConfigValueValidMock,
dispatchConfigEventMock,
dbSaveConfigMock,
accountButtonLoadingMock,
notificationAddMock,
miscReloadAfterMock,
miscTriggerResizeMock,
];
beforeEach(async () => {
vi.useFakeTimers();
mocks.forEach((it) => it.mockReset());
vi.mock("../../src/ts/test/test-state", () => ({
isActive: true,
}));
isConfigValueValidMock.mockReturnValue(true);
canSetConfigWithCurrentFunboxesMock.mockReturnValue(true);
dbSaveConfigMock.mockResolvedValue();
describe("configMeta", () => {
afterAll(() => {
replaceConfig({});
vi.resetModules();
});
it("should have changeRequiresRestart defined", () => {
const configsRequiringRestarts = Object.entries(configMetadata)
.filter(([_key, value]) => value.changeRequiresRestart === true)
.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"].sort()
);
afterAll(() => {
mocks.forEach((it) => it.mockRestore());
vi.useRealTimers();
});
beforeEach(() => isDevEnvironmentMock.mockReset());
it("should throw if config key in not found in metadata", () => {
expect(() => {
Config.genericSet("nonExistentKey" as ConfigKey, true);
@ -83,417 +77,198 @@ describe("Config", () => {
);
});
describe("overrideValue", () => {
const testCases: TestsByConfig<{
given?: Partial<ConfigType>;
expected: Partial<ConfigType>;
}> = {
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("fails if test is active and funbox no_quit", () => {
//GIVEN
replaceConfig({ funbox: ["no_quit"], numbers: false });
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
expect(Config.genericSet("numbers", true, true)).toBe(false);
//WHEN
Config.genericSet(key, value as any);
//THEN
expect(getConfig()).toMatchObject(expected);
//THEN
expect(notificationAddMock).toHaveBeenCalledWith(
"No quit funbox is active. Please finish the test.",
0,
{
important: true,
}
);
});
describe("isBlocked", () => {
const testCases: TestsByConfig<{
given?: Partial<ConfigType>;
fail?: true;
}> = {
funbox: [
{
value: "gibberish" as any,
given: { mode: "quote" },
fail: true,
},
],
showAllLines: [
{ value: true, given: { tapeMode: "off" } },
{ value: false, given: { tapeMode: "word" } },
{ value: true, given: { tapeMode: "word" }, fail: true },
],
};
//TODO isBlocked
it("should fail if config is blocked", () => {
//GIVEN
replaceConfig({ tapeMode: "letter" });
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 / THEN
expect(Config.genericSet("showAllLines", true)).toBe(false);
});
//WHEN
const applied = Config.genericSet(key, value as any);
it("should use overrideValue", () => {
//WHEN
Config.genericSet("customLayoutfluid", ["3l", "ABNT2", "3l"]);
//THEN
expect(applied).toEqual(!fail);
}
//THEN
expect(getConfig().customLayoutfluid).toEqual(["3l", "ABNT2"]);
});
it("fails if config is invalid", () => {
//GIVEN
isConfigValueValidMock.mockReturnValue(false);
//WHEN / THEN
expect(Config.genericSet("caretStyle", "banana" as any)).toBe(false);
expect(isConfigValueValidMock).toHaveBeenCalledWith(
"caret style",
"banana",
CaretStyleSchema
);
});
describe("overrideConfig", () => {
const testCases: TestsByConfig<{
given: Partial<ConfigType>;
expected?: Partial<ConfigType>;
}> = {
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" },
},
],
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 },
},
],
};
it("cannot set if funbox disallows", () => {
//GIVEN
canSetConfigWithCurrentFunboxesMock.mockReturnValue(false);
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 / THEN
expect(Config.genericSet("numbers", true)).toBe(false);
});
//WHEN
Config.genericSet(key, value as any);
it("sets overrideConfigs", () => {
//GIVEN
replaceConfig({
confidenceMode: "off",
freedomMode: false, //already set correctly
stopOnError: "letter", //should get updated
});
//THEN
expect(getConfig()).toMatchObject(expected ?? {});
}
//WHEN
Config.genericSet("confidenceMode", "max");
//THEN
expect(dispatchConfigEventMock).not.toHaveBeenCalledWith(
"freedomMode",
false,
true,
true
);
expect(dispatchConfigEventMock).toHaveBeenCalledWith(
"stopOnError",
"off",
true,
"letter"
);
expect(dispatchConfigEventMock).toHaveBeenCalledWith(
"confidenceMode",
"max",
false,
"off"
);
});
describe("test with mocks", () => {
const canSetConfigWithCurrentFunboxesMock = vi.spyOn(
FunboxValidation,
"canSetConfigWithCurrentFunboxes"
it("saves to localstorage if nosave=false", async () => {
//GIVEN
replaceConfig({ numbers: false });
//WHEN
Config.genericSet("numbers", true);
//THEN
//wait for debounce
await vi.advanceTimersByTimeAsync(2500);
//show loading
expect(accountButtonLoadingMock).toHaveBeenNthCalledWith(1, true);
//save
expect(dbSaveConfigMock).toHaveBeenCalledWith({ numbers: true });
//hide loading
expect(accountButtonLoadingMock).toHaveBeenNthCalledWith(2, false);
//send event
expect(dispatchConfigEventMock).toHaveBeenCalledWith(
"saveToLocalStorage",
expect.stringContaining("numbers")
);
const isConfigValueValidMock = vi.spyOn(
ConfigValidation,
"isConfigValueValid"
});
it("does not save to localstorage if nosave=true", async () => {
//GIVEN
replaceConfig({ numbers: false });
//WHEN
Config.genericSet("numbers", true, true);
//THEN
//wait for debounce
await vi.advanceTimersByTimeAsync(2500);
expect(accountButtonLoadingMock).not.toHaveBeenCalled();
expect(dbSaveConfigMock).not.toHaveBeenCalled();
expect(dispatchConfigEventMock).not.toHaveBeenCalledWith(
"saveToLocalStorage",
expect.any(String)
);
const dispatchConfigEventMock = vi.spyOn(ConfigEvent, "dispatch");
const dbSaveConfigMock = vi.spyOn(DB, "saveConfig");
const accountButtonLoadingMock = vi.spyOn(AccountButton, "loading");
const notificationAddMock = vi.spyOn(Notifications, "add");
const miscReloadAfterMock = vi.spyOn(Misc, "reloadAfter");
});
const mocks = [
canSetConfigWithCurrentFunboxesMock,
isConfigValueValidMock,
dispatchConfigEventMock,
dbSaveConfigMock,
accountButtonLoadingMock,
notificationAddMock,
miscReloadAfterMock,
];
it("dispatches event on set", () => {
//GIVEN
replaceConfig({ numbers: false });
beforeEach(async () => {
vi.useFakeTimers();
mocks.forEach((it) => it.mockReset());
//WHEN
Config.genericSet("numbers", true, true);
vi.mock("../../src/ts/test/test-state", () => ({
isActive: true,
}));
//THEN
isConfigValueValidMock.mockReturnValue(true);
canSetConfigWithCurrentFunboxesMock.mockReturnValue(true);
dbSaveConfigMock.mockResolvedValue();
});
expect(dispatchConfigEventMock).toHaveBeenCalledWith(
"numbers",
true,
true,
false
);
});
afterAll(() => {
mocks.forEach((it) => it.mockRestore());
vi.useRealTimers();
});
it("triggers resize if property is set", () => {
///WHEN
Config.genericSet("maxLineWidth", 50, false);
it("cannot set if funbox disallows", () => {
//GIVEN
canSetConfigWithCurrentFunboxesMock.mockReturnValue(false);
expect(miscTriggerResizeMock).toHaveBeenCalled();
});
//WHEN / THEN
expect(Config.genericSet("numbers", true)).toBe(false);
});
it("does not triggers resize if property is not set", () => {
///WHEN
Config.genericSet("startGraphsAtZero", true, false);
it("fails if config is invalid", () => {
//GIVEN
isConfigValueValidMock.mockReturnValue(false);
expect(miscTriggerResizeMock).not.toHaveBeenCalled();
});
//WHEN / THEN
expect(Config.genericSet("numbers", "off" as any)).toBe(false);
});
it("does not triggers resize if property on nosave", () => {
///WHEN
Config.genericSet("maxLineWidth", 50, true);
it("dispatches event on set", () => {
//GIVEN
replaceConfig({ numbers: false });
expect(miscTriggerResizeMock).not.toHaveBeenCalled();
});
//WHEN
Config.genericSet("numbers", true, true);
it("calls afterSet", () => {
//GIVEN
isDevEnvironmentMock.mockReturnValue(false);
replaceConfig({ ads: "off" });
//THEN
//WHEN
Config.genericSet("ads", "sellout");
expect(dispatchConfigEventMock).toHaveBeenCalledWith(
"numbers",
true,
true,
false
);
});
it("saves to localstorage if nosave=false", async () => {
//GIVEN
replaceConfig({ numbers: false });
//WHEN
Config.genericSet("numbers", true);
//THEN
//wait for debounce
await vi.advanceTimersByTimeAsync(2500);
//show loading
expect(accountButtonLoadingMock).toHaveBeenNthCalledWith(1, true);
//save
expect(dbSaveConfigMock).toHaveBeenCalledWith({ numbers: true });
//hide loading
expect(accountButtonLoadingMock).toHaveBeenNthCalledWith(2, false);
//send event
expect(dispatchConfigEventMock).toHaveBeenCalledWith(
"saveToLocalStorage",
expect.stringContaining("numbers")
);
});
it("does not save to localstorage if nosave=true", async () => {
//GIVEN
replaceConfig({ numbers: false });
//WHEN
Config.genericSet("numbers", true, true);
//THEN
//wait for debounce
await vi.advanceTimersByTimeAsync(2500);
expect(accountButtonLoadingMock).not.toHaveBeenCalled();
expect(dbSaveConfigMock).not.toHaveBeenCalled();
expect(dispatchConfigEventMock).not.toHaveBeenCalledWith(
"saveToLocalStorage",
expect.any(String)
);
});
it("calls afterSet", () => {
//GIVEN
isDevEnvironmentMock.mockReturnValue(false);
replaceConfig({ ads: "off" });
//WHEN
Config.genericSet("ads", "sellout");
//THEN
expect(notificationAddMock).toHaveBeenCalledWith(
"Ad settings changed. Refreshing...",
0
);
expect(miscReloadAfterMock).toHaveBeenCalledWith(3);
});
it("fails if test is active and funbox no_quit", () => {
//GIVEN
replaceConfig({ funbox: ["no_quit"], numbers: false });
//WHEN
expect(Config.genericSet("numbers", true, true)).toBe(false);
//THEN
expect(notificationAddMock).toHaveBeenCalledWith(
"No quit funbox is active. Please finish the test.",
0,
{
important: true,
}
);
});
it("sends configEvents for overrideConfigs", () => {
//GIVEN
replaceConfig({
confidenceMode: "off",
freedomMode: true,
stopOnError: "letter",
});
//WHEN
Config.genericSet("confidenceMode", "max");
//THEN
expect(dispatchConfigEventMock).toHaveBeenCalledWith(
"freedomMode",
false,
true,
true
);
expect(dispatchConfigEventMock).toHaveBeenCalledWith(
"stopOnError",
"off",
true,
"letter"
);
expect(dispatchConfigEventMock).toHaveBeenCalledWith(
"confidenceMode",
"max",
false,
"off"
);
});
//THEN
expect(notificationAddMock).toHaveBeenCalledWith(
"Ad settings changed. Refreshing...",
0
);
expect(miscReloadAfterMock).toHaveBeenCalledWith(3);
});
});
//TODO move the rest to schema/tests or remove after removing the setX functions from Config
it("setMode", () => {
expect(Config.setMode("zen")).toBe(true);
expect(Config.setMode("invalid" as any)).toBe(false);

View file

@ -12,6 +12,7 @@ import {
createErrorMessage,
isObject,
promiseWithResolvers,
triggerResize,
typedKeys,
} from "./utils/misc";
import * as ConfigSchemas from "@monkeytype/schemas/configs";
@ -200,7 +201,7 @@ export function genericSet<T extends keyof ConfigSchemas.Config>(
ConfigEvent.dispatch(key, value, nosave, previousValue);
if (metadata.triggerResize && !nosave) {
$(window).trigger("resize");
triggerResize();
}
metadata.afterSet?.({ nosave: nosave || false, currentConfig: config });

View file

@ -760,4 +760,7 @@ export function sanitize<T extends z.ZodTypeAny>(
) as z.infer<T>;
}
export function triggerResize(): void {
$(window).trigger("resize");
}
// DO NOT ALTER GLOBAL OBJECTSONSTRUCTOR, IT WILL BREAK RESULT HASHES