<commit_before>//
//  DataManagerTests.swift
//  DataManagerTests
//
//  Created by <NAME> on 3/31/16.
//  Copyright © 2016 Metova. All rights reserved.
//

import XCTest
import CoreData
@testable import DataManager

class DataManagerTests: XCTestCase {
    
    // MARK: - Set Up / Tear Down
    
    override func setUp() {
    
        super.setUp()
        
        DataManager.setUpWithDataModelName("TestModel", dataModelBundle: NSBundle(forClass: DataManagerTests.self), persistentStoreName: "Test", persistentStoreType: .InMemory)
    }
    
    
    
    override func tearDown() {
        
        DataManager.deleteAllObjects()
        
        super.tearDown()
    }
    
    
    
    // MARK: Helper
    
    func createTestPerson(name name: String = "Test Person", birthDate: NSDate = NSDate(timeIntervalSince1970: 0)) -> Person {
        
        return Person(context: DataManager.mainContext, name: name, birthDate: birthDate)
    }
    
    
    
    // MARK: - Tests
    // MARK: Child Context Creation
    
    func testCreatingChildContext() {
        
        let childContext = DataManager.createChildContextWithParentContext(DataManager.mainContext)
        
        XCTAssertEqual(childContext.concurrencyType, NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
        XCTAssertTrue(childContext.parentContext === DataManager.mainContext)
    }
    
    
    
    // MARK: Fetch Single Object
    
    func testFetchingSingleObjectWithSortDescriptor() {
        
        let person1 = createTestPerson(birthDate: NSDate(timeIntervalSince1970: 0))
        let person2 = createTestPerson(birthDate: NSDate(timeIntervalSince1970: 1))
        
        let ascendingSortDescriptor = NSSortDescriptor(key: "birthDate", ascending: true)
        let descendingSortDescriptor = NSSortDescriptor(key: "birthDate", ascending: false)
        
        let olderPerson = DataManager.fetchObject(entity: Person.self, sortDescriptors: [ascendingSortDescriptor], context: DataManager.mainContext)
        
        XCTAssertNotNil(olderPerson, "Failed to fetch a single Person.")
        XCTAssertTrue(person1 === olderPerson, "Fetched incorrect Person.")
        
        let youngerPerson = DataManager.fetchObject(entity: Person.self, sortDescriptors: [descendingSortDescriptor], context: DataManager.mainContext)
        
        XCTAssertNotNil(youngerPerson, "Failed to fetch a single Person.")
        XCTAssertTrue(person2 === youngerPerson, "Fetched incorrect Person.")
    }
    
    
    
    func testFetchingSingleObjectWithPredicate() {
        
        let person = createTestPerson(name: "<NAME>")
        _ = createTestPerson()
        
        let predicate = NSPredicate(format: "name == %@", "<NAME>")
        
        let fetchedPerson = DataManager.fetchObject(entity: Person.self, predicate: predicate, context: DataManager.mainContext)
        
        XCTAssertNotNil(fetchedPerson, "Failed to fetch a single Person.")
        XCTAssertTrue(person === fetchedPerson, "Fetched incorrect Person.")
    }
    
    
    
    // MARK: Fetch Multiple Objects
    
    func testFetchingMultipleObjects() {
        
        let person1 = createTestPerson()
        let person2 = createTestPerson()
        
        let fetchedPeople = DataManager.fetchObjects(entity: Person.self, context: DataManager.mainContext)
        
        XCTAssertEqual(fetchedPeople.count, 2)
        XCTAssertTrue(fetchedPeople.contains(person1))
        XCTAssertTrue(fetchedPeople.contains(person2))
    }
    
    
    
    func testFetchingMultipleObjectsWithPredicate() {
        
        let person1 = createTestPerson()
        let person2 = createTestPerson()
        _ = createTestPerson(name: "Some Other Name")
        
        let predicate = NSPredicate(format: "name == %@", "Test Person")
        
        let fetchedPeople = DataManager.fetchObjects(entity: Person.self, predicate: predicate, context: DataManager.mainContext)
        
        XCTAssertEqual(fetchedPeople.count, 2)
        XCTAssertTrue(fetchedPeople.contains(person1))
        XCTAssertTrue(fetchedPeople.contains(person2))
    }
    
    
    
    func testFetchingMultipleObjectsWithSortDescriptor() {
        
        let person1 = createTestPerson(birthDate: NSDate(timeIntervalSince1970: 0))
        let person2 = createTestPerson(birthDate: NSDate(timeIntervalSince1970: 1))
        
        let ascendingSortDescriptor = NSSortDescriptor(key: "birthDate", ascending: true)
        let descendingSortDescriptor = NSSortDescriptor(key: "birthDate", ascending: false)
        
        let fetchedPeopleAscending = DataManager.fetchObjects(entity: Person.self, sortDescriptors: [ascendingSortDescriptor], context: DataManager.mainContext)
        
        XCTAssertEqual(fetchedPeopleAscending.count, 2)
        XCTAssertTrue(fetchedPeopleAscending[0] === person1)
        XCTAssertTrue(fetchedPeopleAscending[1] === person2)
        
        let fetchedPeopleDescending = DataManager.fetchObjects(entity: Person.self, sortDescriptors: [descendingSortDescriptor], context: DataManager.mainContext)
        
        XCTAssertEqual(fetchedPeopleDescending.count, 2)
        XCTAssertTrue(fetchedPeopleDescending[0] === person2)
        XCTAssertTrue(fetchedPeopleDescending[1] === person1)
    }
    
    
    
    // MARK: Deleting
    
    func testDeletingObjects() {
        
        let person1 = createTestPerson()
        let person2 = createTestPerson()
        
        DataManager.deleteObjects([person1, person2], context: DataManager.mainContext)
        
        XCTAssertTrue(person1.deleted)
        XCTAssertTrue(person2.deleted)
    }
    
    
    
    // MARK: Persistence
    
    func testAsynchronousPersistence() {
        
        let person1 = createTestPerson()
        
        XCTAssertTrue(person1.managedObjectContext?.hasChanges == true)
        
        DataManager.persist(synchronously: false)
        
        XCTAssertTrue(person1.managedObjectContext?.hasChanges == false)
        XCTAssertTrue(person1.managedObjectContext?.parentContext?.hasChanges == true)
        
        let expectation = expectationWithDescription("Expect private context to save asynchronously.")
        
        let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
        dispatch_after(delayTime, dispatch_get_main_queue()) {
            
            if person1.managedObjectContext?.parentContext?.hasChanges == false {
                expectation.fulfill()
            }
        }
        
        waitForExpectationsWithTimeout(2) { error in
            <commit_msg>Updated asynchronous persist test to use the persist method's completion block to fulfill the expectation.<commit_after>//
//  DataManagerTests.swift
//  DataManagerTests
//
//  Created by <NAME> on 3/31/16.
//  Copyright © 2016 Metova. All rights reserved.
//

import XCTest
import CoreData
@testable import DataManager

class DataManagerTests: XCTestCase {
    
    // MARK: - Set Up / Tear Down
    
    override func setUp() {
    
        super.setUp()
        
        DataManager.setUpWithDataModelName("TestModel", dataModelBundle: NSBundle(forClass: DataManagerTests.self), persistentStoreName: "Test", persistentStoreType: .InMemory)
    }
    
    
    
    override func tearDown() {
        
        DataManager.deleteAllObjects()
        
        super.tearDown()
    }
    
    
    
    // MARK: Helper
    
    func createTestPerson(name name: String = "Test Person", birthDate: NSDate = NSDate(timeIntervalSince1970: 0)) -> Person {
        
        return Person(context: DataManager.mainContext, name: name, birthDate: birthDate)
    }
    
    
    
    // MARK: - Tests
    // MARK: Child Context Creation
    
    func testCreatingChildContext() {
        
        let childContext = DataManager.createChildContextWithParentContext(DataManager.mainContext)
        
        XCTAssertEqual(childContext.concurrencyType, NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
        XCTAssertTrue(childContext.parentContext === DataManager.mainContext)
    }
    
    
    
    // MARK: Fetch Single Object
    
    func testFetchingSingleObjectWithSortDescriptor() {
        
        let person1 = createTestPerson(birthDate: NSDate(timeIntervalSince1970: 0))
        let person2 = createTestPerson(birthDate: NSDate(timeIntervalSince1970: 1))
        
        let ascendingSortDescriptor = NSSortDescriptor(key: "birthDate", ascending: true)
        let descendingSortDescriptor = NSSortDescriptor(key: "birthDate", ascending: false)
        
        let olderPerson = DataManager.fetchObject(entity: Person.self, sortDescriptors: [ascendingSortDescriptor], context: DataManager.mainContext)
        
        XCTAssertNotNil(olderPerson, "Failed to fetch a single Person.")
        XCTAssertTrue(person1 === olderPerson, "Fetched incorrect Person.")
        
        let youngerPerson = DataManager.fetchObject(entity: Person.self, sortDescriptors: [descendingSortDescriptor], context: DataManager.mainContext)
        
        XCTAssertNotNil(youngerPerson, "Failed to fetch a single Person.")
        XCTAssertTrue(person2 === youngerPerson, "Fetched incorrect Person.")
    }
    
    
    
    func testFetchingSingleObjectWithPredicate() {
        
        let person = createTestPerson(name: "<NAME>")
        _ = createTestPerson()
        
        let predicate = NSPredicate(format: "name == %@", "<NAME>")
        
        let fetchedPerson = DataManager.fetchObject(entity: Person.self, predicate: predicate, context: DataManager.mainContext)
        
        XCTAssertNotNil(fetchedPerson, "Failed to fetch a single Person.")
        XCTAssertTrue(person === fetchedPerson, "Fetched incorrect Person.")
    }
    
    
    
    // MARK: Fetch Multiple Objects
    
    func testFetchingMultipleObjects() {
        
        let person1 = createTestPerson()
        let person2 = createTestPerson()
        
        let fetchedPeople = DataManager.fetchObjects(entity: Person.self, context: DataManager.mainContext)
        
        XCTAssertEqual(fetchedPeople.count, 2)
        XCTAssertTrue(fetchedPeople.contains(person1))
        XCTAssertTrue(fetchedPeople.contains(person2))
    }
    
    
    
    func testFetchingMultipleObjectsWithPredicate() {
        
        let person1 = createTestPerson()
        let person2 = createTestPerson()
        _ = createTestPerson(name: "Some Other Name")
        
        let predicate = NSPredicate(format: "name == %@", "Test Person")
        
        let fetchedPeople = DataManager.fetchObjects(entity: Person.self, predicate: predicate, context: DataManager.mainContext)
        
        XCTAssertEqual(fetchedPeople.count, 2)
        XCTAssertTrue(fetchedPeople.contains(person1))
        XCTAssertTrue(fetchedPeople.contains(person2))
    }
    
    
    
    func testFetchingMultipleObjectsWithSortDescriptor() {
        
        let person1 = createTestPerson(birthDate: NSDate(timeIntervalSince1970: 0))
        let person2 = createTestPerson(birthDate: NSDate(timeIntervalSince1970: 1))
        
        let ascendingSortDescriptor = NSSortDescriptor(key: "birthDate", ascending: true)
        let descendingSortDescriptor = NSSortDescriptor(key: "birthDate", ascending: false)
        
        let fetchedPeopleAscending = DataManager.fetchObjects(entity: Person.self, sortDescriptors: [ascendingSortDescriptor], context: DataManager.mainContext)
        
        XCTAssertEqual(fetchedPeopleAscending.count, 2)
        XCTAssertTrue(fetchedPeopleAscending[0] === person1)
        XCTAssertTrue(fetchedPeopleAscending[1] === person2)
        
        let fetchedPeopleDescending = DataManager.fetchObjects(entity: Person.self, sortDescriptors: [descendingSortDescriptor], context: DataManager.mainContext)
        
        XCTAssertEqual(fetchedPeopleDescending.count, 2)
        XCTAssertTrue(fetchedPeopleDescending[0] === person2)
        XCTAssertTrue(fetchedPeopleDescending[1] === person1)
    }
    
    
    
    // MARK: Deleting
    
    func testDeletingObjects() {
        
        let person1 = createTestPerson()
        let person2 = createTestPerson()
        
        DataManager.deleteObjects([person1, person2], context: DataManager.mainContext)
        
        XCTAssertTrue(person1.deleted)
        XCTAssertTrue(person2.deleted)
    }
    
    
    
    // MARK: Persistence
    
    func testAsynchronousPersistence() {
        
        let person1 = createTestPerson()
        
        XCTAssertTrue(person1.managedObjectContext?.hasChanges == true)
        
        let expectation = expectationWithDescription("Expect private context to save asynchronously.")
        
        DataManager.persist(synchronously: false) { error in
            
            if let privateContext = person1.managedObjectContext?.parentContext where !privateContext.hasChanges && error == nil {
                    expectation.fulfill()
            }
        }
        
        XCTAssertTrue(person1.managedObjectContext?.hasChanges == false)
        XCTAssertTrue(person1.managedObjectContext?.parentContext?.hasChanges == true)
        
        waitForExpectationsWithTimeout(5) { error in
            
{'fraction_non_alphanumeric': 0.08393140439676663, 'fraction_numerical': 0.01110523532522475, 'mean_word_length': 2.6967327562133483, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6690782', 'n_tokens_mistral': 3696, 'n_tokens_neox': 3556, 'n_words': 692}