Switch to Objective-C 2.0 Fast Enumeration.
Signed-off-by: Wincent Colaiuta <win@wincent.com>
+++ /dev/null
-//
-// WOEnumerate.h
-// WOTest (imported from WODebug 28 January 2006)
-//
-// Created by Wincent Colaiuta on 12 October 2004.
-//
-// Copyright 2004-2006 Wincent Colaiuta.
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// in the accompanying file, "LICENSE.txt", for more details.
-//
-
-//! \file WOEnumerate.h
-
-// don't attempt to redefine macro (for example, may already be defined by WOCommon)
-#ifndef WO_ENUMERATE
-
-/*! WO_ENUMERATE is a convenience macro for expressing the Objective-C enumerator idiom in more compact form. Instead of the standard, longer form:
-
-<pre>NSEnumerator *enumerator = [collection objectEnumerator];
-id object = nil;
-while ((object = [enumerator nextObject]))
-NSLog(@"Object: %@", object);</pre>
-
-The following, shorter form can be used:
-
-<pre>WO_ENUMERATE(collection, object)
-NSLog(@"Object: %@", object);</pre>
-
-Or for those that prefer a Perl-like syntax:
-
-<pre>foreach (object, collection)
-NSLog(@"Object: %@", object);</pre>
-
-The WO_ENUMERATE macro is also considerably faster than the standard form because is uses a cached IMP (implementation pointer) and selector to speed up repeated invocations of the <tt>nextObject</tt> selector. In informal testing (enumerating over a 10,000,000-item array ten times) the macro performed 49% faster than the standard idiom (averaging 3.6 million objects per second compared with 2.4 million per second).
-
-If passed a nil pointer instead of a valid collection, no iterations are performed. If passed an object which does not respond to the objectEnumerator selector then an exception is raised. Both of these behaviours match the pattern of the standard idiom.
-
-Note that the compiler C dialect must be set to C99 or GNU99 in order to use this macro because of the initialization of variables inside the for expression.
-
-\see http://mjtsai.com/blog/2003/12/08/cocoa_enumeration and http://rentzsch.com/papers/improvingCocoaObjCEnumeration
-
-*/
-#define WO_ENUMERATE(collection, object) \
-for (id WOMacroEnumerator_ ## object = [collection objectEnumerator], \
- WOMacroSelector_ ## object = (id)@selector(nextObject), \
- WOMacroMethod_ ## object = (id)[WOMacroEnumerator_ ## object methodForSelector:(SEL)WOMacroSelector_ ## object], \
- object = WOMacroEnumerator_ ## object ? \
- ((IMP)WOMacroMethod_ ## object)(WOMacroEnumerator_ ## object, (SEL)WOMacroSelector_ ## object) : nil; \
- object != nil; \
- object = ((IMP)WOMacroMethod_ ## object)(WOMacroEnumerator_ ## object, (SEL)WOMacroSelector_ ## object))
-
-/*! Perl-like syntax for WO_ENUMERATE. */
-#define foreach(object, collection) WO_ENUMERATE(collection, object)
-
-#endif /* WO_ENUMERATE */
-
-#ifndef WO_REVERSE_ENUMERATE
-
-#define WO_REVERSE_ENUMERATE(collection, object) \
-for (id WOMacroEnumerator_ ## object = [collection reverseObjectEnumerator], \
- WOMacroSelector_ ## object = (id)@selector(nextObject), \
- WOMacroMethod_ ## object = (id)[WOMacroEnumerator_ ## object methodForSelector:(SEL)WOMacroSelector_ ## object], \
- object = WOMacroEnumerator_ ## object ? \
- ((IMP)WOMacroMethod_ ## object)(WOMacroEnumerator_ ## object,(SEL)WOMacroSelector_ ## object) : nil; \
- object != nil; \
- object = ((IMP)WOMacroMethod_ ## object)(WOMacroEnumerator_ ## object, (SEL)WOMacroSelector_ ## object))
-
-#endif /* WO_REVERSE_ENUMERATE */
-
-#ifndef WO_KEY_ENUMERATE
-
-#define WO_KEY_ENUMERATE(collection, key) \
-for (id WOMacroEnumerator_ ## key = [collection keyEnumerator], \
- WOMacroSelector_ ## key = (id)@selector(nextObject), \
- WOMacroMethod_ ## key = (id)[WOMacroEnumerator_ ## key methodForSelector:(SEL)WOMacroSelector_ ## key], \
- key = WOMacroEnumerator_ ## key ? \
- ((IMP)WOMacroMethod_ ## key)(WOMacroEnumerator_ ## key, (SEL)WOMacroSelector_ ## key) : nil; \
- key != nil; \
- key = ((IMP)WOMacroMethod_ ## key)(WOMacroEnumerator_ ## key, (SEL)WOMacroSelector_ ## key))
-
-/*! Perl-like syntax for WO_KEY_ENUMERATE. */
-#define foreachkey(key, collection) WO_KEY_ENUMERATE(collection, key)
-
-#endif /* WO_KEY_ENUMERATE */
#import "NSProxy+WOTest.h"
#import "NSValue+WOTest.h"
#import "WOClassMock.h"
-#import "WOEnumerate.h"
#import "WOObjectMock.h"
#import "WOProtocolMock.h"
// framework headers
#import "NSInvocation+WOTest.h"
#import "NSObject+WOTest.h"
-#import "WOEnumerate.h"
#import "WOObjectStub.h"
@implementation WOObjectMock
NSParameterAssert(anInvocation != nil);
// check if in reject list
- WO_ENUMERATE(rejected, stub)
+ for (WOStub *stub in rejected)
if ([stub matchesInvocation:anInvocation])
{
[NSException raise:NSInternalInconsistencyException format:@"Rejected selector %@ for class %@",
}
// check if expectedInOrder
- WO_ENUMERATE(expectedInOrder, stub)
+ for (WOStub *stub in expectedInOrder)
if ([stub matchesInvocation:anInvocation])
{
NSAssert2(([expectedInOrder objectAtIndex:0] == stub), @"Invocation selector %@ class %@ received out of order",
}
// check if expected once
- WO_ENUMERATE(expectedOnce, stub)
+ for (WOStub *stub in expectedOnce)
if ([stub matchesInvocation:anInvocation])
{
// move object from "expectedOnce" to "rejected"
}
// check if expected
- WO_ENUMERATE(expected, stub)
+ for (WOStub *stub in expected)
if ([stub matchesInvocation:anInvocation])
{
// move from "expected" to "accepted"
}
// check if accepted once
- WO_ENUMERATE(acceptedOnce, stub)
+ for (WOStub *stub in acceptedOnce)
if ([stub matchesInvocation:anInvocation])
{
// move from "acceptedOnce" to "rejected"
}
// check if accepted
- WO_ENUMERATE(accepted, stub)
+ for (WOStub *stub in accepted)
if ([stub matchesInvocation:anInvocation])
{
[self storeReturnValue:[stub returnValue] forInvocation:anInvocation];
#import "NSInvocation+WOTest.h"
#import "NSMethodSignature+WOTest.h"
-#import "WOEnumerate.h"
#import "WOProtocolStub.h"
#pragma mark -
NSParameterAssert(anInvocation != nil);
// check if in reject list
- WO_ENUMERATE(rejected, stub)
+ for (WOStub *stub in rejected)
if ([anInvocation WOTest_isEqualToInvocation:[stub recordedInvocation]])
{
[NSException raise:NSInternalInconsistencyException format:@"Rejected selector %@ for protocol %@",
}
// check if expectedInOrder
- WO_ENUMERATE(expectedInOrder, stub)
+ for (WOStub *stub in expectedInOrder)
if ([anInvocation WOTest_isEqualToInvocation:[stub recordedInvocation]])
{
NSAssert(([expectedInOrder objectAtIndex:0] != stub), @"invocation received out of order");
}
// check if expected once
- WO_ENUMERATE(expectedOnce, stub)
+ for (WOStub *stub in expectedOnce)
if ([anInvocation WOTest_isEqualToInvocation:[stub recordedInvocation]])
{
// move object from "expectedOnce" to "rejected"
}
// check if expected
- WO_ENUMERATE(expected, stub)
+ for (WOStub *stub in expected)
if ([anInvocation WOTest_isEqualToInvocation:[stub recordedInvocation]])
{
// move from "expected" to "accepted"
}
// check if accepted once
- WO_ENUMERATE(acceptedOnce, stub)
+ for (WOStub *stub in acceptedOnce)
if ([anInvocation WOTest_isEqualToInvocation:[stub recordedInvocation]])
{
// move from "acceptedOnce" to "rejected"
}
// check if accepted
- WO_ENUMERATE(accepted, stub)
+ for (WOStub *stub in accepted)
if ([anInvocation WOTest_isEqualToInvocation:[stub recordedInvocation]])
{
[self storeReturnValue:[stub returnValue] forInvocation:anInvocation];
#pragma mark -
#pragma mark Macros
-#import "WOEnumerate.h"
#import "WOTestMacros.h"
#pragma mark -
// system headers
#import <libkern/OSAtomic.h> /* OSAtomicIncrement32Barrier() */
-// other headers
-#import "WOEnumerate.h"
-
@implementation WOTestBundleInjector
+ (void)load
if (inject)
{
NSArray *bundles = [[NSString stringWithUTF8String:inject] componentsSeparatedByString:@":"];
- WO_ENUMERATE(bundles, bundlePath)
+ for (NSString *bundlePath in bundles)
{
NSString *path = [bundlePath stringByStandardizingPath];
if (![path isAbsolutePath])
{
int failures = 0;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- WO_ENUMERATE([self testableClasses], class)
+ for (NSString *class in [self testableClasses])
[self runTestsForClassName:class] ? : failures++;
[self printTestResultsSummary];
[pool release];
_WOLog(@"Running tests for class %@", NSStringFromClass(aClass));
if ([NSObject WOTest_instancesOfClass:aClass conformToProtocol:@protocol(WOTest)])
{
- NSArray *methods = [self testableMethodsFrom:aClass];
- WO_ENUMERATE(methods, method)
+ for (NSString *method in [self testableMethodsFrom:aClass])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSDate *startMethod = [NSDate date];
- (NSArray *)testableClassesFrom:(NSBundle *)aBundle
{
- NSArray *allClasses = [self testableClasses];
NSMutableArray *classNames = [NSMutableArray array];
if (aBundle) // only search if actually passed a non-nil bundle
{
// add only classes that match the passed bundle and conform to WOTest
- WO_ENUMERATE(allClasses, className)
+ for (NSString *className in [self testableClasses])
{
Class aClass = NSClassFromString(className);
NSBundle *classBundle = [NSBundle bundleForClass:aClass];
if ([testBundles count] > 0) // test only these bundles
{
- WO_ENUMERATE(testBundles, bundlePath)
+ for (NSString *bundlePath in testBundles)
{
bundlePath = [bundlePath WOTest_stringByConvertingToAbsolutePath];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
{
if ([testClasses count] > 0) // test only these classes
{
- WO_ENUMERATE(testClasses, class)
+ for (NSString *class in testClasses)
[WO_TEST_SHARED_INSTANCE runTestsForClassName:class];
}
else // test all classes
{
NSArray *classes = [WO_TEST_SHARED_INSTANCE testableClassesFrom:bundle];
- WO_ENUMERATE(classes, class)
+ for (NSString *class in classes)
{
if ([excludeClasses containsObject:class]) continue;
[WO_TEST_SHARED_INSTANCE runTestsForClassName:class];
{
if ([testClasses count] > 0) // test only these classes
{
- WO_ENUMERATE(testClasses, class)
+ for (NSString *class in testClasses)
[WO_TEST_SHARED_INSTANCE runTestsForClassName:class];
}
else // test all classes
{
- NSArray *classes = [WO_TEST_SHARED_INSTANCE testableClasses];
- WO_ENUMERATE(classes, class)
+ for (NSString *class in [WO_TEST_SHARED_INSTANCE testableClasses])
{
if ([excludeClasses containsObject:class]) continue;
[WO_TEST_SHARED_INSTANCE runTestsForClassName:class];