diff --git a/src/Main.java b/src/Main.java index 6414bc2..4bb3b69 100644 --- a/src/Main.java +++ b/src/Main.java @@ -88,5 +88,62 @@ public static void main(String[] args) { System.out.println(inMemoryTaskManager.getAllSubtask()); System.out.println(inMemoryTaskManager.getEpicList()); System.out.println(inMemoryTaskManager.getTaskList()); + //спринт6 + inMemoryTaskManager.deleteHistory(); + Task task10 = new Task("1", "тело1", TaskStatus.NEW); + Task task20 = new Task("2", "тело2", TaskStatus.IN_PROGRESS); + inMemoryTaskManager.addTask(task10); + inMemoryTaskManager.addTask(task20); + inMemoryTaskManager.getTaskForId(task10.getId()); + System.out.println("первый таск в истории"); + System.out.println(inMemoryTaskManager.getHistory()); + System.out.println(); + inMemoryTaskManager.getTaskForId(task20.getId()); + System.out.println("добавили второй"); + System.out.println(inMemoryTaskManager.getHistory()); + System.out.println(); + inMemoryTaskManager.getTaskForId(task10.getId()); + System.out.println("обратились к первому должен появится в конце и пропасть в начале"); + System.out.println(inMemoryTaskManager.getHistory()); + System.out.println("Доп задание"); + System.out.println(); + + Epic epic01 = new Epic("Эпик1", "Описание 1",TaskStatus.NEW); + inMemoryTaskManager.addEpic(epic01); + Subtask subtask01 = new Subtask("подзадача 1", "тело", epic01.getId(), TaskStatus.NEW); + Subtask subtask02 = new Subtask("подзадача 2", "тело", epic01.getId(), TaskStatus.NEW); + Subtask subtask03 = new Subtask("подзадача 3", "тело", epic01.getId(), TaskStatus.NEW); + inMemoryTaskManager.addSubtask(subtask01); + inMemoryTaskManager.addSubtask(subtask02); + inMemoryTaskManager.addSubtask(subtask03); + Epic epic02 = new Epic("Эпик2", "Описание 1",TaskStatus.IN_PROGRESS); + inMemoryTaskManager.addEpic(epic02); + System.out.println("Пустой список"); + inMemoryTaskManager.deleteHistory(); + System.out.println(inMemoryTaskManager.getHistory()); + inMemoryTaskManager.getEpicForId(epic01.getId()); + System.out.println("Первый эпик"); + System.out.println(inMemoryTaskManager.getHistory()); + inMemoryTaskManager.getSubtaskForId(subtask01.getId()); + System.out.println("Прибавили подзадачу 1 первого эпика"); + System.out.println(inMemoryTaskManager.getHistory()); + inMemoryTaskManager.getSubtaskForId(subtask03.getId()); + System.out.println("Прибавили подзадачу 3 первого эпика"); + System.out.println(inMemoryTaskManager.getHistory()); + inMemoryTaskManager.getSubtaskForId(subtask01.getId()); + System.out.println("Подзадача 1 первого эпика должна быть в хвосте"); + System.out.println(inMemoryTaskManager.getHistory()); + inMemoryTaskManager.removeSubtaskForId(subtask03.getId()); + System.out.println("Удалили подзадачу 3 эпика 1"); + System.out.println(inMemoryTaskManager.getHistory()); + inMemoryTaskManager.removeEpicForId(epic01.getId()); + System.out.println("Удалили эпик с подзадачей"); + System.out.println(inMemoryTaskManager.getHistory()); + + + + + + } } diff --git a/src/managers/HistoryManager.java b/src/managers/HistoryManager.java index 91f00a1..aae0eb9 100644 --- a/src/managers/HistoryManager.java +++ b/src/managers/HistoryManager.java @@ -6,6 +6,8 @@ public interface HistoryManager { void add(Task task); + void remove(int id); + void deleteHistory(); List getHistory(); } \ No newline at end of file diff --git a/src/managers/InMemoryHistoryManager.java b/src/managers/InMemoryHistoryManager.java index 7b339bb..7fd9140 100644 --- a/src/managers/InMemoryHistoryManager.java +++ b/src/managers/InMemoryHistoryManager.java @@ -1,30 +1,108 @@ package managers; import tasks.Task; -import java.util.LinkedList; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; public class InMemoryHistoryManager implements HistoryManager { + private static class Node { + public Task task; + public Node next; + public Node prev; - private LinkedList history = new LinkedList<>(); + public Node(Node prev, Task task, Node next) { + this.task = task; + this.next = next; + this.prev = prev; + } - public static final int MAX_HISTORY_COUNT = 10; + @Override + public String toString() { + return "Node{" + + "task=" + task + + ", next=" + next + (next == null ? null : next.task) + + ", prev=" + prev + (prev == null ? null : prev.task) + + '}'; + } + } + + private final HashMap mapHistory = new HashMap<>(); + private Node head; + private Node tail; @Override public void add(Task task) { if (task == null) { return; } - history.add(new Task(task)); - if (history.size() > MAX_HISTORY_COUNT) { - history.removeFirst(); + final int id = task.getId(); + removeNode(id); + mapHistory.put(id, linkLast(task)); + } + + private ArrayList getTasks() { + ArrayList historyList = new ArrayList<>(); + Node copyHead = head; + while (copyHead != null) { //идем по копии головы пока не пустая + historyList.add(copyHead.task); + copyHead = copyHead.next; //копия головы ссылается теперь на соседа справа } + return historyList; } @Override public List getHistory() { - LinkedList copyHistory = new LinkedList<>(); - copyHistory.addAll(history); - return copyHistory; + return getTasks(); + } + + private Node linkLast(Task task) { + final Node oldTail = tail; + Node newNode = new Node(oldTail, task, null); //создаем узел + if (oldTail == null) { //если соседа слева нет + head = newNode; //голова новый узел + } else { + oldTail.next = newNode; // у соседа слева делаем ссылку на новый узел + } + tail = newNode; //теперь хвост ссылается на новый узел + return tail; + } + + private void removeNode(int id) { + if (mapHistory.containsKey(id)) { //если история содержит элемент с id нужно для удаления + final Node node = mapHistory.remove(id); + if (node == null) { //Если узлов не было + return; + } + if (node.prev != null) { //Если есть узел слева + node.prev.next = node.next; //переписываем у соседа слева ссылку на соседа справа + if (node.next == null) { //но если соседа справа нет + tail = node.prev; //хвост списка сосед слева + } else { + node.next.prev = node.prev; //сосед справа хвостом ссылается на соседа слева + } + } else { //Если это первый узел + head = node.next; //голова ссылается на соседа справа + if (head == null) { // + tail = null; + } else { + head.prev = null; + } + } + } else { + return; + } + } + + @Override + public void remove(int id) { + removeNode(id); + } + + @Override + public void deleteHistory() { //для тестов + mapHistory.clear(); + tail = null; + head = null; } } diff --git a/src/managers/InMemoryTaskManager.java b/src/managers/InMemoryTaskManager.java index a624a29..223544c 100644 --- a/src/managers/InMemoryTaskManager.java +++ b/src/managers/InMemoryTaskManager.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; public class InMemoryTaskManager implements TaskManager { @@ -45,11 +46,17 @@ public ArrayList getAllSubtask() { @Override public void deleteTaskList() { + for (Integer id : taskList.keySet()) { + historyManager.remove(id); + } taskList.clear(); } @Override public void deleteAllSubtask() { + for (Integer id : subtaskList.keySet()) { + historyManager.remove(id); + } subtaskList.clear(); for (Epic epic : epicList.values()) { //идем по списку эпиков checkStatus(epic); @@ -58,40 +65,59 @@ public void deleteAllSubtask() { @Override public void deleteAllEpic() { + for (Integer id : epicList.keySet()) { + historyManager.remove(id); + } epicList.clear(); + for (Integer id : subtaskList.keySet()) { + historyManager.remove(id); + } subtaskList.clear(); } @Override - public void deleteEpicSubtask(Epic epic) { - for (Integer id : subtaskList.keySet()) { - if (id.equals(epic.getId())) { - subtaskList.remove(id); + public void deleteEpicSubtask(Epic epic) { //удаление подзадача по переданному эпику + List idToRemove = new ArrayList<>(); + for (Subtask subtask : subtaskList.values()) { + if (subtask.getEpicId() == epic.getId()) { + idToRemove.add(subtask.getId()); } } + for (Integer key : idToRemove) { + subtaskList.remove(key); + historyManager.remove(key); + } checkStatus(epic); } @Override public void removeTaskForId(Integer id) { taskList.remove(id); + historyManager.remove(id); } @Override public void removeEpicForId(Integer id) { epicList.remove(id); - for (Subtask subtask : subtaskList.values()) { //удаляем подзадачи которые не существуют без эпика + historyManager.remove(id); //чтобы избежать ConcurrentModificationException + List idToRemove = new ArrayList<>(); //формируем список на удаление + for (Subtask subtask : subtaskList.values()) { //ищем подзадачи по id удаляемого эпика if (subtask.getEpicId() == id) { - subtaskList.remove(subtask.getId()); + idToRemove.add(subtask.getId()); } } + for (Integer key : idToRemove) { + subtaskList.remove(key); + historyManager.remove(key); + } } @Override public void removeSubtaskForId(Integer id) { int epicId = subtaskList.get(id).getEpicId(); subtaskList.remove(id); - checkStatus(epicList.get(epicId)); //проверяем статус эпика из которого удалили подзадачу + checkStatus(epicList.get(epicId));//проверяем статус эпика из которого удалили подзадачу + historyManager.remove(id); } @Override @@ -194,4 +220,12 @@ public void checkStatus(Epic epic) { epic.setStatus(TaskStatus.NEW); } } + + public List getHistory() { + return historyManager.getHistory(); + } + + public void deleteHistory() { + historyManager.deleteHistory(); + } } \ No newline at end of file diff --git a/test/managers/InMemoryHistoryManagerTest.java b/test/managers/InMemoryHistoryManagerTest.java index 69c27e3..d1f7883 100644 --- a/test/managers/InMemoryHistoryManagerTest.java +++ b/test/managers/InMemoryHistoryManagerTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import tasks.Task; import tasks.TaskStatus; @@ -20,21 +21,53 @@ public void createHistoryManager() { } @Test + @DisplayName("Проверка что Таск в истории меняет статус если мы его поменяли и добавили в список") public void testHistoryAddWithChangeTaskStatus() { Task task = new Task("переезд", "переезд в другой город", TaskStatus.NEW); historyManager.add(task); assertEquals(1, historyManager.getHistory().size(), "Задача не добавлена"); task.setStatus(TaskStatus.IN_PROGRESS); historyManager.add(task); - assertEquals(TaskStatus.NEW, historyManager.getHistory().get(0).getStatus()); + assertEquals(TaskStatus.IN_PROGRESS, historyManager.getHistory().get(0).getStatus()); } @Test + @DisplayName("Проверка добавления тасков в историю их количества") void add() { - Task task = new Task("переезд", "переезд в другой город", TaskStatus.NEW); - historyManager.add(task); + Task task1 = new Task("1", "тело1", TaskStatus.NEW); + task1.setId(1); + historyManager.add(task1); + Task task2 = new Task("2", "тело2", TaskStatus.IN_PROGRESS); + task2.setId(2); + historyManager.add(task2); final List history = historyManager.getHistory(); assertNotNull(history, "После добавления задачи, история не должна быть пустой."); - assertEquals(1, history.size(), "После добавления задачи, история не должна быть пустой."); + assertEquals(2, history.size(), "После добавления задачи, история не должна быть пустой."); + + } + + @Test + @DisplayName("Проверка удаления Таска из истории") + public void remove() { + Task task = new Task("переезд", "переезд в другой город", TaskStatus.NEW); + final List history = historyManager.getHistory(); + historyManager.add(task); + historyManager.remove(task.getId()); + assertNotNull(history, "История должна быть пустой после удаления"); + } + + @Test + @DisplayName("Проверка корректного расположения таска после повторного получения его") + public void testHistoryChangePositions() { + Task task1 = new Task("1", "тело1", TaskStatus.NEW); + task1.setId(1); + historyManager.add(task1); + Task task2 = new Task("2", "тело2", TaskStatus.IN_PROGRESS); + task2.setId(2); + historyManager.add(task2); + final List history1 = historyManager.getHistory(); + historyManager.add(task1); + final List history2 = historyManager.getHistory(); + assertNotEquals(history1, history2, "Списки должны различаться расположением элементов"); } } \ No newline at end of file diff --git a/test/managers/InMemoryTaskManagerTest.java b/test/managers/InMemoryTaskManagerTest.java index 3ba1ce0..26f5718 100644 --- a/test/managers/InMemoryTaskManagerTest.java +++ b/test/managers/InMemoryTaskManagerTest.java @@ -1,6 +1,7 @@ package managers; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import tasks.Epic; import tasks.Task; @@ -18,6 +19,7 @@ public void createTaskManager() { } @Test + @DisplayName("Проверка присвоения разных id") public void getDifferentTypes() { Task task = new Task("Таск", "Тело таска", TaskStatus.NEW); taskManager.addTask(task); diff --git a/test/managers/ManagersTest.java b/test/managers/ManagersTest.java index 3e05c8b..53b09c5 100644 --- a/test/managers/ManagersTest.java +++ b/test/managers/ManagersTest.java @@ -1,5 +1,6 @@ package managers; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -7,6 +8,7 @@ class ManagersTest { @Test + @DisplayName("Проверка создания менеджеров") public void createManager() { HistoryManager historyManager = Managers.getDefaultHistory(); TaskManager taskManager = Managers.getDefault();; diff --git a/test/tasks/EpicTest.java b/test/tasks/EpicTest.java index 24a1f04..51682dd 100644 --- a/test/tasks/EpicTest.java +++ b/test/tasks/EpicTest.java @@ -3,6 +3,7 @@ import managers.Managers; import managers.TaskManager; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -19,6 +20,7 @@ public void createTaskManager() { } @Test + @DisplayName("Добавление эпика") void addNewEpic() { Epic epic = new Epic("Эпик", "Тело эпика",TaskStatus.NEW); taskManager.addEpic(epic); diff --git a/test/tasks/SubtaskTest.java b/test/tasks/SubtaskTest.java index 9a497f7..f78f15c 100644 --- a/test/tasks/SubtaskTest.java +++ b/test/tasks/SubtaskTest.java @@ -3,6 +3,7 @@ import managers.Managers; import managers.TaskManager; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -19,6 +20,7 @@ public void createTaskManager() { } @Test + @DisplayName("Добавление подзадачи") void addNewSubtask() { Epic epic = new Epic("Эпик", "Тело эпика",TaskStatus.NEW); taskManager.addEpic(epic); diff --git a/test/tasks/TaskTest.java b/test/tasks/TaskTest.java index ad69675..3e9f27f 100644 --- a/test/tasks/TaskTest.java +++ b/test/tasks/TaskTest.java @@ -4,6 +4,7 @@ import managers.Managers; import managers.TaskManager; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -20,6 +21,7 @@ public void createTaskManager() { } @Test + @DisplayName("Добавление задачи") void addNewTask() { Task task = new Task("Таск", "Тело таска",TaskStatus.NEW); taskManager.addTask(task);