Skip to content

Commit cab21d6

Browse files
committed
feat: implement reverse sorting of groups
1 parent 8f23367 commit cab21d6

File tree

5 files changed

+59
-7
lines changed

5 files changed

+59
-7
lines changed

src/Query/Filter/Field.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,8 @@ export abstract class Field {
342342
return null;
343343
}
344344

345-
//const reverse = !!match[1];
346-
return this.createGrouper();
345+
const reverse = !!match[1];
346+
return this.createGrouper(reverse);
347347
}
348348

349349
/**
@@ -362,6 +362,6 @@ export abstract class Field {
362362
throw Error(`grouperRegExp() unimplemented for ${this.fieldNameSingular()}`);
363363
}
364364

365-
return new RegExp(`^group by ${this.fieldNameSingularEscaped()}$`);
365+
return new RegExp(`^group by ${this.fieldNameSingularEscaped()}( reverse)?$`);
366366
}
367367
}

src/Query/Filter/MultiTextField.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,15 @@ export abstract class MultiTextField extends TextField {
6363
/**
6464
* This overloads {@link Field.createGrouper} to put a plural field name in the {@link Grouper.property}.
6565
*/
66-
public createGrouper(): Grouper {
67-
return new Grouper(this.fieldNamePlural(), this.grouper());
66+
public createGrouper(reverse: boolean = false): Grouper {
67+
return new Grouper(this.fieldNamePlural(), this.grouper(), reverse);
6868
}
6969

7070
protected grouperRegExp(): RegExp {
7171
if (!this.supportsGrouping()) {
7272
throw Error(`grouperRegExp() unimplemented for ${this.fieldNameSingular()}`);
7373
}
7474

75-
return new RegExp(`^group by ${this.fieldNamePlural()}$`);
75+
return new RegExp(`^group by ${this.fieldNamePlural()}( reverse)?$`);
7676
}
7777
}

tests/Query.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,25 +201,45 @@ describe('Query parsing', () => {
201201
// In alphabetical order, please
202202
const filters = [
203203
'group by created',
204+
'group by created reverse',
204205
'group by backlink',
206+
'group by backlink reverse',
205207
'group by done',
208+
'group by done reverse',
206209
'group by due',
210+
'group by due reverse',
207211
'group by filename',
212+
'group by filename reverse',
208213
'group by folder',
214+
'group by folder reverse',
209215
'group by happens',
216+
'group by happens reverse',
210217
'group by heading',
218+
'group by heading reverse',
211219
'group by path',
220+
'group by path reverse',
212221
'group by priority',
222+
'group by priority reverse',
213223
'group by recurrence',
224+
'group by recurrence reverse',
214225
'group by recurring',
226+
'group by recurring reverse',
215227
'group by root',
228+
'group by root reverse',
216229
'group by scheduled',
230+
'group by scheduled reverse',
217231
'group by start',
232+
'group by start reverse',
218233
'group by status',
234+
'group by status reverse',
219235
'group by status.name',
236+
'group by status.name reverse',
220237
'group by status.type',
238+
'group by status.type reverse',
221239
'group by tags',
240+
'group by tags reverse',
222241
'group by urgency',
242+
'group by urgency reverse',
223243
];
224244
test.concurrent.each<string>(filters)('recognises %j', (filter) => {
225245
// Arrange

tests/Query/Filter/TagsField.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { fromLine } from '../../TestHelpers';
77
import { Sort } from '../../../src/Query/Sort';
88
import { TaskBuilder } from '../../TestingTools/TaskBuilder';
99
import { expectTaskComparesAfter, expectTaskComparesBefore } from '../../CustomMatchers/CustomMatchersForSorting';
10+
import type { Grouper } from '../../../src/Query/Grouper';
11+
import { TaskGroups } from '../../../src/Query/TaskGroups';
1012

1113
describe('tag presence & absence', () => {
1214
it.each(['has tag', 'has tags'])('should have "%s" filtering', (filterLine: string) => {
@@ -644,4 +646,34 @@ describe('grouping by tag', () => {
644646
// Assert
645647
expect(grouper(fromLine({ line: taskLine }))).toEqual(groups);
646648
});
649+
650+
it('sorts headings in reverse', () => {
651+
// Arrange
652+
const a = fromLine({ line: '- [ ] a #tag1' });
653+
const b = fromLine({ line: '- [ ] b #tag2' });
654+
const inputs = [a, b];
655+
656+
// Act
657+
const grouping: Grouper[] = [new TagsField().createGrouperFromLine('group by tags reverse')!];
658+
const groups = new TaskGroups(grouping, inputs);
659+
660+
// Assert
661+
expect(groups.toString()).toMatchInlineSnapshot(`
662+
"
663+
Group names: [#tag2]
664+
#### #tag2
665+
- [ ] b #tag2
666+
667+
---
668+
669+
Group names: [#tag1]
670+
#### #tag1
671+
- [ ] a #tag1
672+
673+
---
674+
675+
2 tasks
676+
"
677+
`);
678+
});
647679
});

tests/TaskGroups.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ describe('Grouping tasks', () => {
171171
const inputs = [a, b];
172172

173173
// Act
174-
const grouping: Grouper[] = [new DueDateField().createGrouper(true)];
174+
const grouping: Grouper[] = [new DueDateField().createGrouperFromLine('group by due reverse')!];
175175
const groups = new TaskGroups(grouping, inputs);
176176

177177
// Assert

0 commit comments

Comments
 (0)