Repository: obsidian-tasks-group/obsidian-tasks
Pull request #2949 (2024-07-11 10:55:15)

feat: improve access to tags
# Types of changes

Done by pairing with @claremacrae 

- `tasksFile.tags`
- `tasksFile.frontmatter.tags`
- ability to test Obsidian functions `getAllTags()` and `parseFrontMatterTags()`

Changes visible to users:

- [x] **New feature** (prefix: `feat` - non-breaking change which adds functionality)
  - Issue/discussion: https://github.com/obsidian-tasks-group/obsidian-tasks/issues/2480

Internal changes:

- [x] **Refactor** (prefix: `refactor` - non-breaking change which only improves the design or structure of existing code, and making no changes to its external behaviour)
- [x] **Tests** (prefix: `test` - additions and improvements to unit tests and the smoke tests)

## Description

<!--- Remember to provide a general summary of your changes in the Title above -->

<!--- Describe your changes in detail -->

## Motivation and Context

- provide access to filter by YAML tags

## How has this been tested?

- new unit tests

## Checklist

- [x] My code follows the code style of this project and passes `yarn run lint`.
- [x] My change requires a change to the documentation.
- [ ] I have [updated the documentation](https://publish.obsidian.md/tasks-contributing/Documentation/About+Documentation) accordingly.
  - to be done later
- [x] My change has adequate [Unit Test coverage](https://publish.obsidian.md/tasks-contributing/Testing/About+Testing).

## Terms

<!--
By submitting this pull request, you must agree to follow our
[contributing guide](https://publish.obsidian.md/tasks-contributing) and
[Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md).
Put an x in the boxes to confirm you agree.
-->

- [x] My contribution follows this project's [contributing guide](https://publish.obsidian.md/tasks-contributing)
- [x] I agree to follow this project's [Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md)



Patch:
diff --git a/src/Scripting/TasksFile.ts b/src/Scripting/TasksFile.ts
index ff981487..f2111eaa 100644
--- a/src/Scripting/TasksFile.ts
+++ b/src/Scripting/TasksFile.ts
@@ -6,10 +6,17 @@ import { type CachedMetadata, type FrontMatterCache, getAllTags, parseFrontMatte
 export class TasksFile {
     private readonly _path: string;
     private readonly _cachedMetadata: CachedMetadata;
+    private readonly _frontmatter: FrontMatterCache = {} as FrontMatterCache;
 
     constructor(path: string, cachedMetadata: CachedMetadata = {}) {
         this._path = path;
         this._cachedMetadata = cachedMetadata;
+
+        const rawFrontmatter = cachedMetadata.frontmatter;
+        if (rawFrontmatter !== undefined) {
+            this._frontmatter = JSON.parse(JSON.stringify(rawFrontmatter));
+            this._frontmatter.tags = parseFrontMatterTags(rawFrontmatter);
+        }
     }
 
     /**
@@ -29,7 +36,8 @@ export class TasksFile {
      * @todo Review presence of global filter tag in the results.
      */
     get tags(): string[] {
-        return getAllTags(this.cachedMetadata) ?? [];
+        const tags = getAllTags(this.cachedMetadata) ?? [];
+        return [...new Set(tags)];
     }
 
     /**
@@ -71,7 +79,7 @@ export class TasksFile {
      *       or if the markdown file has no frontmatter or empty frontmatter.
      */
     public get frontmatter(): FrontMatterCache {
-        return this._cachedMetadata.frontmatter ?? ({} as FrontMatterCache);
+        return this._frontmatter;
     }
 
     /**


Test patch:
diff --git a/resources/sample_vaults/Tasks-Demo/_meta/templater_scripts/convert_test_data_markdown_to_js.js b/resources/sample_vaults/Tasks-Demo/_meta/templater_scripts/convert_test_data_markdown_to_js.js
index 09cdf30e..4dd1148c 100644
--- a/resources/sample_vaults/Tasks-Demo/_meta/templater_scripts/convert_test_data_markdown_to_js.js
+++ b/resources/sample_vaults/Tasks-Demo/_meta/templater_scripts/convert_test_data_markdown_to_js.js
@@ -7,7 +7,9 @@ async function convertMarkdownFileToTestFunction(filePath, tp) {
     const fileContents = await app.vault.read(tFile);
     const cachedMetadata = app.metadataCache.getFileCache(tFile);
     const obsidianApiVersion = tp.obsidian.apiVersion;
-    const data = { filePath, fileContents, cachedMetadata, obsidianApiVersion };
+    const getAllTags = tp.obsidian.getAllTags(cachedMetadata);
+    const parseFrontMatterTags = tp.obsidian.parseFrontMatterTags(cachedMetadata.frontmatter);
+    const data = { filePath, fileContents, cachedMetadata, obsidianApiVersion, getAllTags, parseFrontMatterTags };
 
     const filename = filePath.split('/')[1].replace('.md', '');
     if (filename.includes(' ')) {
diff --git a/tests/Obsidian/__test_data__/blockquote.ts b/tests/Obsidian/__test_data__/blockquote.ts
index baeeed87..f85da8f2 100644
--- a/tests/Obsidian/__test_data__/blockquote.ts
+++ b/tests/Obsidian/__test_data__/blockquote.ts
@@ -124,4 +124,6 @@ export const blockquote = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/callout.ts b/tests/Obsidian/__test_data__/callout.ts
index f17943cc..f53efc45 100644
--- a/tests/Obsidian/__test_data__/callout.ts
+++ b/tests/Obsidian/__test_data__/callout.ts
@@ -145,4 +145,6 @@ export const callout = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/callout_custom.ts b/tests/Obsidian/__test_data__/callout_custom.ts
index 1fa21c47..7c6c8553 100644
--- a/tests/Obsidian/__test_data__/callout_custom.ts
+++ b/tests/Obsidian/__test_data__/callout_custom.ts
@@ -145,4 +145,6 @@ export const callout_custom = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/callout_labelled.ts b/tests/Obsidian/__test_data__/callout_labelled.ts
index c9f95150..2dd298e5 100644
--- a/tests/Obsidian/__test_data__/callout_labelled.ts
+++ b/tests/Obsidian/__test_data__/callout_labelled.ts
@@ -145,4 +145,6 @@ export const callout_labelled = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/callouts_nested_issue_2890_labelled.ts b/tests/Obsidian/__test_data__/callouts_nested_issue_2890_labelled.ts
index db8fa973..70d22d4f 100644
--- a/tests/Obsidian/__test_data__/callouts_nested_issue_2890_labelled.ts
+++ b/tests/Obsidian/__test_data__/callouts_nested_issue_2890_labelled.ts
@@ -177,4 +177,6 @@ export const callouts_nested_issue_2890_labelled = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/callouts_nested_issue_2890_unlabelled.ts b/tests/Obsidian/__test_data__/callouts_nested_issue_2890_unlabelled.ts
index ea4fb456..16d07f9f 100644
--- a/tests/Obsidian/__test_data__/callouts_nested_issue_2890_unlabelled.ts
+++ b/tests/Obsidian/__test_data__/callouts_nested_issue_2890_unlabelled.ts
@@ -177,4 +177,6 @@ export const callouts_nested_issue_2890_unlabelled = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/comments_html_style.ts b/tests/Obsidian/__test_data__/comments_html_style.ts
index 332ab283..e894a574 100644
--- a/tests/Obsidian/__test_data__/comments_html_style.ts
+++ b/tests/Obsidian/__test_data__/comments_html_style.ts
@@ -159,4 +159,6 @@ export const comments_html_style = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/comments_markdown_style.ts b/tests/Obsidian/__test_data__/comments_markdown_style.ts
index 908c8f07..126479b5 100644
--- a/tests/Obsidian/__test_data__/comments_markdown_style.ts
+++ b/tests/Obsidian/__test_data__/comments_markdown_style.ts
@@ -208,4 +208,6 @@ export const comments_markdown_style = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#i-am-parsed-by-obsidian', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/empty_yaml.ts b/tests/Obsidian/__test_data__/empty_yaml.ts
index 946aab5b..3511469e 100644
--- a/tests/Obsidian/__test_data__/empty_yaml.ts
+++ b/tests/Obsidian/__test_data__/empty_yaml.ts
@@ -4,7 +4,6 @@ export const empty_yaml = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 5,
@@ -17,12 +16,11 @@ export const empty_yaml = {
                         offset: 34,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'empty_yaml',
-                level: 1,
                 position: {
                     start: {
                         line: 3,
@@ -35,6 +33,8 @@ export const empty_yaml = {
                         offset: 21,
                     },
                 },
+                heading: 'empty_yaml',
+                level: 1,
             },
         ],
         sections: [
@@ -86,8 +86,6 @@ export const empty_yaml = {
         ],
         listItems: [
             {
-                parent: -5,
-                task: ' ',
                 position: {
                     start: {
                         line: 5,
@@ -100,8 +98,12 @@ export const empty_yaml = {
                         offset: 55,
                     },
                 },
+                parent: -5,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/example_kanban.ts b/tests/Obsidian/__test_data__/example_kanban.ts
index 8e6bd531..2801f7ed 100644
--- a/tests/Obsidian/__test_data__/example_kanban.ts
+++ b/tests/Obsidian/__test_data__/example_kanban.ts
@@ -20,7 +20,6 @@ export const example_kanban = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 8,
@@ -33,12 +32,11 @@ export const example_kanban = {
                         offset: 55,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'Backlog',
-                level: 2,
                 position: {
                     start: {
                         line: 6,
@@ -51,6 +49,8 @@ export const example_kanban = {
                         offset: 42,
                     },
                 },
+                heading: 'Backlog',
+                level: 2,
             },
         ],
         sections: [
@@ -117,8 +117,6 @@ export const example_kanban = {
         ],
         listItems: [
             {
-                parent: -8,
-                task: ' ',
                 position: {
                     start: {
                         line: 8,
@@ -131,12 +129,13 @@ export const example_kanban = {
                         offset: 80,
                     },
                 },
+                parent: -8,
+                task: ' ',
             },
         ],
         frontmatter: {
             'kanban-plugin': 'basic',
         },
-        frontmatterLinks: [],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -149,6 +148,9 @@ export const example_kanban = {
                 offset: 30,
             },
         },
+        frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_1parent1child.ts b/tests/Obsidian/__test_data__/inheritance_1parent1child.ts
index 956e5799..39776601 100644
--- a/tests/Obsidian/__test_data__/inheritance_1parent1child.ts
+++ b/tests/Obsidian/__test_data__/inheritance_1parent1child.ts
@@ -87,4 +87,6 @@ export const inheritance_1parent1child = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_1parent1child1newroot_after_header.ts b/tests/Obsidian/__test_data__/inheritance_1parent1child1newroot_after_header.ts
index 54207aab..206d40d2 100644
--- a/tests/Obsidian/__test_data__/inheritance_1parent1child1newroot_after_header.ts
+++ b/tests/Obsidian/__test_data__/inheritance_1parent1child1newroot_after_header.ts
@@ -205,4 +205,6 @@ export const inheritance_1parent1child1newroot_after_header = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_1parent1child1sibling_emptystring.ts b/tests/Obsidian/__test_data__/inheritance_1parent1child1sibling_emptystring.ts
index cb3c0158..d97ced69 100644
--- a/tests/Obsidian/__test_data__/inheritance_1parent1child1sibling_emptystring.ts
+++ b/tests/Obsidian/__test_data__/inheritance_1parent1child1sibling_emptystring.ts
@@ -118,4 +118,6 @@ export const inheritance_1parent1child1sibling_emptystring = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_1parent2children.ts b/tests/Obsidian/__test_data__/inheritance_1parent2children.ts
index 03eb099c..ac476252 100644
--- a/tests/Obsidian/__test_data__/inheritance_1parent2children.ts
+++ b/tests/Obsidian/__test_data__/inheritance_1parent2children.ts
@@ -118,4 +118,6 @@ export const inheritance_1parent2children = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_1parent2children1grandchild.ts b/tests/Obsidian/__test_data__/inheritance_1parent2children1grandchild.ts
index 6aad54f1..b5211f43 100644
--- a/tests/Obsidian/__test_data__/inheritance_1parent2children1grandchild.ts
+++ b/tests/Obsidian/__test_data__/inheritance_1parent2children1grandchild.ts
@@ -8,7 +8,6 @@ export const inheritance_1parent2children1grandchild = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 0,
@@ -21,9 +20,9 @@ export const inheritance_1parent2children1grandchild = {
                         offset: 11,
                     },
                 },
+                tag: '#task',
             },
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 1,
@@ -36,9 +35,9 @@ export const inheritance_1parent2children1grandchild = {
                         offset: 39,
                     },
                 },
+                tag: '#task',
             },
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 2,
@@ -51,9 +50,9 @@ export const inheritance_1parent2children1grandchild = {
                         offset: 68,
                     },
                 },
+                tag: '#task',
             },
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 3,
@@ -66,6 +65,7 @@ export const inheritance_1parent2children1grandchild = {
                         offset: 101,
                     },
                 },
+                tag: '#task',
             },
         ],
         sections: [
@@ -87,8 +87,6 @@ export const inheritance_1parent2children1grandchild = {
         ],
         listItems: [
             {
-                parent: -1,
-                task: ' ',
                 position: {
                     start: {
                         line: 0,
@@ -101,10 +99,10 @@ export const inheritance_1parent2children1grandchild = {
                         offset: 23,
                     },
                 },
+                parent: -1,
+                task: ' ',
             },
             {
-                parent: 0,
-                task: ' ',
                 position: {
                     start: {
                         line: 1,
@@ -117,10 +115,10 @@ export const inheritance_1parent2children1grandchild = {
                         offset: 52,
                     },
                 },
-            },
-            {
                 parent: 0,
                 task: ' ',
+            },
+            {
                 position: {
                     start: {
                         line: 2,
@@ -133,10 +131,10 @@ export const inheritance_1parent2children1grandchild = {
                         offset: 81,
                     },
                 },
+                parent: 0,
+                task: ' ',
             },
             {
-                parent: 2,
-                task: ' ',
                 position: {
                     start: {
                         line: 3,
@@ -149,8 +147,12 @@ export const inheritance_1parent2children1grandchild = {
                         offset: 114,
                     },
                 },
+                parent: 2,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_1parent2children1sibling.ts b/tests/Obsidian/__test_data__/inheritance_1parent2children1sibling.ts
index 29706c43..28f416f6 100644
--- a/tests/Obsidian/__test_data__/inheritance_1parent2children1sibling.ts
+++ b/tests/Obsidian/__test_data__/inheritance_1parent2children1sibling.ts
@@ -150,4 +150,6 @@ export const inheritance_1parent2children1sibling = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren.ts b/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren.ts
index d4c7207e..dbfad8a5 100644
--- a/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren.ts
+++ b/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren.ts
@@ -185,4 +185,6 @@ export const inheritance_1parent2children2grandchildren = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren1sibling.ts b/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren1sibling.ts
index 801257a5..b4b75e35 100644
--- a/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren1sibling.ts
+++ b/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren1sibling.ts
@@ -217,4 +217,6 @@ export const inheritance_1parent2children2grandchildren1sibling = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task', '#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren1sibling_start_with_heading.ts b/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren1sibling_start_with_heading.ts
index 292e378e..c00200cd 100644
--- a/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren1sibling_start_with_heading.ts
+++ b/tests/Obsidian/__test_data__/inheritance_1parent2children2grandchildren1sibling_start_with_heading.ts
@@ -12,7 +12,6 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 2,
@@ -25,9 +24,9 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 27,
                     },
                 },
+                tag: '#task',
             },
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 3,
@@ -40,9 +39,9 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 55,
                     },
                 },
+                tag: '#task',
             },
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 4,
@@ -55,9 +54,9 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 88,
                     },
                 },
+                tag: '#task',
             },
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 5,
@@ -70,9 +69,9 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 117,
                     },
                 },
+                tag: '#task',
             },
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 6,
@@ -85,9 +84,9 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 150,
                     },
                 },
+                tag: '#task',
             },
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 7,
@@ -100,12 +99,11 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 175,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'Test heading',
-                level: 1,
                 position: {
                     start: {
                         line: 0,
@@ -118,6 +116,8 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 14,
                     },
                 },
+                heading: 'Test heading',
+                level: 1,
             },
         ],
         sections: [
@@ -154,8 +154,6 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
         ],
         listItems: [
             {
-                parent: -2,
-                task: ' ',
                 position: {
                     start: {
                         line: 2,
@@ -168,10 +166,10 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 39,
                     },
                 },
+                parent: -2,
+                task: ' ',
             },
             {
-                parent: 2,
-                task: ' ',
                 position: {
                     start: {
                         line: 3,
@@ -184,10 +182,10 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 68,
                     },
                 },
+                parent: 2,
+                task: ' ',
             },
             {
-                parent: 3,
-                task: ' ',
                 position: {
                     start: {
                         line: 4,
@@ -200,10 +198,10 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 101,
                     },
                 },
+                parent: 3,
+                task: ' ',
             },
             {
-                parent: 2,
-                task: ' ',
                 position: {
                     start: {
                         line: 5,
@@ -216,10 +214,10 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 130,
                     },
                 },
+                parent: 2,
+                task: ' ',
             },
             {
-                parent: 5,
-                task: ' ',
                 position: {
                     start: {
                         line: 6,
@@ -232,10 +230,10 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 163,
                     },
                 },
+                parent: 5,
+                task: ' ',
             },
             {
-                parent: -2,
-                task: ' ',
                 position: {
                     start: {
                         line: 7,
@@ -248,8 +246,12 @@ export const inheritance_1parent2children2grandchildren1sibling_start_with_headi
                         offset: 183,
                     },
                 },
+                parent: -2,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task', '#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_2siblings.ts b/tests/Obsidian/__test_data__/inheritance_2siblings.ts
index 578638ac..00edb655 100644
--- a/tests/Obsidian/__test_data__/inheritance_2siblings.ts
+++ b/tests/Obsidian/__test_data__/inheritance_2siblings.ts
@@ -87,4 +87,6 @@ export const inheritance_2siblings = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_listitem_task.ts b/tests/Obsidian/__test_data__/inheritance_listitem_task.ts
index f512f0d7..9d2e7754 100644
--- a/tests/Obsidian/__test_data__/inheritance_listitem_task.ts
+++ b/tests/Obsidian/__test_data__/inheritance_listitem_task.ts
@@ -54,4 +54,6 @@ export const inheritance_listitem_task = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: [],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_listitem_task_siblings.ts b/tests/Obsidian/__test_data__/inheritance_listitem_task_siblings.ts
index 6aea3361..9a7541bc 100644
--- a/tests/Obsidian/__test_data__/inheritance_listitem_task_siblings.ts
+++ b/tests/Obsidian/__test_data__/inheritance_listitem_task_siblings.ts
@@ -54,4 +54,6 @@ export const inheritance_listitem_task_siblings = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: [],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_task_2listitem_3task.ts b/tests/Obsidian/__test_data__/inheritance_task_2listitem_3task.ts
index ed3ba8bd..1b5ac5e9 100644
--- a/tests/Obsidian/__test_data__/inheritance_task_2listitem_3task.ts
+++ b/tests/Obsidian/__test_data__/inheritance_task_2listitem_3task.ts
@@ -123,4 +123,6 @@ export const inheritance_task_2listitem_3task = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: [],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_task_listitem.ts b/tests/Obsidian/__test_data__/inheritance_task_listitem.ts
index 2243e4bb..240174b6 100644
--- a/tests/Obsidian/__test_data__/inheritance_task_listitem.ts
+++ b/tests/Obsidian/__test_data__/inheritance_task_listitem.ts
@@ -21,8 +21,6 @@ export const inheritance_task_listitem = {
         ],
         listItems: [
             {
-                parent: -1,
-                task: ' ',
                 position: {
                     start: {
                         line: 0,
@@ -35,9 +33,10 @@ export const inheritance_task_listitem = {
                         offset: 17,
                     },
                 },
+                parent: -1,
+                task: ' ',
             },
             {
-                parent: 0,
                 position: {
                     start: {
                         line: 1,
@@ -50,8 +49,11 @@ export const inheritance_task_listitem = {
                         offset: 39,
                     },
                 },
+                parent: 0,
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: [],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_task_listitem_mixed_grandchildren.ts b/tests/Obsidian/__test_data__/inheritance_task_listitem_mixed_grandchildren.ts
index 562fbdaa..6b5915ce 100644
--- a/tests/Obsidian/__test_data__/inheritance_task_listitem_mixed_grandchildren.ts
+++ b/tests/Obsidian/__test_data__/inheritance_task_listitem_mixed_grandchildren.ts
@@ -26,8 +26,6 @@ export const inheritance_task_listitem_mixed_grandchildren = {
         ],
         listItems: [
             {
-                parent: -1,
-                task: ' ',
                 position: {
                     start: {
                         line: 0,
@@ -40,9 +38,10 @@ export const inheritance_task_listitem_mixed_grandchildren = {
                         offset: 17,
                     },
                 },
+                parent: -1,
+                task: ' ',
             },
             {
-                parent: 0,
                 position: {
                     start: {
                         line: 1,
@@ -55,9 +54,9 @@ export const inheritance_task_listitem_mixed_grandchildren = {
                         offset: 39,
                     },
                 },
+                parent: 0,
             },
             {
-                parent: 1,
                 position: {
                     start: {
                         line: 2,
@@ -70,10 +69,9 @@ export const inheritance_task_listitem_mixed_grandchildren = {
                         offset: 72,
                     },
                 },
+                parent: 1,
             },
             {
-                parent: 1,
-                task: ' ',
                 position: {
                     start: {
                         line: 3,
@@ -86,9 +84,10 @@ export const inheritance_task_listitem_mixed_grandchildren = {
                         offset: 102,
                     },
                 },
+                parent: 1,
+                task: ' ',
             },
             {
-                parent: 1,
                 position: {
                     start: {
                         line: 4,
@@ -101,8 +100,11 @@ export const inheritance_task_listitem_mixed_grandchildren = {
                         offset: 135,
                     },
                 },
+                parent: 1,
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: [],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_task_listitem_task.ts b/tests/Obsidian/__test_data__/inheritance_task_listitem_task.ts
index b932becc..fc254f83 100644
--- a/tests/Obsidian/__test_data__/inheritance_task_listitem_task.ts
+++ b/tests/Obsidian/__test_data__/inheritance_task_listitem_task.ts
@@ -21,8 +21,6 @@ export const inheritance_task_listitem_task = {
         ],
         listItems: [
             {
-                parent: -1,
-                task: ' ',
                 position: {
                     start: {
                         line: 0,
@@ -35,9 +33,10 @@ export const inheritance_task_listitem_task = {
                         offset: 17,
                     },
                 },
+                parent: -1,
+                task: ' ',
             },
             {
-                parent: 0,
                 position: {
                     start: {
                         line: 1,
@@ -50,10 +49,9 @@ export const inheritance_task_listitem_task = {
                         offset: 39,
                     },
                 },
+                parent: 0,
             },
             {
-                parent: 1,
-                task: ' ',
                 position: {
                     start: {
                         line: 2,
@@ -66,8 +64,12 @@ export const inheritance_task_listitem_task = {
                         offset: 69,
                     },
                 },
+                parent: 1,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: [],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/inheritance_task_mixed_children.ts b/tests/Obsidian/__test_data__/inheritance_task_mixed_children.ts
index c494ea7d..fcd47943 100644
--- a/tests/Obsidian/__test_data__/inheritance_task_mixed_children.ts
+++ b/tests/Obsidian/__test_data__/inheritance_task_mixed_children.ts
@@ -87,4 +87,6 @@ export const inheritance_task_mixed_children = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: [],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/link_in_file_body.ts b/tests/Obsidian/__test_data__/link_in_file_body.ts
index 6bd5b370..6be9f66b 100644
--- a/tests/Obsidian/__test_data__/link_in_file_body.ts
+++ b/tests/Obsidian/__test_data__/link_in_file_body.ts
@@ -9,9 +9,6 @@ export const link_in_file_body = {
     cachedMetadata: {
         links: [
             {
-                link: 'yaml_tags_is_empty',
-                original: '[[yaml_tags_is_empty]]',
-                displayText: 'yaml_tags_is_empty',
                 position: {
                     start: {
                         line: 2,
@@ -24,11 +21,13 @@ export const link_in_file_body = {
                         offset: 53,
                     },
                 },
+                link: 'yaml_tags_is_empty',
+                original: '[[yaml_tags_is_empty]]',
+                displayText: 'yaml_tags_is_empty',
             },
         ],
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 4,
@@ -41,12 +40,11 @@ export const link_in_file_body = {
                         offset: 66,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'link_in_file_body',
-                level: 1,
                 position: {
                     start: {
                         line: 0,
@@ -59,6 +57,8 @@ export const link_in_file_body = {
                         offset: 19,
                     },
                 },
+                heading: 'link_in_file_body',
+                level: 1,
             },
         ],
         sections: [
@@ -110,8 +110,6 @@ export const link_in_file_body = {
         ],
         listItems: [
             {
-                parent: -4,
-                task: ' ',
                 position: {
                     start: {
                         line: 4,
@@ -124,8 +122,12 @@ export const link_in_file_body = {
                         offset: 94,
                     },
                 },
+                parent: -4,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/link_in_file_body_with_custom_display_text.ts b/tests/Obsidian/__test_data__/link_in_file_body_with_custom_display_text.ts
index 784af71a..fc65c6d3 100644
--- a/tests/Obsidian/__test_data__/link_in_file_body_with_custom_display_text.ts
+++ b/tests/Obsidian/__test_data__/link_in_file_body_with_custom_display_text.ts
@@ -9,9 +9,6 @@ export const link_in_file_body_with_custom_display_text = {
     cachedMetadata: {
         links: [
             {
-                link: 'yaml_tags_is_empty',
-                original: '[[yaml_tags_is_empty|a file and use custom display text]]',
-                displayText: 'a file and use custom display text',
                 position: {
                     start: {
                         line: 2,
@@ -24,11 +21,13 @@ export const link_in_file_body_with_custom_display_text = {
                         offset: 113,
                     },
                 },
+                link: 'yaml_tags_is_empty',
+                original: '[[yaml_tags_is_empty|a file and use custom display text]]',
+                displayText: 'a file and use custom display text',
             },
         ],
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 4,
@@ -41,12 +40,11 @@ export const link_in_file_body_with_custom_display_text = {
                         offset: 126,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'link_in_file_body_with_custom_display_text',
-                level: 1,
                 position: {
                     start: {
                         line: 0,
@@ -59,6 +57,8 @@ export const link_in_file_body_with_custom_display_text = {
                         offset: 44,
                     },
                 },
+                heading: 'link_in_file_body_with_custom_display_text',
+                level: 1,
             },
         ],
         sections: [
@@ -110,8 +110,6 @@ export const link_in_file_body_with_custom_display_text = {
         ],
         listItems: [
             {
-                parent: -4,
-                task: ' ',
                 position: {
                     start: {
                         line: 4,
@@ -124,8 +122,12 @@ export const link_in_file_body_with_custom_display_text = {
                         offset: 179,
                     },
                 },
+                parent: -4,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/link_in_heading.ts b/tests/Obsidian/__test_data__/link_in_heading.ts
index 35662b17..bac06d7d 100644
--- a/tests/Obsidian/__test_data__/link_in_heading.ts
+++ b/tests/Obsidian/__test_data__/link_in_heading.ts
@@ -9,9 +9,6 @@ export const link_in_heading = {
     cachedMetadata: {
         links: [
             {
-                link: 'multiple_headings',
-                original: '[[multiple_headings]]',
-                displayText: 'multiple_headings',
                 position: {
                     start: {
                         line: 2,
@@ -24,11 +21,13 @@ export const link_in_heading = {
                         offset: 53,
                     },
                 },
+                link: 'multiple_headings',
+                original: '[[multiple_headings]]',
+                displayText: 'multiple_headings',
             },
         ],
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 4,
@@ -41,12 +40,11 @@ export const link_in_heading = {
                         offset: 66,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'link_in_heading',
-                level: 1,
                 position: {
                     start: {
                         line: 0,
@@ -59,10 +57,10 @@ export const link_in_heading = {
                         offset: 17,
                     },
                 },
+                heading: 'link_in_heading',
+                level: 1,
             },
             {
-                heading: 'I link to [[multiple_headings]]',
-                level: 2,
                 position: {
                     start: {
                         line: 2,
@@ -75,6 +73,8 @@ export const link_in_heading = {
                         offset: 53,
                     },
                 },
+                heading: 'I link to [[multiple_headings]]',
+                level: 2,
             },
         ],
         sections: [
@@ -126,8 +126,6 @@ export const link_in_heading = {
         ],
         listItems: [
             {
-                parent: -4,
-                task: ' ',
                 position: {
                     start: {
                         line: 4,
@@ -140,8 +138,12 @@ export const link_in_heading = {
                         offset: 92,
                     },
                 },
+                parent: -4,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/link_in_yaml.ts b/tests/Obsidian/__test_data__/link_in_yaml.ts
index 300ac7da..3ad098de 100644
--- a/tests/Obsidian/__test_data__/link_in_yaml.ts
+++ b/tests/Obsidian/__test_data__/link_in_yaml.ts
@@ -11,7 +11,6 @@ export const link_in_yaml = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 6,
@@ -24,12 +23,11 @@ export const link_in_yaml = {
                         offset: 72,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'link_in_yaml',
-                level: 1,
                 position: {
                     start: {
                         line: 4,
@@ -42,6 +40,8 @@ export const link_in_yaml = {
                         offset: 59,
                     },
                 },
+                heading: 'link_in_yaml',
+                level: 1,
             },
         ],
         sections: [
@@ -93,8 +93,6 @@ export const link_in_yaml = {
         ],
         listItems: [
             {
-                parent: -6,
-                task: ' ',
                 position: {
                     start: {
                         line: 6,
@@ -107,19 +105,13 @@ export const link_in_yaml = {
                         offset: 95,
                     },
                 },
+                parent: -6,
+                task: ' ',
             },
         ],
         frontmatter: {
             'test-link': '[[yaml_tags_is_empty]]',
         },
-        frontmatterLinks: [
-            {
-                key: 'test-link',
-                link: 'yaml_tags_is_empty',
-                original: '[[yaml_tags_is_empty]]',
-                displayText: 'yaml_tags_is_empty',
-            },
-        ],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -132,6 +124,16 @@ export const link_in_yaml = {
                 offset: 43,
             },
         },
+        frontmatterLinks: [
+            {
+                key: 'test-link',
+                link: 'yaml_tags_is_empty',
+                original: '[[yaml_tags_is_empty]]',
+                displayText: 'yaml_tags_is_empty',
+            },
+        ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/link_is_broken.ts b/tests/Obsidian/__test_data__/link_is_broken.ts
index 186eba52..2cc8a3af 100644
--- a/tests/Obsidian/__test_data__/link_is_broken.ts
+++ b/tests/Obsidian/__test_data__/link_is_broken.ts
@@ -5,9 +5,6 @@ export const link_is_broken = {
     cachedMetadata: {
         links: [
             {
-                link: 'broken link - do not fix me',
-                original: '[[broken link - do not fix me]]',
-                displayText: 'broken link - do not fix me',
                 position: {
                     start: {
                         line: 2,
@@ -20,11 +17,13 @@ export const link_is_broken = {
                         offset: 86,
                     },
                 },
+                link: 'broken link - do not fix me',
+                original: '[[broken link - do not fix me]]',
+                displayText: 'broken link - do not fix me',
             },
         ],
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 2,
@@ -37,12 +36,11 @@ export const link_is_broken = {
                         offset: 29,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'link_is_broken',
-                level: 1,
                 position: {
                     start: {
                         line: 0,
@@ -55,6 +53,8 @@ export const link_is_broken = {
                         offset: 16,
                     },
                 },
+                heading: 'link_is_broken',
+                level: 1,
             },
         ],
         sections: [
@@ -91,8 +91,6 @@ export const link_is_broken = {
         ],
         listItems: [
             {
-                parent: -2,
-                task: ' ',
                 position: {
                     start: {
                         line: 2,
@@ -105,8 +103,12 @@ export const link_is_broken = {
                         offset: 86,
                     },
                 },
+                parent: -2,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/list_statuses.ts b/tests/Obsidian/__test_data__/list_statuses.ts
index 29a958d9..d06a4146 100644
--- a/tests/Obsidian/__test_data__/list_statuses.ts
+++ b/tests/Obsidian/__test_data__/list_statuses.ts
@@ -170,4 +170,6 @@ export const list_statuses = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/list_styles.ts b/tests/Obsidian/__test_data__/list_styles.ts
index fc592451..72863215 100644
--- a/tests/Obsidian/__test_data__/list_styles.ts
+++ b/tests/Obsidian/__test_data__/list_styles.ts
@@ -329,4 +329,6 @@ export const list_styles = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task', '#task', '#task', '#task', '#task', '#task', '#task', '#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/multi_line_task_and_list_item.ts b/tests/Obsidian/__test_data__/multi_line_task_and_list_item.ts
index fed5b7e2..f3919234 100644
--- a/tests/Obsidian/__test_data__/multi_line_task_and_list_item.ts
+++ b/tests/Obsidian/__test_data__/multi_line_task_and_list_item.ts
@@ -130,4 +130,6 @@ export const multi_line_task_and_list_item = {
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/multiple_headings.ts b/tests/Obsidian/__test_data__/multiple_headings.ts
index 338b8c78..a618858d 100644
--- a/tests/Obsidian/__test_data__/multiple_headings.ts
+++ b/tests/Obsidian/__test_data__/multiple_headings.ts
@@ -11,7 +11,6 @@ export const multiple_headings = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 6,
@@ -24,12 +23,11 @@ export const multiple_headings = {
                         offset: 73,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'multiple_headings',
-                level: 1,
                 position: {
                     start: {
                         line: 0,
@@ -42,10 +40,10 @@ export const multiple_headings = {
                         offset: 19,
                     },
                 },
+                heading: 'multiple_headings',
+                level: 1,
             },
             {
-                heading: 'Level 2 heading',
-                level: 2,
                 position: {
                     start: {
                         line: 2,
@@ -58,10 +56,10 @@ export const multiple_headings = {
                         offset: 39,
                     },
                 },
+                heading: 'Level 2 heading',
+                level: 2,
             },
             {
-                heading: 'Level 3 heading',
-                level: 3,
                 position: {
                     start: {
                         line: 4,
@@ -74,6 +72,8 @@ export const multiple_headings = {
                         offset: 60,
                     },
                 },
+                heading: 'Level 3 heading',
+                level: 3,
             },
         ],
         sections: [
@@ -140,8 +140,6 @@ export const multiple_headings = {
         ],
         listItems: [
             {
-                parent: -6,
-                task: ' ',
                 position: {
                     start: {
                         line: 6,
@@ -154,8 +152,12 @@ export const multiple_headings = {
                         offset: 101,
                     },
                 },
+                parent: -6,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/no_heading.ts b/tests/Obsidian/__test_data__/no_heading.ts
index 056c7001..e6a3ede0 100644
--- a/tests/Obsidian/__test_data__/no_heading.ts
+++ b/tests/Obsidian/__test_data__/no_heading.ts
@@ -4,7 +4,6 @@ export const no_heading = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 0,
@@ -17,6 +16,7 @@ export const no_heading = {
                         offset: 11,
                     },
                 },
+                tag: '#task',
             },
         ],
         sections: [
@@ -38,8 +38,6 @@ export const no_heading = {
         ],
         listItems: [
             {
-                parent: -1,
-                task: ' ',
                 position: {
                     start: {
                         line: 0,
@@ -52,8 +50,12 @@ export const no_heading = {
                         offset: 32,
                     },
                 },
+                parent: -1,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/no_yaml.ts b/tests/Obsidian/__test_data__/no_yaml.ts
index b99f62be..55c73517 100644
--- a/tests/Obsidian/__test_data__/no_yaml.ts
+++ b/tests/Obsidian/__test_data__/no_yaml.ts
@@ -4,7 +4,6 @@ export const no_yaml = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 2,
@@ -17,12 +16,11 @@ export const no_yaml = {
                         offset: 22,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'no_yaml',
-                level: 1,
                 position: {
                     start: {
                         line: 0,
@@ -35,6 +33,8 @@ export const no_yaml = {
                         offset: 9,
                     },
                 },
+                heading: 'no_yaml',
+                level: 1,
             },
         ],
         sections: [
@@ -71,8 +71,6 @@ export const no_yaml = {
         ],
         listItems: [
             {
-                parent: -2,
-                task: ' ',
                 position: {
                     start: {
                         line: 2,
@@ -85,8 +83,12 @@ export const no_yaml = {
                         offset: 40,
                     },
                 },
+                parent: -2,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/one_task.ts b/tests/Obsidian/__test_data__/one_task.ts
index af3e8177..e6777a9f 100644
--- a/tests/Obsidian/__test_data__/one_task.ts
+++ b/tests/Obsidian/__test_data__/one_task.ts
@@ -4,7 +4,6 @@ export const one_task = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 0,
@@ -17,6 +16,7 @@ export const one_task = {
                         offset: 11,
                     },
                 },
+                tag: '#task',
             },
         ],
         sections: [
@@ -38,8 +38,6 @@ export const one_task = {
         ],
         listItems: [
             {
-                parent: -1,
-                task: ' ',
                 position: {
                     start: {
                         line: 0,
@@ -52,8 +50,12 @@ export const one_task = {
                         offset: 30,
                     },
                 },
+                parent: -1,
+                task: ' ',
             },
         ],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/yaml_1_alias.ts b/tests/Obsidian/__test_data__/yaml_1_alias.ts
index 2c27ecac..ee595775 100644
--- a/tests/Obsidian/__test_data__/yaml_1_alias.ts
+++ b/tests/Obsidian/__test_data__/yaml_1_alias.ts
@@ -12,7 +12,6 @@ export const yaml_1_alias = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 7,
@@ -25,12 +24,11 @@ export const yaml_1_alias = {
                         offset: 62,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'yaml_1_alias',
-                level: 1,
                 position: {
                     start: {
                         line: 5,
@@ -43,6 +41,8 @@ export const yaml_1_alias = {
                         offset: 49,
                     },
                 },
+                heading: 'yaml_1_alias',
+                level: 1,
             },
         ],
         sections: [
@@ -94,8 +94,6 @@ export const yaml_1_alias = {
         ],
         listItems: [
             {
-                parent: -7,
-                task: ' ',
                 position: {
                     start: {
                         line: 7,
@@ -108,12 +106,13 @@ export const yaml_1_alias = {
                         offset: 85,
                     },
                 },
+                parent: -7,
+                task: ' ',
             },
         ],
         frontmatter: {
             aliases: ['YAML Alias 1'],
         },
-        frontmatterLinks: [],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -126,6 +125,9 @@ export const yaml_1_alias = {
                 offset: 33,
             },
         },
+        frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/yaml_2_aliases.ts b/tests/Obsidian/__test_data__/yaml_2_aliases.ts
index 05c79224..54f1b90f 100644
--- a/tests/Obsidian/__test_data__/yaml_2_aliases.ts
+++ b/tests/Obsidian/__test_data__/yaml_2_aliases.ts
@@ -13,7 +13,6 @@ export const yaml_2_aliases = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 8,
@@ -26,12 +25,11 @@ export const yaml_2_aliases = {
                         offset: 81,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'yaml_2_aliases',
-                level: 1,
                 position: {
                     start: {
                         line: 6,
@@ -44,6 +42,8 @@ export const yaml_2_aliases = {
                         offset: 68,
                     },
                 },
+                heading: 'yaml_2_aliases',
+                level: 1,
             },
         ],
         sections: [
@@ -95,8 +95,6 @@ export const yaml_2_aliases = {
         ],
         listItems: [
             {
-                parent: -8,
-                task: ' ',
                 position: {
                     start: {
                         line: 8,
@@ -109,12 +107,13 @@ export const yaml_2_aliases = {
                         offset: 106,
                     },
                 },
+                parent: -8,
+                task: ' ',
             },
         ],
         frontmatter: {
             aliases: ['YAML Alias 1', 'YAML Alias 2'],
         },
-        frontmatterLinks: [],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -127,6 +126,9 @@ export const yaml_2_aliases = {
                 offset: 50,
             },
         },
+        frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/yaml_complex_example.ts b/tests/Obsidian/__test_data__/yaml_complex_example.ts
index 66cfba8a..4b9964e0 100644
--- a/tests/Obsidian/__test_data__/yaml_complex_example.ts
+++ b/tests/Obsidian/__test_data__/yaml_complex_example.ts
@@ -187,4 +187,6 @@ export const yaml_complex_example = {
         frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#value1', '#value2', '#task'],
+    parseFrontMatterTags: ['#value1', '#value2'],
 };
diff --git a/tests/Obsidian/__test_data__/yaml_complex_example_standardised.ts b/tests/Obsidian/__test_data__/yaml_complex_example_standardised.ts
index 7d282818..f8d35dd8 100644
--- a/tests/Obsidian/__test_data__/yaml_complex_example_standardised.ts
+++ b/tests/Obsidian/__test_data__/yaml_complex_example_standardised.ts
@@ -185,4 +185,6 @@ export const yaml_complex_example_standardised = {
         frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#value1', '#value2', '#task'],
+    parseFrontMatterTags: ['#value1', '#value2'],
 };
diff --git a/tests/Obsidian/__test_data__/yaml_custom_number_property.ts b/tests/Obsidian/__test_data__/yaml_custom_number_property.ts
index 4dc71307..3f1d7f1e 100644
--- a/tests/Obsidian/__test_data__/yaml_custom_number_property.ts
+++ b/tests/Obsidian/__test_data__/yaml_custom_number_property.ts
@@ -88,4 +88,6 @@ export const yaml_custom_number_property = {
         frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/yaml_tags_field_added_by_obsidian_but_not_populated.ts b/tests/Obsidian/__test_data__/yaml_tags_field_added_by_obsidian_but_not_populated.ts
index ea1d0d64..56072465 100644
--- a/tests/Obsidian/__test_data__/yaml_tags_field_added_by_obsidian_but_not_populated.ts
+++ b/tests/Obsidian/__test_data__/yaml_tags_field_added_by_obsidian_but_not_populated.ts
@@ -11,7 +11,6 @@ export const yaml_tags_field_added_by_obsidian_but_not_populated = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 6,
@@ -24,12 +23,11 @@ export const yaml_tags_field_added_by_obsidian_but_not_populated = {
                         offset: 81,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'yaml_tags_field_added_by_obsidian_but_not_populated',
-                level: 1,
                 position: {
                     start: {
                         line: 4,
@@ -42,6 +40,8 @@ export const yaml_tags_field_added_by_obsidian_but_not_populated = {
                         offset: 68,
                     },
                 },
+                heading: 'yaml_tags_field_added_by_obsidian_but_not_populated',
+                level: 1,
             },
         ],
         sections: [
@@ -93,8 +93,6 @@ export const yaml_tags_field_added_by_obsidian_but_not_populated = {
         ],
         listItems: [
             {
-                parent: -6,
-                task: ' ',
                 position: {
                     start: {
                         line: 6,
@@ -107,12 +105,13 @@ export const yaml_tags_field_added_by_obsidian_but_not_populated = {
                         offset: 143,
                     },
                 },
+                parent: -6,
+                task: ' ',
             },
         ],
         frontmatter: {
             tags: null,
         },
-        frontmatterLinks: [],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -125,6 +124,9 @@ export const yaml_tags_field_added_by_obsidian_but_not_populated = {
                 offset: 13,
             },
         },
+        frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/yaml_tags_had_value_then_was_emptied_by_obsidian.ts b/tests/Obsidian/__test_data__/yaml_tags_had_value_then_was_emptied_by_obsidian.ts
index dab63149..4a59557b 100644
--- a/tests/Obsidian/__test_data__/yaml_tags_had_value_then_was_emptied_by_obsidian.ts
+++ b/tests/Obsidian/__test_data__/yaml_tags_had_value_then_was_emptied_by_obsidian.ts
@@ -12,7 +12,6 @@ export const yaml_tags_had_value_then_was_emptied_by_obsidian = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 7,
@@ -25,12 +24,11 @@ export const yaml_tags_had_value_then_was_emptied_by_obsidian = {
                         offset: 82,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'yaml_tags_had_value_then_was_emptied_by_obsidian',
-                level: 1,
                 position: {
                     start: {
                         line: 5,
@@ -43,6 +41,8 @@ export const yaml_tags_had_value_then_was_emptied_by_obsidian = {
                         offset: 69,
                     },
                 },
+                heading: 'yaml_tags_had_value_then_was_emptied_by_obsidian',
+                level: 1,
             },
         ],
         sections: [
@@ -94,8 +94,6 @@ export const yaml_tags_had_value_then_was_emptied_by_obsidian = {
         ],
         listItems: [
             {
-                parent: -7,
-                task: ' ',
                 position: {
                     start: {
                         line: 7,
@@ -108,12 +106,13 @@ export const yaml_tags_had_value_then_was_emptied_by_obsidian = {
                         offset: 141,
                     },
                 },
+                parent: -7,
+                task: ' ',
             },
         ],
         frontmatter: {
             tags: [],
         },
-        frontmatterLinks: [],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -126,6 +125,9 @@ export const yaml_tags_had_value_then_was_emptied_by_obsidian = {
                 offset: 16,
             },
         },
+        frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/yaml_tags_has_multiple_values.ts b/tests/Obsidian/__test_data__/yaml_tags_has_multiple_values.ts
index 7bfe4b71..bd4fc1af 100644
--- a/tests/Obsidian/__test_data__/yaml_tags_has_multiple_values.ts
+++ b/tests/Obsidian/__test_data__/yaml_tags_has_multiple_values.ts
@@ -13,7 +13,6 @@ export const yaml_tags_has_multiple_values = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 8,
@@ -26,12 +25,11 @@ export const yaml_tags_has_multiple_values = {
                         offset: 87,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'yaml_tags_has_multiple_values',
-                level: 1,
                 position: {
                     start: {
                         line: 6,
@@ -44,6 +42,8 @@ export const yaml_tags_has_multiple_values = {
                         offset: 74,
                     },
                 },
+                heading: 'yaml_tags_has_multiple_values',
+                level: 1,
             },
         ],
         sections: [
@@ -95,8 +95,6 @@ export const yaml_tags_has_multiple_values = {
         ],
         listItems: [
             {
-                parent: -8,
-                task: ' ',
                 position: {
                     start: {
                         line: 8,
@@ -109,12 +107,13 @@ export const yaml_tags_has_multiple_values = {
                         offset: 127,
                     },
                 },
+                parent: -8,
+                task: ' ',
             },
         ],
         frontmatter: {
             tags: ['multiple1', 'multiple2'],
         },
-        frontmatterLinks: [],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -127,6 +126,9 @@ export const yaml_tags_has_multiple_values = {
                 offset: 41,
             },
         },
+        frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#multiple1', '#multiple2', '#task'],
+    parseFrontMatterTags: ['#multiple1', '#multiple2'],
 };
diff --git a/tests/Obsidian/__test_data__/yaml_tags_is_empty.ts b/tests/Obsidian/__test_data__/yaml_tags_is_empty.ts
index cbeddec2..33ddc7a3 100644
--- a/tests/Obsidian/__test_data__/yaml_tags_is_empty.ts
+++ b/tests/Obsidian/__test_data__/yaml_tags_is_empty.ts
@@ -11,7 +11,6 @@ export const yaml_tags_is_empty = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 6,
@@ -24,12 +23,11 @@ export const yaml_tags_is_empty = {
                         offset: 48,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'yaml_tags_is_empty',
-                level: 1,
                 position: {
                     start: {
                         line: 4,
@@ -42,6 +40,8 @@ export const yaml_tags_is_empty = {
                         offset: 35,
                     },
                 },
+                heading: 'yaml_tags_is_empty',
+                level: 1,
             },
         ],
         sections: [
@@ -93,8 +93,6 @@ export const yaml_tags_is_empty = {
         ],
         listItems: [
             {
-                parent: -6,
-                task: ' ',
                 position: {
                     start: {
                         line: 6,
@@ -107,12 +105,13 @@ export const yaml_tags_is_empty = {
                         offset: 77,
                     },
                 },
+                parent: -6,
+                task: ' ',
             },
         ],
         frontmatter: {
             tags: null,
         },
-        frontmatterLinks: [],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -125,6 +124,9 @@ export const yaml_tags_is_empty = {
                 offset: 13,
             },
         },
+        frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/yaml_tags_is_empty_list.ts b/tests/Obsidian/__test_data__/yaml_tags_is_empty_list.ts
index 635962d9..382f1047 100644
--- a/tests/Obsidian/__test_data__/yaml_tags_is_empty_list.ts
+++ b/tests/Obsidian/__test_data__/yaml_tags_is_empty_list.ts
@@ -11,7 +11,6 @@ export const yaml_tags_is_empty_list = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 6,
@@ -24,12 +23,11 @@ export const yaml_tags_is_empty_list = {
                         offset: 56,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'yaml_tags_is_empty_list',
-                level: 1,
                 position: {
                     start: {
                         line: 4,
@@ -42,6 +40,8 @@ export const yaml_tags_is_empty_list = {
                         offset: 43,
                     },
                 },
+                heading: 'yaml_tags_is_empty_list',
+                level: 1,
             },
         ],
         sections: [
@@ -93,8 +93,6 @@ export const yaml_tags_is_empty_list = {
         ],
         listItems: [
             {
-                parent: -6,
-                task: ' ',
                 position: {
                     start: {
                         line: 6,
@@ -107,12 +105,13 @@ export const yaml_tags_is_empty_list = {
                         offset: 90,
                     },
                 },
+                parent: -6,
+                task: ' ',
             },
         ],
         frontmatter: {
             tags: [],
         },
-        frontmatterLinks: [],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -125,6 +124,9 @@ export const yaml_tags_is_empty_list = {
                 offset: 16,
             },
         },
+        frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#task'],
+    parseFrontMatterTags: null,
 };
diff --git a/tests/Obsidian/__test_data__/yaml_tags_with_one_value_on_new_line.ts b/tests/Obsidian/__test_data__/yaml_tags_with_one_value_on_new_line.ts
index 93d47f02..74c2229e 100644
--- a/tests/Obsidian/__test_data__/yaml_tags_with_one_value_on_new_line.ts
+++ b/tests/Obsidian/__test_data__/yaml_tags_with_one_value_on_new_line.ts
@@ -13,7 +13,6 @@ export const yaml_tags_with_one_value_on_new_line = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 8,
@@ -26,12 +25,11 @@ export const yaml_tags_with_one_value_on_new_line = {
                         offset: 93,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'yaml_tags_with_one_value_on_new_line',
-                level: 1,
                 position: {
                     start: {
                         line: 6,
@@ -44,6 +42,8 @@ export const yaml_tags_with_one_value_on_new_line = {
                         offset: 80,
                     },
                 },
+                heading: 'yaml_tags_with_one_value_on_new_line',
+                level: 1,
             },
         ],
         sections: [
@@ -95,8 +95,6 @@ export const yaml_tags_with_one_value_on_new_line = {
         ],
         listItems: [
             {
-                parent: -8,
-                task: ' ',
                 position: {
                     start: {
                         line: 8,
@@ -109,12 +107,13 @@ export const yaml_tags_with_one_value_on_new_line = {
                         offset: 140,
                     },
                 },
+                parent: -8,
+                task: ' ',
             },
         ],
         frontmatter: {
             tags: ['single-value-new-line'],
         },
-        frontmatterLinks: [],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -127,6 +126,9 @@ export const yaml_tags_with_one_value_on_new_line = {
                 offset: 39,
             },
         },
+        frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#single-value-new-line', '#task'],
+    parseFrontMatterTags: ['#single-value-new-line'],
 };
diff --git a/tests/Obsidian/__test_data__/yaml_tags_with_one_value_on_single_line.ts b/tests/Obsidian/__test_data__/yaml_tags_with_one_value_on_single_line.ts
index 180c9a13..4e89e8c0 100644
--- a/tests/Obsidian/__test_data__/yaml_tags_with_one_value_on_single_line.ts
+++ b/tests/Obsidian/__test_data__/yaml_tags_with_one_value_on_single_line.ts
@@ -11,7 +11,6 @@ export const yaml_tags_with_one_value_on_single_line = {
     cachedMetadata: {
         tags: [
             {
-                tag: '#task',
                 position: {
                     start: {
                         line: 6,
@@ -24,12 +23,11 @@ export const yaml_tags_with_one_value_on_single_line = {
                         offset: 94,
                     },
                 },
+                tag: '#task',
             },
         ],
         headings: [
             {
-                heading: 'yaml_tags_with_one_value_on_single_line',
-                level: 1,
                 position: {
                     start: {
                         line: 4,
@@ -42,6 +40,8 @@ export const yaml_tags_with_one_value_on_single_line = {
                         offset: 81,
                     },
                 },
+                heading: 'yaml_tags_with_one_value_on_single_line',
+                level: 1,
             },
         ],
         sections: [
@@ -93,8 +93,6 @@ export const yaml_tags_with_one_value_on_single_line = {
         ],
         listItems: [
             {
-                parent: -6,
-                task: ' ',
                 position: {
                     start: {
                         line: 6,
@@ -107,12 +105,13 @@ export const yaml_tags_with_one_value_on_single_line = {
                         offset: 144,
                     },
                 },
+                parent: -6,
+                task: ' ',
             },
         ],
         frontmatter: {
             tags: 'single-value-single-line',
         },
-        frontmatterLinks: [],
         frontmatterPosition: {
             start: {
                 line: 0,
@@ -125,6 +124,9 @@ export const yaml_tags_with_one_value_on_single_line = {
                 offset: 38,
             },
         },
+        frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#single-value-single-line', '#task'],
+    parseFrontMatterTags: ['#single-value-single-line'],
 };
diff --git a/tests/Obsidian/__test_data__/yaml_tags_with_two_values_on_one_line.ts b/tests/Obsidian/__test_data__/yaml_tags_with_two_values_on_one_line.ts
index 06cbd0ed..c3896eb9 100644
--- a/tests/Obsidian/__test_data__/yaml_tags_with_two_values_on_one_line.ts
+++ b/tests/Obsidian/__test_data__/yaml_tags_with_two_values_on_one_line.ts
@@ -127,4 +127,6 @@ export const yaml_tags_with_two_values_on_one_line = {
         frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#value-1-of-2-on-one-line', '#value-2-of-2-on-one-line', '#task'],
+    parseFrontMatterTags: ['#value-1-of-2-on-one-line', '#value-2-of-2-on-one-line'],
 };
diff --git a/tests/Obsidian/__test_data__/yaml_tags_with_two_values_on_two_lines.ts b/tests/Obsidian/__test_data__/yaml_tags_with_two_values_on_two_lines.ts
index 5fb326b5..8b78df91 100644
--- a/tests/Obsidian/__test_data__/yaml_tags_with_two_values_on_two_lines.ts
+++ b/tests/Obsidian/__test_data__/yaml_tags_with_two_values_on_two_lines.ts
@@ -129,4 +129,6 @@ export const yaml_tags_with_two_values_on_two_lines = {
         frontmatterLinks: [],
     },
     obsidianApiVersion: '1.6.5',
+    getAllTags: ['#value-1-of-2-on-two-lines', '#value-2-of-2-on-two-lines', '#task'],
+    parseFrontMatterTags: ['#value-1-of-2-on-two-lines', '#value-2-of-2-on-two-lines'],
 };
diff --git a/tests/Scripting/TasksFile.test.ts b/tests/Scripting/TasksFile.test.ts
index 9f551f74..4f2ede64 100644
--- a/tests/Scripting/TasksFile.test.ts
+++ b/tests/Scripting/TasksFile.test.ts
@@ -1,5 +1,7 @@
 import type { CachedMetadata } from 'obsidian';
 import { TasksFile } from '../../src/Scripting/TasksFile';
+import { setCurrentCacheFile } from '../__mocks__/obsidian';
+import { callouts_nested_issue_2890_unlabelled } from '../Obsidian/__test_data__/callouts_nested_issue_2890_unlabelled';
 import { no_yaml } from '../Obsidian/__test_data__/no_yaml';
 import { empty_yaml } from '../Obsidian/__test_data__/empty_yaml';
 import { yaml_tags_has_multiple_values } from '../Obsidian/__test_data__/yaml_tags_has_multiple_values';
@@ -53,6 +55,12 @@ describe('TasksFile', () => {
     });
 });
 
+function getTasksFileFromMockData(data: any) {
+    setCurrentCacheFile(data);
+    const cachedMetadata = data.cachedMetadata as any as CachedMetadata;
+    return new TasksFile(data.filePath, cachedMetadata);
+}
+
 describe('TasksFile - reading frontmatter', () => {
     it('should read file if not given CachedMetadata', () => {
         const tasksFile = new TasksFile('some path.md', {});
@@ -62,30 +70,33 @@ describe('TasksFile - reading frontmatter', () => {
     });
 
     it('should read file with no yaml metadata', () => {
-        const data = no_yaml;
-        const cachedMetadata = data.cachedMetadata as any as CachedMetadata;
-        const tasksFile = new TasksFile(data.filePath, cachedMetadata);
-
+        const tasksFile = getTasksFileFromMockData(no_yaml);
         expect(tasksFile.cachedMetadata.frontmatter).toBeUndefined();
         expect(tasksFile.frontmatter).toEqual({});
     });
 
     it('should read file with empty yaml metadata', () => {
-        const data = empty_yaml;
-        const cachedMetadata = data.cachedMetadata as any as CachedMetadata;
-        const tasksFile = new TasksFile(data.filePath, cachedMetadata);
-
+        const tasksFile = getTasksFileFromMockData(empty_yaml);
         expect(tasksFile.cachedMetadata.frontmatter).toBeUndefined();
         expect(tasksFile.frontmatter).toEqual({});
     });
 
-    it('should read file with multiple tags in yaml metadata', () => {
-        const data = yaml_tags_has_multiple_values;
-        const cachedMetadata = data.cachedMetadata as any as CachedMetadata;
-        const tasksFile = new TasksFile(data.filePath, cachedMetadata);
+    it('should provide an independent copy of frontmatter', () => {
+        const tasksFile = getTasksFileFromMockData(yaml_tags_has_multiple_values);
+
+        expect(tasksFile.frontmatter).not.toBe(tasksFile.cachedMetadata.frontmatter);
+
+        expect(tasksFile.cachedMetadata.frontmatter?.tags).toEqual(['multiple1', 'multiple2']);
+        expect(tasksFile.frontmatter.tags).toEqual(['#multiple1', '#multiple2']);
 
+        tasksFile.frontmatter.tags.push('newTag');
+        expect(tasksFile.cachedMetadata.frontmatter?.tags).toEqual(['multiple1', 'multiple2']);
+        expect(tasksFile.frontmatter.tags).toEqual(['#multiple1', '#multiple2', 'newTag']);
+    });
+
+    it('should read file with multiple tags in yaml metadata', () => {
+        const tasksFile = getTasksFileFromMockData(yaml_tags_has_multiple_values);
         expect(tasksFile.cachedMetadata.frontmatter?.tags).toEqual(['multiple1', 'multiple2']);
-        expect(tasksFile.frontmatter.tags).toEqual(['multiple1', 'multiple2']);
     });
 
     // See property types: https://help.obsidian.md/Editing+and+formatting/Properties#Property+types
@@ -97,22 +108,20 @@ describe('TasksFile - reading frontmatter', () => {
     //  Date
     //  Date & time
     it('should read file with custom number property', () => {
-        const data = yaml_custom_number_property;
-        const cachedMetadata = data.cachedMetadata as any as CachedMetadata;
-        const tasksFile = new TasksFile(data.filePath, cachedMetadata);
-
+        const tasksFile = getTasksFileFromMockData(yaml_custom_number_property);
         expect(tasksFile.frontmatter?.custom_number_prop).toEqual(42);
     });
 });
 
 describe('TasksFile - reading tags', () => {
-    it.failing('should read a tag from the frontmatter', () => {
-        // Fails with 'TypeError: (0 , obsidian_1.getAllTags) is not a function'
-        // It looks like Obsidian's getAllTags() cannot be called outside of a vault.
-        const data = yaml_tags_with_one_value_on_new_line;
-        const cachedMetadata = data.cachedMetadata as any as CachedMetadata;
-        const tasksFile = new TasksFile(data.filePath, cachedMetadata);
-
-        expect(tasksFile.tags).toEqual(['#single-value-new-line']);
+    it('should read a tag from body and the frontmatter', () => {
+        const tasksFile = getTasksFileFromMockData(yaml_tags_with_one_value_on_new_line);
+        expect(tasksFile.tags).toEqual(['#single-value-new-line', '#task']);
+        expect(tasksFile.frontmatter.tags).toEqual(['#single-value-new-line']);
+    });
+
+    it('should read tags from body of file without duplication', () => {
+        const tasksFile = getTasksFileFromMockData(callouts_nested_issue_2890_unlabelled);
+        expect(tasksFile.tags).toEqual(['#task']);
     });
 });
diff --git a/tests/__mocks__/obsidian.ts b/tests/__mocks__/obsidian.ts
index e4066687..20d56642 100644
--- a/tests/__mocks__/obsidian.ts
+++ b/tests/__mocks__/obsidian.ts
@@ -1,3 +1,5 @@
+import type { CachedMetadata } from 'obsidian';
+
 export {};
 
 export class MenuItem {
@@ -122,6 +124,20 @@ function caseInsensitiveSubstringSearch(searchTerm: string, phrase: string): Sea
         : null;
 }
 
+let mockedFileData: any = {};
+
+export function setCurrentCacheFile(mockData: any) {
+    mockedFileData = mockData;
+}
+
+export function getAllTags(_cachedMetadata: CachedMetadata): string[] {
+    return mockedFileData.getAllTags;
+}
+
+export function parseFrontMatterTags(_frontmatter: any | null): string[] | null {
+    return mockedFileData.parseFrontMatterTags;
+}
+
 /**
  * A fake implementation of prepareSimpleSearch(),
  * so we can write tests of code that calls that function.
diff --git a/tests/ui/EditableTask.test.ts b/tests/ui/EditableTask.test.ts
index d6948405..cddc6182 100644
--- a/tests/ui/EditableTask.test.ts
+++ b/tests/ui/EditableTask.test.ts
@@ -195,6 +195,7 @@ describe('EditableTask tests', () => {
                 "_sectionStart": 5,
                 "_tasksFile": TasksFile {
                   "_cachedMetadata": {},
+                  "_frontmatter": {},
                   "_path": "some/folder/fileName.md",
                 },
               },