Skip to content

Commit

Permalink
Merge pull request #3093 from ilandikov/refactor-status-makers
Browse files Browse the repository at this point in the history
refactor: Replace Status factory functions with static objects
  • Loading branch information
claremacrae authored Sep 24, 2024
2 parents 3c6809d + d1a6fba commit 914e858
Show file tree
Hide file tree
Showing 17 changed files with 134 additions and 145 deletions.
8 changes: 4 additions & 4 deletions src/Config/StatusSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ export class StatusSettings {
constructor() {
this.coreStatuses = [
// The two statuses that do not need CSS styling
Status.makeTodo().configuration,
Status.makeDone().configuration,
Status.TODO.configuration,
Status.DONE.configuration,
]; // Do not modify directly: use the static mutation methods in this class.
this.customStatuses = [
// Any statuses that are always supported, but need custom CSS styling
Status.makeInProgress().configuration,
Status.makeCancelled().configuration,
Status.IN_PROGRESS.configuration,
Status.CANCELLED.configuration,
]; // Do not modify directly: use the static mutation methods in this class.
}
readonly coreStatuses: StatusConfiguration[];
Expand Down
83 changes: 37 additions & 46 deletions src/Statuses/Status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ export class Status {
* @type {Status}
* @memberof Status
*/
public static DONE: Status = Status.makeDone();
public static readonly DONE: Status = new Status(new StatusConfiguration('x', 'Done', ' ', true, StatusType.DONE));

/**
* A default status of empty, used when things go wrong.
*
* @static
* @type {Status}
* @memberof Status
*/
public static EMPTY: Status = Status.makeEmpty();
public static readonly EMPTY: Status = new Status(new StatusConfiguration('', 'EMPTY', '', true, StatusType.EMPTY));

/**
* The default Todo status. Goes to Done when toggled.
Expand All @@ -40,7 +41,40 @@ export class Status {
* @type {Status}
* @memberof Status
*/
public static TODO: Status = Status.makeTodo();
public static readonly TODO: Status = new Status(new StatusConfiguration(' ', 'Todo', 'x', true, StatusType.TODO));

/**
* The default Cancelled status. Goes to Todo when toggled.
*
* @static
* @type {Status}
* @memberof Status
*/
public static readonly CANCELLED: Status = new Status(
new StatusConfiguration('-', 'Cancelled', ' ', true, StatusType.CANCELLED),
);

/**
* The default In Progress status. Goes to Done when toggled.
*
* @static
* @type {Status}
* @memberof Status
*/
public static readonly IN_PROGRESS: Status = new Status(
new StatusConfiguration('/', 'In Progress', 'x', true, StatusType.IN_PROGRESS),
);

/**
* A sample Non-Task status. Goes to NON_TASK when toggled.
*
* @static
* @type {Status}
* @memberof Status
*/
public static readonly NON_TASK: Status = new Status(
new StatusConfiguration('Q', 'Non-Task', 'A', true, StatusType.NON_TASK),
);

/**
* The configuration stored in the data.json file.
Expand Down Expand Up @@ -156,49 +190,6 @@ export class Status {
this.configuration = configuration;
}

/**
* The default Done status. Goes to Todo when toggled.
*/
static makeDone(): Status {
return new Status(new StatusConfiguration('x', 'Done', ' ', true, StatusType.DONE));
}

/**
* A default status of empty, used when things go wrong.
*/
static makeEmpty(): Status {
return new Status(new StatusConfiguration('', 'EMPTY', '', true, StatusType.EMPTY));
}

/**
* The default Todo status. Goes to Done when toggled.
* User may later be able to override this to go to In Progress instead.
*/
static makeTodo(): Status {
return new Status(new StatusConfiguration(' ', 'Todo', 'x', true, StatusType.TODO));
}

/**
* The default Cancelled status. Goes to Todo when toggled.
*/
static makeCancelled(): Status {
return new Status(new StatusConfiguration('-', 'Cancelled', ' ', true, StatusType.CANCELLED));
}

/**
* The default In Progress status. Goes to Done when toggled.
*/
static makeInProgress(): Status {
return new Status(new StatusConfiguration('/', 'In Progress', 'x', true, StatusType.IN_PROGRESS));
}

/**
* A sample Non-Task status. Goes to NON_TASK when toggled.
*/
static makeNonTask(): Status {
return new Status(new StatusConfiguration('Q', 'Non-Task', 'A', true, StatusType.NON_TASK));
}

/**
* Return the StatusType to use for a symbol, if it is not in the StatusRegistry.
* The core symbols are recognised.
Expand Down
2 changes: 1 addition & 1 deletion src/Statuses/StatusRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ export class StatusRegistry {
* @memberof StatusRegistry
*/
private addDefaultStatusTypes(): void {
const defaultStatuses = [Status.makeTodo(), Status.makeInProgress(), Status.makeDone(), Status.makeCancelled()];
const defaultStatuses = [Status.TODO, Status.IN_PROGRESS, Status.DONE, Status.CANCELLED];

defaultStatuses.forEach((status) => {
this.add(status);
Expand Down
12 changes: 6 additions & 6 deletions tests/DocumentationSamples/DocsSamplesForStatuses.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ describe('DefaultStatuses', () => {
// These "test" write out a markdown representation of the default task statuses,
// for embedding in the user docs.
it('core-statuses', () => {
VerifyStatuses.verifyStatusesInMultipleFormats([Status.makeTodo(), Status.makeDone()], true);
VerifyStatuses.verifyStatusesInMultipleFormats([Status.TODO, Status.DONE], true);
});

it('custom-statuses', () => {
VerifyStatuses.verifyStatusesInMultipleFormats([Status.makeInProgress(), Status.makeCancelled()], true);
VerifyStatuses.verifyStatusesInMultipleFormats([Status.IN_PROGRESS, Status.CANCELLED], true);
});

it('important-cycle', () => {
Expand Down Expand Up @@ -95,10 +95,10 @@ describe('Theme', () => {
describe('Status Transitions', () => {
it('status-types', () => {
const statuses = [
Status.makeTodo(),
Status.makeInProgress(),
Status.makeDone(),
Status.makeCancelled(),
Status.TODO,
Status.IN_PROGRESS,
Status.DONE,
Status.CANCELLED,
new Status(new StatusConfiguration('~', 'My custom status', ' ', false, StatusType.NON_TASK)),
];
VerifyStatuses.verifyTransitionsAsMarkdownTable(statuses);
Expand Down
2 changes: 1 addition & 1 deletion tests/Query/Filter/BlockingField.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe('blocking', () => {
const notBlocking = new TaskBuilder().build();
const child = new TaskBuilder().id('12345').build();
const childWithoutParent = new TaskBuilder().id('23456').build();
const childThatIsDone = new TaskBuilder().id('34567').status(Status.makeDone()).build();
const childThatIsDone = new TaskBuilder().id('34567').status(Status.DONE).build();
const parent = new TaskBuilder().dependsOn(['12345', '34567']).build();
const allTasks = [notBlocking, child, childWithoutParent, childThatIsDone, parent];

Expand Down
8 changes: 4 additions & 4 deletions tests/Query/Filter/FunctionField.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -583,15 +583,15 @@ describe('FunctionField - grouping - example functions', () => {
// A single space as the character in a heading is not useful, so replace with something displayable:
const line = 'group by function task.status.symbol.replace(" ", "space")';
const grouper = createGrouper(line);
toGroupTaskFromBuilder(grouper, new TaskBuilder().status(Status.makeCancelled()), ['-']);
toGroupTaskFromBuilder(grouper, new TaskBuilder().status(Status.makeTodo()), ['space']);
toGroupTaskFromBuilder(grouper, new TaskBuilder().status(Status.CANCELLED), ['-']);
toGroupTaskFromBuilder(grouper, new TaskBuilder().status(Status.TODO), ['space']);
});

it('group by status nextStatusSymbol', () => {
const line = 'group by function task.status.nextStatusSymbol.replace(" ", "space")';
const grouper = createGrouper(line);
toGroupTaskFromBuilder(grouper, new TaskBuilder().status(Status.makeInProgress()), ['x']);
toGroupTaskFromBuilder(grouper, new TaskBuilder().status(Status.makeDone()), ['space']);
toGroupTaskFromBuilder(grouper, new TaskBuilder().status(Status.IN_PROGRESS), ['x']);
toGroupTaskFromBuilder(grouper, new TaskBuilder().status(Status.DONE), ['space']);
});

it('group by using number', () => {
Expand Down
16 changes: 8 additions & 8 deletions tests/Query/Filter/StatusField.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ describe('status', () => {
const filter = new StatusField().createFilterOrErrorMessage('done');

// Assert
expect(filter).not.toMatchTaskWithStatus(Status.makeTodo().configuration);
expect(filter).toMatchTaskWithStatus(Status.makeDone().configuration);
expect(filter).not.toMatchTaskWithStatus(Status.TODO.configuration);
expect(filter).toMatchTaskWithStatus(Status.DONE.configuration);
expect(filter).toMatchTaskWithStatus(new StatusConfiguration('X', 'Really Done', 'x', true, StatusType.DONE));
expect(filter).not.toMatchTaskWithStatus(Status.makeInProgress().configuration);
expect(filter).toMatchTaskWithStatus(Status.makeCancelled().configuration);
expect(filter).not.toMatchTaskWithStatus(Status.IN_PROGRESS.configuration);
expect(filter).toMatchTaskWithStatus(Status.CANCELLED.configuration);
expect(filter).not.toMatchTaskWithStatus(new StatusConfiguration('!', 'Todo', 'x', true, StatusType.TODO)); // 'done' checks type.
expect(filter).toMatchTaskWithStatus(new StatusConfiguration('^', 'Non', 'x', true, StatusType.NON_TASK));
});
Expand All @@ -30,13 +30,13 @@ describe('status', () => {
const filter = new StatusField().createFilterOrErrorMessage('not done');

// Assert
expect(filter).toMatchTaskWithStatus(Status.makeTodo().configuration);
expect(filter).not.toMatchTaskWithStatus(Status.makeDone().configuration);
expect(filter).toMatchTaskWithStatus(Status.TODO.configuration);
expect(filter).not.toMatchTaskWithStatus(Status.DONE.configuration);
expect(filter).not.toMatchTaskWithStatus(
new StatusConfiguration('X', 'Really Done', 'x', true, StatusType.DONE),
);
expect(filter).toMatchTaskWithStatus(Status.makeInProgress().configuration);
expect(filter).not.toMatchTaskWithStatus(Status.makeCancelled().configuration);
expect(filter).toMatchTaskWithStatus(Status.IN_PROGRESS.configuration);
expect(filter).not.toMatchTaskWithStatus(Status.CANCELLED.configuration);
expect(filter).toMatchTaskWithStatus(new StatusConfiguration('!', 'Todo', 'x', true, StatusType.TODO)); // 'not done' type.
expect(filter).not.toMatchTaskWithStatus(new StatusConfiguration('^', 'Non', 'x', true, StatusType.NON_TASK));
});
Expand Down
2 changes: 1 addition & 1 deletion tests/Query/Filter/StatusTypeField.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const non_Task = new TaskBuilder()
.statusValues('^', 'non-task', 'x', false, StatusType.NON_TASK)
.description('Non-task')
.build();
const emptTask = new TaskBuilder().status(Status.makeEmpty()).description('Empty task').build();
const emptTask = new TaskBuilder().status(Status.EMPTY).description('Empty task').build();

describe('status.name', () => {
it('value', () => {
Expand Down
2 changes: 1 addition & 1 deletion tests/Scripting/TaskProperties.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ window.moment = moment;
describe('task', () => {
function verifyFieldDataForReferenceDocs(fields: string[]) {
const task1 = TaskBuilder.createFullyPopulatedTask();
const task2 = new TaskBuilder().description('minimal task').status(Status.makeInProgress()).build();
const task2 = new TaskBuilder().description('minimal task').status(Status.IN_PROGRESS).build();
verifyFieldDataFromTasksForReferenceDocs([task1, task2], fields);
}

Expand Down
16 changes: 7 additions & 9 deletions tests/Statuses/Status.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@ describe('Status', () => {
});

it('factory methods for default statuses', () => {
expect(Status.makeDone().previewText()).toEqual("- [x] => [ ], name: 'Done', type: 'DONE'.");
expect(Status.makeEmpty().previewText()).toEqual("- [] => [], name: 'EMPTY', type: 'EMPTY'.");
expect(Status.makeTodo().previewText()).toEqual("- [ ] => [x], name: 'Todo', type: 'TODO'.");
expect(Status.makeCancelled().previewText()).toEqual("- [-] => [ ], name: 'Cancelled', type: 'CANCELLED'.");
expect(Status.makeInProgress().previewText()).toEqual(
"- [/] => [x], name: 'In Progress', type: 'IN_PROGRESS'.",
);
expect(Status.makeNonTask().previewText()).toEqual("- [Q] => [A], name: 'Non-Task', type: 'NON_TASK'.");
expect(Status.DONE.previewText()).toEqual("- [x] => [ ], name: 'Done', type: 'DONE'.");
expect(Status.EMPTY.previewText()).toEqual("- [] => [], name: 'EMPTY', type: 'EMPTY'.");
expect(Status.TODO.previewText()).toEqual("- [ ] => [x], name: 'Todo', type: 'TODO'.");
expect(Status.CANCELLED.previewText()).toEqual("- [-] => [ ], name: 'Cancelled', type: 'CANCELLED'.");
expect(Status.IN_PROGRESS.previewText()).toEqual("- [/] => [x], name: 'In Progress', type: 'IN_PROGRESS'.");
expect(Status.NON_TASK.previewText()).toEqual("- [Q] => [A], name: 'Non-Task', type: 'NON_TASK'.");
});

it('should initialize with valid properties', () => {
Expand Down Expand Up @@ -126,7 +124,7 @@ describe('Status', () => {
});

it('should provide text with sorting comments for convenience of custom grouping', () => {
const status = Status.makeCancelled();
const status = Status.CANCELLED;
expect(status.typeGroupText).toEqual('%%4%%CANCELLED');
});
});
Expand Down
24 changes: 12 additions & 12 deletions tests/Statuses/StatusRegistry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ describe('StatusRegistry', () => {
// Assert
expect(statusRegistry).not.toBeNull();

expect(doneStatus.symbol).toEqual(Status.makeDone().symbol);
expect(doneStatus.symbol).toEqual(Status.DONE.symbol);

expect(statusRegistry.bySymbol('x').symbol).toEqual(Status.makeDone().symbol);
expect(statusRegistry.bySymbol('').symbol).toEqual(Status.makeEmpty().symbol);
expect(statusRegistry.bySymbol(' ').symbol).toEqual(Status.makeTodo().symbol);
expect(statusRegistry.bySymbol('-').symbol).toEqual(Status.makeCancelled().symbol);
expect(statusRegistry.bySymbol('/').symbol).toEqual(Status.makeInProgress().symbol);
expect(statusRegistry.bySymbol('x').symbol).toEqual(Status.DONE.symbol);
expect(statusRegistry.bySymbol('').symbol).toEqual(Status.EMPTY.symbol);
expect(statusRegistry.bySymbol(' ').symbol).toEqual(Status.TODO.symbol);
expect(statusRegistry.bySymbol('-').symbol).toEqual(Status.CANCELLED.symbol);
expect(statusRegistry.bySymbol('/').symbol).toEqual(Status.IN_PROGRESS.symbol);

// Detect unrecognised symbol:
expect(statusRegistry.bySymbol('?').symbol).toEqual(Status.makeEmpty().symbol);
expect(statusRegistry.bySymbol('?').symbol).toEqual(Status.EMPTY.symbol);
});

it('should clear the statuses', () => {
Expand Down Expand Up @@ -395,13 +395,13 @@ describe('StatusRegistry', () => {

// Assert
expect(task).not.toBeNull();
expect(task!.status.symbol).toEqual(Status.makeTodo().symbol);
expect(task!.status.symbol).toEqual(Status.TODO.symbol);

const toggledDone = task?.toggle()[0];
expect(toggledDone?.status.symbol).toEqual(Status.makeDone().symbol);
expect(toggledDone?.status.symbol).toEqual(Status.DONE.symbol);

const toggledTodo = toggledDone?.toggle()[0];
expect(toggledTodo?.status.symbol).toEqual(Status.makeTodo().symbol);
expect(toggledTodo?.status.symbol).toEqual(Status.TODO.symbol);
});

it('should allow task to toggle from cancelled to todo', () => {
Expand All @@ -419,10 +419,10 @@ describe('StatusRegistry', () => {

// Assert
expect(task).not.toBeNull();
expect(task!.status.symbol).toEqual(Status.makeCancelled().symbol);
expect(task!.status.symbol).toEqual(Status.CANCELLED.symbol);

const toggledTodo = task?.toggle()[0];
expect(toggledTodo?.status.symbol).toEqual(Status.makeTodo().symbol);
expect(toggledTodo?.status.symbol).toEqual(Status.TODO.symbol);
});

it('should allow task to toggle through custom transitions', () => {
Expand Down
Loading

0 comments on commit 914e858

Please sign in to comment.