From 665b33a40b0fd9f7a3d17e6a465ff884ecdc759a Mon Sep 17 00:00:00 2001 From: Erlend Skutlaberg Date: Thu, 9 Jan 2025 16:03:51 +0100 Subject: [PATCH] completed the tasks --- domain-model.md | 14 ++ tdd-todo-list.CSharp.Main/Extension.cs | 160 +++++++++++++++++++- tdd-todo-list.CSharp.Main/Program.cs | 14 +- tdd-todo-list.CSharp.Main/ToDoList.cs | 111 ++++++++++++++ tdd-todo-list.CSharp.Test/CoreTests.cs | 158 ++++++++++++++++++- tdd-todo-list.CSharp.Test/ExtensionTests.cs | 74 +++++++++ tdd-todo-list.sln | 1 + 7 files changed, 527 insertions(+), 5 deletions(-) create mode 100644 domain-model.md diff --git a/domain-model.md b/domain-model.md new file mode 100644 index 00000000..0d2e1484 --- /dev/null +++ b/domain-model.md @@ -0,0 +1,14 @@ +| Classes | Methods/properties | Scenario | Outputs | +|-------------|----------------------------------------------------|--------------------------------------------------------------------|-----------------------------------------------------------------| +| TodoList.cs | Task Add(string title, string description) | Add a task to the tasklist | The added task | +| TodoList.cs | List GetTasks() | Get all tasks from the Tasklist | The complete tasklist | +| TodoList.cs | Task ChangeTask(string title, bool status) | Change the status of a task based on the title of a task | The updated task | +| TodoList.cs | List GetCompletedTasks() | Get all tasks that are done | All completed tasks | +| TodoList.cs | List GetIncompleteTasks() | Get all tasks that are not done | All incomplete tasks | +| TodoList.cs | Task GetTask(string Title) | Get a task based on the title. Return an empty task if not found. | The specified task, an empty task otherwise | +| TodoList.cs | Task RemoveTask(string Title) | Remove a task from the tasklist based on the title of the task | The removed task, an empty task if not found | +| TodoList.cs | List SortTasksAlphabetically(bool ascending) | Sorts the tasklist alphabetically based on the ascending parameter | The tasklist sorted alphabetically | +| TodoList.cs | Task GetTaskByID(long id) | Get a task by its ID | The specified task, an empty task if not found | +| TodoList.cs | Task UpdateTaskTitle(long id, string title) | Set the title of a task by its ID | The updated task, an empty task if not found | +| TodoList.cs | Task UpdateTaskStatus(long id, bool status) | Set the status of a task by its ID | The updated task, an empty task if not found | +| TodoList.cs | string GetCreationTime() | Get the creation time, id, and title of each task | A string consisting of the ID, title, and datetime of all tasks | \ No newline at end of file diff --git a/tdd-todo-list.CSharp.Main/Extension.cs b/tdd-todo-list.CSharp.Main/Extension.cs index e4c08912..4559b946 100644 --- a/tdd-todo-list.CSharp.Main/Extension.cs +++ b/tdd-todo-list.CSharp.Main/Extension.cs @@ -3,10 +3,166 @@ using System.Linq; using System.Text; using System.Threading.Tasks; - namespace tdd_todo_list.CSharp.Main { - public class TodoListExtension + public class TodoListExtension + { + public List tasks { get; set; } + + public TodoListExtension() + { + tasks = new List(); + + } + + public List GetIDs() + { + List ids = new List(); + foreach (TaskExtension t in tasks) + { + ids.Add(t.id); + } + return ids; + } + + public TaskExtension Add(string title, string description) + { + + // TaskExtensions needs different titles + if (tasks.Where(x => x.title == title).Any() || title == "") + { + return new TaskExtension("", "", GetIDs()); + } + TaskExtension taskToAdd = new TaskExtension(title, description, GetIDs()); + tasks.Add(taskToAdd); + return new TaskExtension(taskToAdd); + } + + public List GetTasks() + { + return new List(tasks); + } + + public TaskExtension GetTask(string title) + { + TaskExtension? queried_task = tasks.FirstOrDefault(x => x.title == title) ?? new TaskExtension("", "", GetIDs()); + + return new TaskExtension(queried_task); + } + + public TaskExtension ChangeTask(string title, bool status) + { + TaskExtension? taskToUpdate = tasks.FirstOrDefault(x => x.title == title) ?? new TaskExtension("", "", GetIDs()); + taskToUpdate.status = status; + return new TaskExtension(taskToUpdate); + } + + public List GetCompletedTasks() + { + List? completedTasks = tasks.Where(x => x.status).ToList() ?? new List(); + return new List(completedTasks); + } + + public List GetIncompleteTasks() + { + List? completedTasks = tasks.Where(x => !x.status).ToList() ?? new List(); + return new List(completedTasks); + } + + + + public TaskExtension RemoveTask(string title) + { + TaskExtension? taskToRemove = tasks.FirstOrDefault(x => x.title == title) ?? new TaskExtension("", "", GetIDs()); + if (taskToRemove.title == "") + { + return taskToRemove; + } + tasks.Remove(taskToRemove); + return new TaskExtension(taskToRemove); + } + + public List SortTasksAlphabetically(bool ascending) + { + List sortedTasks = new List(); + if (ascending) + { + sortedTasks = tasks.OrderBy(x => x.title).ToList(); + } + else + { + sortedTasks = tasks.OrderByDescending(x => x.title).ToList(); + } + + return new List(sortedTasks); + } + public TaskExtension GetTaskByID(long id) + { + TaskExtension? retrievedTask = tasks.FirstOrDefault(x => x.id == id) ?? new TaskExtension("", "", GetIDs()); + return new TaskExtension(retrievedTask); + } + + public TaskExtension UpdateTaskTitle(long id, string title) + { + TaskExtension? taskToUpdate = tasks.FirstOrDefault(x => x.id == id) ?? new TaskExtension("", "", GetIDs()); + taskToUpdate.title = title; + return new TaskExtension(taskToUpdate); + } + + public TaskExtension UpdateTaskStatus(long id, bool status) + { + TaskExtension? taskToUpdate = tasks.FirstOrDefault(x => x.id == id) ?? new TaskExtension("", "", GetIDs()); + taskToUpdate.status = status; + return new TaskExtension(taskToUpdate); + } + + public string GetCreationTime() + { + string creationTime = ""; + foreach (TaskExtension task in tasks) + { + creationTime += task.id + " " + task.title + " " + task.creationTime.ToString() + "\n"; + } + return creationTime; + } + } + + + public class TaskExtension { + public string title { get; set; } + public string description { get; set; } + public bool status { get; set; } + public long id { get; } + public DateTime creationTime = DateTime.Now; + public Random rng = new Random(); + + public TaskExtension(string title, string description, List usedIDs) + { + this.title = title; + this.description = description; + status = false; + long id = 0; + while (usedIDs.Contains(id)) + { + id = rng.NextInt64(0, 1000); + } + this.id = id; + } + + public TaskExtension(TaskExtension t) + { + this.title = t.title; + this.description = t.description; + this.status = t.status; + this.id = id; + + } + + + public bool Equals(TaskExtension other) + { + return this.title == other.title && this.id == other.id; //Check whether the identifier of a task are equal + } } } diff --git a/tdd-todo-list.CSharp.Main/Program.cs b/tdd-todo-list.CSharp.Main/Program.cs index 3751555c..d1080080 100644 --- a/tdd-todo-list.CSharp.Main/Program.cs +++ b/tdd-todo-list.CSharp.Main/Program.cs @@ -1,2 +1,14 @@ // See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); + +using System.ComponentModel; +using tdd_todo_list.CSharp.Main; + +TodoListExtension l = new TodoListExtension(); +l.Add("Task 1", "work"); +l.Add("Task 2", "Coffee"); +l.Add("Task 3", "Lunch"); +l.Add("Task 4", "Go Home"); + +string time = l.GetCreationTime(); +Console.WriteLine(time); + diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 835cb600..627f467b 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -1,12 +1,123 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace tdd_todo_list.CSharp.Main { + public class TodoList { + public List tasks { get; set; } + + public TodoList() + { + tasks = new List(); + + } + + + + public Task Add(string title, string description) + { + // Tasks needs different titles + if (tasks.Where(x => x.title == title).Any() || title == "") + { + return new Task("", ""); + } + Task taskToAdd = new Task(title, description); + tasks.Add(taskToAdd); + return new Task(taskToAdd); + } + + public List GetTasks() + { + return new List(tasks); + } + + public Task GetTask(string title) + { + Task? queried_task = tasks.FirstOrDefault(x => x.title == title) ?? new Task("", ""); + + return new Task(queried_task); + } + + public Task ChangeTask(string title, bool status) + { + Task? taskToUpdate = tasks.FirstOrDefault(x => x.title == title) ?? new Task("", ""); + taskToUpdate.status = status; + return new Task(taskToUpdate); + } + + public List GetCompletedTasks() + { + List? completedTasks = tasks.Where(x => x.status).ToList() ?? new List(); + return new List(completedTasks); + } + + public List GetIncompleteTasks() + { + List? completedTasks = tasks.Where(x => !x.status).ToList() ?? new List(); + return new List(completedTasks); + } + + + + public Task RemoveTask(string title) + { + Task? taskToRemove = tasks.FirstOrDefault(x => x.title == title) ?? new Task("", ""); + if (taskToRemove.title == "") + { + return taskToRemove; + } + tasks.Remove(taskToRemove); + return new Task(taskToRemove); + } + + public List SortTasksAlphabetically(bool ascending) + { + List sortedTasks = new List (); + if (ascending) + { + sortedTasks = tasks.OrderBy(x => x.title).ToList(); + } + else + { + sortedTasks = tasks.OrderByDescending(x => x.title).ToList(); + } + + return new List(sortedTasks); + } + + + } + + public class Task + { + public string title { get; set; } + public string description { get; set; } + public bool status { get; set; } + + public Task(string title, string description) + { + this.title = title; + this.description = description; + status = false; + } + + public Task(Task t) + { + this.title = t.title; + this.description = t.description; + status = t.status; + } + + + public bool Equals(Task other) + { + return this.title == other.title; //Check whether the identifier of a task are equal + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 084cce19..2965f211 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -1,5 +1,6 @@ -using tdd_todo_list.CSharp.Main; -using NUnit.Framework; +using NUnit.Framework; +using tdd_todo_list.CSharp.Main; +using Task = tdd_todo_list.CSharp.Main.Task; namespace tdd_todo_list.CSharp.Test { @@ -13,5 +14,158 @@ public void FirstTest() TodoList core = new TodoList(); Assert.Pass(); } + + [TestCase("Task 1", "Something that just needs to be done")] + [TestCase("Task 2", "Do some more work")] + public void TestAddTaskAddsTask(string title, string description) + { + TodoList mylist = new TodoList(); + + Task t = mylist.Add(title, description); + Assert.That(t.title, Is.EqualTo(title)); + Assert.That(t.description, Is.EqualTo(description)); + Assert.NotNull(mylist.tasks.FirstOrDefault(x => x.title == title)); + } + [Test] + public void TestAddDoesNotAddTasksWithIdenticalTitles() + { + TodoList mylist = new TodoList(); + + Task t1 = mylist.Add("t1", "work"); + Task t2 = mylist.Add("t1", "run"); + + Assert.NotNull(mylist.tasks.FirstOrDefault(x => x.title == "t1" && x.description == "work")); + Assert.That(mylist.tasks, Has.No.Member(t2)); + + } + + [TestCase("Task 1", "Something that just needs to be done")] + [TestCase("Task 2", "Do some more work")] + public void TestGetAllTasks(string title, string description) + { + TodoList mylist = new TodoList(); + mylist.Add(title, description); + List all_tasks = mylist.GetTasks(); + Assert.That(all_tasks, Is.EquivalentTo(mylist.tasks)); //Contains the same elements + Assert.AreNotSame(all_tasks, mylist.tasks); //Are not the same object + } + + [TestCase("Task 1", "Something that just needs to be done")] + [TestCase("Task 2", "Do some more work")] + [TestCase("", "")] + public void TestGetTask(string title, string description) + { + TodoList mylist = new TodoList(); + Task t1 = mylist.Add(title, description); + Task t2 = mylist.GetTask(title); + + Assert.True(t1.Equals(t2));//Contains the same information + Assert.AreNotSame(t2, t1);//Are not the same object + } + + [TestCase("Task 1", "Run")] + [TestCase("Task 2", "Code")] + [TestCase("Task 3", "Jump")] + [TestCase("Task 4", "")] + public void TestChangeTask(string title, string description) + { + TodoList mylist = new TodoList(); + Task initialTask = mylist.Add(title, description); + Task updatedTask = mylist.ChangeTask(title, true); + Task actualTask = mylist.GetTask(title); + + Assert.True(initialTask.title == updatedTask.title); + Assert.True(actualTask.status); + Assert.AreNotSame(updatedTask, actualTask); + } + + [Test] + public void TestCompletedTasks() + { + TodoList mylist = new TodoList(); + + mylist.Add("Task 1", "Zoom"); + mylist.Add("Task 2", "Have a coffee"); + mylist.Add("Task 3", "Code"); + mylist.Add("Task 4", "Zoom"); + mylist.Add("Task 5", "Lunsj"); + + Task done1 = mylist.ChangeTask("Task 1", true); + Task done2 = mylist.ChangeTask("Task 2", true); + + List completedTasks = mylist.GetCompletedTasks(); + + Assert.AreEqual(2, completedTasks.Count); + Assert.NotNull(completedTasks.FirstOrDefault(x => x.title == "Task 1" && x.status == true)); + Assert.NotNull(completedTasks.FirstOrDefault(x => x.title == "Task 2" && x.status == true)); + } + + [Test] + public void TestIncompletedTasks() + { + TodoList mylist = new TodoList(); + + mylist.Add("Task 1", "Zoom"); + mylist.Add("Task 2", "Have a coffee"); + mylist.Add("Task 3", "Code"); + mylist.Add("Task 4", "Zoom"); + mylist.Add("Task 5", "Lunsj"); + + Task done1 = mylist.ChangeTask("Task 1", true); + Task done2 = mylist.ChangeTask("Task 2", true); + + List incompleteTasks = mylist.GetIncompleteTasks(); + + Assert.AreEqual(3, incompleteTasks.Count); + Assert.NotNull(incompleteTasks.FirstOrDefault(x => x.title == "Task 3" && x.status == false)); + Assert.NotNull(incompleteTasks.FirstOrDefault(x => x.title == "Task 4" && x.status == false)); + Assert.NotNull(incompleteTasks.FirstOrDefault(x => x.title == "Task 5" && x.status == false)); + } + + + [TestCase("Task 1", "Run")] + [TestCase("Task 2", "Code")] + [TestCase("Task 3", "Jump")] + [TestCase("Task 4", "")] + public void TestRemoveTask(string title, string status) + { + TodoList mylist = new TodoList(); + Task addedTask = mylist.Add(title, status); + Task removedTask = mylist.RemoveTask(title); + + Assert.True(mylist.tasks.Count == 0); + + + } + + [Test] + public void TestSortTasks() + { + TodoList mylist = new TodoList(); + + Task t1 = mylist.Add("a", ""); + Task t2 = mylist.Add("b", ""); + Task t3 = mylist.Add("c", ""); + + List ascendingSort = mylist.SortTasksAlphabetically(true); + List descendingSort = mylist.SortTasksAlphabetically(false); + + Assert.That(t1.status, Is.EqualTo(ascendingSort[0].status)); + Assert.That(t2.status, Is.EqualTo(ascendingSort[1].status)); + Assert.That(t3.status, Is.EqualTo(ascendingSort[2].status)); + + Assert.That(t1.status, Is.EqualTo(descendingSort[2].status)); + Assert.That(t2.status, Is.EqualTo(descendingSort[1].status)); + Assert.That(t3.status, Is.EqualTo(descendingSort[0].status)); + + + } + + + + + + + } } \ 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..8a2e90d7 100644 --- a/tdd-todo-list.CSharp.Test/ExtensionTests.cs +++ b/tdd-todo-list.CSharp.Test/ExtensionTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using NUnit.Framework; namespace tdd_todo_list.CSharp.Test { @@ -14,5 +15,78 @@ public ExtensionTests() { _extension = new TodoListExtension(); } + + [Test] + public void TestGetIds() + { + _extension = new TodoListExtension(); + TaskExtension t1 = _extension.Add("1", ""); + TaskExtension t2 = _extension.Add("2", ""); + TaskExtension t3 = _extension.Add("3", ""); + + List ids = _extension.GetIDs(); + + Assert.Contains(t1.id, ids); + Assert.Contains(t2.id, ids); + Assert.Contains(t3.id, ids); + + } + + + [TestCase("Task 1", "Do some work")] + [TestCase("Task 2", "Take a break")] + public void TestGetTaskById(string title, string description) + { + _extension = new TodoListExtension(); + TaskExtension t1 = _extension.Add(title, description); + + TaskExtension retrievedTask = _extension.GetTaskByID(t1.id); + + Assert.True(t1.Equals(retrievedTask)); + } + + + [TestCase("akdnskd", "...", "ksdskdmks")] + [TestCase("ajsndfouasbfd", "...", "saudasodhasjodhasjd")] + public void UpdateTaskTitleByID(string title, string description, string new_title) + { + _extension = new TodoListExtension(); + TaskExtension t1 = _extension.Add(title, description); + + TaskExtension updated = _extension.UpdateTaskTitle(t1.id, new_title); + + Assert.NotNull(_extension.tasks.FirstOrDefault(x => x.title == new_title)); + Assert.Null(_extension.tasks.FirstOrDefault(x => x.title == title)); + } + + [TestCase("Task 1", "Do some work")] + [TestCase("Task 2", "Take a break")] + public void TestUpdateTaskStatusByID(string title, string description) + { + _extension = new TodoListExtension(); + TaskExtension t1 = _extension.Add(title, description); + Assert.False(t1.status); + TaskExtension updatedTask = _extension.UpdateTaskStatus(t1.id, true); + + Assert.True(updatedTask.status); + } + + [TestCase("Task 1", "Do some work")] + [TestCase("Task 2", "Take a break")] + public void TestTaskListToStr(string title, string description) + { + _extension = new TodoListExtension(); + TaskExtension t1 = _extension.Add(title, description); + string creationTime = _extension.GetCreationTime(); + string expectedOutput = t1.id + " " + t1.title + " " + t1.creationTime.ToString() + "\n"; + Assert.That(expectedOutput, Is.EqualTo(creationTime)); + + } + + + + + + } } 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