Skip to content

Commit 483e733

Browse files
committed
fix: tags parsing issue in frontmatter
1 parent ba18f86 commit 483e733

5 files changed

Lines changed: 340 additions & 21 deletions

File tree

src/__tests__/FileMetadataInheritance.test.ts

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,125 @@ describe("File Metadata Inheritance", () => {
343343
});
344344
});
345345

346+
describe("Tags Inheritance", () => {
347+
test("should inherit tags from file metadata", () => {
348+
const content = "- [ ] Task without tags";
349+
const fileMetadata = {
350+
tags: ["#work", "#urgent", "#meeting"],
351+
};
352+
353+
const tasks = parser.parseLegacy(content, "test.md", fileMetadata);
354+
355+
expect(tasks).toHaveLength(1);
356+
expect(tasks[0].metadata.tags).toBeDefined();
357+
expect(tasks[0].metadata.tags).toEqual(["#work", "#urgent", "#meeting"]);
358+
});
359+
360+
test("should merge task tags with inherited tags", () => {
361+
const content = "- [ ] Task with existing tags #personal";
362+
const fileMetadata = {
363+
tags: ["#work", "#urgent"],
364+
};
365+
366+
const tasks = parser.parseLegacy(content, "test.md", fileMetadata);
367+
368+
expect(tasks).toHaveLength(1);
369+
expect(tasks[0].metadata.tags).toBeDefined();
370+
expect(tasks[0].metadata.tags).toContain("#personal");
371+
expect(tasks[0].metadata.tags).toContain("#work");
372+
expect(tasks[0].metadata.tags).toContain("#urgent");
373+
});
374+
375+
test("should not duplicate tags when merging", () => {
376+
const content = "- [ ] Task with duplicate tag #work";
377+
const fileMetadata = {
378+
tags: ["#work", "#urgent"],
379+
};
380+
381+
const tasks = parser.parseLegacy(content, "test.md", fileMetadata);
382+
383+
expect(tasks).toHaveLength(1);
384+
expect(tasks[0].metadata.tags).toBeDefined();
385+
// Should only have one instance of #work
386+
const workTags = tasks[0].metadata.tags.filter((tag: string) => tag === "#work");
387+
expect(workTags).toHaveLength(1);
388+
expect(tasks[0].metadata.tags).toContain("#urgent");
389+
});
390+
391+
test("should parse special tag formats from file metadata", () => {
392+
const content = "- [ ] Task inheriting project tag";
393+
const fileMetadata = {
394+
tags: ["#project/myproject", "#area/work", "#@/office"],
395+
};
396+
397+
const tasks = parser.parseLegacy(content, "test.md", fileMetadata);
398+
399+
expect(tasks).toHaveLength(1);
400+
expect(tasks[0].metadata.project).toBe("myproject");
401+
expect(tasks[0].metadata.area).toBe("work");
402+
expect(tasks[0].metadata.context).toBe("office");
403+
expect(tasks[0].metadata.tags).toContain("#project/myproject");
404+
expect(tasks[0].metadata.tags).toContain("#area/work");
405+
expect(tasks[0].metadata.tags).toContain("#@/office");
406+
});
407+
408+
test("should prioritize task metadata over tag-derived metadata", () => {
409+
const content = "- [ ] Task with explicit project [project::taskproject]";
410+
const fileMetadata = {
411+
tags: ["#project/fileproject"],
412+
};
413+
414+
const tasks = parser.parseLegacy(content, "test.md", fileMetadata);
415+
416+
expect(tasks).toHaveLength(1);
417+
// Task's explicit project should take precedence
418+
expect(tasks[0].metadata.project).toBe("taskproject");
419+
expect(tasks[0].metadata.tags).toContain("#project/fileproject");
420+
});
421+
422+
test("should handle mixed tag formats in file metadata", () => {
423+
const content = "- [ ] Task with mixed tag inheritance";
424+
const fileMetadata = {
425+
tags: ["#regular-tag", "#project/myproject", "#normalTag", "#area/work"],
426+
};
427+
428+
const tasks = parser.parseLegacy(content, "test.md", fileMetadata);
429+
430+
expect(tasks).toHaveLength(1);
431+
expect(tasks[0].metadata.project).toBe("myproject");
432+
expect(tasks[0].metadata.area).toBe("work");
433+
expect(tasks[0].metadata.tags).toContain("#regular-tag");
434+
expect(tasks[0].metadata.tags).toContain("#normalTag");
435+
expect(tasks[0].metadata.tags).toContain("#project/myproject");
436+
expect(tasks[0].metadata.tags).toContain("#area/work");
437+
});
438+
439+
test("should handle empty tags array in file metadata", () => {
440+
const content = "- [ ] Task with empty tags";
441+
const fileMetadata = {
442+
tags: [],
443+
};
444+
445+
const tasks = parser.parseLegacy(content, "test.md", fileMetadata);
446+
447+
expect(tasks).toHaveLength(1);
448+
expect(tasks[0].metadata.tags).toEqual([]);
449+
});
450+
451+
test("should handle non-array tags in file metadata", () => {
452+
const content = "- [ ] Task with non-array tags";
453+
const fileMetadata = {
454+
tags: "single-tag",
455+
};
456+
457+
const tasks = parser.parseLegacy(content, "test.md", fileMetadata);
458+
459+
expect(tasks).toHaveLength(1);
460+
// Should inherit as a single tag
461+
expect(tasks[0].metadata.tags).toContain("single-tag");
462+
});
463+
});
464+
346465
describe("Configuration Migration", () => {
347466
test("should work with migrated settings", () => {
348467
// 模拟迁移后的设置结构
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* Investigation: Tags Inheritance and Metadata Fields
3+
*/
4+
5+
import { MarkdownTaskParser } from "../utils/workers/ConfigurableTaskParser";
6+
import { getConfig } from "../common/task-parser-config";
7+
import { createMockPlugin } from "./mockUtils";
8+
import { DEFAULT_SETTINGS } from "../common/setting-definition";
9+
10+
describe("Tags Inheritance Investigation", () => {
11+
test("should investigate what fields are being inherited incorrectly", () => {
12+
const mockPlugin = createMockPlugin({
13+
...DEFAULT_SETTINGS,
14+
fileMetadataInheritance: {
15+
enabled: true,
16+
inheritFromFrontmatter: true,
17+
inheritFromFrontmatterForSubtasks: false,
18+
},
19+
});
20+
21+
const config = getConfig("tasks", mockPlugin);
22+
const parser = new MarkdownTaskParser(config);
23+
24+
const content = `- [>] 12312312
25+
- [ ] child task`;
26+
27+
// Simulate problematic file metadata that might contain structural fields
28+
const fileMetadata = {
29+
tags: ["mobility"],
30+
children: ["some-other-task"], // This should NOT be inherited
31+
parent: "some-parent", // This should NOT be inherited
32+
heading: ["Some Heading"], // This should NOT be inherited
33+
id: "file-id", // This should NOT be inherited
34+
priority: "high", // This SHOULD be inherited
35+
area: "work", // This SHOULD be inherited
36+
};
37+
38+
const tasks = parser.parseLegacy(content, "templify-asdasdasd-20250704120358.md", fileMetadata);
39+
40+
const parentTask = tasks[0];
41+
const childTask = tasks[1];
42+
43+
// Check parent task
44+
console.log("Parent task metadata:", JSON.stringify(parentTask.metadata, null, 2));
45+
46+
// Check child task
47+
console.log("Child task metadata:", JSON.stringify(childTask.metadata, null, 2));
48+
49+
// The problematic fields should NOT be inherited from file metadata
50+
expect(parentTask.metadata.children).not.toEqual(["some-other-task"]);
51+
expect(parentTask.metadata.parent).not.toBe("some-parent");
52+
expect(parentTask.metadata.id).not.toBe("file-id");
53+
54+
// But the appropriate fields should be inherited
55+
expect(parentTask.metadata.priority).toBe(4); // "high" converted to 4
56+
expect(parentTask.metadata.area).toBe("work");
57+
expect(parentTask.metadata.tags).toContain("mobility");
58+
59+
// Parent task should have correct structural fields
60+
expect(parentTask.metadata.children).toEqual([childTask.id]);
61+
expect(parentTask.metadata.parent).toBeUndefined();
62+
63+
// Child task should have correct structural fields
64+
expect(childTask.metadata.children).toEqual([]);
65+
expect(childTask.metadata.parent).toBe(parentTask.id);
66+
});
67+
});

src/styles/tag-view.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
height: 100%;
66
width: 100%;
77
overflow: hidden;
8+
flex: 1;
9+
}
10+
11+
.task-genius-view:has(.task-details.visible) .tags-left-column {
12+
display: none;
813
}
914

1015
.tags-content {

0 commit comments

Comments
 (0)