@@ -27,6 +27,7 @@ class TestNSArray : XCTestCase {
2727 ( " test_constructors " , test_constructors) ,
2828 ( " test_constructorWithCopyItems " , test_constructorWithCopyItems) ,
2929 ( " test_enumeration " , test_enumeration) ,
30+ ( " test_enumerationUsingBlock " , test_enumerationUsingBlock) ,
3031 ( " test_sequenceType " , test_sequenceType) ,
3132 ( " test_objectAtIndex " , test_objectAtIndex) ,
3233 ( " test_binarySearch " , test_binarySearch) ,
@@ -123,6 +124,115 @@ class TestNSArray : XCTestCase {
123124 XCTAssertNil ( reverseEmpty. nextObject ( ) )
124125 }
125126
127+ func test_enumerationUsingBlock( ) {
128+ let array : NSArray = NSArray ( array: Array ( 0 ..< 100 ) )
129+ let createIndexesArrayHavingSeen = { ( havingSeen: IndexSet ) in
130+ return ( 0 ..< array. count) . map { havingSeen. contains ( $0) }
131+ }
132+
133+ let noIndexes = IndexSet ( )
134+ let allIndexes = IndexSet ( integersIn: 0 ..< array. count)
135+ let firstHalfOfIndexes = IndexSet ( integersIn: 0 ..< array. count / 2 )
136+ let lastHalfOfIndexes = IndexSet ( integersIn: array. count / 2 ..< array. count)
137+ let evenIndexes : IndexSet = {
138+ var indexes = IndexSet ( )
139+ for index in allIndexes. filter ( { $0 % 2 == 0 } ) {
140+ indexes. insert ( index)
141+ }
142+ return indexes
143+ } ( )
144+
145+ let testExpectingToSee = { ( expectation: IndexSet , block: ( inout UnsafeMutableBufferPointer < Bool > ) -> Void ) in
146+ var indexesSeen = createIndexesArrayHavingSeen ( noIndexes)
147+ indexesSeen. withUnsafeMutableBufferPointer ( block)
148+ XCTAssertEqual ( indexesSeen, createIndexesArrayHavingSeen ( expectation) )
149+ }
150+
151+ // Test enumerateObjects(_:), allowing it to run to completion...
152+
153+ testExpectingToSee ( allIndexes) { ( indexesSeen) in
154+ array. enumerateObjects { ( value, index, stop) in
155+ XCTAssertEqual ( value as! NSNumber , array [ index] as! NSNumber )
156+ indexesSeen [ index] = true
157+ }
158+ }
159+
160+ // ... and stopping after the first half:
161+
162+ testExpectingToSee ( firstHalfOfIndexes) { ( indexesSeen) in
163+ array. enumerateObjects { ( value, index, stop) in
164+ XCTAssertEqual ( value as! NSNumber , array [ index] as! NSNumber )
165+
166+ if firstHalfOfIndexes. contains ( index) {
167+ indexesSeen [ index] = true
168+ } else {
169+ stop. pointee = true
170+ }
171+ }
172+ }
173+
174+ // -----
175+ // Test enumerateObjects(options:using) and enumerateObjects(at:options:using:):
176+
177+ // Test each of these options combinations:
178+ let optionsToTest : [ NSEnumerationOptions ] = [
179+ [ ] ,
180+ [ . concurrent] ,
181+ [ . reverse] ,
182+ [ . concurrent, . reverse] ,
183+ ]
184+
185+ for options in optionsToTest {
186+ // Run to completion,
187+ testExpectingToSee ( allIndexes) { ( indexesSeen) in
188+ array. enumerateObjects ( options: options, using: { ( value, index, stop) in
189+ XCTAssertEqual ( value as! NSNumber , array [ index] as! NSNumber )
190+ indexesSeen [ index] = true
191+ } )
192+ }
193+
194+ // run it only for half the indexes (use the right half depending on where we start),
195+ let indexesForHalfEnumeration = options. contains ( . reverse) ? lastHalfOfIndexes : firstHalfOfIndexes
196+
197+ testExpectingToSee ( indexesForHalfEnumeration) { ( indexesSeen) in
198+ array. enumerateObjects ( options: options, using: { ( value, index, stop) in
199+ XCTAssertEqual ( value as! NSNumber , array [ index] as! NSNumber )
200+
201+ if indexesForHalfEnumeration. contains ( index) {
202+ indexesSeen [ index] = true
203+ } else {
204+ stop. pointee = true
205+ }
206+ } )
207+ }
208+
209+ // run only for a specific index set to test the at:… variant,
210+ testExpectingToSee ( evenIndexes) { ( indexesSeen) in
211+ array. enumerateObjects ( at: evenIndexes, options: options, using: { ( value, index, stop) in
212+ XCTAssertEqual ( value as! NSNumber , array [ index] as! NSNumber )
213+ indexesSeen [ index] = true
214+ } )
215+ }
216+
217+ // and run for some indexes only to test stopping.
218+ var indexesForStaggeredEnumeration = indexesForHalfEnumeration
219+ indexesForStaggeredEnumeration. formIntersection ( evenIndexes)
220+
221+ testExpectingToSee ( indexesForStaggeredEnumeration) { ( indexesSeen) in
222+ array. enumerateObjects ( at: evenIndexes, options: options, using: { ( value, index, stop) in
223+ XCTAssertEqual ( value as! NSNumber , array [ index] as! NSNumber )
224+
225+ if ( indexesForStaggeredEnumeration. contains ( index) ) {
226+ indexesSeen [ index] = true
227+ } else {
228+ stop. pointee = true
229+ }
230+ } )
231+ }
232+ }
233+
234+ }
235+
126236 func test_sequenceType( ) {
127237 let array : NSArray = [ " foo " , " bar " , " baz " ]
128238 var res = [ String] ( )
0 commit comments