//
//  PersistenceServiceTests.swift
//  PersistenceTests
//
//  Created by Javier Cicchelli on 11/04/2023.
//  Copyright © 2023 Röck+Cöde. All rights reserved.
//

import CoreData
import XCTest

@testable import Persistence

final class PersistenceServiceTests: XCTestCase {
    
    // MARK: Properties
    
    private var persistence: PersistenceService!

    // MARK: Initialiser tests
    
    func test_initByDefault() {
        // GIVEN
        // WHEN
        persistence = .init()
        
        // THEN
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.count, 1)
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.first?.type, NSSQLiteStoreType)
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.first?.url?.lastPathComponent, "Model.sqlite")
        XCTAssertNotNil(persistence.container.viewContext)
        XCTAssertTrue(persistence.container.viewContext.automaticallyMergesChangesFromParent)
    }
    
    func test_initWithInMemory() {
        // GIVEN
        // WHEN
        persistence = .init(inMemory: true)
        
        // THEN
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.count, 1)
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.first?.type, NSSQLiteStoreType)
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.first?.url?.absoluteString, "file:///dev/null")
        XCTAssertNotNil(persistence.container.viewContext)
        XCTAssertTrue(persistence.container.viewContext.automaticallyMergesChangesFromParent)
    }
    
    // MARK: Static properties tests
    
    func test_shared() {
        // GIVEN
        persistence = .shared
        
        // WHEN
        // THEN
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.count, 1)
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.first?.type, NSSQLiteStoreType)
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.first?.url?.lastPathComponent, "Model.sqlite")
        XCTAssertNotNil(persistence.container.viewContext)
        XCTAssertTrue(persistence.container.viewContext.automaticallyMergesChangesFromParent)
    }
    
    func test_inMemory() {
        // GIVEN
        persistence = .inMemory
        
        // WHEN
        // THEN
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.count, 1)
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.first?.type, NSSQLiteStoreType)
        XCTAssertEqual(persistence.container.persistentStoreDescriptions.first?.url?.absoluteString, "file:///dev/null")
        XCTAssertNotNil(persistence.container.viewContext)
        XCTAssertTrue(persistence.container.viewContext.automaticallyMergesChangesFromParent)
    }
    
    // MARK: Functions tests
    
    func test_makeTaskContext() {
        // GIVEN
        persistence = .inMemory
        
        // WHEN
        let context = persistence.makeTaskContext()
        
        // THEN
        XCTAssertTrue(context.automaticallyMergesChangesFromParent)
        XCTAssertTrue(context.mergePolicy as AnyObject === NSMergeByPropertyObjectTrumpMergePolicy)
        XCTAssertNil(context.parent)
    }
    
    func test_makeChildContext() {
        // GIVEN
        persistence = .inMemory
        
        // WHEN
        let context = persistence.makeChildContext()
        
        // THEN
        XCTAssertTrue(context.automaticallyMergesChangesFromParent)
        XCTAssertTrue(context.mergePolicy as AnyObject === NSMergeByPropertyObjectTrumpMergePolicy)
        XCTAssertEqual(context.parent, persistence.container.viewContext)
    }

}
