From 81416cb2e2e7be24177a69662465658dcd3b7745 Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Tue, 15 Jul 2025 22:36:50 +0300 Subject: [PATCH 1/7] =?UTF-8?q?feuture:=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=B0=208=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Main.java | 28 ++++-- .../controllers/FileBackedTaskManager.java | 42 ++++---- .../controllers/InMemoryTaskManager.java | 99 ++++++++++++++++--- src/tracker/controllers/TaskManager.java | 2 + src/tracker/model/Epic.java | 29 +++++- src/tracker/model/Subtask.java | 14 ++- src/tracker/model/Task.java | 49 ++++++++- .../FileBackedTaskManagerTest.java | 18 +++- .../InMemoryHistoryManagerTest.java | 16 ++- .../controllers/InMemoryTaskManagerTest.java | 28 +++--- test/tracker/model/SubtaskTest.java | 10 +- 11 files changed, 261 insertions(+), 74 deletions(-) diff --git a/src/Main.java b/src/Main.java index a0d9915..a17bfa5 100644 --- a/src/Main.java +++ b/src/Main.java @@ -5,29 +5,37 @@ import tracker.model.Subtask; import tracker.model.Task; +import java.time.LocalDateTime; + public class Main { public static void main(String[] args) { + final long MINUTES_IN_DAY = 60 * 24; + final LocalDateTime TASK_START_TIME = LocalDateTime.now(); System.out.println("Поехали!"); TaskManager inMemoryTaskManager = Managers.getDefault(); // Создайте две задачи, а также эпик с двумя подзадачами и эпик с одной подзадачей - Task task1 = new Task("tracker.model.Task 1", "Do task 1", inMemoryTaskManager.getTaskId()); + Task task1 = new Task("tracker.model.Task 1", "Do task 1", inMemoryTaskManager.getTaskId(), + MINUTES_IN_DAY, TASK_START_TIME.minusDays(4)); inMemoryTaskManager.createTask(task1); - Task task2 = new Task("tracker.model.Task 2", "Do task 2", inMemoryTaskManager.getTaskId()); + Task task2 = new Task("tracker.model.Task 2", "Do task 2", inMemoryTaskManager.getTaskId(), + MINUTES_IN_DAY, TASK_START_TIME.minusDays(3)); inMemoryTaskManager.createTask(task2); - Epic epic1 = new Epic("tracker.model.Epic 1", "Do all subtasks from epic 1", inMemoryTaskManager.getTaskId()); + Epic epic1 = new Epic("tracker.model.Epic 1", "Do all subtasks from epic 1", + inMemoryTaskManager.getTaskId()); inMemoryTaskManager.createEpic(epic1); - Epic epic2 = new Epic("tracker.model.Epic 2", "Do all subtasks from epic 2", inMemoryTaskManager.getTaskId()); + Epic epic2 = new Epic("tracker.model.Epic 2", "Do all subtasks from epic 2", + inMemoryTaskManager.getTaskId()); inMemoryTaskManager.createEpic(epic2); - Subtask subtask1 = new Subtask("tracker.model.Subtask 1", "Do subtask 1", - inMemoryTaskManager.getTaskId(), epic1); + Subtask subtask1 = new Subtask("tracker.model.Subtask 1", "Do subtask 1", inMemoryTaskManager.getTaskId(), + epic1, MINUTES_IN_DAY, TASK_START_TIME.minusDays(2)); inMemoryTaskManager.createSubtask(subtask1); - Subtask subtask2 = new Subtask("tracker.model.Subtask 2", "Do subtask 2", - inMemoryTaskManager.getTaskId(), epic1); + Subtask subtask2 = new Subtask("tracker.model.Subtask 2", "Do subtask 2", inMemoryTaskManager.getTaskId(), + epic1, MINUTES_IN_DAY, TASK_START_TIME.minusDays(1)); inMemoryTaskManager.createSubtask(subtask2); - Subtask subtask3 = new Subtask("tracker.model.Subtask 3", "Do subtask 3", - inMemoryTaskManager.getTaskId(), epic2); + Subtask subtask3 = new Subtask("tracker.model.Subtask 3", "Do subtask 3", inMemoryTaskManager.getTaskId(), + epic2, MINUTES_IN_DAY, TASK_START_TIME); inMemoryTaskManager.createSubtask(subtask3); // Распечатайте списки эпиков, задач и подзадач через System.out.println(..) diff --git a/src/tracker/controllers/FileBackedTaskManager.java b/src/tracker/controllers/FileBackedTaskManager.java index 43b97eb..ed62bcc 100644 --- a/src/tracker/controllers/FileBackedTaskManager.java +++ b/src/tracker/controllers/FileBackedTaskManager.java @@ -12,10 +12,11 @@ import java.io.Writer; import java.nio.file.Files; import java.nio.file.Path; +import java.time.LocalDateTime; public class FileBackedTaskManager extends InMemoryTaskManager { - private static final String HEADER = "id,type,name,status,description,epic"; + private static final String HEADER = "id,type,name,status,description,duration,startTime,endTime,epic"; private final File file; public FileBackedTaskManager(File file) { @@ -24,14 +25,22 @@ public FileBackedTaskManager(File file) { } public static void main(String[] args) { + final long MINUTES_IN_DAY = 60 * 24; + final LocalDateTime TASK_START_TIME = LocalDateTime.now(); + // Заведите несколько разных задач, эпиков и подзадач. - Task task1 = new Task("task 1", "task 1", 1, Status.NEW); - Task task2 = new Task("task 2", "task 2", 2, Status.NEW); + Task task1 = new Task("task 1", "task 1", 1, Status.NEW, MINUTES_IN_DAY, + TASK_START_TIME.minusDays(4)); + Task task2 = new Task("task 2", "task 2", 2, Status.NEW, MINUTES_IN_DAY, + TASK_START_TIME.minusDays(3)); Epic epic1 = new Epic("epic 1", "epic 1", 3); Epic epic2 = new Epic("epic 2", "epic 2", 4); - Subtask subtask1 = new Subtask("subtask 1", "subtask 1", 5, epic1); - Subtask subtask2 = new Subtask("subtask 2", "subtask 2", 6, epic1); - Subtask subtask3 = new Subtask("subtask 3", "subtask 3", 7, epic2); + Subtask subtask1 = new Subtask("subtask 1", "subtask 1", 5, epic1, MINUTES_IN_DAY, + TASK_START_TIME.minusDays(2)); + Subtask subtask2 = new Subtask("subtask 2", "subtask 2", 6, epic1, MINUTES_IN_DAY, + TASK_START_TIME.minusDays(1)); + Subtask subtask3 = new Subtask("subtask 3", "subtask 3", 7, epic2, MINUTES_IN_DAY, + TASK_START_TIME); try { File tempFile = File.createTempFile("sprint7-", ".csv"); @@ -185,19 +194,14 @@ static void fromString(String value, FileBackedTaskManager fileBackedTasksManage String[] elements = value.split(","); int id = Integer.parseInt(elements[0]); switch (elements[1]) { - case "TASK": - fileBackedTasksManager.tasks.put(id, new Task(elements[2], elements[4], id, - Status.valueOf(elements[3]))); - break; - case "EPIC": - fileBackedTasksManager.epics.put(id, new Epic(elements[2], elements[4], id, - Status.valueOf(elements[3]))); - break; - case "SUBTASK": - fileBackedTasksManager.subtasks.put(id, new Subtask(elements[2], elements[4], id, - Status.valueOf(elements[3]), - fileBackedTasksManager.getEpicById(Integer.parseInt(elements[5])))); - break; + case "TASK" -> fileBackedTasksManager.tasks.put(id, new Task(elements[2], elements[4], id, + Status.valueOf(elements[3]), Long.parseLong(elements[5]), LocalDateTime.parse(elements[6]))); + case "EPIC" -> fileBackedTasksManager.epics.put(id, new Epic(elements[2], elements[4], id, + Status.valueOf(elements[3]), Long.parseLong(elements[5]), LocalDateTime.parse(elements[6]), + LocalDateTime.parse(elements[7]))); + case "SUBTASK" -> fileBackedTasksManager.subtasks.put(id, new Subtask(elements[2], elements[4], id, + Status.valueOf(elements[3]), fileBackedTasksManager.getEpicById(Integer.parseInt(elements[8])), + Long.parseLong(elements[5]), LocalDateTime.parse(elements[6]))); } if (id > fileBackedTasksManager.taskId) { fileBackedTasksManager.taskId = id; diff --git a/src/tracker/controllers/InMemoryTaskManager.java b/src/tracker/controllers/InMemoryTaskManager.java index 9073857..84148aa 100644 --- a/src/tracker/controllers/InMemoryTaskManager.java +++ b/src/tracker/controllers/InMemoryTaskManager.java @@ -5,9 +5,8 @@ import tracker.model.Subtask; import tracker.model.Task; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.time.LocalDateTime; +import java.util.*; public class InMemoryTaskManager implements TaskManager { protected final HashMap tasks; @@ -15,6 +14,7 @@ public class InMemoryTaskManager implements TaskManager { protected final HashMap epics; private final HistoryManager inMemoryHistoryManager; protected int taskId; + private final Comparator comparator; public InMemoryTaskManager() { tasks = new HashMap<>(); @@ -22,6 +22,19 @@ public InMemoryTaskManager() { epics = new HashMap<>(); taskId = 1; inMemoryHistoryManager = Managers.getDefaultHistory(); + comparator = (task1, task2) -> { + LocalDateTime t1 = task1.getStartTime(); + LocalDateTime t2 = task2.getStartTime(); + if (task1.equals(task2)) { + return 0; + } else if (t1.isBefore(t2)) { + return -1; + } else if (t1.isAfter(t2) || t1.equals(t2)) { + return 1; + } + + return 0; + }; } @Override @@ -113,15 +126,24 @@ public ArrayList getEpicsSubtasks(int epicId) { // Создание. Сам объект должен передаваться в качестве параметра. @Override public void createTask(Task task) { - tasks.put(taskId, task); - taskId++; + if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { + tasks.put(taskId, task); + taskId++; + } else { + System.out.println("Пересечение с текущими задачами"); + } } @Override public void createSubtask(Subtask task) { - subtasks.put(taskId, task); - updateEpicStatus(task.getEpic()); - taskId++; + if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { + subtasks.put(taskId, task); + updateEpicStatus(task.getEpic()); + updateEpicDuration(task.getEpic()); + taskId++; + } else { + System.out.println("Пересечение с текущими задачами."); + } } @Override @@ -137,8 +159,11 @@ public void updateTask(Task task) { if (updatedTask == null) { System.out.println("Задача с id = " + task.getId() + " не найдена"); } - - tasks.put(task.getId(), task); + if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { + tasks.put(task.getId(), task); + } else { + System.out.println("Пересечение с текущими задачами"); + } } @Override @@ -147,9 +172,13 @@ public void updateSubtask(Subtask task) { if (updatedTask == null) { System.out.println("Задача с id = " + task.getId() + " не найдена"); } - - updateEpicStatus(task.getEpic()); - subtasks.put(task.getId(), task); + if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { + updateEpicStatus(task.getEpic()); + updateEpicDuration(task.getEpic()); + subtasks.put(task.getId(), task); + } else { + System.out.println("Пересечение с текущими задачами"); + } } @Override @@ -173,6 +202,20 @@ public void updateEpicStatus(Epic epic) { epic.setStatus(Status.IN_PROGRESS); } } + @Override + public void updateEpicDuration(Epic epic) { + ArrayList epicSubtasks = getEpicsSubtasks(epic.getId()); + int epicDuration = 0; + for (Subtask subtask: epicSubtasks) { + epicDuration += subtask.getDuration(); + } + TreeSet sortedTasks = new TreeSet<>(comparator); + sortedTasks.addAll(epicSubtasks); + LocalDateTime epicStartTime = sortedTasks.first().getStartTime(); + epic.setStartTime(epicStartTime); + epic.setDuration(epicDuration); + epic.setEndTime(epicStartTime.plusMinutes(epicDuration)); + } @Override public void updateEpic(Epic task) { @@ -195,6 +238,7 @@ public void deleteSubtask(Subtask task) { inMemoryHistoryManager.remove(task.getId()); subtasks.remove(task.getId()); updateEpicStatus(task.getEpic()); + updateEpicDuration(task.getEpic()); } @Override @@ -213,4 +257,33 @@ public void deleteEpic(Epic epic) { public List getHistory() { return inMemoryHistoryManager.getHistory(); } + + public TreeSet getPrioritizedTasks() { + TreeSet sortedTasks = new TreeSet<>(comparator); + sortedTasks.addAll(tasks.values()); + sortedTasks.addAll(subtasks.values()); + return sortedTasks; + } + + private boolean intersectionChecked (T task1, T task2) { + LocalDateTime endTime1 = task1.getStartTime().plusSeconds(task1.getDuration()); + LocalDateTime endTime2 = task2.getStartTime().plusSeconds(task2.getDuration()); + return task1.getStartTime().isBefore(task2.getStartTime()) && endTime1.isAfter(task2.getStartTime()) + || task1.getStartTime().isBefore(endTime2) && endTime1.isAfter(endTime2); + } + + private boolean noIntersectionWithTasks(T task) { + List intersectedTasks = tasks.values().stream() + .filter(currentTask -> intersectionChecked(task, currentTask)) + .toList(); + return intersectedTasks.isEmpty(); + } + + private boolean noIntersectionWithSubtasks(T task) { + List intersectedTasks = subtasks.values().stream() + .filter(currentTask -> intersectionChecked(task, currentTask)) + .toList(); + return intersectedTasks.isEmpty(); + } } + diff --git a/src/tracker/controllers/TaskManager.java b/src/tracker/controllers/TaskManager.java index 44d7d9d..2aa776b 100644 --- a/src/tracker/controllers/TaskManager.java +++ b/src/tracker/controllers/TaskManager.java @@ -48,6 +48,8 @@ public interface TaskManager { void updateEpicStatus(Epic epic); + void updateEpicDuration(Epic epic); + void updateEpic(Epic task); // Удаление по идентификатору diff --git a/src/tracker/model/Epic.java b/src/tracker/model/Epic.java index 3d763ca..ee66279 100644 --- a/src/tracker/model/Epic.java +++ b/src/tracker/model/Epic.java @@ -1,16 +1,43 @@ package tracker.model; +import java.time.LocalDateTime; + public class Epic extends Task { + + private LocalDateTime endTime; + + @Override + public LocalDateTime getEndTime() { + return endTime; + } + + public void setEndTime(LocalDateTime endTime) { + this.endTime = endTime; + } + public Epic(String name, String description, int id) { super(name, description, id); + this.duration = 0; + this.startTime = LocalDateTime.of(1970, 1, 1, 0, 0); + this.endTime = LocalDateTime.of(1970, 1, 1, 0, 0); } public Epic(String name, String description, int id, Status status) { super(name, description, id, status); + this.duration = 0; + this.startTime = LocalDateTime.of(1970, 1, 1, 0, 0); + this.endTime = LocalDateTime.of(1970, 1, 1, 0, 0); + } + + public Epic(String name, String description, int id, Status status, long duration, LocalDateTime startTime, + LocalDateTime endTime) { + super(name, description, id, status, duration, startTime); + this.endTime = endTime; } @Override public String toString() { - return id + "," + TaskType.EPIC + "," + name + "," + status + "," + description + ","; + return id + "," + TaskType.EPIC + "," + name + "," + status + "," + description + "," + duration + "," + + startTime.toString() + "," + endTime.toString() + ","; } } diff --git a/src/tracker/model/Subtask.java b/src/tracker/model/Subtask.java index 9e10629..043f47f 100644 --- a/src/tracker/model/Subtask.java +++ b/src/tracker/model/Subtask.java @@ -1,15 +1,18 @@ package tracker.model; +import java.time.LocalDateTime; + public class Subtask extends Task { private final Epic epic; - public Subtask(String name, String description, int id, Epic epic) { - super(name, description, id); + public Subtask(String name, String description, int id, Epic epic, long duration, LocalDateTime startTime) { + super(name, description, id, duration, startTime); this.epic = epic; } - public Subtask(String name, String description, int id, Status status, Epic epic) { - super(name, description, id, status); + public Subtask(String name, String description, int id, Status status, Epic epic, long duration, + LocalDateTime startTime) { + super(name, description, id, status, duration, startTime); this.epic = epic; } @@ -19,6 +22,7 @@ public Epic getEpic() { @Override public String toString() { - return id + "," + TaskType.SUBTASK + "," + name + "," + status + "," + description + "," + epic.id; + return id + "," + TaskType.SUBTASK + "," + name + "," + status + "," + description + "," + duration + "," + + startTime.toString() + "," + "," + epic.id; } } diff --git a/src/tracker/model/Task.java b/src/tracker/model/Task.java index 54e1775..87479dc 100644 --- a/src/tracker/model/Task.java +++ b/src/tracker/model/Task.java @@ -1,5 +1,6 @@ package tracker.model; +import java.time.LocalDateTime; import java.util.Objects; public class Task { @@ -7,12 +8,15 @@ public class Task { protected String description; protected final int id; protected Status status; + protected long duration; + protected LocalDateTime startTime; public Task(String name, String description, int id) { this.name = name; this.description = description; this.id = id; - this.status = Status.NEW; + this.duration = 0; + this.startTime = LocalDateTime.of(1970, 1, 1, 0, 0); } public Task(String name, String description, int id, Status status) { @@ -20,6 +24,26 @@ public Task(String name, String description, int id, Status status) { this.description = description; this.id = id; this.status = status; + this.duration = 0; + this.startTime = LocalDateTime.of(1970, 1, 1, 0, 0); + } + + public Task(String name, String description, int id, long duration, LocalDateTime startTime) { + this.name = name; + this.description = description; + this.id = id; + this.status = Status.NEW; + this.duration = duration; + this.startTime = startTime; + } + + public Task(String name, String description, int id, Status status, long duration, LocalDateTime startTime) { + this.name = name; + this.description = description; + this.id = id; + this.status = status; + this.duration = duration; + this.startTime = startTime; } public String getName() { @@ -50,6 +74,26 @@ public void setStatus(Status status) { this.status = status; } + public long getDuration() { + return duration; + } + + public LocalDateTime getStartTime() { + return startTime; + } + + public LocalDateTime getEndTime() { + return startTime.plusSeconds(duration); + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public void setStartTime(LocalDateTime startTime) { + this.startTime = startTime; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -65,6 +109,7 @@ public int hashCode() { @Override public String toString() { - return id + "," + TaskType.TASK + "," + name + "," + status + "," + description + ","; + return id + "," + TaskType.TASK + "," + name + "," + status + "," + description + "," + duration + "," + + startTime.toString() + "," + ","; } } diff --git a/test/tracker/controllers/FileBackedTaskManagerTest.java b/test/tracker/controllers/FileBackedTaskManagerTest.java index e4e0ab2..1bb4cb9 100644 --- a/test/tracker/controllers/FileBackedTaskManagerTest.java +++ b/test/tracker/controllers/FileBackedTaskManagerTest.java @@ -9,11 +9,14 @@ import java.io.File; import java.io.IOException; +import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.*; class FileBackedTaskManagerTest extends InMemoryTaskManagerTest { File file; + final long MINUTES_IN_DAY = 60 * 24; + final LocalDateTime TASK_START_TIME = LocalDateTime.now(); @Override @BeforeEach @@ -43,13 +46,18 @@ void checkImportFromEmptyFile() { @Test void checkImportFromFile() { - Task task1 = new Task("task 1", "task 1", 1, Status.NEW); - Task task2 = new Task("task 2", "task 2", 2, Status.NEW); + Task task1 = new Task("task 1", "task 1", 1, Status.NEW, MINUTES_IN_DAY, + TASK_START_TIME.minusDays(4)); + Task task2 = new Task("task 2", "task 2", 2, Status.NEW, MINUTES_IN_DAY, + TASK_START_TIME.minusDays(3)); Epic epic1 = new Epic("epic 1", "epic 1", 3); Epic epic2 = new Epic("epic 2", "epic 2", 4); - Subtask subtask1 = new Subtask("subtask 1", "subtask 1", 5, epic1); - Subtask subtask2 = new Subtask("subtask 2", "subtask 2", 6, epic1); - Subtask subtask3 = new Subtask("subtask 3", "subtask 3", 7, epic2); + Subtask subtask1 = new Subtask("subtask 1", "subtask 1", 5, epic1, MINUTES_IN_DAY, + TASK_START_TIME.minusDays(2)); + Subtask subtask2 = new Subtask("subtask 2", "subtask 2", 6, epic1, MINUTES_IN_DAY, + TASK_START_TIME.minusDays(1)); + Subtask subtask3 = new Subtask("subtask 3", "subtask 3", 7, epic2, MINUTES_IN_DAY, + TASK_START_TIME); taskManager.createTask(task1); taskManager.createTask(task2); diff --git a/test/tracker/controllers/InMemoryHistoryManagerTest.java b/test/tracker/controllers/InMemoryHistoryManagerTest.java index 6e9a683..1e883d4 100644 --- a/test/tracker/controllers/InMemoryHistoryManagerTest.java +++ b/test/tracker/controllers/InMemoryHistoryManagerTest.java @@ -6,10 +6,14 @@ import tracker.model.Subtask; import tracker.model.Task; +import java.time.LocalDateTime; + import static org.junit.jupiter.api.Assertions.*; class InMemoryHistoryManagerTest { TaskManager taskManager; + final long MINUTES_IN_DAY = 60 * 24; + final LocalDateTime TASK_START_TIME = LocalDateTime.now(); @BeforeEach void initializeTask() { @@ -17,9 +21,11 @@ void initializeTask() { } @Test void checkInMemoryHistoryManager() { - Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId()); + Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY, + TASK_START_TIME.minusDays(4)); taskManager.createTask(task1); - Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId()); + Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY, + TASK_START_TIME.minusDays(3)); taskManager.createTask(task2); Epic epic1 = new Epic("Epic 1", "Do all subtasks from epic 1", taskManager.getTaskId()); @@ -28,13 +34,13 @@ void checkInMemoryHistoryManager() { taskManager.getTaskId()); taskManager.createEpic(epic2); Subtask subtask1 = new Subtask("Subtask 1", "Do subtask 1", - taskManager.getTaskId(), epic1); + taskManager.getTaskId(), epic1, MINUTES_IN_DAY, TASK_START_TIME.minusDays(2)); taskManager.createSubtask(subtask1); Subtask subtask2 = new Subtask("Subtask 2", "Do subtask 2", - taskManager.getTaskId(), epic1); + taskManager.getTaskId(), epic1, MINUTES_IN_DAY, TASK_START_TIME.minusDays(1)); taskManager.createSubtask(subtask2); Subtask subtask3 = new Subtask("Subtask 3", "Do subtask 3", - taskManager.getTaskId(), epic2); + taskManager.getTaskId(), epic2, MINUTES_IN_DAY, TASK_START_TIME); taskManager.createSubtask(subtask3); taskManager.getTaskById(task1.getId()); diff --git a/test/tracker/controllers/InMemoryTaskManagerTest.java b/test/tracker/controllers/InMemoryTaskManagerTest.java index cba0d2c..fe63e87 100644 --- a/test/tracker/controllers/InMemoryTaskManagerTest.java +++ b/test/tracker/controllers/InMemoryTaskManagerTest.java @@ -6,10 +6,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.time.LocalDateTime; + import static org.junit.jupiter.api.Assertions.*; class InMemoryTaskManagerTest { TaskManager taskManager; + final long MINUTES_IN_DAY = 60 * 24; + final LocalDateTime TASK_START_TIME = LocalDateTime.now(); @BeforeEach void initializeTask() { @@ -18,24 +22,24 @@ void initializeTask() { @Test void checkEpic() { - Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId()); + Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY, + TASK_START_TIME.minusDays(4)); taskManager.createTask(task1); - Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId()); + Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY, + TASK_START_TIME.minusDays(3)); taskManager.createTask(task2); - Epic epic1 = new Epic("Epic 1", "Do all subtasks from epic 1", - taskManager.getTaskId()); + Epic epic1 = new Epic("Epic 1", "Do all subtasks from epic 1", taskManager.getTaskId()); taskManager.createEpic(epic1); - Epic epic2 = new Epic("Epic 2", "Do all subtasks from epic 2", - taskManager.getTaskId()); + Epic epic2 = new Epic("Epic 2", "Do all subtasks from epic 2", taskManager.getTaskId()); taskManager.createEpic(epic2); - Subtask subtask1 = new Subtask("Subtask 1", "Do subtask 1", - taskManager.getTaskId(), epic1); + Subtask subtask1 = new Subtask("Subtask 1", "Do subtask 1", taskManager.getTaskId(), epic1, + MINUTES_IN_DAY, TASK_START_TIME.minusDays(2)); taskManager.createSubtask(subtask1); - Subtask subtask2 = new Subtask("Subtask 2", "Do subtask 2", - taskManager.getTaskId(), epic1); + Subtask subtask2 = new Subtask("Subtask 2", "Do subtask 2", taskManager.getTaskId(), epic1, + MINUTES_IN_DAY, TASK_START_TIME.minusDays(1)); taskManager.createSubtask(subtask2); - Subtask subtask3 = new Subtask("Subtask 3", "Do subtask 3", - taskManager.getTaskId(), epic2); + Subtask subtask3 = new Subtask("Subtask 3", "Do subtask 3", taskManager.getTaskId(), epic2, + MINUTES_IN_DAY, TASK_START_TIME); taskManager.createSubtask(subtask3); assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id"); diff --git a/test/tracker/model/SubtaskTest.java b/test/tracker/model/SubtaskTest.java index 55a569a..eb685ba 100644 --- a/test/tracker/model/SubtaskTest.java +++ b/test/tracker/model/SubtaskTest.java @@ -5,10 +5,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.time.LocalDateTime; + import static org.junit.jupiter.api.Assertions.*; class SubtaskTest { TaskManager inMemoryTaskManager; + final long MINUTES_IN_DAY = 60 * 24; + final LocalDateTime TASK_START_TIME = LocalDateTime.now(); @BeforeEach void initializeTask() { @@ -24,9 +28,11 @@ void checkSubtask() { inMemoryTaskManager.getTaskId()); inMemoryTaskManager.createEpic(epic2); - Subtask subtask1 = new Subtask("Subtask 1", "Do subtask 1", 1, epic1); + Subtask subtask1 = new Subtask("Subtask 1", "Do subtask 1", 1, epic1, MINUTES_IN_DAY, + TASK_START_TIME.minusDays(1)); inMemoryTaskManager.createSubtask(subtask1); - Subtask subtask2 = new Subtask("Subtask 2", "Do subtask 2", 1, epic2); + Subtask subtask2 = new Subtask("Subtask 2", "Do subtask 2", 1, epic2, MINUTES_IN_DAY, + TASK_START_TIME); inMemoryTaskManager.createSubtask(subtask2); assertEquals(subtask1, subtask2, "Объекты не равны"); From b53e10e9e5e3c7b7af416e058e52828908236ac4 Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Tue, 15 Jul 2025 22:39:12 +0300 Subject: [PATCH 2/7] =?UTF-8?q?feuture:=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=B0=208=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tracker/controllers/InMemoryTaskManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tracker/controllers/InMemoryTaskManager.java b/src/tracker/controllers/InMemoryTaskManager.java index 84148aa..d4dbef2 100644 --- a/src/tracker/controllers/InMemoryTaskManager.java +++ b/src/tracker/controllers/InMemoryTaskManager.java @@ -202,6 +202,7 @@ public void updateEpicStatus(Epic epic) { epic.setStatus(Status.IN_PROGRESS); } } + @Override public void updateEpicDuration(Epic epic) { ArrayList epicSubtasks = getEpicsSubtasks(epic.getId()); @@ -265,7 +266,7 @@ public TreeSet getPrioritizedTasks() { return sortedTasks; } - private boolean intersectionChecked (T task1, T task2) { + private boolean intersectionChecked(T task1, T task2) { LocalDateTime endTime1 = task1.getStartTime().plusSeconds(task1.getDuration()); LocalDateTime endTime2 = task2.getStartTime().plusSeconds(task2.getDuration()); return task1.getStartTime().isBefore(task2.getStartTime()) && endTime1.isAfter(task2.getStartTime()) From 0bbf9500a9bf2d059d49b43df98ec01d3f11dd97 Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Tue, 15 Jul 2025 23:14:43 +0300 Subject: [PATCH 3/7] =?UTF-8?q?feuture:=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=B0=208=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/InMemoryTaskManager.java | 10 ++-- .../controllers/InMemoryTaskManagerTest.java | 57 +++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/tracker/controllers/InMemoryTaskManager.java b/src/tracker/controllers/InMemoryTaskManager.java index d4dbef2..1bf36c3 100644 --- a/src/tracker/controllers/InMemoryTaskManager.java +++ b/src/tracker/controllers/InMemoryTaskManager.java @@ -267,10 +267,12 @@ public TreeSet getPrioritizedTasks() { } private boolean intersectionChecked(T task1, T task2) { - LocalDateTime endTime1 = task1.getStartTime().plusSeconds(task1.getDuration()); - LocalDateTime endTime2 = task2.getStartTime().plusSeconds(task2.getDuration()); - return task1.getStartTime().isBefore(task2.getStartTime()) && endTime1.isAfter(task2.getStartTime()) - || task1.getStartTime().isBefore(endTime2) && endTime1.isAfter(endTime2); + LocalDateTime endTime1 = task1.getStartTime().plusMinutes(task1.getDuration()).minusSeconds(1); + LocalDateTime endTime2 = task2.getStartTime().plusMinutes(task2.getDuration()).minusSeconds(1); + return (task1.getStartTime().isBefore(task2.getStartTime()) || task1.getStartTime().isEqual(task2.getStartTime())) + && (endTime1.isAfter(task2.getStartTime()) || endTime1.isEqual(task2.getStartTime())) + || (task1.getStartTime().isBefore(endTime2) || task1.getStartTime().isEqual(endTime2)) + && (endTime1.isAfter(endTime2) || endTime1.isEqual(endTime2)); } private boolean noIntersectionWithTasks(T task) { diff --git a/test/tracker/controllers/InMemoryTaskManagerTest.java b/test/tracker/controllers/InMemoryTaskManagerTest.java index fe63e87..d071351 100644 --- a/test/tracker/controllers/InMemoryTaskManagerTest.java +++ b/test/tracker/controllers/InMemoryTaskManagerTest.java @@ -1,6 +1,7 @@ package tracker.controllers; import tracker.model.Epic; +import tracker.model.Status; import tracker.model.Subtask; import tracker.model.Task; import org.junit.jupiter.api.BeforeEach; @@ -50,4 +51,60 @@ void checkEpic() { assertEquals(6, taskManager.getSubtaskById(subtask2.getId()).getId(), "Неверный Id"); assertEquals(7, taskManager.getSubtaskById(subtask3.getId()).getId(), "Неверный Id"); } + + @Test + void checkEpicStatus() { + // Все подзадачи со статусом NEW. + Epic epic1 = new Epic("Epic 1", "Do all subtasks from epic 1", taskManager.getTaskId()); + taskManager.createEpic(epic1); + Subtask subtask1 = new Subtask("Subtask 1", "Do subtask 1", taskManager.getTaskId(), epic1, + MINUTES_IN_DAY, TASK_START_TIME.minusDays(3)); + taskManager.createSubtask(subtask1); + Subtask subtask2 = new Subtask("Subtask 2", "Do subtask 2", taskManager.getTaskId(), epic1, + MINUTES_IN_DAY, TASK_START_TIME.minusDays(2)); + taskManager.createSubtask(subtask2); + assertEquals(Status.NEW, epic1.getStatus(), "Статус эпика должен быть NEW"); + // Подзадачи со статусами NEW и DONE. + subtask2.setStatus(Status.DONE); + taskManager.updateEpicStatus(epic1); + assertEquals(Status.IN_PROGRESS, epic1.getStatus(), "Статус эпика должен быть IN_PROGRESS"); + // Подзадачи со статусом IN_PROGRESS. + Epic epic2 = new Epic("Epic 2", "Do all subtasks from epic 2", taskManager.getTaskId()); + taskManager.createEpic(epic2); + Subtask subtask3 = new Subtask("Subtask 3", "Do subtask 3", taskManager.getTaskId(), epic2, + MINUTES_IN_DAY, TASK_START_TIME.minusDays(1)); + taskManager.createSubtask(subtask3); + Subtask subtask4 = new Subtask("Subtask 4", "Do subtask 4", taskManager.getTaskId(), epic2, + MINUTES_IN_DAY, TASK_START_TIME); + taskManager.createSubtask(subtask4); + subtask3.setStatus(Status.IN_PROGRESS); + subtask4.setStatus(Status.IN_PROGRESS); + taskManager.updateEpicStatus(epic2); + assertEquals(Status.IN_PROGRESS, epic2.getStatus(), "Статус эпика должен быть IN_PROGRESS"); + // Все подзадачи со статусом DONE. + subtask1.setStatus(Status.DONE); + subtask2.setStatus(Status.DONE); + subtask3.setStatus(Status.DONE); + subtask4.setStatus(Status.DONE); + taskManager.updateEpicStatus(epic1); + taskManager.updateEpicStatus(epic2); + assertEquals(Status.DONE, epic1.getStatus(), "Статус эпика должен быть DONE"); + assertEquals(Status.DONE, epic2.getStatus(), "Статус эпика должен быть DONE"); + } + + @Test + void checkTaskIntersection() { + // При наличии пересечения по времени выполнения задача не будет создана + Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY, + TASK_START_TIME); + taskManager.createTask(task1); + Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY, + TASK_START_TIME); + taskManager.createTask(task2); + assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id"); + assertEquals(1, taskManager.getTasks().size(), "Неверное количество задач"); + task2.setStartTime(TASK_START_TIME.plusDays(1)); + taskManager.createTask(task2); + assertEquals(2, taskManager.getTaskById(task2.getId()).getId(), "Неверный Id"); + } } \ No newline at end of file From 4b5700453dcf8805057bc1674aecb1f034ce22ae Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Sat, 19 Jul 2025 23:46:29 +0300 Subject: [PATCH 4/7] =?UTF-8?q?fix:=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=B0=208,=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/FileBackedTaskManager.java | 40 ++++++- .../controllers/InMemoryTaskManager.java | 73 +++++++----- src/tracker/controllers/TaskManager.java | 10 +- src/tracker/model/Epic.java | 9 +- .../FileBackedTaskManagerTest.java | 10 +- .../controllers/InMemoryTaskManagerTest.java | 16 +-- test/tracker/controllers/TaskManagerTest.java | 110 ++++++++++++++++++ 7 files changed, 216 insertions(+), 52 deletions(-) create mode 100644 test/tracker/controllers/TaskManagerTest.java diff --git a/src/tracker/controllers/FileBackedTaskManager.java b/src/tracker/controllers/FileBackedTaskManager.java index ed62bcc..d6204c2 100644 --- a/src/tracker/controllers/FileBackedTaskManager.java +++ b/src/tracker/controllers/FileBackedTaskManager.java @@ -13,6 +13,10 @@ import java.nio.file.Files; import java.nio.file.Path; import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.TreeSet; public class FileBackedTaskManager extends InMemoryTaskManager { @@ -57,9 +61,9 @@ public static void main(String[] args) { fileBackedTasksManager.getTaskById(1); fileBackedTasksManager.getTaskById(2); - fileBackedTasksManager.getTaskById(7); - fileBackedTasksManager.getTaskById(3); - fileBackedTasksManager.getTaskById(5); + fileBackedTasksManager.getSubtaskById(7); + fileBackedTasksManager.getEpicById(3); + fileBackedTasksManager.getSubtaskById(5); System.out.println(fileBackedTasksManager.getHistory()); @@ -166,6 +170,7 @@ protected void save() { for (Task task: this.getSubtasks()) { fileWriter.write("\n" + task.toString()); } + fileWriter.write(prioritizedTaskstoString(this)); } catch (IOException ioException) { throw new ManagerSaveException("Ошибка при создании файла."); } @@ -182,6 +187,16 @@ public static FileBackedTaskManager loadFromFile(File file) { fromString(line, fileBackedTasksManager); } } + List sortedTasks = sortedTasksFromString(lines[lines.length - 1]); + for (String element: sortedTasks) { + Optional task = fileBackedTasksManager.getTaskById(Integer.parseInt(element)); + if (task.isPresent()) { + fileBackedTasksManager.getPrioritizedTasks().add(task.get()); + } else { + Optional subtask = fileBackedTasksManager.getSubtaskById(Integer.parseInt(element)); + subtask.ifPresent(value -> fileBackedTasksManager.getPrioritizedTasks().add(value)); + } + } } } catch (IOException ioException) { throw new ManagerSaveException("Ошибка при чтении файла."); @@ -190,6 +205,21 @@ public static FileBackedTaskManager loadFromFile(File file) { return fileBackedTasksManager; } + static String prioritizedTaskstoString(FileBackedTaskManager fileBackedTaskManager) { + StringBuilder result = new StringBuilder(); + + TreeSet prioritizedTasks = fileBackedTaskManager.getPrioritizedTasks(); + for (Task task: prioritizedTasks) { + if (result.length() == 0) { + result.append("\n\n").append(task.getId()); + } else { + result.append(",").append(task.getId()); + } + } + + return result.toString(); + } + static void fromString(String value, FileBackedTaskManager fileBackedTasksManager) { String[] elements = value.split(","); int id = Integer.parseInt(elements[0]); @@ -207,4 +237,8 @@ static void fromString(String value, FileBackedTaskManager fileBackedTasksManage fileBackedTasksManager.taskId = id; } } + + static List sortedTasksFromString(String value) { + return Arrays.asList(value.split(",")); + } } diff --git a/src/tracker/controllers/InMemoryTaskManager.java b/src/tracker/controllers/InMemoryTaskManager.java index 1bf36c3..faac755 100644 --- a/src/tracker/controllers/InMemoryTaskManager.java +++ b/src/tracker/controllers/InMemoryTaskManager.java @@ -5,16 +5,19 @@ import tracker.model.Subtask; import tracker.model.Task; +import java.time.Duration; import java.time.LocalDateTime; import java.util.*; public class InMemoryTaskManager implements TaskManager { + private final LocalDateTime emptyDateTime = LocalDateTime.of(1970, 1, 1, 0, 0); protected final HashMap tasks; protected final HashMap subtasks; protected final HashMap epics; private final HistoryManager inMemoryHistoryManager; protected int taskId; - private final Comparator comparator; + + private final TreeSet sortedTasks; public InMemoryTaskManager() { tasks = new HashMap<>(); @@ -22,7 +25,7 @@ public InMemoryTaskManager() { epics = new HashMap<>(); taskId = 1; inMemoryHistoryManager = Managers.getDefaultHistory(); - comparator = (task1, task2) -> { + Comparator comparator = (task1, task2) -> { LocalDateTime t1 = task1.getStartTime(); LocalDateTime t2 = task2.getStartTime(); if (task1.equals(task2)) { @@ -35,6 +38,7 @@ public InMemoryTaskManager() { return 0; }; + this.sortedTasks = new TreeSet<>(comparator); } @Override @@ -85,20 +89,16 @@ public void deleteAllEpics() { // Получение по идентификатору. @Override - public Task getTaskById(int id) { - Task task = tasks.get(id); - if (task != null) { - inMemoryHistoryManager.add(task); - } + public Optional getTaskById(int id) { + Optional task = Optional.ofNullable(tasks.get(id)); + task.ifPresent(inMemoryHistoryManager::add); return task; } @Override - public Subtask getSubtaskById(int id) { - Subtask subtask = subtasks.get(id); - if (subtask != null) { - inMemoryHistoryManager.add(subtask); - } + public Optional getSubtaskById(int id) { + Optional subtask = Optional.ofNullable(subtasks.get(id)); + subtask.ifPresent(inMemoryHistoryManager::add); return subtask; } @@ -128,6 +128,7 @@ public ArrayList getEpicsSubtasks(int epicId) { public void createTask(Task task) { if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { tasks.put(taskId, task); + sortedTasks.add(task); taskId++; } else { System.out.println("Пересечение с текущими задачами"); @@ -138,8 +139,9 @@ public void createTask(Task task) { public void createSubtask(Subtask task) { if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { subtasks.put(taskId, task); + sortedTasks.add(task); updateEpicStatus(task.getEpic()); - updateEpicDuration(task.getEpic()); + updateEpicEndTimeAndDuration(task.getEpic()); taskId++; } else { System.out.println("Пересечение с текущими задачами."); @@ -159,8 +161,10 @@ public void updateTask(Task task) { if (updatedTask == null) { System.out.println("Задача с id = " + task.getId() + " не найдена"); } + sortedTasks.remove(updatedTask); if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { tasks.put(task.getId(), task); + sortedTasks.add(task); } else { System.out.println("Пересечение с текущими задачами"); } @@ -172,10 +176,12 @@ public void updateSubtask(Subtask task) { if (updatedTask == null) { System.out.println("Задача с id = " + task.getId() + " не найдена"); } + sortedTasks.remove(updatedTask); if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { - updateEpicStatus(task.getEpic()); - updateEpicDuration(task.getEpic()); subtasks.put(task.getId(), task); + sortedTasks.add(task); + updateEpicStatus(task.getEpic()); + updateEpicEndTimeAndDuration(task.getEpic()); } else { System.out.println("Пересечение с текущими задачами"); } @@ -203,19 +209,29 @@ public void updateEpicStatus(Epic epic) { } } - @Override - public void updateEpicDuration(Epic epic) { + void updateEpicEndTimeAndDuration(Epic epic) { + LocalDateTime epicStartTime = emptyDateTime; + LocalDateTime epicEndTime = emptyDateTime; ArrayList epicSubtasks = getEpicsSubtasks(epic.getId()); - int epicDuration = 0; for (Subtask subtask: epicSubtasks) { - epicDuration += subtask.getDuration(); + if (epicStartTime.isEqual(emptyDateTime)) { + epicStartTime = subtask.getStartTime(); + } else if (!subtask.getStartTime().isEqual(emptyDateTime) + && subtask.getStartTime().isBefore(epicStartTime)) { + epicStartTime = subtask.getStartTime(); + } + + if (epicEndTime.isEqual(emptyDateTime)) { + epicEndTime = subtask.getEndTime(); + } else if (!subtask.getEndTime().isEqual(emptyDateTime) + && subtask.getEndTime().isAfter(epicEndTime)) { + epicEndTime = subtask.getEndTime(); + } } - TreeSet sortedTasks = new TreeSet<>(comparator); - sortedTasks.addAll(epicSubtasks); - LocalDateTime epicStartTime = sortedTasks.first().getStartTime(); + epic.setStartTime(epicStartTime); - epic.setDuration(epicDuration); - epic.setEndTime(epicStartTime.plusMinutes(epicDuration)); + epic.setDuration(Duration.between(epicStartTime, epicEndTime).toMinutes()); + epic.setEndTime(epicEndTime); } @Override @@ -232,14 +248,16 @@ public void updateEpic(Epic task) { public void deleteTask(Task task) { inMemoryHistoryManager.remove(task.getId()); tasks.remove(task.getId()); + sortedTasks.remove(task); } @Override public void deleteSubtask(Subtask task) { inMemoryHistoryManager.remove(task.getId()); subtasks.remove(task.getId()); + sortedTasks.remove(task); updateEpicStatus(task.getEpic()); - updateEpicDuration(task.getEpic()); + updateEpicEndTimeAndDuration(task.getEpic()); } @Override @@ -249,6 +267,7 @@ public void deleteEpic(Epic epic) { for (Subtask subtask: subtasksForDeletion) { inMemoryHistoryManager.remove(subtask.getId()); subtasks.remove(subtask.getId()); + sortedTasks.remove(subtask); } inMemoryHistoryManager.remove(epic.getId()); epics.remove(epic.getId()); @@ -259,10 +278,8 @@ public List getHistory() { return inMemoryHistoryManager.getHistory(); } + @Override public TreeSet getPrioritizedTasks() { - TreeSet sortedTasks = new TreeSet<>(comparator); - sortedTasks.addAll(tasks.values()); - sortedTasks.addAll(subtasks.values()); return sortedTasks; } diff --git a/src/tracker/controllers/TaskManager.java b/src/tracker/controllers/TaskManager.java index 2aa776b..2a1b3bb 100644 --- a/src/tracker/controllers/TaskManager.java +++ b/src/tracker/controllers/TaskManager.java @@ -6,6 +6,8 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.TreeSet; public interface TaskManager { // Получение списка всех задач. @@ -25,9 +27,9 @@ public interface TaskManager { void deleteAllEpics(); // Получение по идентификатору. - Task getTaskById(int id); + Optional getTaskById(int id); - Subtask getSubtaskById(int id); + Optional getSubtaskById(int id); Epic getEpicById(int id); @@ -48,8 +50,6 @@ public interface TaskManager { void updateEpicStatus(Epic epic); - void updateEpicDuration(Epic epic); - void updateEpic(Epic task); // Удаление по идентификатору @@ -60,4 +60,6 @@ public interface TaskManager { void deleteEpic(Epic epic); List getHistory(); + + TreeSet getPrioritizedTasks(); } diff --git a/src/tracker/model/Epic.java b/src/tracker/model/Epic.java index ee66279..10fb55b 100644 --- a/src/tracker/model/Epic.java +++ b/src/tracker/model/Epic.java @@ -5,6 +5,7 @@ public class Epic extends Task { private LocalDateTime endTime; + private final LocalDateTime emptyDateTime = LocalDateTime.of(1970, 1, 1, 0, 0); @Override public LocalDateTime getEndTime() { @@ -18,15 +19,15 @@ public void setEndTime(LocalDateTime endTime) { public Epic(String name, String description, int id) { super(name, description, id); this.duration = 0; - this.startTime = LocalDateTime.of(1970, 1, 1, 0, 0); - this.endTime = LocalDateTime.of(1970, 1, 1, 0, 0); + this.startTime = emptyDateTime; + this.endTime = emptyDateTime; } public Epic(String name, String description, int id, Status status) { super(name, description, id, status); this.duration = 0; - this.startTime = LocalDateTime.of(1970, 1, 1, 0, 0); - this.endTime = LocalDateTime.of(1970, 1, 1, 0, 0); + this.startTime = emptyDateTime; + this.endTime = emptyDateTime; } public Epic(String name, String description, int id, Status status, long duration, LocalDateTime startTime, diff --git a/test/tracker/controllers/FileBackedTaskManagerTest.java b/test/tracker/controllers/FileBackedTaskManagerTest.java index 1bb4cb9..5db71d8 100644 --- a/test/tracker/controllers/FileBackedTaskManagerTest.java +++ b/test/tracker/controllers/FileBackedTaskManagerTest.java @@ -70,19 +70,19 @@ void checkImportFromFile() { TaskManager taskManager1 = FileBackedTaskManager.loadFromFile(file); TaskManager taskManager2 = FileBackedTaskManager.loadFromFile(file); - assertTrue(tasksAreEquals(taskManager1.getTaskById(1), taskManager2.getTaskById(1)), + assertTrue(tasksAreEquals(taskManager1.getTaskById(1).get(), taskManager2.getTaskById(1).get()), "Исходная задача не соответствует загруженной"); - assertTrue(tasksAreEquals(taskManager1.getTaskById(2), taskManager2.getTaskById(2)), + assertTrue(tasksAreEquals(taskManager1.getTaskById(2).get(), taskManager2.getTaskById(2).get()), "Исходная задача не соответствует загруженной"); assertTrue(tasksAreEquals(taskManager1.getEpicById(3), taskManager2.getEpicById(3)), "Исходная задача не соответствует загруженной"); assertTrue(tasksAreEquals(taskManager1.getEpicById(4), taskManager2.getEpicById(4)), "Исходная задача не соответствует загруженной"); - assertTrue(tasksAreEquals(taskManager1.getSubtaskById(5), taskManager2.getSubtaskById(5)), + assertTrue(tasksAreEquals(taskManager1.getSubtaskById(5).get(), taskManager2.getSubtaskById(5).get()), "Исходная задача не соответствует загруженной"); - assertTrue(tasksAreEquals(taskManager1.getSubtaskById(6), taskManager2.getSubtaskById(6)), + assertTrue(tasksAreEquals(taskManager1.getSubtaskById(6).get(), taskManager2.getSubtaskById(6).get()), "Исходная задача не соответствует загруженной"); - assertTrue(tasksAreEquals(taskManager1.getSubtaskById(7), taskManager2.getSubtaskById(7)), + assertTrue(tasksAreEquals(taskManager1.getSubtaskById(7).get(), taskManager2.getSubtaskById(7).get()), "Исходная задача не соответствует загруженной"); } diff --git a/test/tracker/controllers/InMemoryTaskManagerTest.java b/test/tracker/controllers/InMemoryTaskManagerTest.java index d071351..58b99c3 100644 --- a/test/tracker/controllers/InMemoryTaskManagerTest.java +++ b/test/tracker/controllers/InMemoryTaskManagerTest.java @@ -18,7 +18,7 @@ class InMemoryTaskManagerTest { @BeforeEach void initializeTask() { - taskManager = Managers.getDefault(); + taskManager = new InMemoryTaskManager(); } @Test @@ -43,13 +43,13 @@ void checkEpic() { MINUTES_IN_DAY, TASK_START_TIME); taskManager.createSubtask(subtask3); - assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id"); - assertEquals(2, taskManager.getTaskById(task2.getId()).getId(), "Неверный Id"); + assertEquals(1, taskManager.getTaskById(task1.getId()).get().getId(), "Неверный Id"); + assertEquals(2, taskManager.getTaskById(task2.getId()).get().getId(), "Неверный Id"); assertEquals(3, taskManager.getEpicById(epic1.getId()).getId(), "Неверный Id"); assertEquals(4, taskManager.getEpicById(epic2.getId()).getId(), "Неверный Id"); - assertEquals(5, taskManager.getSubtaskById(subtask1.getId()).getId(), "Неверный Id"); - assertEquals(6, taskManager.getSubtaskById(subtask2.getId()).getId(), "Неверный Id"); - assertEquals(7, taskManager.getSubtaskById(subtask3.getId()).getId(), "Неверный Id"); + assertEquals(5, taskManager.getSubtaskById(subtask1.getId()).get().getId(), "Неверный Id"); + assertEquals(6, taskManager.getSubtaskById(subtask2.getId()).get().getId(), "Неверный Id"); + assertEquals(7, taskManager.getSubtaskById(subtask3.getId()).get().getId(), "Неверный Id"); } @Test @@ -101,10 +101,10 @@ void checkTaskIntersection() { Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY, TASK_START_TIME); taskManager.createTask(task2); - assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id"); + assertEquals(1, taskManager.getTaskById(task1.getId()).get().getId(), "Неверный Id"); assertEquals(1, taskManager.getTasks().size(), "Неверное количество задач"); task2.setStartTime(TASK_START_TIME.plusDays(1)); taskManager.createTask(task2); - assertEquals(2, taskManager.getTaskById(task2.getId()).getId(), "Неверный Id"); + assertEquals(2, taskManager.getTaskById(task2.getId()).get().getId(), "Неверный Id"); } } \ No newline at end of file diff --git a/test/tracker/controllers/TaskManagerTest.java b/test/tracker/controllers/TaskManagerTest.java new file mode 100644 index 0000000..e27b2a5 --- /dev/null +++ b/test/tracker/controllers/TaskManagerTest.java @@ -0,0 +1,110 @@ +package tracker.controllers; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import tracker.model.Epic; +import tracker.model.Status; +import tracker.model.Subtask; +import tracker.model.Task; + +import java.time.LocalDateTime; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +abstract class TaskManagerTest { + + TaskManager taskManager; + final long MINUTES_IN_DAY = 60 * 24; + final LocalDateTime TASK_START_TIME = LocalDateTime.now(); + + @BeforeEach + void initializeTask() { + taskManager = Managers.getDefault(); + } + @Test + void checkEpic() { + Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY, + TASK_START_TIME.minusDays(4)); + taskManager.createTask(task1); + Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY, + TASK_START_TIME.minusDays(3)); + taskManager.createTask(task2); + Epic epic1 = new Epic("Epic 1", "Do all subtasks from epic 1", taskManager.getTaskId()); + taskManager.createEpic(epic1); + Epic epic2 = new Epic("Epic 2", "Do all subtasks from epic 2", taskManager.getTaskId()); + taskManager.createEpic(epic2); + Subtask subtask1 = new Subtask("Subtask 1", "Do subtask 1", taskManager.getTaskId(), epic1, + MINUTES_IN_DAY, TASK_START_TIME.minusDays(2)); + taskManager.createSubtask(subtask1); + Subtask subtask2 = new Subtask("Subtask 2", "Do subtask 2", taskManager.getTaskId(), epic1, + MINUTES_IN_DAY, TASK_START_TIME.minusDays(1)); + taskManager.createSubtask(subtask2); + Subtask subtask3 = new Subtask("Subtask 3", "Do subtask 3", taskManager.getTaskId(), epic2, + MINUTES_IN_DAY, TASK_START_TIME); + taskManager.createSubtask(subtask3); + + assertEquals(1, taskManager.getTaskById(task1.getId()).get().getId(), "Неверный Id"); + assertEquals(2, taskManager.getTaskById(task2.getId()).get().getId(), "Неверный Id"); + assertEquals(3, taskManager.getEpicById(epic1.getId()).getId(), "Неверный Id"); + assertEquals(4, taskManager.getEpicById(epic2.getId()).getId(), "Неверный Id"); + assertEquals(5, taskManager.getSubtaskById(subtask1.getId()).get().getId(), "Неверный Id"); + assertEquals(6, taskManager.getSubtaskById(subtask2.getId()).get().getId(), "Неверный Id"); + assertEquals(7, taskManager.getSubtaskById(subtask3.getId()).get().getId(), "Неверный Id"); + } + + @Test + void checkEpicStatus() { + // Все подзадачи со статусом NEW. + Epic epic1 = new Epic("Epic 1", "Do all subtasks from epic 1", taskManager.getTaskId()); + taskManager.createEpic(epic1); + Subtask subtask1 = new Subtask("Subtask 1", "Do subtask 1", taskManager.getTaskId(), epic1, + MINUTES_IN_DAY, TASK_START_TIME.minusDays(3)); + taskManager.createSubtask(subtask1); + Subtask subtask2 = new Subtask("Subtask 2", "Do subtask 2", taskManager.getTaskId(), epic1, + MINUTES_IN_DAY, TASK_START_TIME.minusDays(2)); + taskManager.createSubtask(subtask2); + assertEquals(Status.NEW, epic1.getStatus(), "Статус эпика должен быть NEW"); + // Подзадачи со статусами NEW и DONE. + subtask2.setStatus(Status.DONE); + taskManager.updateEpicStatus(epic1); + assertEquals(Status.IN_PROGRESS, epic1.getStatus(), "Статус эпика должен быть IN_PROGRESS"); + // Подзадачи со статусом IN_PROGRESS. + Epic epic2 = new Epic("Epic 2", "Do all subtasks from epic 2", taskManager.getTaskId()); + taskManager.createEpic(epic2); + Subtask subtask3 = new Subtask("Subtask 3", "Do subtask 3", taskManager.getTaskId(), epic2, + MINUTES_IN_DAY, TASK_START_TIME.minusDays(1)); + taskManager.createSubtask(subtask3); + Subtask subtask4 = new Subtask("Subtask 4", "Do subtask 4", taskManager.getTaskId(), epic2, + MINUTES_IN_DAY, TASK_START_TIME); + taskManager.createSubtask(subtask4); + subtask3.setStatus(Status.IN_PROGRESS); + subtask4.setStatus(Status.IN_PROGRESS); + taskManager.updateEpicStatus(epic2); + assertEquals(Status.IN_PROGRESS, epic2.getStatus(), "Статус эпика должен быть IN_PROGRESS"); + // Все подзадачи со статусом DONE. + subtask1.setStatus(Status.DONE); + subtask2.setStatus(Status.DONE); + subtask3.setStatus(Status.DONE); + subtask4.setStatus(Status.DONE); + taskManager.updateEpicStatus(epic1); + taskManager.updateEpicStatus(epic2); + assertEquals(Status.DONE, epic1.getStatus(), "Статус эпика должен быть DONE"); + assertEquals(Status.DONE, epic2.getStatus(), "Статус эпика должен быть DONE"); + } + + @Test + void checkTaskIntersection() { + // При наличии пересечения по времени выполнения задача не будет создана + Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY, + TASK_START_TIME); + taskManager.createTask(task1); + Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY, + TASK_START_TIME); + taskManager.createTask(task2); + assertEquals(1, taskManager.getTaskById(task1.getId()).get().getId(), "Неверный Id"); + assertEquals(1, taskManager.getTasks().size(), "Неверное количество задач"); + task2.setStartTime(TASK_START_TIME.plusDays(1)); + taskManager.createTask(task2); + assertEquals(2, taskManager.getTaskById(task2.getId()).get().getId(), "Неверный Id"); + } +} From 493262ccc24baf8f5c3605ad5383243a299a4f8c Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Sun, 20 Jul 2025 00:03:37 +0300 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=B0=208,=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/FileBackedTaskManager.java | 14 +++++++------ .../FileBackedTaskManagerTest.java | 20 ++++++++++++++++--- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/tracker/controllers/FileBackedTaskManager.java b/src/tracker/controllers/FileBackedTaskManager.java index d6204c2..fcd6bcc 100644 --- a/src/tracker/controllers/FileBackedTaskManager.java +++ b/src/tracker/controllers/FileBackedTaskManager.java @@ -189,12 +189,14 @@ public static FileBackedTaskManager loadFromFile(File file) { } List sortedTasks = sortedTasksFromString(lines[lines.length - 1]); for (String element: sortedTasks) { - Optional task = fileBackedTasksManager.getTaskById(Integer.parseInt(element)); - if (task.isPresent()) { - fileBackedTasksManager.getPrioritizedTasks().add(task.get()); - } else { - Optional subtask = fileBackedTasksManager.getSubtaskById(Integer.parseInt(element)); - subtask.ifPresent(value -> fileBackedTasksManager.getPrioritizedTasks().add(value)); + if (!element.equals("")) { + Optional task = fileBackedTasksManager.getTaskById(Integer.parseInt(element)); + if (task.isPresent()) { + fileBackedTasksManager.getPrioritizedTasks().add(task.get()); + } else { + Optional subtask = fileBackedTasksManager.getSubtaskById(Integer.parseInt(element)); + subtask.ifPresent(value -> fileBackedTasksManager.getPrioritizedTasks().add(value)); + } } } } diff --git a/test/tracker/controllers/FileBackedTaskManagerTest.java b/test/tracker/controllers/FileBackedTaskManagerTest.java index 5db71d8..1e0ae03 100644 --- a/test/tracker/controllers/FileBackedTaskManagerTest.java +++ b/test/tracker/controllers/FileBackedTaskManagerTest.java @@ -74,9 +74,9 @@ void checkImportFromFile() { "Исходная задача не соответствует загруженной"); assertTrue(tasksAreEquals(taskManager1.getTaskById(2).get(), taskManager2.getTaskById(2).get()), "Исходная задача не соответствует загруженной"); - assertTrue(tasksAreEquals(taskManager1.getEpicById(3), taskManager2.getEpicById(3)), + assertTrue(epicsAreEquals(taskManager1.getEpicById(3), taskManager2.getEpicById(3)), "Исходная задача не соответствует загруженной"); - assertTrue(tasksAreEquals(taskManager1.getEpicById(4), taskManager2.getEpicById(4)), + assertTrue(epicsAreEquals(taskManager1.getEpicById(4), taskManager2.getEpicById(4)), "Исходная задача не соответствует загруженной"); assertTrue(tasksAreEquals(taskManager1.getSubtaskById(5).get(), taskManager2.getSubtaskById(5).get()), "Исходная задача не соответствует загруженной"); @@ -84,12 +84,26 @@ void checkImportFromFile() { "Исходная задача не соответствует загруженной"); assertTrue(tasksAreEquals(taskManager1.getSubtaskById(7).get(), taskManager2.getSubtaskById(7).get()), "Исходная задача не соответствует загруженной"); + + } boolean tasksAreEquals(Task task1, Task task2) { return task1.getId() == task2.getId() && task1.getName().equals(task2.getName()) && task1.getDescription().equals(task2.getDescription()) - && task1.getStatus().equals(task2.getStatus()); + && task1.getStatus().equals(task2.getStatus()) + && task1.getStartTime().equals(task2.getStartTime()) + && task1.getDuration() == task2.getDuration(); + } + + boolean epicsAreEquals(Epic epic1, Epic epic2) { + return epic1.getId() == epic2.getId() + && epic1.getName().equals(epic2.getName()) + && epic1.getDescription().equals(epic2.getDescription()) + && epic1.getStatus().equals(epic2.getStatus()) + && epic1.getStartTime().equals(epic2.getStartTime()) + && epic1.getDuration() == epic2.getDuration() + && epic1.getEndTime().equals(epic2.getEndTime()); } } \ No newline at end of file From 15083497e6b04e589d1884103c3bd9bf7398f6f2 Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Sun, 20 Jul 2025 14:58:35 +0300 Subject: [PATCH 6/7] =?UTF-8?q?fix:=20sprint=208,=20=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/FileBackedTaskManager.java | 62 ++++++------------- .../controllers/InMemoryTaskManager.java | 61 +++++++++--------- src/tracker/controllers/TaskManager.java | 5 +- .../FileBackedTaskManagerTest.java | 13 ++-- .../controllers/InMemoryTaskManagerTest.java | 17 +++-- test/tracker/controllers/TaskManagerTest.java | 21 +++---- 6 files changed, 74 insertions(+), 105 deletions(-) diff --git a/src/tracker/controllers/FileBackedTaskManager.java b/src/tracker/controllers/FileBackedTaskManager.java index fcd6bcc..f4a8e7d 100644 --- a/src/tracker/controllers/FileBackedTaskManager.java +++ b/src/tracker/controllers/FileBackedTaskManager.java @@ -13,10 +13,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.TreeSet; public class FileBackedTaskManager extends InMemoryTaskManager { @@ -170,7 +166,6 @@ protected void save() { for (Task task: this.getSubtasks()) { fileWriter.write("\n" + task.toString()); } - fileWriter.write(prioritizedTaskstoString(this)); } catch (IOException ioException) { throw new ManagerSaveException("Ошибка при создании файла."); } @@ -187,18 +182,6 @@ public static FileBackedTaskManager loadFromFile(File file) { fromString(line, fileBackedTasksManager); } } - List sortedTasks = sortedTasksFromString(lines[lines.length - 1]); - for (String element: sortedTasks) { - if (!element.equals("")) { - Optional task = fileBackedTasksManager.getTaskById(Integer.parseInt(element)); - if (task.isPresent()) { - fileBackedTasksManager.getPrioritizedTasks().add(task.get()); - } else { - Optional subtask = fileBackedTasksManager.getSubtaskById(Integer.parseInt(element)); - subtask.ifPresent(value -> fileBackedTasksManager.getPrioritizedTasks().add(value)); - } - } - } } } catch (IOException ioException) { throw new ManagerSaveException("Ошибка при чтении файла."); @@ -207,40 +190,31 @@ public static FileBackedTaskManager loadFromFile(File file) { return fileBackedTasksManager; } - static String prioritizedTaskstoString(FileBackedTaskManager fileBackedTaskManager) { - StringBuilder result = new StringBuilder(); - - TreeSet prioritizedTasks = fileBackedTaskManager.getPrioritizedTasks(); - for (Task task: prioritizedTasks) { - if (result.length() == 0) { - result.append("\n\n").append(task.getId()); - } else { - result.append(",").append(task.getId()); - } - } - - return result.toString(); - } - static void fromString(String value, FileBackedTaskManager fileBackedTasksManager) { String[] elements = value.split(","); int id = Integer.parseInt(elements[0]); switch (elements[1]) { - case "TASK" -> fileBackedTasksManager.tasks.put(id, new Task(elements[2], elements[4], id, - Status.valueOf(elements[3]), Long.parseLong(elements[5]), LocalDateTime.parse(elements[6]))); - case "EPIC" -> fileBackedTasksManager.epics.put(id, new Epic(elements[2], elements[4], id, - Status.valueOf(elements[3]), Long.parseLong(elements[5]), LocalDateTime.parse(elements[6]), - LocalDateTime.parse(elements[7]))); - case "SUBTASK" -> fileBackedTasksManager.subtasks.put(id, new Subtask(elements[2], elements[4], id, - Status.valueOf(elements[3]), fileBackedTasksManager.getEpicById(Integer.parseInt(elements[8])), - Long.parseLong(elements[5]), LocalDateTime.parse(elements[6]))); + case "TASK" -> { + Task task = new Task(elements[2], elements[4], id, + Status.valueOf(elements[3]), Long.parseLong(elements[5]), LocalDateTime.parse(elements[6])); + fileBackedTasksManager.tasks.put(id, task); + fileBackedTasksManager.sortedTasks.add(task); + } + case "EPIC" -> { + Epic epic = new Epic(elements[2], elements[4], id, Status.valueOf(elements[3]), + Long.parseLong(elements[5]), LocalDateTime.parse(elements[6]), LocalDateTime.parse(elements[7])); + fileBackedTasksManager.epics.put(id, epic); + } + case "SUBTASK" -> { + Subtask subtask = new Subtask(elements[2], elements[4], id, Status.valueOf(elements[3]), + fileBackedTasksManager.epics.get(Integer.parseInt(elements[8])), Long.parseLong(elements[5]), + LocalDateTime.parse(elements[6])); + fileBackedTasksManager.subtasks.put(id, subtask); + fileBackedTasksManager.sortedTasks.add(subtask); + } } if (id > fileBackedTasksManager.taskId) { fileBackedTasksManager.taskId = id; } } - - static List sortedTasksFromString(String value) { - return Arrays.asList(value.split(",")); - } } diff --git a/src/tracker/controllers/InMemoryTaskManager.java b/src/tracker/controllers/InMemoryTaskManager.java index faac755..2277922 100644 --- a/src/tracker/controllers/InMemoryTaskManager.java +++ b/src/tracker/controllers/InMemoryTaskManager.java @@ -5,7 +5,6 @@ import tracker.model.Subtask; import tracker.model.Task; -import java.time.Duration; import java.time.LocalDateTime; import java.util.*; @@ -17,7 +16,7 @@ public class InMemoryTaskManager implements TaskManager { private final HistoryManager inMemoryHistoryManager; protected int taskId; - private final TreeSet sortedTasks; + protected final TreeSet sortedTasks; public InMemoryTaskManager() { tasks = new HashMap<>(); @@ -65,16 +64,18 @@ public ArrayList getEpics() { // Удаление всех задач. @Override public void deleteAllTasks() { - for (Integer taskId: tasks.keySet()) { - inMemoryHistoryManager.remove(taskId); + for (Task task: tasks.values()) { + inMemoryHistoryManager.remove(task.getId()); + sortedTasks.remove(task); } tasks.clear(); } @Override public void deleteAllSubtasks() { - for (Integer subtaskId: subtasks.keySet()) { - inMemoryHistoryManager.remove(subtaskId); + for (Subtask subtask: subtasks.values()) { + inMemoryHistoryManager.remove(subtask.getId()); + sortedTasks.remove(subtask); } subtasks.clear(); } @@ -83,23 +84,28 @@ public void deleteAllSubtasks() { public void deleteAllEpics() { for (Integer epicId: epics.keySet()) { inMemoryHistoryManager.remove(epicId); + ArrayList epicsSubtasks = getEpicsSubtasks(epicId); + for (Subtask subtask: epicsSubtasks) { + inMemoryHistoryManager.remove(subtask.getId()); + sortedTasks.remove(subtask); + } } epics.clear(); } // Получение по идентификатору. @Override - public Optional getTaskById(int id) { - Optional task = Optional.ofNullable(tasks.get(id)); - task.ifPresent(inMemoryHistoryManager::add); + public Task getTaskById(int id) { + Task task = tasks.get(id); + inMemoryHistoryManager.add(task); return task; } @Override - public Optional getSubtaskById(int id) { - Optional subtask = Optional.ofNullable(subtasks.get(id)); - subtask.ifPresent(inMemoryHistoryManager::add); - return subtask; + public Subtask getSubtaskById(int id) { + Subtask task = subtasks.get(id); + inMemoryHistoryManager.add(task); + return task; } @Override @@ -126,7 +132,7 @@ public ArrayList getEpicsSubtasks(int epicId) { // Создание. Сам объект должен передаваться в качестве параметра. @Override public void createTask(Task task) { - if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { + if (noIntersectionWithTasks(task)) { tasks.put(taskId, task); sortedTasks.add(task); taskId++; @@ -137,7 +143,7 @@ public void createTask(Task task) { @Override public void createSubtask(Subtask task) { - if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { + if (noIntersectionWithTasks(task)) { subtasks.put(taskId, task); sortedTasks.add(task); updateEpicStatus(task.getEpic()); @@ -161,8 +167,8 @@ public void updateTask(Task task) { if (updatedTask == null) { System.out.println("Задача с id = " + task.getId() + " не найдена"); } - sortedTasks.remove(updatedTask); - if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { + if (noIntersectionWithTasks(task)) { + sortedTasks.remove(updatedTask); tasks.put(task.getId(), task); sortedTasks.add(task); } else { @@ -176,8 +182,8 @@ public void updateSubtask(Subtask task) { if (updatedTask == null) { System.out.println("Задача с id = " + task.getId() + " не найдена"); } - sortedTasks.remove(updatedTask); - if (noIntersectionWithTasks(task) && noIntersectionWithSubtasks(task)) { + if (noIntersectionWithTasks(task)) { + sortedTasks.remove(updatedTask); subtasks.put(task.getId(), task); sortedTasks.add(task); updateEpicStatus(task.getEpic()); @@ -189,7 +195,7 @@ public void updateSubtask(Subtask task) { @Override public void updateEpicStatus(Epic epic) { - ArrayList epicsSubtasks = getEpicsSubtasks(epic.getId()); + ArrayList epicsSubtasks = getEpicsSubtasks(epic.getId()); int numberOfNewTasks = 0; int numberOfDoneTasks = 0; for (Subtask subtask: epicsSubtasks) { @@ -212,6 +218,7 @@ public void updateEpicStatus(Epic epic) { void updateEpicEndTimeAndDuration(Epic epic) { LocalDateTime epicStartTime = emptyDateTime; LocalDateTime epicEndTime = emptyDateTime; + long epicDuration = 0; ArrayList epicSubtasks = getEpicsSubtasks(epic.getId()); for (Subtask subtask: epicSubtasks) { if (epicStartTime.isEqual(emptyDateTime)) { @@ -227,10 +234,12 @@ void updateEpicEndTimeAndDuration(Epic epic) { && subtask.getEndTime().isAfter(epicEndTime)) { epicEndTime = subtask.getEndTime(); } + + epicDuration += subtask.getDuration(); } epic.setStartTime(epicStartTime); - epic.setDuration(Duration.between(epicStartTime, epicEndTime).toMinutes()); + epic.setDuration(epicDuration); epic.setEndTime(epicEndTime); } @@ -293,14 +302,8 @@ private boolean intersectionChecked(T task1, T task2) { } private boolean noIntersectionWithTasks(T task) { - List intersectedTasks = tasks.values().stream() - .filter(currentTask -> intersectionChecked(task, currentTask)) - .toList(); - return intersectedTasks.isEmpty(); - } - - private boolean noIntersectionWithSubtasks(T task) { - List intersectedTasks = subtasks.values().stream() + List intersectedTasks = sortedTasks.stream() + .filter(currentTask -> !currentTask.equals(task)) .filter(currentTask -> intersectionChecked(task, currentTask)) .toList(); return intersectedTasks.isEmpty(); diff --git a/src/tracker/controllers/TaskManager.java b/src/tracker/controllers/TaskManager.java index 2a1b3bb..71bfd44 100644 --- a/src/tracker/controllers/TaskManager.java +++ b/src/tracker/controllers/TaskManager.java @@ -6,7 +6,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.TreeSet; public interface TaskManager { @@ -27,9 +26,9 @@ public interface TaskManager { void deleteAllEpics(); // Получение по идентификатору. - Optional getTaskById(int id); + Task getTaskById(int id); - Optional getSubtaskById(int id); + Subtask getSubtaskById(int id); Epic getEpicById(int id); diff --git a/test/tracker/controllers/FileBackedTaskManagerTest.java b/test/tracker/controllers/FileBackedTaskManagerTest.java index 1e0ae03..63e270a 100644 --- a/test/tracker/controllers/FileBackedTaskManagerTest.java +++ b/test/tracker/controllers/FileBackedTaskManagerTest.java @@ -13,12 +13,11 @@ import static org.junit.jupiter.api.Assertions.*; -class FileBackedTaskManagerTest extends InMemoryTaskManagerTest { +class FileBackedTaskManagerTest extends TaskManagerTest { File file; final long MINUTES_IN_DAY = 60 * 24; final LocalDateTime TASK_START_TIME = LocalDateTime.now(); - @Override @BeforeEach void initializeTask() { try { @@ -70,19 +69,19 @@ void checkImportFromFile() { TaskManager taskManager1 = FileBackedTaskManager.loadFromFile(file); TaskManager taskManager2 = FileBackedTaskManager.loadFromFile(file); - assertTrue(tasksAreEquals(taskManager1.getTaskById(1).get(), taskManager2.getTaskById(1).get()), + assertTrue(tasksAreEquals(taskManager1.getTaskById(1), taskManager2.getTaskById(1)), "Исходная задача не соответствует загруженной"); - assertTrue(tasksAreEquals(taskManager1.getTaskById(2).get(), taskManager2.getTaskById(2).get()), + assertTrue(tasksAreEquals(taskManager1.getTaskById(2), taskManager2.getTaskById(2)), "Исходная задача не соответствует загруженной"); assertTrue(epicsAreEquals(taskManager1.getEpicById(3), taskManager2.getEpicById(3)), "Исходная задача не соответствует загруженной"); assertTrue(epicsAreEquals(taskManager1.getEpicById(4), taskManager2.getEpicById(4)), "Исходная задача не соответствует загруженной"); - assertTrue(tasksAreEquals(taskManager1.getSubtaskById(5).get(), taskManager2.getSubtaskById(5).get()), + assertTrue(tasksAreEquals(taskManager1.getSubtaskById(5), taskManager2.getSubtaskById(5)), "Исходная задача не соответствует загруженной"); - assertTrue(tasksAreEquals(taskManager1.getSubtaskById(6).get(), taskManager2.getSubtaskById(6).get()), + assertTrue(tasksAreEquals(taskManager1.getSubtaskById(6), taskManager2.getSubtaskById(6)), "Исходная задача не соответствует загруженной"); - assertTrue(tasksAreEquals(taskManager1.getSubtaskById(7).get(), taskManager2.getSubtaskById(7).get()), + assertTrue(tasksAreEquals(taskManager1.getSubtaskById(7), taskManager2.getSubtaskById(7)), "Исходная задача не соответствует загруженной"); diff --git a/test/tracker/controllers/InMemoryTaskManagerTest.java b/test/tracker/controllers/InMemoryTaskManagerTest.java index 58b99c3..a47cfc9 100644 --- a/test/tracker/controllers/InMemoryTaskManagerTest.java +++ b/test/tracker/controllers/InMemoryTaskManagerTest.java @@ -11,8 +11,7 @@ import static org.junit.jupiter.api.Assertions.*; -class InMemoryTaskManagerTest { - TaskManager taskManager; +class InMemoryTaskManagerTest extends TaskManagerTest{ final long MINUTES_IN_DAY = 60 * 24; final LocalDateTime TASK_START_TIME = LocalDateTime.now(); @@ -43,13 +42,13 @@ void checkEpic() { MINUTES_IN_DAY, TASK_START_TIME); taskManager.createSubtask(subtask3); - assertEquals(1, taskManager.getTaskById(task1.getId()).get().getId(), "Неверный Id"); - assertEquals(2, taskManager.getTaskById(task2.getId()).get().getId(), "Неверный Id"); + assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id"); + assertEquals(2, taskManager.getTaskById(task2.getId()).getId(), "Неверный Id"); assertEquals(3, taskManager.getEpicById(epic1.getId()).getId(), "Неверный Id"); assertEquals(4, taskManager.getEpicById(epic2.getId()).getId(), "Неверный Id"); - assertEquals(5, taskManager.getSubtaskById(subtask1.getId()).get().getId(), "Неверный Id"); - assertEquals(6, taskManager.getSubtaskById(subtask2.getId()).get().getId(), "Неверный Id"); - assertEquals(7, taskManager.getSubtaskById(subtask3.getId()).get().getId(), "Неверный Id"); + assertEquals(5, taskManager.getSubtaskById(subtask1.getId()).getId(), "Неверный Id"); + assertEquals(6, taskManager.getSubtaskById(subtask2.getId()).getId(), "Неверный Id"); + assertEquals(7, taskManager.getSubtaskById(subtask3.getId()).getId(), "Неверный Id"); } @Test @@ -101,10 +100,10 @@ void checkTaskIntersection() { Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY, TASK_START_TIME); taskManager.createTask(task2); - assertEquals(1, taskManager.getTaskById(task1.getId()).get().getId(), "Неверный Id"); + assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id"); assertEquals(1, taskManager.getTasks().size(), "Неверное количество задач"); task2.setStartTime(TASK_START_TIME.plusDays(1)); taskManager.createTask(task2); - assertEquals(2, taskManager.getTaskById(task2.getId()).get().getId(), "Неверный Id"); + assertEquals(2, taskManager.getTaskById(task2.getId()).getId(), "Неверный Id"); } } \ No newline at end of file diff --git a/test/tracker/controllers/TaskManagerTest.java b/test/tracker/controllers/TaskManagerTest.java index e27b2a5..1db1a53 100644 --- a/test/tracker/controllers/TaskManagerTest.java +++ b/test/tracker/controllers/TaskManagerTest.java @@ -1,6 +1,5 @@ package tracker.controllers; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import tracker.model.Epic; import tracker.model.Status; @@ -13,14 +12,10 @@ abstract class TaskManagerTest { - TaskManager taskManager; + T taskManager; final long MINUTES_IN_DAY = 60 * 24; final LocalDateTime TASK_START_TIME = LocalDateTime.now(); - @BeforeEach - void initializeTask() { - taskManager = Managers.getDefault(); - } @Test void checkEpic() { Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY, @@ -43,13 +38,13 @@ void checkEpic() { MINUTES_IN_DAY, TASK_START_TIME); taskManager.createSubtask(subtask3); - assertEquals(1, taskManager.getTaskById(task1.getId()).get().getId(), "Неверный Id"); - assertEquals(2, taskManager.getTaskById(task2.getId()).get().getId(), "Неверный Id"); + assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id"); + assertEquals(2, taskManager.getTaskById(task2.getId()).getId(), "Неверный Id"); assertEquals(3, taskManager.getEpicById(epic1.getId()).getId(), "Неверный Id"); assertEquals(4, taskManager.getEpicById(epic2.getId()).getId(), "Неверный Id"); - assertEquals(5, taskManager.getSubtaskById(subtask1.getId()).get().getId(), "Неверный Id"); - assertEquals(6, taskManager.getSubtaskById(subtask2.getId()).get().getId(), "Неверный Id"); - assertEquals(7, taskManager.getSubtaskById(subtask3.getId()).get().getId(), "Неверный Id"); + assertEquals(5, taskManager.getSubtaskById(subtask1.getId()).getId(), "Неверный Id"); + assertEquals(6, taskManager.getSubtaskById(subtask2.getId()).getId(), "Неверный Id"); + assertEquals(7, taskManager.getSubtaskById(subtask3.getId()).getId(), "Неверный Id"); } @Test @@ -101,10 +96,10 @@ void checkTaskIntersection() { Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY, TASK_START_TIME); taskManager.createTask(task2); - assertEquals(1, taskManager.getTaskById(task1.getId()).get().getId(), "Неверный Id"); + assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id"); assertEquals(1, taskManager.getTasks().size(), "Неверное количество задач"); task2.setStartTime(TASK_START_TIME.plusDays(1)); taskManager.createTask(task2); - assertEquals(2, taskManager.getTaskById(task2.getId()).get().getId(), "Неверный Id"); + assertEquals(2, taskManager.getTaskById(task2.getId()).getId(), "Неверный Id"); } } From 8b234f2a2db6d9bedc1a70c749d049ed919e9d19 Mon Sep 17 00:00:00 2001 From: Aleksandr Fedorov Date: Sun, 20 Jul 2025 22:03:36 +0300 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20sprint=208,=20=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/InMemoryTaskManager.java | 2 + .../controllers/InMemoryTaskManagerTest.java | 100 +----------------- 2 files changed, 3 insertions(+), 99 deletions(-) diff --git a/src/tracker/controllers/InMemoryTaskManager.java b/src/tracker/controllers/InMemoryTaskManager.java index 2277922..4c6e9c5 100644 --- a/src/tracker/controllers/InMemoryTaskManager.java +++ b/src/tracker/controllers/InMemoryTaskManager.java @@ -76,6 +76,8 @@ public void deleteAllSubtasks() { for (Subtask subtask: subtasks.values()) { inMemoryHistoryManager.remove(subtask.getId()); sortedTasks.remove(subtask); + updateEpicStatus(subtask.getEpic()); + updateEpicEndTimeAndDuration(subtask.getEpic()); } subtasks.clear(); } diff --git a/test/tracker/controllers/InMemoryTaskManagerTest.java b/test/tracker/controllers/InMemoryTaskManagerTest.java index a47cfc9..8260e39 100644 --- a/test/tracker/controllers/InMemoryTaskManagerTest.java +++ b/test/tracker/controllers/InMemoryTaskManagerTest.java @@ -1,109 +1,11 @@ package tracker.controllers; -import tracker.model.Epic; -import tracker.model.Status; -import tracker.model.Subtask; -import tracker.model.Task; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import java.time.LocalDateTime; - -import static org.junit.jupiter.api.Assertions.*; - -class InMemoryTaskManagerTest extends TaskManagerTest{ - final long MINUTES_IN_DAY = 60 * 24; - final LocalDateTime TASK_START_TIME = LocalDateTime.now(); +class InMemoryTaskManagerTest extends TaskManagerTest { @BeforeEach void initializeTask() { taskManager = new InMemoryTaskManager(); } - - @Test - void checkEpic() { - Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY, - TASK_START_TIME.minusDays(4)); - taskManager.createTask(task1); - Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY, - TASK_START_TIME.minusDays(3)); - taskManager.createTask(task2); - Epic epic1 = new Epic("Epic 1", "Do all subtasks from epic 1", taskManager.getTaskId()); - taskManager.createEpic(epic1); - Epic epic2 = new Epic("Epic 2", "Do all subtasks from epic 2", taskManager.getTaskId()); - taskManager.createEpic(epic2); - Subtask subtask1 = new Subtask("Subtask 1", "Do subtask 1", taskManager.getTaskId(), epic1, - MINUTES_IN_DAY, TASK_START_TIME.minusDays(2)); - taskManager.createSubtask(subtask1); - Subtask subtask2 = new Subtask("Subtask 2", "Do subtask 2", taskManager.getTaskId(), epic1, - MINUTES_IN_DAY, TASK_START_TIME.minusDays(1)); - taskManager.createSubtask(subtask2); - Subtask subtask3 = new Subtask("Subtask 3", "Do subtask 3", taskManager.getTaskId(), epic2, - MINUTES_IN_DAY, TASK_START_TIME); - taskManager.createSubtask(subtask3); - - assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id"); - assertEquals(2, taskManager.getTaskById(task2.getId()).getId(), "Неверный Id"); - assertEquals(3, taskManager.getEpicById(epic1.getId()).getId(), "Неверный Id"); - assertEquals(4, taskManager.getEpicById(epic2.getId()).getId(), "Неверный Id"); - assertEquals(5, taskManager.getSubtaskById(subtask1.getId()).getId(), "Неверный Id"); - assertEquals(6, taskManager.getSubtaskById(subtask2.getId()).getId(), "Неверный Id"); - assertEquals(7, taskManager.getSubtaskById(subtask3.getId()).getId(), "Неверный Id"); - } - - @Test - void checkEpicStatus() { - // Все подзадачи со статусом NEW. - Epic epic1 = new Epic("Epic 1", "Do all subtasks from epic 1", taskManager.getTaskId()); - taskManager.createEpic(epic1); - Subtask subtask1 = new Subtask("Subtask 1", "Do subtask 1", taskManager.getTaskId(), epic1, - MINUTES_IN_DAY, TASK_START_TIME.minusDays(3)); - taskManager.createSubtask(subtask1); - Subtask subtask2 = new Subtask("Subtask 2", "Do subtask 2", taskManager.getTaskId(), epic1, - MINUTES_IN_DAY, TASK_START_TIME.minusDays(2)); - taskManager.createSubtask(subtask2); - assertEquals(Status.NEW, epic1.getStatus(), "Статус эпика должен быть NEW"); - // Подзадачи со статусами NEW и DONE. - subtask2.setStatus(Status.DONE); - taskManager.updateEpicStatus(epic1); - assertEquals(Status.IN_PROGRESS, epic1.getStatus(), "Статус эпика должен быть IN_PROGRESS"); - // Подзадачи со статусом IN_PROGRESS. - Epic epic2 = new Epic("Epic 2", "Do all subtasks from epic 2", taskManager.getTaskId()); - taskManager.createEpic(epic2); - Subtask subtask3 = new Subtask("Subtask 3", "Do subtask 3", taskManager.getTaskId(), epic2, - MINUTES_IN_DAY, TASK_START_TIME.minusDays(1)); - taskManager.createSubtask(subtask3); - Subtask subtask4 = new Subtask("Subtask 4", "Do subtask 4", taskManager.getTaskId(), epic2, - MINUTES_IN_DAY, TASK_START_TIME); - taskManager.createSubtask(subtask4); - subtask3.setStatus(Status.IN_PROGRESS); - subtask4.setStatus(Status.IN_PROGRESS); - taskManager.updateEpicStatus(epic2); - assertEquals(Status.IN_PROGRESS, epic2.getStatus(), "Статус эпика должен быть IN_PROGRESS"); - // Все подзадачи со статусом DONE. - subtask1.setStatus(Status.DONE); - subtask2.setStatus(Status.DONE); - subtask3.setStatus(Status.DONE); - subtask4.setStatus(Status.DONE); - taskManager.updateEpicStatus(epic1); - taskManager.updateEpicStatus(epic2); - assertEquals(Status.DONE, epic1.getStatus(), "Статус эпика должен быть DONE"); - assertEquals(Status.DONE, epic2.getStatus(), "Статус эпика должен быть DONE"); - } - - @Test - void checkTaskIntersection() { - // При наличии пересечения по времени выполнения задача не будет создана - Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY, - TASK_START_TIME); - taskManager.createTask(task1); - Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY, - TASK_START_TIME); - taskManager.createTask(task2); - assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id"); - assertEquals(1, taskManager.getTasks().size(), "Неверное количество задач"); - task2.setStartTime(TASK_START_TIME.plusDays(1)); - taskManager.createTask(task2); - assertEquals(2, taskManager.getTaskById(task2.getId()).getId(), "Неверный Id"); - } } \ No newline at end of file