@@ -34,19 +34,173 @@ class ResultsControllerTests: XCTestCase {
3434 }
3535
3636
37- /// Verifies thatt he ResultsController starts with zero sections, whenever there are no actual entities stored.
3837 ///
39- func testResultsControllerStartsWithNoSectionsWhenNoAccountsAreAvailable( ) {
38+ ///
39+ func testResultsControllerStartsEmptySectionAfterPerformingFetch( ) {
4040 let resultsController = ResultsController < Storage . Account > ( viewContext: viewContext, sortedBy: [ sampleSortDescriptor] )
4141 XCTAssertEqual ( resultsController. sections. count, 0 )
4242
4343 try ? resultsController. performFetch ( )
44- XCTAssertEqual ( resultsController. sections. count, 0 )
44+ XCTAssertEqual ( resultsController. sections. count, 1 )
45+ XCTAssertEqual ( resultsController. sections. first? . objects. count, 0 )
46+ }
47+
48+
49+ ///
50+ ///
51+ func testResultsControllerPicksUpEntitiesAvailablePriorToInstantiation( ) {
52+ insertSampleAccount ( into: viewContext)
53+ viewContext. saveIfNeeded ( )
54+
55+ let resultsController = ResultsController < Storage . Account > ( viewContext: viewContext, sortedBy: [ sampleSortDescriptor] )
56+ try ? resultsController. performFetch ( )
57+
58+ XCTAssertEqual ( resultsController. sections. count, 1 )
59+ XCTAssertEqual ( resultsController. sections. first? . objects. count, 1 )
60+ }
61+
62+
63+ ///
64+ ///
65+ func testResultsControllerPicksUpEntitiesInsertedAfterInstantiation( ) {
66+ let resultsController = ResultsController < Storage . Account > ( viewContext: viewContext, sortedBy: [ sampleSortDescriptor] )
67+ try ? resultsController. performFetch ( )
68+
69+ insertSampleAccount ( into: viewContext)
70+ viewContext. saveIfNeeded ( )
71+
72+ XCTAssertEqual ( resultsController. sections. count, 1 )
73+ XCTAssertEqual ( resultsController. sections. first? . objects. count, 1 )
74+ }
75+
76+
77+ ///
78+ ///
79+ func testResultsControllerGroupSectionsBySectionNameKeypath( ) {
80+ let sectionNameKeyPath = " userID "
81+ let resultsController = ResultsController < Storage . Account > ( viewContext: viewContext, sectionNameKeyPath: sectionNameKeyPath, sortedBy: [ sampleSortDescriptor] )
82+ try ? resultsController. performFetch ( )
83+
84+ let numberOfAccounts = 100
85+ for _ in 0 ..< numberOfAccounts {
86+ insertSampleAccount ( into: viewContext)
87+ }
88+
89+ viewContext. saveIfNeeded ( )
90+
91+ XCTAssertEqual ( resultsController. sections. count, numberOfAccounts)
92+
93+ for section in resultsController. sections {
94+ XCTAssertEqual ( section. numberOfObjects, 1 )
95+ }
96+ }
97+
98+
99+ ///
100+ ///
101+ func testObjectAtIndexPathReturnsExpectedEntity( ) {
102+ let sectionNameKeyPath = " userID "
103+ let resultsController = ResultsController < Storage . Account > ( viewContext: viewContext, sectionNameKeyPath: sectionNameKeyPath, sortedBy: [ sampleSortDescriptor] )
104+ try ? resultsController. performFetch ( )
105+
106+ let mutableAccount = insertSampleAccount ( into: viewContext)
107+ viewContext. saveIfNeeded ( )
108+
109+ let indexPath = IndexPath ( row: 0 , section: 0 )
110+ let readOnlyAccount = resultsController. object ( at: indexPath)
111+
112+ XCTAssertEqual ( Int ( mutableAccount. userID) , readOnlyAccount. userID)
113+ XCTAssertEqual ( mutableAccount. displayName, readOnlyAccount. displayName)
45114 }
46115
47116
48- // let newAccount = insertSampleAccount(into: viewContext)
49- // viewContext.saveIfNeeded()
117+ ///
118+ ///
119+ func testOnWillChangeContentIsEffectivelyCalledBeforeChanges( ) {
120+ let resultsController = ResultsController < Storage . Account > ( viewContext: viewContext, sortedBy: [ sampleSortDescriptor] )
121+ try ? resultsController. performFetch ( )
122+
123+ let expectation = self . expectation ( description: " OnWillChange " )
124+ var didChangeObjectWasCalled = false
125+
126+ resultsController. onWillChangeContent = {
127+ XCTAssertFalse ( didChangeObjectWasCalled)
128+ expectation. fulfill ( )
129+ }
130+ resultsController. onDidChangeObject = { ( _, _, _, _) in
131+ didChangeObjectWasCalled = true
132+ }
133+
134+ insertSampleAccount ( into: viewContext)
135+ viewContext. saveIfNeeded ( )
136+
137+ waitForExpectations ( timeout: Constants . expectationTimeout, handler: nil )
138+ }
139+
140+ ///
141+ ///
142+ func testOnDidChangeContentIsEffectivelyCalledAfterChangesArePerformed( ) {
143+ let resultsController = ResultsController < Storage . Account > ( viewContext: viewContext, sortedBy: [ sampleSortDescriptor] )
144+ try ? resultsController. performFetch ( )
145+
146+ let expectation = self . expectation ( description: " OnDidChange " )
147+ var didChangeObjectWasCalled = false
148+
149+ resultsController. onDidChangeObject = { ( _, _, _, _) in
150+ didChangeObjectWasCalled = true
151+ }
152+ resultsController. onDidChangeContent = {
153+ XCTAssertTrue ( didChangeObjectWasCalled)
154+ expectation. fulfill ( )
155+ }
156+
157+ insertSampleAccount ( into: viewContext)
158+ viewContext. saveIfNeeded ( )
159+
160+ waitForExpectations ( timeout: Constants . expectationTimeout, handler: nil )
161+ }
162+
163+
164+ ///
165+ ///
166+ func testOnDidChangeObjectIsEffectivelyCalledOnceChangesArePerformed( ) {
167+ let resultsController = ResultsController < Storage . Account > ( viewContext: viewContext, sortedBy: [ sampleSortDescriptor] )
168+ try ? resultsController. performFetch ( )
169+
170+ let expectation = self . expectation ( description: " OnDidChange " )
171+ resultsController. onDidChangeObject = { ( object, indexPath, type, newIndexPath) in
172+ let expectedIndexPath = IndexPath ( row: 0 , section: 0 )
173+
174+ XCTAssertEqual ( type, . insert)
175+ XCTAssertEqual ( newIndexPath, expectedIndexPath)
176+ expectation. fulfill ( )
177+ }
178+
179+ insertSampleAccount ( into: viewContext)
180+ viewContext. saveIfNeeded ( )
181+
182+ waitForExpectations ( timeout: Constants . expectationTimeout, handler: nil )
183+ }
184+
185+
186+ ///
187+ ///
188+ func testOnDidChangeSectionIsCalledWheneverNewSectionsAreAdded( ) {
189+ let sectionNameKeyPath = " userID "
190+ let resultsController = ResultsController < Storage . Account > ( viewContext: viewContext, sectionNameKeyPath: sectionNameKeyPath, sortedBy: [ sampleSortDescriptor] )
191+ try ? resultsController. performFetch ( )
192+
193+ let expectation = self . expectation ( description: " OnDidChange " )
194+ resultsController. onDidChangeSection = { ( sectionInfo, index, type) in
195+ XCTAssertEqual ( type, . insert)
196+ expectation. fulfill ( )
197+ }
198+
199+ insertSampleAccount ( into: viewContext)
200+ viewContext. saveIfNeeded ( )
201+
202+ waitForExpectations ( timeout: Constants . expectationTimeout, handler: nil )
203+ }
50204}
51205
52206
@@ -56,6 +210,7 @@ private extension ResultsControllerTests {
56210
57211 /// Inserts a new (Sample) account into the specified context.
58212 ///
213+ @discardableResult
59214 func insertSampleAccount( into context: NSManagedObjectContext ) -> Storage . Account {
60215 let newAccount = context. insertNewObject ( ofType: Storage . Account. self)
61216 newAccount. userID = Int64 ( arc4random ( ) )
0 commit comments