From ea30347da015f82903d76d0f9d2443e4d9a6447d Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Thu, 19 Sep 2024 22:52:50 +0600 Subject: [PATCH 01/27] test: . inline variable --- tests/ui/EditTask.test.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index 404131ffc5..8079f314ce 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -6,8 +6,8 @@ import moment from 'moment'; import { taskFromLine } from '../../src/Commands/CreateOrEditTaskParser'; import { GlobalFilter } from '../../src/Config/GlobalFilter'; import { resetSettings, updateSettings } from '../../src/Config/Settings'; -import { StatusRegistry } from '../../src/Statuses/StatusRegistry'; import { DateFallback } from '../../src/DateTime/DateFallback'; +import { StatusRegistry } from '../../src/Statuses/StatusRegistry'; import type { Task } from '../../src/Task/Task'; import EditTask from '../../src/ui/EditTask.svelte'; import { verifyWithFileExtension } from '../TestingTools/ApprovalTestHelpers'; @@ -334,9 +334,8 @@ describe('Task editing', () => { resetSettings(); }); - const line = '- [ ] simple'; it('should change status to Done and add doneDate', async () => { - const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus(line, 'x'); + const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus('- [ ] simple', 'x'); expect(getElementValue(container, 'done')).toEqual(today); submit.click(); @@ -355,7 +354,7 @@ describe('Task editing', () => { }); it('should change status to Cancelled and add cancelledDate', async () => { - const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus(line, '-'); + const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus('- [ ] simple', '-'); expect(getElementValue(container, 'cancelled')).toEqual(today); submit.click(); From 2d2b3c27acdf61350db48ea799b153c485431b31 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Thu, 19 Sep 2024 22:55:22 +0600 Subject: [PATCH 02/27] test: - make test task descriptions self-explanatory --- tests/ui/EditTask.test.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index 8079f314ce..1d89c14dde 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -335,30 +335,38 @@ describe('Task editing', () => { }); it('should change status to Done and add doneDate', async () => { - const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus('- [ ] simple', 'x'); + const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( + '- [ ] expecting done date to be added', + 'x', + ); expect(getElementValue(container, 'done')).toEqual(today); submit.click(); - expect(await waitForClose).toMatchInlineSnapshot('"- [x] simple ✅ 2024-02-29"'); + expect(await waitForClose).toMatchInlineSnapshot('"- [x] expecting done date to be added ✅ 2024-02-29"'); }); it('should change status to Todo and remove doneDate', async () => { const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( - '- [x] simple ✅ 2024-02-29', + '- [x] expecting done date to be removed ✅ 2024-02-29', ' ', ); expect(getElementValue(container, 'done')).toEqual(''); submit.click(); - expect(await waitForClose).toMatchInlineSnapshot('"- [ ] simple"'); + expect(await waitForClose).toMatchInlineSnapshot('"- [ ] expecting done date to be removed"'); }); it('should change status to Cancelled and add cancelledDate', async () => { - const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus('- [ ] simple', '-'); + const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( + '- [ ] expecting cancelled date to be added', + '-', + ); expect(getElementValue(container, 'cancelled')).toEqual(today); submit.click(); - expect(await waitForClose).toMatchInlineSnapshot('"- [-] simple ❌ 2024-02-29"'); + expect(await waitForClose).toMatchInlineSnapshot( + '"- [-] expecting cancelled date to be added ❌ 2024-02-29"', + ); }); it('should create new instance of recurring task, with doneDate set to today', async () => { From d735a7247f668a8cfc873fefa5f1cb3534aab5fc Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Thu, 19 Sep 2024 23:01:08 +0600 Subject: [PATCH 03/27] test: - add tests showing current behaviour --- tests/ui/EditTask.test.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index 1d89c14dde..9abade5866 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -345,6 +345,17 @@ describe('Task editing', () => { expect(await waitForClose).toMatchInlineSnapshot('"- [x] expecting done date to be added ✅ 2024-02-29"'); }); + it('should change status to Done and change doneDate', async () => { + const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( + '- [ ] expecting done date to be changed ✅ 2024-09-19', + 'x', + ); + expect(getElementValue(container, 'done')).toEqual(today); + + submit.click(); + expect(await waitForClose).toMatchInlineSnapshot('"- [x] expecting done date to be changed ✅ 2024-02-29"'); + }); + it('should change status to Todo and remove doneDate', async () => { const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( '- [x] expecting done date to be removed ✅ 2024-02-29', @@ -369,6 +380,19 @@ describe('Task editing', () => { ); }); + it('should change status to Cancelled and change cancelledDate', async () => { + const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( + '- [ ] expecting cancelled date to be changed ❌ 2024-09-20', + '-', + ); + expect(getElementValue(container, 'cancelled')).toEqual(today); + + submit.click(); + expect(await waitForClose).toMatchInlineSnapshot( + '"- [-] expecting cancelled date to be changed ❌ 2024-02-29"', + ); + }); + it('should create new instance of recurring task, with doneDate set to today', async () => { updateSettings({ recurrenceOnNextLine: false }); const { waitForClose, submit } = await renderTaskModalAndChangeStatus( From 60738be42584d34a2ce4f6f8f4a20a4e1e910c3b Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Thu, 19 Sep 2024 23:08:24 +0600 Subject: [PATCH 04/27] test: - add missing test on cancelled date --- tests/ui/EditTask.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index 9abade5866..ba4e9850eb 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -393,6 +393,17 @@ describe('Task editing', () => { ); }); + it('should change status to Todo and remove cancelledDate', async () => { + const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( + '- [-] expecting cancelled date to be removed ❌ 2024-02-29', + ' ', + ); + expect(getElementValue(container, 'cancelled')).toEqual(''); + + submit.click(); + expect(await waitForClose).toMatchInlineSnapshot('"- [ ] expecting cancelled date to be removed"'); + }); + it('should create new instance of recurring task, with doneDate set to today', async () => { updateSettings({ recurrenceOnNextLine: false }); const { waitForClose, submit } = await renderTaskModalAndChangeStatus( From 52c4a79ba5f9a969980cbe9578c85796e7cb6ea8 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Fri, 20 Sep 2024 03:03:44 +0600 Subject: [PATCH 05/27] fix: - keep done & cancelled date if they are present when status changed to done & cancelled respectively --- src/ui/StatusEditor.svelte | 15 ++++++++++++--- tests/ui/EditTask.test.ts | 12 ++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index e53d71dbe8..f38ef38b79 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -26,9 +26,18 @@ const taskWithEditedStatusApplied = task.handleNewStatus(selectedStatus).pop(); if (taskWithEditedStatusApplied) { - // Update the doneDate field, in case changing the status changed the value: - editableTask.doneDate = taskWithEditedStatusApplied.done.formatAsDate(); - editableTask.cancelledDate = taskWithEditedStatusApplied.cancelled.formatAsDate(); + // change the done date using XNOR logic: + // done date is empty and new status is DONE + // OR + // done date is filled and new status is not DONE + if ((editableTask.doneDate === '') === selectedStatus.isCompleted()) { + editableTask.doneDate = taskWithEditedStatusApplied.done.formatAsDate(); + } + + // same logic for cancelled date & CANCELLED status + if ((editableTask.cancelledDate === '') === selectedStatus.isCancelled()) { + editableTask.cancelledDate = taskWithEditedStatusApplied.cancelled.formatAsDate(); + } } }; diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index ba4e9850eb..c7e8fbfb55 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -347,13 +347,13 @@ describe('Task editing', () => { it('should change status to Done and change doneDate', async () => { const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( - '- [ ] expecting done date to be changed ✅ 2024-09-19', + '- [ ] expecting done date to be kept ✅ 2024-09-19', 'x', ); - expect(getElementValue(container, 'done')).toEqual(today); + expect(getElementValue(container, 'done')).toEqual('2024-09-19'); submit.click(); - expect(await waitForClose).toMatchInlineSnapshot('"- [x] expecting done date to be changed ✅ 2024-02-29"'); + expect(await waitForClose).toMatchInlineSnapshot('"- [x] expecting done date to be kept ✅ 2024-09-19"'); }); it('should change status to Todo and remove doneDate', async () => { @@ -382,14 +382,14 @@ describe('Task editing', () => { it('should change status to Cancelled and change cancelledDate', async () => { const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( - '- [ ] expecting cancelled date to be changed ❌ 2024-09-20', + '- [ ] expecting cancelled date to be kept ❌ 2024-09-20', '-', ); - expect(getElementValue(container, 'cancelled')).toEqual(today); + expect(getElementValue(container, 'cancelled')).toEqual('2024-09-20'); submit.click(); expect(await waitForClose).toMatchInlineSnapshot( - '"- [-] expecting cancelled date to be changed ❌ 2024-02-29"', + '"- [-] expecting cancelled date to be kept ❌ 2024-02-29"', ); }); From ce5b3de5fd252af427eea78bb8675406045c95fc Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Fri, 20 Sep 2024 14:20:06 +0600 Subject: [PATCH 06/27] test: - update test descriptions --- tests/ui/EditTask.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index c7e8fbfb55..dd384fb82a 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -345,7 +345,7 @@ describe('Task editing', () => { expect(await waitForClose).toMatchInlineSnapshot('"- [x] expecting done date to be added ✅ 2024-02-29"'); }); - it('should change status to Done and change doneDate', async () => { + it('should change status to Done and keep doneDate', async () => { const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( '- [ ] expecting done date to be kept ✅ 2024-09-19', 'x', @@ -380,7 +380,7 @@ describe('Task editing', () => { ); }); - it('should change status to Cancelled and change cancelledDate', async () => { + it('should change status to Cancelled and keep cancelledDate', async () => { const { waitForClose, container, submit } = await renderTaskModalAndChangeStatus( '- [ ] expecting cancelled date to be kept ❌ 2024-09-20', '-', From 5d7b558babb0d49882bc1a0cddd71ce403574d57 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Fri, 20 Sep 2024 15:08:05 +0600 Subject: [PATCH 07/27] test: - add test showing current behaviour --- tests/ui/EditTask.test.ts | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index dd384fb82a..882b7257e5 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -158,6 +158,35 @@ async function renderTaskModalAndChangeStatus(line: string, newStatusSymbol: str return { waitForClose, container, submit }; } +/** + * Simulate the behaviour of: + * - clicking on a line in Obsidian, + * - opening the Edit task modal, + * - editing a field, + * - changing the status, + * - and clicking Apply. + * @param line + * @param elementId - specifying the field to edit + * @param newValue - the new value for the field + * @param newStatus - new Status value + */ +async function renderChangeDateAndStatus(line: string, elementId: string, newValue: string, newStatus: string) { + const task = taskFromLine({ line: line, path: '' }); + const { waitForClose, onSubmit } = constructSerialisingOnSubmit(task); + const { result, container } = renderAndCheckModal(task, onSubmit); + + const inputElement = getAndCheckRenderedElement(container, elementId); + await editInputElement(inputElement, newValue); + + const statusSelector = getAndCheckRenderedElement(container, 'status-type'); + await fireEvent.change(statusSelector, { + target: { value: newStatus }, + }); + + const submit = getAndCheckApplyButton(result); + return { waitForClose, container, submit }; +} + function getElementValue(container: HTMLElement, elementId: string) { const element = getAndCheckRenderedElement(container, elementId); return element.value; @@ -404,6 +433,22 @@ describe('Task editing', () => { expect(await waitForClose).toMatchInlineSnapshot('"- [ ] expecting cancelled date to be removed"'); }); + it('should keep the done date and change status to done', async () => { + const { waitForClose, container, submit } = await renderChangeDateAndStatus( + '- [ ] input done date, change status to done and expect the date to be kept', + 'done', + '2024-09-20', + 'x', + ); + + expect(getElementValue(container, 'done')).toEqual('2024-09-20'); + + submit.click(); + expect(await waitForClose).toMatchInlineSnapshot( + '"- [x] input done date, change status to done and expect the date to be kept ✅ 2024-09-20"', + ); + }); + it('should create new instance of recurring task, with doneDate set to today', async () => { updateSettings({ recurrenceOnNextLine: false }); const { waitForClose, submit } = await renderTaskModalAndChangeStatus( From e0ea3730d0f5467714cc89fc75e49eca3b838fd1 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 18:43:54 +0600 Subject: [PATCH 08/27] refactor: - access done date field as a dictionary --- src/ui/StatusEditor.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index f38ef38b79..9d15c9a6b8 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -31,7 +31,7 @@ // OR // done date is filled and new status is not DONE if ((editableTask.doneDate === '') === selectedStatus.isCompleted()) { - editableTask.doneDate = taskWithEditedStatusApplied.done.formatAsDate(); + editableTask.doneDate = taskWithEditedStatusApplied['done'].formatAsDate(); } // same logic for cancelled date & CANCELLED status From e50688a1ba5a36d7766e44cdd1447c9b0b6c745a Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 18:50:12 +0600 Subject: [PATCH 09/27] refactor: - access doneDate date field as a dictionary --- src/ui/StatusEditor.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index 9d15c9a6b8..b9bede9e9d 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -30,8 +30,8 @@ // done date is empty and new status is DONE // OR // done date is filled and new status is not DONE - if ((editableTask.doneDate === '') === selectedStatus.isCompleted()) { - editableTask.doneDate = taskWithEditedStatusApplied['done'].formatAsDate(); + if ((editableTask['doneDate'] === '') === selectedStatus.isCompleted()) { + editableTask['doneDate'] = taskWithEditedStatusApplied['done'].formatAsDate(); } // same logic for cancelled date & CANCELLED status From e63817ac172ca1ddf1de2f5416bbfd6ed5e6dfb0 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 18:51:51 +0600 Subject: [PATCH 10/27] refactor: . extract variables --- src/ui/StatusEditor.svelte | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index b9bede9e9d..29600202df 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -30,8 +30,11 @@ // done date is empty and new status is DONE // OR // done date is filled and new status is not DONE - if ((editableTask['doneDate'] === '') === selectedStatus.isCompleted()) { - editableTask['doneDate'] = taskWithEditedStatusApplied['done'].formatAsDate(); + const editableTaskDateField = 'doneDate'; + const isInStatus = selectedStatus.isCompleted(); + const taskDateField = 'done'; + if ((editableTask[editableTaskDateField] === '') === isInStatus) { + editableTask[editableTaskDateField] = taskWithEditedStatusApplied[taskDateField].formatAsDate(); } // same logic for cancelled date & CANCELLED status From e62a2df790460e428fdbf4e1eb3aabf96d277a52 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 18:52:11 +0600 Subject: [PATCH 11/27] refactor: . extract appleSauce() --- src/ui/StatusEditor.svelte | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index 29600202df..fc7f800ceb 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -11,6 +11,17 @@ let statusSymbol = task.status.symbol; + function appleSauce( + editableTaskDateField: keyof Pick, + isInStatus: boolean, + taskWithEditedStatusApplied: Task, + taskDateField: keyof Pick, + ) { + if ((editableTask[editableTaskDateField] === '') === isInStatus) { + editableTask[editableTaskDateField] = taskWithEditedStatusApplied[taskDateField].formatAsDate(); + } + } + const _onStatusChange = () => { // Use statusSymbol to find the status to save to editableTask.status const selectedStatus: Status | undefined = statusOptions.find((s) => s.symbol === statusSymbol); @@ -33,9 +44,7 @@ const editableTaskDateField = 'doneDate'; const isInStatus = selectedStatus.isCompleted(); const taskDateField = 'done'; - if ((editableTask[editableTaskDateField] === '') === isInStatus) { - editableTask[editableTaskDateField] = taskWithEditedStatusApplied[taskDateField].formatAsDate(); - } + appleSauce(editableTaskDateField, isInStatus, taskWithEditedStatusApplied, taskDateField); // same logic for cancelled date & CANCELLED status if ((editableTask.cancelledDate === '') === selectedStatus.isCancelled()) { From 451bde53a48fc3fb25600bbd18e5e150a3cc4566 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 18:55:42 +0600 Subject: [PATCH 12/27] refactor: . inline variables --- src/ui/StatusEditor.svelte | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index fc7f800ceb..96dbcb861a 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -41,10 +41,7 @@ // done date is empty and new status is DONE // OR // done date is filled and new status is not DONE - const editableTaskDateField = 'doneDate'; - const isInStatus = selectedStatus.isCompleted(); - const taskDateField = 'done'; - appleSauce(editableTaskDateField, isInStatus, taskWithEditedStatusApplied, taskDateField); + appleSauce('doneDate', selectedStatus.isCompleted(), taskWithEditedStatusApplied, 'done'); // same logic for cancelled date & CANCELLED status if ((editableTask.cancelledDate === '') === selectedStatus.isCancelled()) { From 9f2e535ff952100dcab2424ad73cdc74e020b6f6 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 19:23:11 +0600 Subject: [PATCH 13/27] refactor: . extract variable --- src/ui/StatusEditor.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index 96dbcb861a..fcfb9489b0 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -17,7 +17,9 @@ taskWithEditedStatusApplied: Task, taskDateField: keyof Pick, ) { - if ((editableTask[editableTaskDateField] === '') === isInStatus) { + const dateFieldIsEmpty = editableTask[editableTaskDateField] === ''; + + if (dateFieldIsEmpty === isInStatus) { editableTask[editableTaskDateField] = taskWithEditedStatusApplied[taskDateField].formatAsDate(); } } From 1cb380320d350e1feff72ebe22f6a651ee52c171 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 19:30:22 +0600 Subject: [PATCH 14/27] refactor: - split if into two ifs --- src/ui/StatusEditor.svelte | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index fcfb9489b0..b594094bc0 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -19,7 +19,11 @@ ) { const dateFieldIsEmpty = editableTask[editableTaskDateField] === ''; - if (dateFieldIsEmpty === isInStatus) { + if (dateFieldIsEmpty && isInStatus) { + editableTask[editableTaskDateField] = taskWithEditedStatusApplied[taskDateField].formatAsDate(); + } + + if (!dateFieldIsEmpty && !isInStatus) { editableTask[editableTaskDateField] = taskWithEditedStatusApplied[taskDateField].formatAsDate(); } } From 14bcf1494fcb9327b88dd89526d35a1bfc1c7d10 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 19:31:19 +0600 Subject: [PATCH 15/27] refactor: - set the correct value explicitly --- src/ui/StatusEditor.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index b594094bc0..3c7ef5ecb6 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -24,7 +24,7 @@ } if (!dateFieldIsEmpty && !isInStatus) { - editableTask[editableTaskDateField] = taskWithEditedStatusApplied[taskDateField].formatAsDate(); + editableTask[editableTaskDateField] = ''; } } From 8b8f03f0b02d84aba9c226ec13fddb08c89bf587 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 19:33:21 +0600 Subject: [PATCH 16/27] refactor: . rename function and add jsdoc --- src/ui/StatusEditor.svelte | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index 3c7ef5ecb6..30d359c443 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -11,7 +11,20 @@ let statusSymbol = task.status.symbol; - function appleSauce( + /** + * Set the done or cancelled date field of the editable task. + * These fields are connected with the status. + * + * The date should be set in either of 2 cases: + * - the date field is empty and the status was set (set the date from the task with the applied status) + * - the date field is not empty but another status was set (clean the date field) + * + * @param editableTaskDateField + * @param isInStatus + * @param taskWithEditedStatusApplied + * @param taskDateField + */ + function setStatusRelatedDate( editableTaskDateField: keyof Pick, isInStatus: boolean, taskWithEditedStatusApplied: Task, @@ -43,13 +56,7 @@ const taskWithEditedStatusApplied = task.handleNewStatus(selectedStatus).pop(); if (taskWithEditedStatusApplied) { - // change the done date using XNOR logic: - // done date is empty and new status is DONE - // OR - // done date is filled and new status is not DONE - appleSauce('doneDate', selectedStatus.isCompleted(), taskWithEditedStatusApplied, 'done'); - - // same logic for cancelled date & CANCELLED status + setStatusRelatedDate('doneDate', selectedStatus.isCompleted(), taskWithEditedStatusApplied, 'done'); if ((editableTask.cancelledDate === '') === selectedStatus.isCancelled()) { editableTask.cancelledDate = taskWithEditedStatusApplied.cancelled.formatAsDate(); } From 47de533485d085d204288bd19a9035e309b29bb1 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 19:34:03 +0600 Subject: [PATCH 17/27] refactor: - reuse setStatusRelatedDate() --- src/ui/StatusEditor.svelte | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index 30d359c443..397319112a 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -57,9 +57,12 @@ if (taskWithEditedStatusApplied) { setStatusRelatedDate('doneDate', selectedStatus.isCompleted(), taskWithEditedStatusApplied, 'done'); - if ((editableTask.cancelledDate === '') === selectedStatus.isCancelled()) { - editableTask.cancelledDate = taskWithEditedStatusApplied.cancelled.formatAsDate(); - } + setStatusRelatedDate( + 'cancelledDate', + selectedStatus.isCancelled(), + taskWithEditedStatusApplied, + 'cancelled', + ); } }; From fd8c461c8726fed4d8e24bda8501c9b913621d35 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 19:39:38 +0600 Subject: [PATCH 18/27] test: . rename variable --- tests/ui/EditTask.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index 882b7257e5..1a3d66bf8b 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -168,9 +168,9 @@ async function renderTaskModalAndChangeStatus(line: string, newStatusSymbol: str * @param line * @param elementId - specifying the field to edit * @param newValue - the new value for the field - * @param newStatus - new Status value + * @param newStatusSymbol - new Status symbol value */ -async function renderChangeDateAndStatus(line: string, elementId: string, newValue: string, newStatus: string) { +async function renderChangeDateAndStatus(line: string, elementId: string, newValue: string, newStatusSymbol: string) { const task = taskFromLine({ line: line, path: '' }); const { waitForClose, onSubmit } = constructSerialisingOnSubmit(task); const { result, container } = renderAndCheckModal(task, onSubmit); @@ -180,7 +180,7 @@ async function renderChangeDateAndStatus(line: string, elementId: string, newVal const statusSelector = getAndCheckRenderedElement(container, 'status-type'); await fireEvent.change(statusSelector, { - target: { value: newStatus }, + target: { value: newStatusSymbol }, }); const submit = getAndCheckApplyButton(result); From a94e4d67b8b7d9073bce491404ad08181278d546 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 19:44:22 +0600 Subject: [PATCH 19/27] test: . extract variables --- tests/ui/EditTask.test.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index 1a3d66bf8b..601fe32efa 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -434,19 +434,23 @@ describe('Task editing', () => { }); it('should keep the done date and change status to done', async () => { + const line = '- [ ] input done date, change status to done and expect the date to be kept'; + const dateElementToChange = 'done'; + const dateValue = '2024-09-20'; + const newStatusSymbol = 'x'; + const expectedTaskAfterEdits = + '"- [x] input done date, change status to done and expect the date to be kept ✅ 2024-09-20"'; const { waitForClose, container, submit } = await renderChangeDateAndStatus( - '- [ ] input done date, change status to done and expect the date to be kept', - 'done', - '2024-09-20', - 'x', + line, + dateElementToChange, + dateValue, + newStatusSymbol, ); - expect(getElementValue(container, 'done')).toEqual('2024-09-20'); + expect(getElementValue(container, dateElementToChange)).toEqual(dateValue); submit.click(); - expect(await waitForClose).toMatchInlineSnapshot( - '"- [x] input done date, change status to done and expect the date to be kept ✅ 2024-09-20"', - ); + expect(await waitForClose).toMatchInlineSnapshot(expectedTaskAfterEdits); }); it('should create new instance of recurring task, with doneDate set to today', async () => { From 42b2f913b7a6821a14c46f40ac780ede07ffef47 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 19:45:07 +0600 Subject: [PATCH 20/27] test: - use toEqual() matcher --- tests/ui/EditTask.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index 601fe32efa..ff2f36d075 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -439,7 +439,7 @@ describe('Task editing', () => { const dateValue = '2024-09-20'; const newStatusSymbol = 'x'; const expectedTaskAfterEdits = - '"- [x] input done date, change status to done and expect the date to be kept ✅ 2024-09-20"'; + '- [x] input done date, change status to done and expect the date to be kept ✅ 2024-09-20'; const { waitForClose, container, submit } = await renderChangeDateAndStatus( line, dateElementToChange, @@ -450,7 +450,7 @@ describe('Task editing', () => { expect(getElementValue(container, dateElementToChange)).toEqual(dateValue); submit.click(); - expect(await waitForClose).toMatchInlineSnapshot(expectedTaskAfterEdits); + expect(await waitForClose).toEqual(expectedTaskAfterEdits); }); it('should create new instance of recurring task, with doneDate set to today', async () => { From 3de8c504b5e9e47b278b6fe280c99d30edc29b25 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 19:46:30 +0600 Subject: [PATCH 21/27] test: . extract testDateInputAndStatusChange() --- tests/ui/EditTask.test.ts | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index ff2f36d075..05410eaba8 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -433,6 +433,26 @@ describe('Task editing', () => { expect(await waitForClose).toMatchInlineSnapshot('"- [ ] expecting cancelled date to be removed"'); }); + async function testDateInputAndStatusChange( + line: string, + dateElementToChange: string, + dateValue: string, + newStatusSymbol: string, + expectedTaskAfterEdits: string, + ) { + const { waitForClose, container, submit } = await renderChangeDateAndStatus( + line, + dateElementToChange, + dateValue, + newStatusSymbol, + ); + + expect(getElementValue(container, dateElementToChange)).toEqual(dateValue); + + submit.click(); + expect(await waitForClose).toEqual(expectedTaskAfterEdits); + } + it('should keep the done date and change status to done', async () => { const line = '- [ ] input done date, change status to done and expect the date to be kept'; const dateElementToChange = 'done'; @@ -440,17 +460,13 @@ describe('Task editing', () => { const newStatusSymbol = 'x'; const expectedTaskAfterEdits = '- [x] input done date, change status to done and expect the date to be kept ✅ 2024-09-20'; - const { waitForClose, container, submit } = await renderChangeDateAndStatus( + await testDateInputAndStatusChange( line, dateElementToChange, dateValue, newStatusSymbol, + expectedTaskAfterEdits, ); - - expect(getElementValue(container, dateElementToChange)).toEqual(dateValue); - - submit.click(); - expect(await waitForClose).toEqual(expectedTaskAfterEdits); }); it('should create new instance of recurring task, with doneDate set to today', async () => { From 4d52017574d3f883b60fbd7621d42c957ec8d3bd Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 19:50:03 +0600 Subject: [PATCH 22/27] test: - convert it() to it.each() --- tests/ui/EditTask.test.ts | 41 +++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index 05410eaba8..fed4beda7d 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -453,21 +453,32 @@ describe('Task editing', () => { expect(await waitForClose).toEqual(expectedTaskAfterEdits); } - it('should keep the done date and change status to done', async () => { - const line = '- [ ] input done date, change status to done and expect the date to be kept'; - const dateElementToChange = 'done'; - const dateValue = '2024-09-20'; - const newStatusSymbol = 'x'; - const expectedTaskAfterEdits = - '- [x] input done date, change status to done and expect the date to be kept ✅ 2024-09-20'; - await testDateInputAndStatusChange( - line, - dateElementToChange, - dateValue, - newStatusSymbol, - expectedTaskAfterEdits, - ); - }); + it.each([ + [ + '- [ ] input done date, change status to done and expect the date to be kept', + 'done', + '2024-09-20', + 'x', + '- [x] input done date, change status to done and expect the date to be kept ✅ 2024-09-20', + ], + ])( + 'should keep the done date and change status to done', + async ( + line: string, + dateElementToChange: string, + dateValue: string, + newStatusSymbol: string, + expectedTaskAfterEdits: string, + ) => { + await testDateInputAndStatusChange( + line, + dateElementToChange, + dateValue, + newStatusSymbol, + expectedTaskAfterEdits, + ); + }, + ); it('should create new instance of recurring task, with doneDate set to today', async () => { updateSettings({ recurrenceOnNextLine: false }); From b3628f9638f78fd811fa008149ec4d12e35e9983 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 21:16:20 +0600 Subject: [PATCH 23/27] test: - add another test case --- tests/ui/EditTask.test.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index fed4beda7d..9d4edbc2a3 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -461,6 +461,15 @@ describe('Task editing', () => { 'x', '- [x] input done date, change status to done and expect the date to be kept ✅ 2024-09-20', ], + [ + '- [ ] input cancelled date, change status to cancelled and expect the date to be kept', + 'cancelled', + '2024-09-21', + '-', + // TODO the difference between the date in the modal and the saved one is a bug: + // https://github.com/obsidian-tasks-group/obsidian-tasks/issues/3089 + '- [-] input cancelled date, change status to cancelled and expect the date to be kept ❌ 2024-02-29', + ], ])( 'should keep the done date and change status to done', async ( From 9cf76cdf6ab666b7ac651eb4d99e54872b8f04d4 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 21:16:41 +0600 Subject: [PATCH 24/27] test: . document the tester --- tests/ui/EditTask.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index 9d4edbc2a3..c34047960b 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -433,6 +433,16 @@ describe('Task editing', () => { expect(await waitForClose).toMatchInlineSnapshot('"- [ ] expecting cancelled date to be removed"'); }); + /** + * Test opening task modal for a given line, changing a date to a value, changing the status, + * clicking Apply, verifying the final line. + * + * @param line + * @param dateElementToChange + * @param dateValue + * @param newStatusSymbol + * @param expectedTaskAfterEdits + */ async function testDateInputAndStatusChange( line: string, dateElementToChange: string, From 395f088d0b786a6d1a9bb4386291240ff8d7b52b Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 21:20:38 +0600 Subject: [PATCH 25/27] test: . update test description --- tests/ui/EditTask.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/EditTask.test.ts b/tests/ui/EditTask.test.ts index c34047960b..18f790e0aa 100644 --- a/tests/ui/EditTask.test.ts +++ b/tests/ui/EditTask.test.ts @@ -481,7 +481,7 @@ describe('Task editing', () => { '- [-] input cancelled date, change status to cancelled and expect the date to be kept ❌ 2024-02-29', ], ])( - 'should keep the done date and change status to done', + 'for "%s" task, change %s date to %s and status to %s', async ( line: string, dateElementToChange: string, From cfa30a694c2d1cc6d4acbc5aad50501edf675ad7 Mon Sep 17 00:00:00 2001 From: Ilyas Landikov Date: Sat, 21 Sep 2024 21:31:28 +0600 Subject: [PATCH 26/27] refactor: - replace setStatusRelatedDate() with simpler implementation --- src/ui/StatusEditor.svelte | 45 +++++++++++++++----------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/src/ui/StatusEditor.svelte b/src/ui/StatusEditor.svelte index 397319112a..451fc143fd 100644 --- a/src/ui/StatusEditor.svelte +++ b/src/ui/StatusEditor.svelte @@ -1,4 +1,5 @@