Skip to content

Commit b03a079

Browse files
committed
fix: TaskGroupingTree no longer loses any tasks with no group names.
This never affected released code as all the released groupers ensure that every task has at least one group name. However, with the development of custom groupers, I discovered it was possible to have query results displayed that said they had 100 tasks, but only display some of them, as the ones with no group names were just not displayed.
1 parent a55b21f commit b03a079

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

src/Query/TaskGroupingTree.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ export class TaskGroupingTree {
6767
// Get properties of a task for the grouper
6868
// The returned string is rendered, so special Markdown characters will be escaped
6969
const groupNames = grouper.grouper(task);
70+
71+
if (groupNames.length === 0) {
72+
// Create a fake empty group-name so that we can add these tasks
73+
// to the tree. This group will be displayed with no heading.
74+
// Without this, they would be lost and not displayed at all the query results.
75+
groupNames.push('');
76+
}
77+
7078
for (const groupName of groupNames) {
7179
let child = currentTreeNode.children.get(groupName);
7280
if (child === undefined) {

src/Query/TaskGroups.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,20 @@ export class TaskGroups {
153153
group.applyTaskLimit(limit);
154154
});
155155

156-
this.calculateTotalTaskCount();
156+
this.recalculateTotalTaskCount();
157157
}
158158

159-
private calculateTotalTaskCount() {
159+
/**
160+
* Update the stored task count to represent the number of unique tasks
161+
* across all the groups.
162+
*
163+
* In normal operation this is only useful after a limit to group size
164+
* has been applied.
165+
*
166+
* However, it is also useful for test code to be able to ensure consistency
167+
* of task count after the object has been initially constructed.
168+
*/
169+
public recalculateTotalTaskCount() {
160170
let concatenatedTasks: Task[] = [];
161171

162172
this._groups.forEach((group) => {

tests/TaskGroups.test.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44
import moment from 'moment';
55
import { FilenameField } from '../src/Query/Filter/FilenameField';
6-
import type { Grouper } from '../src/Query/Grouper';
6+
import { Grouper, type GrouperFunction } from '../src/Query/Grouper';
77
import type { Task } from '../src/Task';
88
import { PathField } from '../src/Query/Filter/PathField';
99
import { TagsField } from '../src/Query/Filter/TagsField';
@@ -242,6 +242,46 @@ describe('Grouping tasks', () => {
242242
`);
243243
});
244244

245+
it('should retain tasks with no group name', () => {
246+
const a = fromLine({
247+
line: '- [ ] Task with a tag #group1',
248+
});
249+
const b = fromLine({
250+
line: '- [ ] Task without a tag',
251+
});
252+
const inputs = [a, b];
253+
254+
const groupByTags: GrouperFunction = (task: Task) => task.tags;
255+
const grouper = new Grouper('custom tag grouper', groupByTags, false);
256+
const groups = new TaskGroups([grouper], inputs);
257+
258+
expect(groups.totalTasksCount()).toEqual(2);
259+
260+
// Force a recalculation of the task count, to ensure no
261+
// tasks were lost in the grouping:
262+
groups.recalculateTotalTaskCount();
263+
expect(groups.totalTasksCount()).toEqual(2);
264+
265+
expect(groups.toString()).toMatchInlineSnapshot(`
266+
"Groupers (if any):
267+
- custom tag grouper
268+
269+
Group names: []
270+
- [ ] Task without a tag
271+
272+
---
273+
274+
Group names: [#group1]
275+
#### [custom tag grouper] #group1
276+
- [ ] Task with a tag #group1
277+
278+
---
279+
280+
2 tasks
281+
"
282+
`);
283+
});
284+
245285
it('should create nested headings if multiple groups used even if one is reversed', () => {
246286
// Arrange
247287
const t1 = fromLine({

0 commit comments

Comments
 (0)