Skip to content

Commit 7708880

Browse files
authored
Merge pull request #1979 from obsidian-tasks-group/more-expressive-tests
test: More custom matchers, for easier Task testing
2 parents 1de4416 + 353ae55 commit 7708880

File tree

4 files changed

+157
-138
lines changed

4 files changed

+157
-138
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { TaskBuilder } from '../TestingTools/TaskBuilder';
2+
3+
declare global {
4+
namespace jest {
5+
interface Matchers<R> {
6+
toBeIdenticalTo(builder2: TaskBuilder): R;
7+
}
8+
9+
interface Expect {
10+
toBeIdenticalTo(builder2: TaskBuilder): any;
11+
}
12+
13+
interface InverseAsymmetricMatchers {
14+
toBeIdenticalTo(builder2: TaskBuilder): any;
15+
}
16+
}
17+
}
18+
19+
export function toBeIdenticalTo(builder1: TaskBuilder, builder2: TaskBuilder) {
20+
const task1 = builder1.build();
21+
const task2 = builder2.build();
22+
const pass = task1.identicalTo(task2);
23+
24+
if (pass) {
25+
return {
26+
message: () => 'Tasks treated as identical, but should be different',
27+
pass: true,
28+
};
29+
}
30+
return {
31+
message: () => {
32+
return 'Tasks should be identical, but are treated as different';
33+
},
34+
pass: false,
35+
};
36+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { diff } from 'jest-diff';
2+
import { fromLine } from '../TestHelpers';
3+
4+
declare global {
5+
namespace jest {
6+
interface Matchers<R> {
7+
toToggleTo(expectedLines: string[]): R;
8+
toToggleWithRecurrenceInUsersOrderTo(expectedLines: string[]): R;
9+
}
10+
11+
interface Expect {
12+
toToggleTo(expectedLines: string[]): any;
13+
toToggleWithRecurrenceInUsersOrderTo(expectedLines: string[]): any;
14+
}
15+
16+
interface InverseAsymmetricMatchers {
17+
toToggleTo(expectedLines: string[]): any;
18+
toToggleWithRecurrenceInUsersOrderTo(expectedLines: string[]): any;
19+
}
20+
}
21+
}
22+
23+
export function toToggleTo(line: string, expectedLines: string[]) {
24+
const task = fromLine({ line: line });
25+
const receivedLines = task.toggle().map((t) => t.toFileLineString());
26+
return toMatchLines(receivedLines, expectedLines);
27+
}
28+
29+
export function toToggleWithRecurrenceInUsersOrderTo(line: string, expectedLines: string[]) {
30+
const task = fromLine({ line: line });
31+
const receivedLines = task.toggleWithRecurrenceInUsersOrder().map((t) => t.toFileLineString());
32+
return toMatchLines(receivedLines, expectedLines);
33+
}
34+
35+
function toMatchLines(receivedLines: string[], expectedLines: string[]) {
36+
const matches = receivedLines.join('\n') === expectedLines.join('\n');
37+
if (!matches) {
38+
return {
39+
message: () => 'unexpected incorrect new task lines:\n' + diff(expectedLines, receivedLines),
40+
pass: false,
41+
};
42+
}
43+
44+
return {
45+
message: () => `new task lines" should not be: "${receivedLines}"`,
46+
pass: true,
47+
};
48+
}

tests/CustomMatchers/jest.custom_matchers.setup.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ import {
1010
toMatchTaskWithPath,
1111
toMatchTaskWithStatus,
1212
} from './CustomMatchersForFilters';
13-
14-
import { toSupportGroupingWithProperty } from './CustomMatchersForGrouping';
15-
16-
import { toMatchTaskDetails } from './CustomMatchersForTaskSerializer';
17-
1813
expect.extend({
1914
toBeValid,
2015
toHaveExplanation,
@@ -23,6 +18,37 @@ expect.extend({
2318
toMatchTaskWithHeading,
2419
toMatchTaskWithPath,
2520
toMatchTaskWithStatus,
26-
toMatchTaskDetails,
21+
});
22+
23+
// ---------------------------------------------------------------------
24+
// CustomMatchersForGrouping
25+
// ---------------------------------------------------------------------
26+
import { toSupportGroupingWithProperty } from './CustomMatchersForGrouping';
27+
expect.extend({
2728
toSupportGroupingWithProperty,
2829
});
30+
31+
// ---------------------------------------------------------------------
32+
// CustomMatchersForTaskBuilder
33+
// ---------------------------------------------------------------------
34+
import { toBeIdenticalTo } from './CustomMatchersForTaskBuilder';
35+
expect.extend({
36+
toBeIdenticalTo,
37+
});
38+
39+
// ---------------------------------------------------------------------
40+
// CustomMatchersForTasks
41+
// ---------------------------------------------------------------------
42+
import { toToggleTo, toToggleWithRecurrenceInUsersOrderTo } from './CustomMatchersForTasks';
43+
expect.extend({
44+
toToggleTo,
45+
toToggleWithRecurrenceInUsersOrderTo,
46+
});
47+
48+
// ---------------------------------------------------------------------
49+
// CustomMatchersForTaskBuilder
50+
// ---------------------------------------------------------------------
51+
import { toMatchTaskDetails } from './CustomMatchersForTaskSerializer';
52+
expect.extend({
53+
toMatchTaskDetails,
54+
});

tests/Task.test.ts

Lines changed: 41 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,107 +1018,63 @@ describe('toggle done', () => {
10181018
});
10191019
});
10201020

1021-
describe('set correct created date on reccurence task', () => {
1022-
it('does not set created date with disabled setting', () => {
1023-
// Arrange
1024-
const line = '- [ ] this is a task 📅 2021-09-12 🔁 every day';
1025-
updateSettings({ setCreatedDate: false });
1026-
1027-
// Act
1028-
const task = fromLine({
1029-
line,
1030-
});
1031-
1032-
// Assert
1033-
expect(task).not.toBeNull();
1034-
expect(task!.createdDate).toBeNull();
1035-
1036-
const tasks = task!.toggle();
1037-
expect(tasks.length).toEqual(2);
1038-
const nextTask: Task = tasks[0];
1039-
expect(nextTask.createdDate).toBeNull();
1021+
describe('created dates on recurring task', () => {
1022+
beforeEach(() => {
1023+
jest.useFakeTimers();
1024+
jest.setSystemTime(new Date('2023-03-08'));
1025+
});
10401026

1041-
// cleanup
1027+
afterEach(() => {
1028+
jest.useRealTimers();
10421029
resetSettings();
10431030
});
10441031

1045-
it('does not set created date with disabled setting when repeated has created date', () => {
1032+
it('should not set created date with disabled setting', () => {
10461033
// Arrange
1047-
const line = '- [ ] this is a task ➕ 2021-09-11 📅 2021-09-12 🔁 every day';
1034+
const line = '- [ ] this is a task 🔁 every day 📅 2021-09-12';
10481035
updateSettings({ setCreatedDate: false });
10491036

10501037
// Act
1051-
const task = fromLine({
1052-
line,
1053-
});
1054-
1055-
// Assert
1056-
expect(task).not.toBeNull();
1057-
expect(task!.createdDate).not.toBeNull();
1058-
expect(task!.createdDate!.isSame(moment('2021-09-11', 'YYYY-MM-DD'))).toStrictEqual(true);
1038+
expect(line).toToggleTo([
1039+
'- [ ] this is a task 🔁 every day 📅 2021-09-13',
1040+
'- [x] this is a task 🔁 every day 📅 2021-09-12 ✅ 2023-03-08',
1041+
]);
1042+
});
10591043

1060-
const tasks = task!.toggle();
1061-
expect(tasks.length).toEqual(2);
1062-
const nextTask: Task = tasks[0];
1063-
expect(nextTask.createdDate).toBeNull();
1044+
it('should not set created date if setting disabled, even if original has created date', () => {
1045+
// Arrange
1046+
const line = '- [ ] this is a task 🔁 every day ➕ 2021-09-11 📅 2021-09-12';
1047+
updateSettings({ setCreatedDate: false });
10641048

1065-
// cleanup
1066-
resetSettings();
1049+
// Act
1050+
expect(line).toToggleTo([
1051+
'- [ ] this is a task 🔁 every day 📅 2021-09-13',
1052+
'- [x] this is a task 🔁 every day ➕ 2021-09-11 📅 2021-09-12 ✅ 2023-03-08',
1053+
]);
10671054
});
10681055

1069-
it('set created date with enabled setting', () => {
1056+
it('should set created date if setting enabled', () => {
10701057
// Arrange
1071-
const today = '2023-03-08';
1072-
const todaySpy = jest.spyOn(Date, 'now').mockReturnValue(moment(today).valueOf());
1073-
const line = '- [ ] this is a task 📅 2021-09-12 🔁 every day';
1058+
const line = '- [ ] this is a task 🔁 every day 📅 2021-09-12';
10741059
updateSettings({ setCreatedDate: true });
10751060

10761061
// Act
1077-
const task = fromLine({
1078-
line,
1079-
});
1080-
1081-
// Assert
1082-
expect(task).not.toBeNull();
1083-
expect(task!.createdDate).toBeNull();
1084-
1085-
const tasks = task!.toggle();
1086-
expect(tasks.length).toEqual(2);
1087-
const nextTask: Task = tasks[0];
1088-
expect(nextTask.createdDate).not.toBeNull();
1089-
expect(nextTask!.createdDate!.isSame(moment(today, 'YYYY-MM-DD'))).toStrictEqual(true);
1090-
1091-
// cleanup
1092-
resetSettings();
1093-
todaySpy.mockClear();
1062+
expect(line).toToggleTo([
1063+
'- [ ] this is a task 🔁 every day ➕ 2023-03-08 📅 2021-09-13',
1064+
'- [x] this is a task 🔁 every day 📅 2021-09-12 ✅ 2023-03-08',
1065+
]);
10941066
});
10951067

1096-
it('set created date with enabled setting when repeated has created date', () => {
1068+
it('should set created date if setting enabled, when original has created date', () => {
10971069
// Arrange
1098-
const today = '2023-03-08';
1099-
const todaySpy = jest.spyOn(Date, 'now').mockReturnValue(moment(today).valueOf());
1100-
const line = '- [ ] this is a task ➕ 2021-09-11 📅 2021-09-12 🔁 every day';
1070+
const line = '- [ ] this is a task 🔁 every day ➕ 2021-09-11 📅 2021-09-12';
11011071
updateSettings({ setCreatedDate: true });
11021072

11031073
// Act
1104-
const task = fromLine({
1105-
line,
1106-
});
1107-
1108-
// Assert
1109-
expect(task).not.toBeNull();
1110-
expect(task!.createdDate).not.toBeNull();
1111-
expect(task!.createdDate!.isSame(moment('2021-09-11', 'YYYY-MM-DD'))).toStrictEqual(true);
1112-
1113-
const tasks = task!.toggle();
1114-
expect(tasks.length).toEqual(2);
1115-
const nextTask: Task = tasks[0];
1116-
expect(nextTask.createdDate).not.toBeNull();
1117-
expect(nextTask!.createdDate!.isSame(moment(today, 'YYYY-MM-DD'))).toStrictEqual(true);
1118-
1119-
// cleanup
1120-
resetSettings();
1121-
todaySpy.mockClear();
1074+
expect(line).toToggleTo([
1075+
'- [ ] this is a task 🔁 every day ➕ 2023-03-08 📅 2021-09-13',
1076+
'- [x] this is a task 🔁 every day ➕ 2021-09-11 📅 2021-09-12 ✅ 2023-03-08',
1077+
]);
11221078
});
11231079
});
11241080

@@ -1134,19 +1090,9 @@ describe('order of recurring tasks', () => {
11341090
resetSettings();
11351091
});
11361092

1137-
function togglingInUsersOrderShouldGive(line: string, expectedLines: string[]) {
1138-
// Arrange
1139-
const task = fromLine({ line: line });
1140-
1141-
// Act
1142-
const lines = task.toggleWithRecurrenceInUsersOrder().map((t) => t.toFileLineString());
1143-
1144-
// Assert
1145-
expect(lines).toStrictEqual(expectedLines);
1146-
}
1147-
11481093
it('should put new task before old, by default', () => {
1149-
togglingInUsersOrderShouldGive('- [ ] this is a recurring task 🔁 every day', [
1094+
const line = '- [ ] this is a recurring task 🔁 every day';
1095+
expect(line).toToggleWithRecurrenceInUsersOrderTo([
11501096
'- [ ] this is a recurring task 🔁 every day',
11511097
'- [x] this is a recurring task 🔁 every day ✅ 2023-05-16',
11521098
]);
@@ -1155,7 +1101,8 @@ describe('order of recurring tasks', () => {
11551101
it('should honour new-task-before-old setting', () => {
11561102
updateSettings({ recurrenceOnNextLine: false });
11571103

1158-
togglingInUsersOrderShouldGive('- [ ] this is a recurring task 🔁 every day', [
1104+
const line = '- [ ] this is a recurring task 🔁 every day';
1105+
expect(line).toToggleWithRecurrenceInUsersOrderTo([
11591106
'- [ ] this is a recurring task 🔁 every day',
11601107
'- [x] this is a recurring task 🔁 every day ✅ 2023-05-16',
11611108
]);
@@ -1164,52 +1111,14 @@ describe('order of recurring tasks', () => {
11641111
it('should honour old-task-before-new setting', () => {
11651112
updateSettings({ recurrenceOnNextLine: true });
11661113

1167-
togglingInUsersOrderShouldGive('- [ ] this is a recurring task 🔁 every day', [
1114+
const line = '- [ ] this is a recurring task 🔁 every day';
1115+
expect(line).toToggleWithRecurrenceInUsersOrderTo([
11681116
'- [x] this is a recurring task 🔁 every day ✅ 2023-05-16',
11691117
'- [ ] this is a recurring task 🔁 every day',
11701118
]);
11711119
});
11721120
});
11731121

1174-
declare global {
1175-
namespace jest {
1176-
interface Matchers<R> {
1177-
toBeIdenticalTo(builder2: TaskBuilder): R;
1178-
}
1179-
1180-
interface Expect {
1181-
toBeIdenticalTo(builder2: TaskBuilder): any;
1182-
}
1183-
1184-
interface InverseAsymmetricMatchers {
1185-
toBeIdenticalTo(builder2: TaskBuilder): any;
1186-
}
1187-
}
1188-
}
1189-
1190-
export function toBeIdenticalTo(builder1: TaskBuilder, builder2: TaskBuilder) {
1191-
const task1 = builder1.build();
1192-
const task2 = builder2.build();
1193-
const pass = task1.identicalTo(task2);
1194-
1195-
if (pass) {
1196-
return {
1197-
message: () => 'Tasks treated as identical, but should be different',
1198-
pass: true,
1199-
};
1200-
}
1201-
return {
1202-
message: () => {
1203-
return 'Tasks should be identical, but are treated as different';
1204-
},
1205-
pass: false,
1206-
};
1207-
}
1208-
1209-
expect.extend({
1210-
toBeIdenticalTo,
1211-
});
1212-
12131122
describe('identicalTo', () => {
12141123
it('should check status', () => {
12151124
const lhs = new TaskBuilder().status(Status.TODO);

0 commit comments

Comments
 (0)