Repository: obsidian-tasks-group/obsidian-tasks
Pull request #868 (2022-07-07 10:05:28)

fix: Boolean searches with spaces around sub-queries now work
<!--- Provide a general summary of your changes in the Title above -->

## Description
Fixes https://github.com/obsidian-tasks-group/obsidian-tasks/issues/866.

## Motivation and Context
Fixes an issue with spaces inside the sub-queries in a boolean field.

## How has this been tested?
A test was added and the existing tests were run.

## Screenshots (if appropriate):

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] Refactor (non-breaking change which only improves the design or structure of existing code, and making no changes to its external behaviour)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)

## 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 accordingly.
- [x] My change has adequate Unit Test coverage.

By creating a Pull Request you agree to our [Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md). For further guidance on contributing please see [contributing guide](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CONTRIBUTING.md)



Patch:
diff --git a/src/Query/Filter/BooleanField.ts b/src/Query/Filter/BooleanField.ts
index f1ba6431..8475c26e 100644
--- a/src/Query/Filter/BooleanField.ts
+++ b/src/Query/Filter/BooleanField.ts
@@ -59,17 +59,18 @@ export class BooleanField extends Field {
             // final token in the expression
             for (const token of postfixExpression) {
                 if (token.name === 'IDENTIFIER' && token.value) {
-                    if (!(token.value in this.subFields)) {
-                        const parsedField = parseFilter(token.value);
+                    const identifier = token.value.trim();
+                    if (!(identifier in this.subFields)) {
+                        const parsedField = parseFilter(identifier);
                         if (parsedField === null) {
-                            result.error = `couldn't parse sub-expression '${token.value}'`;
+                            result.error = `couldn't parse sub-expression '${identifier}'`;
                             return result;
                         }
                         if (parsedField.error) {
-                            result.error = `couldn't parse sub-expression '${token.value}': ${parsedField.error}`;
+                            result.error = `couldn't parse sub-expression '${identifier}': ${parsedField.error}`;
                             return result;
                         } else if (parsedField.filter) {
-                            this.subFields[token.value] = parsedField.filter;
+                            this.subFields[identifier] = parsedField.filter;
                         }
                     }
                 } else if (token.name === 'OPERATOR') {
@@ -132,7 +133,7 @@ export class BooleanField extends Field {
                 // For each identifier we created earlier the corresponding Filter, so now we can just evaluate the given
                 // task for each identifier that we find in the postfix expression.
                 if (token.value == null) throw Error('null token value'); // This should not happen
-                const filter = this.subFields[token.value];
+                const filter = this.subFields[token.value.trim()];
                 const result = filter(task);
                 booleanStack.push(toString(result));
             } else if (token.name === 'OPERATOR') {


Test patch:
diff --git a/tests/Query/Filter/BooleanField.test.ts b/tests/Query/Filter/BooleanField.test.ts
index f68ff068..7205e448 100644
--- a/tests/Query/Filter/BooleanField.test.ts
+++ b/tests/Query/Filter/BooleanField.test.ts
@@ -96,6 +96,18 @@ describe('boolean query', () => {
             testWithDescription(filter, 'd2', false);
             testWithDescription(filter, 'd1 d2', true);
         });
+
+        it('input components dirty with whitespaces', () => {
+            const filter = new BooleanField().createFilterOrErrorMessage(
+                ' (description includes #context/location1) OR (description includes #context/location2 ) OR (  description includes #context/location3 ) OR   (  description includes #context/location4 )',
+            );
+
+            testWithDescription(filter, 'none', false);
+            testWithDescription(filter, 'xxx #context/location1', true);
+            testWithDescription(filter, 'xxx #context/location2', true);
+            testWithDescription(filter, 'xxx #context/location3', true);
+            testWithDescription(filter, 'xxx #context/location4', true);
+        });
     });
 
     describe('error cases - to show error messages', () => {