diff --git a/domain-model.md b/domain-model.md new file mode 100644 index 00000000..c64798eb --- /dev/null +++ b/domain-model.md @@ -0,0 +1,33 @@ +# Core Requirements + +| Classes | Methods/Properties | Scenario | Outputs +| ----------- | ------------------------------------------------------ | --------------------------------------- | --------------------------------- +| Task.cs | string Name | Name the task | Task name +| Task.cs | Guid Id | Unique identifier for the task | Task ID +| Task.cs | bool IsComplete | Track completion status | True or false +| Task.cs | enum Priority | Task priority Low, Medium, High | Priority status of 3 possible levels +| Task.cs | enum Category | Task categories for differation | Category name +| TodoList.cs | AddTask(string name, enum priority, enum category) | Add task to the list | Task added to list +| TodoList.cs | GetAllTasks() | View all tasks | List of tasks +| TodoList.cs | GetCompletedTasks() | View only completed tasks | Filtered list of tasks +| TodoList.cs | GetIncompleteTasks() | View only incomplete tasks | Filtered list of tasks +| TodoList.cs | ChangeTaskStatus(Guid id, bool isComplete) | Mark task complete/incomplete by ID | Updated task status +| TodoList.cs | SearchTask(string name) | Search task by name | Task found or "Not Found" message +| TodoList.cs | RemoveTask(Guid id) | Remove task from list | Task removed by id +| TodoList.cs | GetTasksAscendingAZ() | Get tasks sorted A-Z | Alphabetically sorted list +| TodoList.cs | GetTasksDescendingAZ() | Get tasks sorted Z-A | Alphabetically sorted list +| TodoList.cs | GetTasksByPriority(string priority) | List tasks by selected priority | List of tasks by priority + +# Extension Requirements + +| Classes | Methods/Properties | Scenario | Outputs +| ----------- | ------------------------------------------ | ---------------------------------------- | ------------- +| Task.cs | GetTaskById(int id) | Retrieve task by ID | Task with matching id +| Task.cs | UpdateTaskName(int id, string newName) | Update task name | Updated task name +| Task.cs | ChangeStatusById(int id, bool isComplete) | Change task status using ID | Updated task +| Task.cs | CreatedAt(DateTime ) | Show creation time | DateTime of creation +| Task.cs | CompletedAt (DateTime) | Show completed time | DateTime of completion +| ToDoList.cs | GetLongestCompletionTime() | Find task that took longest to complete | Task with biggest difference in CreatedAt & CompletedAt +| ToDoList.cs | GetShortestCompletionTime() | Find task that took shortest to complete | Task with shortest difference in CreatedAt & CompletedAt +| ToDoList.cs | GetTasksLongerThanDays(int days) | List tasks completed after x days | List of tasks where the time it took is longer than x days +| ToDoList.cs | GetTasksByCategory(enum category) | List all tasks by category | List of tasks displayed by category diff --git a/tdd-todo-list.CSharp.Main/Task.cs b/tdd-todo-list.CSharp.Main/Task.cs new file mode 100644 index 00000000..bcfd74e3 --- /dev/null +++ b/tdd-todo-list.CSharp.Main/Task.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace tdd_todo_list.CSharp.Main +{ + public class Task + { + public Guid Id { get; set; } + public string Name { get; set; } + public bool IsComplete { get; set; } + public Priority Priority { get; set; } + public Category Category { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime CompletedAt { get; set; } + + public Task(string name, Priority priority, Category category) + { + Id = Guid.NewGuid(); + Name = name; + Priority = priority; + Category = category; + IsComplete = false; + CreatedAt = DateTime.Now; + } + } +} diff --git a/tdd-todo-list.CSharp.Main/ToDoList.cs b/tdd-todo-list.CSharp.Main/ToDoList.cs index 835cb600..b9a916cd 100644 --- a/tdd-todo-list.CSharp.Main/ToDoList.cs +++ b/tdd-todo-list.CSharp.Main/ToDoList.cs @@ -6,7 +6,127 @@ namespace tdd_todo_list.CSharp.Main { - public class TodoList + + public enum Priority + { + Low, + Medium, + High + } + public enum Category + { + Work, + School, + Life + } + + public class ToDoList { + private List tasks = new List(); + + public void AddTask(string name, Priority priority, Category category) + { + var task = new Task(name, priority, category); + tasks.Add(task); + } + + public List GetAllTasks() + { + return tasks; + } + + public List GetCompletedTasks() + { + return tasks.Where(x => x.IsComplete).ToList(); + } + + public List GetInCompletedTasks() + { + return tasks.Where(x => !x.IsComplete).ToList(); + } + + public List ChangeTaskStatus(Guid id, bool isComplete) + { + var task = tasks.Find(x => x.Id == id); + if (task != null) + { + task.IsComplete = isComplete; + task.CompletedAt = isComplete ? DateTime.Now : default; + } + return tasks; + } + + public Task? SearchTask(string name) + { + return tasks.Find(x => x.Name == name); + } + + public void RemoveTask(Guid id) + { + var task = tasks.FirstOrDefault(t => t.Id == id); + if (task != null) + { + tasks.Remove(task); + } + } + + public List GetTasksAscendingAZ() + { + return tasks.OrderBy(x => x.Name).ToList(); + } + + public List GetTasksDescendingAZ() + { + return tasks.OrderByDescending(x => x.Name).ToList(); + } + + public List GetTasksByPriority() + { + return tasks.OrderByDescending(x =>x.Priority).ToList(); + } + + public Task? GetTaskById(Guid id) + { + return tasks.Find(x => x.Id == id); + } + + public void UpdateTaskName(Guid id, string newName) + { + var task = tasks.Find(x => x.Id == id); + if ( task != null) + { + task.Name = newName; + } + } + + public void ChangeStatusById(Guid id, bool isComplete) + { + var task = tasks.Find(x => x.Id == id); + if ( task != null) + { + task.IsComplete = isComplete; + task.CompletedAt = isComplete ? DateTime.Now : default; + } + } + + public Task GetLongestCompletionTime() + { + return null; + } + + public Task GetShortestCompletionTime() + { + return null; + } + + public List GetTasksLongerThanDays(int days) + { + return null; + } + + public List GetTasksByCategory(Category category) + { + return tasks.Where(x => x.Category == category).ToList(); + } } } diff --git a/tdd-todo-list.CSharp.Test/CoreTests.cs b/tdd-todo-list.CSharp.Test/CoreTests.cs index 084cce19..19ae3396 100644 --- a/tdd-todo-list.CSharp.Test/CoreTests.cs +++ b/tdd-todo-list.CSharp.Test/CoreTests.cs @@ -1,17 +1,173 @@ -using tdd_todo_list.CSharp.Main; -using NUnit.Framework; +using NUnit.Framework; +using System.Collections.Generic; +using tdd_todo_list.CSharp.Main; namespace tdd_todo_list.CSharp.Test { [TestFixture] public class CoreTests { + [Test] + public void AddedTaskToList() + { + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Test", Priority.High, Category.Work); + + //act + var tasks = list.GetAllTasks(); + + //assert + Assert.That(tasks[0].Name, Is.EqualTo("Test")); + } + + [Test] + public void ShowsAllTasksOnList() + { + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Test1", Priority.High, Category.Work); + list.AddTask("Test2", Priority.Medium, Category.School); + list.AddTask("Test3", Priority.Low, Category.Life); + + //act + var allTasks = list.GetAllTasks(); + + //assert + Assert.That(allTasks.Count, Is.EqualTo(3)); + + } + + [Test] + public void ChangeTaskStatus() + { + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Test", Priority.High, Category.Work); + + //act + var changed = list.GetAllTasks()[0]; + list.ChangeTaskStatus(changed.Id, true); + + //assert + Assert.That(changed.IsComplete, Is.True); + } + + [Test] + public void GetOnlyCompletedTasks() + { + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Test1", Priority.High, Category.Work); + list.AddTask("Test2", Priority.Medium, Category.School); + + //act + var tasks = list.GetAllTasks()[1]; + list.ChangeTaskStatus(tasks.Id, true); + + //assert + var completedTasks = list.GetCompletedTasks(); + Assert.That(completedTasks[0].Name, Is.EqualTo("Test2")); + } + + [Test] + public void GetOnlyInCompletedTasks() + { + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Test1", Priority.High, Category.Work); + list.AddTask("Test2", Priority.Medium, Category.School); + + //act + var completedTasks = list.GetInCompletedTasks(); + + //assert + Assert.That(completedTasks.Count, Is.EqualTo(2)); + } + + [Test] + public void ErrorMessageIfTaskNotFound() + { + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Test1", Priority.High, Category.Work); + + //act + var search = list.SearchTask("Test32"); + + //assert + Assert.Null(search); + } [Test] - public void FirstTest() + public void RemoveTaskById() { - TodoList core = new TodoList(); - Assert.Pass(); + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Test1", Priority.High, Category.Work); + var task = list.GetAllTasks().First(); + + //act + list.RemoveTask(task.Id); + + //assert + Assert.That(list.GetAllTasks().Count, Is.EqualTo(0)); + } + + [Test] + public void GetTasksAscendingAZ() + { + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Bread", Priority.High, Category.Work); + list.AddTask("Ants", Priority.High, Category.Work); + list.AddTask("Crab", Priority.High, Category.Work); + + //act + var ascendingList = list.GetTasksAscendingAZ(); + + //assert + Assert.That(ascendingList[0].Name, Is.EqualTo("Ants")); + Assert.That(ascendingList[1].Name, Is.EqualTo("Bread")); + Assert.That(ascendingList[2].Name, Is.EqualTo("Crab")); + } + + [Test] + public void GetTasksDescendingAZ() + { + //arrange + ToDoList list = new ToDoList(); + + list.AddTask("Bread", Priority.High, Category.Work); + list.AddTask("Ants", Priority.High, Category.Work); + list.AddTask("Crab", Priority.High, Category.Work); + + //act + var ascendingList = list.GetTasksDescendingAZ(); + + //assert + Assert.That(ascendingList[0].Name, Is.EqualTo("Crab")); + Assert.That(ascendingList[1].Name, Is.EqualTo("Bread")); + Assert.That(ascendingList[2].Name, Is.EqualTo("Ants")); + } + + [Test] + public void ListTasksByPriority() + { + //arrange + ToDoList list = new ToDoList(); + + list.AddTask("Test1", Priority.Medium, Category.Work); + list.AddTask("Test2", Priority.Low, Category.School); + list.AddTask("Test3", Priority.High, Category.Life); + + //act + var byPriority = list.GetTasksByPriority(); + + //assert + Assert.That(byPriority[0].Name, Is.EqualTo("Test3")); + Assert.That(byPriority[1].Name, Is.EqualTo("Test1")); + Assert.That(byPriority[2].Name, Is.EqualTo("Test2")); } } } \ 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..144e5fbe 100644 --- a/tdd-todo-list.CSharp.Test/ExtensionTests.cs +++ b/tdd-todo-list.CSharp.Test/ExtensionTests.cs @@ -1,18 +1,73 @@ -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; namespace tdd_todo_list.CSharp.Test { public class ExtensionTests { - private TodoListExtension _extension; - public ExtensionTests() + [Test] + public void FindATaskById() { - _extension = new TodoListExtension(); + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Test", Priority.High, Category.Work); + + //act + var task = list.GetAllTasks().First(); + var found = list.GetTaskById(task.Id); + + //assert + Assert.That(found?.Name, Is.EqualTo("Test")); + } + + [Test] + public void ChangeTaskNameById() + { + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Test", Priority.High, Category.Work); + + //act + var task = list.GetAllTasks().First(); + list.UpdateTaskName(task.Id, "UpdatedTest"); + var updated = list.GetTaskById(task.Id); + + //assert + Assert.That(updated?.Name, Is.EqualTo("UpdatedTest")); + } + + [Test] + public void TimeCreatedAtIsSet() + { + //arrange + ToDoList list = new ToDoList(); + + //act + list.AddTask("Test", Priority.High, Category.Work); + var task = list.GetAllTasks().First(); + + //assert + Assert.That((DateTime.Now - task.CreatedAt).TotalSeconds, Is.LessThan(2)); + } + + [Test] + public void TimeCompletedAtIsSet() + { + //arrange + ToDoList list = new ToDoList(); + list.AddTask("Test", Priority.High, Category.Work); + var task = list.GetAllTasks().First(); + + //act + list.ChangeStatusById(task.Id, true); + + //assert + Assert.That(task.CompletedAt, Is.Not.EqualTo(default(DateTime))); } } } 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