From d95d684b57b4132057c6353c5b6b5d0a76683f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 12:58:48 +0200 Subject: [PATCH 01/25] Finished domain model --- domain-model.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 domain-model.md diff --git a/domain-model.md b/domain-model.md new file mode 100644 index 00000000..dfbace85 --- /dev/null +++ b/domain-model.md @@ -0,0 +1,24 @@ +# Domain Model + +|Classes|Method/Properties|Scenario|Outputs| +|-------|-----------------|--------|-------| +|`TodoList`|`AddTask(string name)`|Add task with name to todo list| int ID of new task| +|`TodoList`|`GetAllTasks()`|Provide all tasks in todo list | List | +|`Task`| `ToggleComplete()` | Toggle status from complete to incomplete or incomplete to complete| bool | +|`TodoList`| `GetCompleteTasks()`| Provide all complete tasks in todo list | List| +|`TodoList`| `GetIncompleteTasks()`| Provide all incomplete tasks in todo list | List| +|`TodoList`| `GetTaskByName(string name)`| Search for Task with given name | List, provide message if not found | +|`TodoList`| `RemoveTask(string name)` | Remove task with given name from TodoList | bool | +|`TodoList`| `GetAllTasksSortedByName(bool useAscendingOrder)` | Return sorted version of tasks by name, either ascending or descending alphabetical order, to user | Sorted List| +|`TodoList`| `GiveTaskPriority(name)` | Add priority (low, medium, high) to a given task | string current priority | +|`TodoList`| `SortTasksByPriority()` | Return sorted version of tasks sorted by priority | Sorted List | +|`TodoList`| `GetTaskByID(int id)` | Provide task with given id | Task | +|`TodoList`| `UpdateTaskName(int id, string newName)` | Update the name of a task with given id | bool | +|`TodoList`| `UpdateTaskStatus(int id)` | Toggle the status of task with given ID | bool | +|`TodoList`| `GetAllTaskTimeCreated()` | Provide all tasks along with time of creation | (List, datetime) | +|`TodoList`| `GetAllTaskTimeCompleted()` | Provide all tasks along with time of completion | (List, datetime) | +|`TodoList`| `GetTaskWithLongestCompletionTime()` | Provide the task with the longest completion time | (, completion time) | +|`TodoList`| `GetTaskWithShortestCompletionTime()` | Provide the task with the shortest completion time | (, completion time) | +|`TodoList`| `GetTasksByCompletionTime(int numDaysToComplete)` | Provide all tasks with completion time longer than given time | List | +|`Task`| `SetTaskCategory(string name, string category)` | Set category of task | bool | +|`TodoList`| `GetTasksByCategory(string category)` | Get all tasks matching the given category | List | \ No newline at end of file From 4349e53e33dffc775ce5920733a9a593ec2d4d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 13:31:17 +0200 Subject: [PATCH 02/25] Completes first two user stories and updates domain model --- domain-model.md | 2 +- tdd-todo-list.CSharp.Main/Task.cs | 28 ++++++++++++++++++++++++++ tdd-todo-list.CSharp.Main/ToDoList.cs | 12 +++++++++++ tdd-todo-list.CSharp.Test/CoreTests.cs | 27 ++++++++++++++++++++++--- tdd-todo-list.sln | 1 + 5 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 tdd-todo-list.CSharp.Main/Task.cs diff --git a/domain-model.md b/domain-model.md index dfbace85..4d190b5b 100644 --- a/domain-model.md +++ b/domain-model.md @@ -3,7 +3,7 @@ |Classes|Method/Properties|Scenario|Outputs| |-------|-----------------|--------|-------| |`TodoList`|`AddTask(string name)`|Add task with name to todo list| int ID of new task| -|`TodoList`|`GetAllTasks()`|Provide all tasks in todo list | List | +|`TodoList`|`TodoList.Tasks`|Provide all tasks in todo list | List | |`Task`| `ToggleComplete()` | Toggle status from complete to incomplete or incomplete to complete| bool | |`TodoList`| `GetCompleteTasks()`| Provide all complete tasks in todo list | List| |`TodoList`| `GetIncompleteTasks()`| Provide all incomplete tasks in todo list | List| diff --git a/tdd-todo-list.CSharp.Main/Task.cs b/tdd-todo-list.CSharp.Main/Task.cs new file mode 100644 index 00000000..47ef694b --- /dev/null +++ b/tdd-todo-list.CSharp.Main/Task.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace tdd_todo_list.CSharp.Main +{ + public class Task + { + private string _name; + private int _id; + private bool isCompleted = false; + private string priority = "low"; + private string category = String.Empty; + private DateTime timeCreated; + private DateTime timeCompleted; + + public Task(int count, string name) + { + _id = count; + _name = name; + } + + public string Name { get { return _name; } } + public int ID { get { return _id; } } + } +} diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 835cb600..b355953a 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -8,5 +8,17 @@ namespace tdd_todo_list.CSharp.Main { public class TodoList { + private List _tasks = new List(); + private int _taskCount = 0; + + public List Tasks { get { return _tasks; } } + public int TaskCount { get { return _taskCount; } } + + public void AddTask(string name) + { + Task newTask = new Task(_taskCount, name); + _tasks.Add(newTask); + _taskCount++; + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 084cce19..443577bd 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -8,10 +8,31 @@ public class CoreTests { [Test] - public void FirstTest() + public void AddTaskTest() { - TodoList core = new TodoList(); - Assert.Pass(); + TodoList todoList = new TodoList(); + string taskName = "Homework"; + + todoList.AddTask(taskName); + + Assert.That(todoList.Tasks[0].Name, Is.EqualTo(taskName)); + Assert.That(todoList.Tasks[0].ID, Is.EqualTo(0)); + Assert.That(todoList.TaskCount, Is.EqualTo(1)); + } + + [Test] + public void GetAllTasksTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + + Assert.That(todoList.Tasks.Count, Is.EqualTo(2)); } + + [Test] } } \ No newline at end of file diff --git a/tdd-todo-list.sln b/tdd-todo-list.sln index 66d24763..2a5e0bbd 100644 --- a/tdd-todo-list.sln +++ b/tdd-todo-list.sln @@ -10,6 +10,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{663B0373-6031-46F8-ADD5-9AF01A5E82D5}" ProjectSection(SolutionItems) = preProject .github\workflows\core-criteria.yml = .github\workflows\core-criteria.yml + domain-model.md = domain-model.md .github\workflows\extension-criteria.yml = .github\workflows\extension-criteria.yml README.md = README.md EndProjectSection From 8046607aa7f1d9d906119bef856a6fbc5f89e5e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 13:34:58 +0200 Subject: [PATCH 03/25] Small bug fix --- tdd-todo-list.CSharp.Test/CoreTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 443577bd..4a2301df 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -32,7 +32,5 @@ public void GetAllTasksTest() Assert.That(todoList.Tasks.Count, Is.EqualTo(2)); } - - [Test] } } \ No newline at end of file From 0a46f54efa7ae474b54224fdd34e229ecccc309b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 13:54:14 +0200 Subject: [PATCH 04/25] Change list of tasks to a dictionary --- domain-model.md | 2 +- tdd-todo-list.CSharp.Main/ToDoList.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/domain-model.md b/domain-model.md index 4d190b5b..b6d3546b 100644 --- a/domain-model.md +++ b/domain-model.md @@ -3,7 +3,7 @@ |Classes|Method/Properties|Scenario|Outputs| |-------|-----------------|--------|-------| |`TodoList`|`AddTask(string name)`|Add task with name to todo list| int ID of new task| -|`TodoList`|`TodoList.Tasks`|Provide all tasks in todo list | List | +|`TodoList`|`TodoList.Tasks`|Provide all tasks in todo list | Dictionary | |`Task`| `ToggleComplete()` | Toggle status from complete to incomplete or incomplete to complete| bool | |`TodoList`| `GetCompleteTasks()`| Provide all complete tasks in todo list | List| |`TodoList`| `GetIncompleteTasks()`| Provide all incomplete tasks in todo list | List| diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index b355953a..1726646a 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -8,16 +8,16 @@ namespace tdd_todo_list.CSharp.Main { public class TodoList { - private List _tasks = new List(); + private Dictionary _tasks = new Dictionary(); private int _taskCount = 0; - public List Tasks { get { return _tasks; } } + public Dictionary Tasks { get { return _tasks; } } public int TaskCount { get { return _taskCount; } } public void AddTask(string name) { Task newTask = new Task(_taskCount, name); - _tasks.Add(newTask); + _tasks.Add(_taskCount, newTask); _taskCount++; } } From 832c9e8df2be88ade1da4eae2eae11137c8b4843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 14:01:27 +0200 Subject: [PATCH 05/25] Minor adjustments --- domain-model.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/domain-model.md b/domain-model.md index b6d3546b..7f03c2fa 100644 --- a/domain-model.md +++ b/domain-model.md @@ -4,21 +4,21 @@ |-------|-----------------|--------|-------| |`TodoList`|`AddTask(string name)`|Add task with name to todo list| int ID of new task| |`TodoList`|`TodoList.Tasks`|Provide all tasks in todo list | Dictionary | -|`Task`| `ToggleComplete()` | Toggle status from complete to incomplete or incomplete to complete| bool | -|`TodoList`| `GetCompleteTasks()`| Provide all complete tasks in todo list | List| -|`TodoList`| `GetIncompleteTasks()`| Provide all incomplete tasks in todo list | List| -|`TodoList`| `GetTaskByName(string name)`| Search for Task with given name | List, provide message if not found | -|`TodoList`| `RemoveTask(string name)` | Remove task with given name from TodoList | bool | -|`TodoList`| `GetAllTasksSortedByName(bool useAscendingOrder)` | Return sorted version of tasks by name, either ascending or descending alphabetical order, to user | Sorted List| -|`TodoList`| `GiveTaskPriority(name)` | Add priority (low, medium, high) to a given task | string current priority | -|`TodoList`| `SortTasksByPriority()` | Return sorted version of tasks sorted by priority | Sorted List | -|`TodoList`| `GetTaskByID(int id)` | Provide task with given id | Task | -|`TodoList`| `UpdateTaskName(int id, string newName)` | Update the name of a task with given id | bool | -|`TodoList`| `UpdateTaskStatus(int id)` | Toggle the status of task with given ID | bool | -|`TodoList`| `GetAllTaskTimeCreated()` | Provide all tasks along with time of creation | (List, datetime) | -|`TodoList`| `GetAllTaskTimeCompleted()` | Provide all tasks along with time of completion | (List, datetime) | -|`TodoList`| `GetTaskWithLongestCompletionTime()` | Provide the task with the longest completion time | (, completion time) | -|`TodoList`| `GetTaskWithShortestCompletionTime()` | Provide the task with the shortest completion time | (, completion time) | -|`TodoList`| `GetTasksByCompletionTime(int numDaysToComplete)` | Provide all tasks with completion time longer than given time | List | +|`TodoList`|`ToggleComplete(string name)` | Toggle status of give task from complete to incomplete or incomplete to complete| bool | +|`TodoList`|`GetCompleteTasks()`| Provide all complete tasks in todo list | List| +|`TodoList`|`GetIncompleteTasks()`| Provide all incomplete tasks in todo list | List| +|`TodoList`|`GetTaskByName(string name)`| Search for Task with given name | List, provide message if not found | +|`TodoList`|`RemoveTask(string name)` | Remove task with given name from TodoList | bool | +|`TodoList`|`GetAllTasksSortedByName(bool useAscendingOrder)` | Return sorted version of tasks by name, either ascending or descending alphabetical order, to user | Sorted List| +|`TodoList`|`GiveTaskPriority(name)` | Add priority (low, medium, high) to a given task | string current priority | +|`TodoList`|`SortTasksByPriority()` | Return sorted version of tasks sorted by priority | Sorted List | +|`TodoList`|`GetTaskByID(int id)` | Provide task with given id | Task | +|`TodoList`|`UpdateTaskName(int id, string newName)` | Update the name of a task with given id | bool | +|`TodoList`|`UpdateTaskStatus(int id)` | Toggle the status of task with given ID | bool | +|`TodoList`|`GetAllTaskTimeCreated()` | Provide all tasks along with time of creation | (List, datetime) | +|`TodoList`|`GetAllTaskTimeCompleted()` | Provide all tasks along with time of completion | (List, datetime) | +|`TodoList`|`GetTaskWithLongestCompletionTime()` | Provide the task with the longest completion time | (, completion time) | +|`TodoList`|`GetTaskWithShortestCompletionTime()` | Provide the task with the shortest completion time | (, completion time) | +|`TodoList`|`GetTasksByCompletionTime(int numDaysToComplete)` | Provide all tasks with completion time longer than given time | List | |`Task`| `SetTaskCategory(string name, string category)` | Set category of task | bool | -|`TodoList`| `GetTasksByCategory(string category)` | Get all tasks matching the given category | List | \ No newline at end of file +|`TodoList`|`GetTasksByCategory(string category)` | Get all tasks matching the given category | List | \ No newline at end of file From b26a59d01d7366f8a05edb3d19775b4ada543f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 14:02:10 +0200 Subject: [PATCH 06/25] Adds tests for ToggleComplete --- tdd-todo-list.CSharp.Test/CoreTests.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 4a2301df..614bca26 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -32,5 +32,20 @@ public void GetAllTasksTest() Assert.That(todoList.Tasks.Count, Is.EqualTo(2)); } + + [Test] + public void ToggleCompleteTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + + todoList.ToggleComplete(taskName1); + + Assert.That(todoList.Tasks[0].IsCompleted, Is.True); + Assert.That(todoList.Tasks[1].IsCompleted, Is.False); + } } } \ No newline at end of file From 028a64757c8cc3d447baca535e0d55a3cdc36a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 14:14:11 +0200 Subject: [PATCH 07/25] Implements complete status for tasks --- tdd-todo-list.CSharp.Main/Task.cs | 11 ++++++----- tdd-todo-list.CSharp.Test/CoreTests.cs | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tdd-todo-list.CSharp.Main/Task.cs b/tdd-todo-list.CSharp.Main/Task.cs index 47ef694b..6d4efee8 100644 --- a/tdd-todo-list.CSharp.Main/Task.cs +++ b/tdd-todo-list.CSharp.Main/Task.cs @@ -10,11 +10,11 @@ public class Task { private string _name; private int _id; - private bool isCompleted = false; - private string priority = "low"; - private string category = String.Empty; - private DateTime timeCreated; - private DateTime timeCompleted; + private bool _isCompleted = false; + private string _priority = "low"; + private string _category = String.Empty; + private DateTime _timeCreated; + private DateTime _timeCompleted; public Task(int count, string name) { @@ -24,5 +24,6 @@ public Task(int count, string name) public string Name { get { return _name; } } public int ID { get { return _id; } } + public bool IsCompleted { get { return _isCompleted; } set { _isCompleted = value; } } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 614bca26..e7065643 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -42,7 +42,7 @@ public void ToggleCompleteTest() todoList.AddTask(taskName1); todoList.AddTask(taskName2); - todoList.ToggleComplete(taskName1); + todoList.ToggleComplete(0); Assert.That(todoList.Tasks[0].IsCompleted, Is.True); Assert.That(todoList.Tasks[1].IsCompleted, Is.False); From 88e54058375cdfa2e7e5a3f5691c505c5ff4f13f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 14:29:31 +0200 Subject: [PATCH 08/25] Adds tests and implementation for getting all complete and incomplete tasks --- tdd-todo-list.CSharp.Main/ToDoList.cs | 30 ++++++++++++++++ tdd-todo-list.CSharp.Test/CoreTests.cs | 47 ++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 1726646a..62fc6c9e 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -20,5 +20,35 @@ public void AddTask(string name) _tasks.Add(_taskCount, newTask); _taskCount++; } + + public void ToggleComplete(int taskID) + { + _tasks[taskID].IsCompleted = !_tasks[taskID].IsCompleted; + } + + public List GetCompleteTasks() + { + List completeTasks = new List(); + foreach (Task task in _tasks.Values) { + if (task.IsCompleted) + { + completeTasks.Add(task); + } + } + return completeTasks; + } + + public List GetIncompleteTasks() + { + List incompleteTasks = new List(); + foreach (Task task in _tasks.Values) + { + if (!task.IsCompleted) + { + incompleteTasks.Add(task); + } + } + return incompleteTasks; + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index e7065643..3769b195 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -1,5 +1,8 @@ using tdd_todo_list.CSharp.Main; using NUnit.Framework; +using System.Security.Cryptography.X509Certificates; + +using Task = tdd_todo_list.CSharp.Main.Task; namespace tdd_todo_list.CSharp.Test { @@ -47,5 +50,49 @@ public void ToggleCompleteTest() Assert.That(todoList.Tasks[0].IsCompleted, Is.True); Assert.That(todoList.Tasks[1].IsCompleted, Is.False); } + + [Test] + public void GetCompleteTasksTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + string taskName3 = "Dishes"; + string taskName4 = "Run"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + todoList.AddTask(taskName3); + todoList.AddTask(taskName4); + + todoList.ToggleComplete(0); + todoList.ToggleComplete(3); + + List completeTaskList = todoList.GetCompleteTasks(); + + Assert.That(completeTaskList.All(task => task.IsCompleted), Is.True); + Assert.That(completeTaskList.Count == 2); + } + + [Test] + public void GetInompleteTasksTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + string taskName3 = "Dishes"; + string taskName4 = "Run"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + todoList.AddTask(taskName3); + todoList.AddTask(taskName4); + + todoList.ToggleComplete(0); + todoList.ToggleComplete(3); + + List incompleteTaskList = todoList.GetIncompleteTasks(); + + Assert.That(incompleteTaskList.All(task => task.IsCompleted), Is.False); + Assert.That(incompleteTaskList.Count == 2); + } } } \ No newline at end of file From 77763a5602caee0f7f9c40a28fd734073767df55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 14:35:06 +0200 Subject: [PATCH 09/25] Minor updates --- domain-model.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-model.md b/domain-model.md index 7f03c2fa..92a4f049 100644 --- a/domain-model.md +++ b/domain-model.md @@ -4,10 +4,10 @@ |-------|-----------------|--------|-------| |`TodoList`|`AddTask(string name)`|Add task with name to todo list| int ID of new task| |`TodoList`|`TodoList.Tasks`|Provide all tasks in todo list | Dictionary | -|`TodoList`|`ToggleComplete(string name)` | Toggle status of give task from complete to incomplete or incomplete to complete| bool | +|`TodoList`|`ToggleComplete(string name)` | Toggle status of give task from complete to incomplete or incomplete to complete| | |`TodoList`|`GetCompleteTasks()`| Provide all complete tasks in todo list | List| |`TodoList`|`GetIncompleteTasks()`| Provide all incomplete tasks in todo list | List| -|`TodoList`|`GetTaskByName(string name)`| Search for Task with given name | List, provide message if not found | +|`TodoList`|`GetTaskByName(string name)`| Search for Task with given name | Task, provide message if not found | |`TodoList`|`RemoveTask(string name)` | Remove task with given name from TodoList | bool | |`TodoList`|`GetAllTasksSortedByName(bool useAscendingOrder)` | Return sorted version of tasks by name, either ascending or descending alphabetical order, to user | Sorted List| |`TodoList`|`GiveTaskPriority(name)` | Add priority (low, medium, high) to a given task | string current priority | From ad5a4955761afb129f29cf9e956c8b5c0307329e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 14:47:26 +0200 Subject: [PATCH 10/25] Tests and implements search by name --- tdd-todo-list.CSharp.Main/ToDoList.cs | 20 ++++++++++++++++++++ tdd-todo-list.CSharp.Test/CoreTests.cs | 23 ++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 62fc6c9e..e60526fd 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -50,5 +50,25 @@ public List GetIncompleteTasks() } return incompleteTasks; } + + public Task? GetTaskByName(string taskName) + { + Task? resultTask = null; + foreach (KeyValuePair task in _tasks) + { + if (task.Value.Name == taskName) + { + resultTask = task.Value; + break; + } + } + + if (resultTask == null) + { + Console.WriteLine($"Task {taskName} not found"); + } + + return resultTask; + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 3769b195..ee5956b7 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -74,7 +74,7 @@ public void GetCompleteTasksTest() } [Test] - public void GetInompleteTasksTest() + public void GetIncompleteTasksTest() { TodoList todoList = new TodoList(); string taskName1 = "Homework"; @@ -94,5 +94,26 @@ public void GetInompleteTasksTest() Assert.That(incompleteTaskList.All(task => task.IsCompleted), Is.False); Assert.That(incompleteTaskList.Count == 2); } + + [Test] + public void GetTaskByNameTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + string taskName3 = "Dishes"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + todoList.AddTask(taskName3); + + string nonExistingTaskName = "Run"; + + Task? existingTask = todoList.GetTaskByName(taskName1); + Task? nonExistingTask = todoList.GetTaskByName(nonExistingTaskName); + + Assert.That(existingTask.Name, Is.EqualTo(taskName1)); + Assert.That(nonExistingTask, Is.Null); + } + } } \ No newline at end of file From 3a12959190287362c9ce056cdae3cb89f79f84dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 15:46:06 +0200 Subject: [PATCH 11/25] Tests and implements task removal --- tdd-todo-list.CSharp.Main/ToDoList.cs | 13 +++++++++++++ tdd-todo-list.CSharp.Test/CoreTests.cs | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index e60526fd..813a118a 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -70,5 +70,18 @@ public List GetIncompleteTasks() return resultTask; } + + public bool RemoveTask(string taskName) + { + Task? task = GetTaskByName(taskName); + + if (task == null) + { + return false; + } + + return _tasks.Remove(task.ID); + + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index ee5956b7..0876b4bd 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -115,5 +115,24 @@ public void GetTaskByNameTest() Assert.That(nonExistingTask, Is.Null); } + [Test] + public void RemoveTaskName() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + + string nonExistingTaskName = "Run"; + + bool wasRemoved1 = todoList.RemoveTask(taskName1); + bool wasRemoved2 = todoList.RemoveTask(nonExistingTaskName); + + Assert.That(wasRemoved1, Is.True); + Assert.That(wasRemoved2, Is.False); + + } + } } \ No newline at end of file From 2383828783f34d572a0485f34893b3ac3028b00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 16:23:19 +0200 Subject: [PATCH 12/25] Tests and implements sorting (ascending and descending) --- tdd-todo-list.CSharp.Main/ToDoList.cs | 10 ++++++++++ tdd-todo-list.CSharp.Test/CoreTests.cs | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 813a118a..2df2d8b4 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -83,5 +83,15 @@ public bool RemoveTask(string taskName) return _tasks.Remove(task.ID); } + + public List GetAllTasksSortedByName(bool useAscendingOrder) + { + if (useAscendingOrder) + { + return _tasks.Values.OrderBy(task => task.Name).ToList(); + } + return _tasks.Values.OrderByDescending(task => task.Name).ToList(); + + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 0876b4bd..77347983 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -134,5 +134,29 @@ public void RemoveTaskName() } + [Test] + public void GetAllTasksSortedByNameTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + string taskName3 = "Dishes"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + todoList.AddTask(taskName3); + + bool useAscendingOrder = true; + + List sortedTaskAscending = todoList.GetAllTasksSortedByName(useAscendingOrder); + List sortedTaskDescending = todoList.GetAllTasksSortedByName(!useAscendingOrder); + + Assert.That(sortedTaskAscending[0].Name == "Dishes"); + Assert.That(sortedTaskAscending[1].Name == "Homework"); + Assert.That(sortedTaskAscending[2].Name == "Laundry"); + + Assert.That(sortedTaskDescending[0].Name == "Laundry"); + Assert.That(sortedTaskDescending[1].Name == "Homework"); + Assert.That(sortedTaskDescending[2].Name == "Dishes"); + } } } \ No newline at end of file From 58d289de9a959d7d3fd101ecc410b19f1c35bc20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 16:35:20 +0200 Subject: [PATCH 13/25] Tests and implements giving priority to specified task --- domain-model.md | 2 +- tdd-todo-list.CSharp.Main/Task.cs | 1 + tdd-todo-list.CSharp.Main/ToDoList.cs | 11 +++++++++++ tdd-todo-list.CSharp.Test/CoreTests.cs | 23 +++++++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/domain-model.md b/domain-model.md index 92a4f049..88099a4d 100644 --- a/domain-model.md +++ b/domain-model.md @@ -10,7 +10,7 @@ |`TodoList`|`GetTaskByName(string name)`| Search for Task with given name | Task, provide message if not found | |`TodoList`|`RemoveTask(string name)` | Remove task with given name from TodoList | bool | |`TodoList`|`GetAllTasksSortedByName(bool useAscendingOrder)` | Return sorted version of tasks by name, either ascending or descending alphabetical order, to user | Sorted List| -|`TodoList`|`GiveTaskPriority(name)` | Add priority (low, medium, high) to a given task | string current priority | +|`TodoList`|`GiveTaskPriority(string name, string priority)` | Add priority (low, medium, high) to a given task | bool | |`TodoList`|`SortTasksByPriority()` | Return sorted version of tasks sorted by priority | Sorted List | |`TodoList`|`GetTaskByID(int id)` | Provide task with given id | Task | |`TodoList`|`UpdateTaskName(int id, string newName)` | Update the name of a task with given id | bool | diff --git a/tdd-todo-list.CSharp.Main/Task.cs b/tdd-todo-list.CSharp.Main/Task.cs index 6d4efee8..cac42c6f 100644 --- a/tdd-todo-list.CSharp.Main/Task.cs +++ b/tdd-todo-list.CSharp.Main/Task.cs @@ -25,5 +25,6 @@ public Task(int count, string name) public string Name { get { return _name; } } public int ID { get { return _id; } } public bool IsCompleted { get { return _isCompleted; } set { _isCompleted = value; } } + public string Priority { get { return _priority; } set { _priority = value; } } } } diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 2df2d8b4..7c88f037 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -93,5 +93,16 @@ public List GetAllTasksSortedByName(bool useAscendingOrder) return _tasks.Values.OrderByDescending(task => task.Name).ToList(); } + + public bool GiveTaskPriority(string taskName, string priority) + { + Task? task = GetTaskByName(taskName); + if (task == null) + { + return false; + } + task.Priority = priority; + return true; + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 77347983..0bf38342 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -158,5 +158,28 @@ public void GetAllTasksSortedByNameTest() Assert.That(sortedTaskDescending[1].Name == "Homework"); Assert.That(sortedTaskDescending[2].Name == "Dishes"); } + + [Test] + public void GiveTaskPriorityTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + string taskName3 = "Dishes"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + todoList.AddTask(taskName3); + + todoList.GiveTaskPriority(taskName1, "medium"); + todoList.GiveTaskPriority(taskName2, "low"); + todoList.GiveTaskPriority(taskName3, "high"); + + bool result = todoList.GiveTaskPriority("Run", "high"); + + Assert.That(todoList.Tasks[0].Priority == "medium"); + Assert.That(todoList.Tasks[1].Priority == "low"); + Assert.That(todoList.Tasks[2].Priority == "high"); + Assert.That(result, Is.False); + } } } \ No newline at end of file From 6ebd276d3beddcb40ab3fb58ee541e8e970674c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Thu, 7 Aug 2025 16:45:28 +0200 Subject: [PATCH 14/25] Tests and implements sorting by priority, and switch to numeric priority representation --- domain-model.md | 2 +- tdd-todo-list.CSharp.Main/Task.cs | 4 +-- tdd-todo-list.CSharp.Main/ToDoList.cs | 7 ++++- tdd-todo-list.CSharp.Test/CoreTests.cs | 43 ++++++++++++++++++++------ 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/domain-model.md b/domain-model.md index 88099a4d..684beafe 100644 --- a/domain-model.md +++ b/domain-model.md @@ -10,7 +10,7 @@ |`TodoList`|`GetTaskByName(string name)`| Search for Task with given name | Task, provide message if not found | |`TodoList`|`RemoveTask(string name)` | Remove task with given name from TodoList | bool | |`TodoList`|`GetAllTasksSortedByName(bool useAscendingOrder)` | Return sorted version of tasks by name, either ascending or descending alphabetical order, to user | Sorted List| -|`TodoList`|`GiveTaskPriority(string name, string priority)` | Add priority (low, medium, high) to a given task | bool | +|`TodoList`|`GiveTaskPriority(string name, int priority)` | Add priority (1, 2, 3) to a given task | bool | |`TodoList`|`SortTasksByPriority()` | Return sorted version of tasks sorted by priority | Sorted List | |`TodoList`|`GetTaskByID(int id)` | Provide task with given id | Task | |`TodoList`|`UpdateTaskName(int id, string newName)` | Update the name of a task with given id | bool | diff --git a/tdd-todo-list.CSharp.Main/Task.cs b/tdd-todo-list.CSharp.Main/Task.cs index cac42c6f..b015c24e 100644 --- a/tdd-todo-list.CSharp.Main/Task.cs +++ b/tdd-todo-list.CSharp.Main/Task.cs @@ -11,7 +11,7 @@ public class Task private string _name; private int _id; private bool _isCompleted = false; - private string _priority = "low"; + private int _priority = 3; private string _category = String.Empty; private DateTime _timeCreated; private DateTime _timeCompleted; @@ -25,6 +25,6 @@ public Task(int count, string name) public string Name { get { return _name; } } public int ID { get { return _id; } } public bool IsCompleted { get { return _isCompleted; } set { _isCompleted = value; } } - public string Priority { get { return _priority; } set { _priority = value; } } + public int Priority { get { return _priority; } set { _priority = value; } } } } diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 7c88f037..2d207806 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -94,7 +94,7 @@ public List GetAllTasksSortedByName(bool useAscendingOrder) } - public bool GiveTaskPriority(string taskName, string priority) + public bool GiveTaskPriority(string taskName, int priority) { Task? task = GetTaskByName(taskName); if (task == null) @@ -104,5 +104,10 @@ public bool GiveTaskPriority(string taskName, string priority) task.Priority = priority; return true; } + + public List SortTasksByPriority() + { + return _tasks.Values.OrderBy(task => task.Priority).ToList(); + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 0bf38342..1809bef1 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -1,7 +1,7 @@ -using tdd_todo_list.CSharp.Main; -using NUnit.Framework; +using NUnit.Framework; +using NUnit.Framework.Interfaces; using System.Security.Cryptography.X509Certificates; - +using tdd_todo_list.CSharp.Main; using Task = tdd_todo_list.CSharp.Main.Task; namespace tdd_todo_list.CSharp.Test @@ -162,6 +162,7 @@ public void GetAllTasksSortedByNameTest() [Test] public void GiveTaskPriorityTest() { + // Note: Priority from highest to lowest 1, 2, 3 TodoList todoList = new TodoList(); string taskName1 = "Homework"; string taskName2 = "Laundry"; @@ -170,16 +171,38 @@ public void GiveTaskPriorityTest() todoList.AddTask(taskName2); todoList.AddTask(taskName3); - todoList.GiveTaskPriority(taskName1, "medium"); - todoList.GiveTaskPriority(taskName2, "low"); - todoList.GiveTaskPriority(taskName3, "high"); + todoList.GiveTaskPriority(taskName1, 2); + todoList.GiveTaskPriority(taskName2, 3); + todoList.GiveTaskPriority(taskName3, 1); - bool result = todoList.GiveTaskPriority("Run", "high"); + bool result = todoList.GiveTaskPriority("Run", 1); - Assert.That(todoList.Tasks[0].Priority == "medium"); - Assert.That(todoList.Tasks[1].Priority == "low"); - Assert.That(todoList.Tasks[2].Priority == "high"); + Assert.That(todoList.Tasks[0].Priority == 2); + Assert.That(todoList.Tasks[1].Priority == 3); + Assert.That(todoList.Tasks[2].Priority == 1); Assert.That(result, Is.False); } + + [Test] + public void SortTasksByPriorityTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + string taskName3 = "Dishes"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + todoList.AddTask(taskName3); + + todoList.GiveTaskPriority(taskName1, 2); + todoList.GiveTaskPriority(taskName2, 3); + todoList.GiveTaskPriority(taskName3, 1); + + List sortedTasks = todoList.SortTasksByPriority(); + + Assert.That(sortedTasks[0].Name, Is.EqualTo("Dishes")); + Assert.That(sortedTasks[1].Name, Is.EqualTo("Homework")); + Assert.That(sortedTasks[2].Name, Is.EqualTo("Laundry")); + } } } \ No newline at end of file From 9cb3aa8b7251634f8dd39bf98804e13cfe1dd0b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 08:38:41 +0200 Subject: [PATCH 15/25] Tests and implements retrieval by ID --- tdd-todo-list.CSharp.Main/ToDoList.cs | 5 +++++ tdd-todo-list.CSharp.Test/CoreTests.cs | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 2d207806..9304b865 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -109,5 +109,10 @@ public List SortTasksByPriority() { return _tasks.Values.OrderBy(task => task.Priority).ToList(); } + + public Task GetTaskByID(int taskID) + { + return _tasks[taskID]; + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 1809bef1..6fc578d3 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -204,5 +204,29 @@ public void SortTasksByPriorityTest() Assert.That(sortedTasks[1].Name, Is.EqualTo("Homework")); Assert.That(sortedTasks[2].Name, Is.EqualTo("Laundry")); } + + [Test] + public void GetTaskByIDTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + string taskName3 = "Dishes"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + todoList.AddTask(taskName3); + + todoList.RemoveTask("Laundry"); + + int task1ID = 0; + int task3ID = 2; + + Task task1 = todoList.GetTaskByID(task1ID); + Task task3 = todoList.GetTaskByID(task3ID); + + Assert.That(task1.ID, Is.EqualTo(0)); + Assert.That(task3.ID, Is.EqualTo(2)); + + } } } \ No newline at end of file From 271c2f0afc2c5f055413e13385a53d6af2ad6060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 08:41:00 +0200 Subject: [PATCH 16/25] Adds support for nonexisting ID --- tdd-todo-list.CSharp.Main/ToDoList.cs | 8 ++++++-- tdd-todo-list.CSharp.Test/CoreTests.cs | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 9304b865..d0a2568f 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -110,9 +110,13 @@ public List SortTasksByPriority() return _tasks.Values.OrderBy(task => task.Priority).ToList(); } - public Task GetTaskByID(int taskID) + public Task? GetTaskByID(int taskID) { - return _tasks[taskID]; + if (_tasks.ContainsKey(taskID)) + { + return _tasks[taskID]; + } + return null; } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 6fc578d3..8569319f 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -219,13 +219,17 @@ public void GetTaskByIDTest() todoList.RemoveTask("Laundry"); int task1ID = 0; + int task2ID = 1; int task3ID = 2; - Task task1 = todoList.GetTaskByID(task1ID); - Task task3 = todoList.GetTaskByID(task3ID); + Task? task1 = todoList.GetTaskByID(task1ID); + Task? task3 = todoList.GetTaskByID(task3ID); + + Task? task2 = todoList.GetTaskByID(task2ID); Assert.That(task1.ID, Is.EqualTo(0)); Assert.That(task3.ID, Is.EqualTo(2)); + Assert.That(task2, Is.Null); } } From 28f9ca5ef826938a76d11dadc2a8b34b04378539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 08:53:28 +0200 Subject: [PATCH 17/25] Tests and implements name update --- tdd-todo-list.CSharp.Main/Task.cs | 2 +- tdd-todo-list.CSharp.Main/ToDoList.cs | 10 ++++++++++ tdd-todo-list.CSharp.Test/CoreTests.cs | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tdd-todo-list.CSharp.Main/Task.cs b/tdd-todo-list.CSharp.Main/Task.cs index b015c24e..37d3d099 100644 --- a/tdd-todo-list.CSharp.Main/Task.cs +++ b/tdd-todo-list.CSharp.Main/Task.cs @@ -22,7 +22,7 @@ public Task(int count, string name) _name = name; } - public string Name { get { return _name; } } + public string Name { get { return _name; } set { _name = value; } } public int ID { get { return _id; } } public bool IsCompleted { get { return _isCompleted; } set { _isCompleted = value; } } public int Priority { get { return _priority; } set { _priority = value; } } diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index d0a2568f..7a4fb335 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -118,5 +118,15 @@ public List SortTasksByPriority() } return null; } + + public bool UpdateTaskName(int taskID, string newName) + { + if (_tasks.ContainsKey(taskID)) + { + _tasks[taskID].Name = newName; + return true; + } + return false; + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 8569319f..bd87570a 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -232,5 +232,24 @@ public void GetTaskByIDTest() Assert.That(task2, Is.Null); } + + [Test] + public void UpdateTaskNameTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + todoList.AddTask(taskName1); + + string newName = "Dishes"; + int task1ID = 0; + int notExistID= 1; + + bool success = todoList.UpdateTaskName(task1ID, newName); + bool fail = todoList.UpdateTaskName(notExistID, newName); + + Assert.That(todoList.Tasks[0].Name, Is.EqualTo(newName)); + Assert.True(success); + Assert.False(fail); + } } } \ No newline at end of file From 662b741ed1ed916800ebdb9e647363266d1f5e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 09:05:29 +0200 Subject: [PATCH 18/25] Tests and implements toggle status by id and name --- domain-model.md | 2 +- tdd-todo-list.CSharp.Main/ToDoList.cs | 19 ++++++++++++-- tdd-todo-list.CSharp.Test/CoreTests.cs | 35 ++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/domain-model.md b/domain-model.md index 684beafe..e9ba4b5c 100644 --- a/domain-model.md +++ b/domain-model.md @@ -4,7 +4,7 @@ |-------|-----------------|--------|-------| |`TodoList`|`AddTask(string name)`|Add task with name to todo list| int ID of new task| |`TodoList`|`TodoList.Tasks`|Provide all tasks in todo list | Dictionary | -|`TodoList`|`ToggleComplete(string name)` | Toggle status of give task from complete to incomplete or incomplete to complete| | +|`TodoList`|`ToggleComplete(string name)` | Toggle status of give task from complete to incomplete or incomplete to complete| bool | |`TodoList`|`GetCompleteTasks()`| Provide all complete tasks in todo list | List| |`TodoList`|`GetIncompleteTasks()`| Provide all incomplete tasks in todo list | List| |`TodoList`|`GetTaskByName(string name)`| Search for Task with given name | Task, provide message if not found | diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 7a4fb335..9dcb0395 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -21,9 +21,14 @@ public void AddTask(string name) _taskCount++; } - public void ToggleComplete(int taskID) + public bool ToggleComplete(string taskName) { - _tasks[taskID].IsCompleted = !_tasks[taskID].IsCompleted; + Task? task = GetTaskByName(taskName); + if (task != null) { + task.IsCompleted = !task.IsCompleted; + return true; + } + return false; } public List GetCompleteTasks() @@ -128,5 +133,15 @@ public bool UpdateTaskName(int taskID, string newName) } return false; } + + public bool UpdateTaskStatus(int taskID) + { + if (_tasks.ContainsKey(taskID)) + { + _tasks[taskID].IsCompleted = !_tasks[taskID].IsCompleted; + return true; + } + return false; + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index bd87570a..46902208 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -45,10 +45,13 @@ public void ToggleCompleteTest() todoList.AddTask(taskName1); todoList.AddTask(taskName2); - todoList.ToggleComplete(0); + bool success = todoList.ToggleComplete("Homework"); + bool fail = todoList.ToggleComplete("Run"); Assert.That(todoList.Tasks[0].IsCompleted, Is.True); Assert.That(todoList.Tasks[1].IsCompleted, Is.False); + Assert.True(success); + Assert.False(fail); } [Test] @@ -64,8 +67,8 @@ public void GetCompleteTasksTest() todoList.AddTask(taskName3); todoList.AddTask(taskName4); - todoList.ToggleComplete(0); - todoList.ToggleComplete(3); + todoList.ToggleComplete("Homework"); + todoList.ToggleComplete("Run"); List completeTaskList = todoList.GetCompleteTasks(); @@ -86,8 +89,8 @@ public void GetIncompleteTasksTest() todoList.AddTask(taskName3); todoList.AddTask(taskName4); - todoList.ToggleComplete(0); - todoList.ToggleComplete(3); + todoList.ToggleComplete("Homework"); + todoList.ToggleComplete("Run"); List incompleteTaskList = todoList.GetIncompleteTasks(); @@ -251,5 +254,27 @@ public void UpdateTaskNameTest() Assert.True(success); Assert.False(fail); } + + [Test] + public void UpdateTaskStatusTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + + int task1ID = 0; + int task2ID = 1; + int notExistID = 2; + + bool success = todoList.UpdateTaskStatus(task1ID); + bool fail = todoList.UpdateTaskStatus(notExistID); + + Assert.True(todoList.Tasks[task1ID].IsCompleted); + Assert.False(todoList.Tasks[task2ID].IsCompleted); + Assert.True(success); + Assert.False(fail); + } } } \ No newline at end of file From 78b52f4096d4d5aff205841aab8c9b22a132385e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 09:13:44 +0200 Subject: [PATCH 19/25] Separates core and extension tests --- tdd-todo-list.CSharp.Test/CoreTests.cs | 69 +----------------- tdd-todo-list.CSharp.Test/ExtensionTests.cs | 79 +++++++++++++++++++-- 2 files changed, 76 insertions(+), 72 deletions(-) diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 46902208..19da992a 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -208,73 +208,6 @@ public void SortTasksByPriorityTest() Assert.That(sortedTasks[2].Name, Is.EqualTo("Laundry")); } - [Test] - public void GetTaskByIDTest() - { - TodoList todoList = new TodoList(); - string taskName1 = "Homework"; - string taskName2 = "Laundry"; - string taskName3 = "Dishes"; - todoList.AddTask(taskName1); - todoList.AddTask(taskName2); - todoList.AddTask(taskName3); - - todoList.RemoveTask("Laundry"); - - int task1ID = 0; - int task2ID = 1; - int task3ID = 2; - - Task? task1 = todoList.GetTaskByID(task1ID); - Task? task3 = todoList.GetTaskByID(task3ID); - - Task? task2 = todoList.GetTaskByID(task2ID); - - Assert.That(task1.ID, Is.EqualTo(0)); - Assert.That(task3.ID, Is.EqualTo(2)); - Assert.That(task2, Is.Null); - - } - - [Test] - public void UpdateTaskNameTest() - { - TodoList todoList = new TodoList(); - string taskName1 = "Homework"; - todoList.AddTask(taskName1); - - string newName = "Dishes"; - int task1ID = 0; - int notExistID= 1; - - bool success = todoList.UpdateTaskName(task1ID, newName); - bool fail = todoList.UpdateTaskName(notExistID, newName); - - Assert.That(todoList.Tasks[0].Name, Is.EqualTo(newName)); - Assert.True(success); - Assert.False(fail); - } - - [Test] - public void UpdateTaskStatusTest() - { - TodoList todoList = new TodoList(); - string taskName1 = "Homework"; - string taskName2 = "Laundry"; - todoList.AddTask(taskName1); - todoList.AddTask(taskName2); - - int task1ID = 0; - int task2ID = 1; - int notExistID = 2; - - bool success = todoList.UpdateTaskStatus(task1ID); - bool fail = todoList.UpdateTaskStatus(notExistID); - - Assert.True(todoList.Tasks[task1ID].IsCompleted); - Assert.False(todoList.Tasks[task2ID].IsCompleted); - Assert.True(success); - Assert.False(fail); - } + } } \ No newline at end of file diff --git a/tdd-todo-list.CSharp.Test/ExtensionTests.cs b/tdd-todo-list.CSharp.Test/ExtensionTests.cs index bdc82ad7..b57e1968 100644 --- a/tdd-todo-list.CSharp.Test/ExtensionTests.cs +++ b/tdd-todo-list.CSharp.Test/ExtensionTests.cs @@ -1,18 +1,89 @@ -using tdd_todo_list.CSharp.Main; +using NUnit.Framework; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using tdd_todo_list.CSharp.Main; +using Task = tdd_todo_list.CSharp.Main.Task; namespace tdd_todo_list.CSharp.Test { public class ExtensionTests { - private TodoListExtension _extension; - public ExtensionTests() + [Test] + public void GetTaskByIDTest() { - _extension = new TodoListExtension(); + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + string taskName3 = "Dishes"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + todoList.AddTask(taskName3); + + todoList.RemoveTask("Laundry"); + + int task1ID = 0; + int task2ID = 1; + int task3ID = 2; + + Task? task1 = todoList.GetTaskByID(task1ID); + Task? task3 = todoList.GetTaskByID(task3ID); + + Task? task2 = todoList.GetTaskByID(task2ID); + + Assert.That(task1.ID, Is.EqualTo(0)); + Assert.That(task3.ID, Is.EqualTo(2)); + Assert.That(task2, Is.Null); + + } + + [Test] + public void UpdateTaskNameTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + todoList.AddTask(taskName1); + + string newName = "Dishes"; + int task1ID = 0; + int notExistID = 1; + + bool success = todoList.UpdateTaskName(task1ID, newName); + bool fail = todoList.UpdateTaskName(notExistID, newName); + + Assert.That(todoList.Tasks[0].Name, Is.EqualTo(newName)); + Assert.True(success); + Assert.False(fail); + } + + [Test] + public void UpdateTaskStatusTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + + int task1ID = 0; + int task2ID = 1; + int notExistID = 2; + + bool success = todoList.UpdateTaskStatus(task1ID); + bool fail = todoList.UpdateTaskStatus(notExistID); + + Assert.True(todoList.Tasks[task1ID].IsCompleted); + Assert.False(todoList.Tasks[task2ID].IsCompleted); + Assert.True(success); + Assert.False(fail); + } + + [Test] + public void GetAllTaskTimeCreatedTest() + { + } } } From e4cdbab09857fc0e534044447a084eab00244464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 09:36:50 +0200 Subject: [PATCH 20/25] Tests and implements get all time created --- tdd-todo-list.CSharp.Main/Task.cs | 2 ++ tdd-todo-list.CSharp.Main/ToDoList.cs | 10 ++++++++++ tdd-todo-list.CSharp.Test/ExtensionTests.cs | 14 ++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/tdd-todo-list.CSharp.Main/Task.cs b/tdd-todo-list.CSharp.Main/Task.cs index 37d3d099..603b78a1 100644 --- a/tdd-todo-list.CSharp.Main/Task.cs +++ b/tdd-todo-list.CSharp.Main/Task.cs @@ -20,11 +20,13 @@ public Task(int count, string name) { _id = count; _name = name; + _timeCreated = DateTime.Today; } public string Name { get { return _name; } set { _name = value; } } public int ID { get { return _id; } } public bool IsCompleted { get { return _isCompleted; } set { _isCompleted = value; } } public int Priority { get { return _priority; } set { _priority = value; } } + public DateTime TimeCreated { get { return _timeCreated; } } } } diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 9dcb0395..bf7bccb2 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -143,5 +143,15 @@ public bool UpdateTaskStatus(int taskID) } return false; } + + public List<(Task, DateTime)> GetAllTaskTimeCreated() + { + List<(Task, DateTime)> timeCreatedList = new List<(Task, DateTime)> (); + foreach (Task task in _tasks.Values) + { + timeCreatedList.Add((task, task.TimeCreated)); + } + return timeCreatedList; + } } } diff --git a/tdd-todo-list.CSharp.Test/ExtensionTests.cs b/tdd-todo-list.CSharp.Test/ExtensionTests.cs index b57e1968..e87a73cf 100644 --- a/tdd-todo-list.CSharp.Test/ExtensionTests.cs +++ b/tdd-todo-list.CSharp.Test/ExtensionTests.cs @@ -83,6 +83,20 @@ public void UpdateTaskStatusTest() [Test] public void GetAllTaskTimeCreatedTest() { + // Simplifying to date, ignoring time of day + DateTime today = DateTime.Today; + + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + + List < (Task, DateTime) > timeCreatedList = todoList.GetAllTaskTimeCreated(); + + Assert.That(todoList.Tasks[0].TimeCreated, Is.EqualTo(today)); + Assert.That(timeCreatedList[0].Item2, Is.EqualTo(today)); + Assert.That(timeCreatedList[1].Item2, Is.EqualTo(today)); } } From 8f50471f545cbf5e310c9758aa0b6d1b7d45ccd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 09:54:58 +0200 Subject: [PATCH 21/25] Tests and implements list of task completion time --- tdd-todo-list.CSharp.Main/Task.cs | 3 +- tdd-todo-list.CSharp.Main/ToDoList.cs | 11 ++++++++ tdd-todo-list.CSharp.Test/ExtensionTests.cs | 31 +++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/tdd-todo-list.CSharp.Main/Task.cs b/tdd-todo-list.CSharp.Main/Task.cs index 603b78a1..5c484429 100644 --- a/tdd-todo-list.CSharp.Main/Task.cs +++ b/tdd-todo-list.CSharp.Main/Task.cs @@ -27,6 +27,7 @@ public Task(int count, string name) public int ID { get { return _id; } } public bool IsCompleted { get { return _isCompleted; } set { _isCompleted = value; } } public int Priority { get { return _priority; } set { _priority = value; } } - public DateTime TimeCreated { get { return _timeCreated; } } + public DateTime TimeCreated { get { return _timeCreated; } set { _timeCreated = value;} } + public DateTime TimeCompleted { get { return _timeCompleted; } set { _timeCompleted = value; } } } } diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index bf7bccb2..44e20223 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -26,6 +26,7 @@ public bool ToggleComplete(string taskName) Task? task = GetTaskByName(taskName); if (task != null) { task.IsCompleted = !task.IsCompleted; + task.TimeCompleted = DateTime.Today; return true; } return false; @@ -153,5 +154,15 @@ public bool UpdateTaskStatus(int taskID) } return timeCreatedList; } + + public List<(Task, DateTime)> GetAllTaskTimeCompleted() + { + List<(Task, DateTime)> timeCompletedList = new List<(Task, DateTime)> (); + foreach (Task task in _tasks.Values) + { + timeCompletedList.Add((task, task.TimeCompleted)); + } + return timeCompletedList; + } } } diff --git a/tdd-todo-list.CSharp.Test/ExtensionTests.cs b/tdd-todo-list.CSharp.Test/ExtensionTests.cs index e87a73cf..0365724d 100644 --- a/tdd-todo-list.CSharp.Test/ExtensionTests.cs +++ b/tdd-todo-list.CSharp.Test/ExtensionTests.cs @@ -98,6 +98,37 @@ public void GetAllTaskTimeCreatedTest() Assert.That(timeCreatedList[0].Item2, Is.EqualTo(today)); Assert.That(timeCreatedList[1].Item2, Is.EqualTo(today)); + } + + [Test] + public void GetAllTaskTimeCompletedTest() + { + DateTime createdTime = new DateTime(2025, 08, 05); + DateTime completeTime = new DateTime(2025, 08, 06); + + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + todoList.AddTask(taskName1); + todoList.ToggleComplete("Homework"); + todoList.AddTask(taskName2); + todoList.ToggleComplete("Laundry"); + + Assert.That(todoList.Tasks[0].TimeCompleted, Is.Not.Null); + + // Override time created and completed + todoList.Tasks[0].TimeCreated = createdTime; + todoList.Tasks[1].TimeCreated = createdTime; + todoList.Tasks[0].TimeCompleted = completeTime; + todoList.Tasks[1].TimeCompleted = completeTime; + + List<(Task, DateTime)> timeCompletedList = todoList.GetAllTaskTimeCompleted(); + + Assert.That(timeCompletedList[0].Item2, Is.EqualTo(completeTime)); + Assert.That(timeCompletedList[1].Item2, Is.EqualTo(completeTime)); + + + } } } From 6f11863ff0702b479ac1d6e1d717d3886fb1e1e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 10:34:20 +0200 Subject: [PATCH 22/25] Tests and implements getting task with shortest completion time --- domain-model.md | 4 +- tdd-todo-list.CSharp.Main/Task.cs | 9 ++++ tdd-todo-list.CSharp.Main/ToDoList.cs | 51 ++++++++++++++++++- tdd-todo-list.CSharp.Test/ExtensionTests.cs | 55 ++++++++++++++++++++- 4 files changed, 115 insertions(+), 4 deletions(-) diff --git a/domain-model.md b/domain-model.md index e9ba4b5c..7fd67600 100644 --- a/domain-model.md +++ b/domain-model.md @@ -17,8 +17,8 @@ |`TodoList`|`UpdateTaskStatus(int id)` | Toggle the status of task with given ID | bool | |`TodoList`|`GetAllTaskTimeCreated()` | Provide all tasks along with time of creation | (List, datetime) | |`TodoList`|`GetAllTaskTimeCompleted()` | Provide all tasks along with time of completion | (List, datetime) | -|`TodoList`|`GetTaskWithLongestCompletionTime()` | Provide the task with the longest completion time | (, completion time) | -|`TodoList`|`GetTaskWithShortestCompletionTime()` | Provide the task with the shortest completion time | (, completion time) | +|`TodoList`|`GetTaskWithLongestCompletionTime()` | Provide the task with the longest completion time | `Task` | +|`TodoList`|`GetTaskWithShortestCompletionTime()` | Provide the task with the shortest completion time | `Task` | |`TodoList`|`GetTasksByCompletionTime(int numDaysToComplete)` | Provide all tasks with completion time longer than given time | List | |`Task`| `SetTaskCategory(string name, string category)` | Set category of task | bool | |`TodoList`|`GetTasksByCategory(string category)` | Get all tasks matching the given category | List | \ No newline at end of file diff --git a/tdd-todo-list.CSharp.Main/Task.cs b/tdd-todo-list.CSharp.Main/Task.cs index 5c484429..931451ce 100644 --- a/tdd-todo-list.CSharp.Main/Task.cs +++ b/tdd-todo-list.CSharp.Main/Task.cs @@ -15,6 +15,7 @@ public class Task private string _category = String.Empty; private DateTime _timeCreated; private DateTime _timeCompleted; + private int? _completionTime = null; public Task(int count, string name) { @@ -23,11 +24,19 @@ public Task(int count, string name) _timeCreated = DateTime.Today; } + public void CalculateCompletionTime() + { + if (IsCompleted) { + _completionTime = (int)(_timeCompleted - _timeCreated).TotalDays; + } + } + public string Name { get { return _name; } set { _name = value; } } public int ID { get { return _id; } } public bool IsCompleted { get { return _isCompleted; } set { _isCompleted = value; } } public int Priority { get { return _priority; } set { _priority = value; } } public DateTime TimeCreated { get { return _timeCreated; } set { _timeCreated = value;} } public DateTime TimeCompleted { get { return _timeCompleted; } set { _timeCompleted = value; } } + public int? CompletionTime { get { return _completionTime; } } } } diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 44e20223..bb494afe 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -160,9 +160,58 @@ public bool UpdateTaskStatus(int taskID) List<(Task, DateTime)> timeCompletedList = new List<(Task, DateTime)> (); foreach (Task task in _tasks.Values) { - timeCompletedList.Add((task, task.TimeCompleted)); + if (task.IsCompleted) + { + timeCompletedList.Add((task, task.TimeCompleted)); + } } return timeCompletedList; } + + public Task GetTaskWithLongestCompletionTime() + { + int longestCompletionTime = 0; + Task? longestCompletionTask = null; + List<(Task, DateTime)> completedTaskList = GetAllTaskTimeCompleted(); + foreach ((Task, DateTime) listItem in completedTaskList) + { + Task task = listItem.Item1; + if (task.CompletionTime == null) + { + task.CalculateCompletionTime(); + } + if (task.CompletionTime > longestCompletionTime) + { + longestCompletionTime = (int)task.CompletionTime; + longestCompletionTask = task; + } + + } + return longestCompletionTask!; + + } + + public Task GetTaskWithShortestCompletionTime() + { + // Assuming no completion times will exceed 100 days + int shortestCompletionTime = 100; + Task? shortestCompletionTask = null; + List<(Task, DateTime)> completedTaskList = GetAllTaskTimeCompleted(); + foreach ((Task, DateTime) listItem in completedTaskList) + { + Task task = listItem.Item1; + if (task.CompletionTime == null) + { + task.CalculateCompletionTime(); + } + if (task.CompletionTime < shortestCompletionTime) + { + shortestCompletionTime = (int)task.CompletionTime; + shortestCompletionTask = task; + } + + } + return shortestCompletionTask!; + } } } diff --git a/tdd-todo-list.CSharp.Test/ExtensionTests.cs b/tdd-todo-list.CSharp.Test/ExtensionTests.cs index 0365724d..56f2deb7 100644 --- a/tdd-todo-list.CSharp.Test/ExtensionTests.cs +++ b/tdd-todo-list.CSharp.Test/ExtensionTests.cs @@ -113,6 +113,8 @@ public void GetAllTaskTimeCompletedTest() todoList.ToggleComplete("Homework"); todoList.AddTask(taskName2); todoList.ToggleComplete("Laundry"); + // Not completed task + todoList.AddTask("Laundry2"); Assert.That(todoList.Tasks[0].TimeCompleted, Is.Not.Null); @@ -126,9 +128,60 @@ public void GetAllTaskTimeCompletedTest() Assert.That(timeCompletedList[0].Item2, Is.EqualTo(completeTime)); Assert.That(timeCompletedList[1].Item2, Is.EqualTo(completeTime)); + Assert.That(timeCompletedList.Count, Is.EqualTo(2)); - + } + + [Test] + public void GetTaskWithLongestCompletionTimeTest() + { + DateTime createdTime = new DateTime(2025, 08, 05); + DateTime completeTime1 = new DateTime(2025, 08, 06); + DateTime completeTime2 = new DateTime(2025, 08, 10); + + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + todoList.AddTask(taskName1); + todoList.ToggleComplete("Homework"); + todoList.AddTask(taskName2); + todoList.ToggleComplete("Laundry"); + + // Override time created and completed + todoList.Tasks[0].TimeCreated = createdTime; + todoList.Tasks[1].TimeCreated = createdTime; + todoList.Tasks[0].TimeCompleted = completeTime1; + todoList.Tasks[1].TimeCompleted = completeTime2; + + Task longestCompletionTimeTask = todoList.GetTaskWithLongestCompletionTime(); + + Assert.That(longestCompletionTimeTask.Name, Is.EqualTo(taskName2)); + } + + [Test] + public void GetTaskWithShortestCompletionTimeTest() + { + DateTime createdTime = new DateTime(2025, 08, 05); + DateTime completeTime1 = new DateTime(2025, 08, 06); + DateTime completeTime2 = new DateTime(2025, 08, 10); + + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + todoList.AddTask(taskName1); + todoList.ToggleComplete("Homework"); + todoList.AddTask(taskName2); + todoList.ToggleComplete("Laundry"); + + // Override time created and completed + todoList.Tasks[0].TimeCreated = createdTime; + todoList.Tasks[1].TimeCreated = createdTime; + todoList.Tasks[0].TimeCompleted = completeTime1; + todoList.Tasks[1].TimeCompleted = completeTime2; + + Task shortestCompletionTimeTask = todoList.GetTaskWithShortestCompletionTime(); + Assert.That(shortestCompletionTimeTask.Name, Is.EqualTo(taskName1)); } } } From 85e0a5bfd4c6dc666f6998b7c56fc74070197bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 10:44:59 +0200 Subject: [PATCH 23/25] Tests and implements get tasks with completion time higher than a given number of days --- domain-model.md | 2 +- tdd-todo-list.CSharp.Main/ToDoList.cs | 20 +++++++++++++ tdd-todo-list.CSharp.Test/ExtensionTests.cs | 33 +++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/domain-model.md b/domain-model.md index 7fd67600..9bb613f2 100644 --- a/domain-model.md +++ b/domain-model.md @@ -20,5 +20,5 @@ |`TodoList`|`GetTaskWithLongestCompletionTime()` | Provide the task with the longest completion time | `Task` | |`TodoList`|`GetTaskWithShortestCompletionTime()` | Provide the task with the shortest completion time | `Task` | |`TodoList`|`GetTasksByCompletionTime(int numDaysToComplete)` | Provide all tasks with completion time longer than given time | List | -|`Task`| `SetTaskCategory(string name, string category)` | Set category of task | bool | +|`TodoList`| `SetTaskCategory(string name, string category)` | Set category of task | bool | |`TodoList`|`GetTasksByCategory(string category)` | Get all tasks matching the given category | List | \ No newline at end of file diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index bb494afe..bc941119 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -213,5 +213,25 @@ public Task GetTaskWithShortestCompletionTime() } return shortestCompletionTask!; } + + public List GetTasksByCompletionTime(int daysLimit) + { + List tasks = new List(); + List<(Task, DateTime)> completedTaskList = GetAllTaskTimeCompleted(); + foreach ((Task, DateTime) listItem in completedTaskList) + { + Task task = listItem.Item1; + if (task.CompletionTime == null) + { + task.CalculateCompletionTime(); + } + if (task.CompletionTime > daysLimit) + { + tasks.Add(task); + } + } + return tasks; + + } } } diff --git a/tdd-todo-list.CSharp.Test/ExtensionTests.cs b/tdd-todo-list.CSharp.Test/ExtensionTests.cs index 56f2deb7..cff49f79 100644 --- a/tdd-todo-list.CSharp.Test/ExtensionTests.cs +++ b/tdd-todo-list.CSharp.Test/ExtensionTests.cs @@ -183,5 +183,38 @@ public void GetTaskWithShortestCompletionTimeTest() Assert.That(shortestCompletionTimeTask.Name, Is.EqualTo(taskName1)); } + + [Test] + public void GetTasksByCompletionTimeTest() + { + DateTime createdTime = new DateTime(2025, 08, 05); + DateTime completeTime1 = new DateTime(2025, 08, 06); + DateTime completeTime2 = new DateTime(2025, 08, 11); + DateTime completeTime3 = new DateTime(2025, 08, 12); + + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + string taskName3 = "Dishes"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + todoList.AddTask(taskName3); + todoList.ToggleComplete(taskName1); + todoList.ToggleComplete(taskName2); + todoList.ToggleComplete(taskName3); + // Override time created and completed + todoList.Tasks[0].TimeCreated = createdTime; + todoList.Tasks[1].TimeCreated = createdTime; + todoList.Tasks[2].TimeCreated = createdTime; + todoList.Tasks[0].TimeCompleted = completeTime1; + todoList.Tasks[1].TimeCompleted = completeTime2; + todoList.Tasks[2].TimeCompleted = completeTime3; + + int daysLimit = 5; + + List tasks = todoList.GetTasksByCompletionTime(daysLimit); + + Assert.True(tasks.All(task => task.CompletionTime > daysLimit)); + } } } From 6190a8f89278beef77f9079b6d1255d5a0e5e1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 10:57:28 +0200 Subject: [PATCH 24/25] Tests and implements setting category of specific task --- tdd-todo-list.CSharp.Main/Task.cs | 1 + tdd-todo-list.CSharp.Main/ToDoList.cs | 13 +++++++++++++ tdd-todo-list.CSharp.Test/ExtensionTests.cs | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/tdd-todo-list.CSharp.Main/Task.cs b/tdd-todo-list.CSharp.Main/Task.cs index 931451ce..bcb70031 100644 --- a/tdd-todo-list.CSharp.Main/Task.cs +++ b/tdd-todo-list.CSharp.Main/Task.cs @@ -38,5 +38,6 @@ public void CalculateCompletionTime() public DateTime TimeCreated { get { return _timeCreated; } set { _timeCreated = value;} } public DateTime TimeCompleted { get { return _timeCompleted; } set { _timeCompleted = value; } } public int? CompletionTime { get { return _completionTime; } } + public string Category { get { return _category; } set { _category = value; } } } } diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index bc941119..b99a2a50 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -233,5 +233,18 @@ public List GetTasksByCompletionTime(int daysLimit) return tasks; } + + public bool SetTaskCategory(string taskName, string category) + { + Task task = GetTaskByName(taskName); + + if (task == null) { + return false; + } + + task.Category = category; + return true; + + } } } diff --git a/tdd-todo-list.CSharp.Test/ExtensionTests.cs b/tdd-todo-list.CSharp.Test/ExtensionTests.cs index cff49f79..33aa150a 100644 --- a/tdd-todo-list.CSharp.Test/ExtensionTests.cs +++ b/tdd-todo-list.CSharp.Test/ExtensionTests.cs @@ -216,5 +216,26 @@ public void GetTasksByCompletionTimeTest() Assert.True(tasks.All(task => task.CompletionTime > daysLimit)); } + + [Test] + public void SetTaskCategoryTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + + string category = "School"; + + bool success = todoList.SetTaskCategory(taskName1, category); + bool fail = todoList.SetTaskCategory("Dishes", category); + + Assert.True(success); + Assert.False(fail); + Assert.That(todoList.Tasks[0].Category, Is.EqualTo(category)); + Assert.That(todoList.Tasks[1].Category, Is.Empty); + + } } } From 1e6b647697db1b47a87b9547946b0419ee0ad17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Jakob=20H=C3=A5land?= Date: Fri, 8 Aug 2025 11:05:26 +0200 Subject: [PATCH 25/25] Tests and implements list with tasks corresponding to specified category --- tdd-todo-list.CSharp.Main/ToDoList.cs | 16 +++++++++++++ tdd-todo-list.CSharp.Test/ExtensionTests.cs | 26 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index b99a2a50..c3f782c1 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -246,5 +246,21 @@ public bool SetTaskCategory(string taskName, string category) return true; } + + public List GetTasksByCategory(string category) + { + List tasks = new List(); + foreach (Task task in _tasks.Values) + { + if (task.Category == String.Empty) + { + continue; + } + if (task.Category == category) { + tasks.Add(task); + } + } + return tasks; + } } } diff --git a/tdd-todo-list.CSharp.Test/ExtensionTests.cs b/tdd-todo-list.CSharp.Test/ExtensionTests.cs index 33aa150a..80f58d6c 100644 --- a/tdd-todo-list.CSharp.Test/ExtensionTests.cs +++ b/tdd-todo-list.CSharp.Test/ExtensionTests.cs @@ -237,5 +237,31 @@ public void SetTaskCategoryTest() Assert.That(todoList.Tasks[1].Category, Is.Empty); } + + [Test] + public void GetTasksByCategoryTest() + { + TodoList todoList = new TodoList(); + string taskName1 = "Homework"; + string taskName2 = "Laundry"; + string taskName3 = "Dishes"; + todoList.AddTask(taskName1); + todoList.AddTask(taskName2); + todoList.AddTask(taskName3); + string category1 = "School"; + string category2 = "Home"; + todoList.SetTaskCategory(taskName1, category1); + todoList.SetTaskCategory(taskName2, category2); + todoList.SetTaskCategory(taskName3, category2); + + List cat1Tasks = todoList.GetTasksByCategory(category1); + List cat2Tasks = todoList.GetTasksByCategory(category2); + + Assert.That(cat1Tasks.Count, Is.EqualTo(1)); + Assert.That(cat1Tasks[0].Name, Is.EqualTo(taskName1)); + Assert.That(cat2Tasks.Count, Is.EqualTo(2)); + Assert.That(cat2Tasks[0].Name, Is.EqualTo(taskName2)); + Assert.That(cat2Tasks[1].Name, Is.EqualTo(taskName3)); + } } }