diff --git a/src/main/java/com/booleanuk/core/TodoList.java b/src/main/java/com/booleanuk/core/TodoList.java index 675adaf0b..f8aa0921d 100644 --- a/src/main/java/com/booleanuk/core/TodoList.java +++ b/src/main/java/com/booleanuk/core/TodoList.java @@ -1,5 +1,88 @@ package com.booleanuk.core; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + public class TodoList { + HashMap todoMap = new HashMap<>(); + + public TodoList(HashMap map) { + this.todoMap = map; + } + + public Boolean add(String task) { + if (task.toLowerCase().trim().isEmpty()) { + return false; + } else if (todoMap.containsKey(task.toLowerCase().trim())) { + return false; + } + + todoMap.put(task, false); + return true; + } + + public HashMap getAll() { + return todoMap; + } + + public ArrayList getCompletedTasks() { + ArrayList completedTasks = new ArrayList<>(); + + for (Map.Entry entry : todoMap.entrySet()) + if (entry.getValue().equals(true)) + completedTasks.add(entry.getKey()); + + return completedTasks; + } + + public ArrayList getIncompleteTasks() { + ArrayList incompleteTasks = new ArrayList<>(); + + for (Map.Entry entry : todoMap.entrySet()) + if (entry.getValue().equals(false)) + incompleteTasks.add(entry.getKey()); + + return incompleteTasks; + } + + public Boolean toggleStatus(String taskName) { + for (Map.Entry entry : todoMap.entrySet()) + if (entry.getKey().equals(taskName.toLowerCase().trim())) { + entry.setValue(!entry.getValue()); + return true; + } + return false; + } + + public String searchForTask(String taskName) { + for (Map.Entry entry : todoMap.entrySet()) + if (entry.getKey().equals(taskName.toLowerCase().trim())) + return "Task found."; + return "Task not found."; + } + + public void removeTask(String task) { + for (Map.Entry entry : todoMap.entrySet()) + if (entry.getKey().equals(task.toLowerCase().trim())) { + todoMap.remove(entry.getKey()); + return; + } + } + + // Can use TreeMap as return ?? + public ArrayList getAllAscending() { + ArrayList keyList = new ArrayList<>(todoMap.keySet()); + keyList.sort(null); + return keyList; + } + + public ArrayList getAllDescending() { + ArrayList keyList = new ArrayList<>(todoMap.keySet()); + keyList.sort(null); + Collections.reverse(keyList); + return keyList; + } } diff --git a/src/main/java/com/booleanuk/core/domain-model.md b/src/main/java/com/booleanuk/core/domain-model.md new file mode 100644 index 000000000..55454a984 --- /dev/null +++ b/src/main/java/com/booleanuk/core/domain-model.md @@ -0,0 +1,16 @@ + + +| **Class** | **Members** | **Methods** | **Scenario** | **Outputs** | +| ---------- | ------------------------------------ | -------------------------------------- |--------------------------------------------------------------------------------|----------------------------| +| `TodoList` | `HashMap todoMap` | `add(String name)` | Task is not in the list | `true` | +| | | | Task with same name already exists | `false` | +| | | `getAll()` | List contains tasks | `HashMap` | +| | | `getCompleted()` | Some tasks are marked as complete | `HashMap` | +| | | `getIncomplete()` | Some tasks are incomplete | `HashMap` | +| | | `toggleStatus(String name)` | Task with that name exists — changes from incomplete to complete or vice versa | `true` / `false` | +| | | `search(String name)` | Task with that name exists | `"Task found"` | +| | | | Task does not exist | `"Task not found"` | +| | | `remove(String name)` | Task removed from list | `true` | +| | | | Task does not exist | `false` | +| | | `getAllAsc()` | Returns all tasks sorted by name A–Z | `HashMap` | +| | | `getAllDesc()` | Returns all tasks sorted Z–A | `HashMap` | 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..ebe740457 --- /dev/null +++ b/src/main/java/com/booleanuk/extension/Task.java @@ -0,0 +1,72 @@ +package com.booleanuk.extension; + +import java.time.LocalDateTime; +import java.util.Date; + +public class Task { + private int id; + private String name; + private Date creationTime; + private Boolean status; + + public Task(int id, String name, Boolean status) { + this.id = id; + this.name = name; + this.creationTime = getRandomDate(); + this.status = status; + } + + public Date getRandomDate() { + long currentTime = System.currentTimeMillis(); + // Define time range: last year (365 days) + long yearInMillis = 365L * 24 * 60 * 60 * 1000; + long randomTime = currentTime - (long)(Math.random() * yearInMillis); + return new Date(randomTime); + } + + public Task() { + + } + + public Boolean getStatus() { + return status; + } + + public void setStatus(Boolean status) { + this.status = status; + } + + public void toggleStatus() { + this.status = !status; + } + + public Date getCreationTime() { + return creationTime; + } + + public void setCreationTime(Date creationTime) { + this.creationTime = creationTime; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} + +// +//I want to be able to get a task by a unique ID. +//I want to update the name of a task by providing its ID and a new name. +//I want to be able to change the status of a task by providing its ID. +//I want to be able to see the date and time that I created each task. \ No newline at end of file diff --git a/src/main/java/com/booleanuk/extension/TodoListExtension.java b/src/main/java/com/booleanuk/extension/TodoListExtension.java new file mode 100644 index 000000000..f31a65bc3 --- /dev/null +++ b/src/main/java/com/booleanuk/extension/TodoListExtension.java @@ -0,0 +1,52 @@ +package com.booleanuk.extension; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; + +public class TodoListExtension { + ArrayList taskList = new ArrayList<>(); + + public TodoListExtension() { + taskList.add(new Task(1, "task1", false)); + taskList.add(new Task(2, "task2", false)); + taskList.add(new Task(3, "task3", false)); + taskList.add(new Task(4, "task4", false)); + } + + public void addTask(Task newTask) { + taskList.add(newTask); + } + + public Task getTaskByID(int id) { + for (Task task : taskList) { + if (task.getId() == id) { + return task; + } + } + return null; + } + + public void updateTask(int id, String newName) { + for (Task task : taskList) + if (task.getId() == id) + task.setName(newName); + } + + public void changeStatusWithId(int id) { + taskList.stream() + .filter(task -> task.getId() == id) + .findFirst().map(task -> {task.toggleStatus(); + return null; + }); + } + + public Date getTaskCreationTime(String taskName) { + for (Task task : taskList) { + if (task.getName().equals(taskName)) { + return task.getCreationTime(); + } + } + return null; + } +} diff --git a/src/test/java/com/booleanuk/core/TodoListTest.java b/src/test/java/com/booleanuk/core/TodoListTest.java index 0bef779a4..4ec39483f 100644 --- a/src/test/java/com/booleanuk/core/TodoListTest.java +++ b/src/test/java/com/booleanuk/core/TodoListTest.java @@ -3,11 +3,157 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.HashMap; +import java.util.List; + class TodoListTest { + private HashMap testmap = null; + + public void loadTasks() { + testmap = new HashMap<>(); + testmap.put("task1", false); + testmap.put("task2", false); + testmap.put("task3", true); + testmap.put("task4", false); + testmap.put("task5", true); + } + + @Test + public void addTaskThatDoesNotExist() { + loadTasks(); + TodoList list = new TodoList(testmap); + + Assertions.assertFalse(list.add("Task1")); + Assertions.assertFalse(list.add("Task2")); + Assertions.assertFalse(list.add("task2")); + Assertions.assertTrue(list.add("Task10")); + Assertions.assertFalse(list.add("Task5")); + Assertions.assertTrue(list.add("Task20")); + Assertions.assertFalse(list.add(" ")); + } + + @Test + public void addTaskThatAlreadyExists() { + loadTasks(); + TodoList list = new TodoList(testmap); + Assertions.assertFalse(list.add("Task1")); + Assertions.assertTrue(list.add("Task11")); + Assertions.assertFalse(list.add("task1")); // Case-sensitive + Assertions.assertFalse(list.add(" ")); + } + + @Test + public void getAllTasksReturnsMapOrEmptyMapIfNoContent() { + TodoList list = new TodoList(HashMap.newHashMap(0)); + Assertions.assertEquals(0, list.getAll().size()); // Test on Empty + + loadTasks(); + TodoList list2 = new TodoList(testmap); + Assertions.assertEquals(5, list2.getAll().size()); + list2.add("item6"); + Assertions.assertEquals(6, list2.getAll().size()); + } + + @Test + public void getCompletedTasks() { + loadTasks(); + TodoList list = new TodoList(testmap); + + Assertions.assertEquals(2, list.getCompletedTasks().size()); + list.add("task25"); + Assertions.assertEquals(2, list.getCompletedTasks().size()); + } + + @Test + public void getIncompleteTasks() { + loadTasks(); + TodoList list = new TodoList(testmap); + + Assertions.assertEquals(3, list.getIncompleteTasks().size()); + list.add("task25"); + Assertions.assertEquals(4, list.getIncompleteTasks().size()); + } + @Test - public void exampleTest() { - String hello = "Hello"; - Assertions.assertEquals("Hello", hello); - Assertions.assertNotEquals("Goodbye", hello); + public void toggleTaskStatus() { + loadTasks(); + TodoList list = new TodoList(testmap); + + Assertions.assertTrue(list.toggleStatus("task1")); + Assertions.assertFalse(list.toggleStatus("task500")); //task do not exist + Assertions.assertFalse(list.toggleStatus(" ")); + } + + @Test + public void searchForTaskWhichExists() { + loadTasks(); + TodoList list = new TodoList(testmap); + Assertions.assertEquals("Task found.", list.searchForTask("task2")); + Assertions.assertEquals("Task found.", list.searchForTask("task5")); + Assertions.assertEquals("Task found.", list.searchForTask("Task5")); + } + + @Test + public void searchForTaskThatDoesNotExist() { + loadTasks(); + TodoList list = new TodoList(testmap); + Assertions.assertEquals("Task not found.", list.searchForTask("task22")); + Assertions.assertEquals("Task not found.", list.searchForTask("task5515")); + Assertions.assertEquals("Task not found.", list.searchForTask("task")); + Assertions.assertEquals("Task not found.", list.searchForTask(" ")); + } + + @Test + public void removeTaskWhichExists() { + loadTasks(); + TodoList list = new TodoList(testmap); + Assertions.assertEquals(5, list.getAll().size()); + list.removeTask("task2"); + Assertions.assertEquals(4, list.getAll().size()); + list.removeTask("task1"); + Assertions.assertEquals(3, list.getAll().size()); + list.removeTask("task5"); + list.removeTask("task4"); + Assertions.assertEquals(1, list.getAll().size()); } + + @Test + public void removeTaskThatDoNotExist() { + loadTasks(); + TodoList list = new TodoList(testmap); + + list.removeTask("task2"); + Assertions.assertEquals(4, list.getAll().size()); + list.removeTask("task10"); + Assertions.assertEquals(4, list.getAll().size()); + list.removeTask(""); + Assertions.assertEquals(4, list.getAll().size()); + list.removeTask(" "); + Assertions.assertEquals(4, list.getAll().size()); + } + + @Test + public void getTasksInAscendingOrder() { + testmap = new HashMap<>(); + testmap.put("b", false); + testmap.put("d", false); + testmap.put("c", false); + testmap.put("a", false); + TodoList list = new TodoList(testmap); + + Assertions.assertEquals(List.of("a", "b", "c", "d"), list.getAllAscending()); + } + + @Test + public void getTasksInDescendingOrder() { + testmap = new HashMap<>(); + testmap.put("b", false); + testmap.put("d", false); + testmap.put("c", false); + testmap.put("a", false); + TodoList list = new TodoList(testmap); + + Assertions.assertEquals(List.of("d", "c", "b", "a"), list.getAllDescending()); + } + } diff --git a/src/test/java/com/booleanuk/extension/TodoListExtensionTest.java b/src/test/java/com/booleanuk/extension/TodoListExtensionTest.java new file mode 100644 index 000000000..11af8a24d --- /dev/null +++ b/src/test/java/com/booleanuk/extension/TodoListExtensionTest.java @@ -0,0 +1,53 @@ +package com.booleanuk.extension; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class TodoListExtensionTest { + + @Test + public void addTaskSuccessfully() { + TodoListExtension todo = new TodoListExtension(); + Task newTask = new Task(5, "task5", false); + todo.addTask(newTask); + Assertions.assertEquals("task5", todo.getTaskByID(5).getName()); + } + + @Test + public void getTaskByIdElseNotFoundResponse() { + TodoListExtension todo = new TodoListExtension(); + Assertions.assertEquals(1, todo.getTaskByID(1).getId()); + Task task2 = todo.getTaskByID(10); + Assertions.assertNull(task2); + } + + @Test + public void updateTaskByIdAndName() { + TodoListExtension todo = new TodoListExtension(); + + Assertions.assertEquals("task2", todo.getTaskByID(2).getName()); + todo.updateTask(2, "test new name"); + Assertions.assertEquals("test new name", todo.getTaskByID(2).getName()); + } + + @Test + public void updateNonExistentTaskDoesNothing() { + TodoListExtension todo = new TodoListExtension(); + todo.updateTask(99, "newTask"); + Assertions.assertNull(todo.getTaskByID(99)); + } + + @Test + public void changeStatusByTaskId() { + TodoListExtension todo = new TodoListExtension(); + + Assertions.assertFalse(todo.getTaskByID(3).getStatus()); + todo.changeStatusWithId(3); + Assertions.assertTrue(todo.getTaskByID(3).getStatus()); + todo.changeStatusWithId(3); + Assertions.assertFalse(todo.getTaskByID(3).getStatus()); + todo.changeStatusWithId(4); + Assertions.assertTrue(todo.getTaskByID(4).getStatus()); + } + +}