Repository: obsidian-tasks-group/obsidian-tasks
Pull request #2286 (2023-09-24 12:10:30)

refactor: Convert one use of GlobalFilter.getInstance() to instance
<!--- Provide a general summary of your changes in the Title above -->

# Description

<!--- Describe your changes in detail -->

- `explainResults()` now takes a `GlobalFilter` value.
- Tests updated accordingly

I looked at all other uses of `GlobalFilter.getInstance()` to see if they could be converted to take in instance, and none were appropriate.

Fixes  #2281

## Motivation and Context

<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->

This is the last step of  #2281

-  #2281

## How has this been tested?

- Ran existing tests
- Ran the smoke tests in a local build

## Screenshots (if appropriate)

## Types of changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

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)

## Checklist

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [x] My code follows the code style of this project and passes `yarn run lint`.
- [ ] My change requires a change to the documentation.
- [ ] I have [updated the documentation](https://publish.obsidian.md/tasks-contributing/Documentation/About+Documentation) accordingly.
- [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 follow 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/QueryRenderer.ts b/src/QueryRenderer.ts
index c5c905ed..1cca3e27 100644
--- a/src/QueryRenderer.ts
+++ b/src/QueryRenderer.ts
@@ -1,5 +1,6 @@
 import { App, Keymap, MarkdownRenderChild, MarkdownRenderer, Plugin, TFile } from 'obsidian';
 import type { EventRef, MarkdownPostProcessorContext } from 'obsidian';
+import { GlobalFilter } from './Config/GlobalFilter';
 import { GlobalQuery } from './Config/GlobalQuery';
 
 import type { IQuery } from './IQuery';
@@ -199,7 +200,12 @@ class QueryRenderChild extends MarkdownRenderChild {
 
     // Use the 'explain' instruction to enable this
     private createExplanation(content: HTMLDivElement) {
-        const explanationAsString = explainResults(this.source, GlobalQuery.getInstance(), this.filePath);
+        const explanationAsString = explainResults(
+            this.source,
+            GlobalFilter.getInstance(),
+            GlobalQuery.getInstance(),
+            this.filePath,
+        );
 
         const explanationsBlock = content.createEl('pre');
         explanationsBlock.addClasses(['plugin-tasks-query-explanation']);
diff --git a/src/lib/QueryRendererHelper.ts b/src/lib/QueryRendererHelper.ts
index 5ccc6546..3d0e1c81 100644
--- a/src/lib/QueryRendererHelper.ts
+++ b/src/lib/QueryRendererHelper.ts
@@ -1,4 +1,4 @@
-import { GlobalFilter } from '../Config/GlobalFilter';
+import type { GlobalFilter } from '../Config/GlobalFilter';
 import type { GlobalQuery } from '../Config/GlobalQuery';
 import { Query } from '../Query/Query';
 
@@ -19,15 +19,21 @@ import { Query } from '../Query/Query';
  *     * Explains the query described by {@link source}
  *
  * @param {string} source The source of the task block to explain
- * @param globalQuery
+ * @param {GlobalFilter} globalFilter The global filter. In `src/`, generally pass in {@link GlobalFilter.getInstance}
+ * @param {GlobalQuery} globalQuery The global query. In `src/`, generally pass in {@link GlobalQuery.getInstance}
  * @param {string} path The location of the task block, if known
  * @returns {string}
  */
-export function explainResults(source: string, globalQuery: GlobalQuery, path: string | undefined = undefined): string {
+export function explainResults(
+    source: string,
+    globalFilter: GlobalFilter,
+    globalQuery: GlobalQuery,
+    path: string | undefined = undefined,
+): string {
     let result = '';
 
-    if (!GlobalFilter.getInstance().isEmpty()) {
-        result += `Only tasks containing the global filter '${GlobalFilter.getInstance().get()}'.\n\n`;
+    if (!globalFilter.isEmpty()) {
+        result += `Only tasks containing the global filter '${globalFilter.get()}'.\n\n`;
     }
 
     const tasksBlockQuery = new Query({ source }, path);


Test patch:
diff --git a/tests/Query/Explain/DocsSamplesForExplain.test.ts b/tests/Query/Explain/DocsSamplesForExplain.test.ts
index 2eabda5b..c27a72f2 100644
--- a/tests/Query/Explain/DocsSamplesForExplain.test.ts
+++ b/tests/Query/Explain/DocsSamplesForExplain.test.ts
@@ -2,6 +2,7 @@
  * @jest-environment jsdom
  */
 import moment from 'moment';
+import { GlobalFilter } from '../../../src/Config/GlobalFilter';
 import { GlobalQuery } from '../../../src/Config/GlobalQuery';
 import { verifyQuery, verifyTaskBlockExplanation } from '../../TestingTools/ApprovalTestHelpers';
 import { resetSettings } from '../../../src/Config/Settings';
@@ -34,7 +35,7 @@ explain`;
 
         // Act, Assert
         checkExplainPresentAndVerify(instructions);
-        verifyTaskBlockExplanation(instructions, new GlobalQuery());
+        verifyTaskBlockExplanation(instructions, new GlobalFilter(), new GlobalQuery());
     });
 
     it('boolean combinations', () => {
@@ -46,7 +47,7 @@ not done
 
         // Act, Assert
         checkExplainPresentAndVerify(instructions);
-        verifyTaskBlockExplanation(instructions, new GlobalQuery());
+        verifyTaskBlockExplanation(instructions, new GlobalFilter(), new GlobalQuery());
     });
 
     it('nested boolean combinations', () => {
@@ -57,7 +58,7 @@ explain
 
         // Act, Assert
         checkExplainPresentAndVerify(instructions);
-        verifyTaskBlockExplanation(instructions, new GlobalQuery());
+        verifyTaskBlockExplanation(instructions, new GlobalFilter(), new GlobalQuery());
     });
 
     it('regular expression', () => {
@@ -68,7 +69,7 @@ path regex matches /^Root/Sub-Folder/Sample File\\.md/i`;
 
         // Act, Assert
         checkExplainPresentAndVerify(instructions);
-        verifyTaskBlockExplanation(instructions, new GlobalQuery());
+        verifyTaskBlockExplanation(instructions, new GlobalFilter(), new GlobalQuery());
     });
 
     const globalQueryLine = `limit 50
@@ -88,7 +89,7 @@ explain`;
 
         // Act, Assert
         checkExplainPresentAndVerify(blockQuery);
-        verifyTaskBlockExplanation(blockQuery, globalQuery);
+        verifyTaskBlockExplanation(blockQuery, new GlobalFilter(), globalQuery);
     });
 
     it('placeholders', () => {
@@ -102,7 +103,7 @@ filename includes {{query.file.filename}}`;
 
         // Act, Assert
         checkExplainPresentAndVerify(instructions);
-        verifyTaskBlockExplanation(instructions, new GlobalQuery());
+        verifyTaskBlockExplanation(instructions, new GlobalFilter(), new GlobalQuery());
     });
 
     it('placeholders error', () => {
@@ -114,6 +115,6 @@ filename includes {{query.file.fileName}}`;
 
         // Act, Assert
         verifyQuery(instructions); // This does not have an explain, so does not call checkExplainPresentAndVerify()
-        verifyTaskBlockExplanation(instructions, new GlobalQuery());
+        verifyTaskBlockExplanation(instructions, new GlobalFilter(), new GlobalQuery());
     });
 });
diff --git a/tests/TestingTools/ApprovalTestHelpers.ts b/tests/TestingTools/ApprovalTestHelpers.ts
index 3a294acf..ec7a94d9 100644
--- a/tests/TestingTools/ApprovalTestHelpers.ts
+++ b/tests/TestingTools/ApprovalTestHelpers.ts
@@ -1,5 +1,6 @@
 import { Options } from 'approvals/lib/Core/Options';
 import { verify } from 'approvals/lib/Providers/Jest/JestApprovals';
+import type { GlobalFilter } from '../../src/Config/GlobalFilter';
 import type { GlobalQuery } from '../../src/Config/GlobalQuery';
 import { Query } from '../../src/Query/Query';
 import { explainResults } from '../../src/lib/QueryRendererHelper';
@@ -71,11 +72,17 @@ export function verifyQueryExplanation(instructions: string, options?: Options):
  * See {@link verifyQueryExplanation} to just explain the query.
  *
  * @param instructions
+ * @param globalFilter
  * @param globalQuery
- * @param options
+ * @param options?
  */
-export function verifyTaskBlockExplanation(instructions: string, globalQuery: GlobalQuery, options?: Options): void {
-    const explanation = explainResults(instructions, globalQuery, 'some/sample/file path.md');
+export function verifyTaskBlockExplanation(
+    instructions: string,
+    globalFilter: GlobalFilter,
+    globalQuery: GlobalQuery,
+    options?: Options,
+): void {
+    const explanation = explainResults(instructions, globalFilter, globalQuery, 'some/sample/file path.md');
 
     options = options || new Options();
     options = options.forFile().withFileExtention('explanation.text');
diff --git a/tests/lib/QueryRendererHelper.test.ts b/tests/lib/QueryRendererHelper.test.ts
index b62c59e1..59ae6b51 100644
--- a/tests/lib/QueryRendererHelper.test.ts
+++ b/tests/lib/QueryRendererHelper.test.ts
@@ -10,10 +10,6 @@ import { GlobalQuery } from '../../src/Config/GlobalQuery';
 window.moment = moment;
 
 describe('explain', () => {
-    afterEach(() => {
-        GlobalFilter.getInstance().reset();
-    });
-
     it('should explain a task', () => {
         const source = '';
         const query = new Query({ source });
@@ -22,11 +18,12 @@ describe('explain', () => {
 
 No filters supplied. All tasks will match the query.`;
 
-        expect(explainResults(query.source, new GlobalQuery())).toEqual(expectedDisplayText);
+        expect(explainResults(query.source, new GlobalFilter(), new GlobalQuery())).toEqual(expectedDisplayText);
     });
 
     it('should explain a task with global filter active', () => {
-        GlobalFilter.getInstance().set('#task');
+        const globalFilter = new GlobalFilter();
+        globalFilter.set('#task');
 
         const source = '';
         const query = new Query({ source });
@@ -36,7 +33,7 @@ No filters supplied. All tasks will match the query.`;
 Explanation of this Tasks code block query:
 
 No filters supplied. All tasks will match the query.`;
-        expect(explainResults(query.source, new GlobalQuery())).toEqual(expectedDisplayText);
+        expect(explainResults(query.source, globalFilter, new GlobalQuery())).toEqual(expectedDisplayText);
     });
 
     it('should explain a task with global query active', () => {
@@ -53,12 +50,13 @@ Explanation of this Tasks code block query:
 
 No filters supplied. All tasks will match the query.`;
 
-        expect(explainResults(query.source, globalQuery)).toEqual(expectedDisplayText);
+        expect(explainResults(query.source, new GlobalFilter(), globalQuery)).toEqual(expectedDisplayText);
     });
 
     it('should explain a task with global query and global filter active', () => {
         const globalQuery = new GlobalQuery('description includes hello');
-        GlobalFilter.getInstance().set('#task');
+        const globalFilter = new GlobalFilter();
+        globalFilter.set('#task');
 
         const source = '';
         const query = new Query({ source });
@@ -73,7 +71,7 @@ Explanation of this Tasks code block query:
 
 No filters supplied. All tasks will match the query.`;
 
-        expect(explainResults(query.source, globalQuery)).toEqual(expectedDisplayText);
+        expect(explainResults(query.source, globalFilter, globalQuery)).toEqual(expectedDisplayText);
     });
 
     it('should explain a task with global query set but ignored without the global query', () => {
@@ -86,7 +84,7 @@ No filters supplied. All tasks will match the query.`;
 
 No filters supplied. All tasks will match the query.`;
 
-        expect(explainResults(query.source, globalQuery)).toEqual(expectedDisplayText);
+        expect(explainResults(query.source, new GlobalFilter(), globalQuery)).toEqual(expectedDisplayText);
     });
 });