Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions Example/RxCoreData.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@
objects = {

/* Begin PBXBuildFile section */
3F313EA6210C94FB00D9D0F8 /* NSManagedObjectContext+ObserveObjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F9F75E4210C948B00E834AD /* NSManagedObjectContext+ObserveObjectTests.swift */; };
3F8A3384210C5BCD00250BCB /* Contacts.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A3383210C5BCD00250BCB /* Contacts.xcdatamodel */; };
3F8A3385210C5CBE00250BCB /* Bundle+Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A337C210C5AD900250BCB /* Bundle+Test.swift */; };
3F8A3386210C5CC100250BCB /* NSManagedObject+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A337E210C5AFB00250BCB /* NSManagedObject+Extensions.swift */; };
3F8A3387210C5CC500250BCB /* NSManagedObjectContext+Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A3380210C5B1000250BCB /* NSManagedObjectContext+Test.swift */; };
3F9F75E3210C939800E834AD /* NSManagedObjectContext+ObserveContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F9F75E1210C935900E834AD /* NSManagedObjectContext+ObserveContextTests.swift */; };
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; };
607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; };
607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; };
75696D6E47EF4301137E83D3 /* Pods_RxCoreData_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D9B39454206D1A0C6433F6A /* Pods_RxCoreData_Tests.framework */; };
CF5023D00F002ADEF58941A0 /* Pods_RxCoreData_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C2097B9C8F7CECFD35D972D /* Pods_RxCoreData_Example.framework */; };
D2AE78A51CF32FBA00D8411E /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2AE78A31CF32FBA00D8411E /* Event.swift */; };
Expand All @@ -33,6 +38,12 @@
/* Begin PBXFileReference section */
1312AE6406B7B9929CF4EE12 /* Pods-RxCoreData_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxCoreData_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxCoreData_Example/Pods-RxCoreData_Example.release.xcconfig"; sourceTree = "<group>"; };
3D9B39454206D1A0C6433F6A /* Pods_RxCoreData_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RxCoreData_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3F8A337C210C5AD900250BCB /* Bundle+Test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+Test.swift"; sourceTree = "<group>"; };
3F8A337E210C5AFB00250BCB /* NSManagedObject+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Extensions.swift"; sourceTree = "<group>"; };
3F8A3380210C5B1000250BCB /* NSManagedObjectContext+Test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Test.swift"; sourceTree = "<group>"; };
3F8A3383210C5BCD00250BCB /* Contacts.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Contacts.xcdatamodel; sourceTree = "<group>"; };
3F9F75E1210C935900E834AD /* NSManagedObjectContext+ObserveContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+ObserveContextTests.swift"; sourceTree = "<group>"; };
3F9F75E4210C948B00E834AD /* NSManagedObjectContext+ObserveObjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+ObserveObjectTests.swift"; sourceTree = "<group>"; };
607FACD01AFB9204008FA782 /* RxCoreData_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RxCoreData_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
Expand All @@ -41,7 +52,6 @@
607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
607FACE51AFB9204008FA782 /* RxCoreData_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RxCoreData_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = "<group>"; };
609891BD0E152693BAEB65CA /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
694D2F970D4D6C2D5B237BCA /* LICENSE.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = LICENSE.md; path = ../LICENSE.md; sourceTree = "<group>"; };
6C2097B9C8F7CECFD35D972D /* Pods_RxCoreData_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RxCoreData_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -75,6 +85,24 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
3F8A337B210C5AC000250BCB /* Utils */ = {
isa = PBXGroup;
children = (
3F8A337C210C5AD900250BCB /* Bundle+Test.swift */,
3F8A337E210C5AFB00250BCB /* NSManagedObject+Extensions.swift */,
3F8A3380210C5B1000250BCB /* NSManagedObjectContext+Test.swift */,
);
name = Utils;
sourceTree = "<group>";
};
3F8A3382210C5BB100250BCB /* Resources */ = {
isa = PBXGroup;
children = (
3F8A3383210C5BCD00250BCB /* Contacts.xcdatamodel */,
);
name = Resources;
sourceTree = "<group>";
};
607FACC71AFB9204008FA782 = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -124,8 +152,11 @@
607FACE81AFB9204008FA782 /* Tests */ = {
isa = PBXGroup;
children = (
607FACEB1AFB9204008FA782 /* Tests.swift */,
3F8A3382210C5BB100250BCB /* Resources */,
3F8A337B210C5AC000250BCB /* Utils */,
607FACE91AFB9204008FA782 /* Supporting Files */,
3F9F75E1210C935900E834AD /* NSManagedObjectContext+ObserveContextTests.swift */,
3F9F75E4210C948B00E834AD /* NSManagedObjectContext+ObserveObjectTests.swift */,
);
path = Tests;
sourceTree = "<group>";
Expand Down Expand Up @@ -500,7 +531,12 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
607FACEC1AFB9204008FA782 /* Tests.swift in Sources */,
3F8A3384210C5BCD00250BCB /* Contacts.xcdatamodel in Sources */,
3F9F75E3210C939800E834AD /* NSManagedObjectContext+ObserveContextTests.swift in Sources */,
3F8A3386210C5CC100250BCB /* NSManagedObject+Extensions.swift in Sources */,
3F313EA6210C94FB00D9D0F8 /* NSManagedObjectContext+ObserveObjectTests.swift in Sources */,
3F8A3385210C5CBE00250BCB /* Bundle+Test.swift in Sources */,
3F8A3387210C5CC500250BCB /* NSManagedObjectContext+Test.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
17 changes: 17 additions & 0 deletions Example/Tests/Bundle+Test.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Bundle+Test.swift
// RxCoreData_Example
//
// Created by Evghenii Nicolaev on 7/28/18.
// Copyright © 2018 CocoaPods. All rights reserved.
//

import Foundation

private class Test {}

extension Bundle {
static var test: Bundle {
return Bundle(for: Test.self)
}
}
20 changes: 20 additions & 0 deletions Example/Tests/Contacts.xcdatamodel/contents
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14133" systemVersion="17E199" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Contact" representedClassName="Contact" syncable="YES" codeGenerationType="class">
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="phoneNumbers" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="PhoneNumber" syncable="YES"/>
</entity>
<entity name="Group" representedClassName="Group" syncable="YES" codeGenerationType="class">
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="contacts" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="Contact" syncable="YES"/>
</entity>
<entity name="PhoneNumber" representedClassName="PhoneNumber" syncable="YES" codeGenerationType="class">
<attribute name="phoneNumber" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
</entity>
<elements>
<element name="Contact" positionX="-54" positionY="-9" width="128" height="75"/>
<element name="Group" positionX="-63" positionY="-18" width="128" height="75"/>
<element name="PhoneNumber" positionX="-54" positionY="9" width="128" height="75"/>
</elements>
</model>
22 changes: 22 additions & 0 deletions Example/Tests/NSManagedObject+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// NSManagedObject+Extensions.swift
// RxCoreData_Example
//
// Created by Evghenii Nicolaev on 7/28/18.
// Copyright © 2018 CocoaPods. All rights reserved.
//

import Foundation
import CoreData

extension NSManagedObject {

class func new(in managedObjectContext: NSManagedObjectContext) -> Self {
return generateObject(type: self, in: managedObjectContext)
}

private class func generateObject<T>(type: T.Type, in managedObjectContext: NSManagedObjectContext) -> T {
return NSEntityDescription.insertNewObject(forEntityName: String(describing: self), into: managedObjectContext) as! T
}

}
129 changes: 129 additions & 0 deletions Example/Tests/NSManagedObjectContext+ObserveContextTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
//
// NSManagedObjectContext+ObserveContextTests.swift
// RxCoreData_Example
//
// Created by Evghenii Nicolaev on 7/28/18.
// Copyright © 2018 CocoaPods. All rights reserved.
//

import Foundation
import XCTest
import RxSwift
import RxCoreData
import CoreData

class NSManagedObjectContext_ObserveContextTests: XCTestCase {

var testMOC: NSManagedObjectContext!
var disposeBag: DisposeBag!

// MARK: - Setup

override func setUp() {
super.setUp()
disposeBag = DisposeBag()
testMOC = NSManagedObjectContext.test
}

override func tearDown() {
testMOC = nil
disposeBag = nil
super.tearDown()
}

// MARK: - Tests

func testObserveContext_insertion() {
let insertionExpectation = expectation(description: "Expect to get insert event")

testMOC.rx.changes().take(1).subscribe(onNext: { changeEvent in
XCTAssertEqual(changeEvent.deleted.count, 0)
XCTAssertEqual(changeEvent.updated.count, 0)
XCTAssertEqual(changeEvent.refreshed.count, 0)

XCTAssertEqual(changeEvent.inserted.count, 1)
let insertedGroup = changeEvent.inserted.first as? Group
XCTAssertEqual(insertedGroup?.name, "Test group")

insertionExpectation.fulfill()
}).disposed(by: disposeBag)

let group = Group.new(in: testMOC)
group.name = "Test group"

waitForExpectations(timeout: 1.0, handler: nil)
}

func testObserveContext_update() {
let insertionExpectation = expectation(description: "Expect to get update event")

let group = Group.new(in: testMOC)
group.name = "Test group"
try! testMOC.save()

testMOC.rx.changes().take(1).subscribe(onNext: { changeEvent in
XCTAssertEqual(changeEvent.inserted.count, 0)
XCTAssertEqual(changeEvent.deleted.count, 0)
XCTAssertEqual(changeEvent.refreshed.count, 0)

XCTAssertEqual(changeEvent.updated.count, 1)
let updatedGroup = changeEvent.updated.first as? Group
XCTAssertEqual(updatedGroup?.name, "Updated test group")

insertionExpectation.fulfill()
}).disposed(by: disposeBag)

group.name = "Updated test group"

waitForExpectations(timeout: 1.0, handler: nil)
}

func testObserveContext_delete() {
let insertionExpectation = expectation(description: "Expect to get delete event")

let group = Group.new(in: testMOC)
group.name = "Test group"
try! testMOC.save()

testMOC.rx.changes().take(1).subscribe(onNext: { changeEvent in
XCTAssertEqual(changeEvent.inserted.count, 0)
XCTAssertEqual(changeEvent.updated.count, 0)
XCTAssertEqual(changeEvent.refreshed.count, 0)

XCTAssertEqual(changeEvent.deleted.count, 1)
let deletedGroup = changeEvent.deleted.first as? Group
XCTAssertEqual(deletedGroup?.name, "Test group")

insertionExpectation.fulfill()
}).disposed(by: disposeBag)

testMOC.delete(group)

waitForExpectations(timeout: 1.0, handler: nil)
}

func testObserveContext_refresh() {
let insertionExpectation = expectation(description: "Expect to get refresh event")

let group = Group.new(in: testMOC)
group.name = "Test group"
try! testMOC.save()

testMOC.rx.changes().take(1).subscribe(onNext: { changeEvent in
XCTAssertEqual(changeEvent.inserted.count, 0)
XCTAssertEqual(changeEvent.updated.count, 0)
XCTAssertEqual(changeEvent.deleted.count, 0)

XCTAssertEqual(changeEvent.refreshed.count, 1)
let refreshedGroup = changeEvent.refreshed.first as? Group
XCTAssertEqual(refreshedGroup?.name, "Test group")

insertionExpectation.fulfill()
}).disposed(by: disposeBag)

testMOC.refreshAllObjects()

waitForExpectations(timeout: 1.0, handler: nil)
}

}
Loading