Skip to content

Commit 1ea58fb

Browse files
committed
add button action tests
1 parent d75249e commit 1ea58fb

File tree

8 files changed

+346
-26
lines changed

8 files changed

+346
-26
lines changed

bun.lockb

328 Bytes
Binary file not shown.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
"svelte-check": "^3.6.4",
5050
"svelte-preprocess": "^5.1.3",
5151
"tslib": "2.6.2",
52-
"typescript": "^5.3.3"
52+
"typescript": "^5.3.3",
53+
"yaml": "^2.4.1"
5354
},
5455
"dependencies": {
5556
"@codemirror/legacy-modes": "^6.3.3",

packages/core/src/api/InternalAPI.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,17 @@ export abstract class InternalAPI<Plugin extends IPlugin> {
223223

224224
abstract writeFilePath(filePath: string, content: string): Promise<void>;
225225

226+
/**
227+
* Create a file in the given folder with the given name and extension.
228+
* If the name is already taken, a number will be appended to the name.
229+
*
230+
* @param folderPath the path to the folder
231+
* @param fileName the name of the file
232+
* @param extension the extension of the file
233+
* @param open
234+
*
235+
* @returns the path to the created file
236+
*/
226237
abstract createFile(folderPath: string, fileName: string, extension: string, open?: boolean): Promise<string>;
227238

228239
abstract createContextMenu(items: ContextMenuItemDefinition[]): IContextMenu;

packages/core/src/fields/button/ButtonActionRunner.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export class ButtonActionRunner {
154154
* @param position the position of the button in the note
155155
*/
156156
async runAction(
157-
config: ButtonConfig,
157+
config: ButtonConfig | undefined,
158158
action: ButtonAction,
159159
filePath: string,
160160
inline: boolean,
@@ -207,7 +207,7 @@ export class ButtonActionRunner {
207207
this.plugin.internal.executeCommandById(action.command);
208208
}
209209

210-
async runJSAction(config: ButtonConfig, action: JSButtonAction, filePath: string): Promise<void> {
210+
async runJSAction(config: ButtonConfig | undefined, action: JSButtonAction, filePath: string): Promise<void> {
211211
const configOverrides: Record<string, unknown> = {
212212
buttonConfig: config,
213213
args: action.args,

tests/__mocks__/TestFileSystem.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
export class TestFileSystem {
2+
files: Map<string, string>;
3+
4+
constructor() {
5+
this.files = new Map();
6+
}
7+
8+
readFile(path: string): string {
9+
this.validateFilePath(path);
10+
11+
let fileContent = this.files.get(path);
12+
if (fileContent === undefined) {
13+
throw new Error(`File not found: ${path}`);
14+
}
15+
return fileContent;
16+
}
17+
18+
writeFile(path: string, content: string): void {
19+
this.validateFilePath(path);
20+
21+
this.files.set(path, content);
22+
}
23+
24+
deleteFile(path: string): void {
25+
this.validateFilePath(path);
26+
27+
if (!this.fileExists(path)) {
28+
throw new Error(`File does not exist: ${path}`);
29+
}
30+
31+
this.files.delete(path);
32+
}
33+
34+
listFiles(): string[] {
35+
return Array.from(this.files.keys());
36+
}
37+
38+
fileExists(path: string): boolean {
39+
this.validateFilePath(path);
40+
41+
return this.files.has(path);
42+
}
43+
44+
listDirs(): string[] {
45+
const dirs = new Set<string>();
46+
47+
for (const path of this.files.keys()) {
48+
const parts = path.split('/');
49+
parts.pop();
50+
dirs.add(parts.join('/'));
51+
}
52+
53+
return Array.from(dirs);
54+
}
55+
56+
validateFilePath(path: string): void {
57+
if (path === '') {
58+
throw new Error('Invalid file path');
59+
}
60+
61+
const parts = path.split('/');
62+
63+
for (const part of parts) {
64+
if (part === '' || part === '.' || part === '..') {
65+
throw new Error('Invalid file path');
66+
}
67+
}
68+
}
69+
}

tests/__mocks__/TestInternalAPI.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,18 @@ import { ModalContent } from 'packages/core/src/modals/ModalContent';
1212
import { IModal } from 'packages/core/src/modals/IModal';
1313
import { SelectModalContent } from 'packages/core/src/modals/SelectModalContent';
1414
import { ContextMenuItemDefinition, IContextMenu } from 'packages/core/src/utils/IContextMenu';
15-
import { undefined } from 'zod';
15+
import { TestFileSystem } from 'tests/__mocks__/TestFileSystem';
16+
import YAML from 'yaml';
1617

1718
export class TestInternalAPI extends InternalAPI<TestPlugin> {
19+
fileSystem: TestFileSystem;
20+
21+
constructor(plugin: TestPlugin) {
22+
super(plugin);
23+
24+
this.fileSystem = new TestFileSystem();
25+
}
26+
1827
public async renderMarkdown(markdown: string, element: HTMLElement, _filePath: string): Promise<() => void> {
1928
element.innerText += markdown;
2029
return () => {};
@@ -53,12 +62,12 @@ export class TestInternalAPI extends InternalAPI<TestPlugin> {
5362

5463
public showNotice(_: string): void {}
5564

56-
public parseYaml(_yaml: string): unknown {
57-
return {};
65+
public parseYaml(yaml: string): unknown {
66+
return YAML.parse(yaml) as unknown;
5867
}
5968

60-
public stringifyYaml(_yaml: unknown): string {
61-
return '';
69+
public stringifyYaml(yaml: unknown): string {
70+
return YAML.stringify(yaml);
6271
}
6372

6473
public setIcon(_element: HTMLElement, _icon: string): void {}
@@ -84,11 +93,11 @@ export class TestInternalAPI extends InternalAPI<TestPlugin> {
8493
}
8594

8695
public getAllFiles(): string[] {
87-
return [];
96+
return this.fileSystem.listFiles();
8897
}
8998

9099
public getAllFolders(): string[] {
91-
return [];
100+
return this.fileSystem.listDirs();
92101
}
93102

94103
public getImageSuggesterOptions(_inputField: ImageSuggesterIPF): SuggesterOption<string>[] {
@@ -99,16 +108,18 @@ export class TestInternalAPI extends InternalAPI<TestPlugin> {
99108
return [];
100109
}
101110

102-
public readFilePath(_filePath: string): Promise<string> {
103-
return Promise.resolve('');
111+
public async readFilePath(filePath: string): Promise<string> {
112+
return this.fileSystem.readFile(filePath);
104113
}
105114

106-
public writeFilePath(_filePath: string, _content: string): Promise<void> {
107-
return Promise.resolve();
115+
public async writeFilePath(filePath: string, content: string): Promise<void> {
116+
this.fileSystem.writeFile(filePath, content);
108117
}
109118

110-
public createFile(_folderPath: string, _fileName: string, _extension: string, _open?: boolean): Promise<string> {
111-
return Promise.resolve('');
119+
public async createFile(folderPath: string, fileName: string, extension: string, _open?: boolean): Promise<string> {
120+
const filePath = `${folderPath}/${fileName}.${extension}`;
121+
this.fileSystem.writeFile(filePath, '');
122+
return filePath;
112123
}
113124

114125
public createContextMenu(_items: ContextMenuItemDefinition[]): IContextMenu {

0 commit comments

Comments
 (0)