// // FetcherTests.swift // PersistenceTests // // Created by Javier Cicchelli on 17/04/2023. // Copyright © 2023 Röck+Cöde. All rights reserved. // import Persistence import XCTest final class FetcherTests: XCTestCase { // MARK: Properties private let persistence = TestPersistenceService.shared private var fetcher: Fetcher! // MARK: Setup override func setUpWithError() throws { fetcher = .init( fetchRequest: .allTestEntities(), managedObjectContext: persistence.viewContext ) } override func tearDownWithError() throws { fetcher = nil } // MARK: Number of sections tests func test_numberOfSections_whenModelIsEmpty() throws { // GIVEN try fetcher.fetch() // WHEN let numberOfSections = fetcher.numberOfSections // THEN XCTAssertEqual(numberOfSections, 1) } func test_numberOfSections_whenModelIsFilled() throws { // GIVEN let context = persistence.makeChildContext() let _ = [ TestEntity(context: context), TestEntity(context: context), TestEntity(context: context) ] try persistence.save(childContext: context) try fetcher.fetch() // WHEN let numberOfSections = fetcher.numberOfSections // THEN XCTAssertEqual(numberOfSections, 1) } func test_numberOfSections_whenNoFetch() async throws { // GIVEN // WHEN let numberOfSections = fetcher.numberOfSections // THEN XCTAssertEqual(numberOfSections, 0) } // MARK: Number of objects tests func test_numberOfObjects_inFirstSection_whenModelIsEmpty() throws { // GIVEN try fetcher.fetch() // WHEN let section = fetcher.numberOfSections - 1 let numberOfObjects = try fetcher.numberOfObjects(in: section) // THEN XCTAssertEqual(numberOfObjects, 0) } func test_numberOfObjects_inFirstSection_whenModelIsFilled() throws { // GIVEN let context = persistence.makeChildContext() let entities = [ TestEntity(context: context), TestEntity(context: context), TestEntity(context: context) ] try persistence.save(childContext: context) try fetcher.fetch() // WHEN let section = fetcher.numberOfSections - 1 let numberOfObjects = try fetcher.numberOfObjects(in: section) // THEN XCTAssertEqual(numberOfObjects, entities.count) } func test_numberOfObjects_inNonExistingSection() throws { // GIVEN try fetcher.fetch() // WHEN & THEN let section = fetcher.numberOfSections XCTAssertThrowsError(try fetcher.numberOfObjects(in: section)) { error in XCTAssertEqual(error as? FetcherError, .sectionNotFound) } } func test_numberOfObjects_whenNoFetch() throws { // GIVEN // WHEN & THEN XCTAssertThrowsError(try fetcher.numberOfObjects(in: 1)) { error in XCTAssertEqual(error as? FetcherError, .fetchNotExecuted) } } // MARK: Object at tests func test_objectAt_whenModelIsEmpty() throws { // GIVEN try fetcher.fetch() // WHEN & THEN let indexPath = IndexPath( item: 0, section: fetcher.numberOfSections - 1 ) // TODO: Need to find out how to handle NSInvalidArgumentException in this test. // let object = try fetcher.object(at: indexPath) } func test_objectAt_whenModelIsFilled() throws { // GIVEN let context = persistence.makeChildContext() let entities = [TestEntity(context: context)] try persistence.save(childContext: context) try fetcher.fetch() // WHEN & THEN let indexPath = IndexPath( item: entities.count - 1, section: fetcher.numberOfSections - 1 ) let object = try fetcher.object(at: indexPath) XCTAssertNotNil(object) } func test_objectAt_withOutOfBoundsIndexPath() throws { // GIVEN let context = persistence.makeChildContext() let entities = [TestEntity(context: context)] try persistence.save(childContext: context) try fetcher.fetch() // WHEN & THEN let indexPath = IndexPath( item: entities.count, section: fetcher.numberOfSections ) // TODO: Need to find out how to handle NSInvalidArgumentException in this test. // let object = try fetcher.object(at: indexPath) } func test_objectAt_whenNoFetch() throws { // GIVEN // WHEN & THEN let indexPath = IndexPath( item: 0, section: 0 ) XCTAssertThrowsError(try fetcher.object(at: indexPath)) { error in XCTAssertEqual(error as? FetcherError, .fetchNotExecuted) } } }