Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/engine/CaptureChoiceEngine.notice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ vi.mock("../formatters/captureChoiceFormatter", () => {
openExistingFileTab: vi.fn(() => null),
openFile: vi.fn(),
overwriteTemplaterOnce: vi.fn(),
resolveClipboardForNoteContent: vi.fn(async () => ""),
templaterParseTemplate: vi.fn(async (_app, content) => content),
getTemplater: vi.fn(() => ({})),
}));
Expand Down
1 change: 1 addition & 0 deletions src/engine/CaptureChoiceEngine.selection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ vi.mock("../utilityObsidian", () => ({
openExistingFileTab: vi.fn(() => null),
openFile: vi.fn(),
overwriteTemplaterOnce: vi.fn(),
resolveClipboardForNoteContent: vi.fn(async () => ""),
templaterParseTemplate: vi.fn(async (_app, content) => content),
waitForTemplaterTriggerOnCreateToComplete: vi.fn(),
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ vi.mock("../utilityObsidian", () => ({
openExistingFileTab: vi.fn().mockReturnValue(null),
openFile: vi.fn(),
overwriteTemplaterOnce: vi.fn().mockResolvedValue(undefined),
resolveClipboardForNoteContent: vi.fn(async () => ""),
templaterParseTemplate: vi.fn(async (_app, content) => content),
waitForFileToStopChanging: vi.fn().mockResolvedValue(undefined),
getTemplater: vi.fn(() => ({})),
Expand Down
2 changes: 2 additions & 0 deletions src/engine/MacroChoiceEngine.conditional.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ vi.mock("../settingsStore", () => ({
vi.mock("../formatters/completeFormatter", () => ({
CompleteFormatter: class CompleteFormatterMock {
constructor() {}
setDestinationFile() {}
setDestinationSourcePath() {}
},
}));
vi.mock("../ai/AIAssistant", () => ({
Expand Down
5 changes: 4 additions & 1 deletion src/engine/MacroChoiceEngine.editorCommands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import type { App } from "obsidian";
import { beforeEach, describe, expect, it, vi } from "vitest";

vi.mock("../formatters/completeFormatter", () => ({
CompleteFormatter: class CompleteFormatterMock {},
CompleteFormatter: class CompleteFormatterMock {
setDestinationFile() {}
setDestinationSourcePath() {}
},
}));

vi.mock("obsidian-dataview", () => ({
Expand Down
5 changes: 4 additions & 1 deletion src/engine/MacroChoiceEngine.entry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ vi.mock("../settingsStore", () => ({
}));

vi.mock("../formatters/completeFormatter", () => ({
CompleteFormatter: class CompleteFormatterMock {},
CompleteFormatter: class CompleteFormatterMock {
setDestinationFile() {}
setDestinationSourcePath() {}
},
}));

vi.mock("../ai/AIAssistant", () => ({
Expand Down
5 changes: 4 additions & 1 deletion src/engine/MacroChoiceEngine.notice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ vi.mock("../quickAddSettingsTab", () => {
});

vi.mock("../formatters/completeFormatter", () => ({
CompleteFormatter: class CompleteFormatterMock {},
CompleteFormatter: class CompleteFormatterMock {
setDestinationFile() {}
setDestinationSourcePath() {}
},
}));

vi.mock("obsidian-dataview", () => ({
Expand Down
5 changes: 4 additions & 1 deletion src/engine/SingleMacroEngine.member-access.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ vi.mock("../settingsStore", () => ({
}));

vi.mock("../formatters/completeFormatter", () => ({
CompleteFormatter: class CompleteFormatterMock {},
CompleteFormatter: class CompleteFormatterMock {
setDestinationFile() {}
setDestinationSourcePath() {}
},
}));

vi.mock("../ai/AIAssistant", () => ({
Expand Down
4 changes: 4 additions & 0 deletions src/engine/TemplateChoiceEngine.collision.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ vi.mock("../formatters/completeFormatter", () => {
constructor() {}
setLinkToCurrentFileBehavior() {}
setTitle() {}
setDestinationFile() {}
setDestinationSourcePath() {}
clearDestinationContext() {}
async formatFileName(format: string, prompt: string) {
return formatFileNameMock(format, prompt);
}
Expand All @@ -85,6 +88,7 @@ vi.mock("../utilityObsidian", () => ({
insertFileLinkToActiveView: vi.fn(),
openExistingFileTab: vi.fn(() => null),
openFile: vi.fn(),
resolveClipboardForNoteContent: vi.fn(async () => ""),
}));

vi.mock("../gui/GenericSuggester/genericSuggester", () => ({
Expand Down
4 changes: 4 additions & 0 deletions src/engine/TemplateChoiceEngine.notice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ vi.mock("../formatters/completeFormatter", () => {
constructor() {}
setLinkToCurrentFileBehavior() {}
setTitle() {}
setDestinationFile() {}
setDestinationSourcePath() {}
clearDestinationContext() {}
async formatFileName(format: string, prompt: string) {
return formatFileNameMock(format, prompt);
}
Expand Down Expand Up @@ -88,6 +91,7 @@ vi.mock("../formatters/completeFormatter", () => {
insertFileLinkToActiveView: vi.fn(),
openExistingFileTab: vi.fn(() => null),
openFile: vi.fn(),
resolveClipboardForNoteContent: vi.fn(async () => ""),
}));

vi.mock("../gui/GenericSuggester/genericSuggester", () => ({
Expand Down
21 changes: 21 additions & 0 deletions src/engine/TemplateEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,24 @@ export abstract class TemplateEngine extends QuickAddEngine {
| Promise<string>
| Promise<{ file: TFile; content: string }>;

private setTemplateDestinationContext(filePath: string): void {
if (MARKDOWN_FILE_EXTENSION_REGEX.test(filePath)) {
this.formatter.setDestinationSourcePath(filePath);
return;
}

this.formatter.clearDestinationContext();
}

private setTemplateDestinationContextForFile(file: TFile): void {
if (MARKDOWN_FILE_EXTENSION_REGEX.test(file.path)) {
this.formatter.setDestinationFile(file);
return;
}

this.formatter.clearDestinationContext();
}

protected async getOrCreateFolder(
folders: string[],
options: FolderChoiceOptions = {},
Expand Down Expand Up @@ -478,6 +496,7 @@ export abstract class TemplateEngine extends QuickAddEngine {
// Extract filename without extension from the full path.
const fileBasename = basenameWithoutMdOrCanvas(filePath);
this.formatter.setTitle(fileBasename);
this.setTemplateDestinationContext(filePath);

Comment thread
chhoumann marked this conversation as resolved.
const formattedTemplateContent: string =
await this.formatter.withTemplatePropertyCollection(() =>
Expand Down Expand Up @@ -537,6 +556,7 @@ export abstract class TemplateEngine extends QuickAddEngine {
// Use the existing file's basename as the title
const fileBasename = file.basename;
this.formatter.setTitle(fileBasename);
this.setTemplateDestinationContextForFile(file);

const formattedTemplateContent: string =
await this.formatter.withTemplatePropertyCollection(() =>
Expand Down Expand Up @@ -584,6 +604,7 @@ export abstract class TemplateEngine extends QuickAddEngine {
// Use the existing file's basename as the title
const fileBasename = file.basename;
this.formatter.setTitle(fileBasename);
this.setTemplateDestinationContextForFile(file);

let formattedTemplateContent: string =
await this.formatter.formatFileContent(templateContent);
Expand Down
99 changes: 99 additions & 0 deletions src/engine/templateEngine-title.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,26 @@ vi.mock('../formatters/completeFormatter', () => {
return {
CompleteFormatter: vi.fn().mockImplementation(() => {
let title = '';
let destinationFile: unknown = null;
let destinationSourcePath: string | null = null;
return {
setTitle: vi.fn((t: string) => { title = t; }),
setDestinationFile: vi.fn((file: unknown) => {
destinationFile = file;
}),
setDestinationSourcePath: vi.fn((path: string) => {
destinationSourcePath = path;
}),
clearDestinationContext: vi.fn(() => {
destinationFile = null;
destinationSourcePath = null;
}),
getTitle: () => title,
getDestinationFile: () => destinationFile,
getDestinationSourcePath: () => destinationSourcePath,
getAndClearTemplatePropertyVars: vi.fn(
() => new Map<string, unknown>(),
),
withTemplatePropertyCollection: vi.fn(
async (work: () => Promise<unknown>) => await work(),
),
Expand All @@ -29,6 +46,8 @@ vi.mock('../formatters/completeFormatter', () => {
vi.mock('../utilityObsidian', () => ({
getTemplater: vi.fn(() => null),
overwriteTemplaterOnce: vi.fn().mockResolvedValue(undefined),
templaterParseTemplate: vi.fn(async (_app, content: string) => content),
resolveClipboardForNoteContent: vi.fn(async () => ""),
}));

// Test implementation of TemplateEngine
Expand All @@ -46,10 +65,26 @@ class TestTemplateEngine extends TemplateEngine {
return await this.createFileWithTemplate(filePath, templatePath);
}

public async testOverwriteFileWithTemplate(file: any, templatePath: string) {
return await this.overwriteFileWithTemplate(file, templatePath);
}

public async testAppendToFileWithTemplate(file: any, templatePath: string, section: "top" | "bottom") {
return await this.appendToFileWithTemplate(file, templatePath, section);
}

public getFormatterTitle(): string {
// Access the title that was set on the formatter
return (this.formatter as any).getTitle();
}

public getFormatterDestinationSourcePath(): string | null {
return (this.formatter as any).getDestinationSourcePath();
}

public getFormatterDestinationFile(): unknown {
return (this.formatter as any).getDestinationFile();
}
}

describe('TemplateEngine - Title Handling', () => {
Expand Down Expand Up @@ -144,6 +179,70 @@ describe('TemplateEngine - Title Handling', () => {
// Verify formatFileContent was called
expect(mockFormatter.formatFileContent).toHaveBeenCalled();
});

it('should set destination source path before formatting new template content', async () => {
await engine.testCreateFileWithTemplate('folder/TestDocument.md', 'template.md');

expect(engine.getFormatterDestinationSourcePath()).toBe('folder/TestDocument.md');
});

it('should clear destination context for new non-markdown template output', async () => {
await engine.testCreateFileWithTemplate('folder/Kanban.base', 'template.base');

expect(engine.getFormatterDestinationSourcePath()).toBeNull();
expect(engine.getFormatterDestinationFile()).toBeNull();
});
});

describe('existing file template updates', () => {
const existingFile = {
path: 'folder/Existing.md',
basename: 'Existing',
extension: 'md',
} as any;

beforeEach(() => {
mockApp.vault.modify = vi.fn().mockResolvedValue(undefined);
mockApp.vault.cachedRead = vi.fn().mockResolvedValue('Existing content');
});

it('should set destination file before overwriting template content', async () => {
await engine.testOverwriteFileWithTemplate(existingFile, 'template.md');

expect(engine.getFormatterDestinationFile()).toBe(existingFile);
});

it('should set destination file before appending template content', async () => {
await engine.testAppendToFileWithTemplate(existingFile, 'template.md', 'bottom');

expect(engine.getFormatterDestinationFile()).toBe(existingFile);
});

it('should clear destination context before overwriting non-markdown template output', async () => {
const existingBaseFile = {
path: 'folder/Kanban.base',
basename: 'Kanban',
extension: 'base',
} as any;

await engine.testOverwriteFileWithTemplate(existingBaseFile, 'template.base');

expect(engine.getFormatterDestinationFile()).toBeNull();
expect(engine.getFormatterDestinationSourcePath()).toBeNull();
});

it('should clear destination context before appending non-markdown template output', async () => {
const existingCanvasFile = {
path: 'folder/Board.canvas',
basename: 'Board',
extension: 'canvas',
} as any;

await engine.testAppendToFileWithTemplate(existingCanvasFile, 'template.canvas', 'bottom');

expect(engine.getFormatterDestinationFile()).toBeNull();
expect(engine.getFormatterDestinationSourcePath()).toBeNull();
});
});

describe('formatFileName - title exclusion', () => {
Expand Down
1 change: 1 addition & 0 deletions src/formatters/captureChoiceFormatter-frontmatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type ICaptureChoice from '../types/choices/ICaptureChoice';

vi.mock('../utilityObsidian', () => ({
templaterParseTemplate: vi.fn().mockResolvedValue(null),
resolveClipboardForNoteContent: vi.fn(async () => ''),
}));

vi.mock('../gui/InputPrompt', () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type ICaptureChoice from "../types/choices/ICaptureChoice";

vi.mock("../utilityObsidian", () => ({
templaterParseTemplate: vi.fn().mockResolvedValue(null),
resolveClipboardForNoteContent: vi.fn(async () => ""),
}));

vi.mock("../gui/InputPrompt", () => ({
Expand Down
2 changes: 2 additions & 0 deletions src/formatters/captureChoiceFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ export class CaptureChoiceFormatter extends CompleteFormatter {
private templaterProcessed = false;

public setDestinationFile(file: TFile): void {
super.setDestinationFile(file);
this.file = file;
this.sourcePath = file.path;
}

public setDestinationSourcePath(path: string): void {
super.setDestinationSourcePath(path);
this.sourcePath = path;
this.file = null;
}
Expand Down
Loading
Loading