|
| 1 | +import CoreData |
| 2 | +@testable import CycleOne |
| 3 | +import SwiftUI |
| 4 | +import XCTest |
| 5 | + |
| 6 | +final class CoverageIncreaseTests: XCTestCase { |
| 7 | + func testHostRunsOnBackgroundThread() { |
| 8 | + let exp = expectation(description: "host background") |
| 9 | + DispatchQueue.global().async { |
| 10 | + let view = EmptyStateView(icon: "xmark.circle", title: "No Data", message: "Please add data") |
| 11 | + host(view) |
| 12 | + exp.fulfill() |
| 13 | + } |
| 14 | + waitForExpectations(timeout: 5) |
| 15 | + } |
| 16 | + |
| 17 | + func testRebuildAllCycles_withDifferentFlowValueTypes_andFullSyncBackground() throws { |
| 18 | + let context = TestPersistenceController.empty().container.viewContext |
| 19 | + let calendar = Calendar(identifier: .gregorian) |
| 20 | + let date1 = try XCTUnwrap(calendar.date(from: DateComponents(year: 2024, month: 1, day: 1))?.startOfDay) |
| 21 | + let date2 = try XCTUnwrap(calendar.date(from: DateComponents(year: 2024, month: 2, day: 1))?.startOfDay) |
| 22 | + let date3 = try XCTUnwrap(calendar.date(from: DateComponents(year: 2024, month: 3, day: 3))?.startOfDay) |
| 23 | + |
| 24 | + let log1 = NSEntityDescription.insertNewObject(forEntityName: "DayLog", into: context) |
| 25 | + log1.setValue(UUID(), forKey: "id") |
| 26 | + log1.setValue(date1, forKey: "date") |
| 27 | + log1.setValue(NSNumber(value: 1), forKey: "flowLevel") |
| 28 | + |
| 29 | + let log2 = NSEntityDescription.insertNewObject(forEntityName: "DayLog", into: context) |
| 30 | + log2.setValue(UUID(), forKey: "id") |
| 31 | + log2.setValue(date2, forKey: "date") |
| 32 | + log2.setValue(Int(2), forKey: "flowLevel") |
| 33 | + |
| 34 | + let log3 = NSEntityDescription.insertNewObject(forEntityName: "DayLog", into: context) |
| 35 | + log3.setValue(UUID(), forKey: "id") |
| 36 | + log3.setValue(date3, forKey: "date") |
| 37 | + log3.setValue(Int16(3), forKey: "flowLevel") |
| 38 | + |
| 39 | + try context.save() |
| 40 | + |
| 41 | + // Should create three cycles since dates are separated |
| 42 | + CycleManager.shared.rebuildAllCycles(in: context) |
| 43 | + |
| 44 | + let req: NSFetchRequest<Cycle> = Cycle.fetchRequest() |
| 45 | + let cycles = try context.fetch(req) |
| 46 | + XCTAssertEqual(cycles.count, 3) |
| 47 | + |
| 48 | + // Exercise fullSync's background path |
| 49 | + let exp = expectation(description: "fullSync background") |
| 50 | + DispatchQueue.global().async { |
| 51 | + CycleManager.shared.fullSync(in: context) |
| 52 | + exp.fulfill() |
| 53 | + } |
| 54 | + waitForExpectations(timeout: 5) |
| 55 | + } |
| 56 | + |
| 57 | + func testExportService_replacesCommasAndNewlinesInNotesAndJoinsSymptoms() throws { |
| 58 | + let context = TestPersistenceController.empty().container.viewContext |
| 59 | + |
| 60 | + let log = DayLog(context: context) |
| 61 | + log.id = UUID() |
| 62 | + log.date = Date().startOfDay |
| 63 | + log.flowLevel = FlowLevel.light.rawValue |
| 64 | + log.notes = "Line1\nLine2, with comma" |
| 65 | + let symptom = Symptom(context: context) |
| 66 | + symptom.id = UUID().uuidString |
| 67 | + symptom.name = "Cramps" |
| 68 | + symptom.category = "Other" |
| 69 | + log.addToSymptoms(symptom) |
| 70 | + |
| 71 | + try context.save() |
| 72 | + |
| 73 | + let path = ExportService.shared.generateCSV(context: context) |
| 74 | + XCTAssertNotNil(path) |
| 75 | + if let path { |
| 76 | + let csv = try String(contentsOf: path) |
| 77 | + XCTAssertTrue(csv.contains("Cramps")) |
| 78 | + XCTAssertTrue(csv.contains("Line1 Line2")) |
| 79 | + } |
| 80 | + } |
| 81 | +} |
0 commit comments