From 8422095033707777535012b4fcd72490a536f819 Mon Sep 17 00:00:00 2001 From: Daria Simonenko Date: Thu, 6 Nov 2025 17:42:51 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=8B=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=208?= =?UTF-8?q?=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0:=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20=D0=B2=D1=80=D0=B5=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=BC=D0=B5=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/dictionaries/project.xml | 1 + src/ru/yandex/javacourse/model/Epic.java | 15 ++ src/ru/yandex/javacourse/model/Subtask.java | 19 +- src/ru/yandex/javacourse/model/Task.java | 47 +++- .../service/FileBackedTaskManager.java | 62 +++++- .../service/InMemoryTaskManager.java | 182 ++++++++++++--- .../javacourse/service/TaskManager.java | 21 ++ test/ru/yandex/javacourse/model/EpicTest.java | 71 +++++- .../yandex/javacourse/model/SubtaskTest.java | 13 ++ .../service/FileBackedTaskManagerTest.java | 56 +++-- .../service/HistoryManagerTest.java | 63 +++++- .../service/InMemoryTaskManagerTest.java | 208 +++++------------- .../javacourse/service/TaskManagerTest.java | 205 ++++++++++++++++- 13 files changed, 740 insertions(+), 223 deletions(-) diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml index cebcbc3..6198672 100644 --- a/.idea/dictionaries/project.xml +++ b/.idea/dictionaries/project.xml @@ -3,6 +3,7 @@ cоздаёт cписок + автосохранения \ No newline at end of file diff --git a/src/ru/yandex/javacourse/model/Epic.java b/src/ru/yandex/javacourse/model/Epic.java index 14d00d1..e2c3057 100644 --- a/src/ru/yandex/javacourse/model/Epic.java +++ b/src/ru/yandex/javacourse/model/Epic.java @@ -1,14 +1,25 @@ package ru.yandex.javacourse.model; +import java.time.LocalDateTime; import java.util.ArrayList; public class Epic extends Task { private ArrayList subtasksIdList = new ArrayList<>(); + private LocalDateTime endTime; public Epic(String name, String description) { super(name, description); } + @Override + public LocalDateTime getEndTime() { + return endTime; + } + + public void setEndTime(LocalDateTime endTime) { + this.endTime = endTime; + } + public ArrayList getSubtasksIdList() { return subtasksIdList; } @@ -38,6 +49,8 @@ public Epic getCopy() { epicCopy.setId(this.getId()); epicCopy.setStatus(this.getStatus()); epicCopy.setSubtasksIdList(new ArrayList<>(this.getSubtasksIdList())); + epicCopy.setDuration(this.getDuration()); + epicCopy.setStartTime(this.getStartTime()); return epicCopy; } @@ -49,6 +62,8 @@ public String toString() { ", description='" + getDescription() + '\'' + ", id=" + getId() + ", status=" + getStatus() + '\'' + + ", startTime=" + getStartTime() + + ", duration =" + getDuration() + ", subtasksIdList=" + subtasksIdList + '}'; } diff --git a/src/ru/yandex/javacourse/model/Subtask.java b/src/ru/yandex/javacourse/model/Subtask.java index b0474ac..c5175c0 100644 --- a/src/ru/yandex/javacourse/model/Subtask.java +++ b/src/ru/yandex/javacourse/model/Subtask.java @@ -1,5 +1,8 @@ package ru.yandex.javacourse.model; +import java.time.Duration; +import java.time.LocalDateTime; + public class Subtask extends Task { private final int epicId; @@ -13,13 +16,25 @@ public Subtask(String name, String description, TaskStatus status, int epicId) { this.epicId = epicId; } + public Subtask(String name, String description, TaskStatus status, int epicId, Duration duration, + LocalDateTime startTime) { + super(name, description, status, duration, startTime); + this.epicId = epicId; + } + + public Subtask(String name, String description, int epicId, Duration duration, LocalDateTime startTime) { + super(name, description, duration, startTime); + this.epicId = epicId; + } + public int getEpicId() { return epicId; } @Override public Subtask getCopy() { - Subtask copySubtask = new Subtask(this.getName(), this.getDescription(), this.getStatus(), this.getEpicId()); + Subtask copySubtask = new Subtask(this.getName(), this.getDescription(), this.getStatus(), this.getEpicId(), + this.getDuration(), this.getStartTime()); copySubtask.setId(this.getId()); return copySubtask; } @@ -32,6 +47,8 @@ public String toString() { ", id=" + getId() + ", status=" + getStatus() + '\'' + ", epicId=" + epicId + + ", startTime=" + getStartTime() + + ", duration =" + getDuration() + '}'; } } diff --git a/src/ru/yandex/javacourse/model/Task.java b/src/ru/yandex/javacourse/model/Task.java index 6fc9253..eda486d 100644 --- a/src/ru/yandex/javacourse/model/Task.java +++ b/src/ru/yandex/javacourse/model/Task.java @@ -1,10 +1,15 @@ package ru.yandex.javacourse.model; +import java.time.Duration; +import java.time.LocalDateTime; + public class Task { private String name; private String description; private int id; private TaskStatus status; + private Duration duration; + private LocalDateTime startTime; public Task(String name, String description) { @@ -19,6 +24,21 @@ public Task(String name, String description, TaskStatus status) { this.status = status; } + public Task(String name, String description, Duration duration, LocalDateTime startTime) { + this.name = name; + this.description = description; + this.duration = duration; + this.startTime = startTime; + } + + public Task(String name, String description, TaskStatus status, Duration duration, LocalDateTime startTime) { + this.name = name; + this.description = description; + this.status = status; + this.duration = duration; + this.startTime = startTime; + } + public String getName() { return name; } @@ -51,8 +71,31 @@ public void setStatus(TaskStatus status) { this.status = status; } + public Duration getDuration() { + return duration; + } + + public void setDuration(Duration duration) { + this.duration = duration; + } + + public LocalDateTime getStartTime() { + return startTime; + } + + public void setStartTime(LocalDateTime startTime) { + this.startTime = startTime; + } + + public LocalDateTime getEndTime() { + if (startTime != null && duration != null) { + return startTime.plus(duration); + } + return null; + } + public Task getCopy() { - Task copyTask = new Task(this.name, this.description, this.status); + Task copyTask = new Task(this.name, this.description, this.status, this.duration, this.startTime); copyTask.setId(this.id); return copyTask; } @@ -78,6 +121,8 @@ public String toString() { ", description='" + description + '\'' + ", id=" + id + ", status=" + status + + ", startTime=" + startTime + + ", duration =" + duration + '}'; } } diff --git a/src/ru/yandex/javacourse/service/FileBackedTaskManager.java b/src/ru/yandex/javacourse/service/FileBackedTaskManager.java index 47b8ba9..0cdc81a 100644 --- a/src/ru/yandex/javacourse/service/FileBackedTaskManager.java +++ b/src/ru/yandex/javacourse/service/FileBackedTaskManager.java @@ -4,7 +4,12 @@ import ru.yandex.javacourse.model.*; import java.io.*; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Optional; +import java.util.TreeSet; public class FileBackedTaskManager extends InMemoryTaskManager { private final File file; @@ -14,19 +19,30 @@ public static void main(String[] args) throws IOException { System.out.println("Файл создан: " + file.getAbsolutePath()); FileBackedTaskManager fileBackedTaskManager = Managers.getDefaultFileBacked(file); - Task task = fileBackedTaskManager.addTask(new Task("Задача", "Описание задачи")); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime nextHour = now.plusHours(1); + LocalDateTime nextDay = now.plusDays(1); + Duration duration30 = Duration.ofMinutes(30); + Duration duration40 = Duration.ofMinutes(40); + + Task task = fileBackedTaskManager.addTask(new Task("Задача", "Описание задачи", TaskStatus.NEW, + duration30, now)); Epic epic = fileBackedTaskManager.addEpic(new Epic("Эпик", "Описание эпика")); Subtask subtask = fileBackedTaskManager.addSubtask(new Subtask("Подзадача", - "Описание подзадачи", epic.getId())); + "Описание подзадачи", TaskStatus.NEW, epic.getId(), duration30, nextHour)); FileBackedTaskManager newFileBackedTaskManager = loadFromFile(file); Task newTask = newFileBackedTaskManager.addTask(new Task("Новая задача", - "Описание новой задачи")); + "Описание новой задачи", TaskStatus.IN_PROGRESS, duration30, nextDay)); - Subtask updatedSubtask = new Subtask("Подзадача", "Описание подзадачи", epic.getId()); + Subtask updatedSubtask = new Subtask("Подзадача", "Описание подзадачи", epic.getId(), duration40, + now); updatedSubtask.setId(subtask.getId()); updatedSubtask.setStatus(TaskStatus.DONE); newFileBackedTaskManager.updateSubtask(updatedSubtask); + + TreeSet prTasks = newFileBackedTaskManager.getPrioritizedTasks(); + prTasks.forEach(System.out::println); } public FileBackedTaskManager(File file) { @@ -39,7 +55,7 @@ public FileBackedTaskManager(File file) { */ public void save() throws ManagerSaveException { try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) { - bw.write("id,type,name,status,description,epic"); + bw.write("id,type,name,status,description,epic,startTime,duration(min)"); bw.newLine(); ArrayList tasks = getAllTasks(); @@ -216,7 +232,7 @@ public String toString(Task task) { } TaskType taskType; - String epicId = ""; + String epicId = "без эпика"; if (task instanceof Subtask subtask) { taskType = TaskType.SUBTASK; epicId = Integer.toString(subtask.getEpicId()); @@ -225,8 +241,23 @@ public String toString(Task task) { } else { taskType = TaskType.TASK; } - return String.format("%s,%s,%s,%s,%s,%s", - task.getId(), taskType, task.getName(), task.getStatus(), task.getDescription(), epicId); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); + String taskStartTimeString = ""; + Optional taskStartTime = Optional.ofNullable(task.getStartTime()); + if (taskStartTime.isPresent()) { + taskStartTimeString = taskStartTime.get().format(formatter); + } + + String taskDurationString = ""; + Optional taskDuration = Optional.ofNullable(task.getDuration()); + if (taskDuration.isPresent()) { + taskDurationString = String.valueOf(taskDuration.get().toMinutes()); + } + + return String.format("%s,%s,%s,%s,%s,%s,%s,%s", + task.getId(), taskType, task.getName(), task.getStatus(), task.getDescription(), epicId, + taskStartTimeString, taskDurationString); } /** @@ -239,10 +270,20 @@ public Task fromString(String value) { String taskName = splitValues[2]; TaskStatus taskStatus = TaskStatus.valueOf(splitValues[3]); String taskDescription = splitValues[4]; + LocalDateTime taskStartTime = null; + Duration taskDuration = null; + + if (splitValues.length > 6 && !splitValues[6].isEmpty()) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); + taskStartTime = LocalDateTime.parse(splitValues[6], formatter); + } + if (splitValues.length > 7 && !splitValues[7].isEmpty()) { + taskDuration = Duration.ofMinutes(Long.parseLong(splitValues[7])); + } if (taskType.equals(TaskType.SUBTASK)) { int epicId = Integer.parseInt(splitValues[5]); - Subtask subTask = new Subtask(taskName, taskDescription, taskStatus, epicId); + Subtask subTask = new Subtask(taskName, taskDescription, taskStatus, epicId, taskDuration, taskStartTime); subTask.setId(taskId); return subTask; } else if (taskType.equals(TaskType.EPIC)) { @@ -250,9 +291,8 @@ public Task fromString(String value) { epic.setId(taskId); return epic; } else { - Task task = new Task(taskName, taskDescription); + Task task = new Task(taskName, taskDescription, taskStatus, taskDuration, taskStartTime); task.setId(taskId); - task.setStatus(taskStatus); return task; } } diff --git a/src/ru/yandex/javacourse/service/InMemoryTaskManager.java b/src/ru/yandex/javacourse/service/InMemoryTaskManager.java index da2ee2e..0078f69 100644 --- a/src/ru/yandex/javacourse/service/InMemoryTaskManager.java +++ b/src/ru/yandex/javacourse/service/InMemoryTaskManager.java @@ -1,9 +1,10 @@ package ru.yandex.javacourse.service; import ru.yandex.javacourse.model.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; public class InMemoryTaskManager implements TaskManager { protected int idCount = 0; @@ -34,9 +35,7 @@ public ArrayList getAllTasks() { */ @Override public void deleteAllTasks() { - for (Integer taskId : tasks.keySet()) { - historyManager.remove(taskId); - } + tasks.keySet().forEach(historyManager::remove); tasks.clear(); } @@ -66,6 +65,12 @@ public Task addTask(Task task) { if (task == null) { return null; } + + boolean hasCross = hasCrossInTimeWithManagerTasks(task); + if (hasCross) { + return null; + } + Task createdTask = task.getCopy(); createdTask.setId(generateId()); tasks.put(createdTask.getId(), createdTask); @@ -83,6 +88,12 @@ public void updateTask(Task task) { if (task == null) { return; } + + boolean hasCross = hasCrossInTimeWithManagerTasks(task); + if (hasCross) { + return; + } + boolean isTaskExists = tasks.containsKey(task.getId()); if (isTaskExists) { Task updatedTask = task.getCopy(); @@ -112,14 +123,8 @@ public ArrayList getAllEpics() { */ @Override public void deleteAllEpics() { - for (Integer subtaskId : subtasks.keySet()) { - historyManager.remove(subtaskId); - } - - for (Integer epicId : epics.keySet()) { - historyManager.remove(epicId); - } - + subtasks.keySet().forEach(historyManager::remove); + epics.keySet().forEach(historyManager::remove); epics.clear(); subtasks.clear(); } @@ -175,6 +180,7 @@ public void updateEpic(Epic epic) { Epic updatedEpic = epic.getCopy(); updatedEpic.setSubtasksIdList(currentEpicSubtasksIdList); updateEpicStatus(updatedEpic); + updateEpicDates(updatedEpic); epics.put(updatedEpic.getId(), updatedEpic); } } @@ -187,16 +193,15 @@ public void updateEpic(Epic epic) { public void deleteEpicById(int id) { historyManager.remove(id); epics.remove(id); - ArrayList subtasksToRemove = new ArrayList<>(); - for (Subtask subtask : subtasks.values()) { - if (subtask.getEpicId() == id) { - subtasksToRemove.add(subtask.getId()); - } - } - for (Integer subtaskId : subtasksToRemove) { + ArrayList subtasksToRemove = subtasks.values().stream() + .filter(subtask -> subtask.getEpicId() == id) + .map(Subtask::getId) + .collect(Collectors.toCollection(ArrayList::new)); + + subtasksToRemove.forEach(subtaskId -> { historyManager.remove(subtaskId); subtasks.remove(subtaskId); - } + }); } /** @@ -214,15 +219,14 @@ public ArrayList getAllSubtasks() { */ @Override public void deleteAllSubtasks() { - for (Integer subtaskId : subtasks.keySet()) { - historyManager.remove(subtaskId); - } - + subtasks.keySet().forEach(historyManager::remove); subtasks.clear(); - for (Epic epic : epics.values()) { + epics.keySet().forEach(epicId -> { + Epic epic = epics.get(epicId); epic.deleteSubtasksIdList(); updateEpicStatus(epic); - } + updateEpicDates(epic); + }); } /** @@ -254,6 +258,11 @@ public Subtask addSubtask(Subtask subtask) { return null; } + boolean hasCross = hasCrossInTimeWithManagerTasks(subtask); + if (hasCross) { + return null; + } + Epic epic = epics.get(subtask.getEpicId()); if (epic == null || subtask.getEpicId() == subtask.getId()) { return null; @@ -264,6 +273,7 @@ public Subtask addSubtask(Subtask subtask) { epic.addSubtaskId(createdSubtask.getId()); updateEpicStatus(epic); + updateEpicDates(epic); return createdSubtask.getCopy(); } @@ -280,12 +290,18 @@ public void updateSubtask(Subtask subtask) { return; } + boolean hasCross = hasCrossInTimeWithManagerTasks(subtask); + if (hasCross) { + return; + } + boolean isSubtaskExists = subtasks.containsKey(subtask.getId()); if (isSubtaskExists) { Subtask updatedSubtask = subtask.getCopy(); subtasks.put(updatedSubtask.getId(), updatedSubtask); Epic epic = epics.get(updatedSubtask.getEpicId()); updateEpicStatus(epic); + updateEpicDates(epic); } } @@ -303,6 +319,7 @@ public void deleteSubtaskById(int id) { Epic epic = epics.get(subtask.getEpicId()); epic.deleteSubtaskId(id); updateEpicStatus(epic); + updateEpicDates(epic); historyManager.remove(id); subtasks.remove(id); @@ -317,13 +334,9 @@ public void deleteSubtaskById(int id) { */ @Override public ArrayList getAllSubtasksByEpicId(int epicId) { - ArrayList subtasksByEpic = new ArrayList<>(); - for (Subtask subtask : subtasks.values()) { - if (subtask.getEpicId() == epicId) { - subtasksByEpic.add(subtask); - } - } - return subtasksByEpic; + return subtasks.values().stream() + .filter(subtask -> subtask.getEpicId() == epicId) + .collect(Collectors.toCollection(ArrayList::new)); } /** @@ -370,4 +383,103 @@ public List getHistory() { return historyManager.getHistory(); } + /** + * Пересчитывает все даты внутри эпика + */ + @Override + public void updateEpicDates(Epic epic) { + if (epic == null) { + return; + } + + Optional epicStartTime = epic.getSubtasksIdList().stream() + .map(subtasks::get) + .filter(Objects::nonNull) + .filter(subtask -> subtask.getStartTime() != null) + .min(Comparator.comparing(Subtask::getStartTime)) + .map(Subtask::getStartTime); + + Optional epicEndTime = epic.getSubtasksIdList().stream() + .map(subtasks::get) + .filter(Objects::nonNull) + .filter(subtask -> subtask.getEndTime() != null) + .max(Comparator.comparing(Subtask::getEndTime)) + .map(Subtask::getEndTime); + + epic.setStartTime(epicStartTime.orElse(null)); + epic.setEndTime(epicEndTime.orElse(null)); + + if (epic.getStartTime() != null && epic.getEndTime() != null) { + Optional epicDuration = epic.getSubtasksIdList().stream() + .map(subtasks::get) + .filter(Objects::nonNull) + .map(Subtask::getDuration) + .filter(Objects::nonNull) + .reduce(Duration::plus); + epic.setDuration(epicDuration.orElse(null)); + } else { + epic.setDuration(null); + } + } + + /** + * Выводит список задач в порядке приоритета + */ + @Override + public TreeSet getPrioritizedTasks() { + List allTasks = new ArrayList<>(); + allTasks.addAll(getAllTasks()); + allTasks.addAll(getAllSubtasks()); + + return allTasks.stream() + .filter(task -> task.getStartTime() != null) + .collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Task::getStartTime)))); + } + + /** + * Проверяет, пересекаются ли две задачи по времени + */ + @Override + public boolean ifTasksCrossInTime(Task firstTask, Task secondTask) { + if (firstTask == null || secondTask == null || firstTask.equals(secondTask)) { + return false; + } + + LocalDateTime firstTaskStartTime = firstTask.getStartTime(); + LocalDateTime firstTaskEndTime = firstTask.getEndTime(); + + LocalDateTime secondTaskStartTime = secondTask.getStartTime(); + LocalDateTime secondTaskEndTime = secondTask.getEndTime(); + + if (firstTaskStartTime == null || firstTaskEndTime == null || secondTaskStartTime == null + || secondTaskEndTime == null) { + return false; + } + + if (firstTaskEndTime.isBefore(secondTaskStartTime) || + secondTaskEndTime.isBefore(firstTaskStartTime)) { + return false; + } + + return true; + } + + /** + * Проверяет, пересекается ли заданная задача с любой задаче из менеджера + * + * @param task задача для проверки + * @return true если есть пересечение по времени, false если пересечений нет или задача не имеет временных меток + */ + @Override + public boolean hasCrossInTimeWithManagerTasks(Task task) { + if (task == null || task.getStartTime() == null || task.getEndTime() == null) { + return false; + } + + Optional overlapTask = getPrioritizedTasks().stream() + .filter(currentTask -> ifTasksCrossInTime(task, currentTask)) + .findFirst(); + + return overlapTask.isPresent(); + } } diff --git a/src/ru/yandex/javacourse/service/TaskManager.java b/src/ru/yandex/javacourse/service/TaskManager.java index 6d52746..6ff557a 100644 --- a/src/ru/yandex/javacourse/service/TaskManager.java +++ b/src/ru/yandex/javacourse/service/TaskManager.java @@ -5,6 +5,7 @@ import ru.yandex.javacourse.model.Task; import java.util.ArrayList; import java.util.List; +import java.util.TreeSet; public interface TaskManager { @@ -112,6 +113,26 @@ public interface TaskManager { * Возвращает список просмотренных задач */ List getHistory(); + + /** + * Пересчитывает все даты внутри эпика + */ + void updateEpicDates(Epic epic); + + /** + * Выводит список задач в порядке приоритета + */ + TreeSet getPrioritizedTasks(); + + /** + * Проверяет, пересекаются ли две задачи по времени + */ + boolean ifTasksCrossInTime(Task firstTask, Task secondTask); + + /** + * Проверяет, пересекается ли заданная задача с любой задаче из менеджера + */ + boolean hasCrossInTimeWithManagerTasks(Task task); } diff --git a/test/ru/yandex/javacourse/model/EpicTest.java b/test/ru/yandex/javacourse/model/EpicTest.java index d6772f0..2b3a222 100644 --- a/test/ru/yandex/javacourse/model/EpicTest.java +++ b/test/ru/yandex/javacourse/model/EpicTest.java @@ -4,7 +4,6 @@ import org.junit.jupiter.api.Test; import ru.yandex.javacourse.service.Managers; import ru.yandex.javacourse.service.TaskManager; - import static org.junit.jupiter.api.Assertions.*; class EpicTest { @@ -13,6 +12,8 @@ class EpicTest { private static final String EPIC_NAME_2 = "Эпик 2"; private static final String EPIC_DESCRIPTION_2 = "Второй эпик"; private static final int EPIC_ID = 1; + private static final String SUBTASK_NAME = "Подзадача"; + private static final String SUBTASK_DESCRIPTION = "Новая подзадача"; TaskManager taskManager = Managers.getDefault(); @@ -45,4 +46,72 @@ public void test_AddSubtask_WhenEpicAddedAsOwnSubtask_ShouldReturnNull() { //then assertNull(resultSubtask, "Смогли добавить эпик в качестве собственной подзадачи"); } + + @Test + @DisplayName("При добавлении подзадач со статусом NEW у эпика тоже должен быть статус NEW") + public void test_AddSubtask_WhenAllSubtasksNew_EpicStatusNew() { + //given + Epic epic = taskManager.addEpic(new Epic(EPIC_NAME_1,EPIC_DESCRIPTION_1)); + + //when + taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, + epic.getId())); + taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, + epic.getId())); + Epic returnedEpic = taskManager.getEpicById(epic.getId()); + + //then + assertEquals("NEW",returnedEpic.getStatus().toString(), "Статус эпика должен быть NEW"); + } + + @Test + @DisplayName("При добавлении подзадач со статусом DONE у эпика тоже должен быть статус DONE") + public void test_AddSubtask_WhenAllSubtasksDone_EpicStatusDone() { + //given + Epic epic = taskManager.addEpic(new Epic(EPIC_NAME_1,EPIC_DESCRIPTION_1)); + + //when + taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, TaskStatus.DONE, + epic.getId())); + taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, TaskStatus.DONE, + epic.getId())); + Epic returnedEpic = taskManager.getEpicById(epic.getId()); + + //then + assertEquals("DONE",returnedEpic.getStatus().toString(), "Статус эпика должен быть DONE"); + } + + @Test + @DisplayName("При добавлении подзадач со статусом IN_PROGRESS у эпика тоже должен быть статус IN_PROGRESS") + public void test_AddSubtask_WhenAllSubtasksInProgress_EpicStatusInProgress() { + //given + Epic epic = taskManager.addEpic(new Epic(EPIC_NAME_1,EPIC_DESCRIPTION_1)); + + //when + taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, TaskStatus.IN_PROGRESS, + epic.getId())); + taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, TaskStatus.IN_PROGRESS, + epic.getId())); + Epic returnedEpic = taskManager.getEpicById(epic.getId()); + + //then + assertEquals("IN_PROGRESS",returnedEpic.getStatus().toString(), "Статус эпика должен быть DONE"); + } + + @Test + @DisplayName("При добавлении подзадач с разными статусами у эпика должен быть статус IN_PROGRESS") + public void test_AddSubtask_WhenSubtasksInProgressDone_EpicStatusInProgress() { + //given + Epic epic = taskManager.addEpic(new Epic(EPIC_NAME_1,EPIC_DESCRIPTION_1)); + + //when + taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, TaskStatus.IN_PROGRESS, + epic.getId())); + taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, TaskStatus.DONE, + epic.getId())); + Epic returnedEpic = taskManager.getEpicById(epic.getId()); + + //then + assertEquals("IN_PROGRESS",returnedEpic.getStatus().toString(), "Статус эпика должен быть DONE"); + } } \ No newline at end of file diff --git a/test/ru/yandex/javacourse/model/SubtaskTest.java b/test/ru/yandex/javacourse/model/SubtaskTest.java index fc7286f..30613c2 100644 --- a/test/ru/yandex/javacourse/model/SubtaskTest.java +++ b/test/ru/yandex/javacourse/model/SubtaskTest.java @@ -45,4 +45,17 @@ public void test_AddSubtask_WhenSubtaskAddedLikeOwnEpic_ShouldReturnNull() { //then assertNull(resultSubtask, "Удалось добавить подзадачу в качестве собственного эпика"); } + + @Test + @DisplayName("Должен возвращать не null EpicId при попытке добавить подзадачу") + public void test_AddSubtask_WhenSubtaskAdded_ShouldHasEpicId() { + //given + Subtask subtask = new Subtask(SUBTASK_NAME_1,SUBTASK_DESCRIPTION_1 , EPIC_ID); + + //when + Integer resultSubtaskEpicId = subtask.getEpicId(); + + //then + assertNotNull(resultSubtaskEpicId, "При добавлении задачи у неё нет id эпика"); + } } \ No newline at end of file diff --git a/test/ru/yandex/javacourse/service/FileBackedTaskManagerTest.java b/test/ru/yandex/javacourse/service/FileBackedTaskManagerTest.java index e4ea181..80fae3a 100644 --- a/test/ru/yandex/javacourse/service/FileBackedTaskManagerTest.java +++ b/test/ru/yandex/javacourse/service/FileBackedTaskManagerTest.java @@ -1,6 +1,5 @@ package ru.yandex.javacourse.service; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import ru.yandex.javacourse.model.Epic; @@ -16,25 +15,22 @@ import static org.junit.jupiter.api.Assertions.*; -class FileBackedTaskManagerTest { +class FileBackedTaskManagerTest extends TaskManagerTest { private static final String TASK_NAME = "Задача"; private static final String TASK_DESCRIPTION = "Новая задача"; + private File file; - FileBackedTaskManager fileBackedTaskManager; - File file; - - @BeforeEach - @DisplayName("Cоздаёт перед каждым тестом новый менеджер и файл") - public void create() throws IOException { + @Override + protected FileBackedTaskManager createTaskManager() throws IOException { file = File.createTempFile("tmpFile", ".txt"); - fileBackedTaskManager = new FileBackedTaskManager(file); + return Managers.getDefaultFileBacked(file); } @Test @DisplayName("Должен успешно создавать пустой файл") public void test_Save_WhenManagerSaved_FileShouldBeEmpty() { //given - fileBackedTaskManager.save(); + taskManager.save(); List fileContent = new ArrayList<>(); String firstString = ""; @@ -58,7 +54,7 @@ public void test_Save_WhenManagerSaved_FileShouldBeEmpty() { @DisplayName("Должен успешно добавлять задачу в файл") public void test_AddTask_WhenTaskAddedToFileBacked_FileShouldBeNotEmpty() { //given - Task task = fileBackedTaskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); + Task task = taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); //when int taskId = -1; @@ -81,8 +77,8 @@ public void test_AddTask_WhenTaskAddedToFileBacked_FileShouldBeNotEmpty() { @DisplayName("Должен успешно добавлять несколько задач в файл") public void test_AddTask_WhenTwoSubtaskAddedToFileBacked_FileShouldStoreAll() { //given - Task task = fileBackedTaskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); - Task secondTask = fileBackedTaskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); + taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); + taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); //when List fileContent = new ArrayList<>(); @@ -113,23 +109,45 @@ public void test_LoadFromFile_WhenReadFromFile_ShouldBeEmpty() throws IOExceptio ArrayList epics = newFileBackedTaskManager.getAllEpics(); //then - assertEquals(0, tasks.size(), "Из должно быть получено 0 задач"); - assertEquals(0, subtasks.size(), "Из должно быть получено 0 подзадач"); - assertEquals(0, epics.size(), "Из должно быть получено 0 эпиков"); + assertEquals(0, tasks.size(), "Из файла должно быть получено 0 задач"); + assertEquals(0, subtasks.size(), "Из файла должно быть получено 0 подзадач"); + assertEquals(0, epics.size(), "Из файла должно быть получено 0 эпиков"); } @Test @DisplayName("Должен возвращать все задачи, добавленные в файл") public void test_LoadFromFile_WhenReadFromFile_ShouldReturnAllTasks() throws IOException { //given - Task task = fileBackedTaskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); - Task secondTask = fileBackedTaskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); + taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); + taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); FileBackedTaskManager newFileBackedTaskManager = FileBackedTaskManager.loadFromFile(file); //when ArrayList tasks = newFileBackedTaskManager.getAllTasks(); //then - assertEquals(2, tasks.size(), "Из должно быть получено 0 задач"); + assertEquals(2, tasks.size(), "Из файла должно быть получено 2 задачи"); + } + + @Test + @DisplayName("Должен бросать исключение при загрузке из несуществующего файла") + public void test_LoadFromFile_WhenFileNotExists_ShouldThrowException() { + //given + File nonExistentFile = new File("test.csv"); + + //when & then + assertThrows(IOException.class, () -> { + FileBackedTaskManager.loadFromFile(nonExistentFile); // Этот код должен бросить IOException + }, "При загрузке из несуществующего файла должен бросить исключение"); + } + + @Test + @DisplayName("Не должен бросать исключение при вызове метода сохранения") + public void test_Save_WhenAddTask_ShouldNotThrowException() { + //given + taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); + + //when & then + assertDoesNotThrow(taskManager::save, "Сохранение не должно вызывать исключений"); } } \ No newline at end of file diff --git a/test/ru/yandex/javacourse/service/HistoryManagerTest.java b/test/ru/yandex/javacourse/service/HistoryManagerTest.java index e97b69f..52e229f 100644 --- a/test/ru/yandex/javacourse/service/HistoryManagerTest.java +++ b/test/ru/yandex/javacourse/service/HistoryManagerTest.java @@ -24,6 +24,16 @@ public void create() { task = new Task(TASK_NAME,TASK_DESCRIPTION); } + @Test + @DisplayName("Должен возвращать true, если без добавления задачи история пустая") + void test_getHistory_WhenTaskNotAddedToHistoryManager_ShouldBeEmpty() { + //given && when + final List history = historyManager.getHistory(); + + //then + assertEquals(0, history.size(), "Без добавления задачи история должна быть пустой."); + } + @Test @DisplayName("Должен возвращать true, если удалось добавить задачу в менеджер") void test_Add_WhenTaskAddedToHistoryManager_ShouldReturnTrue() { @@ -57,7 +67,7 @@ public void test_Add_AfterUpdatedTaskAddToHistoryManager_ShouldStoreLastVersion( } @Test - @DisplayName("Должен возвращать true, если менеджер хранит только последнюю версию задачи") + @DisplayName("Должен возвращать true, если при удалении средней задачи остальные корректно сдвигаются") public void test_Remove_AfterRemoveMiddleTask_ShouldRemainOrder() { //given task.setId(TASK_ID); @@ -76,7 +86,56 @@ public void test_Remove_AfterRemoveMiddleTask_ShouldRemainOrder() { //then assertEquals(2,historyList.size(), "Из истории должна быть удалена одна задача"); - assertEquals(task3.getId(), historyList.get(1).getId(), "Вторая из середины не удалена"); + assertEquals(task.getId(), historyList.get(0).getId(), "Первая задача перестала быть первой"); + assertEquals(task3.getId(), historyList.get(1).getId(), "Третья задача не стала второй"); + } + + @Test + @DisplayName("Должен возвращать true, если при удалении первой задачи остальные корректно сдвигаются") + public void test_Remove_AfterRemoveFirstTask_ShouldRemainOrder() { + //given + task.setId(TASK_ID); + Task task2 = new Task(TASK_NAME + " " + (TASK_ID + 1), TASK_DESCRIPTION + " " + (TASK_ID + 1)); + task2.setId(TASK_ID + 1); + + Task task3 = new Task(TASK_NAME + " " + (TASK_ID + 2), TASK_DESCRIPTION + " " + (TASK_ID + 2)); + task3.setId(TASK_ID + 2); + + //when + historyManager.add(task); + historyManager.add(task2); + historyManager.add(task3); + historyManager.remove(task.getId()); + List historyList = historyManager.getHistory(); + + //then + assertEquals(2,historyList.size(), "Из истории должна быть удалена одна задача"); + assertEquals(task2.getId(), historyList.get(0).getId(), "Вторая задача не стала первой"); + assertEquals(task3.getId(), historyList.get(1).getId(), "Третья задача не стала второй"); + } + + @Test + @DisplayName("Должен возвращать true, если при удалении первой задачи остальные корректно сдвигаются") + public void test_Remove_AfterRemoveLastTask_ShouldRemainOrder() { + //given + task.setId(TASK_ID); + Task task2 = new Task(TASK_NAME + " " + (TASK_ID + 1), TASK_DESCRIPTION + " " + (TASK_ID + 1)); + task2.setId(TASK_ID + 1); + + Task task3 = new Task(TASK_NAME + " " + (TASK_ID + 2), TASK_DESCRIPTION + " " + (TASK_ID + 2)); + task3.setId(TASK_ID + 2); + + //when + historyManager.add(task); + historyManager.add(task2); + historyManager.add(task3); + historyManager.remove(task3.getId()); + List historyList = historyManager.getHistory(); + + //then + assertEquals(2,historyList.size(), "Из истории должна быть удалена одна задача"); + assertEquals(task.getId(), historyList.get(0).getId(), "Первая задача перестала быть первой"); + assertEquals(task2.getId(), historyList.get(1).getId(), "Вторая задача перестала быть второй"); } } \ No newline at end of file diff --git a/test/ru/yandex/javacourse/service/InMemoryTaskManagerTest.java b/test/ru/yandex/javacourse/service/InMemoryTaskManagerTest.java index b752615..1af8949 100644 --- a/test/ru/yandex/javacourse/service/InMemoryTaskManagerTest.java +++ b/test/ru/yandex/javacourse/service/InMemoryTaskManagerTest.java @@ -2,203 +2,111 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import ru.yandex.javacourse.model.Epic; -import ru.yandex.javacourse.model.Subtask; import ru.yandex.javacourse.model.Task; -import java.util.List; +import java.time.Duration; +import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.*; -class InMemoryTaskManagerTest { +class InMemoryTaskManagerTest extends TaskManagerTest { private static final String TASK_NAME = "Задача"; private static final String TASK_DESCRIPTION = "Новая задача"; - private static final int PREDEFINED_TASK_ID = 99; - private static final String TASK_NAME_UPDATED = "Обновлённая задача"; - private static final String TASK_DESCRIPTION_UPDATED = "Новая задача"; - private static final String EPIC_NAME = "Эпик"; - private static final String EPIC_DESCRIPTION = "Новый эпик"; - private static final String SUBTASK_NAME = "Подзадача"; - private static final String SUBTASK_DESCRIPTION = "Новая подзадача"; + private static final Integer TASK_ID = 1; - TaskManager taskManager = Managers.getDefault(); - - @Test - @DisplayName("Должен успешно добавлять задачу и возвращать ее по ID") - public void test_AddTask_WhenTaskAddedToManager_ShouldBeRetrievableById() { - //given - Task task = taskManager.addTask(new Task(TASK_NAME,TASK_DESCRIPTION)); - - //when - Task findTask = taskManager.getTaskById(task.getId()); - - //then - assertNotNull(findTask, "Задача не найдена."); - assertEquals(task, findTask, "Задачи не совпадают."); - - List tasksList = taskManager.getAllTasks(); - - assertNotNull(tasksList, "Задачи не возвращаются"); - assertEquals(1, tasksList.size(), "Неверное количество задач."); - assertEquals(task, tasksList.get(0), "Задачи не совпадают."); - } - - @Test - @DisplayName("Должен успешно добавлять эпик и возвращать его по ID") - public void test_AddEpic_WhenEpicAddedToManager_ShouldBeRetrievableById() { - //given - Epic epic = taskManager.addEpic(new Epic(EPIC_NAME,EPIC_DESCRIPTION)); - - //when - Epic findEpic = taskManager.getEpicById(epic.getId()); - - //then - assertNotNull(findEpic, "Эпик не найден."); - assertEquals(epic, findEpic, "Эпики не совпадают."); - - List epicsList = taskManager.getAllEpics(); - - assertNotNull(epicsList, "Эпики не возвращаются"); - assertEquals(1, epicsList.size(), "Неверное количество эпиков."); - assertEquals(epic, epicsList.get(0), "Эпики не совпадают."); - } - - @Test - @DisplayName("Должен успешно добавлять подзадачу и возвращать ее по ID") - public void test_AddSubtask_WhenSubtaskAddedToManager_ShouldBeRetrievableById() { - //given - Epic epic = taskManager.addEpic(new Epic(EPIC_NAME,EPIC_DESCRIPTION)); - Subtask subtask = taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, - epic.getId())); - - //when - Subtask findSubtask = taskManager.getSubtaskById(subtask.getId()); - - //then - assertNotNull(findSubtask,"Подзадача не найдена."); - assertEquals(subtask, findSubtask, "Подзадачи не совпадают."); - - List subtasksList = taskManager.getAllSubtasks(); - - assertNotNull(subtasksList, "Подзадачи не возвращаются"); - assertEquals(1, subtasksList.size(), "Неверное количество подзадач."); - assertEquals(subtask, subtasksList.get(0), "Подзадачи не совпадают."); - } - - @Test - @DisplayName("Должен генерировать уникальный ID при добавлении задачи с установленным ID") - public void test_AddTask_WhenTaskHasPredefinedId_ShouldGenerateNewId() { - //given - Task task = new Task(TASK_NAME, TASK_DESCRIPTION); - task.setId(PREDEFINED_TASK_ID); - - //when - Task createdTask = taskManager.addTask(task); - - //then - assertNotEquals(task.getId(),createdTask.getId(), "Менеджер не генерит уникальный id во время" + - "добавления задачи"); - - } - - @Test - @DisplayName("Должен сохранять задачу в неизменном виде после добавления в менеджер") - public void test_AddTask_WhenTaskUpdatedAfterAddToTaskManager_TaskShouldRemainUnchanged() { - //given - Task task = taskManager.addTask(new Task(TASK_NAME,TASK_DESCRIPTION)); - - //when - task.setName(TASK_NAME_UPDATED); - task.setDescription(TASK_DESCRIPTION_UPDATED); - - //then - Task findTask = taskManager.getTaskById(task.getId()); - assertEquals(TASK_NAME, findTask.getName(), "Задачи не совпадают по name."); - assertEquals(TASK_DESCRIPTION, findTask.getDescription(), "Задачи не совпадают по description."); + @Override + protected TaskManager createTaskManager() { + return Managers.getDefault(); } @Test - @DisplayName("При удалении задачи из менеджера она должна быть удалена из истории") - public void test_DeleteTaskById_WhenTaskRemoved_HistoryShouldBeEmpty() { + @DisplayName("Должен возвращать false, если при поиске пересечений для сравнения переданы две одинаковые задачи") + public void test_ifTasksCrossInTime_WhenTaskEquals_ShouldReturnFalse() { //given - Task task = taskManager.addTask(new Task(TASK_NAME,TASK_DESCRIPTION)); - taskManager.getTaskById(task.getId()); + LocalDateTime now = LocalDateTime.now(); + Duration taskDuration = Duration.ofMinutes(30); + Task task = taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION,taskDuration, now)); + task.setId(TASK_ID); //when - taskManager.deleteTaskById(task.getId()); + Task firstTask = taskManager.getTaskById(task.getId()); + Task secondTask = taskManager.getTaskById(task.getId()); + boolean hasCross = taskManager.ifTasksCrossInTime(firstTask,secondTask); //then - final List history = taskManager.getHistory(); - assertEquals(0,history.size(), "История после удаления задачи должна быть пустой"); + assertFalse(hasCross, "Пересечение не должно считаться, если задача сравнивается сама с собой."); } @Test - @DisplayName("При удалении эпика из менеджера он должен быть удален из истории") - public void test_DeleteEpicById_WhenEpicRemoved_HistoryShouldBeEmpty() { + @DisplayName("Должен возвращать true, если вторая задача начинается до конца первой") + public void test_ifTasksCrossInTime_WhenTaskStartsBeforeOtherFinish_ShouldReturnTrue() { //given - Epic epic = taskManager.addEpic(new Epic(EPIC_NAME,EPIC_DESCRIPTION)); - taskManager.getEpicById(epic.getId()); + LocalDateTime now = LocalDateTime.now(); + LocalDateTime nowPlus = now.plusHours(1); + Duration taskDuration = Duration.ofHours(10); + Task firstTask = new Task(TASK_NAME, TASK_DESCRIPTION,taskDuration, now); + firstTask.setId(TASK_ID); + Task secondTask = new Task(TASK_NAME, TASK_DESCRIPTION,taskDuration, nowPlus); + secondTask.setId(TASK_ID + 1); //when - taskManager.deleteEpicById(epic.getId()); + boolean hasCross = taskManager.ifTasksCrossInTime(firstTask,secondTask); //then - final List history = taskManager.getHistory(); - assertEquals(0,history.size(), "История после удаления эпика должна быть пустой"); + assertTrue(hasCross, "Задача не может начаться пока другая задача не закончится."); } @Test - @DisplayName("При удалении подзадачи из менеджера она должна быть удален из истории") - public void test_DeleteSubtaskById_WhenSubtaskRemoved_HistoryShouldBeEmpty() { + @DisplayName("Должен возвращать true, если первая задача начинается до конца второй задачи") + public void test_ifTasksCrossInTime_WhenTaskStartsBeforeOtherFinishSwitch_ShouldReturnTrue() { //given - Epic epic = taskManager.addEpic(new Epic(EPIC_NAME,EPIC_DESCRIPTION)); - Subtask subtask = taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, - epic.getId())); - taskManager.getSubtaskById(subtask.getId()); + LocalDateTime secondStart = LocalDateTime.now(); + LocalDateTime firstStart = secondStart.plusHours(3); + Duration firstDuration = Duration.ofHours(10); + Duration secondDuration = Duration.ofHours(4); + Task firstTask = new Task(TASK_NAME, TASK_DESCRIPTION,firstDuration, firstStart); + firstTask.setId(TASK_ID); + Task secondTask = new Task(TASK_NAME, TASK_DESCRIPTION,secondDuration, secondStart); + secondTask.setId(TASK_ID + 1); //when - taskManager.deleteSubtaskById(subtask.getId()); + boolean hasCross = taskManager.ifTasksCrossInTime(firstTask,secondTask); //then - final List history = taskManager.getHistory(); - assertEquals(0,history.size(), "История после удаления подзадачи должна быть пустой"); + assertTrue(hasCross, "Задача не может начаться пока другая задача не закончится."); } @Test - @DisplayName("При удалении подзадач из менеджера она должна быть удален из списка id подзадач эпика") - public void test_DeleteAllSubtask_WhenSubtasksRemoved_EpicSubtasksIdListShouldBeEmpty() { + @DisplayName("Должен возвращать true, если две разные задачи начинаются в одинаковое время") + public void test_ifTasksCrossInTime_WhenTaskHasSameStart_ShouldReturnTrue() { //given - Epic epic = taskManager.addEpic(new Epic(EPIC_NAME,EPIC_DESCRIPTION)); - Subtask subtask1 = taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, - epic.getId())); - Subtask subtask2 = taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, - epic.getId())); - + LocalDateTime now = LocalDateTime.now(); + Duration taskDuration = Duration.ofMinutes(30); + Task firstTask = new Task(TASK_NAME, TASK_DESCRIPTION,taskDuration, now); + firstTask.setId(TASK_ID); + Task secondTask = new Task(TASK_NAME, TASK_DESCRIPTION,taskDuration, now); + firstTask.setId(TASK_ID+1); //when - taskManager.deleteAllSubtasks(); + boolean hasCross = taskManager.ifTasksCrossInTime(firstTask,secondTask); //then - assertEquals(0,epic.getSubtasksIdList().size(), "После удаления подзадач внутри эпиков" + - " не должно оставаться неактуальных id подзадач"); + assertTrue(hasCross, "Задача не должна пересекаться по времени сама с собой."); } @Test - @DisplayName("При удалении эпика из менеджера его подзадачи должны быть удалены из списка подзадач") - public void test_DeleteEpicById_WhenSEpicRemoved_SubtasksShouldBeEmpty() { + @DisplayName("Должен возвращать null при попытке добавить в менеджер задачу, пересекающуюся по времени" + + " с уже добавленной") + public void test_hasCrossInTimeWithManagerTasks_WhenTaskHasSameStart_ShouldReturnNull() { //given - Epic epic = taskManager.addEpic(new Epic(EPIC_NAME,EPIC_DESCRIPTION)); - Subtask subtask1 = taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, - epic.getId())); - Subtask subtask2 = taskManager.addSubtask(new Subtask(SUBTASK_NAME,SUBTASK_DESCRIPTION, - epic.getId())); - + LocalDateTime now = LocalDateTime.now(); + Duration taskDuration = Duration.ofDays(30); + taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION,taskDuration, now)); //when - taskManager.deleteEpicById(epic.getId()); - List subtasks = taskManager.getAllSubtasks(); + Task secondTask = taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION,taskDuration, now)); //then - assertEquals(0,subtasks.size(), "После удаления эпика список подзадач должен быть очищен"); + assertNull(secondTask, "Задача не может быть добавлена в менеджер, если есть пересечение по времени"); } } \ No newline at end of file diff --git a/test/ru/yandex/javacourse/service/TaskManagerTest.java b/test/ru/yandex/javacourse/service/TaskManagerTest.java index e902741..ade67f9 100644 --- a/test/ru/yandex/javacourse/service/TaskManagerTest.java +++ b/test/ru/yandex/javacourse/service/TaskManagerTest.java @@ -1,20 +1,40 @@ package ru.yandex.javacourse.service; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import ru.yandex.javacourse.model.Epic; +import ru.yandex.javacourse.model.Subtask; import ru.yandex.javacourse.model.Task; + +import java.io.IOException; +import java.util.List; import static org.junit.jupiter.api.Assertions.*; -class TaskManagerTest { +abstract class TaskManagerTest { private static final String TASK_NAME = "Задача"; private static final String TASK_DESCRIPTION = "Новая задача"; - TaskManager taskManager = Managers.getDefault(); + private static final int PREDEFINED_TASK_ID = 99; + private static final String TASK_NAME_UPDATED = "Обновлённая задача"; + private static final String TASK_DESCRIPTION_UPDATED = "Новая задача"; + private static final String EPIC_NAME = "Эпик"; + private static final String EPIC_DESCRIPTION = "Новый эпик"; + private static final String SUBTASK_NAME = "Подзадача"; + private static final String SUBTASK_DESCRIPTION = "Новая подзадача"; + + protected T taskManager; + protected abstract T createTaskManager() throws IOException; + + @BeforeEach + void setTaskManager() throws IOException { + taskManager = createTaskManager(); + } @Test @DisplayName("Должен сохранять задачу в неизменном виде после добавления в менеджер") public void test_AddTask_WhenTaskAddedToTaskManager_TaskShouldRemainUnchanged() { //given - Task task = taskManager.addTask(new Task(TASK_NAME,TASK_DESCRIPTION)); + Task task = taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); //when Task findTask = taskManager.getTaskById(task.getId()); @@ -25,4 +45,183 @@ public void test_AddTask_WhenTaskAddedToTaskManager_TaskShouldRemainUnchanged() assertEquals(task.getDescription(), findTask.getDescription(), "Задачи не совпадают по description."); } + @Test + @DisplayName("Должен успешно добавлять задачу и возвращать ее по ID") + public void test_AddTask_WhenTaskAddedToManager_ShouldBeRetrievableById() { + //given + Task task = taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); + + //when + Task findTask = taskManager.getTaskById(task.getId()); + + //then + assertNotNull(findTask, "Задача не найдена."); + assertEquals(task, findTask, "Задачи не совпадают."); + + List tasksList = taskManager.getAllTasks(); + + assertNotNull(tasksList, "Задачи не возвращаются"); + assertEquals(1, tasksList.size(), "Неверное количество задач."); + assertEquals(task, tasksList.get(0), "Задачи не совпадают."); + } + + @Test + @DisplayName("Должен успешно добавлять эпик и возвращать его по ID") + public void test_AddEpic_WhenEpicAddedToManager_ShouldBeRetrievableById() { + //given + Epic epic = taskManager.addEpic(new Epic(EPIC_NAME, EPIC_DESCRIPTION)); + + //when + Epic findEpic = taskManager.getEpicById(epic.getId()); + + //then + assertNotNull(findEpic, "Эпик не найден."); + assertEquals(epic, findEpic, "Эпики не совпадают."); + + List epicsList = taskManager.getAllEpics(); + + assertNotNull(epicsList, "Эпики не возвращаются"); + assertEquals(1, epicsList.size(), "Неверное количество эпиков."); + assertEquals(epic, epicsList.get(0), "Эпики не совпадают."); + } + + @Test + @DisplayName("Должен успешно добавлять подзадачу и возвращать ее по ID") + public void test_AddSubtask_WhenSubtaskAddedToManager_ShouldBeRetrievableById() { + //given + Epic epic = taskManager.addEpic(new Epic(EPIC_NAME, EPIC_DESCRIPTION)); + Subtask subtask = taskManager.addSubtask(new Subtask(SUBTASK_NAME, SUBTASK_DESCRIPTION, + epic.getId())); + + //when + Subtask findSubtask = taskManager.getSubtaskById(subtask.getId()); + + //then + assertNotNull(findSubtask, "Подзадача не найдена."); + assertEquals(subtask, findSubtask, "Подзадачи не совпадают."); + + List subtasksList = taskManager.getAllSubtasks(); + + assertNotNull(subtasksList, "Подзадачи не возвращаются"); + assertEquals(1, subtasksList.size(), "Неверное количество подзадач."); + assertEquals(subtask, subtasksList.get(0), "Подзадачи не совпадают."); + } + + @Test + @DisplayName("Должен генерировать уникальный ID при добавлении задачи с установленным ID") + public void test_AddTask_WhenTaskHasPredefinedId_ShouldGenerateNewId() { + //given + Task task = new Task(TASK_NAME, TASK_DESCRIPTION); + task.setId(PREDEFINED_TASK_ID); + + //when + Task createdTask = taskManager.addTask(task); + + //then + assertNotEquals(task.getId(), createdTask.getId(), "Менеджер не генерит уникальный id во время" + + "добавления задачи"); + + } + + @Test + @DisplayName("Должен сохранять задачу в неизменном виде после добавления в менеджер") + public void test_AddTask_WhenTaskUpdatedAfterAddToTaskManager_TaskShouldRemainUnchanged() { + //given + Task task = taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); + + //when + task.setName(TASK_NAME_UPDATED); + task.setDescription(TASK_DESCRIPTION_UPDATED); + + //then + Task findTask = taskManager.getTaskById(task.getId()); + assertEquals(TASK_NAME, findTask.getName(), "Задачи не совпадают по name."); + assertEquals(TASK_DESCRIPTION, findTask.getDescription(), "Задачи не совпадают по description."); + } + + @Test + @DisplayName("При удалении задачи из менеджера она должна быть удалена из истории") + public void test_DeleteTaskById_WhenTaskRemoved_HistoryShouldBeEmpty() { + //given + Task task = taskManager.addTask(new Task(TASK_NAME, TASK_DESCRIPTION)); + taskManager.getTaskById(task.getId()); + + //when + taskManager.deleteTaskById(task.getId()); + + //then + final List history = taskManager.getHistory(); + assertEquals(0, history.size(), "История после удаления задачи должна быть пустой"); + } + + @Test + @DisplayName("При удалении эпика из менеджера он должен быть удален из истории") + public void test_DeleteEpicById_WhenEpicRemoved_HistoryShouldBeEmpty() { + //given + Epic epic = taskManager.addEpic(new Epic(EPIC_NAME, EPIC_DESCRIPTION)); + taskManager.getEpicById(epic.getId()); + + //when + taskManager.deleteEpicById(epic.getId()); + + //then + final List history = taskManager.getHistory(); + assertEquals(0, history.size(), "История после удаления эпика должна быть пустой"); + } + + @Test + @DisplayName("При удалении подзадачи из менеджера она должна быть удален из истории") + public void test_DeleteSubtaskById_WhenSubtaskRemoved_HistoryShouldBeEmpty() { + //given + Epic epic = taskManager.addEpic(new Epic(EPIC_NAME, EPIC_DESCRIPTION)); + Subtask subtask = taskManager.addSubtask(new Subtask(SUBTASK_NAME, SUBTASK_DESCRIPTION, + epic.getId())); + taskManager.getSubtaskById(subtask.getId()); + + + //when + taskManager.deleteSubtaskById(subtask.getId()); + + //then + final List history = taskManager.getHistory(); + assertEquals(0, history.size(), "История после удаления подзадачи должна быть пустой"); + } + + @Test + @DisplayName("При удалении подзадач из менеджера она должна быть удален из списка id подзадач эпика") + public void test_DeleteAllSubtask_WhenSubtasksRemoved_EpicSubtasksIdListShouldBeEmpty() { + //given + Epic epic = taskManager.addEpic(new Epic(EPIC_NAME, EPIC_DESCRIPTION)); + taskManager.addSubtask(new Subtask(SUBTASK_NAME, SUBTASK_DESCRIPTION, + epic.getId())); + taskManager.addSubtask(new Subtask(SUBTASK_NAME, SUBTASK_DESCRIPTION, + epic.getId())); + + + //when + taskManager.deleteAllSubtasks(); + + //then + assertEquals(0, epic.getSubtasksIdList().size(), "После удаления подзадач внутри эпиков" + + " не должно оставаться неактуальных id подзадач"); + } + + @Test + @DisplayName("При удалении эпика из менеджера его подзадачи должны быть удалены из списка подзадач") + public void test_DeleteEpicById_WhenSEpicRemoved_SubtasksShouldBeEmpty() { + //given + Epic epic = taskManager.addEpic(new Epic(EPIC_NAME, EPIC_DESCRIPTION)); + taskManager.addSubtask(new Subtask(SUBTASK_NAME, SUBTASK_DESCRIPTION, + epic.getId())); + taskManager.addSubtask(new Subtask(SUBTASK_NAME, SUBTASK_DESCRIPTION, + epic.getId())); + + + //when + taskManager.deleteEpicById(epic.getId()); + List subtasks = taskManager.getAllSubtasks(); + + //then + assertEquals(0, subtasks.size(), "После удаления эпика список подзадач должен быть очищен"); + } } \ No newline at end of file