Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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