feat: add unit tests for models and ListStore and UI test for adding a todo
This commit is contained in:
139
MindDumpTests/MindDumpTests.swift
Normal file
139
MindDumpTests/MindDumpTests.swift
Normal file
@@ -0,0 +1,139 @@
|
||||
import XCTest
|
||||
import SwiftData
|
||||
@testable import MindDump
|
||||
|
||||
final class TodoItemTests: XCTestCase {
|
||||
|
||||
// MARK: - isOverdue
|
||||
|
||||
/// Past deadline should be overdue
|
||||
func testIsOverdue_deadlineYesterday_returnsTrue() {
|
||||
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
|
||||
let item = TodoItem(title: "Test", deadline: yesterday)
|
||||
XCTAssertTrue(item.isOverdue)
|
||||
}
|
||||
|
||||
/// Completed items are never overdue, even with past deadline
|
||||
func testIsOverdue_completedWithPastDeadline_returnsFalse() {
|
||||
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
|
||||
let item = TodoItem(title: "Test", isCompleted: true, deadline: yesterday)
|
||||
XCTAssertFalse(item.isOverdue)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
final class TodoListTests: XCTestCase {
|
||||
|
||||
// MARK: - openItems / completedItems
|
||||
|
||||
/// Items are correctly split into open and completed
|
||||
func testOpenAndCompletedItems_correctSplit() {
|
||||
let open1 = TodoItem(title: "Open 1")
|
||||
let open2 = TodoItem(title: "Open 2")
|
||||
let done = TodoItem(title: "Done", isCompleted: true)
|
||||
|
||||
let list = TodoList(name: "Test", items: [open1, done, open2])
|
||||
|
||||
XCTAssertEqual(list.openItems.count, 2)
|
||||
XCTAssertEqual(list.completedItems.count, 1)
|
||||
XCTAssertEqual(list.completedItems.first?.title, "Done")
|
||||
}
|
||||
|
||||
/// Open items are sorted oldest first
|
||||
func testOpenItems_sortedByCreatedAtAscending() {
|
||||
let older = TodoItem(title: "Older", createdAt: Date().addingTimeInterval(-100))
|
||||
let newer = TodoItem(title: "Newer", createdAt: Date())
|
||||
|
||||
let list = TodoList(name: "Test", items: [newer, older])
|
||||
|
||||
XCTAssertEqual(list.openItems.map(\.title), ["Older", "Newer"])
|
||||
}
|
||||
|
||||
/// Completed items are sorted newest first (by modifiedAt)
|
||||
func testCompletedItems_sortedByModifiedAtDescending() {
|
||||
let earlier = TodoItem(title: "Earlier", isCompleted: true, modifiedAt: Date().addingTimeInterval(-100))
|
||||
let later = TodoItem(title: "Later", isCompleted: true, modifiedAt: Date())
|
||||
|
||||
let list = TodoList(name: "Test", items: [earlier, later])
|
||||
|
||||
XCTAssertEqual(list.completedItems.map(\.title), ["Later", "Earlier"])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - ListStore Tests
|
||||
|
||||
@MainActor
|
||||
final class ListStoreTests: XCTestCase {
|
||||
|
||||
private var container: ModelContainer!
|
||||
private var store: ListStore!
|
||||
|
||||
override func setUp() {
|
||||
let config = ModelConfiguration(isStoredInMemoryOnly: true)
|
||||
container = try! ModelContainer(for: TodoList.self, TodoItem.self, configurations: config)
|
||||
store = ListStore(modelContext: container.mainContext)
|
||||
}
|
||||
|
||||
// MARK: - addItem / deleteItem
|
||||
|
||||
/// Adding an item increases the list count and stores the title
|
||||
func testAddItem_increasesCount() {
|
||||
let inboxID = store.inboxID
|
||||
store.addItem(to: inboxID, title: "Buy milk")
|
||||
|
||||
XCTAssertEqual(store.lists.first!.items.count, 1)
|
||||
XCTAssertEqual(store.lists.first!.items.first?.title, "Buy milk")
|
||||
}
|
||||
|
||||
/// Deleting an item removes it from the list
|
||||
func testDeleteItem_removesItem() {
|
||||
let inboxID = store.inboxID
|
||||
store.addItem(to: inboxID, title: "Temp")
|
||||
let itemID = store.lists.first!.items.first!.id
|
||||
|
||||
store.deleteItem(itemID, from: inboxID)
|
||||
|
||||
XCTAssertTrue(store.lists.first!.items.isEmpty)
|
||||
}
|
||||
|
||||
// MARK: - toggleItemCompleted
|
||||
|
||||
/// Toggling flips isCompleted back and forth
|
||||
func testToggleItemCompleted_flipsStatus() {
|
||||
let inboxID = store.inboxID
|
||||
store.addItem(to: inboxID, title: "Task")
|
||||
let itemID = store.lists.first!.items.first!.id
|
||||
|
||||
XCTAssertFalse(store.lists.first!.items.first!.isCompleted)
|
||||
|
||||
store.toggleItemCompleted(itemID, in: inboxID)
|
||||
XCTAssertTrue(store.lists.first!.items.first!.isCompleted)
|
||||
|
||||
store.toggleItemCompleted(itemID, in: inboxID)
|
||||
XCTAssertFalse(store.lists.first!.items.first!.isCompleted)
|
||||
}
|
||||
|
||||
// MARK: - moveItem
|
||||
|
||||
/// Moving an item removes it from the source list, adds it to the target list, and updates modifiedAt
|
||||
func testMoveItem_movesAcrossLists() {
|
||||
let inboxID = store.inboxID
|
||||
store.addList(name: "Arbeit")
|
||||
let arbeitID = store.lists.first { $0.name == "Arbeit" }!.id
|
||||
|
||||
store.addItem(to: inboxID, title: "Wichtige Aufgabe")
|
||||
let itemID = store.lists.first { $0.isInbox }!.items.first!.id
|
||||
|
||||
store.moveItem(itemID, from: inboxID, to: arbeitID)
|
||||
|
||||
let inbox = store.lists.first { $0.isInbox }!
|
||||
let arbeit = store.lists.first { $0.name == "Arbeit" }!
|
||||
|
||||
XCTAssertTrue(inbox.items.isEmpty, "Item should be removed from source lists")
|
||||
XCTAssertEqual(arbeit.items.count, 1, "Item should be in target list")
|
||||
XCTAssertEqual(arbeit.items.first?.title, "Wichtige Aufgabe")
|
||||
XCTAssertNotNil(arbeit.items.first?.modifiedAt, "modifiedAt should be set after move")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user