obsidian#QuickSwitcherOptions TypeScript Examples
The following examples show how to use
obsidian#QuickSwitcherOptions.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: switcherPlusSettings.test.ts From obsidian-switcher-plus with GNU General Public License v3.0 | 4 votes |
describe('SwitcherPlusSettings', () => {
let mockApp: MockProxy<App>;
let mockPlugin: MockProxy<SwitcherPlusPlugin>;
let sut: SwitcherPlusSettings;
beforeAll(() => {
mockApp = mock<App>({ internalPlugins: mock<InternalPlugins>() });
mockPlugin = mock<SwitcherPlusPlugin>({ app: mockApp });
});
beforeEach(() => {
sut = new SwitcherPlusSettings(mockPlugin);
});
it('should return default settings', () => {
// extract enabledSymbolTypes to handle separately, because it's not exposed
// on SwitcherPlusSettings directly
const { enabledSymbolTypes, ...defaults } = transientSettingsData(true);
expect(sut).toEqual(expect.objectContaining(defaults));
expect(sut.editorListPlaceholderText).toBe(defaults.editorListCommand);
expect(sut.symbolListPlaceholderText).toBe(defaults.symbolListCommand);
expect(sut.workspaceListPlaceholderText).toBe(defaults.workspaceListCommand);
expect(sut.headingsListPlaceholderText).toBe(defaults.headingsListCommand);
expect(sut.starredListPlaceholderText).toBe(defaults.starredListCommand);
expect(sut.commandListPlaceholderText).toBe(defaults.commandListCommand);
expect(sut.relatedItemsListPlaceholderText).toBe(defaults.relatedItemsListCommand);
expect(sut.includeSidePanelViewTypesPlaceholder).toBe(
defaults.includeSidePanelViewTypes.join('\n'),
);
expect(sut.isSymbolTypeEnabled(SymbolType.Embed)).toBe(
enabledSymbolTypes[SymbolType.Embed],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Heading)).toBe(
enabledSymbolTypes[SymbolType.Heading],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Link)).toBe(
enabledSymbolTypes[SymbolType.Link],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Tag)).toBe(
enabledSymbolTypes[SymbolType.Tag],
);
});
it('should save modified settings', async () => {
const settings = transientSettingsData(false);
sut.onOpenPreferNewPane = settings.onOpenPreferNewPane;
sut.alwaysNewPaneForSymbols = settings.alwaysNewPaneForSymbols;
sut.useActivePaneForSymbolsOnMobile = settings.useActivePaneForSymbolsOnMobile;
sut.symbolsInLineOrder = settings.symbolsInLineOrder;
sut.editorListCommand = settings.editorListCommand;
sut.symbolListCommand = settings.symbolListCommand;
sut.workspaceListCommand = settings.workspaceListCommand;
sut.headingsListCommand = settings.headingsListCommand;
sut.starredListCommand = settings.starredListCommand;
sut.commandListCommand = settings.commandListCommand;
sut.relatedItemsListCommand = settings.relatedItemsListCommand;
sut.strictHeadingsOnly = settings.strictHeadingsOnly;
sut.searchAllHeadings = settings.searchAllHeadings;
sut.includeSidePanelViewTypes = settings.includeSidePanelViewTypes;
sut.limit = settings.limit;
sut.selectNearestHeading = settings.selectNearestHeading;
sut.excludeFolders = settings.excludeFolders;
sut.excludeLinkSubTypes = settings.excludeLinkSubTypes;
sut.excludeRelatedFolders = settings.excludeRelatedFolders;
sut.excludeOpenRelatedFiles = settings.excludeOpenRelatedFiles;
sut.setSymbolTypeEnabled(
SymbolType.Heading,
settings.enabledSymbolTypes[SymbolType.Heading],
);
sut.setSymbolTypeEnabled(
SymbolType.Link,
settings.enabledSymbolTypes[SymbolType.Link],
);
sut.setSymbolTypeEnabled(SymbolType.Tag, settings.enabledSymbolTypes[SymbolType.Tag]);
sut.setSymbolTypeEnabled(
SymbolType.Embed,
settings.enabledSymbolTypes[SymbolType.Embed],
);
let savedSettings: SettingsData;
mockPlugin.saveData.mockImplementationOnce((data: SettingsData) => {
savedSettings = data;
return Promise.resolve();
});
await sut.saveSettings();
expect(savedSettings).toEqual(expect.objectContaining(settings));
expect(mockPlugin.saveData).toHaveBeenCalled();
mockPlugin.saveData.mockReset();
});
it('should load saved settings', async () => {
const settings = transientSettingsData(false);
const { enabledSymbolTypes, ...prunedSettings } = settings;
mockPlugin.loadData.mockResolvedValueOnce(settings);
await sut.loadSettings();
expect(sut).toEqual(expect.objectContaining(prunedSettings));
expect(sut.isSymbolTypeEnabled(SymbolType.Heading)).toBe(
enabledSymbolTypes[SymbolType.Heading],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Link)).toBe(
enabledSymbolTypes[SymbolType.Link],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Tag)).toBe(
enabledSymbolTypes[SymbolType.Tag],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Embed)).toBe(
enabledSymbolTypes[SymbolType.Embed],
);
expect(mockPlugin.loadData).toHaveBeenCalled();
mockPlugin.loadData.mockReset();
});
it('should load saved settings, even with missing data keys', async () => {
const defaults = transientSettingsData(true);
const settings = transientSettingsData(false);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { enabledSymbolTypes, ...prunedSettings } = settings;
mockPlugin.loadData.mockResolvedValueOnce(prunedSettings);
await sut.loadSettings();
expect(sut).toEqual(expect.objectContaining(prunedSettings));
expect(sut.isSymbolTypeEnabled(SymbolType.Heading)).toBe(
defaults.enabledSymbolTypes[SymbolType.Heading],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Link)).toBe(
defaults.enabledSymbolTypes[SymbolType.Link],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Tag)).toBe(
defaults.enabledSymbolTypes[SymbolType.Tag],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Embed)).toBe(
defaults.enabledSymbolTypes[SymbolType.Embed],
);
expect(mockPlugin.loadData).toHaveBeenCalled();
mockPlugin.loadData.mockReset();
});
it('should use default data if settings cannot be loaded', async () => {
const { enabledSymbolTypes, ...defaults } = transientSettingsData(true);
mockPlugin.loadData.mockResolvedValueOnce(null);
await sut.loadSettings();
expect(sut).toEqual(expect.objectContaining(defaults));
expect(sut.editorListPlaceholderText).toBe(defaults.editorListCommand);
expect(sut.symbolListPlaceholderText).toBe(defaults.symbolListCommand);
expect(sut.workspaceListPlaceholderText).toBe(defaults.workspaceListCommand);
expect(sut.headingsListPlaceholderText).toBe(defaults.headingsListCommand);
expect(sut.includeSidePanelViewTypesPlaceholder).toBe(
defaults.includeSidePanelViewTypes.join('\n'),
);
expect(sut.isSymbolTypeEnabled(SymbolType.Embed)).toBe(
enabledSymbolTypes[SymbolType.Embed],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Heading)).toBe(
enabledSymbolTypes[SymbolType.Heading],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Link)).toBe(
enabledSymbolTypes[SymbolType.Link],
);
expect(sut.isSymbolTypeEnabled(SymbolType.Tag)).toBe(
enabledSymbolTypes[SymbolType.Tag],
);
expect(mockPlugin.loadData).toHaveBeenCalled();
});
it('should load built-in system switcher settings', () => {
const builtInOptions = mock<QuickSwitcherOptions>({
showAllFileTypes: chance.bool(),
showAttachments: chance.bool(),
showExistingOnly: chance.bool(),
});
const pluginInstance = mock<QuickSwitcherPluginInstance>({
id: 'switcher',
options: builtInOptions,
QuickSwitcherModal: null,
});
const builtInSwitcherPlugin = mock<InstalledPlugin>({
enabled: true,
instance: pluginInstance,
});
const mockInternalPlugins = mockApp.internalPlugins as MockProxy<InternalPlugins>;
mockInternalPlugins.getPluginById.mockReturnValue(builtInSwitcherPlugin);
expect(sut.builtInSystemOptions).toMatchObject(builtInOptions);
expect(sut.showAllFileTypes).toBe(builtInOptions.showAllFileTypes);
expect(sut.showAttachments).toBe(builtInOptions.showAttachments);
expect(sut.showExistingOnly).toBe(builtInOptions.showExistingOnly);
expect(mockInternalPlugins.getPluginById).toHaveBeenCalled();
mockInternalPlugins.getPluginById.mockReset();
});
it('should log errors to console on fire and forget save operation', () => {
// Promise used to trigger the error condition
const saveDataPromise = Promise.resolve();
mockPlugin.saveData.mockImplementationOnce((_data: SettingsData) => {
// throw to simulate saveData() failing. This happens first
return saveDataPromise.then(() => {
throw new Error('saveData() unit test mock error');
});
});
// Promise used to track the call to console.log
let consoleLogPromiseResolveFn: (value: void | PromiseLike<void>) => void;
const consoleLogPromise = new Promise<void>((resolve, _reject) => {
consoleLogPromiseResolveFn = resolve;
});
const consoleLogSpy = jest
.spyOn(console, 'log')
.mockImplementation((message: string) => {
if (message.startsWith('Switcher++: error saving changes to settings')) {
// resolve the consoleLogPromise. This happens second and will allow
// allPromises to resolve itself
consoleLogPromiseResolveFn();
}
});
// wait for the other promises to resolve before this promise can resolve
const allPromises = Promise.all([saveDataPromise, consoleLogPromise]);
sut.save();
// when all the promises are resolved check expectations and clean up
return allPromises.finally(() => {
expect(mockPlugin.saveData).toHaveBeenCalled();
expect(consoleLogSpy).toHaveBeenCalled();
consoleLogSpy.mockRestore();
});
});
});