From 1e9a3823f448eedde72911ef3bdbb92df22bf547 Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 8 Jul 2025 13:10:46 +0400 Subject: [PATCH 1/2] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D1=82=D1=8C=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20?= =?UTF-8?q?=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B2=20=D1=84=D0=B0?= =?UTF-8?q?=D0=B9=D0=BB.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/data.csv | 3 + src/Main.java | 27 ++- src/manager/CsvFormatter.java | 59 +++++ src/manager/FileBackedTaskManager.java | 221 ++++++++++++++++++ src/manager/InMemoryTaskManager.java | 16 +- src/manager/Managers.java | 11 +- .../exceptions/ManagerLoadException.java | 12 + .../exceptions/ManagerSaveException.java | 7 + src/tasks/Epic.java | 5 + src/tasks/Subtask.java | 5 + src/tasks/Task.java | 5 +- src/tasks/TaskType.java | 7 + test/manager/FileBackedTaskManagerTest.java | 148 ++++++++++++ 13 files changed, 515 insertions(+), 11 deletions(-) create mode 100644 resources/data.csv create mode 100644 src/manager/CsvFormatter.java create mode 100644 src/manager/FileBackedTaskManager.java create mode 100644 src/manager/exceptions/ManagerLoadException.java create mode 100644 src/manager/exceptions/ManagerSaveException.java create mode 100644 src/tasks/TaskType.java create mode 100644 test/manager/FileBackedTaskManagerTest.java diff --git a/resources/data.csv b/resources/data.csv new file mode 100644 index 0000000..49a15bb --- /dev/null +++ b/resources/data.csv @@ -0,0 +1,3 @@ +id,type,name,status,description,epic +1,TASK,Manual,NEW,Desc, +2,TASK,Auto,NEW,Desc, diff --git a/src/Main.java b/src/Main.java index 784c22a..8b6e991 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,3 +1,4 @@ +import manager.FileBackedTaskManager; import manager.Managers; import manager.TaskManager; import tasks.Task; @@ -5,9 +6,12 @@ import tasks.Subtask; import tasks.Epic; +import java.io.File; + public class Main { public static void main(String[] args) { + File dataFile = new File("resources/data.csv"); TaskManager taskManager = Managers.getDefault(); // 1. Создать таску @@ -60,20 +64,37 @@ public static void main(String[] args) { System.out.println("История после просмотра второй подзадачи (4 задачи): " + taskManager.getHistory()); System.out.println(); - // 8. Удаляем таску (должна удалиться из истории) + // 8. Проверяем сохранение в файл. + System.out.println("Проверка работы с файлом:"); + TaskManager loadedManager = FileBackedTaskManager.loadFromFile(dataFile); + System.out.println("Загруженные задачи: " + loadedManager.getTasks()); + System.out.println("Загруженные эпики: " + loadedManager.getEpics()); + System.out.println("Загруженные сабтаски: " + loadedManager.getSubtasks()); + System.out.println(); + + // 9. Удаляем таску (должна удалиться из истории) System.out.println("Удаляем таску"); taskManager.deleteTask(task.getId()); System.out.println("История после удаления задачи (3 задачи): " + taskManager.getHistory()); System.out.println(); - // 9. Удаляем Эпик (должны удалиться эпик и его подзадачи из истории) + // 10. Удаляем Эпик (должны удалиться эпик и его подзадачи из истории) System.out.println("Удаляем Эпик"); taskManager.deleteEpic(epic.getId()); System.out.println("История после удаления эпика (должна быть пустая): " + taskManager.getHistory()); System.out.println(); - // 10. Проверяем историю после всех операций + // 11. Проверяем историю после всех операций. System.out.println("Финальная проверка истории"); System.out.println("История: " + taskManager.getHistory()); + System.out.println(); + + // 12. Проверяем удаление из файла. + System.out.println("Проверка работы с файлом:"); + TaskManager newLoadedManager = FileBackedTaskManager.loadFromFile(dataFile); + System.out.println("Загруженные задачи: " + newLoadedManager.getTasks()); + System.out.println("Загруженные эпики: " + newLoadedManager.getEpics()); + System.out.println("Загруженные сабтаски: " + newLoadedManager.getSubtasks()); + System.out.println(); } } diff --git a/src/manager/CsvFormatter.java b/src/manager/CsvFormatter.java new file mode 100644 index 0000000..6d33f14 --- /dev/null +++ b/src/manager/CsvFormatter.java @@ -0,0 +1,59 @@ +package manager; +import tasks.*; + +public class CsvFormatter { + + public static final String CSV_HEADER = "id,type,name,status,description,epic"; + + + // Преобразование задачи в CSV строку + public static String toString(Task task) { + if (task == null) return ""; + + String epicField = ""; + if (task.getType() == TaskType.SUBTASK) { + epicField = String.valueOf(((Subtask) task).getEpicId()); + } + + return String.join(",", + String.valueOf(task.getId()), + task.getType().name(), + task.getName(), + task.getTaskStatus().name(), + task.getDescription(), + epicField); + } + + // Создание задачи из CSV строки + public static Task fromString(String value) { + if (value == null || value.isEmpty()) return null; + + String[] fields = value.split(","); + if (fields.length < 5) return null; + + int id = Integer.parseInt(fields[0]); + TaskType type = TaskType.valueOf(fields[1]); + String name = fields[2]; + TaskStatus status = TaskStatus.valueOf(fields[3]); + String description = fields[4]; + + switch (type) { + case TASK: + return new Task(id, name, description, status); + case EPIC: + Epic epic = new Epic(name, description); + epic.setId(id); + epic.setTaskStatus(status); + return epic; + case SUBTASK: + int epicId = fields.length > 5 ? Integer.parseInt(fields[5]) : 0; + Subtask subtask = new Subtask(name, description, status, epicId); + subtask.setId(id); + return subtask; + default: + return null; + } + } +} + + diff --git a/src/manager/FileBackedTaskManager.java b/src/manager/FileBackedTaskManager.java new file mode 100644 index 0000000..a558e3b --- /dev/null +++ b/src/manager/FileBackedTaskManager.java @@ -0,0 +1,221 @@ +package manager; + +import tasks.*; +import manager.exceptions.ManagerSaveException; +import manager.exceptions.ManagerLoadException; +import java.io.*; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +public class FileBackedTaskManager extends InMemoryTaskManager { + + private final File file; + + + public FileBackedTaskManager(File file, HistoryManager historyManager) { + this.file = file; + this.historyManager = historyManager; + } + + // Загрузка данных из файла. + public static FileBackedTaskManager loadFromFile(File file) { + FileBackedTaskManager manager = new FileBackedTaskManager(file, Managers.getDefaultHistory()); + + if (file.exists() && file.length() > 0) { + try { + manager.load(); + } catch (ManagerLoadException e) { + System.out.println("Ошибка при загрузке файла " + file.getName() + ": " + e.getMessage()); + } + } + return manager; + } + + + + // Переопределенные методы Task + @Override + public List getTasks() { + return super.getTasks(); + } + + @Override + public Task getTask(int id) { + Task task = super.getTask(id); + save(); + return task; + } + + @Override + public Task createTask(Task task) { + Task createdTask = super.createTask(task); + save(); + return createdTask; + } + + @Override + public Task updateTask(Task task) { + Task updatedTask = super.updateTask(task); + save(); + return updatedTask; + } + + @Override + public Task deleteTask(int id) { + Task deletedTask = super.deleteTask(id); + save(); + return deletedTask; + } + + // Переопределенные методы Subtask + @Override + public List getSubtasks() { + return super.getSubtasks(); + } + + @Override + public Subtask getSubtasks(int id) { + Subtask subtask = super.getSubtasks(id); + save(); + return subtask; + } + + @Override + public Subtask createSubtask(Subtask subtask) { + Subtask createdSubtask = super.createSubtask(subtask); + save(); + return createdSubtask; + } + + @Override + public Subtask updateSubtask(Subtask subtask) { + Subtask updatedSubtask = super.updateSubtask(subtask); + save(); + return updatedSubtask; + } + + @Override + public Subtask deleteSubtask(int id) { + Subtask deletedSubtask = super.deleteSubtask(id); + save(); + return deletedSubtask; + } + + @Override + public List getEpicSubtasks(int epicId) { + return super.getEpicSubtasks(epicId); + } + + // Переопределенные методы Epic + @Override + public List getEpics() { + return super.getEpics(); + } + + @Override + public Epic getEpic(int id) { + Epic epic = super.getEpic(id); + save(); + return epic; + } + + @Override + public Epic createEpic(Epic epic) { + Epic createdEpic = super.createEpic(epic); + save(); + return createdEpic; + } + + @Override + public Epic updateEpic(Epic epic) { + Epic updatedEpic = super.updateEpic(epic); + save(); + return updatedEpic; + } + + @Override + public Epic deleteEpic(int id) { + Epic deletedEpic = super.deleteEpic(id); + save(); + return deletedEpic; + } + + // Переопределенные методы удаления всех задач + @Override + public void deleteAllTasks() { + super.deleteAllTasks(); + save(); + } + + @Override + public void deleteAllSubtasks() { + super.deleteAllSubtasks(); + save(); + } + + @Override + public void deleteAllEpics() { + super.deleteAllEpics(); + save(); + } + + @Override + public void deleteAll() { + super.deleteAll(); + save(); + } + + + // Загрузка данных + private void load() throws ManagerLoadException { + try { + String content = Files.readString(file.toPath()); + String[] lines = content.split("\n"); + + if (lines.length < 2) return; + + for (int i = 1; i < lines.length; i++) { + Task task = CsvFormatter.fromString(lines[i]); + if (task == null) continue; + + switch (task.getType()) { + case TASK: + tasks.put(task.getId(), task); + break; + case EPIC: + epics.put(task.getId(), (Epic) task); + break; + case SUBTASK: + subtasks.put(task.getId(), (Subtask) task); + break; + } + } + } catch (IOException e) { + throw new ManagerLoadException("Не удалось загрузить задачи из файла: " + file.getPath(), e); + } + } + + // Сохранение данных в файл + void save() throws ManagerSaveException { + try (FileWriter writer = new FileWriter(file)) { + writer.write(CsvFormatter.CSV_HEADER + "\n"); // Запись заголовка + for (Task task : getAllTasks()) { + writer.write(CsvFormatter.toString(task) + "\n"); // Запись задач + } + } catch (IOException e) { + throw new ManagerSaveException("Ошибка сохранения файла", e); + } + } + + // Получение всех задач. + private List getAllTasks() { + List tasks = new ArrayList<>(); + tasks.addAll(getTasks()); + tasks.addAll(getEpics()); + tasks.addAll(getSubtasks()); + return tasks; + } +} + + diff --git a/src/manager/InMemoryTaskManager.java b/src/manager/InMemoryTaskManager.java index 2c7dae9..daf3737 100644 --- a/src/manager/InMemoryTaskManager.java +++ b/src/manager/InMemoryTaskManager.java @@ -13,11 +13,15 @@ public class InMemoryTaskManager implements TaskManager { - private Map tasks = new HashMap<>(); - private Map subtasks = new HashMap<>(); - private Map epics = new HashMap<>(); - private int generatorId = 1; - private HistoryManager historyManager = Managers.getDefaultHistory(); + protected final Map tasks = new HashMap<>(); + protected final Map subtasks = new HashMap<>(); + protected final Map epics = new HashMap<>(); + protected int generatorId = 1; + protected HistoryManager historyManager; + + public InMemoryTaskManager() { + this.historyManager = Managers.getDefaultHistory(); + } // Методы для Task @@ -269,6 +273,6 @@ private void updateEpicStatus(Epic epic) { private int getNextId() { return generatorId++; } - } + diff --git a/src/manager/Managers.java b/src/manager/Managers.java index fd5b454..c143b49 100644 --- a/src/manager/Managers.java +++ b/src/manager/Managers.java @@ -1,12 +1,21 @@ package manager; +import java.io.File; + public class Managers { private Managers() { } public static TaskManager getDefault() { - return new InMemoryTaskManager(); + String path = "resources" + File.separator + "data.csv"; + File file = new File(path); + + File dir = new File("resources"); + if (!dir.exists()) { + dir.mkdir(); + } + return new FileBackedTaskManager(file, getDefaultHistory()); } public static HistoryManager getDefaultHistory() { diff --git a/src/manager/exceptions/ManagerLoadException.java b/src/manager/exceptions/ManagerLoadException.java new file mode 100644 index 0000000..cc2aec9 --- /dev/null +++ b/src/manager/exceptions/ManagerLoadException.java @@ -0,0 +1,12 @@ +package manager.exceptions; + +public class ManagerLoadException extends RuntimeException { + + public ManagerLoadException(String message) { + super(message); + } + + public ManagerLoadException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/manager/exceptions/ManagerSaveException.java b/src/manager/exceptions/ManagerSaveException.java new file mode 100644 index 0000000..7352e06 --- /dev/null +++ b/src/manager/exceptions/ManagerSaveException.java @@ -0,0 +1,7 @@ +package manager.exceptions; + +public class ManagerSaveException extends RuntimeException { + public ManagerSaveException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/tasks/Epic.java b/src/tasks/Epic.java index 4272c85..e8fe0e3 100644 --- a/src/tasks/Epic.java +++ b/src/tasks/Epic.java @@ -22,6 +22,11 @@ public void removeSubtaskId(int subtaskId) { subtasksId.remove((Integer) subtaskId); } + @Override + public TaskType getType() { + return TaskType.EPIC; + } + @Override public void setTaskStatus(TaskStatus taskStatus) { super.setTaskStatus(taskStatus); diff --git a/src/tasks/Subtask.java b/src/tasks/Subtask.java index 4103a52..df98a57 100644 --- a/src/tasks/Subtask.java +++ b/src/tasks/Subtask.java @@ -14,6 +14,11 @@ public Subtask(Integer id, String name, String description, TaskStatus taskStatu this.epicId = epicId; } + @Override + public TaskType getType() { + return TaskType.SUBTASK; + } + public int getEpicId() { return epicId; } diff --git a/src/tasks/Task.java b/src/tasks/Task.java index bdaa9fc..98ff3ba 100644 --- a/src/tasks/Task.java +++ b/src/tasks/Task.java @@ -1,7 +1,6 @@ package tasks; - public class Task { private Integer id; @@ -23,6 +22,10 @@ public Task(Integer id, String name, String description, TaskStatus taskStatus) this.taskStatus = taskStatus; } + public TaskType getType() { + return TaskType.TASK; + } + public Integer getId() { return id; } diff --git a/src/tasks/TaskType.java b/src/tasks/TaskType.java new file mode 100644 index 0000000..4dd6736 --- /dev/null +++ b/src/tasks/TaskType.java @@ -0,0 +1,7 @@ +package tasks; + +public enum TaskType { + TASK, + EPIC, + SUBTASK +} diff --git a/test/manager/FileBackedTaskManagerTest.java b/test/manager/FileBackedTaskManagerTest.java new file mode 100644 index 0000000..c6e18ef --- /dev/null +++ b/test/manager/FileBackedTaskManagerTest.java @@ -0,0 +1,148 @@ +package manager; +import static org.junit.jupiter.api.Assertions.*; + +import java.io.File; +import java.io.IOException; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import tasks.Epic; +import tasks.Subtask; +import tasks.Task; +import tasks.TaskStatus; + + + +public class FileBackedTaskManagerTest { + private File tempFile; + private FileBackedTaskManager manager; + + @BeforeEach + void setUP() throws IOException { + tempFile = File.createTempFile("data", ".csv"); + manager = new FileBackedTaskManager(tempFile, Managers.getDefaultHistory()); + } + + @AfterEach + void remove() { + tempFile.delete(); + } + + @Test + void testSaveAndLoadEmptyManager() { + manager.save(); + FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); + assertTrue(loadedManager.getTasks().isEmpty()); + assertTrue(loadedManager.getEpics().isEmpty()); + assertTrue(loadedManager.getSubtasks().isEmpty()); + } + + @Test + void testSaveAndLoadTasks() { + Task task = new Task("Task 1", "Description 1", TaskStatus.NEW); + manager.createTask(task); + int taskId = task.getId(); + + Epic epic = new Epic("Epic 1", "Epic description"); + manager.createEpic(epic); + int epicId = epic.getId(); + + Subtask subtask = new Subtask("Subtask 1", "Subtask desc", TaskStatus.NEW, epic.getId()); + manager.createSubtask(subtask); + int subtaskId = subtask.getId(); + + FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); + + Task loadedTask = loadedManager.getTask(taskId); + assertNotNull(loadedTask); + assertEquals("Task 1", loadedTask.getName()); + + Epic loadedEpic = loadedManager.getEpic(epicId); + assertNotNull(loadedEpic); + assertEquals("Epic 1", loadedEpic.getName()); + + Subtask loadedSubtask = loadedManager.getSubtasks(subtaskId); + assertNotNull(loadedSubtask); + assertEquals("Subtask 1", loadedSubtask.getName()); + + } + + @Test + void testTaskUpdateAndSave() { + Task task = new Task("Original task", "Desc", TaskStatus.NEW); + manager.createTask(task); + int taskId = task.getId(); + + task.setName("Updated task"); + task.setTaskStatus(TaskStatus.IN_PROGRESS); + manager.updateTask(task); + + FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); + + Task loadedTask = loadedManager.getTask(taskId); + assertEquals("Updated task", loadedTask.getName()); + assertEquals(TaskStatus.IN_PROGRESS, loadedTask.getTaskStatus()); + } + + @Test + void testEpicStatusAfterLoading() { + Epic epic = new Epic("Epic", "Epic desc"); + manager.createEpic(epic); + int epicId = epic.getId(); + + Subtask subtask = new Subtask("Subtask", "Desc", TaskStatus.NEW, epicId); + manager.createSubtask(subtask); + int subtaskId = subtask.getId(); + + subtask.setTaskStatus(TaskStatus.DONE); + manager.updateSubtask(subtask); + + FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); + + assertEquals(TaskStatus.DONE, loadedManager.getEpic(epicId).getTaskStatus()); + } + + @Test + void testDeleteTaskAndSave() { + Task task = new Task("Task to delete", "Desc", TaskStatus.NEW); + manager.createTask(task); + int taskId = task.getId(); + + manager.deleteTask(taskId); + + FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); + + assertNull(loadedManager.getTask(taskId)); + assertTrue(loadedManager.getTasks().isEmpty()); + } + + @Test + void testLoadFromNonExistentFile() { + File nonExistentFile = new File("non_existent_file.csv"); + FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(nonExistentFile); + + assertTrue(loadedManager.getTasks().isEmpty()); + assertTrue(loadedManager.getEpics().isEmpty()); + assertTrue(loadedManager.getSubtasks().isEmpty()); + } + + @Test + void testSaveAfterDeletingAllTasks() { + Task task1 = new Task("Task 1", "Desc", TaskStatus.NEW); + manager.createTask(task1); + int task1Id = task1.getId(); + + Task task2 = new Task("Task 2", "Desc", TaskStatus.NEW); + manager.createTask(task2); + int task2Id = task2.getId(); + + manager.deleteAllTasks(); + + FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); + + assertNull(loadedManager.getTask(task1Id)); + assertNull(loadedManager.getTask(task2Id)); + assertTrue(loadedManager.getTasks().isEmpty()); + } +} \ No newline at end of file From f7d9fe717b38267deb8ea317ecd4d3e52154578b Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 9 Jul 2025 19:27:06 +0400 Subject: [PATCH 2/2] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20pull=20requests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/data.csv | 2 - src/manager/FileBackedTaskManager.java | 44 ++-- test/manager/FileBackedTaskManagerTest.java | 46 +++-- test/manager/InMemoryTaskManagerTest.java | 211 +------------------ test/manager/TaskManagerTest.java | 214 ++++++++++++++++++++ 5 files changed, 258 insertions(+), 259 deletions(-) create mode 100644 test/manager/TaskManagerTest.java diff --git a/resources/data.csv b/resources/data.csv index 49a15bb..5cdfc28 100644 --- a/resources/data.csv +++ b/resources/data.csv @@ -1,3 +1 @@ id,type,name,status,description,epic -1,TASK,Manual,NEW,Desc, -2,TASK,Auto,NEW,Desc, diff --git a/src/manager/FileBackedTaskManager.java b/src/manager/FileBackedTaskManager.java index a558e3b..29e8831 100644 --- a/src/manager/FileBackedTaskManager.java +++ b/src/manager/FileBackedTaskManager.java @@ -23,11 +23,7 @@ public static FileBackedTaskManager loadFromFile(File file) { FileBackedTaskManager manager = new FileBackedTaskManager(file, Managers.getDefaultHistory()); if (file.exists() && file.length() > 0) { - try { - manager.load(); - } catch (ManagerLoadException e) { - System.out.println("Ошибка при загрузке файла " + file.getName() + ": " + e.getMessage()); - } + manager.load(); } return manager; } @@ -35,11 +31,6 @@ public static FileBackedTaskManager loadFromFile(File file) { // Переопределенные методы Task - @Override - public List getTasks() { - return super.getTasks(); - } - @Override public Task getTask(int id) { Task task = super.getTask(id); @@ -69,11 +60,6 @@ public Task deleteTask(int id) { } // Переопределенные методы Subtask - @Override - public List getSubtasks() { - return super.getSubtasks(); - } - @Override public Subtask getSubtasks(int id) { Subtask subtask = super.getSubtasks(id); @@ -102,17 +88,7 @@ public Subtask deleteSubtask(int id) { return deletedSubtask; } - @Override - public List getEpicSubtasks(int epicId) { - return super.getEpicSubtasks(epicId); - } - // Переопределенные методы Epic - @Override - public List getEpics() { - return super.getEpics(); - } - @Override public Epic getEpic(int id) { Epic epic = super.getEpic(id); @@ -168,17 +144,23 @@ public void deleteAll() { // Загрузка данных - private void load() throws ManagerLoadException { + private void load() { try { String content = Files.readString(file.toPath()); String[] lines = content.split("\n"); if (lines.length < 2) return; + int maxId = 0; + for (int i = 1; i < lines.length; i++) { Task task = CsvFormatter.fromString(lines[i]); if (task == null) continue; + if (task.getId() > maxId) { + maxId = task.getId(); + } + switch (task.getType()) { case TASK: tasks.put(task.getId(), task); @@ -187,17 +169,23 @@ private void load() throws ManagerLoadException { epics.put(task.getId(), (Epic) task); break; case SUBTASK: - subtasks.put(task.getId(), (Subtask) task); + Subtask subtask = (Subtask) task; + subtasks.put(task.getId(), subtask); + Epic epic = epics.get(subtask.getEpicId()); + if (epic != null) { + epic.addSubtaskId(subtask.getId()); + } break; } } + generatorId = maxId + 1; } catch (IOException e) { throw new ManagerLoadException("Не удалось загрузить задачи из файла: " + file.getPath(), e); } } // Сохранение данных в файл - void save() throws ManagerSaveException { + private void save() throws ManagerSaveException { try (FileWriter writer = new FileWriter(file)) { writer.write(CsvFormatter.CSV_HEADER + "\n"); // Запись заголовка for (Task task : getAllTasks()) { diff --git a/test/manager/FileBackedTaskManagerTest.java b/test/manager/FileBackedTaskManagerTest.java index c6e18ef..40a60fd 100644 --- a/test/manager/FileBackedTaskManagerTest.java +++ b/test/manager/FileBackedTaskManagerTest.java @@ -3,9 +3,7 @@ import java.io.File; import java.io.IOException; - import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import tasks.Epic; import tasks.Subtask; @@ -14,14 +12,19 @@ -public class FileBackedTaskManagerTest { +public class FileBackedTaskManagerTest extends TaskManagerTest { + private File tempFile; - private FileBackedTaskManager manager; - @BeforeEach - void setUP() throws IOException { - tempFile = File.createTempFile("data", ".csv"); - manager = new FileBackedTaskManager(tempFile, Managers.getDefaultHistory()); + + @Override + protected FileBackedTaskManager createTaskManager() { + try { + tempFile = File.createTempFile("data", ".csv"); + return new FileBackedTaskManager(tempFile, Managers.getDefaultHistory()); + } catch (IOException e) { + throw new RuntimeException("Не удалось создать временный файл", e); + } } @AfterEach @@ -31,7 +34,6 @@ void remove() { @Test void testSaveAndLoadEmptyManager() { - manager.save(); FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); assertTrue(loadedManager.getTasks().isEmpty()); assertTrue(loadedManager.getEpics().isEmpty()); @@ -41,15 +43,15 @@ void testSaveAndLoadEmptyManager() { @Test void testSaveAndLoadTasks() { Task task = new Task("Task 1", "Description 1", TaskStatus.NEW); - manager.createTask(task); + taskManager.createTask(task); int taskId = task.getId(); Epic epic = new Epic("Epic 1", "Epic description"); - manager.createEpic(epic); + taskManager.createEpic(epic); int epicId = epic.getId(); Subtask subtask = new Subtask("Subtask 1", "Subtask desc", TaskStatus.NEW, epic.getId()); - manager.createSubtask(subtask); + taskManager.createSubtask(subtask); int subtaskId = subtask.getId(); FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); @@ -71,12 +73,12 @@ void testSaveAndLoadTasks() { @Test void testTaskUpdateAndSave() { Task task = new Task("Original task", "Desc", TaskStatus.NEW); - manager.createTask(task); + taskManager.createTask(task); int taskId = task.getId(); task.setName("Updated task"); task.setTaskStatus(TaskStatus.IN_PROGRESS); - manager.updateTask(task); + taskManager.updateTask(task); FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); @@ -88,15 +90,15 @@ void testTaskUpdateAndSave() { @Test void testEpicStatusAfterLoading() { Epic epic = new Epic("Epic", "Epic desc"); - manager.createEpic(epic); + taskManager.createEpic(epic); int epicId = epic.getId(); Subtask subtask = new Subtask("Subtask", "Desc", TaskStatus.NEW, epicId); - manager.createSubtask(subtask); + taskManager.createSubtask(subtask); int subtaskId = subtask.getId(); subtask.setTaskStatus(TaskStatus.DONE); - manager.updateSubtask(subtask); + taskManager.updateSubtask(subtask); FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); @@ -106,10 +108,10 @@ void testEpicStatusAfterLoading() { @Test void testDeleteTaskAndSave() { Task task = new Task("Task to delete", "Desc", TaskStatus.NEW); - manager.createTask(task); + taskManager.createTask(task); int taskId = task.getId(); - manager.deleteTask(taskId); + taskManager.deleteTask(taskId); FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); @@ -130,14 +132,14 @@ void testLoadFromNonExistentFile() { @Test void testSaveAfterDeletingAllTasks() { Task task1 = new Task("Task 1", "Desc", TaskStatus.NEW); - manager.createTask(task1); + taskManager.createTask(task1); int task1Id = task1.getId(); Task task2 = new Task("Task 2", "Desc", TaskStatus.NEW); - manager.createTask(task2); + taskManager.createTask(task2); int task2Id = task2.getId(); - manager.deleteAllTasks(); + taskManager.deleteAllTasks(); FileBackedTaskManager loadedManager = FileBackedTaskManager.loadFromFile(tempFile); diff --git a/test/manager/InMemoryTaskManagerTest.java b/test/manager/InMemoryTaskManagerTest.java index 1af39da..7164838 100644 --- a/test/manager/InMemoryTaskManagerTest.java +++ b/test/manager/InMemoryTaskManagerTest.java @@ -1,212 +1,9 @@ package manager; -import static org.junit.jupiter.api.Assertions.*; -import java.util.List; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import tasks.Epic; -import tasks.Subtask; -import tasks.Task; -import tasks.TaskStatus; +public class InMemoryTaskManagerTest extends TaskManagerTest { - - -public class InMemoryTaskManagerTest { - - private TaskManager taskManager; - - @BeforeEach - void init() { - taskManager = Managers.getDefault(); - - } - - @Test - public void testCreateTask() { - taskManager.createTask(new Task("name", "desk", TaskStatus.NEW)); - List tasks = taskManager.getTasks(); - assertEquals(1, tasks.size()); - } - - //Задачи с одинаковым id должны быть равны. - @Test - void tasksWithSameIdAreEqual() { - Task task1 = new Task("Task1", "Desc1", TaskStatus.NEW); - Task task2 = new Task("Task2", "Desc2", TaskStatus.DONE); - task1.setId(1); - task2.setId(1); - - assertEquals(task1, task2, "Задачи с одинаковым id должны быть равны"); - } - - //Подзадачи с одинаковым id должны быть равны. - @Test - void subtasksWithSameIdAreEqual() { - Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); - Subtask sub1 = new Subtask("Sub1", "Desc1", TaskStatus.NEW, epic.getId()); - Subtask sub2 = new Subtask("Sub2", "Desc2", TaskStatus.DONE, epic.getId()); - sub1.setId(2); - sub2.setId(2); - - assertEquals(sub1, sub2, "Подзадачи с одинаковым id должны быть равны"); - } - - // Эпик не может быть своей подзадачей - @Test - void epicCannotBeItsOwnSubtask() { - Epic epic = new Epic("Test Epic", "Test Epic description"); - int epicId = taskManager.createEpic(epic).getId(); - - Subtask subtask = new Subtask("Test Subtask", "Test Subtask description", TaskStatus.NEW, epicId); - subtask.setId(epicId); // Пытаемся сделать подзадачу с тем же ID, что и эпик - - Subtask createdSubtask = taskManager.createSubtask(subtask); - - assertNull(createdSubtask, "Эпик не должен быть своей собственной подзадачей"); - assertTrue(taskManager.getEpicSubtasks(epicId).isEmpty(), "У эпика не должно быть подзадач"); - } - - // Подзадача не может быть своим эпиком - @Test - void subtaskCannotBeItsOwnEpic() { - Subtask subtask = new Subtask("Test Subtask", "Test Subtask description", TaskStatus.NEW, 1); - subtask.setId(1); // Пытаемся сделать подзадачу с тем же ID, что и её эпик - - // Сначала создаем эпик с ID=1 - Epic epic = new Epic("Test Epic", "Test Epic description"); - epic.setId(1); - taskManager.createEpic(epic); - - Subtask createdSubtask = taskManager.createSubtask(subtask); - - assertNull(createdSubtask, "Подзадача не должна быть своим собственным эпиком"); - assertTrue(taskManager.getEpicSubtasks(1).isEmpty(), "У эпика не должно быть подзадач"); - } - - //Менеджеры должны инициализироваться. - @Test - void managersInitialize() { - assertNotNull(Managers.getDefault(), "TaskManager должен быть инициализирован"); - assertNotNull(Managers.getDefaultHistory(), "HistoryManager должен быть инициализирован"); - } - - //Добавление и поиск задач разных типов. - @Test - void addAndFindTasks() { - Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); - Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); - Subtask sub = taskManager.createSubtask( - new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId())); - - assertNotNull(taskManager.getTask(task.getId()), "Задача должна быть найдена"); - assertNotNull(taskManager.getEpic(epic.getId()), "Эпик должен быть найден"); - assertNotNull(taskManager.getSubtasks(sub.getId()), "Подзадача должна быть найдена"); - } - - //Ручные и автоматические id не конфликтуют/ - @Test - void manualAndAutoIds() { - Task manualTask = new Task("Manual", "Desc", TaskStatus.NEW); - manualTask.setId(100); - taskManager.createTask(manualTask); - - Task autoTask = taskManager.createTask(new Task("Auto", "Desc", TaskStatus.NEW)); - - assertNotEquals(manualTask.getId(), autoTask.getId(), "ID не должны совпадать"); - } - - //Задача не изменяется при добавлении. - @Test - void taskRemainsUnchanged() { - Task original = new Task("Original", "Desc", TaskStatus.NEW); - Task added = taskManager.createTask(original); - - assertEquals(original.getName(), added.getName(), "Имя не должно изменяться"); - assertEquals(original.getDescription(), added.getDescription(), "Описание не должно изменяться"); - assertEquals(original.getTaskStatus(), added.getTaskStatus(), "Статус не должен изменяться"); - } - - // Удаление задачи удаляет её из истории. - @Test - void deleteTaskRemovesFromHistory() { - Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); - taskManager.getTask(task.getId()); - taskManager.deleteTask(task.getId()); - - List history = taskManager.getHistory(); - assertTrue(history.isEmpty(), "История должна быть пустой после удаления задачи"); - } - - // Удаление эпика удаляет его подзадачи из истории. - @Test - void deleteEpicRemovesSubtasksFromHistory() { - Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); - Subtask subtask = taskManager.createSubtask( - new Subtask("Subtask", "Desc", TaskStatus.NEW, epic.getId())); - taskManager.getSubtasks(subtask.getId()); - taskManager.getEpic(epic.getId()); - taskManager.deleteEpic(epic.getId()); - - List history = taskManager.getHistory(); - assertTrue(history.isEmpty(), "История должна быть пустой после удаления эпика"); - } - - // Удаляем только таски. - @Test - void deleteAllTasksRemovesOnlyTasks() { - Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); - Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); - Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId())); - - taskManager.deleteAllTasks(); - - assertTrue(taskManager.getTasks().isEmpty(), "Все задачи должны быть удалены"); - assertFalse(taskManager.getEpics().isEmpty(), "Эпики должны остаться"); - assertFalse(taskManager.getSubtasks().isEmpty(), "Подзадачи должны остаться"); - } - - // Удаляем только сабтаски. - @Test - void deleteAllSubtasksRemovesOnlySubtasks() { - Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); - Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); - Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId())); - - taskManager.deleteAllSubtasks(); - - assertFalse(taskManager.getTasks().isEmpty(), "Задачи должны остаться"); - assertFalse(taskManager.getEpics().isEmpty(), "Эпики должны остаться"); - assertTrue(taskManager.getSubtasks().isEmpty(), "Все подзадачи должны быть удалены"); - } - - // Удаляем эпики и их сабтаски. - @Test - void deleteAllEpicsRemovesEpicsAndSubtasks() { - Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); - Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); - Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId())); - - taskManager.deleteAllEpics(); - - assertFalse(taskManager.getTasks().isEmpty(), "Задачи должны остаться"); - assertTrue(taskManager.getEpics().isEmpty(), "Все эпики должны быть удалены"); - assertTrue(taskManager.getSubtasks().isEmpty(), "Все подзадачи должны быть удалены"); - } - - // Удаляем всё. - @Test - void deleteAllRemovesEverything() { - Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); - Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); - Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId())); - - taskManager.deleteAll(); - - assertTrue(taskManager.getTasks().isEmpty(), "Все задачи должны быть удалены"); - assertTrue(taskManager.getEpics().isEmpty(), "Все эпики должны быть удалены"); - assertTrue(taskManager.getSubtasks().isEmpty(), "Все подзадачи должны быть удалены"); + @Override + protected InMemoryTaskManager createTaskManager() { + return new InMemoryTaskManager(); } } - - - diff --git a/test/manager/TaskManagerTest.java b/test/manager/TaskManagerTest.java new file mode 100644 index 0000000..878d996 --- /dev/null +++ b/test/manager/TaskManagerTest.java @@ -0,0 +1,214 @@ +package manager; + +import static org.junit.jupiter.api.Assertions.*; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import tasks.Epic; +import tasks.Subtask; +import tasks.Task; +import tasks.TaskStatus; + + + +public abstract class TaskManagerTest { + + protected T taskManager; + + protected abstract T createTaskManager(); + + @BeforeEach + void init() { + taskManager = createTaskManager(); + + } + + @Test + public void testCreateTask() { + taskManager.createTask(new Task("name", "desk", TaskStatus.NEW)); + List tasks = taskManager.getTasks(); + assertEquals(1, tasks.size()); + } + + //Задачи с одинаковым id должны быть равны. + @Test + void tasksWithSameIdAreEqual() { + Task task1 = new Task("Task1", "Desc1", TaskStatus.NEW); + Task task2 = new Task("Task2", "Desc2", TaskStatus.DONE); + task1.setId(1); + task2.setId(1); + + assertEquals(task1, task2, "Задачи с одинаковым id должны быть равны"); + } + + //Подзадачи с одинаковым id должны быть равны. + @Test + void subtasksWithSameIdAreEqual() { + Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); + Subtask sub1 = new Subtask("Sub1", "Desc1", TaskStatus.NEW, epic.getId()); + Subtask sub2 = new Subtask("Sub2", "Desc2", TaskStatus.DONE, epic.getId()); + sub1.setId(2); + sub2.setId(2); + + assertEquals(sub1, sub2, "Подзадачи с одинаковым id должны быть равны"); + } + + // Эпик не может быть своей подзадачей + @Test + void epicCannotBeItsOwnSubtask() { + Epic epic = new Epic("Test Epic", "Test Epic description"); + int epicId = taskManager.createEpic(epic).getId(); + + Subtask subtask = new Subtask("Test Subtask", "Test Subtask description", TaskStatus.NEW, epicId); + subtask.setId(epicId); // Пытаемся сделать подзадачу с тем же ID, что и эпик + + Subtask createdSubtask = taskManager.createSubtask(subtask); + + assertNull(createdSubtask, "Эпик не должен быть своей собственной подзадачей"); + assertTrue(taskManager.getEpicSubtasks(epicId).isEmpty(), "У эпика не должно быть подзадач"); + } + + // Подзадача не может быть своим эпиком + @Test + void subtaskCannotBeItsOwnEpic() { + Subtask subtask = new Subtask("Test Subtask", "Test Subtask description", TaskStatus.NEW, 1); + subtask.setId(1); // Пытаемся сделать подзадачу с тем же ID, что и её эпик + + // Сначала создаем эпик с ID=1 + Epic epic = new Epic("Test Epic", "Test Epic description"); + epic.setId(1); + taskManager.createEpic(epic); + + Subtask createdSubtask = taskManager.createSubtask(subtask); + + assertNull(createdSubtask, "Подзадача не должна быть своим собственным эпиком"); + assertTrue(taskManager.getEpicSubtasks(1).isEmpty(), "У эпика не должно быть подзадач"); + } + + //Менеджеры должны инициализироваться. + @Test + void managersInitialize() { + assertNotNull(Managers.getDefault(), "TaskManager должен быть инициализирован"); + assertNotNull(Managers.getDefaultHistory(), "HistoryManager должен быть инициализирован"); + } + + //Добавление и поиск задач разных типов. + @Test + void addAndFindTasks() { + Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); + Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); + Subtask sub = taskManager.createSubtask( + new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId())); + + assertNotNull(taskManager.getTask(task.getId()), "Задача должна быть найдена"); + assertNotNull(taskManager.getEpic(epic.getId()), "Эпик должен быть найден"); + assertNotNull(taskManager.getSubtasks(sub.getId()), "Подзадача должна быть найдена"); + } + + //Ручные и автоматические id не конфликтуют/ + @Test + void manualAndAutoIds() { + Task manualTask = new Task("Manual", "Desc", TaskStatus.NEW); + manualTask.setId(100); + taskManager.createTask(manualTask); + + Task autoTask = taskManager.createTask(new Task("Auto", "Desc", TaskStatus.NEW)); + + assertNotEquals(manualTask.getId(), autoTask.getId(), "ID не должны совпадать"); + } + + //Задача не изменяется при добавлении. + @Test + void taskRemainsUnchanged() { + Task original = new Task("Original", "Desc", TaskStatus.NEW); + Task added = taskManager.createTask(original); + + assertEquals(original.getName(), added.getName(), "Имя не должно изменяться"); + assertEquals(original.getDescription(), added.getDescription(), "Описание не должно изменяться"); + assertEquals(original.getTaskStatus(), added.getTaskStatus(), "Статус не должен изменяться"); + } + + // Удаление задачи удаляет её из истории. + @Test + void deleteTaskRemovesFromHistory() { + Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); + taskManager.getTask(task.getId()); + taskManager.deleteTask(task.getId()); + + List history = taskManager.getHistory(); + assertTrue(history.isEmpty(), "История должна быть пустой после удаления задачи"); + } + + // Удаление эпика удаляет его подзадачи из истории. + @Test + void deleteEpicRemovesSubtasksFromHistory() { + Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); + Subtask subtask = taskManager.createSubtask( + new Subtask("Subtask", "Desc", TaskStatus.NEW, epic.getId())); + taskManager.getSubtasks(subtask.getId()); + taskManager.getEpic(epic.getId()); + taskManager.deleteEpic(epic.getId()); + + List history = taskManager.getHistory(); + assertTrue(history.isEmpty(), "История должна быть пустой после удаления эпика"); + } + + // Удаляем только таски. + @Test + void deleteAllTasksRemovesOnlyTasks() { + Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); + Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); + Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId())); + + taskManager.deleteAllTasks(); + + assertTrue(taskManager.getTasks().isEmpty(), "Все задачи должны быть удалены"); + assertFalse(taskManager.getEpics().isEmpty(), "Эпики должны остаться"); + assertFalse(taskManager.getSubtasks().isEmpty(), "Подзадачи должны остаться"); + } + + // Удаляем только сабтаски. + @Test + void deleteAllSubtasksRemovesOnlySubtasks() { + Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); + Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); + Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId())); + + taskManager.deleteAllSubtasks(); + + assertFalse(taskManager.getTasks().isEmpty(), "Задачи должны остаться"); + assertFalse(taskManager.getEpics().isEmpty(), "Эпики должны остаться"); + assertTrue(taskManager.getSubtasks().isEmpty(), "Все подзадачи должны быть удалены"); + } + + // Удаляем эпики и их сабтаски. + @Test + void deleteAllEpicsRemovesEpicsAndSubtasks() { + Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); + Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); + Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId())); + + taskManager.deleteAllEpics(); + + assertFalse(taskManager.getTasks().isEmpty(), "Задачи должны остаться"); + assertTrue(taskManager.getEpics().isEmpty(), "Все эпики должны быть удалены"); + assertTrue(taskManager.getSubtasks().isEmpty(), "Все подзадачи должны быть удалены"); + } + + // Удаляем всё. + @Test + void deleteAllRemovesEverything() { + Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW)); + Epic epic = taskManager.createEpic(new Epic("Epic", "Desc")); + Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId())); + + taskManager.deleteAll(); + + assertTrue(taskManager.getTasks().isEmpty(), "Все задачи должны быть удалены"); + assertTrue(taskManager.getEpics().isEmpty(), "Все эпики должны быть удалены"); + assertTrue(taskManager.getSubtasks().isEmpty(), "Все подзадачи должны быть удалены"); + } +} + + +