diff --git a/domainmodel.md b/domainmodel.md new file mode 100644 index 000000000..5424e9ae3 --- /dev/null +++ b/domainmodel.md @@ -0,0 +1,113 @@ +## Core Requirements Domain Model + +### 1. I want to add tasks to my todo list. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | -------------------------------- | --------------------------- | --------------------------------- | ------ | +| TodoList | List tasks | addTask(Task task): boolean | task.name does not exist in tasks | true | +| | | | task.name already exists in tasks | false | +| Task | String name
boolean completed | | | | + + +### 2. I want to see all the tasks in my todo list. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------ | ------------------------- | ------------------------------ | -------------------- | +| TodoList | List tasks | getAllTasks(): List | tasks contains at least 1 task | list of task objects | +| | | | tasks is empty or null | null | + + +### 3. I want to change the status of a task between incomplete and complete. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------ | ---------------------------------- | --------------------------------------------------------------- | ------ | +| TodoList | List tasks | toggleStatus(String name): boolean | tasks contains a Task with name = "X" | true | +| | | | tasks is empty or tasks does not contain a Task with name = "X" | false | + + +### 4. I want to be able to get only the complete tasks. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------ | ------------------------------ | -------------------------------------------------------- | ----------------------- | +| TodoList | List tasks | getCompleteTasks(): List | tasks contains at least one Task where completed == true | list of completed tasks | +| | | | tasks is empty or no Task is completed | empty list or null | + + +### 5. I want to be able to get only the incomplete tasks. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------ | -------------------------------- | --------------------------------------------------------- | ------------------------ | +| TodoList | List tasks | getIncompleteTasks(): List | tasks contains at least one Task where completed == false | list of incomplete tasks | +| | | | tasks is empty or all Tasks are completed | empty list or null | + + +### 6. I want to search for a task and receive a message that says it wasn't found if it doesn't exist. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------ | ----------------------------- | --------------------------------------------------- | ---------------- | +| TodoList | List tasks | findTask(String name): String | tasks contains a Task with name = "X" | task name | +| | | | tasks is empty or does not contain a Task with name | "Task not found" | + + +### 7. I want to remove tasks from my list. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------ | -------------------------------- | --------------------------------------------------- | ------ | +| TodoList | List tasks | removeTask(String name): boolean | tasks contains a Task with name = "X" | true | +| | | | tasks is empty or does not contain a Task with name | false | + + +### 8. I want to see all the tasks in my list ordered alphabetically in ascending order. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------ | ------------------------------- | ----------------------------- | --------------- | +| TodoList | List tasks | getTasksAscending(): List | tasks contains multiple tasks | list sorted A-Z | + + +### 9. I want to see all the tasks in my list ordered alphabetically in descending order. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------ | -------------------------------- | ----------------------------- | --------------- | +| TodoList | List tasks | getTasksDescending(): List | tasks contains multiple tasks | list sorted Z-A | + + +## Extension Requirements Domain Model + +### 1. I want to be able to get a task by a unique ID. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------------------------------------------------------------ | ---------------------------- | ----------------------------------- | ----------- | +| TodoList | List tasks | getTaskById(String id): Task | tasks contains a task with ID = "X" | Task object | +| | | | tasks is empty or no task with ID | null | +| Task | String id
String name
boolean completed
LocalDateTime createdAt | | | | + + + +### 2. I want to update the name of a task by providing its ID and a new name. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------------------------------------------------------------ | -------------------------------------------------- | ------------------------------------- | ------ | +| TodoList | List tasks | updateTaskName(String id, String newName): boolean | task with ID exists
name is unique | true | +| | | | task not found
name not unique | false | +| Task | String id
String name
boolean completed
LocalDateTime createdAt | | | | + + + +### 3. I want to be able to change the status of a task by providing its ID. + +| Class | Instance Variables | Methods | Scenario | Output | +| -------- | ------------------------------------------------------------------------ | ------------------------------------ | ------------------- | ------ | +| TodoList | List tasks | toggleStatusById(String id): boolean | task with ID exists | true | +| | | | task not found | false | +| Task | String id
String name
boolean completed
LocalDateTime createdAt | | | | + + + +### 4. I want to be able to see the date and time that I created each task. + +| Class | Instance Variables | Methods | Scenario | Output | +| ----- | ------------------------------------------------------------------------ | ----------------------------- | -------- | ---------------- | +| Task | String id
String name
boolean completed
LocalDateTime createdAt | getCreatedAt(): LocalDateTime | | Date/time object | + + + diff --git a/src/main/java/com/booleanuk/core/Task.java b/src/main/java/com/booleanuk/core/Task.java new file mode 100644 index 000000000..21f4ae6b8 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Task.java @@ -0,0 +1,23 @@ +package com.booleanuk.core; + +public class Task { + private String name; + private boolean completed; + + public Task(String name) { + this.name = name; + } + + public String getName() { + return name; + } + public boolean isCompleted() { + return completed; + } + + public void setCompleted(boolean completed) { + this.completed = completed; + } + + +} diff --git a/src/main/java/com/booleanuk/core/TodoList.java b/src/main/java/com/booleanuk/core/TodoList.java index 675adaf0b..4f934b9e2 100644 --- a/src/main/java/com/booleanuk/core/TodoList.java +++ b/src/main/java/com/booleanuk/core/TodoList.java @@ -1,5 +1,92 @@ package com.booleanuk.core; +import java.util.ArrayList; +import java.util.List; +import java.util.Comparator; + public class TodoList { + private List tasks; + + public TodoList() { + this.tasks = new ArrayList<>(); + } + + public boolean addTask(Task task) { + for (Task t : tasks) { + if (t.getName().equals(task.getName())) { + return false; + } + } + tasks. add(task); + return true; + } + + public List getAllTasks(){ + return this.tasks; + } + + public boolean toggleStatus(String name) { + for (Task t : tasks) { + if (t.getName().equals(name)) { + t.setCompleted(!t.isCompleted()); + return true; + } + } + return false; + } + + public List getCompleteTasks() { + List completed = new ArrayList<>(); + for (Task task : this.tasks) { + if (task.isCompleted()) { + completed.add(task); + } + } + return completed; + } + + public List getIncompleteTasks(){ + List incompleted = new ArrayList<>(); + for (Task task : this.tasks) { + if (!task.isCompleted()){ + incompleted.add(task); + } + } + return incompleted; + } + + public String findTask(String name) { + for (Task task : tasks) { + if (task.getName().equals(name)) { + return task.getName(); + } + + } + return "Task not found!"; + } + + public boolean removeTask(String name) { + for (Task task : tasks) { + if (task.getName().equals(name)) { + tasks.remove(task); + return true; + } + } + return false; + } + + public List getTasksSortedAscending() { + List sortedTasks = new ArrayList<>(tasks); + sortedTasks.sort(Comparator.comparing(Task::getName)); + return sortedTasks; + } + + public List getTasksSortedDescending() { + List sortedTasks = new ArrayList<>(tasks); + sortedTasks.sort(Comparator.comparing(Task::getName).reversed()); + return sortedTasks; + } + + } diff --git a/src/main/java/com/booleanuk/extension/Task.java b/src/main/java/com/booleanuk/extension/Task.java new file mode 100644 index 000000000..3d794a5b8 --- /dev/null +++ b/src/main/java/com/booleanuk/extension/Task.java @@ -0,0 +1,42 @@ +package com.booleanuk.extension; + +import java.time.LocalDateTime; +import java.util.UUID; + +public class Task { + private final String id; + private String name; + private boolean completed; + private final LocalDateTime createdAt; + + public Task(String name) { + this.id = UUID.randomUUID().toString(); + this.name = name; + this.completed = false; + this.createdAt = LocalDateTime.now(); + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public boolean isCompleted() { + return completed; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setName(String name) { + this.name = name; + } + + public void toggleCompleted() { + this.completed = !this.completed; + } +} diff --git a/src/main/java/com/booleanuk/extension/TodoList.java b/src/main/java/com/booleanuk/extension/TodoList.java new file mode 100644 index 000000000..7aa6553ef --- /dev/null +++ b/src/main/java/com/booleanuk/extension/TodoList.java @@ -0,0 +1,59 @@ +package com.booleanuk.extension; + +import java.util.ArrayList; +import java.util.List; + +public class TodoList { + private final List tasks; + + public TodoList() { + this.tasks = new ArrayList<>(); + } + + public boolean addTask(Task task) { + + for (Task t : tasks) { + if (t.getName().equalsIgnoreCase(task.getName())) { + return false; + } + } + tasks.add(task); + return true; + } + + public Task getTaskById(String id) { + for (Task t : tasks) { + if (t.getId().equals(id)) { + return t; + } + } + return null; + } + public boolean updateTaskName(String id, String newName) { + for (Task t : tasks) { + if (t.getName().equalsIgnoreCase(newName)) { + return false; + } + } + Task task = getTaskById(id); + if (task != null) { + task.setName(newName); + return true; + } + return false; + } + + public boolean toggleStatusById(String id) { + Task task = getTaskById(id); + if (task != null) { + task.toggleCompleted(); + return true; + } + return false; + } + + public List getAllTasks() { + + return this.tasks; + } +} diff --git a/src/test/java/com/booleanuk/core/TodoListTest.java b/src/test/java/com/booleanuk/core/TodoListTest.java index 0bef779a4..3fc2f495a 100644 --- a/src/test/java/com/booleanuk/core/TodoListTest.java +++ b/src/test/java/com/booleanuk/core/TodoListTest.java @@ -2,6 +2,9 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.List; + + class TodoListTest { @Test @@ -10,4 +13,175 @@ public void exampleTest() { Assertions.assertEquals("Hello", hello); Assertions.assertNotEquals("Goodbye", hello); } + + @Test + public void addTaskWhenNotExist(){ + TodoList todoList = new TodoList(); + Task task = new Task("do laundry"); + + boolean result = todoList.addTask(task); + + Assertions.assertTrue(result); + } + + @Test + public void addTaskWhenAlreadyExists() { + TodoList todoList = new TodoList(); + Task task = new Task("Do laundry"); + + todoList.addTask(task); + boolean result = todoList.addTask(task); + + Assertions.assertFalse(result); + } + + @Test + public void testgetAllTasks(){ + TodoList todoList = new TodoList(); + Task task1 = new Task("Buy groceries"); + Task task2 = new Task("Do dishes"); + Task task3 = new Task("Walk the dog"); + + todoList.addTask(task1); + todoList.addTask(task2); + todoList.addTask(task3); + + List tasks = todoList.getAllTasks(); + + Assertions.assertEquals(3,tasks.size()); + Assertions.assertTrue(tasks.contains(task1)); + Assertions.assertTrue(tasks.contains(task2)); + Assertions.assertTrue(tasks.contains(task3)); + } + + @Test + public void testToggleStatus(){ + TodoList todoList = new TodoList(); + Task task1 = new Task("Buy groceries"); + Task task2 = new Task("Walk the dog"); + + todoList.addTask(task1); + todoList.addTask(task2); + + boolean toggledExisting = todoList.toggleStatus("Buy groceries"); + Assertions.assertTrue(toggledExisting); + + boolean toggledNonExisting = todoList.toggleStatus("Walk the dog"); + Assertions.assertTrue(toggledNonExisting); + + } + + @Test + public void testGetCompleteTasks(){ + TodoList todoList = new TodoList(); + Task task1 = new Task("Do dishes"); + Task task2 = new Task("Clean room"); + Task task3 = new Task("Do laundry"); + + todoList.addTask(task1); + todoList.addTask(task2); + todoList.addTask(task3); + + todoList.toggleStatus("Do laundry"); + todoList.toggleStatus("Clean room"); + + List completedTasks = todoList.getCompleteTasks(); + + Assertions.assertEquals(2, completedTasks.size()); + Assertions.assertTrue(completedTasks.contains(task2)); + Assertions.assertTrue(completedTasks.contains(task3)); + Assertions.assertFalse(completedTasks.contains(task1)); + + } + + @Test + public void testGetIncompleteTasks() { + TodoList todoList = new TodoList(); + Task task1 = new Task("Buy groceries"); + Task task2 = new Task("Walk the dog"); + Task task3 = new Task("Do laundry"); + + todoList.addTask(task1); + todoList.addTask(task2); + todoList.addTask(task3); + + todoList.toggleStatus("Walk the dog"); + + List incompleteTasks = todoList.getIncompleteTasks(); + + Assertions.assertTrue(incompleteTasks.contains(task1)); + Assertions.assertTrue(incompleteTasks.contains(task3)); + Assertions.assertFalse(incompleteTasks.contains(task2)); + Assertions.assertEquals(2, incompleteTasks.size()); + } + + @Test + public void testFindTask(){ + TodoList todoList = new TodoList(); + Task task1 = new Task("Buy groceries"); + Task task2 = new Task("Walk the dog"); + + todoList.addTask(task1); + todoList.addTask(task2); + + String foundTaskName = todoList.findTask("Walk the dog"); + Assertions.assertEquals("Walk the dog", foundTaskName); + + String notFoundTaskName = todoList.findTask("Do dishes"); + Assertions.assertEquals("Task not found!", notFoundTaskName); + + + } + + @Test + public void testRemoveTask() { + TodoList todoList = new TodoList(); + Task task1 = new Task("Do laundry"); + Task task2 = new Task("Do dishes"); + + todoList.addTask(task1); + todoList.addTask(task2); + + boolean removed = todoList.removeTask("Do laundry"); + + Assertions.assertTrue(removed); + Assertions.assertEquals(1, todoList.getAllTasks().size()); + Assertions.assertFalse(todoList.getAllTasks().contains(task1)); + Assertions.assertTrue(todoList.getAllTasks().contains(task2)); + + boolean removedNonExisting = todoList.removeTask("Buy groceries"); + Assertions.assertFalse(removedNonExisting); + + } + + @Test + public void testSortTasksAscending() { + TodoList todoList = new TodoList(); + todoList.addTask(new Task("Write report")); + todoList.addTask(new Task("Buy groceries")); + todoList.addTask(new Task("Attend meeting")); + + List sorted = todoList.getTasksSortedAscending(); + + Assertions.assertEquals("Attend meeting", sorted.get(0).getName()); + Assertions.assertEquals("Buy groceries", sorted.get(1).getName()); + Assertions.assertEquals("Write report", sorted.get(2).getName()); + } + + @Test + public void testSortTasksDescending() { + TodoList todoList = new TodoList(); + todoList.addTask(new Task("Write report")); + todoList.addTask(new Task("Buy groceries")); + todoList.addTask(new Task("Attend meeting")); + + List sorted = todoList.getTasksSortedDescending(); + + Assertions.assertEquals("Write report", sorted.get(0).getName()); + Assertions.assertEquals("Buy groceries", sorted.get(1).getName()); + Assertions.assertEquals("Attend meeting", sorted.get(2).getName()); + } + + + } diff --git a/src/test/java/com/booleanuk/extension/TodoListTest.java b/src/test/java/com/booleanuk/extension/TodoListTest.java new file mode 100644 index 000000000..5dcdb4d60 --- /dev/null +++ b/src/test/java/com/booleanuk/extension/TodoListTest.java @@ -0,0 +1,80 @@ +package com.booleanuk.extension; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +public class TodoListTest { + + @Test + public void testAddAndGetTaskById() { + TodoList todoList = new TodoList(); + Task task = new Task("Buy milk"); + + boolean added = todoList.addTask(task); + Assertions.assertTrue(added); + + Task found = todoList.getTaskById(task.getId()); + Assertions.assertNotNull(found); + Assertions.assertEquals(task.getName(), found.getName()); + } + @Test + public void testGetTaskByIdNotFound() { + TodoList todoList = new TodoList(); + Task found = todoList.getTaskById("non-existent-id"); + Assertions.assertNull(found); + } + + @Test + public void testUpdateTaskName() { + TodoList todoList = new TodoList(); + Task task = new Task("Wash car"); + todoList.addTask(task); + + boolean updated = todoList.updateTaskName(task.getId(), "Clean car"); + Assertions.assertTrue(updated); + + Task updatedTask = todoList.getTaskById(task.getId()); + Assertions.assertEquals("Clean car", updatedTask.getName()); + } + + @Test + public void testUpdateTaskNameDuplicateFails() { + TodoList todoList = new TodoList(); + Task task1 = new Task("Task One"); + Task task2 = new Task("Task Two"); + todoList.addTask(task1); + todoList.addTask(task2); + + boolean updated = todoList.updateTaskName(task1.getId(), "Task Two"); + Assertions.assertFalse(updated); + } + @Test + public void testToggleStatusById() { + TodoList todoList = new TodoList(); + Task task = new Task("Do homework"); + todoList.addTask(task); + + Assertions.assertFalse(task.isCompleted()); + boolean toggled = todoList.toggleStatusById(task.getId()); + Assertions.assertTrue(toggled); + Assertions.assertTrue(task.isCompleted()); + } + + @Test + public void testToggleStatusByIdNotFound() { + TodoList todoList = new TodoList(); + boolean toggled = todoList.toggleStatusById("non-existent-id"); + Assertions.assertFalse(toggled); + } + @Test + public void testTaskCreatedAtIsSet() { + Task task = new Task("Read book"); + LocalDateTime now = LocalDateTime.now(); + + Assertions.assertNotNull(task.getCreatedAt()); + Assertions.assertTrue(task.getCreatedAt().isBefore(now.plusSeconds(1))); + Assertions.assertTrue(task.getCreatedAt().isAfter(now.minusSeconds(5))); + } +}