diff options
Diffstat (limited to 'Foundation')
102 files changed, 3575 insertions, 13094 deletions
diff --git a/Foundation/GTMAbstractDOListener.h b/Foundation/GTMAbstractDOListener.h deleted file mode 100644 index 104ec05..0000000 --- a/Foundation/GTMAbstractDOListener.h +++ /dev/null @@ -1,231 +0,0 @@ -// -// GTMAbstractDOListener.h -// -// Copyright 2006-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// -#import <Foundation/Foundation.h> -#import "GTMDefines.h" - -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -@class GTMReceivePortDelegate; -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - -// Abstract base class for DO "listeners". -// A class that needs to vend itself over DO should subclass this abstract -// class. This class takes care of certain things like creating a new thread -// to handle requests, setting request/reply timeouts, and ensuring the vended -// object only gets requests that comply with the specified protocol. -// -// Subclassers will want to use the -// GTM_ABSTRACTDOLISTENER_SUBCLASS_THREADMAIN_IMPL macro for easier debugging -// of stack traces. Please read it's description below. -// -@interface GTMAbstractDOListener : NSObject <NSConnectionDelegate> { - @protected - NSString *registeredName_; - GTM_WEAK Protocol *protocol_; - NSConnection *connection_; - BOOL isRunningInNewThread_; - BOOL shouldShutdown_; - NSTimeInterval requestTimeout_; - NSTimeInterval replyTimeout_; - NSPort *port_; - NSTimeInterval heartRate_; - -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - GTMReceivePortDelegate *receivePortDelegate_; // Strong (only used on Tiger) -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -} - -// Returns a set of all live instances of GTMAbstractDOListener subclasses. -// If no listeners have been created, this will return an empty array--not nil. -// -// TODO: Remove this method -// -+ (NSArray *)allListeners; - -// Initializer. This actually calls -// initWithRegisteredName:protocol:port with [NSMachPort port] as the port. -// -// Args: -// name - the name that the object will register under -// proto - the protocol that this object (self) should conform to -// -- (id)initWithRegisteredName:(NSString *)name protocol:(Protocol *)proto; - -// The designated initializer. -// -// Args: -// name - the name used to register the port. While not necessarily required -// for an NSSocketPort this class still requires it. -// proto - the protocol that this object (self) should conform to -// port - the port to be used when creating the NSConnection. If a NSMachPort -// is being used then initWithRegisteredName:protocol is recommended. -// Otherwise the port must be allocted by the caller. -// -- (id)initWithRegisteredName:(NSString *)name - protocol:(Protocol *)proto - port:(NSPort *)port; - -// Returns the name that this server will register with the -// mach port name sever. This is the name of the port that this class -// will "listen" on when -runInNewThread is called. -// -// Returns: -// The registered name as a string -// -- (NSString *)registeredName; - -// Sets the registered name to use when listening over DO. This only makes -// sense to be called before -runInNewThread has been called, because -// -runInNewThread will listen on this "registered name", so setting it -// afterwards would do nothing. -// -// Args: -// name - the name to register under. May not be nil. -// -- (void)setRegisteredName:(NSString *)name; - -// Get/set the request timeout interval. If set to a value less than 0, -// the default DO connection timeout will be used (maximum possible value). -// -- (NSTimeInterval)requestTimeout; -- (void)setRequestTimeout:(NSTimeInterval)timeout; - -// Get/set the reply timeout interval. If set to a value less than 0, -// the default DO connection timeout will be used (maximum possible value). -// -- (NSTimeInterval)replyTimeout; -- (void)setReplyTimeout:(NSTimeInterval)timeout; - -// Get/set how long the thread will spin the run loop. This only takes affect -// if runInNewThreadWithErrorTarget:selector:withObjectArgument: is used. The -// default heart rate is 10.0 seconds. -// -- (void)setThreadHeartRate:(NSTimeInterval)heartRate; -- (NSTimeInterval)ThreadHeartRate; - -// Returns the listeners associated NSConnection. May be nil if no connection -// has been setup yet. -// -- (NSConnection *)connection; - -// Starts the DO system listening using the current thread and current runloop. -// It only makes sense to call this method -OR- -runInNewThread, but not both. -// Returns YES if it was able to startup the DO listener, NO otherwise. -// -- (BOOL)runInCurrentThread; - -// Starts the DO system listening, and creates a new thread to handle the DO -// connections. It only makes sense to call this method -OR- -// -runInCurrentThread, but not both. -// if |errObject| is non nil, it will be used along with |selector| and -// |argument| to signal that the startup of the listener in the new thread -// failed. The actual selector will be invoked back on the main thread so -// it does not have to be thread safe. -// The most basic way to call this method is as follows: -// [listener runInNewThreadWithErrorTarget:nil -// selector:NULL -// withObjectArgument:nil]; -// -// Note: Using the example above you will not know if the listener failed to -// startup due to some error. -// -- (void)runInNewThreadWithErrorTarget:(id)errObject - selector:(SEL)selector - withObjectArgument:(id)argument; - -// Shuts down the connection. If it was running in a new thread, that thread -// should exit (within about 10 seconds). This call does not block. -// -// NOTE: This method is called in -dealloc, so if -runInNewThread had previously -// been called, -dealloc will return *before* the thread actually exits. This -// can be a problem as "self" may be gone before the thread exits. This is a -// bug and needs to be fixed. Currently, to be safe, only call -shutdown if -// -runInCurrentThread had previously been called. -// -- (void)shutdown; - -@end - - -// Methods that subclasses may implement to vary the behavior of this abstract -// class. -// -@interface GTMAbstractDOListener (GTMAbstractDOListenerSubclassMethods) - -// Called by the -runIn* methods. In the case where a new thread is being used, -// this method is called on the new thread. The default implementation of this -// method just returns YES, but subclasses can override it to do subclass -// specific initialization. If this method returns NO, the -runIn* method that -// called it will fail with an error. -// -// Returns: -// YES if the -runIn* method should continue successfully, NO if the it should -// fail. -// -- (BOOL)doRunInitialization; - -// Called as the "main" for the thread spun off by GTMAbstractDOListener. -// Not really for use by subclassers, except to use the -// GTMABSTRACTDOLISTENER_SUBCLASS_THREADMAIN_IMPL macro defined below. -// -// This method runs forever in a new thread. This method actually starts the -// DO connection listening. -// -- (void)threadMain:(NSInvocation *)failureCallback; - -@end - -// GTMAbstractDOListeners used to be hard to debug because crashes in their -// stacks looked like this: -// -// #0 0x90009cd7 in mach_msg_trap () -// #1 0x90009c38 in mach_msg () -// #2 0x9082d2b3 in CFRunLoopRunSpecific () -// #3 0x9082cace in CFRunLoopRunInMode () -// #4 0x9282ad3a in -[NSRunLoop runMode:beforeDate:] () -// #5 0x928788e4 in -[NSRunLoop runUntilDate:] () -// #6 0x00052696 in -[GTMAbstractDOListener(GTMAbstractDOListenerSubclassMethods) threadMain:] ... -// #7 0x927f52e0 in forkThreadForFunction () -// #8 0x90024227 in _pthread_body () -// -// and there was no good way to figure out what thread had the problem because -// they all originated from -// -[GTMAbstractDOListener(GTMAbstractDOListenerSubclassMethods) threadMain:] -// -// If you add GTMABSTRACTDOLISTENER_SUBCLASS_THREADMAIN_IMPL to the impl of your -// subclass you will get a stack that looks like this: -// #0 0x90009cd7 in mach_msg_trap () -// #1 0x90009c38 in mach_msg () -// #2 0x9082d2b3 in CFRunLoopRunSpecific () -// #3 0x9082cace in CFRunLoopRunInMode () -// #4 0x9282ad3a in -[NSRunLoop runMode:beforeDate:] () -// #5 0x928788e4 in -[NSRunLoop runUntilDate:] () -// #6 0x00052696 in -[GTMAbstractDOListener(GTMAbstractDOListenerSubclassMethods) threadMain:] ... -// #7 0x0004b35c in -[GDStatsListener threadMain:] -// #8 0x927f52e0 in forkThreadForFunction () #9 0x90024227 in _pthread_body () -// -// so we can see that this was the GDStatsListener thread that failed. -// It will look something like this -// @implemetation MySubclassOfGTMAbstractDOListenerSubclassMethods -// GTM_ABSTRACTDOLISTENER_SUBCLASS_THREADMAIN_IMPL -// .... -// @end - -#define GTM_ABSTRACTDOLISTENER_SUBCLASS_THREADMAIN_IMPL \ - - (void)threadMain:(NSInvocation *)failureCallback { \ - [super threadMain:failureCallback]; \ - } diff --git a/Foundation/GTMAbstractDOListener.m b/Foundation/GTMAbstractDOListener.m deleted file mode 100644 index 4ac69bd..0000000 --- a/Foundation/GTMAbstractDOListener.m +++ /dev/null @@ -1,454 +0,0 @@ -// -// GTMAbstractDOListener.m -// -// Copyright 2006-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMAbstractDOListener.h" -#import "GTMSystemVersion.h" -#import <mach/mach_init.h> - -// Hack workaround suggested by DTS for the DO deadlock bug. Basically, this -// class intercepts the delegate role for DO's receive port (which is an -// NSMachPort). When -handlePortMessage: is called, it verifies that the send -// and receive ports are not nil, then forwards the message on to the original -// delegate. If the ports are nil, then the resulting NSConnection would -// eventually cause us to deadlock. In this case, it simply ignores the -// message. This is only need on Tiger. -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -@interface GTMReceivePortDelegate : NSObject { - GTM_WEAK id delegate_; -} -- (id)initWithDelegate:(id)delegate; -- (void)handlePortMessage:(NSPortMessage *)message; -@end -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - -@interface GTMAbstractDOListener (PrivateMethods) -- (BOOL)startListening; -- (void)stopListening; - -// Returns a description of the port based on the type of port. -- (NSString *)portDescription; - -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -// Uses the GTMReceivePortDelegate hack (see comments above) if we're on Tiger. -- (void)hackaroundTigerDOWedgeBug:(NSConnection *)conn; -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -@end - -// Static global set that holds a pointer to all instances of -// GTMAbstractDOListener subclasses. -// -static NSMutableSet *gAllListeners = nil; - -@implementation GTMAbstractDOListener - -+ (void)initialize { - if (self == [GTMAbstractDOListener class]) { - // We create the set using CFSetCreateMutable because we don't - // want to retain things in this set. If we retained things in the - // set we would never be able to dealloc ourselves because we - // add "self" to this set in it's init routine would cause an - // extra retain to be added to it. - gAllListeners = (NSMutableSet*)CFSetCreateMutable(NULL, 0, NULL); - } -} - -+ (NSArray *)allListeners { - // We return an NSArray instead of an NSSet here because NSArrays look nicer - // when displayed as %@ - NSArray *allListeners = nil; - - @synchronized (gAllListeners) { - allListeners = [gAllListeners allObjects]; - } - return allListeners; -} - -- (id)init { - return [self initWithRegisteredName:nil protocol:NULL]; -} - -- (id)initWithRegisteredName:(NSString *)name protocol:(Protocol *)proto { - return [self initWithRegisteredName:name - protocol:proto - port:[NSMachPort port]]; -} - -- (id)initWithRegisteredName:(NSString *)name - protocol:(Protocol *)proto - port:(NSPort *)port { - self = [super init]; - if (!self) { - return nil; - } - - if ((!proto) || (!port) || (!name)) { - if (!proto) { - _GTMDevLog(@"Failed to create a listener, a protocol must be specified"); - } - - if (!port) { - _GTMDevLog(@"Failed to create a listener, a port must be specified"); - } - - if (!name) { - _GTMDevLog(@"Failed to create a listener, a name must be specified"); - } - - [self release]; - return nil; - } - - registeredName_ = [name copy]; - protocol_ = proto; // Can't retain protocols - port_ = [port retain]; - - requestTimeout_ = -1; - replyTimeout_ = -1; - - heartRate_ = (NSTimeInterval)10.0; - - _GTMDevAssert(gAllListeners, @"gAllListeners is not nil"); - @synchronized (gAllListeners) { - [gAllListeners addObject:self]; - } - - return self; -} - -- (void)dealloc { - _GTMDevAssert(gAllListeners, @"gAllListeners is not nil"); - @synchronized (gAllListeners) { - [gAllListeners removeObject:self]; - } - -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - [receivePortDelegate_ release]; -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - - [self shutdown]; - [port_ release]; - [registeredName_ release]; - [super dealloc]; -} - - -#pragma mark Getters and Setters - -- (NSString *)registeredName { - return registeredName_; -} - -- (void)setRegisteredName:(NSString *)name { - if (!name) { - return; - } - [registeredName_ autorelease]; - registeredName_ = [name copy]; -} - -- (NSTimeInterval)requestTimeout { - return requestTimeout_; -} - -- (void)setRequestTimeout:(NSTimeInterval)timeout { - requestTimeout_ = timeout; -} - -- (NSTimeInterval)replyTimeout { - return replyTimeout_; -} - -- (void)setReplyTimeout:(NSTimeInterval)timeout { - replyTimeout_ = timeout; -} - -- (void)setThreadHeartRate:(NSTimeInterval)heartRate { - heartRate_ = heartRate; -} - -- (NSTimeInterval)ThreadHeartRate { - return heartRate_; -} - -- (NSConnection *)connection { - return connection_; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"%@<%p> { name=\"%@\", %@ }", - [self class], self, registeredName_, [self portDescription]]; -} - -#pragma mark "Run" methods - -- (BOOL)runInCurrentThread { - return [self startListening]; -} - -- (void)runInNewThreadWithErrorTarget:(id)errObject - selector:(SEL)selector - withObjectArgument:(id)argument { - NSInvocation *invocation = nil; - - _GTMDevAssert(((errObject != nil && selector != NULL) || - (!errObject && !selector)), @"errObject and selector must " - @"both be nil or not nil"); - - // create an invocation we can use if things fail - if (errObject) { - NSMethodSignature *signature = - [errObject methodSignatureForSelector:selector]; - invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:selector]; - [invocation setTarget:errObject]; - - // If the selector they passed in takes an arg (i.e., it has at least one - // colon in the selector name), then set the first user-specified arg to be - // the |argument| they specified. The first two args are self and _cmd. - if ([signature numberOfArguments] > 2) { - [invocation setArgument:&argument atIndex:2]; - } - - [invocation retainArguments]; - } - - shouldShutdown_ = NO; - [NSThread detachNewThreadSelector:@selector(threadMain:) - toTarget:self - withObject:invocation]; -} - -- (void)shutdown { - // If we're not running in a new thread (then we're running in the "current" - // thread), tear down the NSConnection here. If we are running in a new - // thread we just set the shouldShutdown_ flag, and the thread will teardown - // the NSConnection itself. - if (!isRunningInNewThread_) { - [self stopListening]; - } else { - shouldShutdown_ = YES; - } -} - -@end - -@implementation GTMAbstractDOListener (PrivateMethods) - -- (BOOL)startListening { - BOOL result = NO; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - _GTMDevAssert(!connection_, @"Connection_ should not be set. Was this " - @"listener already started? %@", self); - connection_ = [[NSConnection alloc] initWithReceivePort:port_ sendPort:nil]; - - NSProtocolChecker *checker = - [NSProtocolChecker protocolCheckerWithTarget:self - protocol:protocol_]; - - if (requestTimeout_ >= 0) { - [connection_ setRequestTimeout:requestTimeout_]; - } - - if (replyTimeout_ >= 0) { - [connection_ setReplyTimeout:replyTimeout_]; - } - - // Set the connection's root object to be the protocol checker so that only - // methods listed in the protocol_ are available via DO. - [connection_ setRootObject:checker]; - - // Allow subclasses to be the connection delegate - [connection_ setDelegate:self]; - - // Because of radar 5493309 we need to do this. [NSConnection registeredName:] - // returns NO when the connection is created using an NSSocketPort under - // Leopard. - // - // The recommendation from Apple was to use the command: - // [NSConnection registerName:withNameServer:]. - NSPortNameServer *server; - if ([port_ isKindOfClass:[NSSocketPort class]]) { - server = [NSSocketPortNameServer sharedInstance]; - } else { - server = [NSPortNameServer systemDefaultPortNameServer]; - } - - BOOL registered = [connection_ registerName:registeredName_ - withNameServer:server]; - - if (registeredName_ && registered) { -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - [self hackaroundTigerDOWedgeBug:connection_]; -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - - result = YES; - - _GTMDevLog(@"listening on %@ with name '%@'", [self portDescription], - registeredName_); - } else { - _GTMDevLog(@"failed to register %@ with %@", connection_, registeredName_); - } - - // we're good, so call the overrideable initializer - if (result) { - // Call the virtual "runIn*" initializer - result = [self doRunInitialization]; - } else { - [connection_ invalidate]; - [connection_ release]; - connection_ = nil; - } - - [pool drain]; - - return result; -} - -- (void)stopListening { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [connection_ invalidate]; - [connection_ release]; - connection_ = nil; - [pool drain]; -} - -- (NSString *)portDescription { - NSString *portDescription; - if ([port_ isKindOfClass:[NSMachPort class]]) { - portDescription = [NSString stringWithFormat:@"mach_port=%#x", - [(NSMachPort *)port_ machPort]]; - } else { - portDescription = [NSString stringWithFormat:@"port=%@", - [port_ description]]; - } - return portDescription; -} - -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -- (void)hackaroundTigerDOWedgeBug:(NSConnection *)conn { - if ([GTMSystemVersion isTiger]) { - NSPort *receivePort = [conn receivePort]; - if ([receivePort isKindOfClass:[NSMachPort class]]) { - id portDelegate = [receivePort delegate]; - receivePortDelegate_ = - [[GTMReceivePortDelegate alloc] initWithDelegate:portDelegate]; - [receivePort setDelegate:receivePortDelegate_]; - } - } -} -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - -@end - -@implementation GTMAbstractDOListener (GTMAbstractDOListenerSubclassMethods) - -- (BOOL)doRunInitialization { - return YES; -} - -// -// -threadMain: -// - -// -- (void)threadMain:(NSInvocation *)failureCallback { - isRunningInNewThread_ = YES; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - // register - if ([self startListening]) { - // spin - for (;;) { // Run forever - - // check if we were asked to shutdown - if (shouldShutdown_) { - break; - } - - NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init]; - // Wrap our runloop in case we get an exception from DO - @try { - NSDate *waitDate = [NSDate dateWithTimeIntervalSinceNow:heartRate_]; - [[NSRunLoop currentRunLoop] runUntilDate:waitDate]; - } @catch (id e) { - _GTMDevLog(@"Listener '%@' caught exception: %@", registeredName_, e); - } - [localPool drain]; - } - } else { - // failed, if we had something to invoke, call it on the main thread - if (failureCallback) { - [failureCallback performSelectorOnMainThread:@selector(invoke) - withObject:nil - waitUntilDone:NO]; - } - } - - [self stopListening]; - [pool drain]; - - isRunningInNewThread_ = NO; -} - -@end - -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -@implementation GTMReceivePortDelegate - -- (id)initWithDelegate:(id)delegate { - if ((self = [super init])) { - delegate_ = delegate; // delegates aren't retained - } - return self; -} - -- (void)handlePortMessage:(NSPortMessage *)message { - NSPort *receivePort = [message receivePort]; - NSPort *sendPort = [message sendPort]; - - // If we don't have a sensible send or receive port, just act like - // the message never arrived. Otherwise, hand it off to the original - // delegate (which is the NSMachPort itself). - if (receivePort == nil || sendPort == nil || [receivePort isEqual:sendPort]) { - _GTMDevLog(@"Dropping port message destined for itself to avoid DO wedge."); - } else { - // Uncomment for super-duper verbose DO message forward logging - // _GTMDevLog(@"--> Forwarding message %@ to delegate %@", - // message, delegate_); - [delegate_ handlePortMessage:message]; - } - - // If processing the message caused us to drop no longer being the delegate, - // set us back. Due to interactions between NSConnection and NSMachPort, - // it's possible for the NSMachPort's delegate to get set back to its - // original value. If that happens, we set it back to the value we want. - if ([delegate_ delegate] != self) { - if ([delegate_ delegate] == delegate_) { - _GTMDevLog(@"Restoring DO delegate to %@", self); - [delegate_ setDelegate:self]; - } else { - _GTMDevLog(@"GMReceivePortDelegate replaced with %@", - [delegate_ delegate]); - } - } -} -@end -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 diff --git a/Foundation/GTMAbstractDOListenerTest.m b/Foundation/GTMAbstractDOListenerTest.m deleted file mode 100644 index 6a5a90a..0000000 --- a/Foundation/GTMAbstractDOListenerTest.m +++ /dev/null @@ -1,365 +0,0 @@ -// -// GTMAbstractDOListenerTest.m -// -// Copyright 2006-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" -#import "GTMAbstractDOListener.h" - -// Needed for GTMUnitTestDevLog expectPattern -#import "GTMUnitTestDevLog.h" - -// Used for request/reply timeouts -#define kDefaultTimeout 0.5 - -// Used when waiting for something to shutdown -#define kDelayTimeout 30.0 - -enum { - kGTMAbstractDOConditionWaiting = 123, - kGTMAbstractDOConditionReceivedMessage -}; - -#pragma mark - -#pragma mark Test Protocols - -@protocol TestServerDOProtocol -- (oneway void)testCommand; -- (in bycopy NSNumber *)delayResponseForTime:(in byref NSNumber *)delay; -@end - -@protocol TestServerEvilDOProtocol -// This command is not implemented, but is declared to remove all compiler -// warnings. -// -- (oneway void)evilCommand; -@end - -@protocol TestServerDelegateProtocol -- (void)clientSentMessage; -@end - -#pragma mark - -#pragma mark Test Server - -@interface TestServer : GTMAbstractDOListener<TestServerDOProtocol> { - @private - GTM_WEAK id delegate_; -} -- (void)setDelegate:(id)delegate; -@end - -@implementation TestServer - -- (void)setDelegate:(id)delegate { - delegate_ = delegate; -} - -- (in bycopy NSNumber *)delayResponseForTime:(in byref NSNumber *)delay { - NSDate *future = [NSDate dateWithTimeIntervalSinceNow:[delay doubleValue]]; - [NSThread sleepUntilDate:future]; - return [NSNumber numberWithDouble:kDefaultTimeout]; -} - -- (oneway void)testCommand { - [delegate_ performSelector:@selector(clientSentMessage)]; -} - -@end - -#pragma mark - -#pragma mark Test Client - -@interface TestClient : NSObject { - @private - id proxy_; - NSString *serverName_; -} -- (id)initWithName:(NSString *)name; -- (id)connect; -- (void)disconnect; -@end - -@implementation TestClient -- (id)initWithName:(NSString *)name { - self = [super init]; - if (self) { - serverName_ = [[NSString alloc] initWithString:name]; - if (!serverName_) { - [self release]; - self = nil; - } - } - return self; -} - -- (void)finalize { - [self disconnect]; - [super finalize]; -} - -- (void)dealloc { - [self disconnect]; - [serverName_ release]; - [super dealloc]; -} - -- (id)connect { - NSConnection *connection = - [NSConnection connectionWithRegisteredName:serverName_ host:nil]; - - [connection setReplyTimeout:kDefaultTimeout]; - [connection setRequestTimeout:kDefaultTimeout]; - - @try { - proxy_ = [[connection rootProxy] retain]; - } @catch (NSException *e) { - [self disconnect]; - } - return proxy_; -} - -- (void)disconnect { - NSConnection *connection = - [NSConnection connectionWithRegisteredName:serverName_ host:nil]; - [connection invalidate]; - [proxy_ release]; - proxy_ = nil; -} - -@end - -#pragma mark - -#pragma mark Tests - -@interface GTMAbstractDOListenerTest : GTMTestCase<TestServerDelegateProtocol> { - @private - NSConditionLock *lock_; -} -@end - -@implementation GTMAbstractDOListenerTest - -- (void)clientSentMessage { - NSDate *future = [NSDate dateWithTimeIntervalSinceNow:kDefaultTimeout]; - STAssertTrue([lock_ lockWhenCondition:kGTMAbstractDOConditionWaiting - beforeDate:future], @"Unable to acquire lock " - @"for client send message. This is BAD!"); - [lock_ unlockWithCondition:kGTMAbstractDOConditionReceivedMessage]; -} - -- (void)listenerErrorEncountered:(id)error { - // Do nothing -} - -- (void)testAbstractDOListenerProtocol { - lock_ = - [[NSConditionLock alloc] initWithCondition:kGTMAbstractDOConditionWaiting]; - [lock_ autorelease]; - - NSString *serverName = @"ProtoTest"; - - // Build and start the server - TestServer *listener = - [[TestServer alloc] initWithRegisteredName:serverName - protocol:@protocol(TestServerDOProtocol)]; - [listener autorelease]; - [listener setDelegate:self]; - [GTMUnitTestDevLog expectPattern:@"listening on.*"]; - [listener runInCurrentThread]; - - // Connect with our simple client - TestClient *client = - [[[TestClient alloc] initWithName:serverName] autorelease]; - id proxy = [client connect]; - STAssertNotNil(proxy, @"should have a proxy object"); - - [proxy testCommand]; - - NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:kDelayTimeout]; - while (![lock_ tryLockWhenCondition:kGTMAbstractDOConditionReceivedMessage] && - ([timeout compare:[NSDate date]] == NSOrderedDescending)) { - NSDate* runUntil = [NSDate dateWithTimeIntervalSinceNow:0.1]; - [[NSRunLoop currentRunLoop] runUntilDate:runUntil]; - } - - STAssertFalse([lock_ tryLockWhenCondition:kGTMAbstractDOConditionWaiting], - @"A message was never received from the client."); - - STAssertThrows([proxy evilCommand], - @"An exception should have been thrown for a method not in" - @"the specified protocol."); - - [client disconnect]; - [listener shutdown]; - - STAssertNil([listener connection], @"The connection should be nil after " - @"shutdown."); - - // We are done with the lock. - [lock_ unlockWithCondition:kGTMAbstractDOConditionWaiting]; -} - -- (void)testAbstractDOListenerBadInitializers { - [GTMUnitTestDevLog expectString: - @"Failed to create a listener, a protocol must be specified"]; - [GTMUnitTestDevLog expectString: - @"Failed to create a listener, a name must be specified"]; - TestServer *listener = [[TestServer alloc] init]; - STAssertNil(listener, @"We should not have created a server using init"); - - [GTMUnitTestDevLog expectString: - @"Failed to create a listener, a name must be specified"]; - listener = - [[TestServer alloc] initWithRegisteredName:nil - protocol:@protocol(TestServerDOProtocol) - port:[NSMachPort port]]; - STAssertNil(listener, @"We should not have created a server with a nil name"); - - [GTMUnitTestDevLog expectString: - @"Failed to create a listener, a protocol must be specified"]; - listener = - [[TestServer alloc] initWithRegisteredName:@"NilProtocol" - protocol:nil - port:[NSMachPort port]]; - STAssertNil(listener, - @"We should not have created a server with a nil protocol"); - - [GTMUnitTestDevLog expectString: - @"Failed to create a listener, a port must be specified"]; - listener = - [[TestServer alloc] initWithRegisteredName:@"NilPort" - protocol:@protocol(TestServerDOProtocol) - port:nil]; - STAssertNil(listener, @"We should not have created a server with a nil port"); - -} - -- (void)testAbstractDOListenerMultipleRegistration { - TestServer *listener = - [[[TestServer alloc] initWithRegisteredName:@"MyUniqueName" - protocol:@protocol(TestServerDOProtocol) - port:[NSMachPort port]] autorelease]; - [GTMUnitTestDevLog expectPattern:@"listening on.*"]; - [listener runInCurrentThread]; - - TestServer *copyCat = - [[[TestServer alloc] initWithRegisteredName:@"copyCat" - protocol:@protocol(TestServerDOProtocol) - port:[NSMachPort port]] autorelease]; - STAssertTrue(([[copyCat registeredName] isEqualToString:@"copyCat"]), - @"The name we set to register with is not correct."); - - TestServer *listener2 = - [[[TestServer alloc] initWithRegisteredName:@"MyUniqueName" - protocol:@protocol(TestServerDOProtocol) - port:[NSMachPort port]] autorelease]; - - [GTMUnitTestDevLog expectPattern:@"failed to register.*"]; - [listener2 runInCurrentThread]; - STAssertNil([listener2 connection], @"We should not have been able to create " - @"a server with a name that has already been taken."); -} - -- (void)testAbstractDOListenerRequestTimeout { - NSString *serverName = @"RequestTimeoutTest"; - - // Build and start the server - TestServer *listener = - [[TestServer alloc] initWithRegisteredName:serverName - protocol:@protocol(TestServerDOProtocol)]; - [listener autorelease]; - [listener setReplyTimeout:kDefaultTimeout]; - [listener setRequestTimeout:kDefaultTimeout]; - - STAssertLessThanOrEqual(ABS([listener replyTimeout] - kDefaultTimeout), - (kDefaultTimeout / pow(kDefaultTimeout, 15)), nil); - - STAssertLessThanOrEqual(ABS([listener requestTimeout] - kDefaultTimeout), - (kDefaultTimeout / pow(kDefaultTimeout, 15)), nil); - - NSTimeInterval customHeartRate = 0.25; - [listener setThreadHeartRate:0.25]; - - STAssertLessThanOrEqual(ABS([listener ThreadHeartRate] - customHeartRate), - (customHeartRate / pow(customHeartRate, 15)), nil); - - [GTMUnitTestDevLog expectPattern:@"listening on.*"]; - [listener runInNewThreadWithErrorTarget:self - selector:@selector(listenerErrorEncountered:) - withObjectArgument:nil]; - - // It will take a little while for the new thread to spin up and start - // listening. We will spin here and wait for it to come on-line. - NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:kDelayTimeout]; - while (![listener connection] && - ([timeout compare:[NSDate date]] == NSOrderedDescending)) { - NSDate *waitTime = [NSDate dateWithTimeIntervalSinceNow:0.05]; - [[NSRunLoop currentRunLoop] runUntilDate:waitTime]; - } - - STAssertNotNil([listener connection], - @"The server never created a connection."); - - // Connect with our simple client - TestClient *client = - [[[TestClient alloc] initWithName:serverName] autorelease]; - id proxy = [client connect]; - STAssertNotNil(proxy, @"should have a proxy object"); - - NSNumber *overDelay = [NSNumber numberWithDouble:(kDefaultTimeout + 0.25)]; - STAssertThrows([proxy delayResponseForTime:overDelay], - @"An exception should have been thrown for the response taking" - @"longer than the replyTimout."); - - [client disconnect]; - [listener shutdown]; - - timeout = [NSDate dateWithTimeIntervalSinceNow:kDelayTimeout]; - while ([listener connection] && - ([timeout compare:[NSDate date]] == NSOrderedDescending)) { - NSDate *waitTime = [NSDate dateWithTimeIntervalSinceNow:0.05]; - [[NSRunLoop currentRunLoop] runUntilDate:waitTime]; - } - - STAssertNil([listener connection], - @"The connection should be nil after shutdown."); -} - -- (void)testAbstractDOListenerRelease { - NSUInteger listenerCount = [[GTMAbstractDOListener allListeners] count]; - GTMAbstractDOListener *listener = - [[GTMAbstractDOListener alloc] initWithRegisteredName:@"FOO" - protocol:@protocol(NSObject) - port:[NSPort port]]; - STAssertNotNil(listener, nil); - - // We throw an autorelease pool here because allStores does a couple of - // autoreleased retains on us which would screws up our retain count - // numbers. - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - STAssertEquals([[GTMAbstractDOListener allListeners] count], - listenerCount + 1, nil); - [pool drain]; - - STAssertEquals([listener retainCount], (NSUInteger)1, nil); - - [listener release]; - STAssertEquals([[GTMAbstractDOListener allListeners] count], listenerCount, - nil); -} - -@end diff --git a/Foundation/GTMCalculatedRange.h b/Foundation/GTMCalculatedRange.h deleted file mode 100644 index c51181a..0000000 --- a/Foundation/GTMCalculatedRange.h +++ /dev/null @@ -1,105 +0,0 @@ -// -// GTMCalculatedRange.h -// -// This is a collection that allows you to calculate a value based on -// defined stops in a range. -// -// Copyright 2006-2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> -#import "GTMDefines.h" -#if GTM_IPHONE_SDK -#import <CoreGraphics/CoreGraphics.h> -#endif // GTM_IPHONE_SDK - -/// Allows you to calculate a value based on defined stops in a range. -// -/// For example if you have a range from 0.0 to 1.0 where the stop -/// located at 0.0 is red and the stop located at 1.0 is blue, -/// the value based on the position 0.5 would come out as purple assuming -/// that the valueAtPosition function calculates a purely linear mapping between -/// the stops at 0.0 and 1.0. Stops have indices and are sorted from lowest to -/// highest. The example above would have 2 stops. Stop 0 would be red and stop -/// 1 would be blue. -/// -/// Subclasses of GTMCalculatedRange are expected to override the valueAtPosition: -/// method to return a value based on the position passed in, and the stops -/// that are currently set in the range. Stops do not necessarily have to -/// be the same type as the values that are calculated, but normally they are. -@interface GTMCalculatedRange : NSObject { - NSMutableArray *storage_; -} - -// Adds a stop to the range at |position|. If there is already a stop -// at position |position| it is replaced. -// -// Args: -// item: the object to place at |position|. -// position: the position in the range to put |item|. -// -- (void)insertStop:(id)item atPosition:(CGFloat)position; - -// Removes a stop from the range at |position|. -// -// Args: -// position: the position in the range to remove |item|. -// -// Returns: -// YES if there is a stop at |position| that has been removed -// NO if there is not a stop at the |position| -- (BOOL)removeStopAtPosition:(CGFloat)position; - -// Removes stop |index| from the range. Stops are ordered -// based on position where index of x < index of y if position -// of x < position of y. -// -// Args: -// item: the object to place at |position|. -// position: the position in the range to put |item|. -// -- (void)removeStopAtIndex:(NSUInteger)index; - -// Returns the number of stops in the range. -// -// Returns: -// number of stops -- (NSUInteger)stopCount; - -// Returns the value at position |position|. -// This function should be overridden by subclasses to calculate a -// value for any given range. -// The default implementation returns a value if there happens to be -// a stop for the given position. Otherwise it returns nil. -// -// Args: -// position: the position to calculate a value for. -// -// Returns: -// value for position -- (id)valueAtPosition:(CGFloat)position; - -// Returns the |index|'th stop and position in the set. -// Throws an exception if out of range. -// -// Args: -// index: the index of the stop -// outPosition: a pointer to a value to be filled in with a position. -// this can be NULL, in which case no position is returned. -// -// Returns: -// the stop at the index. -- (id)stopAtIndex:(NSUInteger)index position:(CGFloat*)outPosition; -@end diff --git a/Foundation/GTMCalculatedRange.m b/Foundation/GTMCalculatedRange.m deleted file mode 100644 index 3e8aa69..0000000 --- a/Foundation/GTMCalculatedRange.m +++ /dev/null @@ -1,148 +0,0 @@ -// -// GTMCalculatedRange.m -// -// Copyright 2006-2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMCalculatedRange.h" - -// Our internal storage type. It keeps track of an item and it's -// position. -@interface GTMCalculatedRangeStopPrivate : NSObject { - id item_; // the item (STRONG) - CGFloat position_; // -} -+ (id)stopWithObject:(id)item position:(CGFloat)inPosition; -- (id)initWithObject:(id)item position:(CGFloat)inPosition; -- (id)item; -- (CGFloat)position; -@end - -GTM_INLINE BOOL FPEqual(CGFloat a, CGFloat b) { - return (fpclassify(a - b) == FP_ZERO); -} - -@implementation GTMCalculatedRangeStopPrivate -+ (id)stopWithObject:(id)item position:(CGFloat)inPosition { - return [[[self alloc] initWithObject:item position:inPosition] autorelease]; -} - -- (id)initWithObject:(id)item position:(CGFloat)inPosition { - self = [super init]; - if (self != nil) { - item_ = [item retain]; - position_ = inPosition; - } - return self; -} - -- (void)dealloc { - [item_ release]; - [super dealloc]; -} - -- (id)item { - return item_; -} - -- (CGFloat)position { - return position_; -} - -- (NSString *)description { - return [NSString stringWithFormat: @"%f %@", position_, item_]; -} -@end - -@implementation GTMCalculatedRange -- (id)init { - self = [super init]; - if (self != nil) { - storage_ = [[NSMutableArray arrayWithCapacity:0] retain]; - } - return self; -} -- (void)dealloc { - [storage_ release]; - [super dealloc]; -} - -- (void)insertStop:(id)item atPosition:(CGFloat)position { - NSUInteger positionIndex = 0; - GTMCalculatedRangeStopPrivate *theStop; - GTM_FOREACH_OBJECT(theStop, storage_) { - if ([theStop position] < position) { - positionIndex += 1; - } - else if (FPEqual([theStop position], position)) { - // remove and stop the enum since we just modified the object - [storage_ removeObjectAtIndex:positionIndex]; - break; - } - } - [storage_ insertObject:[GTMCalculatedRangeStopPrivate stopWithObject:item position:position] - atIndex:positionIndex]; -} - -- (BOOL)removeStopAtPosition:(CGFloat)position { - NSUInteger positionIndex = 0; - BOOL foundStop = NO; - GTMCalculatedRangeStopPrivate *theStop; - GTM_FOREACH_OBJECT(theStop, storage_) { - if (FPEqual([theStop position], position)) { - break; - } else { - positionIndex += 1; - } - } - if (nil != theStop) { - [self removeStopAtIndex:positionIndex]; - foundStop = YES; - } - return foundStop; -} - -- (void)removeStopAtIndex:(NSUInteger)positionIndex { - [storage_ removeObjectAtIndex:positionIndex]; -} - -- (NSUInteger)stopCount { - return [storage_ count]; -} - -- (id)stopAtIndex:(NSUInteger)positionIndex position:(CGFloat*)outPosition { - GTMCalculatedRangeStopPrivate *theStop = [storage_ objectAtIndex:positionIndex]; - if (nil != outPosition) { - *outPosition = [theStop position]; - } - return [theStop item]; -} - -- (id)valueAtPosition:(CGFloat)position { - id theValue = nil; - GTMCalculatedRangeStopPrivate *theStop; - GTM_FOREACH_OBJECT(theStop, storage_) { - if (FPEqual([theStop position], position)) { - theValue = [theStop item]; - break; - } - } - return theValue; -} - -- (NSString *)description { - return [storage_ description]; -} -@end diff --git a/Foundation/GTMCalculatedRangeTest.m b/Foundation/GTMCalculatedRangeTest.m deleted file mode 100644 index 0806a0d..0000000 --- a/Foundation/GTMCalculatedRangeTest.m +++ /dev/null @@ -1,101 +0,0 @@ -// -// GTMCalculatedRangeTest.m -// -// Copyright 2006-2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMCalculatedRange.h" -#import "GTMSenTestCase.h" - -@interface GTMCalculatedRangeTest : GTMTestCase { - GTMCalculatedRange *range_; -} -@end - -@implementation GTMCalculatedRangeTest -NSString *kStrings[] = { @"Fee", @"Fi", @"Fo", @"Fum" }; -const NSUInteger kStringCount = sizeof(kStrings) / sizeof(NSString*); -const CGFloat kOddPosition = 0.14159265f; -const CGFloat kExistingPosition = 0.5f; -const NSUInteger kExisitingIndex = 2; - -- (void)setUp { - range_ = [[GTMCalculatedRange alloc] init]; - for(NSUInteger i = kStringCount; i > 0; --i) { - [range_ insertStop:kStrings[kStringCount - i] atPosition:(CGFloat)(1.0 / i)]; - } -} - -- (void)tearDown { - [range_ release]; -} - -- (void)testInsertStop { - // new position - NSString *theString = @"I smell the blood of an Englishman!"; - [range_ insertStop:theString atPosition:kOddPosition]; - STAssertEquals([range_ stopCount], kStringCount + 1, @"Stop count was bad"); - NSString *getString = [range_ valueAtPosition:kOddPosition]; - STAssertNotNil(getString, @"String was bad"); - STAssertEquals(theString, getString, @"Stops weren't equal"); - // existing position - NSString *theStringTake2 = @"I smell the blood of an Englishman! Take 2"; - [range_ insertStop:theStringTake2 atPosition:kOddPosition]; - STAssertEquals([range_ stopCount], kStringCount + 1, @"Stop count was bad"); - getString = [range_ valueAtPosition:kOddPosition]; - STAssertNotNil(getString, @"String was bad"); - STAssertEquals(theStringTake2, getString, @"Stops weren't equal"); - STAssertNotEquals(theString, getString, @"Should be the new value"); - STAssertNotEqualObjects(theString, getString, @"Should be the new value"); -} - -- (void)testRemoveStopAtPosition { - STAssertFalse([range_ removeStopAtPosition: kOddPosition], @"Was able to remove non-existant stop"); - STAssertTrue([range_ removeStopAtPosition: kExistingPosition], @"Was unable to remove good stop"); - STAssertEquals([range_ stopCount], kStringCount - 1, @"Removing stop should adjust stop count"); -} - -- (void)testRemoveStopAtIndex { - STAssertThrows([range_ removeStopAtIndex: kStringCount], @"Was able to remove non-existant stop"); - STAssertNoThrow([range_ removeStopAtIndex: kStringCount - 1], @"Was unable to remove good stop"); - STAssertEquals([range_ stopCount], kStringCount - 1, @"Removing stop should adjust stop count"); -} - -- (void)testStopCount { - STAssertEquals([range_ stopCount], kStringCount, @"Bad stop count"); -} - -- (void)testValueAtPosition { - STAssertEqualObjects([range_ valueAtPosition: kExistingPosition], kStrings[kExisitingIndex], nil); - STAssertNotEqualObjects([range_ valueAtPosition: kExistingPosition], kStrings[kStringCount - 1], nil); - STAssertNil([range_ valueAtPosition: kOddPosition], nil); -} - -- (void)testStopAtIndex { - CGFloat thePosition; - - STAssertEqualObjects([range_ stopAtIndex:kStringCount - 1 position:nil], kStrings[kStringCount - 1], nil); - STAssertEqualObjects([range_ stopAtIndex:kExisitingIndex position:&thePosition], kStrings[kExisitingIndex], nil); - STAssertEquals(thePosition, kExistingPosition, nil); - STAssertNotEqualObjects([range_ stopAtIndex:kStringCount - 1 position:nil], kStrings[2], nil); - STAssertThrows([range_ stopAtIndex:kStringCount position:nil], nil); -} - -- (void)testDescription { - // we expect a description of atleast a few chars - STAssertGreaterThan([[range_ description] length], (NSUInteger)10, nil); -} - -@end diff --git a/Foundation/GTMExceptionalInlines.h b/Foundation/GTMExceptionalInlines.h deleted file mode 100644 index ee3a3db..0000000 --- a/Foundation/GTMExceptionalInlines.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// GTMExceptionalInlines.h -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> -#import "GTMDefines.h" -#if GTM_IPHONE_SDK -#import <CoreGraphics/CoreGraphics.h> -#endif // GTM_IPHONE_SDK - -// This file exists because when you have full warnings on you can run into -// troubles with functions that Apple has inlined that have structures or -// local variables defined in them. -// You only see this warning if you have -Wuninitialized turned on, -// and you will only see them in release mode. -Wno-unitialized turns them -// off, but you also lose all the good warnings that come with -Wuninitialized. -// If you have the inline versions of any of the functions below in a -// @syncronized, or @try block, you will get -// warning: variable 'r' might be clobbered by 'longjmp' or 'vfork' -// By moving this local vars "out of line" you fix the problem. -// These functions do nothing more than act as "out of line" calls to the -// functions they are masking to avoid the warning. -// If you run into others, feel free to add them. - -// Please only use these to avoid the warning above. Use the Apple defined -// functions where possible. - -FOUNDATION_EXPORT NSRange GTMNSMakeRange(NSUInteger loc, NSUInteger len); -FOUNDATION_EXPORT CFRange GTMCFRangeMake(NSUInteger loc, NSUInteger len); - -FOUNDATION_EXPORT CGPoint GTMCGPointMake(CGFloat x, CGFloat y); -FOUNDATION_EXPORT CGSize GTMCGSizeMake(CGFloat width, CGFloat height); -FOUNDATION_EXPORT CGRect GTMCGRectMake(CGFloat x, CGFloat y, - CGFloat width, CGFloat height); - -#if !GTM_IPHONE_SDK -// iPhone does not have NSTypes defined, only CGTypes. So no NSRect, NSPoint etc. -FOUNDATION_EXPORT NSPoint GTMNSMakePoint(CGFloat x, CGFloat y); -FOUNDATION_EXPORT NSSize GTMNSMakeSize(CGFloat w, CGFloat h); -FOUNDATION_EXPORT NSRect GTMNSMakeRect(CGFloat x, CGFloat y, - CGFloat w, CGFloat h); -#endif diff --git a/Foundation/GTMExceptionalInlines.m b/Foundation/GTMExceptionalInlines.m deleted file mode 100644 index d803ea9..0000000 --- a/Foundation/GTMExceptionalInlines.m +++ /dev/null @@ -1,56 +0,0 @@ -// -// GTMExceptionalInlines.m -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMExceptionalInlines.h" - -NSRange GTMNSMakeRange(NSUInteger loc, NSUInteger len) { - return NSMakeRange(loc, len); -} - -CFRange GTMCFRangeMake(NSUInteger loc, NSUInteger len) { - return CFRangeMake(loc, len); -} - -CGPoint GTMCGPointMake(CGFloat x, CGFloat y) { - return CGPointMake(x, y); -} - -CGSize GTMCGSizeMake(CGFloat width, CGFloat height) { - return CGSizeMake(width, height); -} - -CGRect GTMCGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height) { - return CGRectMake(x, y, width, height); -} - -#if !GTM_IPHONE_SDK -// iPhone does not have NSTypes defined, only CGTypes. So no NSRect, NSPoint etc. - -NSPoint GTMNSMakePoint(CGFloat x, CGFloat y) { - return NSMakePoint(x, y); -} - -NSSize GTMNSMakeSize(CGFloat w, CGFloat h) { - return NSMakeSize(w, h); -} - -NSRect GTMNSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h) { - return NSMakeRect(x, y, w, h); -} - -#endif diff --git a/Foundation/GTMExceptionalInlinesTest.m b/Foundation/GTMExceptionalInlinesTest.m deleted file mode 100644 index 6142236..0000000 --- a/Foundation/GTMExceptionalInlinesTest.m +++ /dev/null @@ -1,71 +0,0 @@ -// -// GTMExceptionalInlinesTest.m -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" -#import "GTMExceptionalInlines.h" - -@interface GTMExceptionalInlinesTest : GTMTestCase -@end - -@implementation GTMExceptionalInlinesTest -- (void)testExceptionalInlines { - // Numbers chosen basically at random. - NSUInteger loc = 5; - NSUInteger len = 10; - CGFloat x = 22.5; - CGFloat y = 40.2; - CGFloat h = 21.6; - CGFloat w = 54.2; - - NSRange range1 = GTMNSMakeRange(loc, len); - NSRange range2 = NSMakeRange(loc, len); - STAssertTrue(NSEqualRanges(range1, range2), nil); - - CFRange cfrange1 = GTMCFRangeMake(loc, len); - CFRange cfrange2 = CFRangeMake(loc, len); - STAssertEquals(cfrange1.length, cfrange2.length, nil); - STAssertEquals(cfrange1.location, cfrange2.location, nil); - - - CGPoint cgpoint1 = GTMCGPointMake(x, y); - CGPoint cgpoint2 = CGPointMake(x, y); - STAssertTrue(CGPointEqualToPoint(cgpoint1, cgpoint2), nil); - - CGSize cgsize1 = GTMCGSizeMake(x, y); - CGSize cgsize2 = CGSizeMake(x, y); - STAssertTrue(CGSizeEqualToSize(cgsize1, cgsize2), nil); - - CGRect cgrect1 = GTMCGRectMake(x, y, w, h); - CGRect cgrect2 = CGRectMake(x, y, w, h); - STAssertTrue(CGRectEqualToRect(cgrect1, cgrect2), nil); - -#if !GTM_IPHONE_SDK - NSPoint point1 = GTMNSMakePoint(x, y); - NSPoint point2 = NSMakePoint(x, y); - STAssertTrue(NSEqualPoints(point1, point2), nil); - - NSSize size1 = GTMNSMakeSize(w, h); - NSSize size2 = NSMakeSize(w, h); - STAssertTrue(NSEqualSizes(size1, size2), nil); - - NSRect rect1 = GTMNSMakeRect(x, y, w, h); - NSRect rect2 = NSMakeRect(x, y, w, h); - STAssertTrue(NSEqualRects(rect1, rect2), nil); -#endif -} -@end diff --git a/Foundation/GTMFileSystemKQueueTest.m b/Foundation/GTMFileSystemKQueueTest.m index 3919b86..9ffc046 100644 --- a/Foundation/GTMFileSystemKQueueTest.m +++ b/Foundation/GTMFileSystemKQueueTest.m @@ -18,7 +18,6 @@ #import "GTMSenTestCase.h" #import "GTMFileSystemKQueue.h" -#import "GTMUnitTestDevLog.h" // Private methods of GTMFileSystemKQueue we use for some tests @@ -47,17 +46,9 @@ - (void)callbackForQueue:(GTMFileSystemKQueue *)queue events:(GTMFileSystemKQueueEvents)event { - // Can't use standard ST macros here because our helper - // is not a subclass of GTMTestCase. This is intentional. if (queue != queue_) { - NSString *file = [NSString stringWithUTF8String:__FILE__]; - NSException *exception - = [NSException failureInEqualityBetweenObject:queue - andObject:queue_ - inFile:file - atLine:__LINE__ - withDescription:nil]; - [exception raise]; + // We should never get here. + [NSException raise:NSInternalInconsistencyException format:@"Bad Queue!"]; } if (event & kGTMFileSystemKQueueWriteEvent) { @@ -132,13 +123,11 @@ - (void)testInit { GTMFileSystemKQueue *testKQ; GTMFSKQTestHelper *helper = [[[GTMFSKQTestHelper alloc] init] autorelease]; - STAssertNotNil(helper, nil); + XCTAssertNotNil(helper); // init should fail - [GTMUnitTestDevLog expectString:@"Don't call init, use " - @"initWithPath:forEvents:acrossReplace:target:action:"]; testKQ = [[[GTMFileSystemKQueue alloc] init] autorelease]; - STAssertNil(testKQ, nil); + XCTAssertNil(testKQ); // no path testKQ @@ -147,7 +136,7 @@ acrossReplace:YES target:helper action:@selector(callbackForQueue:events:)] autorelease]; - STAssertNil(testKQ, nil); + XCTAssertNil(testKQ); // not events testKQ @@ -156,7 +145,7 @@ acrossReplace:YES target:helper action:@selector(callbackForQueue:events:)] autorelease]; - STAssertNil(testKQ, nil); + XCTAssertNil(testKQ); // no target testKQ @@ -165,7 +154,7 @@ acrossReplace:YES target:nil action:@selector(callbackForQueue:events:)] autorelease]; - STAssertNil(testKQ, nil); + XCTAssertNil(testKQ); // no handler testKQ @@ -174,7 +163,7 @@ acrossReplace:YES target:helper action:nil] autorelease]; - STAssertNil(testKQ, nil); + XCTAssertNil(testKQ); // path that doesn't exist @@ -184,7 +173,7 @@ acrossReplace:YES target:helper action:@selector(callbackForQueue:events:)] autorelease]; - STAssertNil(testKQ, nil); + XCTAssertNil(testKQ); } - (void)spinForEvents:(GTMFSKQTestHelper *)helper { @@ -201,11 +190,11 @@ NSFileManager *fm = [NSFileManager defaultManager]; GTMFSKQTestHelper *helper = [[[GTMFSKQTestHelper alloc] init] autorelease]; - STAssertNotNil(helper, nil); + XCTAssertNotNil(helper); - STAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil], nil); + XCTAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil]); NSFileHandle *testFH = [NSFileHandle fileHandleForWritingAtPath:testPath_]; - STAssertNotNil(testFH, nil); + XCTAssertNotNil(testFH); // Start monitoring the file GTMFileSystemKQueue *testKQ @@ -214,8 +203,8 @@ acrossReplace:YES target:helper action:@selector(callbackForQueue:events:)]; - STAssertNotNil(testKQ, nil); - STAssertEqualObjects([testKQ path], testPath_, nil); + XCTAssertNotNil(testKQ); + XCTAssertEqualObjects([testKQ path], testPath_); [helper setKQueue:testKQ]; // Write to the file @@ -223,27 +212,27 @@ // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 1, nil); + XCTAssertEqual([helper totals], 1); // Close and delete [testFH closeFile]; #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 NSError *error = nil; - STAssertTrue([fm removeItemAtPath:testPath_ error:&error], @"Err: %@", error); + XCTAssertTrue([fm removeItemAtPath:testPath_ error:&error], @"Err: %@", error); #else - STAssertTrue([fm removeFileAtPath:testPath_ handler:nil], nil); + XCTAssertTrue([fm removeFileAtPath:testPath_ handler:nil]); #endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 [self spinForEvents:helper]; - STAssertEquals([helper totals], 2, nil); + XCTAssertEqual([helper totals], 2); // Clean up the kqueue [testKQ release]; testKQ = nil; - STAssertEquals([helper writes], 1, nil); - STAssertEquals([helper deletes], 1, nil); - STAssertEquals([helper renames], 0, nil); + XCTAssertEqual([helper writes], 1); + XCTAssertEqual([helper deletes], 1); + XCTAssertEqual([helper renames], 0); } - (void)testWriteAndDeleteAndWrite { @@ -252,14 +241,14 @@ NSFileManager *fm = [NSFileManager defaultManager]; GTMFSKQTestHelper *helper = [[[GTMFSKQTestHelper alloc] init] autorelease]; - STAssertNotNil(helper, nil); + XCTAssertNotNil(helper); GTMFSKQTestHelper *helper2 = [[[GTMFSKQTestHelper alloc] init] autorelease]; - STAssertNotNil(helper, nil); + XCTAssertNotNil(helper); // Create a temp file path - STAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil], nil); + XCTAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil]); NSFileHandle *testFH = [NSFileHandle fileHandleForWritingAtPath:testPath_]; - STAssertNotNil(testFH, nil); + XCTAssertNotNil(testFH); // Start monitoring the file GTMFileSystemKQueue *testKQ @@ -268,8 +257,8 @@ acrossReplace:YES target:helper action:@selector(callbackForQueue:events:)]; - STAssertNotNil(testKQ, nil); - STAssertEqualObjects([testKQ path], testPath_, nil); + XCTAssertNotNil(testKQ); + XCTAssertEqualObjects([testKQ path], testPath_); [helper setKQueue:testKQ]; GTMFileSystemKQueue *testKQ2 @@ -278,8 +267,8 @@ acrossReplace:NO target:helper2 action:@selector(callbackForQueue:events:)]; - STAssertNotNil(testKQ2, nil); - STAssertEqualObjects([testKQ2 path], testPath_, nil); + XCTAssertNotNil(testKQ2); + XCTAssertEqualObjects([testKQ2 path], testPath_); [helper2 setKQueue:testKQ2]; // Write to the file @@ -287,49 +276,49 @@ // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 1, nil); - STAssertEquals([helper2 totals], 1, nil); + XCTAssertEqual([helper totals], 1); + XCTAssertEqual([helper2 totals], 1); // Close and delete [testFH closeFile]; #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 NSError *error = nil; - STAssertTrue([fm removeItemAtPath:testPath_ error:&error], @"Err: %@", error); + XCTAssertTrue([fm removeItemAtPath:testPath_ error:&error], @"Err: %@", error); #else - STAssertTrue([fm removeFileAtPath:testPath_ handler:nil], nil); + XCTAssertTrue([fm removeFileAtPath:testPath_ handler:nil]); #endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 // Recreate - STAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil], nil); + XCTAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil]); testFH = [NSFileHandle fileHandleForWritingAtPath:testPath_]; - STAssertNotNil(testFH, nil); + XCTAssertNotNil(testFH); [testFH writeData:[@"ha!" dataUsingEncoding:NSUnicodeStringEncoding]]; // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 2, nil); - STAssertEquals([helper2 totals], 2, nil); + XCTAssertEqual([helper totals], 2); + XCTAssertEqual([helper2 totals], 2); // Write to it again [testFH writeData:[@"continued..." dataUsingEncoding:NSUnicodeStringEncoding]]; // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 3, nil); - STAssertEquals([helper2 totals], 2, nil); + XCTAssertEqual([helper totals], 3); + XCTAssertEqual([helper2 totals], 2); // Close and delete [testFH closeFile]; #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - STAssertTrue([fm removeItemAtPath:testPath_ error:&error], @"Err: %@", error); + XCTAssertTrue([fm removeItemAtPath:testPath_ error:&error], @"Err: %@", error); #else - STAssertTrue([fm removeFileAtPath:testPath_ handler:nil], nil); + XCTAssertTrue([fm removeFileAtPath:testPath_ handler:nil]); #endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 4, nil); - STAssertEquals([helper2 totals], 2, nil); + XCTAssertEqual([helper totals], 4); + XCTAssertEqual([helper2 totals], 2); // Clean up the kqueue [testKQ release]; @@ -337,12 +326,12 @@ [testKQ2 release]; testKQ2 = nil; - STAssertEquals([helper writes], 2, nil); - STAssertEquals([helper deletes], 2, nil); - STAssertEquals([helper renames], 0, nil); - STAssertEquals([helper2 writes], 1, nil); - STAssertEquals([helper2 deletes], 1, nil); - STAssertEquals([helper2 renames], 0, nil); + XCTAssertEqual([helper writes], 2); + XCTAssertEqual([helper deletes], 2); + XCTAssertEqual([helper renames], 0); + XCTAssertEqual([helper2 writes], 1); + XCTAssertEqual([helper2 deletes], 1); + XCTAssertEqual([helper2 renames], 0); } - (void)testWriteAndRenameAndWrite { @@ -351,14 +340,14 @@ NSFileManager *fm = [NSFileManager defaultManager]; GTMFSKQTestHelper *helper = [[[GTMFSKQTestHelper alloc] init] autorelease]; - STAssertNotNil(helper, nil); + XCTAssertNotNil(helper); GTMFSKQTestHelper *helper2 = [[[GTMFSKQTestHelper alloc] init] autorelease]; - STAssertNotNil(helper2, nil); + XCTAssertNotNil(helper2); // Create a temp file path - STAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil], nil); + XCTAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil]); NSFileHandle *testFH = [NSFileHandle fileHandleForWritingAtPath:testPath_]; - STAssertNotNil(testFH, nil); + XCTAssertNotNil(testFH); // Start monitoring the file GTMFileSystemKQueue *testKQ @@ -367,8 +356,8 @@ acrossReplace:YES target:helper action:@selector(callbackForQueue:events:)]; - STAssertNotNil(testKQ, nil); - STAssertEqualObjects([testKQ path], testPath_, nil); + XCTAssertNotNil(testKQ); + XCTAssertEqualObjects([testKQ path], testPath_); [helper setKQueue:testKQ]; GTMFileSystemKQueue *testKQ2 @@ -377,8 +366,8 @@ acrossReplace:NO target:helper2 action:@selector(callbackForQueue:events:)]; - STAssertNotNil(testKQ2, nil); - STAssertEqualObjects([testKQ2 path], testPath_, nil); + XCTAssertNotNil(testKQ2); + XCTAssertEqualObjects([testKQ2 path], testPath_); [helper2 setKQueue:testKQ2]; // Write to the file @@ -386,70 +375,70 @@ // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 1, nil); - STAssertEquals([helper2 totals], 1, nil); + XCTAssertEqual([helper totals], 1); + XCTAssertEqual([helper2 totals], 1); // Move it and create the file again #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 NSError *error = nil; - STAssertTrue([fm moveItemAtPath:testPath_ toPath:testPath2_ error:&error], - @"Error: %@", error); + XCTAssertTrue([fm moveItemAtPath:testPath_ toPath:testPath2_ error:&error], + @"Error: %@", error); #else - STAssertTrue([fm movePath:testPath_ toPath:testPath2_ handler:nil], nil); + XCTAssertTrue([fm movePath:testPath_ toPath:testPath2_ handler:nil]); #endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - STAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil], nil); + XCTAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil]); NSFileHandle *testFHPrime = [NSFileHandle fileHandleForWritingAtPath:testPath_]; - STAssertNotNil(testFHPrime, nil); + XCTAssertNotNil(testFHPrime); [testFHPrime writeData:[@"eh?" dataUsingEncoding:NSUnicodeStringEncoding]]; // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 2, nil); - STAssertEquals([helper2 totals], 2, nil); + XCTAssertEqual([helper totals], 2); + XCTAssertEqual([helper2 totals], 2); // Write to the new file [testFHPrime writeData:[@"continue..." dataUsingEncoding:NSUnicodeStringEncoding]]; // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 3, nil); - STAssertEquals([helper2 totals], 2, nil); + XCTAssertEqual([helper totals], 3); + XCTAssertEqual([helper2 totals], 2); // Write to the old file [testFH writeData:[@"continue old..." dataUsingEncoding:NSUnicodeStringEncoding]]; // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 3, nil); - STAssertEquals([helper2 totals], 3, nil); + XCTAssertEqual([helper totals], 3); + XCTAssertEqual([helper2 totals], 3); // and now close old [testFH closeFile]; #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - STAssertTrue([fm removeItemAtPath:testPath2_ error:&error], @"Err: %@", error); + XCTAssertTrue([fm removeItemAtPath:testPath2_ error:&error], @"Err: %@", error); #else - STAssertTrue([fm removeFileAtPath:testPath2_ handler:nil], nil); + XCTAssertTrue([fm removeFileAtPath:testPath2_ handler:nil]); #endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 3, nil); - STAssertEquals([helper2 totals], 4, nil); + XCTAssertEqual([helper totals], 3); + XCTAssertEqual([helper2 totals], 4); // and now close new [testFHPrime closeFile]; #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - STAssertTrue([fm removeItemAtPath:testPath_ error:&error], @"Err: %@", error); + XCTAssertTrue([fm removeItemAtPath:testPath_ error:&error], @"Err: %@", error); #else - STAssertTrue([fm removeFileAtPath:testPath_ handler:nil], nil); + XCTAssertTrue([fm removeFileAtPath:testPath_ handler:nil]); #endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 // Spin the runloop for a second so that the helper callbacks fire [self spinForEvents:helper]; - STAssertEquals([helper totals], 4, nil); - STAssertEquals([helper2 totals], 4, nil); + XCTAssertEqual([helper totals], 4); + XCTAssertEqual([helper2 totals], 4); // Clean up the kqueue [testKQ release]; @@ -457,12 +446,12 @@ [testKQ2 release]; testKQ2 = nil; - STAssertEquals([helper writes], 2, nil); - STAssertEquals([helper deletes], 1, nil); - STAssertEquals([helper renames], 1, nil); - STAssertEquals([helper2 writes], 2, nil); - STAssertEquals([helper2 deletes], 1, nil); - STAssertEquals([helper2 renames], 1, nil); + XCTAssertEqual([helper writes], 2); + XCTAssertEqual([helper deletes], 1); + XCTAssertEqual([helper renames], 1); + XCTAssertEqual([helper2 writes], 2); + XCTAssertEqual([helper2 deletes], 1); + XCTAssertEqual([helper2 renames], 1); } - (void)testNoSpinHang { @@ -480,10 +469,10 @@ NSFileManager *fm = [NSFileManager defaultManager]; GTMFSKQTestHelper *helper = [[[GTMFSKQTestHelper alloc] init] autorelease]; - STAssertNotNil(helper, nil); - STAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil], nil); + XCTAssertNotNil(helper); + XCTAssertTrue([fm createFileAtPath:testPath_ contents:nil attributes:nil]); NSFileHandle *testFH = [NSFileHandle fileHandleForWritingAtPath:testPath_]; - STAssertNotNil(testFH, nil); + XCTAssertNotNil(testFH); // Start monitoring the file GTMFileSystemKQueue *testKQ @@ -492,8 +481,8 @@ acrossReplace:YES target:helper action:@selector(callbackForQueue:events:)]; - STAssertNotNil(testKQ, nil); - STAssertEqualObjects([testKQ path], testPath_, nil); + XCTAssertNotNil(testKQ); + XCTAssertEqualObjects([testKQ path], testPath_); [helper setKQueue:testKQ]; // Write to the file @@ -502,20 +491,20 @@ [testFH closeFile]; #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 NSError *error = nil; - STAssertTrue([fm removeItemAtPath:testPath_ error:&error], @"Err: %@", error); + XCTAssertTrue([fm removeItemAtPath:testPath_ error:&error], @"Err: %@", error); #else - STAssertTrue([fm removeFileAtPath:testPath_ handler:nil], nil); + XCTAssertTrue([fm removeFileAtPath:testPath_ handler:nil]); #endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 // Now destroy the queue, with events outstanding from the CFSocket, but // unconsumed. - STAssertEquals([testKQ retainCount], (NSUInteger)1, nil); + XCTAssertEqual([testKQ retainCount], (NSUInteger)1); [testKQ release]; testKQ = nil; // Spin the runloop, no events were delivered (and we should not hang) [self spinForEvents:helper]; - STAssertEquals([helper totals], 0, nil); + XCTAssertEqual([helper totals], 0); } @end diff --git a/Foundation/GTMFourCharCode.h b/Foundation/GTMFourCharCode.h deleted file mode 100644 index 90853b5..0000000 --- a/Foundation/GTMFourCharCode.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// GTMFourCharCode -// Wrapper for FourCharCodes -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> - -// FourCharCodes are OSTypes, ResTypes etc. This class wraps them if -// you need to store them in dictionaries etc. -@interface GTMFourCharCode : NSObject <NSCopying, NSCoding> { - FourCharCode code_; -} - -// returns a string for a FourCharCode -+ (id)stringWithFourCharCode:(FourCharCode)code; - -// String must be 4 chars or less, or you will get nil back. -+ (id)fourCharCodeWithString:(NSString*)string; -+ (id)fourCharCodeWithFourCharCode:(FourCharCode)code; - -// String must be 4 chars or less, or you will get nil back. -- (id)initWithString:(NSString*)string; - -// Designated Initializer -- (id)initWithFourCharCode:(FourCharCode)code; - -// Returns 'APPL' for "APPL" -- (FourCharCode)fourCharCode; - -// For FourCharCode of 'APPL' returns "APPL". For 1 returns "\0\0\0\1" -- (NSString*)stringValue; - -// For FourCharCode of "APPL" returns an NSNumber with 1095782476 (0x4150504C). -// For 1 returns 1. -- (NSNumber*)numberValue; - -@end diff --git a/Foundation/GTMFourCharCode.m b/Foundation/GTMFourCharCode.m deleted file mode 100644 index 02eea23..0000000 --- a/Foundation/GTMFourCharCode.m +++ /dev/null @@ -1,97 +0,0 @@ -// -// GTMFourCharCode.m -// Wrapper for FourCharCodes -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMDefines.h" -#import "GTMFourCharCode.h" -#import <CoreServices/CoreServices.h> - -@implementation GTMFourCharCode - -+ (id)stringWithFourCharCode:(FourCharCode)code { - return GTMCFAutorelease(UTCreateStringForOSType(code)); -} - -+ (id)fourCharCodeWithString:(NSString*)string { - return [[[self alloc] initWithString:string] autorelease]; -} - -+ (id)fourCharCodeWithFourCharCode:(FourCharCode)code { - return [[[self alloc] initWithFourCharCode:code] autorelease]; -} - -- (id)initWithString:(NSString*)string { - NSUInteger length = [string length]; - if (length == 0 || length > 4) { - [self release]; - return nil; - } else { - return [self initWithFourCharCode:UTGetOSTypeFromString((CFStringRef)string)]; - } -} - -- (id)initWithFourCharCode:(FourCharCode)code { - if ((self = [super init])) { - code_ = code; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - if ((self = [super init])) { - code_ = [aDecoder decodeInt32ForKey:@"FourCharCode"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)aCoder { - [aCoder encodeInt32:code_ forKey:@"FourCharCode"]; -} - -- (id)copyWithZone:(NSZone *)zone { - return [[[self class] alloc] initWithFourCharCode:code_]; -} - -- (BOOL)isEqual:(id)object { - return [object isKindOfClass:[self class]] && [object fourCharCode] == code_; -} - -- (NSUInteger)hash { - return (NSUInteger)code_; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"%@ - %@ (0x%lX)", - [self class], - [self stringValue], - (unsigned long)code_]; -} - -- (FourCharCode)fourCharCode { - return code_; -} - -- (NSString*)stringValue { - return GTMCFAutorelease(UTCreateStringForOSType(code_)); -} - -- (NSNumber*)numberValue { - return [NSNumber numberWithUnsignedInt:code_]; -} - -@end diff --git a/Foundation/GTMFourCharCodeTest.m b/Foundation/GTMFourCharCodeTest.m deleted file mode 100644 index 1799629..0000000 --- a/Foundation/GTMFourCharCodeTest.m +++ /dev/null @@ -1,122 +0,0 @@ -// -// GTMFourCharCodeTest.m -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" -#import "GTMFourCharCode.h" - -@interface GTMFourCharCodeTest : GTMTestCase { - @private - NSString *lowAsciiString_; - NSString *highMacOSRomanString_; -} - -@end - -@implementation GTMFourCharCodeTest - -static const FourCharCode kGTMHighMacOSRomanCode = 0xA5A8A9AA; // '•®©™' - -- (void)setUp { - // There appears to be a bug in the gcc 4.0 that is included with Xcode - // 3.2.5 where in release mode it doesn't like some string constants - // that include high or low ascii using the @"blah" string style. - // So we build them by hand. - // Use 8 bytes instead of 4, because stack protection gives us a warning - // if we have a buffer smaller than 8 bytes. - char string[8] = { 0, 0, 0, 1, 0, 0, 0, 0 }; - lowAsciiString_ = [[NSString alloc] initWithBytes:string - length:4 - encoding:NSASCIIStringEncoding]; - - // Must make sure our bytes are in the right order for building strings with, - // otherwise the string comes out in the wrong order on low-endian systems. - FourCharCode orderedString = htonl(kGTMHighMacOSRomanCode); - highMacOSRomanString_ - = [[NSString alloc] initWithBytes:&orderedString - length:sizeof(orderedString) - encoding:NSMacOSRomanStringEncoding]; -} - -- (void)tearDown { - [lowAsciiString_ release]; - [highMacOSRomanString_ release]; -} - -- (void)testFourCharCode { - GTMFourCharCode *fcc = [GTMFourCharCode fourCharCodeWithString:@"APPL"]; - STAssertNotNil(fcc, nil); - STAssertEqualObjects([fcc stringValue], @"APPL", nil); - STAssertEqualObjects([fcc numberValue], - [NSNumber numberWithUnsignedInt:'APPL'], nil); - STAssertEquals([fcc fourCharCode], (FourCharCode)'APPL', nil); - - STAssertEqualObjects([fcc description], - @"GTMFourCharCode - APPL (0x4150504C)", nil); - STAssertEquals([fcc hash], (NSUInteger)'APPL', nil); - - NSData *data = [NSKeyedArchiver archivedDataWithRootObject:fcc]; - STAssertNotNil(data, nil); - GTMFourCharCode *fcc2 - = (GTMFourCharCode*)[NSKeyedUnarchiver unarchiveObjectWithData:data]; - STAssertNotNil(fcc2, nil); - STAssertEqualObjects(fcc, fcc2, nil); - - fcc = [[[GTMFourCharCode alloc] initWithFourCharCode:'\?\?\?\?'] autorelease]; - STAssertNotNil(fcc, nil); - STAssertEqualObjects([fcc stringValue], @"????", nil); - STAssertEqualObjects([fcc numberValue], - [NSNumber numberWithUnsignedInt:'\?\?\?\?'], nil); - STAssertEquals([fcc fourCharCode], (FourCharCode)'\?\?\?\?', nil); - - fcc = [[[GTMFourCharCode alloc] initWithString:@"????"] autorelease]; - STAssertNotNil(fcc, nil); - STAssertEqualObjects([fcc stringValue], @"????", nil); - STAssertEqualObjects([fcc numberValue], - [NSNumber numberWithUnsignedInt:'\?\?\?\?'], nil); - STAssertEquals([fcc fourCharCode], (FourCharCode)'\?\?\?\?', nil); - - fcc = [GTMFourCharCode fourCharCodeWithFourCharCode:1]; - STAssertNotNil(fcc, nil); - STAssertTrue([[fcc stringValue] isEqualToString:lowAsciiString_], nil); - STAssertEqualObjects([fcc numberValue], - [NSNumber numberWithUnsignedInt:1], nil); - STAssertEquals([fcc fourCharCode], (FourCharCode)1, nil); - - fcc = [GTMFourCharCode fourCharCodeWithString:@"BADDSTRING"]; - STAssertNil(fcc, nil); - - fcc2 = [GTMFourCharCode fourCharCodeWithFourCharCode:kGTMHighMacOSRomanCode]; - STAssertNotNil(fcc2, nil); - STAssertEqualObjects([fcc2 stringValue], highMacOSRomanString_, nil); - STAssertEqualObjects([fcc2 numberValue], - [NSNumber numberWithUnsignedInt:kGTMHighMacOSRomanCode], - nil); - STAssertEquals([fcc2 fourCharCode], - (FourCharCode)kGTMHighMacOSRomanCode, nil); -} - -- (void)testStringWithCode { - STAssertEqualObjects([GTMFourCharCode stringWithFourCharCode:'APPL'], - @"APPL", nil); - STAssertEqualObjects([GTMFourCharCode stringWithFourCharCode:1], - lowAsciiString_, nil); - STAssertEqualObjects([GTMFourCharCode stringWithFourCharCode:kGTMHighMacOSRomanCode], - highMacOSRomanString_, nil); -} - -@end diff --git a/Foundation/GTMGeometryUtilsTest.m b/Foundation/GTMGeometryUtilsTest.m index f765526..f4cf731 100644 --- a/Foundation/GTMGeometryUtilsTest.m +++ b/Foundation/GTMGeometryUtilsTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -28,49 +28,49 @@ - (void)testGTMNSRectToCGRect { NSRect nsRect = NSMakeRect(4.6,3.2,22.1,45.0); CGRect cgRect = GTMNSRectToCGRect(nsRect); - STAssertTrue(CGRectEqualToRect(cgRect, *(CGRect*)&nsRect), nil); + XCTAssertTrue(CGRectEqualToRect(cgRect, *(CGRect*)&nsRect)); } - (void)testGTMNSSizeToCGSize { NSSize nsSize = {22,15}; CGSize cgSize = GTMNSSizeToCGSize(nsSize); - STAssertTrue(CGSizeEqualToSize(cgSize, *(CGSize*)&nsSize), nil); + XCTAssertTrue(CGSizeEqualToSize(cgSize, *(CGSize*)&nsSize)); } - (void)testGTMNSPointsOnRect { NSRect rect = NSMakeRect(0, 0, 2, 2); - + NSPoint point = GTMNSMidMinX(rect); - STAssertEqualsWithAccuracy(point.y, (CGFloat)1.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(point.x, (CGFloat)0.0, (CGFloat)0.01, nil); - + XCTAssertEqualWithAccuracy(point.y, 1.0, 0.01); + XCTAssertEqualWithAccuracy(point.x, 0.0, 0.01); + point = GTMNSMidMaxX(rect); - STAssertEqualsWithAccuracy(point.y, (CGFloat)1.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(point.x, (CGFloat)2.0, (CGFloat)0.01, nil); - + XCTAssertEqualWithAccuracy(point.y, 1.0, 0.01); + XCTAssertEqualWithAccuracy(point.x, 2.0, 0.01); + point = GTMNSMidMaxY(rect); - STAssertEqualsWithAccuracy(point.y, (CGFloat)2.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(point.x, (CGFloat)1.0, (CGFloat)0.01, nil); - + XCTAssertEqualWithAccuracy(point.y, 2.0, 0.01); + XCTAssertEqualWithAccuracy(point.x, 1.0, 0.01); + point = GTMNSMidMinY(rect); - STAssertEqualsWithAccuracy(point.y, (CGFloat)0.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(point.x, (CGFloat)1.0, (CGFloat)0.01, nil); + XCTAssertEqualWithAccuracy(point.y, 0.0, 0.01); + XCTAssertEqualWithAccuracy(point.x, 1.0, 0.01); point = GTMNSCenter(rect); - STAssertEqualsWithAccuracy(point.y, (CGFloat)1.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(point.x, (CGFloat)1.0, (CGFloat)0.01, nil); + XCTAssertEqualWithAccuracy(point.y, 1.0, 0.01); + XCTAssertEqualWithAccuracy(point.x, 1.0, 0.01); } - (void)testGTMNSRectSize { NSSize nsSize = GTMNSRectSize(NSMakeRect(1, 1, 10, 5)); - STAssertEqualsWithAccuracy(nsSize.width, (CGFloat)10.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(nsSize.height, (CGFloat)5.0, (CGFloat)0.01, nil); + XCTAssertEqualWithAccuracy(nsSize.width, 10.0, 0.01); + XCTAssertEqualWithAccuracy(nsSize.height, 5.0, 0.01); } - (void)testGTMNSRectOfSize { NSRect outRect = GTMNSRectOfSize(NSMakeSize(10, 5)); NSRect expectedRect = NSMakeRect(0, 0, 10, 5); - STAssertEquals(outRect, expectedRect, nil); + XCTAssertTrue(NSEqualRects(outRect, expectedRect)); } - (void)testGTMNSAlignRectangles { @@ -78,7 +78,7 @@ NSPoint expectedOrigin; GTMRectAlignment alignment; } TestData; - + TestData data[] = { { {1,2}, GTMRectAlignTop }, { {0,2}, GTMRectAlignTopLeft }, @@ -90,17 +90,17 @@ { {2,1}, GTMRectAlignRight }, { {1,1}, GTMRectAlignCenter }, }; - + NSRect rect1 = NSMakeRect(0, 0, 4, 4); NSRect rect2 = NSMakeRect(0, 0, 2, 2); - + NSRect expectedRect; expectedRect.size = NSMakeSize(2, 2); - + for (size_t i = 0; i < sizeof(data) / sizeof(TestData); i++) { expectedRect.origin = data[i].expectedOrigin; NSRect outRect = GTMNSAlignRectangles(rect2, rect1, data[i].alignment); - STAssertEquals(outRect, expectedRect, nil); + XCTAssertTrue(NSEqualRects(outRect, expectedRect)); } } @@ -120,24 +120,25 @@ { { 2.0, 2.0 }, { 2.0, 2.0 } }, { { 0.0, 10.0 }, { 0.0, 0.0 } } }; - + for (size_t i = 0; i < sizeof(tests) / sizeof(Test); ++i) { NSRect result = GTMNSScaleRectangleToSize(rect, tests[i].size_, GTMScaleProportionally); - STAssertEquals(result, GTMNSRectOfSize(tests[i].newSize_), @"failed on test %zd", i); + XCTAssertTrue(NSEqualRects(result, GTMNSRectOfSize(tests[i].newSize_)), + @"failed on test %zd", i); } - + NSRect result = GTMNSScaleRectangleToSize(NSZeroRect, tests[0].size_, GTMScaleProportionally); - STAssertEquals(result, NSZeroRect, nil); - + XCTAssertTrue(NSEqualRects(result, NSZeroRect)); + result = GTMNSScaleRectangleToSize(rect, tests[0].size_, GTMScaleToFit); - STAssertEquals(result, GTMNSRectOfSize(tests[0].size_), nil); - + XCTAssertTrue(NSEqualRects(result, GTMNSRectOfSize(tests[0].size_))); + result = GTMNSScaleRectangleToSize(rect, tests[0].size_, GTMScaleNone); - STAssertEquals(result, rect, nil); + XCTAssertTrue(NSEqualRects(result, rect)); } @@ -147,20 +148,20 @@ GTMScaling scaling; GTMRectAlignment alignment; } TestData; - + NSRect rect1 = NSMakeRect(0, 0, 4, 4); NSRect rect2 = NSMakeRect(0, 0, 2, 1); - + TestData data[] = { { NSMakeRect(2, 3, 2, 1), GTMScaleToFillProportionally, GTMRectAlignTopRight }, { NSMakeRect(0, 0, 4, 4), GTMScaleToFit, GTMRectAlignCenter }, { NSMakeRect(1, 1.5, 2, 1), GTMScaleNone, GTMRectAlignCenter }, { NSMakeRect(1, 0, 2, 1), GTMScaleProportionally, GTMRectAlignBottom }, }; - + for (size_t i = 0; i < sizeof(data) / sizeof(TestData); i++) { NSRect outRect = GTMNSScaleRectToRect(rect2, rect1, data[i].scaling, data[i].alignment); - STAssertEquals(outRect, data[i].expectedRect, nil); + XCTAssertTrue(NSEqualRects(outRect, data[i].expectedRect)); } } @@ -168,18 +169,17 @@ - (void)testGTMNSDistanceBetweenPoints { NSPoint pt1 = NSMakePoint(0, 0); NSPoint pt2 = NSMakePoint(3, 4); - STAssertEquals(GTMNSDistanceBetweenPoints(pt1, pt2), (CGFloat)5.0, nil); - STAssertEquals(GTMNSDistanceBetweenPoints(pt2, pt1), (CGFloat)5.0, nil); + XCTAssertEqualWithAccuracy(GTMNSDistanceBetweenPoints(pt1, pt2), 5.0, 0.01); + XCTAssertEqualWithAccuracy(GTMNSDistanceBetweenPoints(pt2, pt1), 5.0, 0.01); pt1 = NSMakePoint(1, 1); pt2 = NSMakePoint(1, 1); - STAssertEquals(GTMNSDistanceBetweenPoints(pt1, pt2), (CGFloat)0.0, nil); + XCTAssertEqualWithAccuracy(GTMNSDistanceBetweenPoints(pt1, pt2), 0.0, 0.01); } - (void)testGTMNSRectScaling { NSRect rect = NSMakeRect(1.0f, 2.0f, 5.0f, 10.0f); - NSRect rect2 = NSMakeRect((CGFloat)1.0, (CGFloat)2.0, (CGFloat)1.0, (CGFloat)12.0); - STAssertEquals(GTMNSRectScale(rect, (CGFloat)0.2, (CGFloat)1.2), - rect2, nil); + NSRect rect2 = NSMakeRect(1.0, 2.0, 1.0, 12.0); + XCTAssertTrue(NSEqualRects(GTMNSRectScale(rect, 0.2, 1.2), rect2)); } #endif // !GTM_IPHONE_SDK @@ -187,11 +187,11 @@ - (void)testGTMCGDistanceBetweenPoints { CGPoint pt1 = CGPointMake(0, 0); CGPoint pt2 = CGPointMake(3, 4); - STAssertEquals(GTMCGDistanceBetweenPoints(pt1, pt2), (CGFloat)5.0, nil); - STAssertEquals(GTMCGDistanceBetweenPoints(pt2, pt1), (CGFloat)5.0, nil); + XCTAssertEqualWithAccuracy(GTMCGDistanceBetweenPoints(pt1, pt2), 5.0, 0.01); + XCTAssertEqualWithAccuracy(GTMCGDistanceBetweenPoints(pt2, pt1), 5.0, 0.01); pt1 = CGPointMake(1, 1); pt2 = CGPointMake(1, 1); - STAssertEquals(GTMCGDistanceBetweenPoints(pt1, pt2), (CGFloat)0.0, nil); + XCTAssertEqualWithAccuracy(GTMCGDistanceBetweenPoints(pt1, pt2), 0.0, 0.01); } - (void)testGTMCGAlignRectangles { @@ -199,7 +199,7 @@ CGPoint expectedOrigin; GTMRectAlignment alignment; } TestData; - + TestData data[] = { { {1,2}, GTMRectAlignTop }, { {0,2}, GTMRectAlignTopLeft }, @@ -211,61 +211,60 @@ { {2,1}, GTMRectAlignRight }, { {1,1}, GTMRectAlignCenter }, }; - + CGRect rect1 = CGRectMake(0, 0, 4, 4); CGRect rect2 = CGRectMake(0, 0, 2, 2); - + CGRect expectedRect; expectedRect.size = CGSizeMake(2, 2); - + for (size_t i = 0; i < sizeof(data) / sizeof(TestData); i++) { expectedRect.origin = data[i].expectedOrigin; CGRect outRect = GTMCGAlignRectangles(rect2, rect1, data[i].alignment); - STAssertEquals(outRect, expectedRect, nil); + XCTAssertTrue(CGRectEqualToRect(outRect, expectedRect)); } } - (void)testGTMCGPointsOnRect { CGRect rect = CGRectMake(0, 0, 2, 2); - + CGPoint point = GTMCGMidMinX(rect); - STAssertEqualsWithAccuracy(point.y, (CGFloat)1.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(point.x, (CGFloat)0.0, (CGFloat)0.01, nil); - + XCTAssertEqualWithAccuracy(point.y, 1.0, 0.01); + XCTAssertEqualWithAccuracy(point.x, 0.0, 0.01); + point = GTMCGMidMaxX(rect); - STAssertEqualsWithAccuracy(point.y, (CGFloat)1.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(point.x, (CGFloat)2.0, (CGFloat)0.01, nil); - + XCTAssertEqualWithAccuracy(point.y, 1.0, 0.01); + XCTAssertEqualWithAccuracy(point.x, 2.0, 0.01); + point = GTMCGMidMaxY(rect); - STAssertEqualsWithAccuracy(point.y, (CGFloat)2.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(point.x, (CGFloat)1.0, (CGFloat)0.01, nil); - + XCTAssertEqualWithAccuracy(point.y, 2.0, 0.01); + XCTAssertEqualWithAccuracy(point.x, 1.0, 0.01); + point = GTMCGMidMinY(rect); - STAssertEqualsWithAccuracy(point.y, (CGFloat)0.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(point.x, (CGFloat)1.0, (CGFloat)0.01, nil); - + XCTAssertEqualWithAccuracy(point.y, 0.0, 0.01); + XCTAssertEqualWithAccuracy(point.x, 1.0, 0.01); + point = GTMCGCenter(rect); - STAssertEqualsWithAccuracy(point.y, (CGFloat)1.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(point.x, (CGFloat)1.0, (CGFloat)0.01, nil); + XCTAssertEqualWithAccuracy(point.y, 1.0, 0.01); + XCTAssertEqualWithAccuracy(point.x, 1.0, 0.01); } - (void)testGTMCGRectSize { CGSize cgSize = GTMCGRectSize(CGRectMake(1, 1, 10, 5)); - STAssertEqualsWithAccuracy(cgSize.width, (CGFloat)10.0, (CGFloat)0.01, nil); - STAssertEqualsWithAccuracy(cgSize.height, (CGFloat)5.0, (CGFloat)0.01, nil); + XCTAssertEqualWithAccuracy(cgSize.width, 10.0, 0.01); + XCTAssertEqualWithAccuracy(cgSize.height, 5.0, 0.01); } - (void)testGTMCGRectOfSize { CGRect outRect = GTMCGRectOfSize(CGSizeMake(10, 5)); CGRect expectedRect = CGRectMake(0, 0, 10, 5); - STAssertEquals(outRect, expectedRect, nil); + XCTAssertTrue(CGRectEqualToRect(outRect, expectedRect)); } - (void)testGTMCGRectScaling { CGRect rect = CGRectMake(1.0f, 2.0f, 5.0f, 10.0f); - CGRect rect2 = CGRectMake((CGFloat)1.0, (CGFloat)2.0, (CGFloat)1.0, (CGFloat)12.0); - STAssertEquals(GTMCGRectScale(rect, (CGFloat)0.2, (CGFloat)1.2), - rect2, nil); + CGRect rect2 = CGRectMake(1.0, 2.0, 1.0, 12.0); + XCTAssertTrue(CGRectEqualToRect(GTMCGRectScale(rect, 0.2, 1.2), rect2)); } - (void)testGTMCGScaleRectangleToSize { @@ -284,24 +283,25 @@ { { 2.0, 2.0 }, { 2.0, 2.0 } }, { { 0.0, 10.0 }, { 0.0, 0.0 } } }; - + for (size_t i = 0; i < sizeof(tests) / sizeof(Test); ++i) { CGRect result = GTMCGScaleRectangleToSize(rect, tests[i].size_, GTMScaleProportionally); - STAssertEquals(result, GTMCGRectOfSize(tests[i].newSize_), @"failed on test %zd", i); + XCTAssertTrue(CGRectEqualToRect(result, GTMCGRectOfSize(tests[i].newSize_)), + @"failed on test %zd", i); } - + CGRect result = GTMCGScaleRectangleToSize(CGRectZero, tests[0].size_, GTMScaleProportionally); - STAssertEquals(result, CGRectZero, nil); - + XCTAssertTrue(CGRectEqualToRect(result, CGRectZero)); + result = GTMCGScaleRectangleToSize(rect, tests[0].size_, GTMScaleToFit); - STAssertEquals(result, GTMCGRectOfSize(tests[0].size_), nil); - + XCTAssertTrue(CGRectEqualToRect(result, GTMCGRectOfSize(tests[0].size_))); + result = GTMCGScaleRectangleToSize(rect, tests[0].size_, GTMScaleNone); - STAssertEquals(result, rect, nil); + XCTAssertTrue(CGRectEqualToRect(result, rect)); } @end diff --git a/Foundation/GTMLightweightProxyTest.m b/Foundation/GTMLightweightProxyTest.m index 03a1979..cdf29b6 100644 --- a/Foundation/GTMLightweightProxyTest.m +++ b/Foundation/GTMLightweightProxyTest.m @@ -37,59 +37,59 @@ - (void)testInit { id proxy = [[[GTMLightweightProxy alloc] initWithRepresentedObject:self] autorelease]; - STAssertNotNil(proxy, nil); + XCTAssertNotNil(proxy); proxy = [[[GTMLightweightProxy alloc] init] autorelease]; - STAssertNotNil(proxy, nil); + XCTAssertNotNil(proxy); } - (void)testProxy { id proxy = [[[GTMLightweightProxy alloc] initWithRepresentedObject:self] autorelease]; - STAssertEqualObjects(self, [proxy representedObject], - @"Represented object setup failed"); + XCTAssertEqualObjects(self, [proxy representedObject], + @"Represented object setup failed"); // Check that it identifies itself as a proxy. - STAssertTrue([proxy isProxy], @"Should identify as a proxy"); + XCTAssertTrue([proxy isProxy], @"Should identify as a proxy"); // Check that it passes class requests on - STAssertTrue([proxy isMemberOfClass:[self class]], - @"Should pass class requests through"); + XCTAssertTrue([proxy isMemberOfClass:[self class]], + @"Should pass class requests through"); // Check that it claims to respond to its selectors. - STAssertTrue([proxy respondsToSelector:@selector(initWithRepresentedObject:)], - @"Claims not to respond to initWithRepresentedObject:"); - STAssertTrue([proxy respondsToSelector:@selector(representedObject)], - @"Claims not to respond to representedObject:"); - STAssertTrue([proxy respondsToSelector:@selector(setRepresentedObject:)], - @"Claims not to respond to setRepresentedObject:"); + XCTAssertTrue([proxy respondsToSelector:@selector(initWithRepresentedObject:)], + @"Claims not to respond to initWithRepresentedObject:"); + XCTAssertTrue([proxy respondsToSelector:@selector(representedObject)], + @"Claims not to respond to representedObject:"); + XCTAssertTrue([proxy respondsToSelector:@selector(setRepresentedObject:)], + @"Claims not to respond to setRepresentedObject:"); // Check that it responds to its represented object's selectors - STAssertTrue([proxy respondsToSelector:@selector(returnYes)], - @"Claims not to respond to returnYes"); + XCTAssertTrue([proxy respondsToSelector:@selector(returnYes)], + @"Claims not to respond to returnYes"); // ... but not to made up selectors. #if !(__IPHONE_OS_VERSION_MIN_REQUIRED == __IPHONE_3_2 || __IPHONE_OS_VERSION_MIN_REQUIRED == __IPHONE_4_0) // Exceptions thrown by - (void)doesNotRecognizeSelector:(SEL)aSelector // does not get caught on iOS 3.2 and greater. // http://openradar.appspot.com/radar?id=420401 - STAssertThrows([proxy someMadeUpMethod], - @"Calling a bogus method should throw"); + XCTAssertThrows([proxy someMadeUpMethod], + @"Calling a bogus method should throw"); #endif // Check that callthrough works. - STAssertTrue([proxy returnYes], - @"Calling through to the represented object failed"); + XCTAssertTrue([proxy returnYes], + @"Calling through to the represented object failed"); // Check that nilling out the represented object works. [proxy setRepresentedObject:nil]; - STAssertTrue([proxy respondsToSelector:@selector(setRepresentedObject:)], - @"Claims not to respond to setRepresentedObject: after nilling" - @" out represented object"); - STAssertFalse([proxy respondsToSelector:@selector(returnYes)], - @"Claims to respond to returnYes after nilling out represented" - @" object"); + XCTAssertTrue([proxy respondsToSelector:@selector(setRepresentedObject:)], + @"Claims not to respond to setRepresentedObject: after nilling" + @" out represented object"); + XCTAssertFalse([proxy respondsToSelector:@selector(returnYes)], + @"Claims to respond to returnYes after nilling out represented" + @" object"); // Calling through once the represented object is nil should fail silently - STAssertNoThrow([proxy returnYes], - @"Calling through without a represented object should fail" - @" silently"); + XCTAssertNoThrow([proxy returnYes], + @"Calling through without a represented object should fail" + @" silently"); // ... even when they are made up. #if !(__IPHONE_OS_VERSION_MIN_REQUIRED == __IPHONE_3_2 || __IPHONE_OS_VERSION_MIN_REQUIRED == __IPHONE_4_0) @@ -97,8 +97,8 @@ // does not get caught on iOS 3.2 and greater. // http://openradar.appspot.com/radar?id=420401 - STAssertNoThrow([proxy someMadeUpMethod], - @"Calling a bogus method on a nilled proxy should not throw"); + XCTAssertNoThrow([proxy someMadeUpMethod], + @"Calling a bogus method on a nilled proxy should not throw"); #endif } diff --git a/Foundation/GTMLogger+ASLTest.m b/Foundation/GTMLogger+ASLTest.m index 2756bfc..db85d70 100644 --- a/Foundation/GTMLogger+ASLTest.m +++ b/Foundation/GTMLogger+ASLTest.m @@ -57,10 +57,10 @@ static NSMutableArray *gDummyLog; // weak - (void)testCreation { GTMLogger *aslLogger = [GTMLogger standardLoggerWithASL]; - STAssertNotNil(aslLogger, nil); + XCTAssertNotNil(aslLogger); GTMLogASLWriter *writer = [GTMLogASLWriter aslWriter]; - STAssertNotNil(writer, nil); + XCTAssertNotNil(writer); } - (void)testLogWriter { @@ -71,8 +71,8 @@ static NSMutableArray *gDummyLog; // weak autorelease]; - STAssertNotNil(writer, nil); - STAssertEquals([gDummyLog count], (NSUInteger)0, nil); + XCTAssertNotNil(writer); + XCTAssertEqual([gDummyLog count], (NSUInteger)0); // Log some messages [writer logMessage:@"unknown" level:kGTMLoggerLevelUnknown]; @@ -93,7 +93,7 @@ static NSMutableArray *gDummyLog; // weak @"-assert-1", nil]; - STAssertEqualObjects(gDummyLog, expected, nil); + XCTAssertEqualObjects(gDummyLog, expected); [gDummyLog removeAllObjects]; // Same test with facility @@ -102,8 +102,8 @@ static NSMutableArray *gDummyLog; // weak facility:@"testfac"] autorelease]; - STAssertNotNil(writer, nil); - STAssertEquals([gDummyLog count], (NSUInteger)0, nil); + XCTAssertNotNil(writer); + XCTAssertEqual([gDummyLog count], (NSUInteger)0); [writer logMessage:@"unknown" level:kGTMLoggerLevelUnknown]; [writer logMessage:@"debug" level:kGTMLoggerLevelDebug]; @@ -117,14 +117,14 @@ static NSMutableArray *gDummyLog; // weak @"testfac-error-3", @"testfac-assert-1", nil]; - STAssertEqualObjects(gDummyLog, expected, nil); + XCTAssertEqualObjects(gDummyLog, expected); gDummyLog = nil; } - (void)testASLClient { GTMLoggerASLClient *client = [[GTMLoggerASLClient alloc] init]; - STAssertNotNil(client, nil); + XCTAssertNotNil(client); [client release]; } diff --git a/Foundation/GTMLogger.m b/Foundation/GTMLogger.m index 3ace20f..e6b2ba1 100644 --- a/Foundation/GTMLogger.m +++ b/Foundation/GTMLogger.m @@ -367,7 +367,7 @@ static GTMLogger *gSharedLogger = nil; - (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level { @synchronized(self) { id<GTMLogWriter> child = nil; - GTM_FOREACH_OBJECT(child, self) { + for (child in self) { if ([child conformsToProtocol:@protocol(GTMLogWriter)]) [child logMessage:msg level:level]; } diff --git a/Foundation/GTMLoggerRingBufferWriterTest.m b/Foundation/GTMLoggerRingBufferWriterTest.m index 1c5d72b..73cc306 100644 --- a/Foundation/GTMLoggerRingBufferWriterTest.m +++ b/Foundation/GTMLoggerRingBufferWriterTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -19,7 +19,6 @@ #import "GTMSenTestCase.h" #import "GTMLoggerRingBufferWriter.h" #import "GTMLogger.h" -#import "GTMUnitTestDevLog.h" // -------------------------------------------------- // CountingWriter keeps a count of the number of times it has been @@ -87,16 +86,16 @@ line:(int)line { NSArray *loggedContents = [writer loggedContents]; - STAssertEquals([expected count], [loggedContents count], + XCTAssertEqual([expected count], [loggedContents count], @"count mismatch from line %d", line); for (unsigned int i = 0; i < [expected count]; i++) { - STAssertEqualObjects([expected objectAtIndex:i], - [loggedContents objectAtIndex:i], - @"logging mistmatch at index %d from line %d", - i, line); + XCTAssertEqualObjects([expected objectAtIndex:i], + [loggedContents objectAtIndex:i], + @"logging mistmatch at index %d from line %d", + i, line); } - + } // compareWithExpectedLogging @@ -118,24 +117,24 @@ GTMLoggerRingBufferWriter *writer = [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:32 writer:countingWriter_]; - STAssertEquals([writer capacity], (NSUInteger)32, nil); - STAssertTrue([writer writer] == countingWriter_, nil); - STAssertEquals([writer count], (NSUInteger)0, nil); - STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil); - STAssertEquals([writer totalLogged], (NSUInteger)0, nil); + XCTAssertEqual([writer capacity], (NSUInteger)32); + XCTAssertTrue([writer writer] == countingWriter_); + XCTAssertEqual([writer count], (NSUInteger)0); + XCTAssertEqual([writer droppedLogCount], (NSUInteger)0); + XCTAssertEqual([writer totalLogged], (NSUInteger)0); // Try with invalid arguments. Should always get nil back. writer = [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:0 writer:countingWriter_]; - STAssertNil(writer, nil); + XCTAssertNil(writer); writer = [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:32 writer:nil]; - STAssertNil(writer, nil); + XCTAssertNil(writer); writer = [[GTMLoggerRingBufferWriter alloc] init]; - STAssertNil(writer, nil); + XCTAssertNil(writer); } // testCreation @@ -145,31 +144,31 @@ [GTMLoggerRingBufferWriter ringBufferWriterWithCapacity:4 writer:countingWriter_]; [logger_ setWriter:writer]; - + // Shouldn't do anything if there are no contents. [writer dumpContents]; - STAssertEquals([writer count], (NSUInteger)0, nil); - STAssertEquals([countingWriter_ count], (NSUInteger)0, nil); + XCTAssertEqual([writer count], (NSUInteger)0); + XCTAssertEqual([countingWriter_ count], (NSUInteger)0); // Log a single item. Make sure the counts are accurate. [logger_ logDebug:@"oop"]; - STAssertEquals([writer count], (NSUInteger)1, nil); - STAssertEquals([writer totalLogged], (NSUInteger)1, nil); - STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil); - STAssertEquals([countingWriter_ count], (NSUInteger)0, nil); + XCTAssertEqual([writer count], (NSUInteger)1); + XCTAssertEqual([writer totalLogged], (NSUInteger)1); + XCTAssertEqual([writer droppedLogCount], (NSUInteger)0); + XCTAssertEqual([countingWriter_ count], (NSUInteger)0); // Log a second item. Also make sure counts are accurate. [logger_ logDebug:@"ack"]; - STAssertEquals([writer count], (NSUInteger)2, nil); - STAssertEquals([writer totalLogged], (NSUInteger)2, nil); - STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil); - STAssertEquals([countingWriter_ count], (NSUInteger)0, nil); + XCTAssertEqual([writer count], (NSUInteger)2); + XCTAssertEqual([writer totalLogged], (NSUInteger)2); + XCTAssertEqual([writer droppedLogCount], (NSUInteger)0); + XCTAssertEqual([countingWriter_ count], (NSUInteger)0); // Print them, and make sure the countingWriter sees the right stuff. [writer dumpContents]; - STAssertEquals([countingWriter_ count], (NSUInteger)2, nil); - STAssertEquals([writer count], (NSUInteger)2, nil); // Should not be zeroed. - STAssertEquals([writer totalLogged], (NSUInteger)2, nil); + XCTAssertEqual([countingWriter_ count], (NSUInteger)2); + XCTAssertEqual([writer count], (NSUInteger)2); // Should not be zeroed. + XCTAssertEqual([writer totalLogged], (NSUInteger)2); [self compareWriter:countingWriter_ withExpectedLogging:[NSArray arrayWithObjects:@"oop",@"ack", nil] @@ -179,18 +178,18 @@ // Wipe the slates clean. [writer reset]; [countingWriter_ reset]; - STAssertEquals([writer count], (NSUInteger)0, nil); - STAssertEquals([writer totalLogged], (NSUInteger)0, nil); + XCTAssertEqual([writer count], (NSUInteger)0); + XCTAssertEqual([writer totalLogged], (NSUInteger)0); // An error log level should print the buffer and empty it. [logger_ logDebug:@"oop"]; [logger_ logInfo:@"ack"]; - STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil); - STAssertEquals([writer totalLogged], (NSUInteger)2, nil); + XCTAssertEqual([writer droppedLogCount], (NSUInteger)0); + XCTAssertEqual([writer totalLogged], (NSUInteger)2); [logger_ logError:@"blargh"]; - STAssertEquals([countingWriter_ count], (NSUInteger)3, nil); - STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil); + XCTAssertEqual([countingWriter_ count], (NSUInteger)3); + XCTAssertEqual([writer droppedLogCount], (NSUInteger)0); [self compareWriter:countingWriter_ withExpectedLogging:[NSArray arrayWithObjects:@"oop", @"ack", @@ -204,13 +203,13 @@ [logger_ logDebug:@"oop"]; [logger_ logInfo:@"ack"]; [logger_ logDebug:@"blargh"]; - STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil); - STAssertEquals([writer count], (NSUInteger)3, nil); - STAssertEquals([writer totalLogged], (NSUInteger)3, nil); + XCTAssertEqual([writer droppedLogCount], (NSUInteger)0); + XCTAssertEqual([writer count], (NSUInteger)3); + XCTAssertEqual([writer totalLogged], (NSUInteger)3); [logger_ logAssert:@"ouch"]; - STAssertEquals([countingWriter_ count], (NSUInteger)4, nil); - STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil); + XCTAssertEqual([countingWriter_ count], (NSUInteger)4); + XCTAssertEqual([writer droppedLogCount], (NSUInteger)0); [self compareWriter:countingWriter_ withExpectedLogging:[NSArray arrayWithObjects:@"oop", @"ack", @"blargh", @"ouch", nil] @@ -223,11 +222,11 @@ [logger_ logDebug:@"oop"]; [logger_ logDebug:@"blargh"]; [logger_ logDebug:@"flong"]; // Fills buffer - STAssertEquals([writer droppedLogCount], (NSUInteger)0, nil); - STAssertEquals([writer count], (NSUInteger)4, nil); + XCTAssertEqual([writer droppedLogCount], (NSUInteger)0); + XCTAssertEqual([writer count], (NSUInteger)4); [logger_ logAssert:@"ouch"]; // should drop "ack" - STAssertEquals([countingWriter_ count], (NSUInteger)4, nil); + XCTAssertEqual([countingWriter_ count], (NSUInteger)4); [self compareWriter:countingWriter_ withExpectedLogging:[NSArray arrayWithObjects:@"oop", @"blargh", @@ -242,11 +241,11 @@ [logger_ logDebug:@"blargh"]; [logger_ logDebug:@"flong"]; // Fills buffer [logger_ logDebug:@"bloogie"]; // should drop "ack" - STAssertEquals([writer droppedLogCount], (NSUInteger)1, nil); - STAssertEquals([writer count], (NSUInteger)4, nil); + XCTAssertEqual([writer droppedLogCount], (NSUInteger)1); + XCTAssertEqual([writer count], (NSUInteger)4); [logger_ logAssert:@"ouch"]; // should drop "oop" - STAssertEquals([countingWriter_ count], (NSUInteger)4, nil); + XCTAssertEqual([countingWriter_ count], (NSUInteger)4); [self compareWriter:countingWriter_ withExpectedLogging:[NSArray arrayWithObjects:@"blargh", @@ -264,22 +263,22 @@ [logger_ setWriter:writer]; [logger_ logInfo:@"ack"]; - STAssertEquals([countingWriter_ count], (NSUInteger)0, nil); - STAssertEquals([writer count], (NSUInteger)1, nil); + XCTAssertEqual([countingWriter_ count], (NSUInteger)0); + XCTAssertEqual([writer count], (NSUInteger)1); [writer dumpContents]; - STAssertEquals([countingWriter_ count], (NSUInteger)1, nil); + XCTAssertEqual([countingWriter_ count], (NSUInteger)1); [self compareWriter:countingWriter_ - withExpectedLogging:[NSArray arrayWithObjects:@"ack", nil] + withExpectedLogging:[NSArray arrayWithObject:@"ack"] line:__LINE__]; [logger_ logDebug:@"oop"]; // should drop "ack" - STAssertEquals([writer count], (NSUInteger)1, nil); - STAssertEquals([writer droppedLogCount], (NSUInteger)1, nil); + XCTAssertEqual([writer count], (NSUInteger)1); + XCTAssertEqual([writer droppedLogCount], (NSUInteger)1); [countingWriter_ reset]; [logger_ logError:@"snoogy"]; // should drop "oop" - STAssertEquals([countingWriter_ count], (NSUInteger)1, nil); + XCTAssertEqual([countingWriter_ count], (NSUInteger)1); [self compareWriter:countingWriter_ withExpectedLogging:[NSArray arrayWithObjects:@"snoogy", nil] @@ -289,7 +288,7 @@ -// Run 10 threads, all logging through the same logger. +// Run 10 threads, all logging through the same logger. static volatile NSUInteger gStoppedThreads = 0; // Total number that have stopped. @@ -343,15 +342,15 @@ static volatile NSUInteger gStoppedThreads = 0; // Total number that have stoppe } // Now make sure we get back what's expected. - STAssertEquals([writer count], kThreadCount, nil); - STAssertEquals([countingWriter_ count], (NSUInteger)0, nil); // Nothing should be logged - STAssertEquals([writer totalLogged], (NSUInteger)420, nil); + XCTAssertEqual([writer count], kThreadCount); + XCTAssertEqual([countingWriter_ count], (NSUInteger)0); // Nothing should be logged + XCTAssertEqual([writer totalLogged], (NSUInteger)420); [logger_ logError:@"bork"]; - STAssertEquals([countingWriter_ count], kCapacity, nil); - + XCTAssertEqual([countingWriter_ count], kCapacity); + NSArray *expected = [NSArray arrayWithObjects: - @"ack", @"ack", @"ack", @"ack", @"ack", + @"ack", @"ack", @"ack", @"ack", @"ack", @"ack", @"ack", @"ack", @"ack", @"bork", nil]; [self compareWriter:countingWriter_ diff --git a/Foundation/GTMLoggerTest.m b/Foundation/GTMLoggerTest.m index bea75b2..6ce60bd 100644 --- a/Foundation/GTMLoggerTest.m +++ b/Foundation/GTMLoggerTest.m @@ -112,22 +112,14 @@ - (void)setUp { path_ = [[NSTemporaryDirectory() stringByAppendingPathComponent: @"GTMLoggerUnitTest.log"] retain]; - STAssertNotNil(path_, nil); + XCTAssertNotNil(path_); // Make sure we're cleaned up from the last run -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - [[NSFileManager defaultManager] removeFileAtPath:path_ handler:nil]; -#else [[NSFileManager defaultManager] removeItemAtPath:path_ error:NULL]; -#endif } - (void)tearDown { - STAssertNotNil(path_, nil); -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - [[NSFileManager defaultManager] removeFileAtPath:path_ handler:nil]; -#else + XCTAssertNotNil(path_); [[NSFileManager defaultManager] removeItemAtPath:path_ error:NULL]; -#endif [path_ release]; path_ = nil; } @@ -138,58 +130,58 @@ logger1 = [GTMLogger sharedLogger]; logger2 = [GTMLogger sharedLogger]; - STAssertTrue(logger1 == logger2, nil); + XCTAssertTrue(logger1 == logger2); - STAssertNotNil([logger1 writer], nil); - STAssertNotNil([logger1 formatter], nil); - STAssertNotNil([logger1 filter], nil); + XCTAssertNotNil([logger1 writer]); + XCTAssertNotNil([logger1 formatter]); + XCTAssertNotNil([logger1 filter]); // Get a new instance; not the shared instance logger2 = [GTMLogger standardLogger]; - STAssertTrue(logger1 != logger2, nil); - STAssertNotNil([logger2 writer], nil); - STAssertNotNil([logger2 formatter], nil); - STAssertNotNil([logger2 filter], nil); + XCTAssertTrue(logger1 != logger2); + XCTAssertNotNil([logger2 writer]); + XCTAssertNotNil([logger2 formatter]); + XCTAssertNotNil([logger2 filter]); // Set the new instance to be the shared logger. [GTMLogger setSharedLogger:logger2]; - STAssertTrue(logger2 == [GTMLogger sharedLogger], nil); - STAssertTrue(logger1 != [GTMLogger sharedLogger], nil); + XCTAssertTrue(logger2 == [GTMLogger sharedLogger]); + XCTAssertTrue(logger1 != [GTMLogger sharedLogger]); // Set the shared logger to nil, which should reset it to a new "standard" // logger. [GTMLogger setSharedLogger:nil]; - STAssertNotNil([GTMLogger sharedLogger], nil); - STAssertTrue(logger2 != [GTMLogger sharedLogger], nil); - STAssertTrue(logger1 != [GTMLogger sharedLogger], nil); + XCTAssertNotNil([GTMLogger sharedLogger]); + XCTAssertTrue(logger2 != [GTMLogger sharedLogger]); + XCTAssertTrue(logger1 != [GTMLogger sharedLogger]); GTMLogger *logger = [GTMLogger logger]; - STAssertNotNil(logger, nil); + XCTAssertNotNil(logger); logger = [GTMLogger standardLoggerWithStderr]; - STAssertNotNil(logger, nil); + XCTAssertNotNil(logger); logger = [GTMLogger standardLoggerWithPath:path_]; - STAssertNotNil(logger, nil); + XCTAssertNotNil(logger); } - (void)testAccessors { GTMLogger *logger = [GTMLogger standardLogger]; - STAssertNotNil(logger, nil); + XCTAssertNotNil(logger); - STAssertNotNil([logger writer], nil); - STAssertNotNil([logger formatter], nil); - STAssertNotNil([logger filter], nil); + XCTAssertNotNil([logger writer]); + XCTAssertNotNil([logger formatter]); + XCTAssertNotNil([logger filter]); [logger setWriter:nil]; [logger setFormatter:nil]; [logger setFilter:nil]; // These attributes should NOT be nil. They should be set to their defaults. - STAssertNotNil([logger writer], nil); - STAssertNotNil([logger formatter], nil); - STAssertNotNil([logger filter], nil); + XCTAssertNotNil([logger writer]); + XCTAssertNotNil([logger formatter]); + XCTAssertNotNil([logger filter]); } - (void)testLogger { @@ -212,7 +204,7 @@ formatter:nil // basic formatter filter:filter]; - STAssertNotNil(logger, nil); + XCTAssertNotNil(logger); // Log a few messages to test with [logger logInfo:@"hi"]; @@ -222,22 +214,22 @@ // Makes sure the messages got logged NSArray *messages = [writer messages]; - STAssertNotNil(messages, nil); - STAssertEquals([messages count], (NSUInteger)4, nil); - STAssertEqualObjects([messages objectAtIndex:0], @"hi", nil); - STAssertEqualObjects([messages objectAtIndex:1], @"foo", nil); - STAssertEqualObjects([messages objectAtIndex:2], @"blah", nil); - STAssertEqualObjects([messages objectAtIndex:3], @"baz", nil); + XCTAssertNotNil(messages); + XCTAssertEqual([messages count], (NSUInteger)4); + XCTAssertEqualObjects([messages objectAtIndex:0], @"hi"); + XCTAssertEqualObjects([messages objectAtIndex:1], @"foo"); + XCTAssertEqualObjects([messages objectAtIndex:2], @"blah"); + XCTAssertEqualObjects([messages objectAtIndex:3], @"baz"); // Log a message that should be ignored, and make sure it did NOT get logged [logger logInfo:@"please ignore this"]; messages = [writer messages]; - STAssertNotNil(messages, nil); - STAssertEquals([messages count], (NSUInteger)4, nil); - STAssertEqualObjects([messages objectAtIndex:0], @"hi", nil); - STAssertEqualObjects([messages objectAtIndex:1], @"foo", nil); - STAssertEqualObjects([messages objectAtIndex:2], @"blah", nil); - STAssertEqualObjects([messages objectAtIndex:3], @"baz", nil); + XCTAssertNotNil(messages); + XCTAssertEqual([messages count], (NSUInteger)4); + XCTAssertEqualObjects([messages objectAtIndex:0], @"hi"); + XCTAssertEqualObjects([messages objectAtIndex:1], @"foo"); + XCTAssertEqualObjects([messages objectAtIndex:2], @"blah"); + XCTAssertEqualObjects([messages objectAtIndex:3], @"baz"); // Change the formatter to our "dumb formatter" id<GTMLogFormatter> formatter = [[[DumbFormatter alloc] init] autorelease]; @@ -245,14 +237,14 @@ [logger logInfo:@"bleh"]; messages = [writer messages]; - STAssertNotNil(messages, nil); - STAssertEquals([messages count], (NSUInteger)5, nil); // Message count should increase + XCTAssertNotNil(messages); + XCTAssertEqual([messages count], (NSUInteger)5); // Message count should increase // The previously logged messages should not change - STAssertEqualObjects([messages objectAtIndex:0], @"hi", nil); - STAssertEqualObjects([messages objectAtIndex:1], @"foo", nil); - STAssertEqualObjects([messages objectAtIndex:2], @"blah", nil); - STAssertEqualObjects([messages objectAtIndex:3], @"baz", nil); - STAssertEqualObjects([messages objectAtIndex:4], @"DUMB [2] bleh", nil); + XCTAssertEqualObjects([messages objectAtIndex:0], @"hi"); + XCTAssertEqualObjects([messages objectAtIndex:1], @"foo"); + XCTAssertEqualObjects([messages objectAtIndex:2], @"blah"); + XCTAssertEqualObjects([messages objectAtIndex:3], @"baz"); + XCTAssertEqualObjects([messages objectAtIndex:4], @"DUMB [2] bleh"); } - (void)testConvenienceMacros { @@ -267,10 +259,10 @@ // test to make sure the logged message does indeed contain the name of the // current function "testConvenienceMacros". GTMLoggerError(@"test ========================"); - STAssertEquals([[writer messages] count], (NSUInteger)1, nil); + XCTAssertEqual([[writer messages] count], (NSUInteger)1); NSRange rangeOfFuncName = [[[writer messages] objectAtIndex:0] rangeOfString:@"testConvenienceMacros"]; - STAssertTrue(rangeOfFuncName.location != NSNotFound, nil); + XCTAssertTrue(rangeOfFuncName.location != NSNotFound); [writer clear]; [[GTMLogger sharedLogger] setFormatter:nil]; @@ -281,19 +273,19 @@ GTMLoggerAssert(@"test %d", 4); NSArray *messages = [writer messages]; - STAssertNotNil(messages, nil); + XCTAssertNotNil(messages); #ifdef DEBUG - STAssertEquals([messages count], (NSUInteger)4, nil); - STAssertEqualObjects([messages objectAtIndex:0], @"test 1", nil); - STAssertEqualObjects([messages objectAtIndex:1], @"test 2", nil); - STAssertEqualObjects([messages objectAtIndex:2], @"test 3", nil); - STAssertEqualObjects([messages objectAtIndex:3], @"test 4", nil); + XCTAssertEqual([messages count], (NSUInteger)4); + XCTAssertEqualObjects([messages objectAtIndex:0], @"test 1"); + XCTAssertEqualObjects([messages objectAtIndex:1], @"test 2"); + XCTAssertEqualObjects([messages objectAtIndex:2], @"test 3"); + XCTAssertEqualObjects([messages objectAtIndex:3], @"test 4"); #else // In Release builds, only the Error and Assert messages will be logged - STAssertEquals([messages count], (NSUInteger)2, nil); - STAssertEqualObjects([messages objectAtIndex:0], @"test 3", nil); - STAssertEqualObjects([messages objectAtIndex:1], @"test 4", nil); + XCTAssertEqual([messages count], (NSUInteger)2); + XCTAssertEqualObjects([messages objectAtIndex:0], @"test 3"); + XCTAssertEqualObjects([messages objectAtIndex:1], @"test 4"); #endif } @@ -302,10 +294,10 @@ NSFileHandle *fh = nil; fh = [NSFileHandle fileHandleForWritingAtPath:path_]; - STAssertNil(fh, nil); + XCTAssertNil(fh); fh = [NSFileHandle fileHandleForLoggingAtPath:path_ mode:0644]; - STAssertNotNil(fh, nil); + XCTAssertNotNil(fh); [fh logMessage:@"test 0" level:kGTMLoggerLevelUnknown]; [fh logMessage:@"test 1" level:kGTMLoggerLevelDebug]; @@ -318,24 +310,24 @@ NSString *contents = [NSString stringWithContentsOfFile:path_ encoding:NSUTF8StringEncoding error:&err]; - STAssertNotNil(contents, @"Error loading log file: %@", err); - STAssertEqualObjects(@"test 0\ntest 1\ntest 2\ntest 3\ntest 4\n", contents, nil); + XCTAssertNotNil(contents, @"Error loading log file: %@", err); + XCTAssertEqualObjects(@"test 0\ntest 1\ntest 2\ntest 3\ntest 4\n", contents); } - (void)testLoggerAdapterWriter { ArrayWriter *writer = [[[ArrayWriter alloc] init] autorelease]; - STAssertNotNil(writer, nil); + XCTAssertNotNil(writer); GTMLogger *sublogger = [GTMLogger loggerWithWriter:writer formatter:nil filter:nil]; - STAssertNotNil(sublogger, nil); + XCTAssertNotNil(sublogger); GTMLogger *logger = [GTMLogger loggerWithWriter:sublogger formatter:nil filter:nil]; - STAssertNotNil(logger, nil); + XCTAssertNotNil(logger); // Log a few messages to test with [logger logInfo:@"hi"]; @@ -345,12 +337,12 @@ // Makes sure the messages got logged NSArray *messages = [writer messages]; - STAssertNotNil(messages, nil); - STAssertEquals([messages count], (NSUInteger)4, nil); - STAssertEqualObjects([messages objectAtIndex:0], @"hi", nil); - STAssertEqualObjects([messages objectAtIndex:1], @"foo", nil); - STAssertEqualObjects([messages objectAtIndex:2], @"blah", nil); - STAssertEqualObjects([messages objectAtIndex:3], @"assert", nil); + XCTAssertNotNil(messages); + XCTAssertEqual([messages count], (NSUInteger)4); + XCTAssertEqualObjects([messages objectAtIndex:0], @"hi"); + XCTAssertEqualObjects([messages objectAtIndex:1], @"foo"); + XCTAssertEqualObjects([messages objectAtIndex:2], @"blah"); + XCTAssertEqualObjects([messages objectAtIndex:3], @"assert"); } // Helper method to help testing GTMLogFormatters @@ -370,211 +362,177 @@ - (void)testFunctionPrettifier { GTMLogBasicFormatter *fmtr = [[[GTMLogBasicFormatter alloc] init] autorelease]; - STAssertNotNil(fmtr, nil); + XCTAssertNotNil(fmtr); // Nil, empty and whitespace - STAssertEqualObjects([fmtr prettyNameForFunc:nil], @"(unknown)", nil); - STAssertEqualObjects([fmtr prettyNameForFunc:@""], @"(unknown)", nil); - STAssertEqualObjects([fmtr prettyNameForFunc:@" \n\t"], @"(unknown)", nil); + XCTAssertEqualObjects([fmtr prettyNameForFunc:nil], @"(unknown)"); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@""], @"(unknown)"); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@" \n\t"], @"(unknown)"); // C99 __func__ - STAssertEqualObjects([fmtr prettyNameForFunc:@"main"], @"main()", nil); - STAssertEqualObjects([fmtr prettyNameForFunc:@"main"], @"main()", nil); - STAssertEqualObjects([fmtr prettyNameForFunc:@" main "], @"main()", nil); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@"main"], @"main()"); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@"main"], @"main()"); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@" main "], @"main()"); // GCC Obj-C __func__ and __PRETTY_FUNCTION__ - STAssertEqualObjects([fmtr prettyNameForFunc:@"+[Foo bar]"], @"+[Foo bar]", - nil); - STAssertEqualObjects([fmtr prettyNameForFunc:@" +[Foo bar] "], @"+[Foo bar]", - nil); - STAssertEqualObjects([fmtr prettyNameForFunc:@"-[Foo baz]"], @"-[Foo baz]", - nil); - STAssertEqualObjects([fmtr prettyNameForFunc:@" -[Foo baz] "], @"-[Foo baz]", - nil); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@"+[Foo bar]"], @"+[Foo bar]"); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@" +[Foo bar] "], @"+[Foo bar]"); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@"-[Foo baz]"], @"-[Foo baz]"); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@" -[Foo baz] "], @"-[Foo baz]"); // GCC C++ __PRETTY_FUNCTION__ - STAssertEqualObjects([fmtr prettyNameForFunc:@"void a::sub(int)"], - @"void a::sub(int)", nil); - STAssertEqualObjects([fmtr prettyNameForFunc:@" void a::sub(int) "], - @"void a::sub(int)", nil); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@"void a::sub(int)"], + @"void a::sub(int)"); + XCTAssertEqualObjects([fmtr prettyNameForFunc:@" void a::sub(int) "], + @"void a::sub(int)"); } - (void)testBasicFormatter { id<GTMLogFormatter> fmtr = [[[GTMLogBasicFormatter alloc] init] autorelease]; - STAssertNotNil(fmtr, nil); + XCTAssertNotNil(fmtr); NSString *msg = nil; msg = [self stringFromFormatter:fmtr level:kGTMLoggerLevelDebug format:@"test"]; - STAssertEqualObjects(msg, @"test", nil); + XCTAssertEqualObjects(msg, @"test"); msg = [self stringFromFormatter:fmtr level:kGTMLoggerLevelDebug format:@"test %d", 1]; - STAssertEqualObjects(msg, @"test 1", nil); + XCTAssertEqualObjects(msg, @"test 1"); msg = [self stringFromFormatter:fmtr level:kGTMLoggerLevelDebug format:@"test %@", @"foo"]; - STAssertEqualObjects(msg, @"test foo", nil); + XCTAssertEqualObjects(msg, @"test foo"); msg = [self stringFromFormatter:fmtr level:kGTMLoggerLevelDebug format:@""]; - STAssertEqualObjects(msg, @"", nil); + XCTAssertEqualObjects(msg, @""); msg = [self stringFromFormatter:fmtr level:kGTMLoggerLevelDebug format:@" "]; - STAssertEqualObjects(msg, @" ", nil); + XCTAssertEqualObjects(msg, @" "); } - (void)testStandardFormatter { id<GTMLogFormatter> fmtr = [[[GTMLogStandardFormatter alloc] init] autorelease]; - STAssertNotNil(fmtr, nil); - - NSString * kFormatBasePattern; -#if GTM_MACOS_SDK - // E.g. 2008-01-04 09:16:26.906 otest[5567/0xa07d0f60] [lvl=1] (no func) test - // E.g. 2009-10-26 22:26:25.086 otest-i386[53200/0xa0438500] [lvl=1] (no func) test - kFormatBasePattern = - @"[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3} ((otest)|(otest-i386)|(otest-x86_64)|(otest-ppc))\\[[0-9]+/0x[0-9a-f]+\\] \\[lvl=[0-3]\\] \\(unknown\\) "; -#else // GTM_MACOS_SDK - // E.g. 2008-01-04 09:16:26.906 otest[5567/0xa07d0f60] [lvl=1] (no func) test - // 2011-11-29 12:32:24.129 GTMiPhoneUnitTestingOCUnitTestRig[31540/0xa04dd540] [lvl=1] (unknown) test - kFormatBasePattern = - @"[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3} (GTMiPhoneTest|GTMiPhoneUnitTestingOCUnitTestRig)\\[[0-9]+/0x[0-9a-f]+\\] \\[lvl=[0-3]\\] \\(unknown\\) "; -#endif // GTM_MACOS_SDK + XCTAssertNotNil(fmtr); + + // E.g. 2008-01-04 09:16:26.906 xctest[5567/0xa07d0f60] [lvl=1] (no func) test + #define kFormatBasePattern @"[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3} %@\\[[0-9]+/0x[0-9a-f]+\\] \\[lvl=[0-3]\\] \\(unknown\\) %@" NSString *msg = nil; + NSString *executableName = [[[NSBundle mainBundle] executablePath] lastPathComponent]; msg = [self stringFromFormatter:fmtr level:kGTMLoggerLevelDebug format:@"test"]; - STAssertTrue([msg gtm_matchesPattern:[kFormatBasePattern stringByAppendingString:@"test"]], - @"msg: %@", msg); + NSString *pattern = [NSString stringWithFormat:kFormatBasePattern, executableName, @"test"]; + XCTAssertTrue([msg gtm_matchesPattern:pattern], @"msg: %@", msg); msg = [self stringFromFormatter:fmtr level:kGTMLoggerLevelError format:@"test %d", 1]; - STAssertTrue([msg gtm_matchesPattern:[kFormatBasePattern stringByAppendingString:@"test 1"]], - @"msg: %@", msg); - + pattern = [NSString stringWithFormat:kFormatBasePattern, executableName, @"test 1"]; + XCTAssertTrue([msg gtm_matchesPattern:pattern], @"msg: %@", msg); msg = [self stringFromFormatter:fmtr level:kGTMLoggerLevelInfo format:@"test %@", @"hi"]; - STAssertTrue([msg gtm_matchesPattern:[kFormatBasePattern stringByAppendingString:@"test hi"]], - @"msg: %@", msg); + pattern = [NSString stringWithFormat:kFormatBasePattern, executableName, @"test hi"]; + XCTAssertTrue([msg gtm_matchesPattern:pattern], @"msg: %@", msg); msg = [self stringFromFormatter:fmtr level:kGTMLoggerLevelUnknown format:@"test"]; - STAssertTrue([msg gtm_matchesPattern:[kFormatBasePattern stringByAppendingString:@"test"]], - @"msg: %@", msg); + pattern = [NSString stringWithFormat:kFormatBasePattern, executableName, @"test"]; + XCTAssertTrue([msg gtm_matchesPattern:pattern], @"msg: %@", msg); } - (void)testNoFilter { id<GTMLogFilter> filter = [[[GTMLogNoFilter alloc] init] autorelease]; - STAssertNotNil(filter, nil); - - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelUnknown], nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelDebug], nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelInfo], nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelError], nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelAssert], nil); - STAssertTrue([filter filterAllowsMessage:@"" level:kGTMLoggerLevelDebug], nil); - STAssertTrue([filter filterAllowsMessage:nil level:kGTMLoggerLevelDebug], nil); + XCTAssertNotNil(filter); + + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelUnknown]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelDebug]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelInfo]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelError]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelAssert]); + XCTAssertTrue([filter filterAllowsMessage:@"" level:kGTMLoggerLevelDebug]); + XCTAssertTrue([filter filterAllowsMessage:nil level:kGTMLoggerLevelDebug]); } - (void)testMinimumFilter { id<GTMLogFilter> filter = [[[GTMLogMininumLevelFilter alloc] initWithMinimumLevel:kGTMLoggerLevelInfo] autorelease]; - STAssertNotNil(filter, nil); - STAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelUnknown], - nil); - STAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelDebug], - nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelInfo], - nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelError], - nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelAssert], - nil); + XCTAssertNotNil(filter); + XCTAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelUnknown]); + XCTAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelDebug]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelInfo]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelError]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelAssert]); filter = [[[GTMLogMininumLevelFilter alloc] initWithMinimumLevel:kGTMLoggerLevelDebug] autorelease]; - STAssertNotNil(filter, nil); - STAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelUnknown], - nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelDebug], - nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelInfo], - nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelError], - nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelAssert], - nil); + XCTAssertNotNil(filter); + XCTAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelUnknown]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelDebug]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelInfo]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelError]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelAssert]); // Cannot exceed min/max levels filter filter = [[[GTMLogMininumLevelFilter alloc] initWithMinimumLevel:kGTMLoggerLevelAssert + 1] autorelease]; - STAssertNil(filter, nil); + XCTAssertNil(filter); filter = [[[GTMLogMininumLevelFilter alloc] initWithMinimumLevel:kGTMLoggerLevelUnknown - 1] autorelease]; - STAssertNil(filter, nil); + XCTAssertNil(filter); } - (void)testMaximumFilter { id<GTMLogFilter> filter = [[[GTMLogMaximumLevelFilter alloc] initWithMaximumLevel:kGTMLoggerLevelInfo] autorelease]; - STAssertNotNil(filter, nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelUnknown], - nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelDebug], - nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelInfo], - nil); - STAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelError], - nil); - STAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelAssert], - nil); + XCTAssertNotNil(filter); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelUnknown]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelDebug]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelInfo]); + XCTAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelError]); + XCTAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelAssert]); filter = [[[GTMLogMaximumLevelFilter alloc] initWithMaximumLevel:kGTMLoggerLevelDebug] autorelease]; - STAssertNotNil(filter, nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelUnknown], - nil); - STAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelDebug], - nil); - STAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelInfo], - nil); - STAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelError], - nil); - STAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelAssert], - nil); + XCTAssertNotNil(filter); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelUnknown]); + XCTAssertTrue([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelDebug]); + XCTAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelInfo]); + XCTAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelError]); + XCTAssertFalse([filter filterAllowsMessage:@"hi" level:kGTMLoggerLevelAssert]); // Cannot exceed min/max levels filter filter = [[[GTMLogMaximumLevelFilter alloc] initWithMaximumLevel:kGTMLoggerLevelAssert + 1] autorelease]; - STAssertNil(filter, nil); + XCTAssertNil(filter); filter = [[[GTMLogMaximumLevelFilter alloc] initWithMaximumLevel:kGTMLoggerLevelUnknown - 1] autorelease]; - STAssertNil(filter, nil); + XCTAssertNil(filter); } - (void)testFileHandleCreation { NSFileHandle *fh = nil; fh = [NSFileHandle fileHandleForLoggingAtPath:nil mode:0644]; - STAssertNil(fh, nil); + XCTAssertNil(fh); fh = [NSFileHandle fileHandleForLoggingAtPath:path_ mode:0644]; - STAssertNotNil(fh, nil); + XCTAssertNotNil(fh); [fh logMessage:@"test 1" level:kGTMLoggerLevelInfo]; [fh logMessage:@"test 2" level:kGTMLoggerLevelInfo]; @@ -583,7 +541,7 @@ // Re-open file and make sure our log messages get appended fh = [NSFileHandle fileHandleForLoggingAtPath:path_ mode:0644]; - STAssertNotNil(fh, nil); + XCTAssertNotNil(fh); [fh logMessage:@"test 4" level:kGTMLoggerLevelInfo]; [fh logMessage:@"test 5" level:kGTMLoggerLevelInfo]; @@ -594,8 +552,8 @@ NSString *contents = [NSString stringWithContentsOfFile:path_ encoding:NSUTF8StringEncoding error:&err]; - STAssertNotNil(contents, @"Error loading log file: %@", err); - STAssertEqualObjects(@"test 1\ntest 2\ntest 3\ntest 4\ntest 5\ntest 6\n", contents, nil); + XCTAssertNotNil(contents, @"Error loading log file: %@", err); + XCTAssertEqualObjects(@"test 1\ntest 2\ntest 3\ntest 4\ntest 5\ntest 6\n", contents); } @end diff --git a/Foundation/GTMNSAppleEvent+HandlerTest.applescript b/Foundation/GTMNSAppleEvent+HandlerTest.applescript deleted file mode 100644 index 377d733..0000000 --- a/Foundation/GTMNSAppleEvent+HandlerTest.applescript +++ /dev/null @@ -1,60 +0,0 @@ --- --- Copyright 2008 Google Inc. --- --- Licensed under the Apache License, Version 2.0 (the "License"); you may not --- use this file except in compliance with the License. You may obtain a copy --- of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT --- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the --- License for the specific language governing permissions and limitations under --- the License. --- - -script parentTestScript - property parentTestScriptProperty : 6 - on parentTestScriptFunc() - return "parent" - end parentTestScriptFunc -end script - -script testScript - property parent : parentTestScript - property testScriptProperty : 5 - on testScriptFunc() - return "child" - end testScriptFunc - on open foo - end open -end script - -property foo : 1 - -on test() -end test - -on testReturnOne() - return 1 -end testReturnOne - -on testReturnParam(param) - return param -end testReturnParam - -on testAddParams(param1, param2) - return param1 + param2 -end testAddParams - -on testAdd of a onto b given otherValue:d - return a + b + d -end testAdd - -on testGetScript() - return testScript -end testGetScript - -on print -end print diff --git a/Foundation/GTMNSAppleEventDescriptor+Foundation.h b/Foundation/GTMNSAppleEventDescriptor+Foundation.h deleted file mode 100644 index 8e62bcc..0000000 --- a/Foundation/GTMNSAppleEventDescriptor+Foundation.h +++ /dev/null @@ -1,102 +0,0 @@ -// -// GTMNSAppleEventDescriptor+Foundation.h -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> -#import "GTMDefines.h" -#import "GTMFourCharCode.h" - -// A category for dealing with NSAppleEventDescriptors and NSArrays. -@interface NSAppleEventDescriptor (GTMAppleEventDescriptorArrayAdditions) -// Used to register the types you know how to convert into -// NSAppleEventDescriptors. -// See examples in GTMNSAppleEventDescriptor+Foundation. -// Args: -// selector - selector to call for any of the types in |types| -// -(NSAppleEventDesc *)selector_name; -// types - an std c array of types of length |count| -// count - number of types in |types| -+ (void)gtm_registerSelector:(SEL)selector - forTypes:(DescType*)types - count:(NSUInteger)count; - -// Returns an NSObject for any NSAppleEventDescriptor -// Uses types registerd by registerSelector:forTypes:count: to determine -// what type of object to create. If it doesn't know a type, it attempts -// to return [self stringValue]. -- (id)gtm_objectValue; - -// Return an NSArray for an AEList -// Returns nil on failure. -- (NSArray*)gtm_arrayValue; - -// Return an NSDictionary for an AERecord -// Returns nil on failure. -- (NSDictionary*)gtm_dictionaryValue; - -// Return an NSNull for a desc of typeNull -// Returns nil on failure. -- (NSNull*)gtm_nullValue; - -// Return a NSAppleEventDescriptor for a double value. -+ (NSAppleEventDescriptor*)gtm_descriptorWithDouble:(double)real; - -// Return a NSAppleEventDescriptor for a float value. -+ (NSAppleEventDescriptor*)gtm_descriptorWithFloat:(float)real; - -// Return a NSAppleEventDescriptor for a CGFloat value. -+ (NSAppleEventDescriptor*)gtm_descriptorWithCGFloat:(CGFloat)real; - -// Attempt to extract a double value. Returns NAN on error. -- (double)gtm_doubleValue; - -// Attempt to extract a float value. Returns NAN on error. -- (float)gtm_floatValue; - -// Attempt to extract a CGFloat value. Returns NAN on error. -- (CGFloat)gtm_cgFloatValue; - -// Attempt to extract a NSNumber. Returns nil on error. -- (NSNumber*)gtm_numberValue; - -// Attempt to return a GTMFourCharCode. Returns nil on error. -- (GTMFourCharCode*)gtm_fourCharCodeValue; -@end - -@interface NSObject (GTMAppleEventDescriptorObjectAdditions) -// A informal protocol that objects can override to return appleEventDescriptors -// for their type. The default is to return [self description] rolled up -// in an NSAppleEventDescriptor. Built in support for: -// NSArray, NSDictionary, NSNull, NSString, NSNumber and NSProcessInfo -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor; -@end - -@interface NSAppleEventDescriptor (GTMAppleEventDescriptorAdditions) -// Allows you to send events. -// Returns YES if send was successful. -- (BOOL)gtm_sendEventWithMode:(AESendMode)mode - timeOut:(NSTimeInterval)timeout - reply:(NSAppleEventDescriptor**)reply; -@end - -@interface GTMFourCharCode (GTMAppleEventDescriptorObjectAdditions) - -// if you call gtm_appleEventDescriptor on GTMFourCharCode it will be of -// type typeType. If you need something different (like typeProperty) this -// allows you to define the type you want. -- (NSAppleEventDescriptor*)gtm_appleEventDescriptorOfType:(DescType)type; -@end diff --git a/Foundation/GTMNSAppleEventDescriptor+Foundation.m b/Foundation/GTMNSAppleEventDescriptor+Foundation.m deleted file mode 100644 index f9828d4..0000000 --- a/Foundation/GTMNSAppleEventDescriptor+Foundation.m +++ /dev/null @@ -1,536 +0,0 @@ -// -// GTMNSAppleEventDescriptor+Foundation.m -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMNSAppleEventDescriptor+Foundation.h" -#import "GTMDebugSelectorValidation.h" -#import <Carbon/Carbon.h> // Needed Solely For keyASUserRecordFields - -// Map of types to selectors. -static NSMutableDictionary *gTypeMap = nil; - -@implementation NSAppleEventDescriptor (GTMAppleEventDescriptorArrayAdditions) - -+ (void)gtm_registerSelector:(SEL)selector - forTypes:(DescType*)types - count:(NSUInteger)count { - if (selector && types && count > 0) { -#if DEBUG - NSAppleEventDescriptor *desc - = [[[NSAppleEventDescriptor alloc] initListDescriptor] autorelease]; - GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(desc, - selector, - @encode(id), - NULL); -#endif - @synchronized(self) { - if (!gTypeMap) { - gTypeMap = [[NSMutableDictionary alloc] init]; - } - NSString *selString = NSStringFromSelector(selector); - for (NSUInteger i = 0; i < count; ++i) { - NSNumber *key = [NSNumber numberWithUnsignedInt:types[i]]; - NSString *exists = [gTypeMap objectForKey:key]; - if (exists) { - _GTMDevLog(@"%@ being replaced with %@ exists for type: %@", - exists, selString, key); - } - [gTypeMap setObject:selString forKey:key]; - } - } - } -} - -- (id)gtm_objectValue { - id value = nil; - - // Check our registered types to see if we have anything - if (gTypeMap) { - @synchronized(gTypeMap) { - DescType type = [self descriptorType]; - NSNumber *key = [NSNumber numberWithUnsignedInt:type]; - NSString *selectorString = [gTypeMap objectForKey:key]; - if (selectorString) { - SEL selector = NSSelectorFromString(selectorString); - value = [self performSelector:selector]; - } else { - value = [self stringValue]; - } - } - } - return value; -} - -- (NSArray*)gtm_arrayValue { - NSUInteger count = [self numberOfItems]; - NSAppleEventDescriptor *workingDesc = self; - if (count == 0) { - // Create a list to work with. - workingDesc = [self coerceToDescriptorType:typeAEList]; - count = [workingDesc numberOfItems]; - } - NSMutableArray *items = [NSMutableArray arrayWithCapacity:count]; - for (NSUInteger i = 1; i <= count; ++i) { - NSAppleEventDescriptor *desc = [workingDesc descriptorAtIndex:i]; - id value = [desc gtm_objectValue]; - if (!value) { - _GTMDevLog(@"Unknown type of descriptor %@", [desc description]); - return nil; - } - [items addObject:value]; - } - return items; -} - -- (NSDictionary*)gtm_dictionaryValue { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - NSAppleEventDescriptor *userRecord = [self descriptorForKeyword:keyASUserRecordFields]; - if (userRecord) { - NSArray *userItems = [userRecord gtm_arrayValue]; - NSString *key = nil; - NSString *item; - GTM_FOREACH_OBJECT(item, userItems) { - if (key) { - // Save the pair and reset our state - [dictionary setObject:item forKey:key]; - key = nil; - } else { - // Save it for the next pair - key = item; - } - } - if (key) { - _GTMDevLog(@"Got a key %@ with no value in %@", key, userItems); - return nil; - } - } else { - NSUInteger count = [self numberOfItems]; - for (NSUInteger i = 1; i <= count; ++i) { - AEKeyword key = [self keywordForDescriptorAtIndex:i]; - NSAppleEventDescriptor *desc = [self descriptorForKeyword:key]; - id value = [desc gtm_objectValue]; - if (!value) { - _GTMDevLog(@"Unknown type of descriptor %@", [desc description]); - return nil; - } - [dictionary setObject:value - forKey:[GTMFourCharCode fourCharCodeWithFourCharCode:key]]; - } - } - return dictionary; -} - -- (NSNull*)gtm_nullValue { - return [NSNull null]; -} - -+ (NSAppleEventDescriptor*)gtm_descriptorWithDouble:(double)real { - return [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE64BitFloatingPoint - bytes:&real - length:sizeof(real)]; -} - -+ (NSAppleEventDescriptor*)gtm_descriptorWithFloat:(float)real { - return [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE32BitFloatingPoint - bytes:&real - length:sizeof(real)]; -} - - -+ (NSAppleEventDescriptor*)gtm_descriptorWithCGFloat:(CGFloat)real { -#if CGFLOAT_IS_DOUBLE - return [self gtm_descriptorWithDouble:real]; -#else - return [self gtm_descriptorWithFloat:real]; -#endif -} - -- (double)gtm_doubleValue { - // Be careful modifying this code as Xcode 3.2.5 gcc 4.2.1 (5664) was - // generating bad code with a previous incarnation. - NSNumber *number = [self gtm_numberValue]; - if (number) { - return [number doubleValue]; - } - return NAN; -} - -- (float)gtm_floatValue { - NSNumber *number = [self gtm_numberValue]; - if (number) { - return [number floatValue]; - } - return NAN; -} - -- (CGFloat)gtm_cgFloatValue { -#if CGFLOAT_IS_DOUBLE - return [self gtm_doubleValue]; -#else - return [self gtm_floatValue]; -#endif -} - -- (NSNumber*)gtm_numberValue { - typedef struct { - DescType type; - SEL selector; - } TypeSelectorMap; - TypeSelectorMap typeSelectorMap[] = { - { typeFalse, @selector(numberWithBool:) }, - { typeTrue, @selector(numberWithBool:) }, - { typeBoolean, @selector(numberWithBool:) }, - { typeSInt16, @selector(numberWithShort:) }, - { typeSInt32, @selector(numberWithInt:) }, - { typeUInt32, @selector(numberWithUnsignedInt:) }, - { typeSInt64, @selector(numberWithLongLong:) }, - { typeIEEE32BitFloatingPoint, @selector(numberWithFloat:) }, - { typeIEEE64BitFloatingPoint, @selector(numberWithDouble:) } - }; - DescType type = [self descriptorType]; - SEL selector = nil; - for (size_t i = 0; i < sizeof(typeSelectorMap) / sizeof(TypeSelectorMap); ++i) { - if (type == typeSelectorMap[i].type) { - selector = typeSelectorMap[i].selector; - break; - } - } - NSAppleEventDescriptor *desc = self; - if (!selector) { - // COV_NF_START - Don't know how to force this in a unittest - _GTMDevLog(@"Didn't get a valid selector?"); - desc = [self coerceToDescriptorType:typeIEEE64BitFloatingPoint]; - selector = @selector(numberWithDouble:); - // COV_NF_END - } - NSData *descData = [desc data]; - const void *bytes = [descData bytes]; - if (!bytes) { - // COV_NF_START - Don't know how to force this in a unittest - _GTMDevLog(@"Unable to get bytes from %@", desc); - return nil; - // COV_NF_END - } - Class numberClass = [NSNumber class]; - NSMethodSignature *signature = [numberClass methodSignatureForSelector:selector]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:selector]; - [invocation setArgument:(void*)bytes atIndex:2]; - [invocation setTarget:numberClass]; - [invocation invoke]; - NSNumber *value = nil; - [invocation getReturnValue:&value]; - return value; -} - -- (GTMFourCharCode*)gtm_fourCharCodeValue { - return [GTMFourCharCode fourCharCodeWithFourCharCode:[self typeCodeValue]]; -} - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - return self; -} - -@end - -@implementation NSObject (GTMAppleEventDescriptorObjectAdditions) -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - return [NSAppleEventDescriptor descriptorWithString:[self description]]; -} -@end - -@implementation NSArray (GTMAppleEventDescriptorObjectAdditions) - -+ (void)load { - DescType types[] = { - typeAEList, - }; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_arrayValue) - forTypes:types - count:sizeof(types)/sizeof(DescType)]; - [pool drain]; -} - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - NSAppleEventDescriptor *desc = [NSAppleEventDescriptor listDescriptor]; - NSUInteger count = [self count]; - for (NSUInteger i = 1; i <= count; ++i) { - id item = [self objectAtIndex:i-1]; - NSAppleEventDescriptor *itemDesc = [item gtm_appleEventDescriptor]; - if (!itemDesc) { - _GTMDevLog(@"Unable to create Apple Event Descriptor for %@", [self description]); - return nil; - } - [desc insertDescriptor:itemDesc atIndex:i]; - } - return desc; -} -@end - -@implementation NSDictionary (GTMAppleEventDescriptorObjectAdditions) - -+ (void)load { - DescType types[] = { - typeAERecord, - }; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_dictionaryValue) - forTypes:types - count:sizeof(types)/sizeof(DescType)]; - [pool drain]; -} - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - Class keyClass = nil; - id key = nil; - GTM_FOREACH_KEY(key, self) { - if (!keyClass) { - if ([key isKindOfClass:[GTMFourCharCode class]]) { - keyClass = [GTMFourCharCode class]; - } else if ([key isKindOfClass:[NSString class]]) { - keyClass = [NSString class]; - } else { - _GTMDevLog(@"Keys must be of type NSString or GTMFourCharCode: %@", key); - return nil; - } - } - if (![key isKindOfClass:keyClass]) { - _GTMDevLog(@"Keys must be homogenous (first key was of type %@) " - "and of type NSString or GTMFourCharCode: %@", keyClass, key); - return nil; - } - } - NSAppleEventDescriptor *desc = [NSAppleEventDescriptor recordDescriptor]; - if ([keyClass isEqual:[NSString class]]) { - NSMutableArray *array = [NSMutableArray arrayWithCapacity:[self count] * 2]; - GTM_FOREACH_KEY(key, self) { - [array addObject:key]; - [array addObject:[self objectForKey:key]]; - } - NSAppleEventDescriptor *userRecord = [array gtm_appleEventDescriptor]; - if (!userRecord) { - return nil; - } - [desc setDescriptor:userRecord forKeyword:keyASUserRecordFields]; - } else { - GTM_FOREACH_KEY(key, self) { - id value = [self objectForKey:key]; - NSAppleEventDescriptor *valDesc = [value gtm_appleEventDescriptor]; - if (!valDesc) { - return nil; - } - [desc setDescriptor:valDesc forKeyword:[key fourCharCode]]; - } - } - return desc; -} - -@end - -@implementation NSNull (GTMAppleEventDescriptorObjectAdditions) -+ (void)load { - DescType types[] = { - typeNull - }; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_nullValue) - forTypes:types - count:sizeof(types)/sizeof(DescType)]; - [pool drain]; -} - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - return [NSAppleEventDescriptor nullDescriptor]; -} -@end - -@implementation NSString (GTMAppleEventDescriptorObjectAdditions) - -+ (void)load { - DescType types[] = { - typeUTF16ExternalRepresentation, - typeUnicodeText, - typeUTF8Text, - typeCString, - typePString, - typeChar, - typeIntlText }; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [NSAppleEventDescriptor gtm_registerSelector:@selector(stringValue) - forTypes:types - count:sizeof(types)/sizeof(DescType)]; - [pool drain]; -} - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - return [NSAppleEventDescriptor descriptorWithString:self]; -} -@end - -@implementation NSNumber (GTMAppleEventDescriptorObjectAdditions) - -+ (void)load { - DescType types[] = { - typeTrue, - typeFalse, - typeBoolean, - typeSInt16, - typeSInt32, - typeUInt32, - typeSInt64, - typeIEEE32BitFloatingPoint, - typeIEEE64BitFloatingPoint }; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_numberValue) - forTypes:types - count:sizeof(types)/sizeof(DescType)]; - [pool drain]; -} - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - const char *type = [self objCType]; - if (!type || strlen(type) != 1) return nil; - - DescType desiredType = typeNull; - NSAppleEventDescriptor *desc = nil; - switch (type[0]) { - // COV_NF_START - // I can't seem to convince objcType to return something of this type - case 'B': - desc = [NSAppleEventDescriptor descriptorWithBoolean:[self boolValue]]; - break; - // COV_NF_END - - case 'c': - case 'C': - case 's': - case 'S': - desiredType = typeSInt16; - break; - - case 'i': - case 'l': - desiredType = typeSInt32; - break; - - // COV_NF_START - // I can't seem to convince objcType to return something of this type - case 'I': - case 'L': - desiredType = typeUInt32; - break; - // COV_NF_END - - case 'q': - case 'Q': - desiredType = typeSInt64; - break; - - case 'f': - desiredType = typeIEEE32BitFloatingPoint; - break; - - case 'd': - default: - desiredType = typeIEEE64BitFloatingPoint; - break; - } - - if (!desc) { - desc = [NSAppleEventDescriptor gtm_descriptorWithDouble:[self doubleValue]]; - if (desc && desiredType != typeIEEE64BitFloatingPoint) { - desc = [desc coerceToDescriptorType:desiredType]; - } - } - return desc; -} - -@end - -@implementation NSProcessInfo (GTMAppleEventDescriptorObjectAdditions) - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - ProcessSerialNumber psn = { 0, kCurrentProcess }; - return [NSAppleEventDescriptor descriptorWithDescriptorType:typeProcessSerialNumber - bytes:&psn - length:sizeof(ProcessSerialNumber)]; -} - -@end - -@implementation GTMFourCharCode (GTMAppleEventDescriptorObjectAdditions) - -+ (void)load { - DescType types[] = { - typeType, - typeKeyword, - typeApplSignature, - typeEnumerated, - }; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_fourCharCodeValue) - forTypes:types - count:sizeof(types)/sizeof(DescType)]; - [pool drain]; -} - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - return [self gtm_appleEventDescriptorOfType:typeType]; -} - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptorOfType:(DescType)type { - FourCharCode code = [self fourCharCode]; - return [NSAppleEventDescriptor descriptorWithDescriptorType:type - bytes:&code - length:sizeof(code)]; -} -@end - -@implementation NSAppleEventDescriptor (GTMAppleEventDescriptorAdditions) - -- (BOOL)gtm_sendEventWithMode:(AESendMode)mode - timeOut:(NSTimeInterval)timeout - reply:(NSAppleEventDescriptor**)reply { - BOOL isGood = YES; - AppleEvent replyEvent = { typeNull, NULL }; - OSStatus err = AESendMessage([self aeDesc], &replyEvent, mode, timeout * 60); - NSAppleEventDescriptor *replyDesc - = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&replyEvent] autorelease]; - if (err) { - isGood = NO; - _GTMDevLog(@"Unable to send message: %@ %d", self, (int)err); - } - if (isGood) { - NSAppleEventDescriptor *errorDesc = [replyDesc descriptorForKeyword:keyErrorNumber]; - if (errorDesc && [errorDesc int32Value]) { - isGood = NO; - } - } - if (reply) { - *reply = replyDesc; - } - return isGood; -} - -@end diff --git a/Foundation/GTMNSAppleEventDescriptor+FoundationTest.m b/Foundation/GTMNSAppleEventDescriptor+FoundationTest.m deleted file mode 100644 index f346e99..0000000 --- a/Foundation/GTMNSAppleEventDescriptor+FoundationTest.m +++ /dev/null @@ -1,643 +0,0 @@ -// -// GTMNSAppleEventDescriptor+FoundationTest.m -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" -#import <Carbon/Carbon.h> -#import "GTMNSAppleEventDescriptor+Foundation.h" -#import "GTMFourCharCode.h" -#import "GTMUnitTestDevLog.h" - -@interface GTMNSAppleEventDescriptor_TestObject : NSObject -@end - -@implementation GTMNSAppleEventDescriptor_TestObject - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - return nil; -} - -@end - -@interface GTMNSAppleEventDescriptor_FoundationTest : GTMTestCase { - BOOL gotEvent_; -} -- (void)handleEvent:(NSAppleEventDescriptor*)event - withReply:(NSAppleEventDescriptor*)reply; -- (void)handleEvent:(NSAppleEventDescriptor*)event - withError:(NSAppleEventDescriptor*)reply; - -@end - -@implementation GTMNSAppleEventDescriptor_FoundationTest -- (void)testRegisterSelectorForTypesCount { - // Weird edge casey stuff. - // + (void)registerSelector:(SEL)selector - // forTypes:(DescType*)types count:(int)count - // is tested heavily by the other NSAppleEventDescriptor+foo categories. - DescType type; - [NSAppleEventDescriptor gtm_registerSelector:nil - forTypes:&type count:1]; - [NSAppleEventDescriptor gtm_registerSelector:@selector(initListDescriptor) - forTypes:nil count:1]; - [NSAppleEventDescriptor gtm_registerSelector:@selector(initListDescriptor) - forTypes:&type count:0]; - // Test the duplicate case - [NSAppleEventDescriptor gtm_registerSelector:@selector(initListDescriptor) - forTypes:&type count:1]; - [GTMUnitTestDevLog expectPattern:@"initListDescriptor being replaced with " - "initListDescriptor exists for type: [0-9]+"]; - [NSAppleEventDescriptor gtm_registerSelector:@selector(initListDescriptor) - forTypes:&type count:1]; -} - -- (void)testObjectValue { - // - (void)testObjectValue is tested heavily by the other - // NSAppleEventDescriptor+foo categories. - long data = 1; - // v@#f is just a bogus descriptor type that we don't recognize. - NSAppleEventDescriptor *desc - = [NSAppleEventDescriptor descriptorWithDescriptorType:'v@#f' - bytes:&data - length:sizeof(data)]; - id value = [desc gtm_objectValue]; - STAssertNil(value, nil); -} - -- (void)testAppleEventDescriptor { - // - (NSAppleEventDescriptor*)appleEventDescriptor is tested heavily by the - // other NSAppleEventDescriptor+foo categories. - NSAppleEventDescriptor *desc = [self gtm_appleEventDescriptor]; - STAssertNotNil(desc, nil); - STAssertEquals([desc descriptorType], (DescType)typeUnicodeText, nil); -} - -- (void)testDescriptorWithArrayAndArrayValue { - // Test empty array - NSAppleEventDescriptor *desc = [[NSArray array] gtm_appleEventDescriptor]; - STAssertNotNil(desc, nil); - STAssertEquals([desc numberOfItems], (NSInteger)0, nil); - - // Complex array - NSArray *array = [NSArray arrayWithObjects: - [NSNumber numberWithInt:4], - @"foo", - [NSNumber numberWithInt:2], - @"bar", - [NSArray arrayWithObjects: - @"bam", - [NSArray arrayWithObject:[NSNumber numberWithFloat:4.2f]], - nil], - nil]; - STAssertNotNil(array, nil); - desc = [array gtm_appleEventDescriptor]; - STAssertNotNil(desc, nil); - NSArray *array2 = [desc gtm_objectValue]; - STAssertNotNil(array2, nil); - NSArray *array3 = [desc gtm_arrayValue]; - STAssertNotNil(array3, nil); - STAssertTrue([array isEqualToArray:array2], - @"array: %@\narray2: %@\ndesc: %@", - [array description], [array2 description], [desc description]); - STAssertTrue([array2 isEqualToArray:array3], - @"array: %@\narray2: %@\ndesc: %@", - [array description], [array2 description], [desc description]); - - // Test a single object - array = [NSArray arrayWithObject:@"foo"]; - desc = [NSAppleEventDescriptor descriptorWithString:@"foo"]; - STAssertNotNil(desc, nil); - array2 = [desc gtm_arrayValue]; - STAssertTrue([array isEqualToArray:array2], - @"array: %@\narray2: %@\ndesc: %@", - [array description], [array2 description], [desc description]); - - // Something that doesn't know how to register itself. - GTMNSAppleEventDescriptor_TestObject *obj - = [[[GTMNSAppleEventDescriptor_TestObject alloc] init] autorelease]; - [GTMUnitTestDevLog expectPattern:@"Unable to create Apple Event Descriptor for .*"]; - desc = [[NSArray arrayWithObject:obj] gtm_appleEventDescriptor]; - STAssertNil(desc, @"Should be nil"); - - // A list containing something we don't know how to deal with - desc = [NSAppleEventDescriptor listDescriptor]; - NSAppleEventDescriptor *desc2 - = [NSAppleEventDescriptor descriptorWithDescriptorType:'@!@#' - bytes:&desc - length:sizeof(desc)]; - [GTMUnitTestDevLog expectPattern:@"Unknown type of descriptor " - "<NSAppleEventDescriptor: '@!@#'\\(\\$[0-9A-F]*\\$\\)>"]; - [desc insertDescriptor:desc2 atIndex:0]; - array = [desc gtm_objectValue]; - STAssertEquals([array count], (NSUInteger)0, @"Should have 0 items"); -} - -- (void)testDescriptorWithDictionaryAndDictionaryValue { - // Test empty dictionary - NSAppleEventDescriptor *desc - = [[NSDictionary dictionary] gtm_appleEventDescriptor]; - STAssertNotNil(desc, nil); - STAssertEquals([desc numberOfItems], (NSInteger)0, nil); - - // Complex dictionary - NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys: - @"fooobject", - @"fookey", - @"barobject", - @"barkey", - [NSDictionary dictionaryWithObjectsAndKeys: - @"january", - [GTMFourCharCode fourCharCodeWithFourCharCode:cJanuary], - @"february", - [GTMFourCharCode fourCharCodeWithFourCharCode:cFebruary], - nil], - @"dictkey", - nil]; - STAssertNotNil(dictionary, nil); - desc = [dictionary gtm_appleEventDescriptor]; - STAssertNotNil(desc, nil); - NSDictionary *dictionary2 = [desc gtm_objectValue]; - STAssertNotNil(dictionary2, nil); - NSDictionary *dictionary3 = [desc gtm_dictionaryValue]; - STAssertNotNil(dictionary3, nil); - STAssertEqualObjects(dictionary, dictionary2, - @"desc: %@", [desc description]); - STAssertEqualObjects(dictionary2, dictionary3, - @"desc: %@", [desc description]); - - // Something that doesn't know how to register itself. - GTMNSAppleEventDescriptor_TestObject *obj - = [[[GTMNSAppleEventDescriptor_TestObject alloc] init] autorelease]; - [GTMUnitTestDevLog expectPattern:@"Unable to create Apple Event Descriptor for .*"]; - desc = [[NSDictionary dictionaryWithObject:obj - forKey:@"foo"] gtm_appleEventDescriptor]; - STAssertNil(desc, @"Should be nil"); - - GTMFourCharCode *fcc = [GTMFourCharCode fourCharCodeWithFourCharCode:cJanuary]; - desc = [[NSDictionary dictionaryWithObject:obj - forKey:fcc] gtm_appleEventDescriptor]; - STAssertNil(desc, @"Should be nil"); - - // A list containing something we don't know how to deal with - desc = [NSAppleEventDescriptor recordDescriptor]; - NSAppleEventDescriptor *desc2 - = [NSAppleEventDescriptor descriptorWithDescriptorType:'@!@#' - bytes:&desc - length:sizeof(desc)]; - [desc setDescriptor:desc2 forKeyword:cJanuary]; - [GTMUnitTestDevLog expectPattern:@"Unknown type of descriptor " - "<NSAppleEventDescriptor: '@!@#'\\(\\$[0-9A-F]+\\$\\)>"]; - dictionary = [desc gtm_objectValue]; - STAssertEquals([dictionary count], (NSUInteger)0, @"Should have 0 items"); - - // A bad dictionary - dictionary = [NSDictionary dictionaryWithObjectsAndKeys: - @"foo", - [GTMFourCharCode fourCharCodeWithFourCharCode:'APPL'], - @"bam", - @"bar", - nil]; - STAssertNotNil(dictionary, nil); - // I cannot use expectString here to the exact string because interestingly - // dictionaries in 64 bit enumerate in a different order from dictionaries - // on 32 bit. This is the closest pattern I can match. - [GTMUnitTestDevLog expectPattern:@"Keys must be homogenous .*"]; - desc = [dictionary gtm_appleEventDescriptor]; - STAssertNil(desc, nil); - - // Another bad dictionary - dictionary = [NSDictionary dictionaryWithObjectsAndKeys: - @"foo", - [NSNumber numberWithInt:4], - @"bam", - @"bar", - nil]; - STAssertNotNil(dictionary, nil); - // I cannot use expectString here to the exact string because interestingly - // dictionaries in 64 bit enumerate in a different order from dictionaries - // on 32 bit. This is the closest pattern I can match. - [GTMUnitTestDevLog expectPattern:@"Keys must be .*"]; - desc = [dictionary gtm_appleEventDescriptor]; - STAssertNil(desc, nil); - - // A bad descriptor - desc = [NSAppleEventDescriptor recordDescriptor]; - STAssertNotNil(desc, @""); - NSArray *array = [NSArray arrayWithObjects:@"foo", @"bar", @"bam", nil]; - STAssertNotNil(array, @""); - NSAppleEventDescriptor *userRecord = [array gtm_appleEventDescriptor]; - STAssertNotNil(userRecord, @""); - [desc setDescriptor:userRecord forKeyword:keyASUserRecordFields]; - [GTMUnitTestDevLog expectPattern:@"Got a key bam with no value in \\(.*"]; - dictionary = [desc gtm_objectValue]; - STAssertNil(dictionary, @"Should be nil"); -} - -- (void)testDescriptorWithNull { - // Test Null - NSNull *null = [NSNull null]; - NSAppleEventDescriptor *desc = [null gtm_appleEventDescriptor]; - STAssertNotNil(desc, nil); - NSNull *null2 = [desc gtm_objectValue]; - STAssertNotNil(null2, nil); - NSNull *null3 = [desc gtm_nullValue]; - STAssertNotNil(null2, nil); - STAssertEqualObjects(null, null2, - @"null: %@\null2: %@\ndesc: %@", - [null description], [null2 description], - [desc description]); - STAssertEqualObjects(null, null3, - @"null: %@\null3: %@\ndesc: %@", - [null description], [null3 description], - [desc description]); -} - -- (void)testDescriptorWithString { - // Test empty String - NSAppleEventDescriptor *desc = [[NSString string] gtm_appleEventDescriptor]; - STAssertNotNil(desc, nil); - - // Test String - NSString *string = @"Ratatouille!"; - desc = [string gtm_appleEventDescriptor]; - STAssertNotNil(desc, nil); - NSString *string2 = [desc gtm_objectValue]; - STAssertNotNil(string2, nil); - STAssertEqualObjects(string, string2, - @"string: %@\nstring: %@\ndesc: %@", - [string description], [string2 description], [desc description]); - -} - -- (void)testDescriptorWithNumberAndNumberValue { - // There's really no good way to make this into a loop sadly due - // to me having to pass a pointer of bytes to NSInvocation as an argument. - // I want the compiler to convert my int to the appropriate type. - - NSNumber *original = [NSNumber numberWithBool:YES]; - STAssertNotNil(original, @"Value: YES"); - NSAppleEventDescriptor *desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: YES"); - id returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: YES"); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: YES"); - STAssertEqualObjects(original, returned, @"Value: YES"); - desc = [desc coerceToDescriptorType:typeBoolean]; - NSNumber *number = [desc gtm_numberValue]; - STAssertEqualObjects(number, original, @"Value: YES"); - - original = [NSNumber numberWithBool:NO]; - STAssertNotNil(original, @"Value: NO"); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: NO"); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: NO"); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: NO"); - STAssertEqualObjects(original, returned, @"Value: NO"); - - sranddev(); - double value = rand(); - - original = [NSNumber numberWithChar:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = rand(); - original = [NSNumber numberWithUnsignedChar:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = rand(); - original = [NSNumber numberWithShort:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = rand(); - original = [NSNumber numberWithUnsignedShort:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = rand(); - original = [NSNumber numberWithInt:(int)value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = rand(); - original = [NSNumber numberWithUnsignedInt:(unsigned int)value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = rand(); - original = [NSNumber numberWithLong:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = rand(); - original = [NSNumber numberWithUnsignedLong:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = rand(); - original = [NSNumber numberWithLongLong:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = rand(); - original = [NSNumber numberWithUnsignedLongLong:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - float floatA = rand(); - float floatB = rand(); - value = floatA / floatB; - original = [NSNumber numberWithFloat:(float)value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - double doubleA = rand(); - double doubleB = rand(); - value = doubleA / doubleB; - original = [NSNumber numberWithDouble:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = rand(); - original = [NSNumber numberWithBool:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = NAN; - original = [NSNumber numberWithDouble:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = INFINITY; - original = [NSNumber numberWithDouble:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = -0.0; - original = [NSNumber numberWithDouble:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); - - value = -INFINITY; - original = [NSNumber numberWithDouble:value]; - STAssertNotNil(original, @"Value: %g", value); - desc = [original gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Value: %g", value); - returned = [desc gtm_objectValue]; - STAssertNotNil(returned, @"Value: %g", value); - STAssertTrue([returned isKindOfClass:[NSNumber class]], @"Value: %g", value); - STAssertEqualObjects(original, returned, @"Value: %g", value); -} - -- (void)testDescriptorWithDoubleAndDoubleValue { - sranddev(); - for (int i = 0; i < 1000; ++i) { - double value1 = rand(); - double value2 = rand(); - double value = value1 / value2; - NSAppleEventDescriptor *desc - = [NSAppleEventDescriptor gtm_descriptorWithDouble:value]; - STAssertNotNil(desc, @"Value: %g", value); - double returnedValue = [desc gtm_doubleValue]; - STAssertEquals(value, returnedValue, @"Value: %g", value); - } - - double specialCases[] = { 0.0f, __DBL_MIN__, __DBL_EPSILON__, INFINITY, NAN }; - for (size_t i = 0; i < sizeof(specialCases) / sizeof(double); ++i) { - double value = specialCases[i]; - NSAppleEventDescriptor *desc - = [NSAppleEventDescriptor gtm_descriptorWithDouble:value]; - STAssertNotNil(desc, @"Value: %g", value); - double returnedValue = [desc gtm_doubleValue]; - STAssertEquals(value, returnedValue, @"Value: %g", value); - } -} - -- (void)testDescriptorWithFloatAndFloatValue { - sranddev(); - for (int i = 0; i < 1000; ++i) { - float value1 = rand(); - float value2 = rand(); - float value = value1 / value2; - NSAppleEventDescriptor *desc - = [NSAppleEventDescriptor gtm_descriptorWithFloat:value]; - STAssertNotNil(desc, @"Value: %f", value); - float returnedValue = [desc gtm_floatValue]; - STAssertEquals(value, returnedValue, @"Value: %f", value); - } - - float specialCases[] = { 0.0f, FLT_MIN, FLT_MAX, FLT_EPSILON, INFINITY, NAN }; - for (size_t i = 0; i < sizeof(specialCases) / sizeof(float); ++i) { - float value = specialCases[i]; - NSAppleEventDescriptor *desc - = [NSAppleEventDescriptor gtm_descriptorWithFloat:value]; - STAssertNotNil(desc, @"Value: %f", value); - float returnedValue = [desc gtm_floatValue]; - STAssertEquals(value, returnedValue, @"Value: %f", value); - } -} - -- (void)testDescriptorWithCGFloatAndCGFloatValue { - sranddev(); - for (int i = 0; i < 1000; ++i) { - CGFloat value1 = rand(); - CGFloat value2 = rand(); - CGFloat value = value1 / value2; - NSAppleEventDescriptor *desc - = [NSAppleEventDescriptor gtm_descriptorWithCGFloat:value]; - STAssertNotNil(desc, @"Value: %g", (double)value); - CGFloat returnedValue = [desc gtm_cgFloatValue]; - STAssertEquals(value, returnedValue, @"Value: %g", (double)value); - } - - CGFloat specialCases[] = { 0.0f, CGFLOAT_MIN, CGFLOAT_MAX, NAN }; - for (size_t i = 0; i < sizeof(specialCases) / sizeof(CGFloat); ++i) { - CGFloat value = specialCases[i]; - NSAppleEventDescriptor *desc - = [NSAppleEventDescriptor gtm_descriptorWithCGFloat:value]; - STAssertNotNil(desc, @"Value: %g", (double)value); - CGFloat returnedValue = [desc gtm_cgFloatValue]; - STAssertEquals(value, returnedValue, @"Value: %g", (double)value); - } -} - -- (void)testDescriptorWithGTMFourCharCode { - GTMFourCharCode *fcc = [GTMFourCharCode fourCharCodeWithFourCharCode:'APPL']; - STAssertNotNil(fcc, nil); - NSAppleEventDescriptor *desc = [fcc gtm_appleEventDescriptor]; - STAssertNotNil(desc, nil); - GTMFourCharCode *fcc2 = [desc gtm_objectValue]; - STAssertNotNil(fcc2, nil); - STAssertEqualObjects(fcc, fcc2, nil); - STAssertEquals([desc descriptorType], (DescType)typeType, nil); - desc = [fcc gtm_appleEventDescriptorOfType:typeKeyword]; - STAssertNotNil(desc, nil); - fcc2 = [desc gtm_objectValue]; - STAssertNotNil(fcc2, nil); - STAssertEqualObjects(fcc, fcc2, nil); - STAssertEquals([desc descriptorType], (DescType)typeKeyword, nil); -} - -- (void)testDescriptorWithDescriptor { - NSAppleEventDescriptor *desc - = [NSAppleEventDescriptor descriptorWithString:@"foo"]; - NSAppleEventDescriptor *desc2 = [desc gtm_appleEventDescriptor]; - STAssertEqualObjects(desc, desc2, nil); -} - -- (void)handleEvent:(NSAppleEventDescriptor*)event - withReply:(NSAppleEventDescriptor*)reply { - gotEvent_ = YES; - NSAppleEventDescriptor *answer = [NSAppleEventDescriptor descriptorWithInt32:1]; - [reply setDescriptor:answer forKeyword:keyDirectObject]; -} - -- (void)handleEvent:(NSAppleEventDescriptor*)event - withError:(NSAppleEventDescriptor*)error { - gotEvent_ = YES; - NSAppleEventDescriptor *answer = [NSAppleEventDescriptor descriptorWithInt32:1]; - [error setDescriptor:answer forKeyword:keyErrorNumber]; -} - -- (void)testSend { - const AEEventClass eventClass = 'Fooz'; - const AEEventID eventID = 'Ball'; - NSAppleEventManager *mgr = [NSAppleEventManager sharedAppleEventManager]; - [mgr setEventHandler:self - andSelector:@selector(handleEvent:withReply:) - forEventClass:eventClass - andEventID:'Ball']; - NSAppleEventDescriptor *currentProcess - = [[NSProcessInfo processInfo] gtm_appleEventDescriptor]; - NSAppleEventDescriptor *event - = [NSAppleEventDescriptor appleEventWithEventClass:eventClass - eventID:eventID - targetDescriptor:currentProcess - returnID:kAutoGenerateReturnID - transactionID:kAnyTransactionID]; - gotEvent_ = NO; - NSAppleEventDescriptor *reply; - BOOL goodEvent = [event gtm_sendEventWithMode:kAEWaitReply timeOut:60 reply:&reply]; - [mgr removeEventHandlerForEventClass:eventClass andEventID:eventID]; - STAssertTrue(goodEvent, @"bad event?"); - STAssertTrue(gotEvent_, @"Handler not called"); - NSAppleEventDescriptor *value = [reply descriptorForKeyword:keyDirectObject]; - STAssertEquals([value int32Value], (SInt32)1, @"didn't get reply"); - - - gotEvent_ = NO; - [GTMUnitTestDevLog expectString:@"Unable to send message: " - "<NSAppleEventDescriptor: 'Fooz'\\'Ball'{ }> -1708"]; - goodEvent = [event gtm_sendEventWithMode:kAEWaitReply timeOut:60 reply:&reply]; - STAssertFalse(goodEvent, @"good event?"); - STAssertFalse(gotEvent_, @"Handler called?"); - - [mgr setEventHandler:self - andSelector:@selector(handleEvent:withError:) - forEventClass:eventClass - andEventID:eventID]; - gotEvent_ = NO; - goodEvent = [event gtm_sendEventWithMode:kAEWaitReply timeOut:60 reply:&reply]; - STAssertFalse(goodEvent, @"good event?"); - STAssertTrue(gotEvent_, @"Handler not called?"); - [mgr removeEventHandlerForEventClass:eventClass andEventID:eventID]; -} - -@end diff --git a/Foundation/GTMNSAppleEventDescriptor+Handler.h b/Foundation/GTMNSAppleEventDescriptor+Handler.h deleted file mode 100644 index 29c9c1e..0000000 --- a/Foundation/GTMNSAppleEventDescriptor+Handler.h +++ /dev/null @@ -1,45 +0,0 @@ -// -// GTMNSAppleEventDescriptor+Handler.h -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> -#import "GTMDefines.h" - -@interface NSAppleEventDescriptor (GTMAppleEventDescriptorHandlerAdditions) -+ (id)gtm_descriptorWithPositionalHandler:(NSString*)handler - parametersArray:(NSArray*)params; -+ (id)gtm_descriptorWithPositionalHandler:(NSString*)handler - parametersDescriptor:(NSAppleEventDescriptor*)params; -+ (id)gtm_descriptorWithLabeledHandler:(NSString*)handler - labels:(AEKeyword*)labels - parameters:(id*)params - count:(NSUInteger)count; - -- (id)gtm_initWithPositionalHandler:(NSString*)handler - parametersArray:(NSArray*)params - NS_RETURNS_RETAINED NS_CONSUMES_SELF; - -- (id)gtm_initWithPositionalHandler:(NSString*)handler - parametersDescriptor:(NSAppleEventDescriptor*)params - NS_RETURNS_RETAINED NS_CONSUMES_SELF; - -- (id)gtm_initWithLabeledHandler:(NSString*)handler - labels:(AEKeyword*)labels - parameters:(id*)params - count:(NSUInteger)count - NS_RETURNS_RETAINED NS_CONSUMES_SELF; -@end diff --git a/Foundation/GTMNSAppleEventDescriptor+Handler.m b/Foundation/GTMNSAppleEventDescriptor+Handler.m deleted file mode 100644 index 76b6e85..0000000 --- a/Foundation/GTMNSAppleEventDescriptor+Handler.m +++ /dev/null @@ -1,130 +0,0 @@ -// -// GTMNSAppleEventDescriptor+Handler.m -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMNSAppleEventDescriptor+Handler.h" -#import "GTMNSAppleEventDescriptor+Foundation.h" -#import "GTMMethodCheck.h" -#import <Carbon/Carbon.h> - -@implementation NSAppleEventDescriptor (GTMAppleEventDescriptorHandlerAdditions) -GTM_METHOD_CHECK(NSProcessInfo, gtm_appleEventDescriptor); - -+ (id)gtm_descriptorWithPositionalHandler:(NSString*)handler - parametersArray:(NSArray*)params { - return [[[self alloc] gtm_initWithPositionalHandler:handler - parametersArray:params] autorelease]; -} - -+ (id)gtm_descriptorWithPositionalHandler:(NSString*)handler - parametersDescriptor:(NSAppleEventDescriptor*)params { - return [[[self alloc] gtm_initWithPositionalHandler:handler - parametersDescriptor:params] autorelease]; -} - -+ (id)gtm_descriptorWithLabeledHandler:(NSString*)handler - labels:(AEKeyword*)labels - parameters:(id*)params - count:(NSUInteger)count { - return [[[self alloc] gtm_initWithLabeledHandler:handler - labels:labels - parameters:params - count:count] autorelease]; -} - -- (id)gtm_initWithPositionalHandler:(NSString*)handler - parametersArray:(NSArray*)params { - return [self gtm_initWithPositionalHandler:handler - parametersDescriptor:[params gtm_appleEventDescriptor]]; -} - -- (id)gtm_initWithPositionalHandler:(NSString*)handler - parametersDescriptor:(NSAppleEventDescriptor*)params { - if ((self = [self initWithEventClass:kASAppleScriptSuite - eventID:kASSubroutineEvent - targetDescriptor:[[NSProcessInfo processInfo] gtm_appleEventDescriptor] - returnID:kAutoGenerateReturnID - transactionID:kAnyTransactionID])) { - // Create an NSAppleEventDescriptor with the method handler. Note that the - // name must be lowercase (even if it is uppercase in AppleScript). - // http://developer.apple.com/qa/qa2001/qa1111.html - // has details. - handler = [handler lowercaseString]; - if (!handler) { - [self release]; - return nil; - } - NSAppleEventDescriptor *handlerDesc - = [NSAppleEventDescriptor descriptorWithString:handler]; - [self setParamDescriptor:handlerDesc forKeyword:keyASSubroutineName]; - if (params) { - [self setParamDescriptor:params forKeyword:keyDirectObject]; - } - } - return self; -} - - -- (id)gtm_initWithLabeledHandler:(NSString*)handler - labels:(AEKeyword*)labels - parameters:(id*)params - count:(NSUInteger)count { - if ((self = [self initWithEventClass:kASAppleScriptSuite - eventID:kASSubroutineEvent - targetDescriptor:[[NSProcessInfo processInfo] gtm_appleEventDescriptor] - returnID:kAutoGenerateReturnID - transactionID:kAnyTransactionID])) { - if (!handler) { - [self release]; - return nil; - } - // Create an NSAppleEventDescriptor with the method handler. Note that the - // name must be lowercase (even if it is uppercase in AppleScript). - NSAppleEventDescriptor *handlerDesc - = [NSAppleEventDescriptor descriptorWithString:[handler lowercaseString]]; - [self setParamDescriptor:handlerDesc forKeyword:keyASSubroutineName]; - for (NSUInteger i = 0; i < count; i++) { - NSAppleEventDescriptor *paramDesc = [params[i] gtm_appleEventDescriptor]; - if(labels[i] == keyASPrepositionGiven) { - if (![params[i] isKindOfClass:[NSDictionary class]]) { - _GTMDevLog(@"Must pass in dictionary for keyASPrepositionGiven " - "(got %@)", params[i]); - [self release]; - self = nil; - break; - } - NSAppleEventDescriptor *userDesc - = [paramDesc descriptorForKeyword:keyASUserRecordFields]; - if (!userDesc) { - _GTMDevLog(@"Dictionary for keyASPrepositionGiven must be a user " - "record field dictionary (got %@)", params[i]); - [self release]; - self = nil; - break; - } - [self setParamDescriptor:userDesc - forKeyword:keyASUserRecordFields]; - } else { - [self setParamDescriptor:paramDesc - forKeyword:labels[i]]; - } - } - } - return self; -} - -@end diff --git a/Foundation/GTMNSAppleEventDescriptor+HandlerTest.m b/Foundation/GTMNSAppleEventDescriptor+HandlerTest.m deleted file mode 100644 index a137d8a..0000000 --- a/Foundation/GTMNSAppleEventDescriptor+HandlerTest.m +++ /dev/null @@ -1,70 +0,0 @@ -// -// GTNNSAppleEventDescriptor+HandlerTest.m -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Carbon/Carbon.h> -#import "GTMSenTestCase.h" -#import "GTMNSAppleEventDescriptor+Foundation.h" -#import "GTMNSAppleEventDescriptor+Handler.h" -#import "GTMUnitTestDevLog.h" - -@interface GTMNSAppleEventDescriptor_HandlerTest : GTMTestCase -@end - -@implementation GTMNSAppleEventDescriptor_HandlerTest -// Most of this gets tested by the NSAppleScript+Handler tests. -- (void)testPositionalHandlers { - NSAppleEventDescriptor *desc - = [NSAppleEventDescriptor gtm_descriptorWithPositionalHandler:nil - parametersArray:[NSArray array]]; - STAssertNil(desc, @"got a desc?"); - - desc = [NSAppleEventDescriptor gtm_descriptorWithPositionalHandler:@"happy" - parametersDescriptor:nil]; - STAssertNotNil(desc, @"didn't get a desc?"); - - desc = [NSAppleEventDescriptor gtm_descriptorWithLabeledHandler:nil - labels:nil - parameters:nil - count:0]; - STAssertNil(desc, @"got a desc?"); - - AEKeyword keys[] = { keyASPrepositionGiven }; - NSString *string = @"foo"; - [GTMUnitTestDevLog expectString:@"Must pass in dictionary for " - "keyASPrepositionGiven (got foo)"]; - desc = [NSAppleEventDescriptor gtm_descriptorWithLabeledHandler:@"happy" - labels:keys - parameters:&string - count:1]; - STAssertNil(desc, @"got a desc?"); - - NSDictionary *dict = [NSDictionary dictionaryWithObject:@"bart" - forKey:[NSNumber numberWithInt:4]]; - [GTMUnitTestDevLog expectString:@"Keys must be of type NSString or " - "GTMFourCharCode: 4"]; - [GTMUnitTestDevLog expectPattern:@"Dictionary for keyASPrepositionGiven must " - "be a user record field dictionary \\(got .*"]; - desc = [NSAppleEventDescriptor gtm_descriptorWithLabeledHandler:@"happy" - labels:keys - parameters:&dict - count:1]; - STAssertNil(desc, @"got a desc?"); - -} - -@end diff --git a/Foundation/GTMNSAppleScript+Handler.h b/Foundation/GTMNSAppleScript+Handler.h deleted file mode 100644 index ba4fe72..0000000 --- a/Foundation/GTMNSAppleScript+Handler.h +++ /dev/null @@ -1,132 +0,0 @@ -// -// GTMNSAppleScript+Handler.h -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> -#import "GTMDefines.h" - -// A category for calling handlers in NSAppleScript - -enum { - // Data type is OSAID. These will generally be representing - // scripts. - typeGTMOSAID = 'GTMO' -}; - -@interface NSAppleScript(GTMAppleScriptHandlerAdditions) -// Allows us to call a specific handler in an AppleScript. -// parameters are passed in left-right order 0-n. -// -// Args: -// handler - name of the handler to call in the Applescript -// params - the parameters to pass to the handler -// error - in non-nil returns any error that may have occurred. -// -// Returns: -// The result of the handler being called. nil on failure. -- (NSAppleEventDescriptor*)gtm_executePositionalHandler:(NSString*)handler - parameters:(NSArray*)params - error:(NSDictionary**)error; - - -// Allows us to call a specific labeled handler in an AppleScript. -// Parameters for a labeled handler can be in any order, as long as the -// order of the params array corresponds to the order of the labels array -// such that labels are associated with their correct parameter values. -// -// Args: -// handler - name of the handler to call in the Applescript -// labels - the labels to associate with the parameters -// params - the parameters to pass to the handler -// count - number of labels/parameters -// error - in non-nil returns any error that may have occurred. -// -// Returns: -// The result of the handler being called. nil on failure. -- (NSAppleEventDescriptor*)gtm_executeLabeledHandler:(NSString*)handler - labels:(AEKeyword*)labels - parameters:(id*)params - count:(NSUInteger)count - error:(NSDictionary **)error; - -// Same as executeAppleEvent:error: except that it handles return values of -// script correctly. Return values containing scripts will have the -// typeGTMOSAID. Calling gtm_objectValue on a NSAppleEventDescriptor of -// typeGTMOSAID will resolve correctly to a script value. We don't use -// typeScript because that actually copies the script instead of returning the -// actual value. Therefore if you called executeAppleEvent:error: (instead of -// the GTM version) to execute an event that returns a script, you will -// get a completely new Applescript, instead of the actual script you wanted. If -// you are working with script information, use gtm_executeAppleEvent:error -// instead of executeAppleEvent:error: to avoid the problem. -- (NSAppleEventDescriptor *)gtm_executeAppleEvent:(NSAppleEventDescriptor *)event - error:(NSDictionary **)error; - -// The set of all handlers that are defined in this script and its parents. -// Remember that handlers that are defined in an sdef will have their -// eventclass/eventid as their handler instead of the name seen in the script. -// So: -// on open(a) -// blah -// end open -// won't be "open" it will be "aevtodoc". -- (NSSet*)gtm_handlers; - -// The set of all properties that are defined in this script and its parents. -// Note that properties can be strings or GTMNSFourCharCodes, so expect both -// coming back in the set. -- (NSSet*)gtm_properties; - -// Return a value for a property. Will look up the inheritence tree. -// Property must be an NSString or a GTMFourCharCode. -- (id)gtm_valueForProperty:(id)property; - -// Return a value for a property by type (eg pASParent). Will look up the -// inheritence tree -- (id)gtm_valueForPropertyEnum:(DescType)property; - -// Set a script property value. Returns YES/NO on success/failure. -// Property must be of kind NSString or GTMFourCharCode. -// If addingDefinition is YES, it will add a definition to the script -// if the value doesn't exist in the script or one of it's parents. -- (BOOL)gtm_setValue:(id)value - forProperty:(id)property - addingDefinition:(BOOL)adding; - -// Set a value for a property by type (eg pASParent). See note above -// for gtm_setValue:forProperty. -- (BOOL)gtm_setValue:(id)value - forPropertyEnum:(DescType)property - addingDefinition:(BOOL)adding; - -// Return YES if the script has an open documents (odoc) handler -// Does not require script compilation, so it's a fast check. -- (BOOL)gtm_hasOpenDocumentsHandler; - -@end - -// Error keys that we may return in the error dictionary on top of the standard -// NSAppleScriptError* keys. -extern NSString const* GTMNSAppleScriptErrorPartialResult; // id -extern NSString const* GTMNSAppleScriptErrorOffendingObject; // id -extern NSString const* GTMNSAppleScriptErrorExpectedType; // GTMFourCharCode - -@interface NSAppleEventDescriptor (GTMAppleEventDescriptorOSAAdditions) -// Returns an NSValue containing an NSRange of script source when an error -// occurs while compiling and/or executing a script. -- (id)gtm_OSAErrorRangeValue; -@end diff --git a/Foundation/GTMNSAppleScript+Handler.m b/Foundation/GTMNSAppleScript+Handler.m deleted file mode 100644 index 850de58..0000000 --- a/Foundation/GTMNSAppleScript+Handler.m +++ /dev/null @@ -1,662 +0,0 @@ -// -// GTMNSAppleScript+Handler.m -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Carbon/Carbon.h> -#import "GTMNSAppleScript+Handler.h" -#import "GTMNSAppleEventDescriptor+Foundation.h" -#import "GTMNSAppleEventDescriptor+Handler.h" -#import "GTMFourCharCode.h" -#import "GTMMethodCheck.h" - -// Keys for passing AppleScript calls from other threads to the main thread -// and back through gtm_internalExecuteAppleEvent: -static NSString *const GTMNSAppleScriptEventKey = @"GTMNSAppleScriptEvent"; -static NSString *const GTMNSAppleScriptResultKey = @"GTMNSAppleScriptResult"; -static NSString *const GTMNSAppleScriptErrorKey = @"GTMNSAppleScriptError"; - -// Error keys that we may return in the error dictionary on top of the standard -// NSAppleScriptError* keys. -NSString const* GTMNSAppleScriptErrorPartialResult - = @"GTMNSAppleScriptErrorPartialResult"; -NSString const* GTMNSAppleScriptErrorOffendingObject - = @"GTMNSAppleScriptErrorOffendingObject"; -NSString const* GTMNSAppleScriptErrorExpectedType - = @"GTMNSAppleScriptErrorExpectedType"; - -// Some private methods that we need to call -@interface NSAppleScript (NSPrivate) -+ (ComponentInstance)_defaultScriptingComponent; -- (OSAID) _compiledScriptID; -- (id)_initWithData:(NSData*)data error:(NSDictionary**)error; -- (id)_initWithScriptIDNoCopy:(OSAID)osaID; -@end - -@interface NSMethodSignature (NSPrivate) -+ (id)signatureWithObjCTypes:(const char *)fp8; -@end - -// Our own private interfaces. -@interface NSAppleScript (GTMAppleScriptHandlerAdditionsPrivate) - -// Return an descriptor for a property. Properties are only supposed to be -// of type NSString or GTMFourCharCode. GTMFourCharCode's need special handling -// as they must be turned into NSAppleEventDescriptors of typeProperty. -- (NSAppleEventDescriptor*)gtm_descriptorForPropertyValue:(id)property; - -// Return an NSAppleEventDescriptor for a given property. -// |property| must be kind of class GTMFourCharCode -- (NSAppleEventDescriptor*)gtm_valueDescriptorForProperty:(id)property; - -// Utility routine for extracting multiple values in scripts and their -// parents. -- (NSSet*)gtm_allValuesUsingSelector:(SEL)selector; - -// Utility routine for extracting the handlers for a specific script without -// referring to parent scripts. -- (NSSet*)gtm_scriptHandlers; - -// Utility routine for extracting the properties for a specific script without -// referring to parent scripts. -- (NSSet*)gtm_scriptProperties; - -// Handles creating an NSAppleEventDescriptor from an OSAID -- (NSAppleEventDescriptor*)descForScriptID:(OSAID)scriptID - component:(ComponentInstance)component; - -// Utility methods for converting between real and generic OSAIDs. -- (OSAID)gtm_genericID:(OSAID)osaID forComponent:(ComponentInstance)component; -- (OSAID)gtm_realIDAndComponent:(ComponentInstance*)component; - -- (void)gtm_internalExecuteAppleEvent:(NSMutableDictionary *)data; - -- (NSDictionary *)gtm_errorDictionaryFromOSStatus:(OSStatus)status - component:(ComponentInstance)component; -@end - -// Private methods for dealing with Scripts/Events and NSAppleEventDescriptors -@interface NSAppleEventDescriptor (GTMAppleEventDescriptorScriptAdditions) - -// Return an NSAppleScript for a desc of typeScript. This will create a new -// Applescript that is a copy of the script that you want. -// Returns nil on failure. -- (NSAppleScript*)gtm_scriptValue; - -// Return an NSAppleScript for a desc of typeGTMOSAID. This will not copy the -// script, but will create an NSAppleScript wrapping the script represented -// by the OSAID. -// Returns nil on failure. -- (NSAppleScript*)gtm_osaIDValue; - -// Return a NSString with [eventClass][eventID] for typeEvent 'evnt' -- (NSString*)gtm_eventValue; -@end - -@implementation NSAppleScript(GTMAppleScriptHandlerAdditions) -GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_descriptorWithPositionalHandler:parametersArray:); -GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_descriptorWithLabeledHandler:labels:parameters:count:); -GTM_METHOD_CHECK(NSAppleEventDescriptor, gtm_registerSelector:forTypes:count:); - -+ (void)load { - DescType types[] = { - typeScript - }; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_scriptValue) - forTypes:types - count:sizeof(types)/sizeof(DescType)]; - - DescType types2[] = { - 'evnt' // No type code for this one - }; - - [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_eventValue) - forTypes:types2 - count:sizeof(types2)/sizeof(DescType)]; - - DescType types3[] = { - typeGTMOSAID - }; - - [NSAppleEventDescriptor gtm_registerSelector:@selector(gtm_osaIDValue) - forTypes:types3 - count:sizeof(types3)/sizeof(DescType)]; - [pool drain]; -} - -- (NSAppleEventDescriptor *)gtm_executeAppleEvent:(NSAppleEventDescriptor *)event - error:(NSDictionary **)error { - NSMutableDictionary *data = [NSMutableDictionary dictionaryWithObjectsAndKeys: - event, GTMNSAppleScriptEventKey, nil]; - [self performSelectorOnMainThread:@selector(gtm_internalExecuteAppleEvent:) - withObject:data - waitUntilDone:YES]; - if (error) { - *error = [data objectForKey:GTMNSAppleScriptErrorKey]; - } - return [data objectForKey:GTMNSAppleScriptResultKey]; -} - -- (NSAppleEventDescriptor*)gtm_executePositionalHandler:(NSString*)handler - parameters:(NSArray*)params - error:(NSDictionary**)error { - NSAppleEventDescriptor *event - = [NSAppleEventDescriptor gtm_descriptorWithPositionalHandler:handler - parametersArray:params]; - return [self gtm_executeAppleEvent:event error:error]; -} - -- (NSAppleEventDescriptor*)gtm_executeLabeledHandler:(NSString*)handler - labels:(AEKeyword*)labels - parameters:(id*)params - count:(NSUInteger)count - error:(NSDictionary **)error { - NSAppleEventDescriptor *event - = [NSAppleEventDescriptor gtm_descriptorWithLabeledHandler:handler - labels:labels - parameters:params - count:count]; - return [self gtm_executeAppleEvent:event error:error]; -} - -- (NSSet*)gtm_handlers { - return [self gtm_allValuesUsingSelector:@selector(gtm_scriptHandlers)]; -} - -- (NSSet*)gtm_properties { - return [self gtm_allValuesUsingSelector:@selector(gtm_scriptProperties)]; -} - -// Set a value for a property by type (eg pASTopLevelScript) -- (BOOL)gtm_setValue:(id)value - forPropertyEnum:(DescType)property - addingDefinition:(BOOL)adding { - GTMFourCharCode *fcc - = [GTMFourCharCode fourCharCodeWithFourCharCode:property]; - return [self gtm_setValue:value forProperty:fcc addingDefinition:adding]; -} - -- (BOOL)gtm_setValue:(id)value - forProperty:(id)property - addingDefinition:(BOOL)adding{ - OSAError error = paramErr; - BOOL wasGood = NO; - NSAppleEventDescriptor *propertyName - = [self gtm_descriptorForPropertyValue:property]; - NSAppleEventDescriptor *desc = [value gtm_appleEventDescriptor]; - if (propertyName && desc) { - NSAppleScript *script = self; - OSAID valueID = kOSANullScript; - ComponentInstance component = NULL; - OSAID scriptID = [script gtm_realIDAndComponent:&component]; - error = OSACoerceFromDesc(component, - [desc aeDesc], - kOSAModeNull, - &valueID); - if (error == noErr) { - error = OSASetProperty(component, - adding ? kOSAModeNull : kOSAModeDontDefine, - scriptID, - [propertyName aeDesc], - valueID); - if (error == noErr) { - wasGood = YES; - } - } - } - if (!wasGood) { - _GTMDevLog(@"Unable to setValue:%@ forProperty:%@ from %@ (%d)", - value, property, self, (int)error); - } - return wasGood; -} - -- (id)gtm_valueForProperty:(id)property { - return [[self gtm_valueDescriptorForProperty:property] gtm_objectValue]; -} - -- (id)gtm_valueForPropertyEnum:(DescType)property { - GTMFourCharCode *fcc = [GTMFourCharCode fourCharCodeWithFourCharCode:property]; - return [self gtm_valueForProperty:fcc]; -} - -- (NSAppleEventDescriptor*)gtm_appleEventDescriptor { - ComponentInstance component; - OSAID osaID = [self gtm_realIDAndComponent:&component]; - AEDesc result = { typeNull, NULL }; - NSAppleEventDescriptor *desc = nil; - OSAError error = OSACoerceToDesc(component, - osaID, - typeScript, - kOSAModeNull, - &result); - if (error == noErr) { - desc = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&result] - autorelease]; - } else { - _GTMDevLog(@"Unable to coerce script %ld", (long)error); - } - return desc; -} - -- (BOOL)gtm_hasOpenDocumentsHandler { - ComponentInstance component = NULL; - OSAID osaID = [self gtm_realIDAndComponent:&component]; - long value = 0; - OSAError error = OSAGetScriptInfo(component, - osaID, - kASHasOpenHandler, - &value); - if (error) { - _GTMDevLog(@"Unable to get script info about open handler %ld", (long)error); - value = 0; - } - return value != 0; -} - -- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { - NSMethodSignature *signature = [super methodSignatureForSelector:aSelector]; - if (!signature) { - NSMutableString *types = [NSMutableString stringWithString:@"@@:"]; - NSString *selName = NSStringFromSelector(aSelector); - NSArray *selArray = [selName componentsSeparatedByString:@":"]; - NSUInteger count = [selArray count]; - for (NSUInteger i = 1; i < count; i++) { - [types appendString:@"@"]; - } - signature = [NSMethodSignature signatureWithObjCTypes:[types UTF8String]]; - } - return signature; -} - -- (void)forwardInvocation:(NSInvocation *)invocation { - SEL sel = [invocation selector]; - NSMutableString *handlerName - = [NSMutableString stringWithString:NSStringFromSelector(sel)]; - NSUInteger handlerOrigLength = [handlerName length]; - [handlerName replaceOccurrencesOfString:@":" - withString:@"" - options:0 - range:NSMakeRange(0,handlerOrigLength)]; - NSUInteger argCount = handlerOrigLength - [handlerName length]; - NSMutableArray *args = [NSMutableArray arrayWithCapacity:argCount]; - for (NSUInteger i = 0; i < argCount; ++i) { - id arg; - // +2 to ignore _sel and _cmd - [invocation getArgument:&arg atIndex:i + 2]; - [args addObject:arg]; - } - NSDictionary *error = nil; - NSAppleEventDescriptor *desc = [self gtm_executePositionalHandler:handlerName - parameters:args - error:&error]; - if ([[invocation methodSignature] methodReturnLength] > 0) { - id returnValue = [desc gtm_objectValue]; - [invocation setReturnValue:&returnValue]; - } -} -@end - -@implementation NSAppleScript (GTMAppleScriptHandlerAdditionsPrivate) - -- (NSAppleEventDescriptor*)gtm_descriptorForPropertyValue:(id)property { - NSAppleEventDescriptor *propDesc = nil; - if ([property isKindOfClass:[GTMFourCharCode class]]) { - propDesc = [property gtm_appleEventDescriptorOfType:typeProperty]; - } else if ([property isKindOfClass:[NSString class]]) { - propDesc = [property gtm_appleEventDescriptor]; - } - return propDesc; -} - -- (NSAppleEventDescriptor*)gtm_valueDescriptorForProperty:(id)property { - _GTMDevAssert([NSThread isMainThread], @"Requires main thread."); - OSAError error = paramErr; - NSAppleEventDescriptor *desc = nil; - NSAppleEventDescriptor *propertyName - = [self gtm_descriptorForPropertyValue:property]; - if (propertyName) { - ComponentInstance component = NULL; - OSAID scriptID = [self gtm_realIDAndComponent:&component]; - OSAID valueID = kOSANullScript; - error = OSAGetProperty(component, - kOSAModeNull, - scriptID, - [propertyName aeDesc], - &valueID); - if (error == noErr) { - desc = [self descForScriptID:valueID component:component]; - } - } - if (error) { - _GTMDevLog(@"Unable to get valueForProperty:%@ from %@ (%d)", - property, self, (int)error); - } - return desc; -} - -- (NSSet*)gtm_allValuesUsingSelector:(SEL)selector { - NSMutableSet *resultSet = [NSMutableSet set]; - NSAppleEventDescriptor *scriptDesc = [self gtm_appleEventDescriptor]; - NSMutableSet *scriptDescsWeveSeen = [NSMutableSet set]; - GTMFourCharCode *fcc = [GTMFourCharCode fourCharCodeWithFourCharCode:pASParent]; - Class appleScriptClass = [NSAppleScript class]; - while (scriptDesc) { - NSAppleScript *script = [scriptDesc gtm_objectValue]; - if ([script isKindOfClass:appleScriptClass]) { - NSData *data = [scriptDesc data]; - if (!data || [scriptDescsWeveSeen containsObject:data]) { - break; - } else { - [scriptDescsWeveSeen addObject:data]; - } - NSSet *newSet = [script performSelector:selector]; - [resultSet unionSet:newSet]; - scriptDesc = [script gtm_valueDescriptorForProperty:fcc]; - } else { - break; - } - } - return resultSet; -} - -- (NSSet*)gtm_scriptHandlers { - _GTMDevAssert([NSThread isMainThread], @"Requires main thread."); - AEDescList names = { typeNull, NULL }; - NSArray *array = nil; - ComponentInstance component = NULL; - OSAID osaID = [self gtm_realIDAndComponent:&component]; - OSAError error = OSAGetHandlerNames(component, kOSAModeNull, osaID, &names); - if (error == noErr) { - NSAppleEventDescriptor *desc - = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&names] - autorelease]; - array = [desc gtm_objectValue]; - } - if (error != noErr) { - _GTMDevLog(@"Error getting handlers: %d", (int)error); // COV_NF_LINE - } - return [NSSet setWithArray:array]; -} - -- (NSSet*)gtm_scriptProperties { - _GTMDevAssert([NSThread isMainThread], @"Requires main thread."); - AEDescList names = { typeNull, NULL }; - NSArray *array = nil; - ComponentInstance component = NULL; - OSAID osaID = [self gtm_realIDAndComponent:&component]; - OSAError error = OSAGetPropertyNames(component, kOSAModeNull, osaID, &names); - if (error == noErr) { - NSAppleEventDescriptor *desc - = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&names] - autorelease]; - array = [desc gtm_objectValue]; - } - if (error != noErr) { - _GTMDevLog(@"Error getting properties: %d", (int)error); // COV_NF_LINE - } - return [NSSet setWithArray:array]; -} - -- (OSAID)gtm_genericID:(OSAID)osaID forComponent:(ComponentInstance)component { - _GTMDevAssert([NSThread isMainThread], @"Requires main thread."); - ComponentInstance genericComponent = [NSAppleScript _defaultScriptingComponent]; - OSAID exactID = osaID; - OSAError error = OSARealToGenericID(genericComponent, &exactID, component); - if (error != noErr) { - _GTMDevLog(@"Unable to get real id script: %@ %d", self, (int)error); // COV_NF_LINE - exactID = kOSANullScript; // COV_NF_LINE - } - return exactID; -} - -- (NSAppleEventDescriptor*)descForScriptID:(OSAID)osaID - component:(ComponentInstance)component { - _GTMDevAssert([NSThread isMainThread], @"Requires main thread."); - NSAppleEventDescriptor *desc = nil; - // If we have a script, return a typeGTMOSAID, otherwise convert it to - // it's default AEDesc using OSACoerceToDesc with typeWildCard. - long value = 0; - OSAError err = noErr; - if (osaID == 0) { - desc = [NSAppleEventDescriptor nullDescriptor]; - } else { - err = OSAGetScriptInfo(component, - osaID, - kOSAScriptBestType, - &value); - if (err == noErr) { - if (value == typeScript) { - osaID = [self gtm_genericID:osaID forComponent:component]; - desc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeGTMOSAID - bytes:&osaID - length:sizeof(osaID)]; - } else { - AEDesc aeDesc; - err = OSACoerceToDesc(component, - osaID, - typeWildCard, - kOSAModeNull, - &aeDesc); - if (err == noErr) { - desc = [[[NSAppleEventDescriptor alloc] - initWithAEDescNoCopy:&aeDesc] autorelease]; - } - } - } - } - if (err != noErr) { - _GTMDevLog(@"Unable to create desc for id:%lu (%ld)", (unsigned long)osaID, (long)err); // COV_NF_LINE - } - return desc; -} - -- (OSAID)gtm_realIDAndComponent:(ComponentInstance*)component { - _GTMDevAssert([NSThread isMainThread], @"Requires main thread."); - if (![self isCompiled]) { - NSDictionary *error; - if (![self compileAndReturnError:&error]) { - _GTMDevLog(@"Unable to compile script: %@ %@", self, error); - return kOSANullScript; - } - } - OSAID genericID = [self _compiledScriptID]; - ComponentInstance genericComponent = [NSAppleScript _defaultScriptingComponent]; - OSAError error = OSAGenericToRealID(genericComponent, &genericID, component); - if (error != noErr) { - _GTMDevLog(@"Unable to get real id script: %@ %d", self, (int)error); // COV_NF_LINE - genericID = kOSANullScript; // COV_NF_LINE - } - return genericID; -} - -- (void)gtm_internalExecuteAppleEvent:(NSMutableDictionary *)data { - _GTMDevAssert([NSThread isMainThread], @"Requires main thread."); - NSDictionary *error = nil; - if (![self isCompiled]) { - [self compileAndReturnError:&error]; - } - if (!error) { - NSAppleEventDescriptor *desc = nil; - NSAppleEventDescriptor *event = [data objectForKey:GTMNSAppleScriptEventKey]; - ComponentInstance component = NULL; - OSAID scriptID = [self gtm_realIDAndComponent:&component]; - OSAID valueID; - OSAError err = OSAExecuteEvent(component, [event aeDesc], scriptID, - kOSAModeNull, &valueID); - if (err == noErr) { - // descForScriptID:component: is what sets this apart from the - // standard executeAppleEvent:error: in that it handles - // taking script results and turning them into AEDescs of typeGTMOSAID - // instead of typeScript. - desc = [self descForScriptID:valueID component:component]; - if (desc) { - [data setObject:desc forKey:GTMNSAppleScriptResultKey]; - } - } else { - error = [self gtm_errorDictionaryFromOSStatus:err component:component]; - } - } - if (error) { - [data setObject:error forKey:GTMNSAppleScriptErrorKey]; - } -} - -- (NSDictionary *)gtm_errorDictionaryFromOSStatus:(OSStatus)status - component:(ComponentInstance)component { - NSMutableDictionary *error = nil; - if (status == errOSAScriptError) { - error = [NSMutableDictionary dictionary]; - struct { - OSType selector; - DescType desiredType; - SEL extractor; - id key; - } errMap[] = { - { - kOSAErrorNumber, - typeSInt16, - @selector(gtm_numberValue), - NSAppleScriptErrorNumber - }, - { - kOSAErrorMessage, - typeText, - @selector(stringValue), - NSAppleScriptErrorMessage - }, - { - kOSAErrorBriefMessage, - typeText, - @selector(stringValue), - NSAppleScriptErrorBriefMessage - }, - { kOSAErrorApp, - typeText, - @selector(stringValue), - NSAppleScriptErrorAppName - }, - { kOSAErrorRange, - typeOSAErrorRange, - @selector(gtm_OSAErrorRangeValue), - NSAppleScriptErrorRange - }, - { - kOSAErrorPartialResult, - typeBest, - @selector(gtm_objectValue), - GTMNSAppleScriptErrorPartialResult - }, - { - kOSAErrorOffendingObject, - typeBest, - @selector(gtm_objectValue), - GTMNSAppleScriptErrorOffendingObject - }, - { - kOSAErrorExpectedType, - typeType, - @selector(gtm_fourCharCodeValue), - GTMNSAppleScriptErrorExpectedType - }, - }; - for (size_t i = 0; i < sizeof(errMap) / sizeof(errMap[0]); ++i) { - AEDesc errorResult = { typeNull, NULL }; - OSStatus err = OSAScriptError(component, - errMap[i].selector, - errMap[i].desiredType, - &errorResult); - if (err == noErr) { - NSAppleEventDescriptor *desc = [[[NSAppleEventDescriptor alloc] - initWithAEDescNoCopy:&errorResult] autorelease]; - id value = [desc performSelector:errMap[i].extractor]; - if (value) { - [error setObject:value forKey:errMap[i].key]; - } - } - } - } else if (status != noErr) { - // Unknown error. Do our best to give the user something good. - NSNumber *errNum = [NSNumber numberWithInt:status]; - error - = [NSMutableDictionary dictionaryWithObject:errNum - forKey:NSAppleScriptErrorNumber]; - NSString *briefMessage - = [NSString stringWithUTF8String:GetMacOSStatusErrorString(status)]; - if (briefMessage) { - [error setValue:briefMessage forKey:NSAppleScriptErrorBriefMessage]; - } - NSString *message - = [NSString stringWithUTF8String:GetMacOSStatusCommentString(status)]; - if (message) { - [error setValue:message forKey:NSAppleScriptErrorMessage]; - } - } - return error; -} -@end - -@implementation NSAppleEventDescriptor (GMAppleEventDescriptorScriptAdditions) - -- (NSAppleScript*)gtm_scriptValue { - NSDictionary *error; - NSAppleScript *script = [[[NSAppleScript alloc] _initWithData:[self data] - error:&error] autorelease]; - if (!script) { - _GTMDevLog(@"Unable to create script: %@", error); // COV_NF_LINE - } - return script; -} - -- (NSAppleScript*)gtm_osaIDValue { - _GTMDevAssert([[self data] length] == sizeof(OSAID), nil); - OSAID osaID = *(const OSAID*)[[self data] bytes]; - return [[[NSAppleScript alloc] _initWithScriptIDNoCopy:osaID] autorelease]; -} - -- (NSString*)gtm_eventValue { - struct AEEventRecordStruct { - AEEventClass eventClass; - AEEventID eventID; - }; - NSData *data = [self data]; - const struct AEEventRecordStruct *record - = (const struct AEEventRecordStruct*)[data bytes]; - NSString *eClass = [GTMFourCharCode stringWithFourCharCode:record->eventClass]; - NSString *eID = [GTMFourCharCode stringWithFourCharCode:record->eventID]; - return [eClass stringByAppendingString:eID]; -} -@end - -@implementation NSAppleEventDescriptor (GTMAppleEventDescriptorOSAAdditions) - -- (id)gtm_OSAErrorRangeValue { - id value = nil; - NSAppleEventDescriptor *start = [self descriptorForKeyword:keyOSASourceStart]; - if (start) { - NSAppleEventDescriptor *end = [self descriptorForKeyword:keyOSASourceEnd]; - if (end) { - NSRange range = NSMakeRange([start int32Value], [end int32Value]); - value = [NSValue valueWithRange:range]; - } - } - return value; -} - -@end - diff --git a/Foundation/GTMNSAppleScript+HandlerTest.m b/Foundation/GTMNSAppleScript+HandlerTest.m deleted file mode 100644 index 6a064dd..0000000 --- a/Foundation/GTMNSAppleScript+HandlerTest.m +++ /dev/null @@ -1,504 +0,0 @@ -// -// GTMNSAppleScript+HandlerTest.m -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" -#import <Carbon/Carbon.h> -#import "GTMNSAppleScript+Handler.h" -#import "GTMNSAppleEventDescriptor+Foundation.h" -#import "GTMUnitTestDevLog.h" -#import "GTMSystemVersion.h" -#import "GTMFourCharCode.h" - -@protocol ScriptInterface -- (id)test; -- (id)testReturnParam:(id)param; -- (id)testAddParams:(id)param1 :(id)param2; -@end - -@interface GTMNSAppleScript_HandlerTest : GTMTestCase { - NSAppleScript *script_; -} -@end - -@implementation GTMNSAppleScript_HandlerTest - -- (void)setUp { - NSBundle *bundle - = [NSBundle bundleForClass:[GTMNSAppleScript_HandlerTest class]]; - STAssertNotNil(bundle, nil); - NSString *path = [bundle pathForResource:@"GTMNSAppleEvent+HandlerTest" - ofType:@"scpt" - inDirectory:@"Scripts"]; - STAssertNotNil(path, [bundle description]); - NSDictionary *error = nil; - script_ - = [[NSAppleScript alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] - error:&error]; - STAssertNotNil(script_, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); -} - -- (void)tearDown { - [script_ release]; - script_ = nil; -} - -- (void)testExecuteAppleEvent { - NSString *source = @"on test()\nreturn 1\nend test"; - NSAppleScript *script - = [[[NSAppleScript alloc] initWithSource:source] autorelease]; - STAssertNotNil(script, nil); - NSDictionary *error = nil; - NSAppleEventDescriptor *desc = [script gtm_executePositionalHandler:@"test" - parameters:nil - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc gtm_objectValue], [NSNumber numberWithInt:1], nil); - - // bogus script - source = @"adf872345ba asdf asdf gr"; - script = [[[NSAppleScript alloc] initWithSource:source] autorelease]; - STAssertNotNil(script, nil); - desc = [script gtm_executePositionalHandler:@"test" - parameters:nil - error:&error]; - STAssertNil(desc, nil); - STAssertNotNil(error, @"Error should not be nil"); -} - -- (void)testHandlerNoParamsNoReturn { - NSDictionary *error = nil; - NSAppleEventDescriptor *desc = [script_ gtm_executePositionalHandler:@"test" - parameters:nil - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeNull, nil); - desc = [script_ gtm_executePositionalHandler:@"test" - parameters:[NSArray array] - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeNull, nil); - - //Applescript doesn't appear to get upset about extra params - desc = [script_ gtm_executePositionalHandler:@"test" - parameters:[NSArray arrayWithObject:@"foo"] - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeNull, nil); -} - -- (void)testHandlerNoParamsWithReturn { - NSDictionary *error = nil; - NSAppleEventDescriptor *desc - = [script_ gtm_executePositionalHandler:@"testReturnOne" - parameters:nil - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil); - STAssertEquals([desc int32Value], (SInt32)1, nil); - desc = [script_ gtm_executePositionalHandler:@"testReturnOne" - parameters:[NSArray array] - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil); - STAssertEquals([desc int32Value], (SInt32)1, nil); - - //Applescript doesn't appear to get upset about extra params - desc = [script_ gtm_executePositionalHandler:@"testReturnOne" - parameters:[NSArray arrayWithObject:@"foo"] - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil); - STAssertEquals([desc int32Value], (SInt32)1, nil); -} - -- (void)testHandlerOneParamWithReturn { - NSDictionary *error = nil; - // Note case change in executeHandler call - NSAppleEventDescriptor *desc - = [script_ gtm_executePositionalHandler:@"testreturnParam" - parameters:nil - error:&error]; - STAssertNil(desc, @"Desc should by nil %@", desc); - STAssertNotNil(error, nil); - error = nil; - - desc = [script_ gtm_executePositionalHandler:@"testReturnParam" - parameters:[NSArray array] - error:&error]; - STAssertNil(desc, @"Desc should by nil %@", desc); - - // Verify that our error handling is working correctly. - STAssertEquals([[error allKeys] count], (NSUInteger)6, @"%@", error); - STAssertNotNil([error objectForKey:GTMNSAppleScriptErrorOffendingObject], - @"%@", error); - STAssertNotNil([error objectForKey:GTMNSAppleScriptErrorPartialResult], - @"%@", error); - - error = nil; - - desc = [script_ gtm_executePositionalHandler:@"testReturnParam" - parameters:[NSArray arrayWithObject:@"foo"] - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeUnicodeText, nil); - STAssertEqualObjects([desc gtm_objectValue], @"foo", nil); -} - -- (void)testHandlerTwoParamsWithReturn { - NSDictionary *error = nil; - // Note case change in executeHandler call - // Test case and empty params - NSAppleEventDescriptor *desc - = [script_ gtm_executePositionalHandler:@"testADDPArams" - parameters:nil - error:&error]; - STAssertNil(desc, @"Desc should by nil %@", desc); - STAssertNotNil(error, nil); - - // Test empty params - error = nil; - desc = [script_ gtm_executePositionalHandler:@"testAddParams" - parameters:[NSArray array] - error:&error]; - STAssertNil(desc, @"Desc should by nil %@", desc); - STAssertNotNil(error, nil); - - error = nil; - NSArray *args = [NSArray arrayWithObjects: - [NSNumber numberWithInt:1], - [NSNumber numberWithInt:2], - nil]; - desc = [script_ gtm_executePositionalHandler:@"testAddParams" - parameters:args - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil); - STAssertEquals([desc int32Value], (SInt32)3, nil); - - // Test bad params - error = nil; - args = [NSArray arrayWithObjects: - @"foo", - @"bar", - nil]; - desc = [script_ gtm_executePositionalHandler:@"testAddParams" - parameters:args - error:&error]; - STAssertNil(desc, @"Desc should by nil %@", desc); - STAssertNotNil(error, nil); - - // Test too many params. Currently Applescript allows this so it should pass - error = nil; - args = [NSArray arrayWithObjects: - [NSNumber numberWithInt:1], - [NSNumber numberWithInt:2], - [NSNumber numberWithInt:3], - nil]; - desc = [script_ gtm_executePositionalHandler:@"testAddParams" - parameters:args - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil); - STAssertEquals([desc int32Value], (SInt32)3, nil);} - -- (void)testLabeledHandler { - NSDictionary *error = nil; - AEKeyword labels[] = { keyDirectObject, - keyASPrepositionOnto, - keyASPrepositionGiven }; - id params[3]; - params[0] = [NSNumber numberWithInt:1]; - params[1] = [NSNumber numberWithInt:3]; - params[2] = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:4] - forKey:@"othervalue"]; - - NSAppleEventDescriptor *desc - = [script_ gtm_executeLabeledHandler:@"testAdd" - labels:labels - parameters:params - count:sizeof(params) / sizeof(id) - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil); - STAssertEquals([desc int32Value], (SInt32)8, nil); - - // Test too many params. Currently Applescript allows this so it should pass - AEKeyword labels2[] = { keyDirectObject, - keyASPrepositionOnto, - keyASPrepositionBetween, - keyASPrepositionGiven }; - id params2[4]; - params2[0] = [NSNumber numberWithInt:1]; - params2[1] = [NSNumber numberWithInt:3]; - params2[2] = [NSNumber numberWithInt:5]; - params2[3] = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:4] - forKey:@"othervalue"]; - - error = nil; - desc = [script_ gtm_executeLabeledHandler:@"testAdd" - labels:labels2 - parameters:params2 - count:sizeof(params2) / sizeof(id) - error:&error]; - STAssertNotNil(desc, [error description]); - STAssertNil(error, @"Error should be nil. Error = %@", [error description]); - STAssertEquals([desc descriptorType], (DescType)typeSInt32, nil); - STAssertEquals([desc int32Value], (SInt32)8, nil);} - -- (void)testHandlers { - NSSet *handlers = [script_ gtm_handlers]; - NSSet *expected = [NSSet setWithObjects: - @"aevtpdoc", - @"test", - @"testreturnone", - @"testreturnparam", - @"testaddparams", - @"testadd", - @"testgetscript", - nil]; - if ([GTMSystemVersion isSnowLeopardOrGreater]) { - // Workaround for bug in SnowLeopard - // rdar://66688601 OSAGetHandlersNames returns names in camelcase instead - // of smallcaps. - handlers = [handlers valueForKey:@"lowercaseString"]; - } - STAssertEqualObjects(handlers, expected, @"Unexpected handlers?"); -} - -- (void)testInheritedHandlers { - NSDictionary *error = nil; - NSAppleEventDescriptor *desc - = [script_ gtm_executePositionalHandler:@"testGetScript" - parameters:nil - error:&error]; - STAssertNil(error, nil); - STAssertNotNil(desc, nil); - NSAppleScript *script = [desc gtm_objectValue]; - STAssertTrue([script isKindOfClass:[NSAppleScript class]], nil); - error = nil; - desc = [script gtm_executePositionalHandler:@"parentTestScriptFunc" - parameters:nil error:&error]; - STAssertNil(error, nil); - STAssertNotNil(desc, nil); - NSString *value = [desc gtm_objectValue]; - STAssertEqualObjects(value, @"parent", nil); -} - -- (void)testProperties { - NSDictionary *error = nil; - NSAppleEventDescriptor *desc - = [script_ gtm_executePositionalHandler:@"testGetScript" - parameters:nil - error:&error]; - STAssertNil(error, nil); - STAssertNotNil(desc, nil); - NSAppleScript *script = [desc gtm_objectValue]; - STAssertTrue([script isKindOfClass:[NSAppleScript class]], nil); - - NSSet *properties = [script gtm_properties]; - NSSet *expected - = [NSSet setWithObjects: - @"testscriptproperty", - @"parenttestscriptproperty", - @"foo", - @"testscript", - @"parenttestscript", - @"asdscriptuniqueidentifier", - [GTMFourCharCode fourCharCodeWithFourCharCode:pVersion], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASPrintDepth], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASTopLevelScript], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASResult], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASMinutes], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASDays], - // No constant for linefeed in the 10.5 sdk - // Radar 6132775 Need a constant for the Applescript Property 'lnfd' - [GTMFourCharCode fourCharCodeWithFourCharCode:'lnfd'], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASPi], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASReturn], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASSpace], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASPrintLength], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASQuote], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASWeeks], - [GTMFourCharCode fourCharCodeWithFourCharCode:pTextItemDelimiters], - // Applescript properties should be pASSeconds, but - // on 10.5.4/10.5.5 it is actually using cSeconds. - // Radar 6132696 Applescript root level property is cSeconds - // instead of pASSeconds - [GTMFourCharCode fourCharCodeWithFourCharCode:cSeconds], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASHours], - [GTMFourCharCode fourCharCodeWithFourCharCode:pASTab], - nil]; - if ([GTMSystemVersion isSnowLeopardOrGreater]) { - // Workaround for bug in SnowLeopard - // rdar://6289077 OSAGetPropertyNames returns names in camelcase instead - // of lowercase. - id obj; - NSMutableSet *properties2 = [NSMutableSet set]; - GTM_FOREACH_OBJECT(obj, properties) { - if ([obj isKindOfClass:[NSString class]]) { - obj = [obj lowercaseString]; - } - [properties2 addObject:obj]; - } - properties = properties2; - } - STAssertEqualObjects(properties, expected, @"Unexpected properties?"); - id value = [script gtm_valueForProperty:@"testScriptProperty"]; - STAssertEqualObjects(value, [NSNumber numberWithInt:5], @"bad property?"); - BOOL goodSet = [script gtm_setValue:@"bar" - forProperty:@"foo" - addingDefinition:NO]; - STAssertTrue(goodSet, @"Couldn't set property"); - - // Test local set - value = [script gtm_valueForProperty:@"foo"]; - STAssertEqualObjects(value, @"bar", @"bad property?"); - - // Test inherited set - value = [script_ gtm_valueForProperty:@"foo"]; - STAssertEqualObjects(value, @"bar", @"bad property?"); - - [GTMUnitTestDevLog expectPattern:@"Unable to setValue:bar forProperty:" - "\\(null\\) from <NSAppleScript: 0x[0-9a-f]+> \\(-50\\)"]; - goodSet = [script gtm_setValue:@"bar" - forProperty:nil - addingDefinition:NO]; - STAssertFalse(goodSet, @"Set property?"); - - [GTMUnitTestDevLog expectPattern:@"Unable to setValue:bar forProperty:3" - " from <NSAppleScript: 0x[0-9a-f]+> \\(-50\\)"]; - goodSet = [script gtm_setValue:@"bar" - forProperty:[NSNumber numberWithInt:3] - addingDefinition:YES]; - STAssertFalse(goodSet, @"Set property?"); - - - [GTMUnitTestDevLog expectPattern:@"Unable to get valueForProperty:gargle " - "from <NSAppleScript: 0x[0-9a-f]+> \\(-1753\\)"]; - value = [script gtm_valueForProperty:@"gargle"]; - STAssertNil(value, @"Property named gargle?"); - - goodSet = [script_ gtm_setValue:@"wow" - forProperty:@"addedProperty" - addingDefinition:YES]; - STAssertTrue(goodSet, @"Unable to addProperty"); - - value = [script gtm_valueForProperty:@"addedProperty"]; - STAssertNotNil(value, nil); - STAssertEqualObjects(value, @"wow", nil); - - // http://www.straightdope.com/classics/a3_341.html - NSNumber *newPI = [NSNumber numberWithInt:3]; - goodSet = [script gtm_setValue:newPI - forPropertyEnum:pASPi - addingDefinition:NO]; - STAssertTrue(goodSet, @"Unable to set property"); - value = [script_ gtm_valueForPropertyEnum:pASPi]; - STAssertNotNil(value, nil); - STAssertEqualObjects(value, newPI, @"bad property"); -} - -- (void)testFailures { - NSDictionary *error = nil; - NSAppleEventDescriptor *desc - = [script_ gtm_executePositionalHandler:@"noSuchTest" - parameters:nil - error:&error]; - STAssertNil(desc, nil); - STAssertNotNil(error, nil); - - // Test with empty handler name - error = nil; - desc = [script_ gtm_executePositionalHandler:@"" - parameters:[NSArray array] - error:&error]; - STAssertNil(desc, nil); - STAssertNotNil(error, nil); - - // Test with nil handler - error = nil; - desc = [script_ gtm_executePositionalHandler:nil - parameters:[NSArray array] - error:&error]; - STAssertNil(desc, nil); - STAssertNotNil(error, nil); - - // Test with nil handler and nil error - desc = [script_ gtm_executePositionalHandler:nil - parameters:nil - error:nil]; - STAssertNil(desc, nil); - - // Test with a bad script - NSAppleScript *script - = [[[NSAppleScript alloc] initWithSource:@"david hasselhoff"] autorelease]; - [GTMUnitTestDevLog expectPattern:@"Unable to compile script: .*"]; - [GTMUnitTestDevLog expectString:@"Unable to coerce script -2147450879"]; - NSSet *handlers = [script gtm_handlers]; - STAssertEquals([handlers count], (NSUInteger)0, @"Should have no handlers"); - [GTMUnitTestDevLog expectPattern:@"Unable to compile script: .*"]; - [GTMUnitTestDevLog expectString:@"Unable to coerce script -2147450879"]; - NSSet *properties = [script gtm_properties]; - STAssertEquals([properties count], - (NSUInteger)0, - @"Should have no properties"); - [GTMUnitTestDevLog expectPattern:@"Unable to compile script: .*"]; - [GTMUnitTestDevLog expectString:@"Unable to get script info about " - @"open handler -2147450879"]; - STAssertFalse([script gtm_hasOpenDocumentsHandler], - @"Has an opendoc handler?"); -} - -- (void)testScriptDescriptors { - NSAppleEventDescriptor *desc = [script_ gtm_appleEventDescriptor]; - STAssertNotNil(desc, @"Couldn't make a script desc"); - NSAppleScript *script = [desc gtm_objectValue]; - STAssertNotNil(script, @"Couldn't get a script back"); - NSSet *handlers = [script gtm_handlers]; - STAssertNotNil(handlers, @"Couldn't get handlers"); -} - -- (void)testOpenHandler { - STAssertFalse([script_ gtm_hasOpenDocumentsHandler], nil); - id script = [script_ gtm_valueForProperty:@"testscript"]; - STAssertNotNil(script, nil); - STAssertTrue([script gtm_hasOpenDocumentsHandler], nil); -} - -- (void)testForwarding { - id<ScriptInterface> foo = (id<ScriptInterface>)script_; - [foo test]; - NSNumber *val = [foo testReturnParam:[NSNumber numberWithInt:2]]; - STAssertEquals([val intValue], 2, @"should be 2"); - val = [foo testAddParams:[NSNumber numberWithInt:2] - :[NSNumber numberWithInt:3]]; - STAssertEquals([val intValue], 5, @"should be 5"); -} -@end diff --git a/Foundation/GTMNSArray+Merge.m b/Foundation/GTMNSArray+Merge.m index 5bf07c8..4b67853 100644 --- a/Foundation/GTMNSArray+Merge.m +++ b/Foundation/GTMNSArray+Merge.m @@ -6,13 +6,13 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations +// License for the specific language governing permissions and limitations // under the License. // @@ -48,20 +48,20 @@ [mergingArray sortUsingSelector:comparer]; NSArray *sortedNewArray = [newArray sortedArrayUsingSelector:comparer]; - + NSUInteger oldIndex = 0; NSUInteger oldCount = [mergingArray count]; id oldItem = (oldIndex < oldCount) ? [mergingArray objectAtIndex:0] : nil; - + id newItem = nil; - GTM_FOREACH_OBJECT(newItem, sortedNewArray) { + for (newItem in sortedNewArray) { BOOL stillLooking = YES; while (oldIndex < oldCount && stillLooking) { // We must take care here, since Intel leaves junk in high bytes of // return register for predicates that return BOOL. - // For details see: + // For details see: // http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_23.html // and // http://www.red-sweater.com/blog/320/abusing-objective-c-with-class#comment-83187 diff --git a/Foundation/GTMNSArray+MergeTest.m b/Foundation/GTMNSArray+MergeTest.m index 9148ba7..535e0ce 100644 --- a/Foundation/GTMNSArray+MergeTest.m +++ b/Foundation/GTMNSArray+MergeTest.m @@ -37,8 +37,8 @@ NSArray *emptyArrayB = [NSArray array]; NSArray *mergedArray = [emptyArrayA gtm_mergeArray:emptyArrayB mergeSelector:nil]; - STAssertNil(mergedArray, - @"merge of two empty arrays with no merger should render nil"); + XCTAssertNil(mergedArray, + @"merge of two empty arrays with no merger should render nil"); } - (void)testMergingTwoEmptyArraysWithMerger { @@ -47,8 +47,8 @@ NSArray *mergedArray = [emptyArrayA gtm_mergeArray:emptyArrayB mergeSelector:@selector(mergeString:)]; - STAssertNil(mergedArray, - @"merge of two empty arrays with merger should render nil"); + XCTAssertNil(mergedArray, + @"merge of two empty arrays with merger should render nil"); } - (void)testMergingEmptyWithNilArray { @@ -56,8 +56,8 @@ NSArray *nilArrayB = nil; NSArray *mergedArray = [emptyArrayA gtm_mergeArray:nilArrayB mergeSelector:nil]; - STAssertNil(mergedArray, - @"merge of empty with nil array with no merger should render nil"); + XCTAssertNil(mergedArray, + @"merge of empty with nil array with no merger should render nil"); } - (void)testMergingEmptyWithNilArrayWithMerger { @@ -66,8 +66,8 @@ NSArray *mergedArray = [emptyArrayA gtm_mergeArray:nilArrayB mergeSelector:@selector(mergeString:)]; - STAssertNil(mergedArray, - @"merge of empty with nil array with merger should render nil"); + XCTAssertNil(mergedArray, + @"merge of empty with nil array with merger should render nil"); } - (void)testMergingTwoOneItemArraysThatDontMatch { @@ -75,13 +75,13 @@ NSArray *arrayB = [NSArray arrayWithObject:@"abc.ghi"]; NSArray *mergedArray = [arrayA gtm_mergeArray:arrayB mergeSelector:nil]; - STAssertNotNil(mergedArray, - @"merge of two non empty arrays with no merger should render " - @"an array"); - STAssertEquals([mergedArray count], (NSUInteger)2, + XCTAssertNotNil(mergedArray, + @"merge of two non empty arrays with no merger should render " + @"an array"); + XCTAssertEqual([mergedArray count], (NSUInteger)2, @"merged array should have two items"); - STAssertEqualObjects([mergedArray objectAtIndex:0], @"abc.def", nil); - STAssertEqualObjects([mergedArray objectAtIndex:1], @"abc.ghi", nil); + XCTAssertEqualObjects([mergedArray objectAtIndex:0], @"abc.def"); + XCTAssertEqualObjects([mergedArray objectAtIndex:1], @"abc.ghi"); } - (void)testMergingTwoOneItemArraysThatDontMatchWithMerger { @@ -89,13 +89,13 @@ NSArray *arrayB = [NSArray arrayWithObject:@"abc.ghi"]; NSArray *mergedArray = [arrayA gtm_mergeArray:arrayB mergeSelector:@selector(mergeString:)]; - STAssertNotNil(mergedArray, - @"merge of two non empty arrays with merger should render " - @"an array"); - STAssertEquals([mergedArray count], (NSUInteger)2, + XCTAssertNotNil(mergedArray, + @"merge of two non empty arrays with merger should render " + @"an array"); + XCTAssertEqual([mergedArray count], (NSUInteger)2, @"merged array should have two items"); - STAssertEqualObjects([mergedArray objectAtIndex:0], @"abc.def", nil); - STAssertEqualObjects([mergedArray objectAtIndex:1], @"abc.ghi", nil); + XCTAssertEqualObjects([mergedArray objectAtIndex:0], @"abc.def"); + XCTAssertEqualObjects([mergedArray objectAtIndex:1], @"abc.ghi"); } - (void)testMergingTwoOneItemArraysThatMatch { @@ -103,13 +103,13 @@ NSArray *arrayB = [NSArray arrayWithObject:@"abc.def"]; NSArray *mergedArray = [arrayA gtm_mergeArray:arrayB mergeSelector:nil]; - STAssertNotNil(mergedArray, - @"merge of two matching arrays with no merger should render " - @"an array"); - STAssertEquals([mergedArray count], (NSUInteger)2, + XCTAssertNotNil(mergedArray, + @"merge of two matching arrays with no merger should render " + @"an array"); + XCTAssertEqual([mergedArray count], (NSUInteger)2, @"merged array with no merger should have two items"); - STAssertEqualObjects([mergedArray objectAtIndex:0], @"abc.def", nil); - STAssertEqualObjects([mergedArray objectAtIndex:1], @"abc.def", nil); + XCTAssertEqualObjects([mergedArray objectAtIndex:0], @"abc.def"); + XCTAssertEqualObjects([mergedArray objectAtIndex:1], @"abc.def"); } - (void)testMergingTwoOneItemArraysThatMatchWithMerger { @@ -117,12 +117,12 @@ NSArray *arrayB = [NSArray arrayWithObject:@"abc.def"]; NSArray *mergedArray = [arrayA gtm_mergeArray:arrayB mergeSelector:@selector(mergeString:)]; - STAssertNotNil(mergedArray, - @"merge of two matching arrays with merger should render " - @"an array"); - STAssertEquals([mergedArray count], (NSUInteger)1, + XCTAssertNotNil(mergedArray, + @"merge of two matching arrays with merger should render " + @"an array"); + XCTAssertEqual([mergedArray count], (NSUInteger)1, @"merged array with merger should have one items"); - STAssertEqualObjects([mergedArray objectAtIndex:0], @"abc.def", nil); + XCTAssertEqualObjects([mergedArray objectAtIndex:0], @"abc.def"); } - (void)testMergingMultipleItemArray { @@ -141,10 +141,10 @@ nil]; NSArray *mergedArray = [arrayA gtm_mergeArray:arrayB mergeSelector:nil]; - STAssertNotNil(mergedArray, - @"merge of two non empty arrays with no merger should render " - @"an array"); - STAssertEquals([mergedArray count], (NSUInteger)9, + XCTAssertNotNil(mergedArray, + @"merge of two non empty arrays with no merger should render " + @"an array"); + XCTAssertEqual([mergedArray count], (NSUInteger)9, @"merged array should have 9 items"); } @@ -164,10 +164,10 @@ nil]; NSArray *mergedArray = [arrayA gtm_mergeArray:arrayB mergeSelector:@selector(mergeString:)]; - STAssertNotNil(mergedArray, - @"merge of two non empty arrays with merger should render " - @"an array"); - STAssertEquals([mergedArray count], (NSUInteger)7, + XCTAssertNotNil(mergedArray, + @"merge of two non empty arrays with merger should render " + @"an array"); + XCTAssertEqual([mergedArray count], (NSUInteger)7, @"merged array should have 7 items"); } @@ -175,35 +175,34 @@ NSArray *arrayA = [NSArray arrayWithObjects:@"xyz", @"abc", @"mno", nil]; NSArray *arrayB = [NSArray array]; NSArray *expected = [NSArray arrayWithObjects:@"abc", @"mno", @"xyz", nil]; - STAssertNotNil(arrayA, nil); - STAssertNotNil(arrayB, nil); - STAssertNotNil(expected, nil); + XCTAssertNotNil(arrayA); + XCTAssertNotNil(arrayB); + XCTAssertNotNil(expected); NSArray *mergedArray; // no merger mergedArray = [arrayA gtm_mergeArray:arrayB mergeSelector:nil]; - STAssertNotNil(mergedArray, nil); - STAssertEqualObjects(mergedArray, expected, nil); + XCTAssertNotNil(mergedArray); + XCTAssertEqualObjects(mergedArray, expected); // w/ merger mergedArray = [arrayA gtm_mergeArray:arrayB mergeSelector:@selector(mergeString:)]; - STAssertNotNil(mergedArray, nil); - STAssertEqualObjects(mergedArray, expected, nil); + XCTAssertNotNil(mergedArray); + XCTAssertEqualObjects(mergedArray, expected); // no merger and array args reversed mergedArray = [arrayB gtm_mergeArray:arrayA mergeSelector:nil]; - STAssertNotNil(mergedArray, nil); - STAssertEqualObjects(mergedArray, expected, nil); + XCTAssertNotNil(mergedArray); + XCTAssertEqualObjects(mergedArray, expected); // w/ merger and array args reversed mergedArray = [arrayB gtm_mergeArray:arrayA mergeSelector:@selector(mergeString:)]; - STAssertNotNil(mergedArray, nil); - STAssertEqualObjects(mergedArray, expected, nil); - + XCTAssertNotNil(mergedArray); + XCTAssertEqualObjects(mergedArray, expected); } @end diff --git a/Foundation/GTMNSData+zlib.h b/Foundation/GTMNSData+zlib.h index 08fbb9a..dceadc4 100644 --- a/Foundation/GTMNSData+zlib.h +++ b/Foundation/GTMNSData+zlib.h @@ -33,22 +33,34 @@ // Uses the default compression level. + (NSData *)gtm_dataByGzippingBytes:(const void *)bytes length:(NSUInteger)length; ++ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of gzipping the payload of |data|. // // Uses the default compression level. -+ (NSData *)gtm_dataByGzippingData:(NSData *)data; ++ (NSData *)gtm_dataByGzippingData:(NSData *)data __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByGzippingData:(NSData *)data + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of gzipping the bytes using |level| compression level. // // |level| can be 1-9, any other values will be clipped to that range. + (NSData *)gtm_dataByGzippingBytes:(const void *)bytes length:(NSUInteger)length - compressionLevel:(int)level; + compressionLevel:(int)level __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes + length:(NSUInteger)length + compressionLevel:(int)level + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of gzipping the payload of |data| using |level| compression level. + (NSData *)gtm_dataByGzippingData:(NSData *)data - compressionLevel:(int)level; + compressionLevel:(int)level __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByGzippingData:(NSData *)data + compressionLevel:(int)level + error:(NSError **)error; #pragma mark Zlib "Stream" Compression @@ -59,23 +71,35 @@ // // Uses the default compression level. + (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes - length:(NSUInteger)length; + length:(NSUInteger)length __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of deflating the payload of |data|. // // Uses the default compression level. -+ (NSData *)gtm_dataByDeflatingData:(NSData *)data; ++ (NSData *)gtm_dataByDeflatingData:(NSData *)data __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByDeflatingData:(NSData *)data + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of deflating the bytes using |level| compression level. // // |level| can be 1-9, any other values will be clipped to that range. + (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes length:(NSUInteger)length - compressionLevel:(int)level; + compressionLevel:(int)level __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + compressionLevel:(int)level + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of deflating the payload of |data| using |level| compression level. + (NSData *)gtm_dataByDeflatingData:(NSData *)data - compressionLevel:(int)level; + compressionLevel:(int)level __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByDeflatingData:(NSData *)data + compressionLevel:(int)level + error:(NSError **)error; #pragma mark Uncompress of Gzip or Zlib @@ -83,13 +107,17 @@ // // The bytes to decompress can be zlib or gzip payloads. + (NSData *)gtm_dataByInflatingBytes:(const void *)bytes - length:(NSUInteger)length; + length:(NSUInteger)length __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of decompressing the payload of |data|. // // The data to decompress can be zlib or gzip payloads. -+ (NSData *)gtm_dataByInflatingData:(NSData *)data; - ++ (NSData *)gtm_dataByInflatingData:(NSData *)data __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByInflatingData:(NSData *)data + error:(NSError **)error; #pragma mark "Raw" Compression Support @@ -103,13 +131,18 @@ // Uses the default compression level. // *No* header is added to the resulting data. + (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes - length:(NSUInteger)length; + length:(NSUInteger)length __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of *raw* deflating the payload of |data|. // // Uses the default compression level. // *No* header is added to the resulting data. -+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data; ++ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of *raw* deflating the bytes using |level| compression level. // @@ -117,22 +150,50 @@ // *No* header is added to the resulting data. + (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes length:(NSUInteger)length - compressionLevel:(int)level; + compressionLevel:(int)level __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + compressionLevel:(int)level + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of *raw* deflating the payload of |data| using |level| compression level. // *No* header is added to the resulting data. + (NSData *)gtm_dataByRawDeflatingData:(NSData *)data - compressionLevel:(int)level; + compressionLevel:(int)level __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data + compressionLevel:(int)level + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of *raw* decompressing the bytes. // // The data to decompress, it should *not* have any header (zlib nor gzip). + (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes - length:(NSUInteger)length; + length:(NSUInteger)length __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **)error; /// Return an autoreleased NSData w/ the result of *raw* decompressing the payload of |data|. // // The data to decompress, it should *not* have any header (zlib nor gzip). -+ (NSData *)gtm_dataByRawInflatingData:(NSData *)data; ++ (NSData *)gtm_dataByRawInflatingData:(NSData *)data __attribute__((deprecated("Use error variant"))); ++ (NSData *)gtm_dataByRawInflatingData:(NSData *)data + error:(NSError **)error; @end + +FOUNDATION_EXPORT NSString *const GTMNSDataZlibErrorDomain; +FOUNDATION_EXPORT NSString *const GTMNSDataZlibErrorKey; // NSNumber +FOUNDATION_EXPORT NSString *const GTMNSDataZlibRemainingBytesKey; // NSNumber + +typedef NS_ENUM(NSInteger, GTMNSDataZlibError) { + GTMNSDataZlibErrorGreaterThan32BitsToCompress = 1024, + // An internal zlib error. + // GTMNSDataZlibErrorKey will contain the error value. + // NSLocalizedDescriptionKey may contain an error string from zlib. + // Look in zlib.h for list of errors. + GTMNSDataZlibErrorInternal, + // There was left over data in the buffer that was not used. + // GTMNSDataZlibRemainingBytesKey will contain number of remaining bytes. + GTMNSDataZlibErrorDataRemaining +}; diff --git a/Foundation/GTMNSData+zlib.m b/Foundation/GTMNSData+zlib.m index 4f8df8c..bf74b2d 100644 --- a/Foundation/GTMNSData+zlib.m +++ b/Foundation/GTMNSData+zlib.m @@ -20,12 +20,12 @@ #import <zlib.h> #import "GTMDefines.h" -// Export a nonsense symbol to suppress a libtool warning when this is linked alone in a static lib. -__attribute__((visibility("default"))) char GTMNSDataZLibExportToSuppressLibToolWarning = 0; - - #define kChunkSize 1024 +NSString *const GTMNSDataZlibErrorDomain = @"com.google.GTMNSDataZlibErrorDomain"; +NSString *const GTMNSDataZlibErrorKey = @"GTMNSDataZlibErrorKey"; +NSString *const GTMNSDataZlibRemainingBytesKey = @"GTMNSDataZlibRemainingBytesKey"; + typedef enum { CompressionModeZlib, CompressionModeGzip, @@ -36,10 +36,12 @@ typedef enum { + (NSData *)gtm_dataByCompressingBytes:(const void *)bytes length:(NSUInteger)length compressionLevel:(int)level - mode:(CompressionMode)mode; + mode:(CompressionMode)mode + error:(NSError **)error; + (NSData *)gtm_dataByInflatingBytes:(const void *)bytes length:(NSUInteger)length - isRawData:(BOOL)isRawData; + isRawData:(BOOL)isRawData + error:(NSError **)error; @end @implementation NSData (GTMZlibAdditionsPrivate) @@ -47,7 +49,8 @@ typedef enum { + (NSData *)gtm_dataByCompressingBytes:(const void *)bytes length:(NSUInteger)length compressionLevel:(int)level - mode:(CompressionMode)mode { + mode:(CompressionMode)mode + error:(NSError **)error { if (!bytes || !length) { return nil; } @@ -55,6 +58,11 @@ typedef enum { #if defined(__LP64__) && __LP64__ // Don't support > 32bit length for 64 bit, see note in header. if (length > UINT_MAX) { + if (error) { + *error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain + code:GTMNSDataZlibErrorGreaterThan32BitsToCompress + userInfo:nil]; + } return nil; } #endif @@ -90,8 +98,13 @@ typedef enum { if ((retCode = deflateInit2(&strm, level, Z_DEFLATED, windowBits, memLevel, Z_DEFAULT_STRATEGY)) != Z_OK) { // COV_NF_START - no real way to force this in a unittest (we guard all args) - _GTMDevLog(@"Failed to init for deflate w/ level %d, error %d", - level, retCode); + if (error) { + NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode] + forKey:GTMNSDataZlibErrorKey]; + *error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain + code:GTMNSDataZlibErrorInternal + userInfo:userInfo]; + } return nil; // COV_NF_END } @@ -115,8 +128,13 @@ typedef enum { // (in inflate, we can feed bogus/truncated data to test, but an error // here would be some internal issue w/in zlib, and there isn't any real // way to test it) - _GTMDevLog(@"Error trying to deflate some of the payload, error %d", - retCode); + if (error) { + NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode] + forKey:GTMNSDataZlibErrorKey]; + *error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain + code:GTMNSDataZlibErrorInternal + userInfo:userInfo]; + } deflateEnd(&strm); return nil; // COV_NF_END @@ -145,7 +163,8 @@ typedef enum { + (NSData *)gtm_dataByInflatingBytes:(const void *)bytes length:(NSUInteger)length - isRawData:(BOOL)isRawData { + isRawData:(BOOL)isRawData + error:(NSError **)error { if (!bytes || !length) { return nil; } @@ -174,7 +193,13 @@ typedef enum { int retCode; if ((retCode = inflateInit2(&strm, windowBits)) != Z_OK) { // COV_NF_START - no real way to force this in a unittest (we guard all args) - _GTMDevLog(@"Failed to init for inflate, error %d", retCode); + if (error) { + NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode] + forKey:GTMNSDataZlibErrorKey]; + *error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain + code:GTMNSDataZlibErrorInternal + userInfo:userInfo]; + } return nil; // COV_NF_END } @@ -190,8 +215,20 @@ typedef enum { strm.next_out = output; retCode = inflate(&strm, Z_NO_FLUSH); if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) { - _GTMDevLog(@"Error trying to inflate some of the payload, error %d: %s", - retCode, strm.msg); + if (error) { + NSMutableDictionary *userInfo = + [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode] + forKey:GTMNSDataZlibErrorKey]; + if (strm.msg) { + NSString *message = [NSString stringWithUTF8String:strm.msg]; + if (message) { + [userInfo setObject:message forKey:NSLocalizedDescriptionKey]; + } + } + *error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain + code:GTMNSDataZlibErrorInternal + userInfo:userInfo]; + } inflateEnd(&strm); return nil; } @@ -206,8 +243,14 @@ typedef enum { // make sure there wasn't more data tacked onto the end of a valid compressed // stream. if (strm.avail_in != 0) { - _GTMDevLog(@"thought we finished inflate w/o using all input, %u bytes left", - strm.avail_in); + if (error) { + NSDictionary *userInfo = + [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:strm.avail_in] + forKey:GTMNSDataZlibRemainingBytesKey]; + *error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain + code:GTMNSDataZlibErrorDataRemaining + userInfo:userInfo]; + } result = nil; } // the only way out of the loop was by hitting the end of the stream @@ -228,69 +271,135 @@ typedef enum { + (NSData *)gtm_dataByGzippingBytes:(const void *)bytes length:(NSUInteger)length { + return [self gtm_dataByGzippingBytes:bytes length:length error:NULL]; +} // gtm_dataByGzippingBytes:length: + ++ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **)error { return [self gtm_dataByCompressingBytes:bytes length:length compressionLevel:Z_DEFAULT_COMPRESSION - mode:CompressionModeGzip]; -} // gtm_dataByGzippingBytes:length: + mode:CompressionModeGzip + error:error]; +} // gtm_dataByGzippingBytes:length:error: + (NSData *)gtm_dataByGzippingData:(NSData *)data { + return [self gtm_dataByGzippingData:data error:NULL]; +} // gtm_dataByGzippingData: + ++ (NSData *)gtm_dataByGzippingData:(NSData *)data error:(NSError **)error { return [self gtm_dataByCompressingBytes:[data bytes] length:[data length] compressionLevel:Z_DEFAULT_COMPRESSION - mode:CompressionModeGzip]; -} // gtm_dataByGzippingData: + mode:CompressionModeGzip + error:error]; +} // gtm_dataByGzippingData:error: + (NSData *)gtm_dataByGzippingBytes:(const void *)bytes length:(NSUInteger)length compressionLevel:(int)level { + return [self gtm_dataByGzippingBytes:bytes + length:length + compressionLevel:level + error:NULL]; +} // gtm_dataByGzippingBytes:length:level: + ++ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes + length:(NSUInteger)length + compressionLevel:(int)level + error:(NSError **)error{ return [self gtm_dataByCompressingBytes:bytes length:length compressionLevel:level - mode:CompressionModeGzip]; -} // gtm_dataByGzippingBytes:length:level: + mode:CompressionModeGzip + error:error]; +} // gtm_dataByGzippingBytes:length:level:error + (NSData *)gtm_dataByGzippingData:(NSData *)data compressionLevel:(int)level { + return [self gtm_dataByGzippingData:data + compressionLevel:level + error:NULL]; +} // gtm_dataByGzippingData:level: + ++ (NSData *)gtm_dataByGzippingData:(NSData *)data + compressionLevel:(int)level + error:(NSError **)error{ return [self gtm_dataByCompressingBytes:[data bytes] length:[data length] compressionLevel:level - mode:CompressionModeGzip]; -} // gtm_dataByGzippingData:level: + mode:CompressionModeGzip + error:error]; +} // gtm_dataByGzippingData:level:error #pragma mark - + (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes length:(NSUInteger)length { + return [self gtm_dataByDeflatingBytes:bytes + length:length + error:NULL]; +} // gtm_dataByDeflatingBytes:length: + ++ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **)error{ return [self gtm_dataByCompressingBytes:bytes length:length compressionLevel:Z_DEFAULT_COMPRESSION - mode:CompressionModeZlib]; -} // gtm_dataByDeflatingBytes:length: + mode:CompressionModeZlib + error:error]; +} // gtm_dataByDeflatingBytes:length:error + (NSData *)gtm_dataByDeflatingData:(NSData *)data { + return [self gtm_dataByDeflatingData:data error:NULL]; +} // gtm_dataByDeflatingData: + ++ (NSData *)gtm_dataByDeflatingData:(NSData *)data error:(NSError **)error { return [self gtm_dataByCompressingBytes:[data bytes] length:[data length] compressionLevel:Z_DEFAULT_COMPRESSION - mode:CompressionModeZlib]; + mode:CompressionModeZlib + error:error]; } // gtm_dataByDeflatingData: + (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes length:(NSUInteger)length compressionLevel:(int)level { + return [self gtm_dataByDeflatingBytes:bytes + length:length + compressionLevel:level + error:NULL]; +} // gtm_dataByDeflatingBytes:length:level: + ++ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + compressionLevel:(int)level + error:(NSError **)error { return [self gtm_dataByCompressingBytes:bytes length:length compressionLevel:level - mode:CompressionModeZlib]; -} // gtm_dataByDeflatingBytes:length:level: + mode:CompressionModeZlib + error:error]; +} // gtm_dataByDeflatingBytes:length:level:error: + (NSData *)gtm_dataByDeflatingData:(NSData *)data compressionLevel:(int)level { + return [self gtm_dataByDeflatingData:data + compressionLevel:level + error:NULL]; +} // gtm_dataByDeflatingData:level: + ++ (NSData *)gtm_dataByDeflatingData:(NSData *)data + compressionLevel:(int)level + error:(NSError **)error { return [self gtm_dataByCompressingBytes:[data bytes] length:[data length] compressionLevel:level - mode:CompressionModeZlib]; -} // gtm_dataByDeflatingData:level: + mode:CompressionModeZlib + error:error]; +} // gtm_dataByDeflatingData:level:error: #pragma mark - @@ -298,60 +407,125 @@ typedef enum { length:(NSUInteger)length { return [self gtm_dataByInflatingBytes:bytes length:length - isRawData:NO]; + error:NULL]; } // gtm_dataByInflatingBytes:length: ++ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **)error { + return [self gtm_dataByInflatingBytes:bytes + length:length + isRawData:NO + error:error]; +} // gtm_dataByInflatingBytes:length:error: + + (NSData *)gtm_dataByInflatingData:(NSData *)data { + return [self gtm_dataByInflatingData:data error:NULL]; +} // gtm_dataByInflatingData: + ++ (NSData *)gtm_dataByInflatingData:(NSData *)data + error:(NSError **)error { return [self gtm_dataByInflatingBytes:[data bytes] length:[data length] - isRawData:NO]; + isRawData:NO + error:error]; } // gtm_dataByInflatingData: #pragma mark - + (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes length:(NSUInteger)length { + return [self gtm_dataByRawDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + error:NULL]; +} // gtm_dataByRawDeflatingBytes:length: + ++ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **)error { return [self gtm_dataByCompressingBytes:bytes length:length compressionLevel:Z_DEFAULT_COMPRESSION - mode:CompressionModeRaw]; -} // gtm_dataByRawDeflatingBytes:length: + mode:CompressionModeRaw + error:error]; +} // gtm_dataByRawDeflatingBytes:length:error: + (NSData *)gtm_dataByRawDeflatingData:(NSData *)data { + return [self gtm_dataByRawDeflatingData:data error:NULL]; +} // gtm_dataByRawDeflatingData: + ++ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data error:(NSError **)error { return [self gtm_dataByCompressingBytes:[data bytes] length:[data length] compressionLevel:Z_DEFAULT_COMPRESSION - mode:CompressionModeRaw]; -} // gtm_dataByRawDeflatingData: + mode:CompressionModeRaw + error:error]; +} // gtm_dataByRawDeflatingData:error: + (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes length:(NSUInteger)length compressionLevel:(int)level { + return [self gtm_dataByRawDeflatingBytes:bytes + length:length + compressionLevel:level + error:NULL]; +} // gtm_dataByRawDeflatingBytes:length:compressionLevel: + ++ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes + length:(NSUInteger)length + compressionLevel:(int)level + error:(NSError **)error{ return [self gtm_dataByCompressingBytes:bytes length:length compressionLevel:level - mode:CompressionModeRaw]; -} // gtm_dataByRawDeflatingBytes:length:compressionLevel: + mode:CompressionModeRaw + error:error]; +} // gtm_dataByRawDeflatingBytes:length:compressionLevel:error: + (NSData *)gtm_dataByRawDeflatingData:(NSData *)data compressionLevel:(int)level { + return [self gtm_dataByRawDeflatingData:data + compressionLevel:level + error:NULL]; +} // gtm_dataByRawDeflatingData:compressionLevel: + ++ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data + compressionLevel:(int)level + error:(NSError **)error { return [self gtm_dataByCompressingBytes:[data bytes] length:[data length] compressionLevel:level - mode:CompressionModeRaw]; -} // gtm_dataByRawDeflatingData:compressionLevel: + mode:CompressionModeRaw + error:error]; +} // gtm_dataByRawDeflatingData:compressionLevel:error: + (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes length:(NSUInteger)length { return [self gtm_dataByInflatingBytes:bytes length:length - isRawData:YES]; + error:NULL]; } // gtm_dataByRawInflatingBytes:length: ++ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes + length:(NSUInteger)length + error:(NSError **)error{ + return [self gtm_dataByInflatingBytes:bytes + length:length + isRawData:YES + error:error]; +} // gtm_dataByRawInflatingBytes:length:error: + + (NSData *)gtm_dataByRawInflatingData:(NSData *)data { + return [self gtm_dataByRawInflatingData:data + error:NULL]; +} // gtm_dataByRawInflatingData: + ++ (NSData *)gtm_dataByRawInflatingData:(NSData *)data + error:(NSError **)error { return [self gtm_dataByInflatingBytes:[data bytes] length:[data length] - isRawData:YES]; -} // gtm_dataByRawInflatingData: + isRawData:YES + error:error]; +} // gtm_dataByRawInflatingData:error: @end diff --git a/Foundation/GTMNSData+zlibTest.m b/Foundation/GTMNSData+zlibTest.m index 8a14919..4f3acc1 100644 --- a/Foundation/GTMNSData+zlibTest.m +++ b/Foundation/GTMNSData+zlibTest.m @@ -17,9 +17,8 @@ // #import "GTMSenTestCase.h" -#import "GTMUnitTestDevLog.h" #import "GTMNSData+zlib.h" -#import <stdlib.h> // for randiom/srandomdev +#import <stdlib.h> // for random/srandomdev #import <zlib.h> @interface GTMNSData_zlibTest : GTMTestCase @@ -91,405 +90,526 @@ static BOOL HasGzipHeader(NSData *data) { ((bytes[0] == 0x1f) && (bytes[1] == 0x8b)); } +#define GTMCheckZLibError(error, errorCode) \ + XCTAssertEqual([error code], GTMNSDataZlibErrorInternal); \ + XCTAssertEqualObjects([error domain], GTMNSDataZlibErrorDomain); \ + XCTAssertEqualObjects([[error userInfo] objectForKey:GTMNSDataZlibErrorKey], \ + [NSNumber numberWithInt:errorCode]); \ + error = nil + +#define GTMCheckRemainingError(error, bytes) \ + XCTAssertEqual([error code], GTMNSDataZlibErrorDataRemaining); \ + XCTAssertEqualObjects([error domain], GTMNSDataZlibErrorDomain); \ + XCTAssertEqualObjects([[error userInfo] objectForKey:GTMNSDataZlibRemainingBytesKey], \ + [NSNumber numberWithInt:bytes]); \ + error = nil @implementation GTMNSData_zlibTest -- (void)testBoundryValues { +- (void)testBoundaryValues { // build some test data NSData *data = [NSData dataWithBytes:randomDataLarge length:sizeof(randomDataLarge)]; - STAssertNotNil(data, @"failed to alloc data block"); + XCTAssertNotNil(data, @"failed to alloc data block"); // bogus args to start - STAssertNil([NSData gtm_dataByDeflatingData:nil], nil); - STAssertNil([NSData gtm_dataByDeflatingBytes:nil length:666], nil); - STAssertNil([NSData gtm_dataByDeflatingBytes:[data bytes] length:0], nil); - STAssertNil([NSData gtm_dataByGzippingData:nil], nil); - STAssertNil([NSData gtm_dataByGzippingBytes:nil length:666], nil); - STAssertNil([NSData gtm_dataByGzippingBytes:[data bytes] length:0], nil); - STAssertNil([NSData gtm_dataByInflatingData:nil], nil); - STAssertNil([NSData gtm_dataByInflatingBytes:nil length:666], nil); - STAssertNil([NSData gtm_dataByInflatingBytes:[data bytes] length:0], nil); - STAssertNil([NSData gtm_dataByRawDeflatingData:nil], nil); - STAssertNil([NSData gtm_dataByRawDeflatingBytes:nil length:666], nil); - STAssertNil([NSData gtm_dataByRawDeflatingBytes:[data bytes] length:0], nil); - STAssertNil([NSData gtm_dataByRawInflatingData:nil], nil); - STAssertNil([NSData gtm_dataByRawInflatingBytes:nil length:666], nil); - STAssertNil([NSData gtm_dataByRawInflatingBytes:[data bytes] length:0], nil); + NSError *error = nil; + XCTAssertNil([NSData gtm_dataByDeflatingData:nil error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByDeflatingBytes:nil length:666 error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByDeflatingBytes:[data bytes] length:0 error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByGzippingData:nil error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByGzippingBytes:nil length:666 error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByGzippingBytes:[data bytes] length:0 error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByInflatingData:nil error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByInflatingBytes:nil length:666 error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByInflatingBytes:[data bytes] length:0 error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByRawDeflatingData:nil error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByRawDeflatingBytes:nil length:666 error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByRawDeflatingBytes:[data bytes] length:0 error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByRawInflatingData:nil error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByRawInflatingBytes:nil length:666 error:&error]); + XCTAssertNil(error); + error = nil; + XCTAssertNil([NSData gtm_dataByRawInflatingBytes:[data bytes] length:0 error:&error]); + XCTAssertNil(error); + error = nil; // test deflate w/ compression levels out of range NSData *deflated = [NSData gtm_dataByDeflatingData:data - compressionLevel:-4]; - STAssertNotNil(deflated, nil); - STAssertFalse(HasGzipHeader(deflated), nil); - NSData *dataPrime = [NSData gtm_dataByInflatingData:deflated]; - STAssertNotNil(dataPrime, nil); - STAssertEqualObjects(data, dataPrime, nil); + compressionLevel:-4 + error:&error]; + XCTAssertNotNil(deflated); + XCTAssertNil(error); + error = nil; + XCTAssertFalse(HasGzipHeader(deflated)); + NSData *dataPrime = [NSData gtm_dataByInflatingData:deflated error:&error]; + XCTAssertNotNil(dataPrime); + XCTAssertEqualObjects(data, dataPrime); + XCTAssertNil(error); + error = nil; deflated = [NSData gtm_dataByDeflatingData:data - compressionLevel:20]; - STAssertNotNil(deflated, nil); - STAssertFalse(HasGzipHeader(deflated), nil); - dataPrime = [NSData gtm_dataByInflatingData:deflated]; - STAssertNotNil(dataPrime, nil); - STAssertEqualObjects(data, dataPrime, nil); + compressionLevel:20 + error:&error]; + XCTAssertNotNil(deflated); + XCTAssertFalse(HasGzipHeader(deflated)); + XCTAssertNil(error); + error = nil; + dataPrime = [NSData gtm_dataByInflatingData:deflated error:&error]; + XCTAssertNotNil(dataPrime); + XCTAssertEqualObjects(data, dataPrime); + XCTAssertNil(error); + error = nil; // test gzip w/ compression levels out of range NSData *gzipped = [NSData gtm_dataByGzippingData:data - compressionLevel:-4]; - STAssertNotNil(gzipped, nil); - STAssertTrue(HasGzipHeader(gzipped), nil); - dataPrime = [NSData gtm_dataByInflatingData:gzipped]; - STAssertNotNil(dataPrime, nil); - STAssertEqualObjects(data, dataPrime, nil); + compressionLevel:-4 + error:&error]; + XCTAssertNotNil(gzipped); + XCTAssertNil(error); + error = nil; + XCTAssertTrue(HasGzipHeader(gzipped)); + dataPrime = [NSData gtm_dataByInflatingData:gzipped error:&error]; + XCTAssertNotNil(dataPrime); + XCTAssertEqualObjects(data, dataPrime); + XCTAssertNil(error); + error = nil; gzipped = [NSData gtm_dataByGzippingData:data - compressionLevel:20]; - STAssertNotNil(gzipped, nil); - STAssertTrue(HasGzipHeader(gzipped), nil); - dataPrime = [NSData gtm_dataByInflatingData:gzipped]; - STAssertNotNil(dataPrime, nil); - STAssertEqualObjects(data, dataPrime, nil); + compressionLevel:20 + error:&error]; + XCTAssertNotNil(gzipped); + XCTAssertTrue(HasGzipHeader(gzipped)); + XCTAssertNil(error); + error = nil; + dataPrime = [NSData gtm_dataByInflatingData:gzipped error:&error]; + XCTAssertNotNil(dataPrime); + XCTAssertEqualObjects(data, dataPrime); + XCTAssertNil(error); + error = nil; // test raw deflate w/ compression levels out of range NSData *rawDeflated = [NSData gtm_dataByRawDeflatingData:data - compressionLevel:-4]; - STAssertNotNil(rawDeflated, nil); - STAssertFalse(HasGzipHeader(rawDeflated), nil); - dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated]; - STAssertNotNil(dataPrime, nil); - STAssertEqualObjects(data, dataPrime, nil); + compressionLevel:-4 + error:&error]; + XCTAssertNotNil(rawDeflated); + XCTAssertFalse(HasGzipHeader(rawDeflated)); + XCTAssertNil(error); + error = nil; + dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated error:&error]; + XCTAssertNotNil(dataPrime); + XCTAssertEqualObjects(data, dataPrime); + XCTAssertNil(error); + error = nil; rawDeflated = [NSData gtm_dataByRawDeflatingData:data - compressionLevel:20]; - STAssertNotNil(rawDeflated, nil); - STAssertFalse(HasGzipHeader(rawDeflated), nil); - dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated]; - STAssertNotNil(dataPrime, nil); - STAssertEqualObjects(data, dataPrime, nil); + compressionLevel:20 + error:&error]; + XCTAssertNotNil(rawDeflated); + XCTAssertFalse(HasGzipHeader(rawDeflated)); + XCTAssertNil(error); + error = nil; + dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated error:&error]; + XCTAssertNotNil(dataPrime); + XCTAssertEqualObjects(data, dataPrime); + XCTAssertNil(error); + error = nil; // test non-compressed data data itself - [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - @"payload, error -3: incorrect header check"]; - STAssertNil([NSData gtm_dataByInflatingData:data], nil); - + XCTAssertNil([NSData gtm_dataByInflatingData:data error:&error]); + GTMCheckZLibError(error, -3); // test deflated data runs that end before they are done - [GTMUnitTestDevLog expect:([deflated length] / 11) + 1 - casesOfString:@"Error trying to inflate some of the payload, " - @"error -5: (null)"]; for (NSUInteger x = 1 ; x < [deflated length] ; x += 11) { - STAssertNil([NSData gtm_dataByInflatingBytes:[deflated bytes] - length:x], nil); + XCTAssertNil([NSData gtm_dataByInflatingBytes:[deflated bytes] + length:x + error:&error]); + GTMCheckZLibError(error, -5); } // test gzipped data runs that end before they are done - [GTMUnitTestDevLog expect:([gzipped length] / 11) + 1 - casesOfString:@"Error trying to inflate some of the payload, " - @"error -5: (null)"]; for (NSUInteger x = 1 ; x < [gzipped length] ; x += 11) { - STAssertNil([NSData gtm_dataByInflatingBytes:[gzipped bytes] - length:x], nil); + XCTAssertNil([NSData gtm_dataByInflatingBytes:[gzipped bytes] + length:x + error:&error]); + GTMCheckZLibError(error, -5); } // test raw deflated data runs that end before they are done - [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - @"payload, error -5: (null)"]; - [GTMUnitTestDevLog expect:([rawDeflated length] / 11) - 1 - casesOfString:@"Error trying to inflate some of the payload, " - @"error -3: incorrect header check"]; for (NSUInteger x = 1 ; x < [rawDeflated length] ; x += 11) { - STAssertNil([NSData gtm_dataByInflatingBytes:[rawDeflated bytes] - length:x], nil); + XCTAssertNil([NSData gtm_dataByInflatingBytes:[rawDeflated bytes] + length:x + error:&error]); + int expectedError = (x == 1) ? -5 : -3; + GTMCheckZLibError(error, expectedError); } // test extra data before the deflated/gzipped data (just to make sure we // don't seek to the "real" data) NSMutableData *prefixedDeflated = [NSMutableData dataWithBytes:randomDataSmall length:sizeof(randomDataSmall)]; - STAssertNotNil(prefixedDeflated, @"failed to alloc data block"); + XCTAssertNotNil(prefixedDeflated, @"failed to alloc data block"); [prefixedDeflated appendData:deflated]; - [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - @"payload, error -3: incorrect header check"]; - STAssertNil([NSData gtm_dataByInflatingData:prefixedDeflated], nil); - [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - @"payload, error -3: incorrect header check"]; - STAssertNil([NSData gtm_dataByInflatingBytes:[prefixedDeflated bytes] - length:[prefixedDeflated length]], - nil); + XCTAssertNil([NSData gtm_dataByInflatingData:prefixedDeflated error:&error]); + GTMCheckZLibError(error, -3); + XCTAssertNil([NSData gtm_dataByInflatingBytes:[prefixedDeflated bytes] + length:[prefixedDeflated length] + error:&error]); + GTMCheckZLibError(error, -3); NSMutableData *prefixedGzipped = [NSMutableData dataWithBytes:randomDataSmall length:sizeof(randomDataSmall)]; - STAssertNotNil(prefixedDeflated, @"failed to alloc data block"); + XCTAssertNotNil(prefixedDeflated, @"failed to alloc data block"); [prefixedGzipped appendData:gzipped]; - [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - @"payload, error -3: incorrect header check"]; - STAssertNil([NSData gtm_dataByInflatingData:prefixedGzipped], nil); - [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - @"payload, error -3: incorrect header check"]; - STAssertNil([NSData gtm_dataByInflatingBytes:[prefixedGzipped bytes] - length:[prefixedGzipped length]], - nil); + XCTAssertNil([NSData gtm_dataByInflatingData:prefixedGzipped error:&error]); + GTMCheckZLibError(error, -3); + XCTAssertNil([NSData gtm_dataByInflatingBytes:[prefixedGzipped bytes] + length:[prefixedGzipped length] + error:&error]); + GTMCheckZLibError(error, -3); NSMutableData *prefixedRawDeflated = [NSMutableData dataWithBytes:randomDataSmall length:sizeof(randomDataSmall)]; - STAssertNotNil(prefixedRawDeflated, @"failed to alloc data block"); + XCTAssertNotNil(prefixedRawDeflated, @"failed to alloc data block"); [prefixedRawDeflated appendData:rawDeflated]; - [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - @"payload, error -3: invalid stored block lengths"]; - STAssertNil([NSData gtm_dataByRawInflatingData:prefixedRawDeflated], nil); - [GTMUnitTestDevLog expectString:@"Error trying to inflate some of the " - @"payload, error -3: invalid stored block lengths"]; - STAssertNil([NSData gtm_dataByRawInflatingBytes:[prefixedRawDeflated bytes] - length:[prefixedRawDeflated length]], - nil); + XCTAssertNil([NSData gtm_dataByRawInflatingData:prefixedRawDeflated error:&error]); + GTMCheckZLibError(error, -3); + XCTAssertNil([NSData gtm_dataByRawInflatingBytes:[prefixedRawDeflated bytes] + length:[prefixedRawDeflated length] + error:&error]); + GTMCheckZLibError(error, -3); // test extra data after the deflated/gzipped data (just to make sure we // don't ignore some of the data) NSMutableData *suffixedDeflated = [NSMutableData data]; - STAssertNotNil(suffixedDeflated, @"failed to alloc data block"); + XCTAssertNotNil(suffixedDeflated, @"failed to alloc data block"); [suffixedDeflated appendData:deflated]; [suffixedDeflated appendBytes:[data bytes] length:20]; - [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " - @"all input, 20 bytes left"]; - STAssertNil([NSData gtm_dataByInflatingData:suffixedDeflated], nil); - [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " - @"all input, 20 bytes left"]; - STAssertNil([NSData gtm_dataByInflatingBytes:[suffixedDeflated bytes] - length:[suffixedDeflated length]], - nil); + XCTAssertNil([NSData gtm_dataByInflatingData:suffixedDeflated + error:&error]); + GTMCheckRemainingError(error, 20); + XCTAssertNil([NSData gtm_dataByInflatingBytes:[suffixedDeflated bytes] + length:[suffixedDeflated length] + error:&error]); + GTMCheckRemainingError(error, 20); NSMutableData *suffixedGZipped = [NSMutableData data]; - STAssertNotNil(suffixedGZipped, @"failed to alloc data block"); + XCTAssertNotNil(suffixedGZipped, @"failed to alloc data block"); [suffixedGZipped appendData:gzipped]; [suffixedGZipped appendBytes:[data bytes] length:20]; - [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " - @"all input, 20 bytes left"]; - STAssertNil([NSData gtm_dataByInflatingData:suffixedGZipped], nil); - [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " - @"all input, 20 bytes left"]; - STAssertNil([NSData gtm_dataByInflatingBytes:[suffixedGZipped bytes] - length:[suffixedGZipped length]], - nil); + XCTAssertNil([NSData gtm_dataByInflatingData:suffixedGZipped error:&error]); + GTMCheckRemainingError(error, 20); + XCTAssertNil([NSData gtm_dataByInflatingBytes:[suffixedGZipped bytes] + length:[suffixedGZipped length] + error:&error]); + GTMCheckRemainingError(error, 20); NSMutableData *suffixedRawDeflated = [NSMutableData data]; - STAssertNotNil(suffixedRawDeflated, @"failed to alloc data block"); + XCTAssertNotNil(suffixedRawDeflated, @"failed to alloc data block"); [suffixedRawDeflated appendData:rawDeflated]; [suffixedRawDeflated appendBytes:[data bytes] length:20]; - [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " - @"all input, 20 bytes left"]; - STAssertNil([NSData gtm_dataByRawInflatingData:suffixedRawDeflated], nil); - [GTMUnitTestDevLog expectString:@"thought we finished inflate w/o using " - @"all input, 20 bytes left"]; - STAssertNil([NSData gtm_dataByRawInflatingBytes:[suffixedRawDeflated bytes] - length:[suffixedRawDeflated length]], - nil); + XCTAssertNil([NSData gtm_dataByRawInflatingData:suffixedRawDeflated error:&error]); + GTMCheckRemainingError(error, 20); + XCTAssertNil([NSData gtm_dataByRawInflatingBytes:[suffixedRawDeflated bytes] + length:[suffixedRawDeflated length] + error:&error]); + GTMCheckRemainingError(error, 20); } - (void)testInflateDeflate { NSData *data = [NSData dataWithBytes:randomDataLarge length:sizeof(randomDataLarge)]; - STAssertNotNil(data, @"failed to alloc data block"); + XCTAssertNotNil(data, @"failed to alloc data block"); // w/ *Bytes apis, default level + NSError *error = nil; NSData *deflated = [NSData gtm_dataByDeflatingBytes:[data bytes] - length:[data length]]; - STAssertNotNil(deflated, @"failed to deflate data block"); - STAssertGreaterThan([deflated length], - (NSUInteger)0, @"failed to deflate data block"); - STAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data"); + length:[data length] + error:&error]; + XCTAssertNotNil(deflated, @"failed to deflate data block"); + XCTAssertGreaterThan([deflated length], (NSUInteger)0, + @"failed to deflate data block"); + XCTAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data"); + XCTAssertNil(error); + error = nil; + NSData *dataPrime = [NSData gtm_dataByInflatingBytes:[deflated bytes] - length:[deflated length]]; - STAssertNotNil(dataPrime, @"failed to inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to inflate data block"); - STAssertEqualObjects(data, - dataPrime, @"failed to round trip via *Bytes apis"); + length:[deflated length] + error:&error]; + XCTAssertNotNil(dataPrime, @"failed to inflate data block"); + XCTAssertGreaterThan([dataPrime length], (NSUInteger)0, + @"failed to inflate data block"); + XCTAssertEqualObjects(data, dataPrime, + @"failed to round trip via *Bytes apis"); + XCTAssertNil(error); + error = nil; // w/ *Data apis, default level - deflated = [NSData gtm_dataByDeflatingData:data]; - STAssertNotNil(deflated, @"failed to deflate data block"); - STAssertGreaterThan([deflated length], - (NSUInteger)0, @"failed to deflate data block"); - STAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data"); - dataPrime = [NSData gtm_dataByInflatingData:deflated]; - STAssertNotNil(dataPrime, @"failed to inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to inflate data block"); - STAssertEqualObjects(data, - dataPrime, @"failed to round trip via *Data apis"); + deflated = [NSData gtm_dataByDeflatingData:data error:&error]; + XCTAssertNotNil(deflated, @"failed to deflate data block"); + XCTAssertGreaterThan([deflated length], (NSUInteger)0, + @"failed to deflate data block"); + XCTAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data"); + XCTAssertNil(error); + error = nil; + dataPrime = [NSData gtm_dataByInflatingData:deflated error:&error]; + + XCTAssertNotNil(dataPrime, @"failed to inflate data block"); + XCTAssertGreaterThan([dataPrime length], (NSUInteger)0, + @"failed to inflate data block"); + XCTAssertEqualObjects(data, dataPrime, + @"failed to round trip via *Data apis"); + XCTAssertNil(error); + error = nil; // loop over the compression levels for (int level = 1 ; level <= 9 ; ++level) { // w/ *Bytes apis, using our level deflated = [NSData gtm_dataByDeflatingBytes:[data bytes] length:[data length] - compressionLevel:level]; - STAssertNotNil(deflated, @"failed to deflate data block"); - STAssertGreaterThan([deflated length], - (NSUInteger)0, @"failed to deflate data block"); - STAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data"); + compressionLevel:level + error:&error]; + XCTAssertNotNil(deflated, @"failed to deflate data block"); + XCTAssertGreaterThan([deflated length], + (NSUInteger)0, @"failed to deflate data block"); + XCTAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data"); + XCTAssertNil(error); + error = nil; dataPrime = [NSData gtm_dataByInflatingBytes:[deflated bytes] - length:[deflated length]]; - STAssertNotNil(dataPrime, @"failed to inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to inflate data block"); - STAssertEqualObjects(data, - dataPrime, @"failed to round trip via *Bytes apis"); + length:[deflated length] + error:&error]; + XCTAssertNotNil(dataPrime, @"failed to inflate data block"); + XCTAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to inflate data block"); + XCTAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Bytes apis"); + XCTAssertNil(error); + error = nil; // w/ *Data apis, using our level - deflated = [NSData gtm_dataByDeflatingData:data compressionLevel:level]; - STAssertNotNil(deflated, @"failed to deflate data block"); - STAssertGreaterThan([deflated length], - (NSUInteger)0, @"failed to deflate data block"); - STAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data"); - dataPrime = [NSData gtm_dataByInflatingData:deflated]; - STAssertNotNil(dataPrime, @"failed to inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to inflate data block"); - STAssertEqualObjects(data, - dataPrime, @"failed to round trip via *Data apis"); + deflated = [NSData gtm_dataByDeflatingData:data compressionLevel:level error:&error]; + XCTAssertNotNil(deflated, @"failed to deflate data block"); + XCTAssertGreaterThan([deflated length], + (NSUInteger)0, @"failed to deflate data block"); + XCTAssertFalse(HasGzipHeader(deflated), @"has gzip header on zlib data"); + XCTAssertNil(error); + error = nil; + dataPrime = [NSData gtm_dataByInflatingData:deflated error:&error]; + XCTAssertNotNil(dataPrime, @"failed to inflate data block"); + XCTAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to inflate data block"); + XCTAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Data apis"); + XCTAssertNil(error); + error = nil; } } - (void)testInflateGzip { NSData *data = [NSData dataWithBytes:randomDataLarge length:sizeof(randomDataLarge)]; - STAssertNotNil(data, @"failed to alloc data block"); + XCTAssertNotNil(data, @"failed to alloc data block"); // w/ *Bytes apis, default level + NSError *error = nil; NSData *gzipped = [NSData gtm_dataByGzippingBytes:[data bytes] length:[data length]]; - STAssertNotNil(gzipped, @"failed to gzip data block"); - STAssertGreaterThan([gzipped length], - (NSUInteger)0, @"failed to gzip data block"); - STAssertTrue(HasGzipHeader(gzipped), - @"doesn't have gzip header on gzipped data"); + XCTAssertNotNil(gzipped, @"failed to gzip data block"); + XCTAssertGreaterThan([gzipped length], + (NSUInteger)0, @"failed to gzip data block"); + XCTAssertTrue(HasGzipHeader(gzipped), + @"doesn't have gzip header on gzipped data"); NSData *dataPrime = [NSData gtm_dataByInflatingBytes:[gzipped bytes] - length:[gzipped length]]; - STAssertNotNil(dataPrime, @"failed to inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to inflate data block"); - STAssertEqualObjects(data, - dataPrime, @"failed to round trip via *Bytes apis"); + length:[gzipped length] + error:&error]; + XCTAssertNotNil(dataPrime, @"failed to inflate data block"); + XCTAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to inflate data block"); + XCTAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Bytes apis"); + XCTAssertNil(error); + error = nil; // w/ *Data apis, default level - gzipped = [NSData gtm_dataByGzippingData:data]; - STAssertNotNil(gzipped, @"failed to gzip data block"); - STAssertGreaterThan([gzipped length], + gzipped = [NSData gtm_dataByGzippingData:data error:&error]; + XCTAssertNotNil(gzipped, @"failed to gzip data block"); + XCTAssertGreaterThan([gzipped length], (NSUInteger)0, @"failed to gzip data block"); - STAssertTrue(HasGzipHeader(gzipped), - @"doesn't have gzip header on gzipped data"); - dataPrime = [NSData gtm_dataByInflatingData:gzipped]; - STAssertNotNil(dataPrime, @"failed to inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to inflate data block"); - STAssertEqualObjects(data, dataPrime, - @"failed to round trip via *Data apis"); + XCTAssertTrue(HasGzipHeader(gzipped), + @"doesn't have gzip header on gzipped data"); + XCTAssertNil(error); + error = nil; + dataPrime = [NSData gtm_dataByInflatingData:gzipped error:&error]; + XCTAssertNotNil(dataPrime, @"failed to inflate data block"); + XCTAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to inflate data block"); + XCTAssertEqualObjects(data, dataPrime, + @"failed to round trip via *Data apis"); + XCTAssertNil(error); + error = nil; // loop over the compression levels for (int level = 1 ; level <= 9 ; ++level) { // w/ *Bytes apis, using our level gzipped = [NSData gtm_dataByGzippingBytes:[data bytes] length:[data length] - compressionLevel:level]; - STAssertNotNil(gzipped, @"failed to gzip data block"); - STAssertGreaterThan([gzipped length], - (NSUInteger)0, @"failed to gzip data block"); - STAssertTrue(HasGzipHeader(gzipped), - @"doesn't have gzip header on gzipped data"); + compressionLevel:level + error:&error]; + XCTAssertNotNil(gzipped, @"failed to gzip data block"); + XCTAssertGreaterThan([gzipped length], + (NSUInteger)0, @"failed to gzip data block"); + XCTAssertTrue(HasGzipHeader(gzipped), + @"doesn't have gzip header on gzipped data"); + XCTAssertNil(error); + error = nil; dataPrime = [NSData gtm_dataByInflatingBytes:[gzipped bytes] - length:[gzipped length]]; - STAssertNotNil(dataPrime, @"failed to inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to inflate data block"); - STAssertEqualObjects(data, dataPrime, - @"failed to round trip via *Bytes apis"); + length:[gzipped length] + error:&error]; + XCTAssertNotNil(dataPrime, @"failed to inflate data block"); + XCTAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to inflate data block"); + XCTAssertEqualObjects(data, dataPrime, + @"failed to round trip via *Bytes apis"); + XCTAssertNil(error); + error = nil; // w/ *Data apis, using our level - gzipped = [NSData gtm_dataByGzippingData:data compressionLevel:level]; - STAssertNotNil(gzipped, @"failed to gzip data block"); - STAssertGreaterThan([gzipped length], - (NSUInteger)0, @"failed to gzip data block"); - STAssertTrue(HasGzipHeader(gzipped), - @"doesn't have gzip header on gzipped data"); - dataPrime = [NSData gtm_dataByInflatingData:gzipped]; - STAssertNotNil(dataPrime, @"failed to inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to inflate data block"); - STAssertEqualObjects(data, - dataPrime, @"failed to round trip via *Data apis"); + gzipped = [NSData gtm_dataByGzippingData:data compressionLevel:level error:&error]; + XCTAssertNotNil(gzipped, @"failed to gzip data block"); + XCTAssertGreaterThan([gzipped length], + (NSUInteger)0, @"failed to gzip data block"); + XCTAssertTrue(HasGzipHeader(gzipped), + @"doesn't have gzip header on gzipped data"); + XCTAssertNil(error); + error = nil; + dataPrime = [NSData gtm_dataByInflatingData:gzipped error:&error]; + XCTAssertNotNil(dataPrime, @"failed to inflate data block"); + XCTAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to inflate data block"); + XCTAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Data apis"); + XCTAssertNil(error); + error = nil; } } - (void)testRawtInflateRawDeflate { + NSError *error = nil; NSData *data = [NSData dataWithBytes:randomDataLarge length:sizeof(randomDataLarge)]; - STAssertNotNil(data, @"failed to alloc data block"); + XCTAssertNotNil(data, @"failed to alloc data block"); // w/ *Bytes apis, default level NSData *rawDeflated = [NSData gtm_dataByRawDeflatingBytes:[data bytes] - length:[data length]]; - STAssertNotNil(rawDeflated, @"failed to raw deflate data block"); - STAssertGreaterThan([rawDeflated length], - (NSUInteger)0, @"failed to raw deflate data block"); - STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); + length:[data length] + error:&error]; + XCTAssertNotNil(rawDeflated, @"failed to raw deflate data block"); + XCTAssertGreaterThan([rawDeflated length], + (NSUInteger)0, @"failed to raw deflate data block"); + XCTAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); + XCTAssertNil(error); + error = nil; NSData *dataPrime = [NSData gtm_dataByRawInflatingBytes:[rawDeflated bytes] - length:[rawDeflated length]]; - STAssertNotNil(dataPrime, @"failed to raw inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to raw inflate data block"); - STAssertEqualObjects(data, - dataPrime, @"failed to round trip via *Bytes apis"); + length:[rawDeflated length] + error:&error]; + XCTAssertNotNil(dataPrime, @"failed to raw inflate data block"); + XCTAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to raw inflate data block"); + XCTAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Bytes apis"); + XCTAssertNil(error); + error = nil; // w/ *Data apis, default level - rawDeflated = [NSData gtm_dataByRawDeflatingData:data]; - STAssertNotNil(rawDeflated, @"failed to raw deflate data block"); - STAssertGreaterThan([rawDeflated length], - (NSUInteger)0, @"failed to raw deflate data block"); - STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); - dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated]; - STAssertNotNil(dataPrime, @"failed to raw inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to raw inflate data block"); - STAssertEqualObjects(data, - dataPrime, @"failed to round trip via *Data apis"); + rawDeflated = [NSData gtm_dataByRawDeflatingData:data error:&error]; + XCTAssertNotNil(rawDeflated, @"failed to raw deflate data block"); + XCTAssertGreaterThan([rawDeflated length], + (NSUInteger)0, @"failed to raw deflate data block"); + XCTAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); + XCTAssertNil(error); + error = nil; + dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated error:&error]; + XCTAssertNotNil(dataPrime, @"failed to raw inflate data block"); + XCTAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to raw inflate data block"); + XCTAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Data apis"); + XCTAssertNil(error); + error = nil; // loop over the compression levels for (int level = 1 ; level <= 9 ; ++level) { // w/ *Bytes apis, using our level rawDeflated = [NSData gtm_dataByRawDeflatingBytes:[data bytes] length:[data length] - compressionLevel:level]; - STAssertNotNil(rawDeflated, @"failed to rawDeflate data block"); - STAssertGreaterThan([rawDeflated length], - (NSUInteger)0, @"failed to raw deflate data block"); - STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); + compressionLevel:level + error:&error]; + XCTAssertNotNil(rawDeflated, @"failed to rawDeflate data block"); + XCTAssertGreaterThan([rawDeflated length], + (NSUInteger)0, @"failed to raw deflate data block"); + XCTAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); + XCTAssertNil(error); + error = nil; dataPrime = [NSData gtm_dataByRawInflatingBytes:[rawDeflated bytes] - length:[rawDeflated length]]; - STAssertNotNil(dataPrime, @"failed to raw inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to raw inflate data block"); - STAssertEqualObjects(data, - dataPrime, @"failed to round trip via *Bytes apis"); + length:[rawDeflated length] + error:&error]; + XCTAssertNotNil(dataPrime, @"failed to raw inflate data block"); + XCTAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to raw inflate data block"); + XCTAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Bytes apis"); + XCTAssertNil(error); + error = nil; // w/ *Data apis, using our level rawDeflated = [NSData gtm_dataByRawDeflatingData:data - compressionLevel:level]; - STAssertNotNil(rawDeflated, @"failed to deflate data block"); - STAssertGreaterThan([rawDeflated length], - (NSUInteger)0, @"failed to raw deflate data block"); - STAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); - dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated]; - STAssertNotNil(dataPrime, @"failed to raw inflate data block"); - STAssertGreaterThan([dataPrime length], - (NSUInteger)0, @"failed to raw inflate data block"); - STAssertEqualObjects(data, - dataPrime, @"failed to round trip via *Data apis"); + compressionLevel:level + error:&error]; + XCTAssertNotNil(rawDeflated, @"failed to deflate data block"); + XCTAssertGreaterThan([rawDeflated length], + (NSUInteger)0, @"failed to raw deflate data block"); + XCTAssertFalse(HasGzipHeader(rawDeflated), @"has gzip header on raw data"); + XCTAssertNil(error); + error = nil; + dataPrime = [NSData gtm_dataByRawInflatingData:rawDeflated error:&error]; + XCTAssertNotNil(dataPrime, @"failed to raw inflate data block"); + XCTAssertGreaterThan([dataPrime length], + (NSUInteger)0, @"failed to raw inflate data block"); + XCTAssertEqualObjects(data, + dataPrime, @"failed to round trip via *Data apis"); + XCTAssertNil(error); + error = nil; } } - (void)testLargeData { // Generate some large data out of the random chunk by xoring over it // to make sure it changes and isn't too repeated. + NSError *error = nil; NSData *data = [NSData dataWithBytes:randomDataLarge length:sizeof(randomDataLarge)]; - STAssertNotNil(data, @"failed to alloc data block"); + XCTAssertNotNil(data, @"failed to alloc data block"); const uint8_t *dataBytes = [data bytes]; NSMutableData *scratch = [NSMutableData dataWithLength:[data length]]; - STAssertNotNil(scratch, @"failed to alloc data block"); + XCTAssertNotNil(scratch, @"failed to alloc data block"); uint8_t *scratchBytes = [scratch mutableBytes]; NSMutableData *input = [NSMutableData dataWithCapacity:200 * [data length]]; for (NSUInteger i = 0; i < 200; ++i) { @@ -505,22 +625,27 @@ static BOOL HasGzipHeader(NSData *data) { // Should deflate to more then one buffer size to make sure the internal loop // is working. NSData *compressed = [NSData gtm_dataByDeflatingData:input - compressionLevel:9]; - STAssertNotNil(compressed, @"failed to deflate"); - STAssertGreaterThan([compressed length], internalBufferSize, - @"should have been more then %d bytes", - (int)internalBufferSize); + compressionLevel:9 + error:&error]; + XCTAssertNotNil(compressed, @"failed to deflate"); + XCTAssertGreaterThan([compressed length], internalBufferSize, + @"should have been more then %d bytes", + (int)internalBufferSize); + XCTAssertNil(error); + error = nil; // Should inflate to more then one buffer size to make sure the internal loop // is working. - NSData *uncompressed = [NSData gtm_dataByInflatingData:compressed]; - STAssertNotNil(uncompressed, @"fail to inflate"); - STAssertGreaterThan([uncompressed length], internalBufferSize, - @"should have been more then %d bytes", - (int)internalBufferSize); - - STAssertEqualObjects(uncompressed, input, - @"didn't get the same thing back"); + NSData *uncompressed = [NSData gtm_dataByInflatingData:compressed error:&error]; + XCTAssertNotNil(uncompressed, @"fail to inflate"); + XCTAssertGreaterThan([uncompressed length], internalBufferSize, + @"should have been more then %d bytes", + (int)internalBufferSize); + + XCTAssertEqualObjects(uncompressed, input, + @"didn't get the same thing back"); + XCTAssertNil(error); + error = nil; } @end diff --git a/Foundation/GTMNSDictionary+CaseInsensitive.h b/Foundation/GTMNSDictionary+CaseInsensitive.h deleted file mode 100644 index 890af4b..0000000 --- a/Foundation/GTMNSDictionary+CaseInsensitive.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// GTMNSDictionary+CaseInsensitive.h -// -// Copyright 2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> -#import "GTMDefines.h" - -/// Utility for building case-insensitive NSDictionary objects. -@interface NSDictionary (GTMNSDictionaryCaseInsensitiveAdditions) - -/// Initializes an NSDictionary with a case-insensitive comparison function -/// for NSString keys, while non-NSString keys are treated normally. -/// -/// The case for NSString keys is preserved, though duplicate keys (when -/// compared in a case-insensitive fashion) have one of their values dropped -/// arbitrarily. -/// -/// An example of use with HTTP headers in an NSHTTPURLResponse object: -/// -/// NSDictionary *headers = -/// [NSDictionary gtm_dictionaryWithDictionaryCaseInsensitive: -/// [response allHeaderFields]]; -/// NSString *contentType = [headers objectForKey:@"Content-Type"]; -- (id)gtm_initWithDictionaryCaseInsensitive:(NSDictionary *)dictionary - NS_RETURNS_RETAINED NS_CONSUMES_SELF; - -/// Returns a newly created and autoreleased NSDictionary object as above. -+ (id)gtm_dictionaryWithDictionaryCaseInsensitive:(NSDictionary *)dictionary; - -@end diff --git a/Foundation/GTMNSDictionary+CaseInsensitive.m b/Foundation/GTMNSDictionary+CaseInsensitive.m deleted file mode 100644 index 96494c2..0000000 --- a/Foundation/GTMNSDictionary+CaseInsensitive.m +++ /dev/null @@ -1,116 +0,0 @@ -// -// GTMNSDictionary+CaseInsensitive.m -// -// Copyright 2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMNSDictionary+CaseInsensitive.h" -#import "GTMDefines.h" -#import <CoreFoundation/CoreFoundation.h> - -@interface NSMutableDictionary (GTMNSMutableDictionaryCaseInsensitiveAdditions) - -// Returns a mutable equivalent to GTMNSDictionaryCaseInsensitiveAdditions. -- (id)gtm_initWithDictionaryCaseInsensitive:(NSDictionary *)dictionary; - -@end - -static Boolean CaseInsensitiveEqualCallback(const void *a, const void *b) { - id idA = (id)a; - id idB = (id)b; - Boolean ret = FALSE; - if ([idA isKindOfClass:[NSString class]] && - [idB isKindOfClass:[NSString class]]) { - ret = ([idA compare:idB options:NSCaseInsensitiveSearch|NSLiteralSearch] - == NSOrderedSame); - } else { - ret = [idA isEqual:idB]; - } - return ret; -} - -static CFHashCode CaseInsensitiveHashCallback(const void *value) { - id idValue = (id)value; - CFHashCode ret = 0; - if ([idValue isKindOfClass:[NSString class]]) { - ret = [[idValue lowercaseString] hash]; - } else { - ret = [idValue hash]; - } - return ret; -} - -@implementation NSDictionary (GTMNSDictionaryCaseInsensitiveAdditions) - -- (id)gtm_initWithDictionaryCaseInsensitive:(NSDictionary *)dictionary { - [self release]; - self = nil; - - CFIndex count = 0; - void *keys = NULL; - void *values = NULL; - - if (dictionary) { - count = CFDictionaryGetCount((CFDictionaryRef)dictionary); - - if (count) { - keys = malloc(count * sizeof(void *)); - values = malloc(count * sizeof(void *)); - if (!keys || !values) { - free(keys); - free(values); - return self; - } - - CFDictionaryGetKeysAndValues((CFDictionaryRef)dictionary, keys, values); - } - } - - CFDictionaryKeyCallBacks keyCallbacks = kCFCopyStringDictionaryKeyCallBacks; - _GTMDevAssert(keyCallbacks.version == 0, - @"CFDictionaryKeyCallBacks structure updated"); - keyCallbacks.equal = CaseInsensitiveEqualCallback; - keyCallbacks.hash = CaseInsensitiveHashCallback; - - self = (id)CFDictionaryCreate(kCFAllocatorDefault, - keys, values, count, &keyCallbacks, - &kCFTypeDictionaryValueCallBacks); - - free(keys); - free(values); - - return self; -} - -+ (id)gtm_dictionaryWithDictionaryCaseInsensitive:(NSDictionary *)dictionary { - return [[[self alloc] - gtm_initWithDictionaryCaseInsensitive:dictionary] autorelease]; -} - -@end - -@implementation NSMutableDictionary (GTMNSMutableDictionaryCaseInsensitiveAdditions) - -- (id)gtm_initWithDictionaryCaseInsensitive:(NSDictionary *)dictionary { - if ((self = [super gtm_initWithDictionaryCaseInsensitive:dictionary])) { - id copy = (id)CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, - (CFDictionaryRef)self); - [self release]; - self = copy; - } - return self; -} - -@end diff --git a/Foundation/GTMNSDictionary+CaseInsensitiveTest.m b/Foundation/GTMNSDictionary+CaseInsensitiveTest.m deleted file mode 100644 index 67584ff..0000000 --- a/Foundation/GTMNSDictionary+CaseInsensitiveTest.m +++ /dev/null @@ -1,119 +0,0 @@ -// -// GTMNSDictionary+CaseInsensitiveTest.m -// -// Copyright 2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" -#import "GTMNSDictionary+CaseInsensitive.h" - -@interface GTMNSDictionary_CaseInsensitiveTest : GTMTestCase -@end - -@implementation GTMNSDictionary_CaseInsensitiveTest - -- (void)testNSDictionaryCaseInsensitiveAdditions { - NSURL *objKey = [NSURL URLWithString:@"http://WWW.Google.COM/"]; - NSURL *lcObjKey = [NSURL URLWithString:[[objKey absoluteString] - lowercaseString]]; - - NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: - @"value", @"key", - @"value", @"KEY", - @"bar", @"FOO", - @"yes", objKey, - nil]; - - NSDictionary *ciDict = - [NSDictionary gtm_dictionaryWithDictionaryCaseInsensitive:dict]; - - STAssertNotNil(ciDict, @"gtm_dictionaryWithDictionaryCaseInsensitive failed"); - - STAssertTrue([ciDict count] == 3, - @"wrong count, multiple 'key' entries should be folded."); - - STAssertEqualStrings([ciDict objectForKey:@"foo"], @"bar", - @"case insensitive key lookup failed"); - - STAssertEqualStrings([ciDict objectForKey:@"kEy"], @"value", - @"case insensitive key lookup failed"); - - STAssertNotNil([ciDict objectForKey:objKey], - @"exact matches on non-NSString objects should still work."); - - STAssertNil([ciDict objectForKey:lcObjKey], - @"only NSString and subclasses are case-insensitive."); - - STAssertNotNil([NSDictionary gtm_dictionaryWithDictionaryCaseInsensitive: - [NSDictionary dictionary]], - @"empty dictionary should not return nil"); - - STAssertNotNil([NSDictionary gtm_dictionaryWithDictionaryCaseInsensitive: - nil], - @"nil dictionary should return empty dictionary"); - - STAssertNotNil([[[NSDictionary alloc] gtm_initWithDictionaryCaseInsensitive: - nil] autorelease], - @"nil dictionary should return empty dictionary"); -} - -- (void)testNSMutableDictionaryCaseInsensitiveAdditions { - NSURL *objKey = [NSURL URLWithString:@"http://WWW.Google.COM/"]; - NSURL *lcObjKey = [NSURL URLWithString:[[objKey absoluteString] - lowercaseString]]; - - NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: - @"value", @"key", - @"value", @"KEY", - @"bar", @"FOO", - @"yes", objKey, - nil]; - - NSMutableDictionary *ciDict = - [NSMutableDictionary gtm_dictionaryWithDictionaryCaseInsensitive:dict]; - - STAssertNotNil(ciDict, @"gtm_dictionaryWithDictionaryCaseInsensitive failed"); - - STAssertTrue([ciDict count] == 3, - @"wrong count, multiple 'key' entries should be folded."); - - STAssertEqualStrings([ciDict objectForKey:@"foo"], @"bar", - @"case insensitive key lookup failed"); - - STAssertEqualStrings([ciDict objectForKey:@"kEy"], @"value", - @"case insensitive key lookup failed"); - - STAssertNotNil([ciDict objectForKey:objKey], - @"exact matches on non-NSString objects should still work."); - - STAssertNil([ciDict objectForKey:lcObjKey], - @"only NSString and subclasses are case-insensitive."); - - NSObject *obj = [[[NSObject alloc] init] autorelease]; - [ciDict setObject:obj forKey:@"kEy"]; - STAssertEquals([ciDict objectForKey:@"key"], obj, - @"mutable dictionary value not overwritten"); - - STAssertNotNil( - [NSMutableDictionary gtm_dictionaryWithDictionaryCaseInsensitive: - [NSDictionary dictionary]], - @"empty dictionary should not return nil"); - - STAssertNotNil( - [NSMutableDictionary gtm_dictionaryWithDictionaryCaseInsensitive:nil], - @"nil dictionary should return empty dictionary"); -} - -@end diff --git a/Foundation/GTMNSDictionary+URLArguments.m b/Foundation/GTMNSDictionary+URLArguments.m index 5a7aa5f..e9fa766 100644 --- a/Foundation/GTMNSDictionary+URLArguments.m +++ b/Foundation/GTMNSDictionary+URLArguments.m @@ -38,7 +38,7 @@ GTM_METHOD_CHECK(NSString, gtm_stringByUnescapingFromURLArgument); NSString* component; // Use reverse order so that the first occurrence of a key replaces // those subsequent. - GTM_FOREACH_ENUMEREE(component, [components reverseObjectEnumerator]) { + for (component in [components reverseObjectEnumerator]) { if ([component length] == 0) continue; NSRange pos = [component rangeOfString:@"="]; @@ -65,7 +65,7 @@ GTM_METHOD_CHECK(NSString, gtm_stringByUnescapingFromURLArgument); - (NSString *)gtm_httpArgumentsString { NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:[self count]]; NSString* key; - GTM_FOREACH_KEY(key, self) { + for (key in self) { [arguments addObject:[NSString stringWithFormat:@"%@=%@", [key gtm_stringByEscapingForURLArgument], [[[self objectForKey:key] description] gtm_stringByEscapingForURLArgument]]]; diff --git a/Foundation/GTMNSDictionary+URLArgumentsTest.m b/Foundation/GTMNSDictionary+URLArgumentsTest.m index 8ec9520..11ceb8a 100644 --- a/Foundation/GTMNSDictionary+URLArgumentsTest.m +++ b/Foundation/GTMNSDictionary+URLArgumentsTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -26,42 +26,42 @@ @implementation GTMNSDictionary_URLArgumentsTest - (void)testFromArgumentsString { - STAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@""], - [NSDictionary dictionary], - @"- empty arguments string should give an empty dictionary"); - STAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"a"], - [NSDictionary dictionaryWithObject:@"" forKey:@"a"], - @"- missing '=' should result in an empty string value"); - STAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"a="], - [NSDictionary dictionaryWithObject:@"" forKey:@"a"], - @"- no value"); - STAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"&a=1"], - [NSDictionary dictionaryWithObject:@"1" forKey:@"a"], - @"- empty segment should be skipped"); - STAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"abc=123"], - [NSDictionary dictionaryWithObject:@"123" forKey:@"abc"], - @"- simple one-pair dictionary should work"); - STAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"a=1&a=2&a=3"], - [NSDictionary dictionaryWithObject:@"1" forKey:@"a"], - @"- only first occurrence of a key is returned"); + XCTAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@""], + [NSDictionary dictionary], + @"- empty arguments string should give an empty dictionary"); + XCTAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"a"], + [NSDictionary dictionaryWithObject:@"" forKey:@"a"], + @"- missing '=' should result in an empty string value"); + XCTAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"a="], + [NSDictionary dictionaryWithObject:@"" forKey:@"a"], + @"- no value"); + XCTAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"&a=1"], + [NSDictionary dictionaryWithObject:@"1" forKey:@"a"], + @"- empty segment should be skipped"); + XCTAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"abc=123"], + [NSDictionary dictionaryWithObject:@"123" forKey:@"abc"], + @"- simple one-pair dictionary should work"); + XCTAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"a=1&a=2&a=3"], + [NSDictionary dictionaryWithObject:@"1" forKey:@"a"], + @"- only first occurrence of a key is returned"); NSString* complex = @"a%2Bb=specialkey&complex=1%2B1%21%3D3%20%26%202%2A6%2F3%3D4&c"; NSDictionary* result = [NSDictionary dictionaryWithObjectsAndKeys: @"1+1!=3 & 2*6/3=4", @"complex", @"specialkey", @"a+b", @"", @"c", nil]; - STAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:complex], - result, - @"- keys and values should be unescaped correctly"); - STAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"a=%FC"], - [NSDictionary dictionaryWithObject:@"" forKey:@"a"], - @"- invalid UTF8 characters result in an empty value, not a crash"); + XCTAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:complex], + result, + @"- keys and values should be unescaped correctly"); + XCTAssertEqualObjects([NSDictionary gtm_dictionaryWithHttpArgumentsString:@"a=%FC"], + [NSDictionary dictionaryWithObject:@"" forKey:@"a"], + @"- invalid UTF8 characters result in an empty value, not a crash"); } - (void)testArgumentsString { - STAssertEqualObjects([[NSDictionary dictionary] gtm_httpArgumentsString], @"", - @"- empty dictionary should give an empty string"); - STAssertEqualObjects([[NSDictionary dictionaryWithObject:@"123" forKey:@"abc"] gtm_httpArgumentsString], + XCTAssertEqualObjects([[NSDictionary dictionary] gtm_httpArgumentsString], @"", + @"- empty dictionary should give an empty string"); + XCTAssertEqualObjects([[NSDictionary dictionaryWithObject:@"123" forKey:@"abc"] gtm_httpArgumentsString], @"abc=123", @"- simple one-pair dictionary should work"); NSDictionary* arguments = [NSDictionary dictionaryWithObjectsAndKeys: @@ -72,15 +72,15 @@ // check for individual pieces since order is not guaranteed NSString* component1 = @"a%2Bb=specialkey"; NSString* component2 = @"complex=1%2B1%21%3D3%20%26%202%2A6%2F3%3D4"; - STAssertNotEquals([argumentString rangeOfString:component1].location, (NSUInteger)NSNotFound, + XCTAssertNotEqual([argumentString rangeOfString:component1].location, (NSUInteger)NSNotFound, @"- '%@' not found in '%@'", component1, argumentString); - STAssertNotEquals([argumentString rangeOfString:component2].location, (NSUInteger)NSNotFound, + XCTAssertNotEqual([argumentString rangeOfString:component2].location, (NSUInteger)NSNotFound, @"- '%@' not found in '%@'", component2, argumentString); - STAssertNotEquals([argumentString rangeOfString:@"&"].location, (NSUInteger)NSNotFound, + XCTAssertNotEqual([argumentString rangeOfString:@"&"].location, (NSUInteger)NSNotFound, @"- special characters should be escaped"); - STAssertNotEquals([argumentString characterAtIndex:0], (unichar)'&', + XCTAssertNotEqual([argumentString characterAtIndex:0], (unichar)'&', @"- there should be no & at the beginning of the string"); - STAssertNotEquals([argumentString characterAtIndex:([argumentString length] - 1)], (unichar)'&', + XCTAssertNotEqual([argumentString characterAtIndex:([argumentString length] - 1)], (unichar)'&', @"- there should be no & at the end of the string"); } diff --git a/Foundation/GTMNSEnumerator+Filter.h b/Foundation/GTMNSEnumerator+Filter.h deleted file mode 100644 index 8e4a6b7..0000000 --- a/Foundation/GTMNSEnumerator+Filter.h +++ /dev/null @@ -1,69 +0,0 @@ -// -// GTMNSEnumerator+Filter.h -// -// Copyright 2007-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> - -// A generic category for methods that allow us to filter enumeratable -// containers, inspired by C++ Standard Library's use of iterators. -// Like in C++, these assume the underlying container is not modified during -// the lifetime of the iterator. -// -@interface NSEnumerator (GTMEnumeratorFilterAdditions) - -// Performs -[element predicate:argument] on each object in self. -// Returns an enumerator where -[element predicate:argument] returned YES. -// Predicate must be of form -(BOOL)predicate:(id)argument. -- (NSEnumerator *)gtm_filteredEnumeratorByMakingEachObjectPerformSelector:(SEL)predicate - withObject:(id)argument; - -// Performs -[element selector:argument] on each object in self. -// Returns an enumerator of the return values of -[element selector:argument]. -// Selector must be of form -(id)selector:(id)argument. -- (NSEnumerator *)gtm_enumeratorByMakingEachObjectPerformSelector:(SEL)selector - withObject:(id)argument; - -// Performs -[target predicate:element] on each object in self. -// Returns an enumerator where -[target predicate:element] returned YES. -// Predicate must be of form -(BOOL)predicate:(id)element. -- (NSEnumerator *)gtm_filteredEnumeratorByTarget:(id)target - performOnEachSelector:(SEL)predicate; - -// Performs -[target predicate:element withObject:object] on each object in self. -// Returns an enumerator where -[target predicate:element withObject:object] -// returned YES. -// Predicate must be of form -(BOOL)predicate:(id)element withObject:(id)object. -- (NSEnumerator *)gtm_filteredEnumeratorByTarget:(id)target - performOnEachSelector:(SEL)predicate - withObject:(id)object; - -// Performs -[target selector:element] on each object in self. -// Returns an enumerator of the return values of -[target selector:element]. -// Selector must be of form -(id)selector:(id)element. -- (NSEnumerator *)gtm_enumeratorByTarget:(id)target - performOnEachSelector:(SEL)selector; - -// Performs -[target selector:element withObject:object] on each object in self. -// Returns an enumerator of the return values of -// -[target selector:element withObject:object]. -// Selector must be of form -(id)selector:(id)element withObject:(id)object. -- (NSEnumerator *)gtm_enumeratorByTarget:(id)target - performOnEachSelector:(SEL)selector - withObject:(id)object; - -@end - diff --git a/Foundation/GTMNSEnumerator+Filter.m b/Foundation/GTMNSEnumerator+Filter.m deleted file mode 100644 index cc1cb41..0000000 --- a/Foundation/GTMNSEnumerator+Filter.m +++ /dev/null @@ -1,221 +0,0 @@ -// -// GTMNSEnumerator+Filter.m -// -// Copyright 2007-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMNSEnumerator+Filter.h" -#import "GTMDebugSelectorValidation.h" -#import "GTMDefines.h" -#if GTM_IPHONE_SDK -#import <objc/message.h> -#import <objc/runtime.h> -#else -#import <objc/objc-runtime.h> -#endif - -// a private subclass of NSEnumerator that does all the work. -// public interface just returns one of these. -// This top level class contains all the additional boilerplate. Specific -// behavior is in the subclasses. -@interface GTMEnumeratorPrivateBase : NSEnumerator { - @protected - NSEnumerator *base_; - SEL operation_; // either a predicate or a transform depending on context. - id target_; // may be nil - id object_; // may be nil -} -@end - -@interface GTMEnumeratorPrivateBase (SubclassesMustProvide) -- (BOOL)filterObject:(id)obj returning:(id *)resultp; -@end - -@implementation GTMEnumeratorPrivateBase -- (id)initWithBase:(NSEnumerator *)base - sel:(SEL)filter - target:(id)optionalTarget - object:(id)optionalOther { - self = [super init]; - if (self) { - - // someone would have to subclass or directly create an object of this - // class, and this class is private to this impl. - _GTMDevAssert(base, @"can't initWithBase: a nil base enumerator"); - base_ = [base retain]; - operation_ = filter; - target_ = [optionalTarget retain]; - object_ = [optionalOther retain]; - } - return self; -} - -// we don't provide an init because this base class is private to this -// impl, and no one would be able to create it (if they do, they get whatever -// they happens...). - -- (void)dealloc { - [base_ release]; - [target_ release]; - [object_ release]; - [super dealloc]; -} - -- (id)nextObject { - for (id obj = [base_ nextObject]; obj; obj = [base_ nextObject]) { - id result = nil; - if ([self filterObject:obj returning:&result]) { - return result; - } - } - return nil; -} -@end - -// a transformer, for each item in the enumerator, returns a f(item). -@interface GTMEnumeratorTransformer : GTMEnumeratorPrivateBase -@end -@implementation GTMEnumeratorTransformer -- (BOOL)filterObject:(id)obj returning:(id *)resultp { - *resultp = [obj performSelector:operation_ withObject:object_]; - return nil != *resultp; -} -@end - -// a transformer, for each item in the enumerator, returns a f(item). -// a target transformer swaps the target and the argument. -@interface GTMEnumeratorTargetTransformer : GTMEnumeratorPrivateBase -@end -@implementation GTMEnumeratorTargetTransformer -- (BOOL)filterObject:(id)obj returning:(id *)resultp { - *resultp = [target_ performSelector:operation_ - withObject:obj - withObject:object_]; - return nil != *resultp; -} -@end - -// a filter, for each item in the enumerator, if(f(item)) { returns item. } -@interface GTMEnumeratorFilter : GTMEnumeratorPrivateBase -@end -@implementation GTMEnumeratorFilter -// We must take care here, since Intel leaves junk in high bytes of return -// register for predicates that return BOOL. -// For details see: -// http://developer.apple.com/legacy/mac/library/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/universal_binary_tips.html#//apple_ref/doc/uid/TP40002217-CH239-280661 -// and -// http://www.red-sweater.com/blog/320/abusing-objective-c-with-class#comment-83187 -- (BOOL)filterObject:(id)obj returning:(id *)resultp { - *resultp = obj; - return ((BOOL (*)(id, SEL, id))objc_msgSend)(obj, operation_, object_); -} -@end - -// a target filter, for each item in the enumerator, if(f(item)) { returns item. } -// a target transformer swaps the target and the argument. -@interface GTMEnumeratorTargetFilter : GTMEnumeratorPrivateBase -@end -@implementation GTMEnumeratorTargetFilter -// We must take care here, since Intel leaves junk in high bytes of return -// register for predicates that return BOOL. -// For details see: -// http://developer.apple.com/legacy/mac/library/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/universal_binary_tips.html#//apple_ref/doc/uid/TP40002217-CH239-280661 -// and -// http://www.red-sweater.com/blog/320/abusing-objective-c-with-class#comment-83187 -- (BOOL)filterObject:(id)obj returning:(id *)resultp { - *resultp = obj; - return ((BOOL (*)(id, SEL, id, id))objc_msgSend)(target_, operation_, obj, object_); -} -@end - -@implementation NSEnumerator (GTMEnumeratorFilterAdditions) - -- (NSEnumerator *)gtm_filteredEnumeratorByMakingEachObjectPerformSelector:(SEL)selector - withObject:(id)argument { - return [[[GTMEnumeratorFilter alloc] initWithBase:self - sel:selector - target:nil - object:argument] autorelease]; -} - -- (NSEnumerator *)gtm_enumeratorByMakingEachObjectPerformSelector:(SEL)selector - withObject:(id)argument { - return [[[GTMEnumeratorTransformer alloc] initWithBase:self - sel:selector - target:nil - object:argument] autorelease]; -} - - -- (NSEnumerator *)gtm_filteredEnumeratorByTarget:(id)target - performOnEachSelector:(SEL)predicate { - // make sure the object impls this selector taking an object as an arg. - GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(target, predicate, - @encode(BOOL), - @encode(id), - NULL); - return [[[GTMEnumeratorTargetFilter alloc] initWithBase:self - sel:predicate - target:target - object:nil] autorelease]; -} - -- (NSEnumerator *)gtm_filteredEnumeratorByTarget:(id)target - performOnEachSelector:(SEL)predicate - withObject:(id)object { - // make sure the object impls this selector taking an object as an arg. - GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(target, predicate, - @encode(BOOL), - @encode(id), - @encode(id), - NULL); - return [[[GTMEnumeratorTargetFilter alloc] initWithBase:self - sel:predicate - target:target - object:object] autorelease]; -} - -- (NSEnumerator *)gtm_enumeratorByTarget:(id)target - performOnEachSelector:(SEL)selector { - // make sure the object impls this selector taking an object as an arg. - GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(target, selector, - @encode(id), - @encode(id), - NULL); - return [[[GTMEnumeratorTargetTransformer alloc] initWithBase:self - sel:selector - target:target - object:nil] - autorelease]; -} - -- (NSEnumerator *)gtm_enumeratorByTarget:(id)target - performOnEachSelector:(SEL)selector - withObject:(id)object { - // make sure the object impls this selector taking an object as an arg. - GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(target, selector, - @encode(id), - @encode(id), - @encode(id), - NULL); - return [[[GTMEnumeratorTargetTransformer alloc] initWithBase:self - sel:selector - target:target - object:object] - autorelease]; -} - -@end - diff --git a/Foundation/GTMNSEnumerator+FilterTest.m b/Foundation/GTMNSEnumerator+FilterTest.m deleted file mode 100644 index 969a5a5..0000000 --- a/Foundation/GTMNSEnumerator+FilterTest.m +++ /dev/null @@ -1,208 +0,0 @@ -// -// GTMNSEnumerator+FilterTest.m -// -// Copyright 2007-2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" -#import "GTMNSEnumerator+Filter.h" - -@interface GTMNSEnumerator_FilterTest : GTMTestCase -@end - -@implementation GTMNSEnumerator_FilterTest - -- (void)testEnumeratorByMakingEachObjectPerformSelector { - // test w/ a set of strings - NSSet *numbers = [NSSet setWithObjects: @"1", @"2", @"3", nil]; - NSEnumerator *e = [[numbers objectEnumerator] - gtm_enumeratorByMakingEachObjectPerformSelector:@selector(stringByAppendingString:) - withObject:@" "]; - NSMutableSet *trailingSpaces = [NSMutableSet set]; - id obj; - while (nil != (obj = [e nextObject])) { - [trailingSpaces addObject:obj]; - } - NSSet *trailingSpacesGood = [NSSet setWithObjects: @"1 ", @"2 ", @"3 ", nil]; - STAssertEqualObjects(trailingSpaces, trailingSpacesGood, @""); - - // test an empty set - NSSet *empty = [NSSet set]; - e = [[empty objectEnumerator] - gtm_enumeratorByMakingEachObjectPerformSelector:@selector(stringByAppendingString:) - withObject:@" "]; - STAssertNil([e nextObject], - @"shouldn't have gotten anything from first advance of " - @"enumerator"); -} - -- (void)testFilteredEnumeratorByMakingEachObjectPerformSelector { - // test with a dict of strings - NSDictionary *testDict = [NSDictionary dictionaryWithObjectsAndKeys: - @"foo", @"1", - @"bar", @"2", - @"foobar", @"3", - nil]; - // test those that have prefixes - NSEnumerator *e = [[testDict objectEnumerator] - gtm_filteredEnumeratorByMakingEachObjectPerformSelector:@selector(hasPrefix:) - withObject:@"foo"]; - // since the dictionary iterates in any order, compare as sets - NSSet *filteredValues = [NSSet setWithArray:[e allObjects]]; - NSSet *expectedValues = [NSSet setWithObjects:@"foo", @"foobar", nil]; - STAssertEqualObjects(filteredValues, expectedValues, @""); - - // test an empty set - NSSet *empty = [NSSet set]; - e = [[empty objectEnumerator] - gtm_filteredEnumeratorByMakingEachObjectPerformSelector:@selector(hasPrefix:) - withObject:@"foo"]; - STAssertNil([e nextObject], - @"shouldn't have gotten anything from first advance of " - @"enumerator"); - - // test an set that will filter out - NSSet *filterAway = [NSSet setWithObjects:@"bar", @"baz", nil]; - e = [[filterAway objectEnumerator] - gtm_filteredEnumeratorByMakingEachObjectPerformSelector:@selector(hasPrefix:) - withObject:@"foo"]; - STAssertNil([e nextObject], - @"shouldn't have gotten anything from first advance of " - @"enumerator"); -} - -- (void)testEnumeratorByTargetPerformOnEachSelector { - // test w/ a set of strings - NSSet *numbers = [NSSet setWithObjects: @"1", @"2", @"3", nil]; - NSString *target = @"foo"; - NSEnumerator *e = [[numbers objectEnumerator] - gtm_enumeratorByTarget:target - performOnEachSelector:@selector(stringByAppendingString:)]; - // since the set iterates in any order, compare as sets - NSSet *collectedValues = [NSSet setWithArray:[e allObjects]]; - NSSet *expectedValues = [NSSet setWithObjects:@"foo1", @"foo2", @"foo3", nil]; - STAssertEqualObjects(collectedValues, expectedValues, @""); - - // test an empty set - NSSet *empty = [NSSet set]; - e = [[empty objectEnumerator] - gtm_enumeratorByTarget:target - performOnEachSelector:@selector(stringByAppendingString:)]; - STAssertNil([e nextObject], - @"shouldn't have gotten anything from first advance of " - @"enumerator"); -} - -- (id)prependString:(NSString*)pre toString:(NSString *)post { - return [pre stringByAppendingString:post]; -} - -- (void)testEnumeratorByTargetPerformOnEachSelectorWithObject { - // test w/ a set of strings - NSSet *numbers = [NSSet setWithObjects: @"1", @"2", @"3", nil]; - NSEnumerator *e = [[numbers objectEnumerator] - gtm_enumeratorByTarget:self - performOnEachSelector:@selector(prependString:toString:) - withObject:@"bar"]; - // since the set iterates in any order, compare as sets - NSSet *collectedValues = [NSSet setWithArray:[e allObjects]]; - NSSet *expectedValues = [NSSet setWithObjects:@"1bar", - @"2bar", - @"3bar", - nil]; - STAssertEqualObjects(collectedValues, expectedValues, @""); - - // test an empty set - NSSet *empty = [NSSet set]; - e = [[empty objectEnumerator] - gtm_enumeratorByTarget:self - performOnEachSelector:@selector(prependString:toString:) - withObject:@"bar"]; - STAssertNil([e nextObject], - @"shouldn't have gotten anything from first advance of " - @"enumerator"); -} - - -- (void)testFilteredEnumeratorByTargetPerformOnEachSelector { - // test w/ a set of strings - NSSet *numbers = [NSSet setWithObjects:@"1", @"2", @"3", @"4", nil]; - NSSet *target = [NSSet setWithObjects:@"2", @"4", @"6", nil]; - NSEnumerator *e = [[numbers objectEnumerator] - gtm_filteredEnumeratorByTarget:target - performOnEachSelector:@selector(containsObject:)]; - // since the set iterates in any order, compare as sets - NSSet *filteredValues = [NSSet setWithArray:[e allObjects]]; - NSSet *expectedValues = [NSSet setWithObjects:@"2", @"4", nil]; - STAssertEqualObjects(filteredValues, expectedValues, @""); - - // test an empty set - NSSet *empty = [NSSet set]; - e = [[empty objectEnumerator] - gtm_filteredEnumeratorByTarget:target - performOnEachSelector:@selector(containsObject:)]; - STAssertNil([e nextObject], - @"shouldn't have gotten anything from first advance of " - @"enumerator"); - - // test a set that will filter out - NSSet *filterAway = [NSSet setWithObjects:@"bar", @"baz", nil]; - e = [[filterAway objectEnumerator] - gtm_filteredEnumeratorByTarget:target - performOnEachSelector:@selector(containsObject:)]; - STAssertNil([e nextObject], - @"shouldn't have gotten anything from first advance of " - @"enumerator"); -} - -- (BOOL)is:(id)a equalTo:(id)b { - return [a isEqual:b]; -} - -- (void)testFilteredEnumeratorByTargetPerformOnEachSelectorWithObject { - // test w/ a set of strings - NSSet *numbers = [NSSet setWithObjects:@"1", @"2", @"3", @"4", nil]; - NSEnumerator *e = [[numbers objectEnumerator] - gtm_filteredEnumeratorByTarget:self - performOnEachSelector:@selector(is:equalTo:) - withObject:@"2"]; - // since the set iterates in any order, compare as sets - NSSet *filteredValues = [NSSet setWithArray:[e allObjects]]; - NSSet *expectedValues = [NSSet setWithObjects:@"2", nil]; - STAssertEqualObjects(filteredValues, expectedValues, @""); - - // test an empty set - NSSet *empty = [NSSet set]; - e = [[empty objectEnumerator] - gtm_filteredEnumeratorByTarget:self - performOnEachSelector:@selector(is:equalTo:) - withObject:@"2"]; - STAssertNil([e nextObject], - @"shouldn't have gotten anything from first advance of " - @"enumerator"); - - // test a set that will filter out - NSSet *filterAway = [NSSet setWithObjects:@"bar", @"baz", nil]; - e = [[filterAway objectEnumerator] - gtm_filteredEnumeratorByTarget:self - performOnEachSelector:@selector(is:equalTo:) - withObject:@"2"]; - STAssertNil([e nextObject], - @"shouldn't have gotten anything from first advance of " - @"enumerator"); -} - - -@end diff --git a/Foundation/GTMNSFileHandle+UniqueNameTest.m b/Foundation/GTMNSFileHandle+UniqueNameTest.m index 45cd8c7..0f0dc49 100644 --- a/Foundation/GTMNSFileHandle+UniqueNameTest.m +++ b/Foundation/GTMNSFileHandle+UniqueNameTest.m @@ -28,69 +28,63 @@ NSFileHandle *handle = [NSFileHandle gtm_fileHandleWithUniqueNameBasedOn:nil finalPath:nil]; - STAssertNil(handle, nil); + XCTAssertNil(handle); // Try and create a file where we shouldn't be able to. NSString *path = nil; handle = [NSFileHandle gtm_fileHandleWithUniqueNameBasedOn:@"/System/HappyXXX.txt" finalPath:&path]; - STAssertNil(handle, nil); - STAssertNil(path, nil); + XCTAssertNil(handle); + XCTAssertNil(path); NSFileManager *fm = [NSFileManager defaultManager]; NSString *tempDir = [fm gtm_createTemporaryDirectoryBasedOn:@"GTMNSFileHandle_UniqueNameTestXXXXXX"]; - STAssertNotNil(tempDir, nil); + XCTAssertNotNil(tempDir); BOOL isDirectory = NO; - STAssertTrue([fm fileExistsAtPath:tempDir isDirectory:&isDirectory] - && isDirectory, nil); + XCTAssertTrue([fm fileExistsAtPath:tempDir isDirectory:&isDirectory] && isDirectory); // Test with extension handle = [NSFileHandle gtm_fileHandleWithUniqueNameBasedOn:@"HappyXXX.txt" inDirectory:tempDir finalPath:&path]; - STAssertNotNil(handle, nil); - STAssertEqualObjects([path pathExtension], @"txt", nil); - STAssertTrue([fm fileExistsAtPath:path], nil); + XCTAssertNotNil(handle); + XCTAssertEqualObjects([path pathExtension], @"txt"); + XCTAssertTrue([fm fileExistsAtPath:path]); // Test without extension handle = [NSFileHandle gtm_fileHandleWithUniqueNameBasedOn:@"HappyXXX" inDirectory:tempDir finalPath:&path]; - STAssertNotNil(handle, nil); - STAssertEqualObjects([path pathExtension], @"", nil); - STAssertTrue([fm fileExistsAtPath:path], nil); + XCTAssertNotNil(handle); + XCTAssertEqualObjects([path pathExtension], @""); + XCTAssertTrue([fm fileExistsAtPath:path]); // Test passing in same name twice NSString *fullPath = [tempDir stringByAppendingPathComponent:@"HappyXXX"]; NSString *newPath = nil; handle = [NSFileHandle gtm_fileHandleWithUniqueNameBasedOn:fullPath finalPath:&newPath]; - STAssertNotNil(handle, nil); - STAssertNotNil(newPath, nil); - STAssertNotEqualObjects(path, newPath, nil); - STAssertTrue([fm fileExistsAtPath:newPath], nil); + XCTAssertNotNil(handle); + XCTAssertNotNil(newPath); + XCTAssertNotEqualObjects(path, newPath); + XCTAssertTrue([fm fileExistsAtPath:newPath]); // Test passing in same name twice with no template fullPath = [tempDir stringByAppendingPathComponent:@"Sad"]; newPath = nil; handle = [NSFileHandle gtm_fileHandleWithUniqueNameBasedOn:fullPath finalPath:&newPath]; - STAssertNotNil(handle, nil); - STAssertNotNil(newPath, nil); + XCTAssertNotNil(handle); + XCTAssertNotNil(newPath); newPath = nil; handle = [NSFileHandle gtm_fileHandleWithUniqueNameBasedOn:fullPath finalPath:&newPath]; - STAssertNil(handle, nil); - STAssertNil(newPath, nil); + XCTAssertNil(handle); + XCTAssertNil(newPath); -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - [fm removeFileAtPath:tempDir handler:nil]; -#else // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 [fm removeItemAtPath:tempDir error:nil]; -#endif - } - (void)testFileHandleWithUniqueNameBasedOnInDirectorySearchMaskFinalPath { @@ -101,21 +95,17 @@ inDirectory:NSCachesDirectory domainMask:NSUserDomainMask finalPath:&path]; - STAssertNil(handle, nil); - STAssertNil(path, nil); + XCTAssertNil(handle); + XCTAssertNil(path); handle = [NSFileHandle gtm_fileHandleWithUniqueNameBasedOn:@"HappyXXX.txt" inDirectory:NSCachesDirectory domainMask:NSUserDomainMask finalPath:&path]; - STAssertNotNil(handle, nil); - STAssertNotNil(path, nil); - STAssertTrue([fm fileExistsAtPath:path], nil); -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - [fm removeFileAtPath:path handler:nil]; -#else // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + XCTAssertNotNil(handle); + XCTAssertNotNil(path); + XCTAssertTrue([fm fileExistsAtPath:path]); [fm removeItemAtPath:path error:nil]; -#endif } @end @@ -129,7 +119,7 @@ NSFileManager *fm = [NSFileManager defaultManager]; NSString *path = [fm gtm_createDirectoryWithUniqueNameBasedOn:@"/System/HappyXXX.txt"]; - STAssertNil(path, nil); + XCTAssertNil(path); } - (void)testCreateDirectoryWithUniqueNameBasedOnInDirectorySearchMask { @@ -137,20 +127,16 @@ NSString *path = [fm gtm_createDirectoryWithUniqueNameBasedOn:nil inDirectory:NSCachesDirectory domainMask:NSUserDomainMask]; - STAssertNil(path, nil); + XCTAssertNil(path); path = [fm gtm_createDirectoryWithUniqueNameBasedOn:@"HappyXXX.txt" inDirectory:NSCachesDirectory domainMask:NSUserDomainMask]; - STAssertNotNil(path, nil); + XCTAssertNotNil(path); BOOL isDirectory = NO; - STAssertTrue([fm fileExistsAtPath:path isDirectory:&isDirectory] - && isDirectory, nil); -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - [fm removeFileAtPath:path handler:nil]; -#else // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - [fm removeItemAtPath:path error:nil]; -#endif + XCTAssertTrue([fm fileExistsAtPath:path isDirectory:&isDirectory] && isDirectory); + NSError *error; + XCTAssertTrue([fm removeItemAtPath:path error:&error], "%@", error); } @end diff --git a/Foundation/GTMNSFileManager+CarbonTest.m b/Foundation/GTMNSFileManager+CarbonTest.m index 95f8814..f42ece4 100644 --- a/Foundation/GTMNSFileManager+CarbonTest.m +++ b/Foundation/GTMNSFileManager+CarbonTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -18,62 +18,56 @@ #import "GTMSenTestCase.h" #import "GTMNSFileManager+Carbon.h" -#import "GTMUnitTestDevLog.h" #import <CoreServices/CoreServices.h> @interface GTMNSFileManager_CarbonTest : GTMTestCase @end - + @implementation GTMNSFileManager_CarbonTest - (void)testAliasPathFSRefConversion { NSString *path = NSHomeDirectory(); - STAssertNotNil(path, nil); + XCTAssertNotNil(path); NSFileManager *fileManager = [NSFileManager defaultManager]; FSRef *fsRef = [fileManager gtm_FSRefForPath:path]; - STAssertNotNULL(fsRef, nil); + XCTAssertNotNULL(fsRef); AliasHandle alias; - STAssertNoErr(FSNewAlias(nil, fsRef, &alias), nil); - STAssertNotNULL(alias, nil); - NSData *aliasData = [NSData dataWithBytes:*alias + XCTAssertNoErr(FSNewAlias(nil, fsRef, &alias)); + XCTAssertNotNULL(alias); + NSData *aliasData = [NSData dataWithBytes:*alias length:GetAliasSize(alias)]; - STAssertNotNil(aliasData, nil); + XCTAssertNotNil(aliasData); NSString *path2 = [fileManager gtm_pathFromAliasData:aliasData]; - STAssertEqualObjects(path, path2, nil); + XCTAssertEqualObjects(path, path2); path2 = [fileManager gtm_pathFromAliasData:aliasData resolve:YES withUI:NO]; - STAssertEqualObjects(path, path2, nil); - + XCTAssertEqualObjects(path, path2); + path2 = [fileManager gtm_pathFromAliasData:aliasData resolve:NO withUI:NO]; - STAssertEqualObjects(path, path2, nil); + XCTAssertEqualObjects(path, path2); NSData *aliasData2 = [fileManager gtm_aliasDataForPath:path2]; - STAssertNotNil(aliasData2, nil); + XCTAssertNotNil(aliasData2); NSString *path3 = [fileManager gtm_pathFromAliasData:aliasData2]; - STAssertEqualObjects(path2, path3, nil); + XCTAssertEqualObjects(path2, path3); NSString *path4 = [fileManager gtm_pathFromFSRef:fsRef]; - STAssertEqualObjects(path, path4, nil); - + XCTAssertEqualObjects(path, path4); + // Failure cases - [GTMUnitTestDevLogDebug expectPattern:@"DebugAssert: " - @"GoogleToolboxForMac: FSPathMakeRef.*"]; - STAssertNULL([fileManager gtm_FSRefForPath:@"/ptah/taht/dosent/esixt/"], - nil); + XCTAssertNULL([fileManager gtm_FSRefForPath:@"/ptah/taht/dosent/esixt/"]); + + XCTAssertNULL([fileManager gtm_FSRefForPath:@""]); + XCTAssertNULL([fileManager gtm_FSRefForPath:nil]); + XCTAssertNil([fileManager gtm_pathFromFSRef:nil]); + XCTAssertNil([fileManager gtm_pathFromAliasData:nil]); + XCTAssertNil([fileManager gtm_pathFromAliasData:[NSData data]]); - STAssertNULL([fileManager gtm_FSRefForPath:@""], nil); - STAssertNULL([fileManager gtm_FSRefForPath:nil], nil); - STAssertNil([fileManager gtm_pathFromFSRef:nil], nil); - STAssertNil([fileManager gtm_pathFromAliasData:nil], nil); - STAssertNil([fileManager gtm_pathFromAliasData:[NSData data]], nil); - - [GTMUnitTestDevLogDebug expectPattern:@"DebugAssert: " - @"GoogleToolboxForMac: FSPathMakeRef.*"]; - STAssertNil([fileManager gtm_aliasDataForPath:@"/ptah/taht/dosent/esixt/"], nil); - STAssertNil([fileManager gtm_aliasDataForPath:@""], nil); - STAssertNil([fileManager gtm_aliasDataForPath:nil], nil); + XCTAssertNil([fileManager gtm_aliasDataForPath:@"/ptah/taht/dosent/esixt/"]); + XCTAssertNil([fileManager gtm_aliasDataForPath:@""]); + XCTAssertNil([fileManager gtm_aliasDataForPath:nil]); } @end diff --git a/Foundation/GTMNSFileManager+Path.h b/Foundation/GTMNSFileManager+Path.h index 80977b3..eea55df 100644 --- a/Foundation/GTMNSFileManager+Path.h +++ b/Foundation/GTMNSFileManager+Path.h @@ -22,33 +22,6 @@ /// A few useful methods for dealing with paths. @interface NSFileManager (GMFileManagerPathAdditions) -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - -/// For the Unix-y at heart, this is "mkdir -p". It tries to create -/// the directory specified by |path|, and any intervening directories that -/// are needed. Each directory that is created is created with |attributes| -/// (see other NSFileManager doco for the details on |attributes|). -/// -/// If you are building for 10.5 or later, you should just use the new api: -/// createDirectoryAtPath:withIntermediateDirectories:attributes:error: -/// -/// Also if you need more control over the creation of paths and their -/// attributes, look into using GTMPath. -/// -/// Args: -/// path - the path of the directory to create. -/// attributes - these are defined in the "Constants" section of Apple's -/// NSFileManager doco -/// -/// Returns: -/// YES if |path| exists or was able to be created successfully -/// NO otherwise -/// -- (BOOL)gtm_createFullPathToDirectory:(NSString *)path - attributes:(NSDictionary *)attributes; - -#endif // GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - /// Return an the paths for all resources in |directoryPath| that have the /// |extension| file extension. /// diff --git a/Foundation/GTMNSFileManager+Path.m b/Foundation/GTMNSFileManager+Path.m index c29697b..165cee1 100644 --- a/Foundation/GTMNSFileManager+Path.m +++ b/Foundation/GTMNSFileManager+Path.m @@ -21,39 +21,6 @@ @implementation NSFileManager (GMFileManagerPathAdditions) -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - -- (BOOL)gtm_createFullPathToDirectory:(NSString *)path - attributes:(NSDictionary *)attributes { - if (!path) return NO; - - BOOL isDir; - BOOL exists = [self fileExistsAtPath:path isDirectory:&isDir]; - - // Quick check for the case where we have nothing to do. - if (exists && isDir) - return YES; - - NSString *actualPath = @"/"; - NSString *directory; - - GTM_FOREACH_OBJECT(directory, [path pathComponents]) { - actualPath = [actualPath stringByAppendingPathComponent:directory]; - - if ([self fileExistsAtPath:actualPath isDirectory:&isDir] && isDir) { - continue; - } else if ([self createDirectoryAtPath:actualPath attributes:attributes]) { - continue; - } else { - return NO; - } - } - - return YES; -} - -#endif // GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - - (NSArray *)gtm_filePathsWithExtension:(NSString *)extension inDirectory:(NSString *)directoryPath { NSArray *extensions = nil; @@ -73,12 +40,9 @@ } // |basenames| will contain only the matching file names, not their full paths. -#if GTM_IPHONE_SDK || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) NSArray *basenames = [self contentsOfDirectoryAtPath:directoryPath error:nil]; -#else - NSArray *basenames = [self directoryContentsAtPath:directoryPath]; -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + // Check if dir doesn't exist or couldn't be opened. if (!basenames) { @@ -94,7 +58,7 @@ NSString *basename; // Convert all the |basenames| to full paths. - GTM_FOREACH_OBJECT(basename, basenames) { + for (basename in basenames) { NSString *fullPath = [directoryPath stringByAppendingPathComponent:basename]; [paths addObject:fullPath]; } diff --git a/Foundation/GTMNSFileManager+PathTest.m b/Foundation/GTMNSFileManager+PathTest.m index 749c151..a0f61fb 100644 --- a/Foundation/GTMNSFileManager+PathTest.m +++ b/Foundation/GTMNSFileManager+PathTest.m @@ -39,53 +39,17 @@ if (baseDir_) { // clean up our directory NSFileManager *fm = [NSFileManager defaultManager]; -#if GTM_IPHONE_SDK || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) NSError *error = nil; [fm removeItemAtPath:baseDir_ error:&error]; - STAssertNil(error, - @"Unable to delete %@: %@", baseDir_, error); -#else - [fm removeFileAtPath:baseDir_ handler:nil]; -#endif + XCTAssertNil(error, @"Unable to delete %@: %@", baseDir_, error); [baseDir_ release]; baseDir_ = nil; } } -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - -- (void)testCreateFullPathToDirectoryAttributes { - STAssertNotNil(baseDir_, @"setUp failed"); - - NSString *testPath = - [baseDir_ stringByAppendingPathComponent:@"/foo/bar/baz"]; - STAssertNotNil(testPath, nil); - NSFileManager *fm = [NSFileManager defaultManager]; - - STAssertFalse([fm fileExistsAtPath:testPath], - @"You must delete '%@' before running this test", testPath); - - STAssertFalse([fm gtm_createFullPathToDirectory:nil attributes:nil], - @"didn't fail on nil input"); - - STAssertTrue([fm gtm_createFullPathToDirectory:testPath attributes:nil], - @"Failed to create nested testPath"); - STAssertTrue([fm gtm_createFullPathToDirectory:testPath attributes:nil], - @"Failed to succeed on second create of testPath"); - - NSString *pathToFail = [@"/etc" stringByAppendingPathComponent:testPath]; - STAssertFalse([fm gtm_createFullPathToDirectory:pathToFail attributes:nil], - @"We were allowed to create a dir in '/etc'?!"); - - STAssertFalse([fm gtm_createFullPathToDirectory:nil attributes:nil], - @"Should have failed when passed (nil)"); -} - -#endif // GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - - (void)testfilePathsWithExtensionsInDirectory { - STAssertNotNil(baseDir_, @"setUp failed"); + XCTAssertNotNil(baseDir_, @"setUp failed"); NSFileManager *fm = [NSFileManager defaultManager]; NSString *bogusPath = @"/some/place/that/does/not/exist"; @@ -94,23 +58,23 @@ // test fail cases first // single - STAssertNil([fm gtm_filePathsWithExtension:nil inDirectory:nil], - @"shouldn't have gotten anything for nil dir"); - STAssertNil([fm gtm_filePathsWithExtension:@"txt" inDirectory:nil], - @"shouldn't have gotten anything for nil dir"); - STAssertNil([fm gtm_filePathsWithExtension:@"txt" inDirectory:bogusPath], - @"shouldn't have gotten anything for a bogus dir"); + XCTAssertNil([fm gtm_filePathsWithExtension:nil inDirectory:nil], + @"shouldn't have gotten anything for nil dir"); + XCTAssertNil([fm gtm_filePathsWithExtension:@"txt" inDirectory:nil], + @"shouldn't have gotten anything for nil dir"); + XCTAssertNil([fm gtm_filePathsWithExtension:@"txt" inDirectory:bogusPath], + @"shouldn't have gotten anything for a bogus dir"); // array - STAssertNil([fm gtm_filePathsWithExtensions:nil inDirectory:nil], - @"shouldn't have gotten anything for nil dir"); - STAssertNil([fm gtm_filePathsWithExtensions:[NSArray array] inDirectory:nil], - @"shouldn't have gotten anything for nil dir"); - STAssertNil([fm gtm_filePathsWithExtensions:[NSArray arrayWithObject:@"txt"] - inDirectory:nil], - @"shouldn't have gotten anything for nil dir"); - STAssertNil([fm gtm_filePathsWithExtensions:[NSArray arrayWithObject:@"txt"] - inDirectory:bogusPath], - @"shouldn't have gotten anything for a bogus dir"); + XCTAssertNil([fm gtm_filePathsWithExtensions:nil inDirectory:nil], + @"shouldn't have gotten anything for nil dir"); + XCTAssertNil([fm gtm_filePathsWithExtensions:[NSArray array] inDirectory:nil], + @"shouldn't have gotten anything for nil dir"); + XCTAssertNil([fm gtm_filePathsWithExtensions:[NSArray arrayWithObject:@"txt"] + inDirectory:nil], + @"shouldn't have gotten anything for nil dir"); + XCTAssertNil([fm gtm_filePathsWithExtensions:[NSArray arrayWithObject:@"txt"] + inDirectory:bogusPath], + @"shouldn't have gotten anything for a bogus dir"); // -------------------------------------------------------------------------- // create some test data @@ -126,26 +90,22 @@ NSString *testDir = nil; if ([testDirs[i] length]) { testDir = [baseDir_ stringByAppendingPathComponent:testDirs[i]]; -#if GTM_IPHONE_SDK || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) NSError *error = nil; - STAssertTrue([fm createDirectoryAtPath:testDir - withIntermediateDirectories:YES - attributes:nil - error:&error], - @"Can't create %@ (%@)", testDir, error); -#else - STAssertTrue([fm createDirectoryAtPath:testDir attributes:nil], nil); -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + XCTAssertTrue([fm createDirectoryAtPath:testDir + withIntermediateDirectories:YES + attributes:nil + error:&error], + @"Can't create %@ (%@)", testDir, error); } else { testDir = baseDir_; } for (size_t j = 0; j < sizeof(testFiles) / sizeof(NSString*); j++) { NSString *testFile = [testDir stringByAppendingPathComponent:testFiles[j]]; NSError *err = nil; - STAssertTrue([@"test" writeToFile:testFile - atomically:YES - encoding:NSUTF8StringEncoding - error:&err], @"Error: %@", err); + XCTAssertTrue([@"test" writeToFile:testFile + atomically:YES + encoding:NSUTF8StringEncoding + error:&err], @"Error: %@", err); } } @@ -173,23 +133,23 @@ // single matches = [fm gtm_filePathsWithExtension:nil inDirectory:baseDir_]; - STAssertEqualObjects([NSSet setWithArray:matches], - [NSSet setWithArray:allFiles], - @"didn't get all files for nil extension"); + XCTAssertEqualObjects([NSSet setWithArray:matches], + [NSSet setWithArray:allFiles], + @"didn't get all files for nil extension"); matches = [fm gtm_filePathsWithExtension:@"" inDirectory:baseDir_]; - STAssertEqualObjects([NSSet setWithArray:matches], - [NSSet setWithArray:allFiles], - @"didn't get all files for nil extension"); + XCTAssertEqualObjects([NSSet setWithArray:matches], + [NSSet setWithArray:allFiles], + @"didn't get all files for nil extension"); // array matches = [fm gtm_filePathsWithExtensions:nil inDirectory:baseDir_]; - STAssertEqualObjects([NSSet setWithArray:matches], - [NSSet setWithArray:allFiles], - @"didn't get all files for nil extension"); + XCTAssertEqualObjects([NSSet setWithArray:matches], + [NSSet setWithArray:allFiles], + @"didn't get all files for nil extension"); matches = [fm gtm_filePathsWithExtensions:[NSArray array] inDirectory:baseDir_]; - STAssertEqualObjects([NSSet setWithArray:matches], - [NSSet setWithArray:allFiles], - @"didn't get all files for nil extension"); + XCTAssertEqualObjects([NSSet setWithArray:matches], + [NSSet setWithArray:allFiles], + @"didn't get all files for nil extension"); // -------------------------------------------------------------------------- // test match something @@ -198,21 +158,21 @@ extensions = [NSArray arrayWithObject:@"txt"]; matches = [fm gtm_filePathsWithExtension:@"txt" inDirectory:baseDir_]; expectedMatches = [allFiles pathsMatchingExtensions:extensions]; - STAssertEqualObjects([NSSet setWithArray:matches], - [NSSet setWithArray:expectedMatches], - @"didn't get expected files"); + XCTAssertEqualObjects([NSSet setWithArray:matches], + [NSSet setWithArray:expectedMatches], + @"didn't get expected files"); // array matches = [fm gtm_filePathsWithExtensions:extensions inDirectory:baseDir_]; expectedMatches = [allFiles pathsMatchingExtensions:extensions]; - STAssertEqualObjects([NSSet setWithArray:matches], - [NSSet setWithArray:expectedMatches], - @"didn't get expected files"); + XCTAssertEqualObjects([NSSet setWithArray:matches], + [NSSet setWithArray:expectedMatches], + @"didn't get expected files"); extensions = [NSArray arrayWithObjects:@"txt", @"rtf", @"xyz", nil]; matches = [fm gtm_filePathsWithExtensions:extensions inDirectory:baseDir_]; expectedMatches = [allFiles pathsMatchingExtensions:extensions]; - STAssertEqualObjects([NSSet setWithArray:matches], - [NSSet setWithArray:expectedMatches], - @"didn't get expected files"); + XCTAssertEqualObjects([NSSet setWithArray:matches], + [NSSet setWithArray:expectedMatches], + @"didn't get expected files"); // -------------------------------------------------------------------------- // test match nothing @@ -221,43 +181,37 @@ extensions = [NSArray arrayWithObject:@"xyz"]; matches = [fm gtm_filePathsWithExtension:@"xyz" inDirectory:baseDir_]; expectedMatches = [allFiles pathsMatchingExtensions:extensions]; - STAssertEqualObjects([NSSet setWithArray:matches], - [NSSet setWithArray:expectedMatches], - @"didn't get expected files"); + XCTAssertEqualObjects([NSSet setWithArray:matches], + [NSSet setWithArray:expectedMatches], + @"didn't get expected files"); // array matches = [fm gtm_filePathsWithExtensions:extensions inDirectory:baseDir_]; expectedMatches = [allFiles pathsMatchingExtensions:extensions]; - STAssertEqualObjects([NSSet setWithArray:matches], - [NSSet setWithArray:expectedMatches], - @"didn't get expected files"); + XCTAssertEqualObjects([NSSet setWithArray:matches], + [NSSet setWithArray:expectedMatches], + @"didn't get expected files"); // -------------------------------------------------------------------------- // test match an empty dir // create the empty dir NSString *emptyDir = [baseDir_ stringByAppendingPathComponent:@"emptyDir"]; -#if GTM_IPHONE_SDK || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) NSError *error = nil; - STAssertTrue([fm createDirectoryAtPath:emptyDir - withIntermediateDirectories:YES - attributes:nil - error:&error], - @"Can't create %@ (%@)", emptyDir, error); -#else - STAssertTrue([fm createDirectoryAtPath:emptyDir attributes:nil], nil); -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - + XCTAssertTrue([fm createDirectoryAtPath:emptyDir + withIntermediateDirectories:YES + attributes:nil + error:&error], + @"Can't create %@ (%@)", emptyDir, error); // single matches = [fm gtm_filePathsWithExtension:@"txt" inDirectory:emptyDir]; - STAssertEqualObjects([NSSet setWithArray:matches], [NSSet set], - @"expected empty dir"); + XCTAssertEqualObjects([NSSet setWithArray:matches], [NSSet set], + @"expected empty dir"); // array matches = [fm gtm_filePathsWithExtensions:[NSArray arrayWithObject:@"txt"] inDirectory:emptyDir]; - STAssertEqualObjects([NSSet setWithArray:matches], [NSSet set], - @"expected empty dir"); - + XCTAssertEqualObjects([NSSet setWithArray:matches], [NSSet set], + @"expected empty dir"); } @end diff --git a/Foundation/GTMNSObject+KeyValueObserving.m b/Foundation/GTMNSObject+KeyValueObserving.m index c4a589d..45eb6fe 100644 --- a/Foundation/GTMNSObject+KeyValueObserving.m +++ b/Foundation/GTMNSObject+KeyValueObserving.m @@ -25,11 +25,13 @@ // This code is based on code by Michael Ash. // See comment in header. -#import "GTMDefines.h" #import "GTMNSObject+KeyValueObserving.h" + +#import <libkern/OSAtomic.h> +#include <objc/runtime.h> + #import "GTMDefines.h" #import "GTMDebugSelectorValidation.h" -#import "GTMObjC2Runtime.h" #import "GTMMethodCheck.h" // A singleton that works as a dispatch center for KVO @@ -172,9 +174,9 @@ static char* GTMKeyValueObservingHelperContext // and the other will set things up so that the failing thread // gets the shared center GTMKeyValueObservingCenter *newCenter = [[self alloc] init]; - if(!objc_atomicCompareAndSwapGlobalBarrier(nil, - newCenter, - (void *)¢er)) { + if(!OSAtomicCompareAndSwapPtrBarrier(NULL, + newCenter, + (void *)¢er)) { [newCenter release]; // COV_NF_LINE no guarantee we'll hit this line } } @@ -252,7 +254,7 @@ static char* GTMKeyValueObservingHelperContext @synchronized(self) { NSString *helperKey; - GTM_FOREACH_OBJECT(helperKey, [observerHelpers_ allKeys]) { + for (helperKey in [observerHelpers_ allKeys]) { if ([helperKey hasPrefix:key]) { [allValidHelperKeys addObject:helperKey]; } diff --git a/Foundation/GTMNSObject+KeyValueObservingTest.m b/Foundation/GTMNSObject+KeyValueObservingTest.m index 43a1bba..66ae799 100644 --- a/Foundation/GTMNSObject+KeyValueObservingTest.m +++ b/Foundation/GTMNSObject+KeyValueObservingTest.m @@ -29,7 +29,6 @@ #import "GTMSenTestCase.h" #import "GTMNSObject+KeyValueObserving.h" #import "GTMDefines.h" -#import "GTMUnitTestDevLog.h" @interface GTMNSObject_KeyValueObservingTest : GTMTestCase { int32_t count_; @@ -61,12 +60,12 @@ options:NSKeyValueObservingOptionNew]; expectedValue_ = @"bar"; [dict_ setObject:expectedValue_ forKey:@"key"]; - STAssertEquals(count_, (int32_t)1, nil); + XCTAssertEqual(count_, (int32_t)1); [dict_ gtm_removeObserver:self forKeyPath:@"key" selector:@selector(observeValueChange:)]; [dict_ setObject:@"foo" forKey:@"key"]; - STAssertEquals(count_, (int32_t)1, nil); + XCTAssertEqual(count_, (int32_t)1); } - (void)testStopObservingAllKeyPaths { @@ -78,17 +77,14 @@ options:NSKeyValueObservingOptionNew]; expectedValue_ = @"bar"; [dict_ setObject:expectedValue_ forKey:@"key"]; - STAssertEquals(count_, (int32_t)1, nil); + XCTAssertEqual(count_, (int32_t)1); [self gtm_stopObservingAllKeyPaths]; [dict_ setObject:@"foo" forKey:@"key"]; - STAssertEquals(count_, (int32_t)1, nil); + XCTAssertEqual(count_, (int32_t)1); } - (void)testRemoving { - [GTMUnitTestDevLogDebug expectPattern:@"-\\[GTMNSObject_KeyValueObservingTest" - @" testRemoving\\] was not observing.*"]; - [dict_ gtm_removeObserver:self forKeyPath:@"key" selector:@selector(observeValueChange:)]; @@ -100,8 +96,6 @@ selector:@selector(observeValueChange:) userInfo:@"userInfo" options:NSKeyValueObservingOptionNew]; - [GTMUnitTestDevLog expectPattern:@"-\\[GTMNSObject_KeyValueObservingTest" - @" testAdding\\] already observing.*"]; [dict_ gtm_addObserver:self forKeyPath:@"key" selector:@selector(observeValueChange:) @@ -113,17 +107,17 @@ } - (void)observeValueChange:(GTMKeyValueChangeNotification *)notification { - STAssertEqualObjects([notification userInfo], @"userInfo", nil); - STAssertEqualObjects([notification keyPath], @"key", nil); - STAssertEqualObjects([notification object], dict_, nil); + XCTAssertEqualObjects([notification userInfo], @"userInfo"); + XCTAssertEqualObjects([notification keyPath], @"key"); + XCTAssertEqualObjects([notification object], dict_); NSDictionary *change = [notification change]; NSString *value = [change objectForKey:NSKeyValueChangeNewKey]; - STAssertEqualObjects(value, expectedValue_, nil); + XCTAssertEqualObjects(value, expectedValue_); ++count_; GTMKeyValueChangeNotification *copy = [[notification copy] autorelease]; - STAssertEqualObjects(notification, copy, nil); - STAssertEquals([notification hash], [copy hash], nil); + XCTAssertEqualObjects(notification, copy); + XCTAssertEqual([notification hash], [copy hash]); } @end diff --git a/Foundation/GTMNSScanner+JSON.m b/Foundation/GTMNSScanner+JSON.m index 1216698..308eae2 100644 --- a/Foundation/GTMNSScanner+JSON.m +++ b/Foundation/GTMNSScanner+JSON.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -19,10 +19,15 @@ #import "GTMDefines.h" #import "GTMNSScanner+JSON.h" +// Export a nonsense symbol to suppress a libtool warning when this is linked +// alone in a static lib. +__attribute__((visibility("default"))) + char NSScanner_GTMNSScannerJSONAdditionsExportToSuppressLibToolWarning = 0; + @implementation NSScanner (GTMNSScannerJSONAdditions) -- (BOOL)gtm_scanJSONString:(NSString **)jsonString - startChar:(unichar)startChar +- (BOOL)gtm_scanJSONString:(NSString **)jsonString + startChar:(unichar)startChar endChar:(unichar)endChar { BOOL isGood = NO; NSRange jsonRange = { NSNotFound, 0 }; @@ -73,11 +78,11 @@ } - (BOOL)gtm_scanJSONObjectString:(NSString **)jsonString { - return [self gtm_scanJSONString:jsonString startChar:'{' endChar:'}']; + return [self gtm_scanJSONString:jsonString startChar:'{' endChar:'}']; } - (BOOL)gtm_scanJSONArrayString:(NSString**)jsonString { - return [self gtm_scanJSONString:jsonString startChar:'[' endChar:']']; + return [self gtm_scanJSONString:jsonString startChar:'[' endChar:']']; } @end diff --git a/Foundation/GTMNSScanner+JSONTest.m b/Foundation/GTMNSScanner+JSONTest.m index 8085148..d78f41d 100644 --- a/Foundation/GTMNSScanner+JSONTest.m +++ b/Foundation/GTMNSScanner+JSONTest.m @@ -86,27 +86,27 @@ struct { BOOL goodObject = [scanner gtm_scanJSONObjectString:&object]; if (testStrings[i].resultString_) { if (testStrings[i].isObject_) { - STAssertEqualStrings(testStrings[i].resultString_, - object, @"Test String: %@", - testStrings[i].testString_); - STAssertNil(array, @"Test String: %@", testStrings[i].testString_); - STAssertTrue(goodObject, @"Test String: %@", - testStrings[i].testString_); - STAssertFalse(goodArray, @"Test String: %@", + XCTAssertEqualStrings(testStrings[i].resultString_, + object, @"Test String: %@", + testStrings[i].testString_); + XCTAssertNil(array, @"Test String: %@", testStrings[i].testString_); + XCTAssertTrue(goodObject, @"Test String: %@", testStrings[i].testString_); + XCTAssertFalse(goodArray, @"Test String: %@", + testStrings[i].testString_); } else { - STAssertEqualStrings(testStrings[i].resultString_, array, - @"Test String: %@", testStrings[i].testString_); - STAssertNil(object, @"Test String: %@", testStrings[i].testString_); - STAssertTrue(goodArray, @"Test String: %@", testStrings[i].testString_); - STAssertFalse(goodObject, @"Test String: %@", - testStrings[i].testString_); + XCTAssertEqualStrings(testStrings[i].resultString_, array, + @"Test String: %@", testStrings[i].testString_); + XCTAssertNil(object, @"Test String: %@", testStrings[i].testString_); + XCTAssertTrue(goodArray, @"Test String: %@", testStrings[i].testString_); + XCTAssertFalse(goodObject, @"Test String: %@", + testStrings[i].testString_); } } else { - STAssertNil(object, @"Test String: %@", testStrings[i].testString_); - STAssertNil(array, @"Test String: %@", testStrings[i].testString_); - STAssertFalse(goodArray, @"Test String: %@", testStrings[i].testString_); - STAssertFalse(goodObject, @"Test String: %@", testStrings[i].testString_); + XCTAssertNil(object, @"Test String: %@", testStrings[i].testString_); + XCTAssertNil(array, @"Test String: %@", testStrings[i].testString_); + XCTAssertFalse(goodArray, @"Test String: %@", testStrings[i].testString_); + XCTAssertFalse(goodObject, @"Test String: %@", testStrings[i].testString_); } } } @@ -117,13 +117,13 @@ struct { NSScanner *scanner = [NSScanner scannerWithString:testString]; [scanner setCharactersToBeSkipped:alphaSet]; NSString *array = nil; - STAssertTrue([scanner gtm_scanJSONArrayString:&array], nil); - STAssertEqualStrings(array, @"[]", nil); + XCTAssertTrue([scanner gtm_scanJSONArrayString:&array]); + XCTAssertEqualStrings(array, @"[]"); NSString *nextValue = nil; - STAssertTrue([scanner scanString:@":," intoString:&nextValue], nil); - STAssertEqualStrings(@":,", nextValue, nil); + XCTAssertTrue([scanner scanString:@":," intoString:&nextValue]); + XCTAssertEqualStrings(@":,", nextValue); scanner = [NSScanner scannerWithString:testString]; - STAssertFalse([scanner gtm_scanJSONArrayString:&array], nil); + XCTAssertFalse([scanner gtm_scanJSONArrayString:&array]); } @end diff --git a/Foundation/GTMNSScanner+Unsigned.h b/Foundation/GTMNSScanner+Unsigned.h deleted file mode 100644 index 80fdcc4..0000000 --- a/Foundation/GTMNSScanner+Unsigned.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// GTMNSScanner+Unsigned.h -// -// Copyright 2010 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> - -#import "GTMDefines.h" - -// Adds support for working with unsigned values. Unsigned values are digits -// only [0-9]. There is no support for "+" or "-" signs. Overflow is handled -// by returning "YES" and the maximum value allowed for the type. -@interface NSScanner (GTMUnsignedAdditions) - -- (BOOL)gtm_scanUnsignedInt:(unsigned int *)value; -- (BOOL)gtm_scanUInteger:(NSUInteger *)value; -- (BOOL)gtm_scanUnsignedLongLong:(unsigned long long *)value; - -@end diff --git a/Foundation/GTMNSScanner+Unsigned.m b/Foundation/GTMNSScanner+Unsigned.m deleted file mode 100644 index 9228ba2..0000000 --- a/Foundation/GTMNSScanner+Unsigned.m +++ /dev/null @@ -1,60 +0,0 @@ -// -// GTMNSScanner+Unsigned.m -// -// Copyright 2010 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMNSScanner+Unsigned.h" -#include <stdlib.h> -#include <limits.h> - -@implementation NSScanner (GTMUnsignedAdditions) - -- (BOOL)gtm_scanUnsignedInt:(unsigned int *)value { - unsigned long long uLongLongValue = 0; - BOOL wasGood = [self gtm_scanUnsignedLongLong:&uLongLongValue]; - if (wasGood && value) { - if (uLongLongValue > UINT_MAX) { - *value = UINT_MAX; - } else { - *value = (unsigned int)uLongLongValue; - } - } - return wasGood; -} - -- (BOOL)gtm_scanUInteger:(NSUInteger *)value { -#if defined(__LP64__) && __LP64__ - return [self gtm_scanUnsignedLongLong:(unsigned long long*)value]; -#else - return [self gtm_scanUnsignedInt:value]; -#endif // defined(__LP64__) && __LP64__ -} - -- (BOOL)gtm_scanUnsignedLongLong:(unsigned long long *)value { - // Slow path - NSCharacterSet *decimalSet = [NSCharacterSet decimalDigitCharacterSet]; - NSString *digitString = nil; - BOOL wasGood = [self scanCharactersFromSet:decimalSet intoString:&digitString]; - if (wasGood) { - const char *digitChars = [digitString UTF8String]; - if (value) { - *value = strtoull(digitChars, NULL, 10); - } - } - return wasGood; -} - -@end diff --git a/Foundation/GTMNSScanner+UnsignedTest.m b/Foundation/GTMNSScanner+UnsignedTest.m deleted file mode 100644 index aab92f3..0000000 --- a/Foundation/GTMNSScanner+UnsignedTest.m +++ /dev/null @@ -1,116 +0,0 @@ -// -// GTMNSScanner+UnsignedTest.m -// -// Copyright 2010 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" -#import "GTMNSScanner+Unsigned.h" - -@interface GTMNSScanner_UnsignedTest : GTMTestCase -@end - -@implementation GTMNSScanner_UnsignedTest - -#define TEST_BLOCK(A_MAX_VALUE) \ - { @"-1", 0, NO, 0 }, \ - { @"- 1", 0, NO, 0 }, \ - { @" - 1", 0, NO, 0 }, \ - { @"+ 1", 1, NO, 0 }, \ - { @" + 1", 1, NO, 0 }, \ - { @"0", 0, YES, 1 }, \ - { @"a", 0, NO, 0 }, \ - { @" ", 0, NO, 0 }, \ - { @"-1a", 0, NO, 0 }, \ - { @"a1", 0, NO, 0 }, \ - { @"1 ", 1, YES, 1 }, \ - { @"2 1 ", 2, YES, 1 }, \ - { @" 2 1 ", 2, YES, 2 }, \ - { @"99999999999999999999999999999999999", A_MAX_VALUE, YES, 35 } - -- (void)testScanUnsignedInt { - struct { - NSString *string; - unsigned int val; - BOOL goodScan; - NSUInteger location; - } testStruct[] = { - TEST_BLOCK(UINT_MAX), - }; - for (size_t i = 0; i < sizeof(testStruct) / sizeof(testStruct[0]); ++i) { - NSScanner *scanner = [NSScanner scannerWithString:testStruct[i].string]; - STAssertNotNil(scanner, nil); - unsigned int value; - BOOL isGood = [scanner gtm_scanUnsignedInt:&value]; - STAssertEquals((int)isGood, (int)testStruct[i].goodScan, - @"%@", testStruct[i].string); - if (isGood && testStruct[i].goodScan) { - STAssertEquals(value, testStruct[i].val, @"%@", testStruct[i].string); - } - STAssertEquals(testStruct[i].location, [scanner scanLocation], - @"%@", testStruct[i].string); - } -} - -- (void)testScanUInteger { - struct { - NSString *string; - NSUInteger val; - BOOL goodScan; - NSUInteger location; - } testStruct[] = { - TEST_BLOCK(NSUIntegerMax), - }; - for (size_t i = 0; i < sizeof(testStruct) / sizeof(testStruct[0]); ++i) { - NSScanner *scanner = [NSScanner scannerWithString:testStruct[i].string]; - STAssertNotNil(scanner, nil); - NSUInteger value; - BOOL isGood = [scanner gtm_scanUInteger:&value]; - STAssertEquals((int)isGood, (int)testStruct[i].goodScan, - @"%@", testStruct[i].string); - if (isGood && testStruct[i].goodScan) { - STAssertEquals(value, testStruct[i].val, @"%@", testStruct[i].string); - } - STAssertEquals(testStruct[i].location, [scanner scanLocation], - @"%@", testStruct[i].string); - } -} - -- (void)testScanUnsignedLongLong { - struct { - NSString *string; - unsigned long long val; - BOOL goodScan; - NSUInteger location; - } testStruct[] = { - TEST_BLOCK(ULLONG_MAX), - { @"4294967296", ((unsigned long long)UINT_MAX) + 1, YES, 10 } - }; - for (size_t i = 0; i < sizeof(testStruct) / sizeof(testStruct[0]); ++i) { - NSScanner *scanner = [NSScanner scannerWithString:testStruct[i].string]; - STAssertNotNil(scanner, nil); - unsigned long long value; - BOOL isGood = [scanner gtm_scanUnsignedLongLong:&value]; - STAssertEquals((int)isGood, (int)testStruct[i].goodScan, - @"%@", testStruct[i].string); - if (isGood && testStruct[i].goodScan) { - STAssertEquals(value, testStruct[i].val, @"%@", testStruct[i].string); - } - STAssertEquals(testStruct[i].location, [scanner scanLocation], - @"%@", testStruct[i].string); - } -} - -@end diff --git a/Foundation/GTMNSString+FindFolderTest.m b/Foundation/GTMNSString+FindFolderTest.m index aae48cb..2f53d76 100644 --- a/Foundation/GTMNSString+FindFolderTest.m +++ b/Foundation/GTMNSString+FindFolderTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -32,20 +32,20 @@ inDomain:kUserDomain doCreate:NO]; NSString *realPrefsPath = [@"~/Library/Preferences" stringByExpandingTildeInPath]; - STAssertEqualObjects(realPrefsPath, prefsPath, @"Found incorrect prefs path"); + XCTAssertEqualObjects(realPrefsPath, prefsPath, @"Found incorrect prefs path"); + - // test the subfolder method; it should return nil if we pass NO and the // subfolder doesn't already exist - + NSString *googCacheNoCreatePath = [NSString gtm_stringWithPathForFolder:kCachedDataFolderType subfolderName:@"GTMUnitTestDuzntExist" inDomain:kUserDomain doCreate:NO]; - STAssertNil(googCacheNoCreatePath, @"Should not exist: %@", googCacheNoCreatePath); + XCTAssertNil(googCacheNoCreatePath, @"Should not exist: %@", googCacheNoCreatePath); // test creating ~/Library/Cache/GTMUnitTestCreated - + NSString *folderName = @"GTMUnitTestCreated"; NSString *gtmCachePath = [NSString gtm_stringWithPathForFolder:kCachedDataFolderType subfolderName:folderName @@ -55,28 +55,28 @@ inDomain:kUserDomain doCreate:NO]; NSString *testPathAppended = [testPath stringByAppendingPathComponent:folderName]; - STAssertEqualObjects(gtmCachePath, testPathAppended, @"Unexpected path name"); - + XCTAssertEqualObjects(gtmCachePath, testPathAppended, @"Unexpected path name"); + NSFileManager* fileMgr = [NSFileManager defaultManager]; BOOL isDir = NO; BOOL pathExists = [fileMgr fileExistsAtPath:gtmCachePath isDirectory:&isDir] && isDir; - STAssertTrue(pathExists, @"Path %@ is not existing like it should", gtmCachePath); + XCTAssertTrue(pathExists, @"Path %@ is not existing like it should", gtmCachePath); // test finding it again w/o having to create it NSString *gtmCachePath2 = [NSString gtm_stringWithPathForFolder:kCachedDataFolderType subfolderName:folderName inDomain:kUserDomain doCreate:NO]; - STAssertEqualObjects(gtmCachePath2, gtmCachePath, nil); - + XCTAssertEqualObjects(gtmCachePath2, gtmCachePath); + #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 NSError *error = nil; BOOL didRemove = [fileMgr removeItemAtPath:gtmCachePath error:&error]; - STAssertTrue(didRemove, @"Error removing %@ (%@)", gtmCachePath, error); + XCTAssertTrue(didRemove, @"Error removing %@ (%@)", gtmCachePath, error); #else BOOL didRemove = [fileMgr removeFileAtPath:gtmCachePath handler:nil]; - STAssertTrue(didRemove, @"Error removing %@", gtmCachePath); + XCTAssertTrue(didRemove, @"Error removing %@", gtmCachePath); #endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 } diff --git a/Foundation/GTMNSString+HTML.m b/Foundation/GTMNSString+HTML.m index d580b9e..04ec23a 100644 --- a/Foundation/GTMNSString+HTML.m +++ b/Foundation/GTMNSString+HTML.m @@ -7,9 +7,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -20,6 +20,11 @@ #import "GTMDefines.h" #import "GTMNSString+HTML.h" +// Export a nonsense symbol to suppress a libtool warning when this is linked +// alone in a static lib. +__attribute__((visibility("default"))) + char GTMNSString_HTMLExportToSuppressLibToolWarning = 0; + typedef struct { NSString *escapeSequence; unichar uchar; @@ -34,105 +39,105 @@ static HTMLEscapeMap gAsciiHTMLEscapeMap[] = { { @"'", 39 }, { @"<", 60 }, { @">", 62 }, - + // A.2.1. Latin-1 characters - { @" ", 160 }, - { @"¡", 161 }, - { @"¢", 162 }, - { @"£", 163 }, - { @"¤", 164 }, - { @"¥", 165 }, - { @"¦", 166 }, - { @"§", 167 }, - { @"¨", 168 }, - { @"©", 169 }, - { @"ª", 170 }, - { @"«", 171 }, - { @"¬", 172 }, - { @"­", 173 }, - { @"®", 174 }, - { @"¯", 175 }, - { @"°", 176 }, - { @"±", 177 }, - { @"²", 178 }, - { @"³", 179 }, - { @"´", 180 }, - { @"µ", 181 }, - { @"¶", 182 }, - { @"·", 183 }, - { @"¸", 184 }, - { @"¹", 185 }, - { @"º", 186 }, - { @"»", 187 }, - { @"¼", 188 }, - { @"½", 189 }, - { @"¾", 190 }, - { @"¿", 191 }, - { @"À", 192 }, - { @"Á", 193 }, - { @"Â", 194 }, - { @"Ã", 195 }, - { @"Ä", 196 }, - { @"Å", 197 }, - { @"Æ", 198 }, - { @"Ç", 199 }, - { @"È", 200 }, - { @"É", 201 }, - { @"Ê", 202 }, - { @"Ë", 203 }, - { @"Ì", 204 }, - { @"Í", 205 }, - { @"Î", 206 }, - { @"Ï", 207 }, - { @"Ð", 208 }, - { @"Ñ", 209 }, - { @"Ò", 210 }, - { @"Ó", 211 }, - { @"Ô", 212 }, - { @"Õ", 213 }, - { @"Ö", 214 }, - { @"×", 215 }, - { @"Ø", 216 }, - { @"Ù", 217 }, - { @"Ú", 218 }, - { @"Û", 219 }, - { @"Ü", 220 }, - { @"Ý", 221 }, - { @"Þ", 222 }, - { @"ß", 223 }, - { @"à", 224 }, - { @"á", 225 }, - { @"â", 226 }, - { @"ã", 227 }, - { @"ä", 228 }, - { @"å", 229 }, - { @"æ", 230 }, - { @"ç", 231 }, - { @"è", 232 }, - { @"é", 233 }, - { @"ê", 234 }, - { @"ë", 235 }, - { @"ì", 236 }, - { @"í", 237 }, - { @"î", 238 }, - { @"ï", 239 }, - { @"ð", 240 }, - { @"ñ", 241 }, - { @"ò", 242 }, - { @"ó", 243 }, - { @"ô", 244 }, - { @"õ", 245 }, - { @"ö", 246 }, - { @"÷", 247 }, - { @"ø", 248 }, - { @"ù", 249 }, - { @"ú", 250 }, - { @"û", 251 }, - { @"ü", 252 }, - { @"ý", 253 }, - { @"þ", 254 }, + { @" ", 160 }, + { @"¡", 161 }, + { @"¢", 162 }, + { @"£", 163 }, + { @"¤", 164 }, + { @"¥", 165 }, + { @"¦", 166 }, + { @"§", 167 }, + { @"¨", 168 }, + { @"©", 169 }, + { @"ª", 170 }, + { @"«", 171 }, + { @"¬", 172 }, + { @"­", 173 }, + { @"®", 174 }, + { @"¯", 175 }, + { @"°", 176 }, + { @"±", 177 }, + { @"²", 178 }, + { @"³", 179 }, + { @"´", 180 }, + { @"µ", 181 }, + { @"¶", 182 }, + { @"·", 183 }, + { @"¸", 184 }, + { @"¹", 185 }, + { @"º", 186 }, + { @"»", 187 }, + { @"¼", 188 }, + { @"½", 189 }, + { @"¾", 190 }, + { @"¿", 191 }, + { @"À", 192 }, + { @"Á", 193 }, + { @"Â", 194 }, + { @"Ã", 195 }, + { @"Ä", 196 }, + { @"Å", 197 }, + { @"Æ", 198 }, + { @"Ç", 199 }, + { @"È", 200 }, + { @"É", 201 }, + { @"Ê", 202 }, + { @"Ë", 203 }, + { @"Ì", 204 }, + { @"Í", 205 }, + { @"Î", 206 }, + { @"Ï", 207 }, + { @"Ð", 208 }, + { @"Ñ", 209 }, + { @"Ò", 210 }, + { @"Ó", 211 }, + { @"Ô", 212 }, + { @"Õ", 213 }, + { @"Ö", 214 }, + { @"×", 215 }, + { @"Ø", 216 }, + { @"Ù", 217 }, + { @"Ú", 218 }, + { @"Û", 219 }, + { @"Ü", 220 }, + { @"Ý", 221 }, + { @"Þ", 222 }, + { @"ß", 223 }, + { @"à", 224 }, + { @"á", 225 }, + { @"â", 226 }, + { @"ã", 227 }, + { @"ä", 228 }, + { @"å", 229 }, + { @"æ", 230 }, + { @"ç", 231 }, + { @"è", 232 }, + { @"é", 233 }, + { @"ê", 234 }, + { @"ë", 235 }, + { @"ì", 236 }, + { @"í", 237 }, + { @"î", 238 }, + { @"ï", 239 }, + { @"ð", 240 }, + { @"ñ", 241 }, + { @"ò", 242 }, + { @"ó", 243 }, + { @"ô", 244 }, + { @"õ", 245 }, + { @"ö", 246 }, + { @"÷", 247 }, + { @"ø", 248 }, + { @"ù", 249 }, + { @"ú", 250 }, + { @"û", 251 }, + { @"ü", 252 }, + { @"ý", 253 }, + { @"þ", 254 }, { @"ÿ", 255 }, - + // A.2.2. Special characters cont'd { @"Œ", 338 }, { @"œ", 339 }, @@ -141,66 +146,66 @@ static HTMLEscapeMap gAsciiHTMLEscapeMap[] = { { @"Ÿ", 376 }, // A.2.3. Symbols - { @"ƒ", 402 }, + { @"ƒ", 402 }, // A.2.2. Special characters cont'd { @"ˆ", 710 }, { @"˜", 732 }, - + // A.2.3. Symbols cont'd - { @"Α", 913 }, - { @"Β", 914 }, - { @"Γ", 915 }, - { @"Δ", 916 }, - { @"Ε", 917 }, - { @"Ζ", 918 }, - { @"Η", 919 }, - { @"Θ", 920 }, - { @"Ι", 921 }, - { @"Κ", 922 }, - { @"Λ", 923 }, - { @"Μ", 924 }, - { @"Ν", 925 }, - { @"Ξ", 926 }, - { @"Ο", 927 }, - { @"Π", 928 }, - { @"Ρ", 929 }, - { @"Σ", 931 }, - { @"Τ", 932 }, - { @"Υ", 933 }, - { @"Φ", 934 }, - { @"Χ", 935 }, - { @"Ψ", 936 }, - { @"Ω", 937 }, - { @"α", 945 }, - { @"β", 946 }, - { @"γ", 947 }, - { @"δ", 948 }, - { @"ε", 949 }, - { @"ζ", 950 }, - { @"η", 951 }, - { @"θ", 952 }, - { @"ι", 953 }, - { @"κ", 954 }, - { @"λ", 955 }, - { @"μ", 956 }, - { @"ν", 957 }, - { @"ξ", 958 }, - { @"ο", 959 }, - { @"π", 960 }, - { @"ρ", 961 }, - { @"ς", 962 }, - { @"σ", 963 }, - { @"τ", 964 }, - { @"υ", 965 }, - { @"φ", 966 }, - { @"χ", 967 }, - { @"ψ", 968 }, - { @"ω", 969 }, - { @"ϑ", 977 }, - { @"ϒ", 978 }, - { @"ϖ", 982 }, - + { @"Α", 913 }, + { @"Β", 914 }, + { @"Γ", 915 }, + { @"Δ", 916 }, + { @"Ε", 917 }, + { @"Ζ", 918 }, + { @"Η", 919 }, + { @"Θ", 920 }, + { @"Ι", 921 }, + { @"Κ", 922 }, + { @"Λ", 923 }, + { @"Μ", 924 }, + { @"Ν", 925 }, + { @"Ξ", 926 }, + { @"Ο", 927 }, + { @"Π", 928 }, + { @"Ρ", 929 }, + { @"Σ", 931 }, + { @"Τ", 932 }, + { @"Υ", 933 }, + { @"Φ", 934 }, + { @"Χ", 935 }, + { @"Ψ", 936 }, + { @"Ω", 937 }, + { @"α", 945 }, + { @"β", 946 }, + { @"γ", 947 }, + { @"δ", 948 }, + { @"ε", 949 }, + { @"ζ", 950 }, + { @"η", 951 }, + { @"θ", 952 }, + { @"ι", 953 }, + { @"κ", 954 }, + { @"λ", 955 }, + { @"μ", 956 }, + { @"ν", 957 }, + { @"ξ", 958 }, + { @"ο", 959 }, + { @"π", 960 }, + { @"ρ", 961 }, + { @"ς", 962 }, + { @"σ", 963 }, + { @"τ", 964 }, + { @"υ", 965 }, + { @"φ", 966 }, + { @"χ", 967 }, + { @"ψ", 968 }, + { @"ω", 969 }, + { @"ϑ", 977 }, + { @"ϒ", 978 }, + { @"ϖ", 982 }, + // A.2.2. Special characters cont'd { @" ", 8194 }, { @" ", 8195 }, @@ -219,93 +224,93 @@ static HTMLEscapeMap gAsciiHTMLEscapeMap[] = { { @"„", 8222 }, { @"†", 8224 }, { @"‡", 8225 }, - // A.2.3. Symbols cont'd - { @"•", 8226 }, - { @"…", 8230 }, - + // A.2.3. Symbols cont'd + { @"•", 8226 }, + { @"…", 8230 }, + // A.2.2. Special characters cont'd { @"‰", 8240 }, - - // A.2.3. Symbols cont'd - { @"′", 8242 }, - { @"″", 8243 }, + + // A.2.3. Symbols cont'd + { @"′", 8242 }, + { @"″", 8243 }, // A.2.2. Special characters cont'd { @"‹", 8249 }, { @"›", 8250 }, - // A.2.3. Symbols cont'd - { @"‾", 8254 }, - { @"⁄", 8260 }, - + // A.2.3. Symbols cont'd + { @"‾", 8254 }, + { @"⁄", 8260 }, + // A.2.2. Special characters cont'd { @"€", 8364 }, - // A.2.3. Symbols cont'd + // A.2.3. Symbols cont'd { @"ℑ", 8465 }, - { @"℘", 8472 }, - { @"ℜ", 8476 }, - { @"™", 8482 }, - { @"ℵ", 8501 }, - { @"←", 8592 }, - { @"↑", 8593 }, - { @"→", 8594 }, - { @"↓", 8595 }, - { @"↔", 8596 }, - { @"↵", 8629 }, - { @"⇐", 8656 }, - { @"⇑", 8657 }, - { @"⇒", 8658 }, - { @"⇓", 8659 }, - { @"⇔", 8660 }, - { @"∀", 8704 }, - { @"∂", 8706 }, - { @"∃", 8707 }, - { @"∅", 8709 }, - { @"∇", 8711 }, - { @"∈", 8712 }, - { @"∉", 8713 }, - { @"∋", 8715 }, - { @"∏", 8719 }, - { @"∑", 8721 }, - { @"−", 8722 }, - { @"∗", 8727 }, - { @"√", 8730 }, - { @"∝", 8733 }, - { @"∞", 8734 }, - { @"∠", 8736 }, - { @"∧", 8743 }, - { @"∨", 8744 }, - { @"∩", 8745 }, - { @"∪", 8746 }, - { @"∫", 8747 }, - { @"∴", 8756 }, - { @"∼", 8764 }, - { @"≅", 8773 }, - { @"≈", 8776 }, - { @"≠", 8800 }, - { @"≡", 8801 }, - { @"≤", 8804 }, - { @"≥", 8805 }, - { @"⊂", 8834 }, - { @"⊃", 8835 }, - { @"⊄", 8836 }, - { @"⊆", 8838 }, - { @"⊇", 8839 }, - { @"⊕", 8853 }, - { @"⊗", 8855 }, - { @"⊥", 8869 }, - { @"⋅", 8901 }, - { @"⌈", 8968 }, - { @"⌉", 8969 }, - { @"⌊", 8970 }, - { @"⌋", 8971 }, - { @"⟨", 9001 }, - { @"⟩", 9002 }, - { @"◊", 9674 }, - { @"♠", 9824 }, - { @"♣", 9827 }, - { @"♥", 9829 }, + { @"℘", 8472 }, + { @"ℜ", 8476 }, + { @"™", 8482 }, + { @"ℵ", 8501 }, + { @"←", 8592 }, + { @"↑", 8593 }, + { @"→", 8594 }, + { @"↓", 8595 }, + { @"↔", 8596 }, + { @"↵", 8629 }, + { @"⇐", 8656 }, + { @"⇑", 8657 }, + { @"⇒", 8658 }, + { @"⇓", 8659 }, + { @"⇔", 8660 }, + { @"∀", 8704 }, + { @"∂", 8706 }, + { @"∃", 8707 }, + { @"∅", 8709 }, + { @"∇", 8711 }, + { @"∈", 8712 }, + { @"∉", 8713 }, + { @"∋", 8715 }, + { @"∏", 8719 }, + { @"∑", 8721 }, + { @"−", 8722 }, + { @"∗", 8727 }, + { @"√", 8730 }, + { @"∝", 8733 }, + { @"∞", 8734 }, + { @"∠", 8736 }, + { @"∧", 8743 }, + { @"∨", 8744 }, + { @"∩", 8745 }, + { @"∪", 8746 }, + { @"∫", 8747 }, + { @"∴", 8756 }, + { @"∼", 8764 }, + { @"≅", 8773 }, + { @"≈", 8776 }, + { @"≠", 8800 }, + { @"≡", 8801 }, + { @"≤", 8804 }, + { @"≥", 8805 }, + { @"⊂", 8834 }, + { @"⊃", 8835 }, + { @"⊄", 8836 }, + { @"⊆", 8838 }, + { @"⊇", 8839 }, + { @"⊕", 8853 }, + { @"⊗", 8855 }, + { @"⊥", 8869 }, + { @"⋅", 8901 }, + { @"⌈", 8968 }, + { @"⌉", 8969 }, + { @"⌊", 8970 }, + { @"⌋", 8971 }, + { @"⟨", 9001 }, + { @"⟩", 9002 }, + { @"◊", 9674 }, + { @"♠", 9824 }, + { @"♣", 9827 }, + { @"♥", 9829 }, { @"♦", 9830 } }; @@ -325,11 +330,11 @@ static HTMLEscapeMap gUnicodeHTMLEscapeMap[] = { { @"Š", 352 }, { @"š", 353 }, { @"Ÿ", 376 }, - + // Spacing Modifier Letters { @"ˆ", 710 }, { @"˜", 732 }, - + // General Punctuation { @" ", 8194 }, { @" ", 8195 }, @@ -372,14 +377,14 @@ static int EscapeMapCompare(const void *ucharVoid, const void *mapVoid) { @implementation NSString (GTMNSStringHTMLAdditions) -- (NSString *)gtm_stringByEscapingHTMLUsingTable:(HTMLEscapeMap*)table - ofSize:(NSUInteger)size - escapingUnicode:(BOOL)escapeUnicode { +- (NSString *)gtm_stringByEscapingHTMLUsingTable:(HTMLEscapeMap*)table + ofSize:(NSUInteger)size + escapingUnicode:(BOOL)escapeUnicode { NSUInteger length = [self length]; if (!length) { return self; } - + NSMutableString *finalString = [NSMutableString string]; NSMutableData *data2 = [NSMutableData dataWithCapacity:sizeof(unichar) * length]; @@ -405,19 +410,19 @@ static int EscapeMapCompare(const void *ucharVoid, const void *mapVoid) { return nil; // COV_NF_END } - + unichar *buffer2 = (unichar *)[data2 mutableBytes]; - + NSUInteger buffer2Length = 0; - + for (NSUInteger i = 0; i < length; ++i) { - HTMLEscapeMap *val = bsearch(&buffer[i], table, - size / sizeof(HTMLEscapeMap), + HTMLEscapeMap *val = bsearch(&buffer[i], table, + size / sizeof(HTMLEscapeMap), sizeof(HTMLEscapeMap), EscapeMapCompare); if (val || (escapeUnicode && buffer[i] > 127)) { if (buffer2Length) { - CFStringAppendCharacters((CFMutableStringRef)finalString, - buffer2, + CFStringAppendCharacters((CFMutableStringRef)finalString, + buffer2, buffer2Length); buffer2Length = 0; } @@ -434,29 +439,29 @@ static int EscapeMapCompare(const void *ucharVoid, const void *mapVoid) { } } if (buffer2Length) { - CFStringAppendCharacters((CFMutableStringRef)finalString, - buffer2, + CFStringAppendCharacters((CFMutableStringRef)finalString, + buffer2, buffer2Length); } return finalString; } - (NSString *)gtm_stringByEscapingForHTML { - return [self gtm_stringByEscapingHTMLUsingTable:gUnicodeHTMLEscapeMap - ofSize:sizeof(gUnicodeHTMLEscapeMap) + return [self gtm_stringByEscapingHTMLUsingTable:gUnicodeHTMLEscapeMap + ofSize:sizeof(gUnicodeHTMLEscapeMap) escapingUnicode:NO]; } // gtm_stringByEscapingHTML - (NSString *)gtm_stringByEscapingForAsciiHTML { - return [self gtm_stringByEscapingHTMLUsingTable:gAsciiHTMLEscapeMap - ofSize:sizeof(gAsciiHTMLEscapeMap) + return [self gtm_stringByEscapingHTMLUsingTable:gAsciiHTMLEscapeMap + ofSize:sizeof(gAsciiHTMLEscapeMap) escapingUnicode:YES]; } // gtm_stringByEscapingAsciiHTML - (NSString *)gtm_stringByUnescapingFromHTML { NSRange range = NSMakeRange(0, [self length]); NSRange subrange = [self rangeOfString:@"&" options:NSBackwardsSearch range:range]; - + // if no ampersands, we've got a quick way out if (subrange.length == 0) return self; NSMutableString *finalString = [NSMutableString stringWithString:self]; @@ -480,9 +485,9 @@ static int EscapeMapCompare(const void *ucharVoid, const void *mapVoid) { NSString *hexSequence = [escapeString substringWithRange:NSMakeRange(3, length - 4)]; NSScanner *scanner = [NSScanner scannerWithString:hexSequence]; unsigned value; - if ([scanner scanHexInt:&value] && + if ([scanner scanHexInt:&value] && value < USHRT_MAX && - value > 0 + value > 0 && [scanner scanLocation] == length - 4) { unichar uchar = (unichar)value; NSString *charString = [NSString stringWithCharacters:&uchar length:1]; @@ -494,9 +499,9 @@ static int EscapeMapCompare(const void *ucharVoid, const void *mapVoid) { NSString *numberSequence = [escapeString substringWithRange:NSMakeRange(2, length - 3)]; NSScanner *scanner = [NSScanner scannerWithString:numberSequence]; int value; - if ([scanner scanInt:&value] && + if ([scanner scanInt:&value] && value < USHRT_MAX && - value > 0 + value > 0 && [scanner scanLocation] == length - 3) { unichar uchar = (unichar)value; NSString *charString = [NSString stringWithCharacters:&uchar length:1]; diff --git a/Foundation/GTMNSString+HTMLTest.m b/Foundation/GTMNSString+HTMLTest.m index 1c7baf0..52c7b6a 100644 --- a/Foundation/GTMNSString+HTMLTest.m +++ b/Foundation/GTMNSString+HTMLTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -25,65 +25,65 @@ @implementation GTMNSString_HTMLTest - (void)testStringByEscapingHTML { - unichar chars[] = + unichar chars[] = { 34, 38, 39, 60, 62, 338, 339, 352, 353, 376, 710, 732, - 8194, 8195, 8201, 8204, 8205, 8206, 8207, 8211, 8212, 8216, 8217, 8218, + 8194, 8195, 8201, 8204, 8205, 8206, 8207, 8211, 8212, 8216, 8217, 8218, 8220, 8221, 8222, 8224, 8225, 8240, 8249, 8250, 8364, }; - + NSString *string1 = [NSString stringWithCharacters:chars length:sizeof(chars) / sizeof(unichar)]; - NSString *string2 = + NSString *string2 = @""&'<>ŒœŠšŸ" "ˆ˜   ‌‍‎‏–" "—‘’‚“”„†‡" "‰‹›€"; - STAssertEqualObjects([string1 gtm_stringByEscapingForHTML], - string2, - @"HTML escaping failed"); - - STAssertEqualObjects([@"<this & that>" gtm_stringByEscapingForHTML], - @"<this & that>", - @"HTML escaping failed"); + XCTAssertEqualObjects([string1 gtm_stringByEscapingForHTML], + string2, + @"HTML escaping failed"); + + XCTAssertEqualObjects([@"<this & that>" gtm_stringByEscapingForHTML], + @"<this & that>", + @"HTML escaping failed"); NSString *string = [NSString stringWithUTF8String:"パン・&ド・カンパーニュ"]; NSString *escapeStr = [NSString stringWithUTF8String:"パン・&ド・カンパーニュ"]; - STAssertEqualObjects([string gtm_stringByEscapingForHTML], - escapeStr, - @"HTML escaping failed"); - + XCTAssertEqualObjects([string gtm_stringByEscapingForHTML], + escapeStr, + @"HTML escaping failed"); + string = [NSString stringWithUTF8String:"abcا1ب<تdef&"]; - STAssertEqualObjects([string gtm_stringByEscapingForHTML], - [NSString stringWithUTF8String:"abcا1ب<تdef&"], - @"HTML escaping failed"); - + XCTAssertEqualObjects([string gtm_stringByEscapingForHTML], + [NSString stringWithUTF8String:"abcا1ب<تdef&"], + @"HTML escaping failed"); + // test empty string - STAssertEqualObjects([@"" gtm_stringByEscapingForHTML], @"", nil); + XCTAssertEqualObjects([@"" gtm_stringByEscapingForHTML], @""); } // testStringByEscapingHTML - (void)testStringByEscapingAsciiHTML { - unichar chars[] = + unichar chars[] = { 34, 38, 39, 60, 62, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 338, 339, 352, 353, 376, - 402, 710, 732, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, - 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 945, 946, 947, - 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, - 963, 964, 965, 966, 967, 968, 969, 977, 978, 982, 8194, 8195, 8201, 8204, - 8205, 8206, 8207, 8211, 8212, 8216, 8217, 8218, 8220, 8221, 8222, 8224, 8225, - 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8254, 8260, 8364, 8472, 8465, 8476, - 8482, 8501, 8592, 8593, 8594, 8595, 8596, 8629, 8656, 8657, 8658, 8659, 8660, - 8704, 8706, 8707, 8709, 8711, 8712, 8713, 8715, 8719, 8721, 8722, 8727, 8730, - 8733, 8734, 8736, 8743, 8744, 8745, 8746, 8747, 8756, 8764, 8773, 8776, 8800, - 8801, 8804, 8805, 8834, 8835, 8836, 8838, 8839, 8853, 8855, 8869, 8901, 8968, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 338, 339, 352, 353, 376, + 402, 710, 732, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, + 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 945, 946, 947, + 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, + 963, 964, 965, 966, 967, 968, 969, 977, 978, 982, 8194, 8195, 8201, 8204, + 8205, 8206, 8207, 8211, 8212, 8216, 8217, 8218, 8220, 8221, 8222, 8224, 8225, + 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8254, 8260, 8364, 8472, 8465, 8476, + 8482, 8501, 8592, 8593, 8594, 8595, 8596, 8629, 8656, 8657, 8658, 8659, 8660, + 8704, 8706, 8707, 8709, 8711, 8712, 8713, 8715, 8719, 8721, 8722, 8727, 8730, + 8733, 8734, 8736, 8743, 8744, 8745, 8746, 8747, 8756, 8764, 8773, 8776, 8800, + 8801, 8804, 8805, 8834, 8835, 8836, 8838, 8839, 8853, 8855, 8869, 8901, 8968, 8969, 8970, 8971, 9001, 9002, 9674, 9824, 9827, 9829, 9830 }; - + NSString *string1 = [NSString stringWithCharacters:chars length:sizeof(chars) / sizeof(unichar)]; - NSString *string2 = + NSString *string2 = @""&'<> ¡¢£¤¥" "¦§¨©ª«¬­®¯°" "±²³´µ¶·¸¹" @@ -112,29 +112,29 @@ "⊂⊃⊄⊆⊇⊕⊗⊥⋅⌈" "⌉⌊⌋⟨⟩◊♠♣♥" "♦"; - - STAssertEqualObjects([string1 gtm_stringByEscapingForAsciiHTML], - string2, - @"HTML escaping failed"); - - STAssertEqualObjects([@"<this & that>" gtm_stringByEscapingForAsciiHTML], - @"<this & that>", - @"HTML escaping failed"); + + XCTAssertEqualObjects([string1 gtm_stringByEscapingForAsciiHTML], + string2, + @"HTML escaping failed"); + + XCTAssertEqualObjects([@"<this & that>" gtm_stringByEscapingForAsciiHTML], + @"<this & that>", + @"HTML escaping failed"); NSString *string = [NSString stringWithUTF8String:"パン・ド・カンパーニュ"]; - STAssertEqualObjects([string gtm_stringByEscapingForAsciiHTML], - @"パン・ド・カ" - "ンパーニュ", - @"HTML escaping failed"); - + XCTAssertEqualObjects([string gtm_stringByEscapingForAsciiHTML], + @"パン・ド・カ" + "ンパーニュ", + @"HTML escaping failed"); + // Mix in some right - to left string = [NSString stringWithUTF8String:"abcا1ب<تdef&"]; - STAssertEqualObjects([string gtm_stringByEscapingForAsciiHTML], - @"abcا1ب<تdef&", - @"HTML escaping failed"); + XCTAssertEqualObjects([string gtm_stringByEscapingForAsciiHTML], + @"abcا1ب<تdef&", + @"HTML escaping failed"); } // stringByEscapingAsciiHTML - (void)testStringByUnescapingHTML { - NSString *string1 = + NSString *string1 = @""&'<> ¡¢£¤¥" "¦§¨©ª«¬­®¯°" "±²³´µ¶·¸¹" @@ -163,80 +163,81 @@ "⊂⊃⊄⊆⊇⊕⊗⊥⋅⌈" "⌉⌊⌋⟨⟩◊♠♣♥" "♦"; - - unichar chars[] = + + unichar chars[] = { 34, 38, 39, 60, 62, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 338, 339, 352, 353, 376, - 402, 710, 732, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, - 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 945, 946, 947, - 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, - 963, 964, 965, 966, 967, 968, 969, 977, 978, 982, 8194, 8195, 8201, 8204, - 8205, 8206, 8207, 8211, 8212, 8216, 8217, 8218, 8220, 8221, 8222, 8224, 8225, - 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8254, 8260, 8364, 8472, 8465, 8476, - 8482, 8501, 8592, 8593, 8594, 8595, 8596, 8629, 8656, 8657, 8658, 8659, 8660, - 8704, 8706, 8707, 8709, 8711, 8712, 8713, 8715, 8719, 8721, 8722, 8727, 8730, - 8733, 8734, 8736, 8743, 8744, 8745, 8746, 8747, 8756, 8764, 8773, 8776, 8800, - 8801, 8804, 8805, 8834, 8835, 8836, 8838, 8839, 8853, 8855, 8869, 8901, 8968, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 338, 339, 352, 353, 376, + 402, 710, 732, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, + 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 945, 946, 947, + 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, + 963, 964, 965, 966, 967, 968, 969, 977, 978, 982, 8194, 8195, 8201, 8204, + 8205, 8206, 8207, 8211, 8212, 8216, 8217, 8218, 8220, 8221, 8222, 8224, 8225, + 8226, 8230, 8240, 8242, 8243, 8249, 8250, 8254, 8260, 8364, 8472, 8465, 8476, + 8482, 8501, 8592, 8593, 8594, 8595, 8596, 8629, 8656, 8657, 8658, 8659, 8660, + 8704, 8706, 8707, 8709, 8711, 8712, 8713, 8715, 8719, 8721, 8722, 8727, 8730, + 8733, 8734, 8736, 8743, 8744, 8745, 8746, 8747, 8756, 8764, 8773, 8776, 8800, + 8801, 8804, 8805, 8834, 8835, 8836, 8838, 8839, 8853, 8855, 8869, 8901, 8968, 8969, 8970, 8971, 9001, 9002, 9674, 9824, 9827, 9829, 9830 }; - + NSString *string2 = [NSString stringWithCharacters:chars length:sizeof(chars) / sizeof(unichar)]; - STAssertEqualObjects([string1 gtm_stringByUnescapingFromHTML], - string2, - @"HTML unescaping failed"); - - STAssertEqualObjects([@"ABC" gtm_stringByUnescapingFromHTML], - @"ABC", @"HTML unescaping failed"); - - STAssertEqualObjects([@"" gtm_stringByUnescapingFromHTML], - @"", @"HTML unescaping failed"); - - STAssertEqualObjects([@"A&Bang;C" gtm_stringByUnescapingFromHTML], - @"A&Bang;C", @"HTML unescaping failed"); - - STAssertEqualObjects([@"A&Bang;C" gtm_stringByUnescapingFromHTML], - @"A&Bang;C", @"HTML unescaping failed"); - - STAssertEqualObjects([@"A&Bang;C" gtm_stringByUnescapingFromHTML], - @"A&Bang;C", @"HTML unescaping failed"); - - STAssertEqualObjects([@"AA;" gtm_stringByUnescapingFromHTML], - @"AA;", @"HTML unescaping failed"); - - STAssertEqualObjects([@"&" gtm_stringByUnescapingFromHTML], - @"&", @"HTML unescaping failed"); - - STAssertEqualObjects([@"&;" gtm_stringByUnescapingFromHTML], - @"&;", @"HTML unescaping failed"); - - STAssertEqualObjects([@"&x;" gtm_stringByUnescapingFromHTML], - @"&x;", @"HTML unescaping failed"); - - STAssertEqualObjects([@"&X;" gtm_stringByUnescapingFromHTML], - @"&X;", @"HTML unescaping failed"); - - STAssertEqualObjects([@";" gtm_stringByUnescapingFromHTML], - @";", @"HTML unescaping failed"); - - STAssertEqualObjects([@"<this & that>" gtm_stringByUnescapingFromHTML], - @"<this & that>", @"HTML unescaping failed"); - - + XCTAssertEqualObjects([string1 gtm_stringByUnescapingFromHTML], + string2, + @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"ABC" gtm_stringByUnescapingFromHTML], + @"ABC", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"" gtm_stringByUnescapingFromHTML], + @"", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"A&Bang;C" gtm_stringByUnescapingFromHTML], + @"A&Bang;C", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"A&Bang;C" gtm_stringByUnescapingFromHTML], + @"A&Bang;C", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"A&Bang;C" gtm_stringByUnescapingFromHTML], + @"A&Bang;C", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"AA;" gtm_stringByUnescapingFromHTML], + @"AA;", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"&" gtm_stringByUnescapingFromHTML], + @"&", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"&;" gtm_stringByUnescapingFromHTML], + @"&;", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"&x;" gtm_stringByUnescapingFromHTML], + @"&x;", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"&X;" gtm_stringByUnescapingFromHTML], + @"&X;", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@";" gtm_stringByUnescapingFromHTML], + @";", @"HTML unescaping failed"); + + XCTAssertEqualObjects([@"<this & that>" gtm_stringByUnescapingFromHTML], + @"<this & that>", @"HTML unescaping failed"); + + } // testStringByUnescapingHTML - (void)testStringRoundtrippingEscapedHTML { NSString *string = [NSString stringWithUTF8String:"This test ©™®๒०᠐٧"]; - STAssertEqualObjects(string, - [[string gtm_stringByEscapingForHTML] gtm_stringByUnescapingFromHTML], - @"HTML Roundtripping failed"); + XCTAssertEqualObjects(string, + [[string gtm_stringByEscapingForHTML] gtm_stringByUnescapingFromHTML], + @"HTML Roundtripping failed"); string = [NSString stringWithUTF8String:"This test ©™®๒०᠐٧"]; - STAssertEqualObjects(string, - [[string gtm_stringByEscapingForAsciiHTML] gtm_stringByUnescapingFromHTML], - @"HTML Roundtripping failed"); + XCTAssertEqualObjects(string, + [[string gtm_stringByEscapingForAsciiHTML] gtm_stringByUnescapingFromHTML], + @"HTML Roundtripping failed"); } + @end diff --git a/Foundation/GTMNSString+URLArgumentsTest.m b/Foundation/GTMNSString+URLArgumentsTest.m index 5555acf..308b5d6 100644 --- a/Foundation/GTMNSString+URLArgumentsTest.m +++ b/Foundation/GTMNSString+URLArgumentsTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -27,68 +27,68 @@ - (void)testEscaping { // should be done already by the basic code - STAssertEqualObjects([@"this that" gtm_stringByEscapingForURLArgument], @"this%20that", @"- space should be escaped"); - STAssertEqualObjects([@"this\"that" gtm_stringByEscapingForURLArgument], @"this%22that", @"- double quote should be escaped"); + XCTAssertEqualObjects([@"this that" gtm_stringByEscapingForURLArgument], @"this%20that", @"- space should be escaped"); + XCTAssertEqualObjects([@"this\"that" gtm_stringByEscapingForURLArgument], @"this%22that", @"- double quote should be escaped"); // make sure our additions are handled - STAssertEqualObjects([@"this!that" gtm_stringByEscapingForURLArgument], @"this%21that", @"- exclamation mark should be escaped"); - STAssertEqualObjects([@"this*that" gtm_stringByEscapingForURLArgument], @"this%2Athat", @"- asterisk should be escaped"); - STAssertEqualObjects([@"this'that" gtm_stringByEscapingForURLArgument], @"this%27that", @"- single quote should be escaped"); - STAssertEqualObjects([@"this(that" gtm_stringByEscapingForURLArgument], @"this%28that", @"- left paren should be escaped"); - STAssertEqualObjects([@"this)that" gtm_stringByEscapingForURLArgument], @"this%29that", @"- right paren should be escaped"); - STAssertEqualObjects([@"this;that" gtm_stringByEscapingForURLArgument], @"this%3Bthat", @"- semi-colon should be escaped"); - STAssertEqualObjects([@"this:that" gtm_stringByEscapingForURLArgument], @"this%3Athat", @"- colon should be escaped"); - STAssertEqualObjects([@"this@that" gtm_stringByEscapingForURLArgument], @"this%40that", @"- at sign should be escaped"); - STAssertEqualObjects([@"this&that" gtm_stringByEscapingForURLArgument], @"this%26that", @"- ampersand should be escaped"); - STAssertEqualObjects([@"this=that" gtm_stringByEscapingForURLArgument], @"this%3Dthat", @"- equals should be escaped"); - STAssertEqualObjects([@"this+that" gtm_stringByEscapingForURLArgument], @"this%2Bthat", @"- plus should be escaped"); - STAssertEqualObjects([@"this$that" gtm_stringByEscapingForURLArgument], @"this%24that", @"- dollar-sign should be escaped"); - STAssertEqualObjects([@"this,that" gtm_stringByEscapingForURLArgument], @"this%2Cthat", @"- comma should be escaped"); - STAssertEqualObjects([@"this/that" gtm_stringByEscapingForURLArgument], @"this%2Fthat", @"- slash should be escaped"); - STAssertEqualObjects([@"this?that" gtm_stringByEscapingForURLArgument], @"this%3Fthat", @"- question mark should be escaped"); - STAssertEqualObjects([@"this%that" gtm_stringByEscapingForURLArgument], @"this%25that", @"- percent should be escaped"); - STAssertEqualObjects([@"this#that" gtm_stringByEscapingForURLArgument], @"this%23that", @"- pound should be escaped"); - STAssertEqualObjects([@"this[that" gtm_stringByEscapingForURLArgument], @"this%5Bthat", @"- left bracket should be escaped"); - STAssertEqualObjects([@"this]that" gtm_stringByEscapingForURLArgument], @"this%5Dthat", @"- right bracket should be escaped"); + XCTAssertEqualObjects([@"this!that" gtm_stringByEscapingForURLArgument], @"this%21that", @"- exclamation mark should be escaped"); + XCTAssertEqualObjects([@"this*that" gtm_stringByEscapingForURLArgument], @"this%2Athat", @"- asterisk should be escaped"); + XCTAssertEqualObjects([@"this'that" gtm_stringByEscapingForURLArgument], @"this%27that", @"- single quote should be escaped"); + XCTAssertEqualObjects([@"this(that" gtm_stringByEscapingForURLArgument], @"this%28that", @"- left paren should be escaped"); + XCTAssertEqualObjects([@"this)that" gtm_stringByEscapingForURLArgument], @"this%29that", @"- right paren should be escaped"); + XCTAssertEqualObjects([@"this;that" gtm_stringByEscapingForURLArgument], @"this%3Bthat", @"- semi-colon should be escaped"); + XCTAssertEqualObjects([@"this:that" gtm_stringByEscapingForURLArgument], @"this%3Athat", @"- colon should be escaped"); + XCTAssertEqualObjects([@"this@that" gtm_stringByEscapingForURLArgument], @"this%40that", @"- at sign should be escaped"); + XCTAssertEqualObjects([@"this&that" gtm_stringByEscapingForURLArgument], @"this%26that", @"- ampersand should be escaped"); + XCTAssertEqualObjects([@"this=that" gtm_stringByEscapingForURLArgument], @"this%3Dthat", @"- equals should be escaped"); + XCTAssertEqualObjects([@"this+that" gtm_stringByEscapingForURLArgument], @"this%2Bthat", @"- plus should be escaped"); + XCTAssertEqualObjects([@"this$that" gtm_stringByEscapingForURLArgument], @"this%24that", @"- dollar-sign should be escaped"); + XCTAssertEqualObjects([@"this,that" gtm_stringByEscapingForURLArgument], @"this%2Cthat", @"- comma should be escaped"); + XCTAssertEqualObjects([@"this/that" gtm_stringByEscapingForURLArgument], @"this%2Fthat", @"- slash should be escaped"); + XCTAssertEqualObjects([@"this?that" gtm_stringByEscapingForURLArgument], @"this%3Fthat", @"- question mark should be escaped"); + XCTAssertEqualObjects([@"this%that" gtm_stringByEscapingForURLArgument], @"this%25that", @"- percent should be escaped"); + XCTAssertEqualObjects([@"this#that" gtm_stringByEscapingForURLArgument], @"this%23that", @"- pound should be escaped"); + XCTAssertEqualObjects([@"this[that" gtm_stringByEscapingForURLArgument], @"this%5Bthat", @"- left bracket should be escaped"); + XCTAssertEqualObjects([@"this]that" gtm_stringByEscapingForURLArgument], @"this%5Dthat", @"- right bracket should be escaped"); // make sure plus and space are handled in the right order - STAssertEqualObjects([@"this that+the other" gtm_stringByEscapingForURLArgument], @"this%20that%2Bthe%20other", @"- pluses and spaces should be different"); + XCTAssertEqualObjects([@"this that+the other" gtm_stringByEscapingForURLArgument], @"this%20that%2Bthe%20other", @"- pluses and spaces should be different"); // high char test NSString *tester = [NSString stringWithUTF8String:"caf\xC3\xA9"]; - STAssertNotNil(tester, @"failed to create from utf8 run"); - STAssertEqualObjects([tester gtm_stringByEscapingForURLArgument], @"caf%C3%A9", @"- high chars should work"); + XCTAssertNotNil(tester, @"failed to create from utf8 run"); + XCTAssertEqualObjects([tester gtm_stringByEscapingForURLArgument], @"caf%C3%A9", @"- high chars should work"); } - (void)testUnescaping { // should be done already by the basic code - STAssertEqualObjects([@"this%20that" gtm_stringByUnescapingFromURLArgument], @"this that", @"- space should be unescaped"); - STAssertEqualObjects([@"this%22that" gtm_stringByUnescapingFromURLArgument], @"this\"that", @"- double quote should be unescaped"); + XCTAssertEqualObjects([@"this%20that" gtm_stringByUnescapingFromURLArgument], @"this that", @"- space should be unescaped"); + XCTAssertEqualObjects([@"this%22that" gtm_stringByUnescapingFromURLArgument], @"this\"that", @"- double quote should be unescaped"); // make sure our additions are handled - STAssertEqualObjects([@"this%21that" gtm_stringByUnescapingFromURLArgument], @"this!that", @"- exclamation mark should be unescaped"); - STAssertEqualObjects([@"this%2Athat" gtm_stringByUnescapingFromURLArgument], @"this*that", @"- asterisk should be unescaped"); - STAssertEqualObjects([@"this%27that" gtm_stringByUnescapingFromURLArgument], @"this'that", @"- single quote should be unescaped"); - STAssertEqualObjects([@"this%28that" gtm_stringByUnescapingFromURLArgument], @"this(that", @"- left paren should be unescaped"); - STAssertEqualObjects([@"this%29that" gtm_stringByUnescapingFromURLArgument], @"this)that", @"- right paren should be unescaped"); - STAssertEqualObjects([@"this%3Bthat" gtm_stringByUnescapingFromURLArgument], @"this;that", @"- semi-colon should be unescaped"); - STAssertEqualObjects([@"this%3Athat" gtm_stringByUnescapingFromURLArgument], @"this:that", @"- colon should be unescaped"); - STAssertEqualObjects([@"this%40that" gtm_stringByUnescapingFromURLArgument], @"this@that", @"- at sign should be unescaped"); - STAssertEqualObjects([@"this%26that" gtm_stringByUnescapingFromURLArgument], @"this&that", @"- ampersand should be unescaped"); - STAssertEqualObjects([@"this%3Dthat" gtm_stringByUnescapingFromURLArgument], @"this=that", @"- equals should be unescaped"); - STAssertEqualObjects([@"this%2Bthat" gtm_stringByUnescapingFromURLArgument], @"this+that", @"- plus should be unescaped"); - STAssertEqualObjects([@"this%24that" gtm_stringByUnescapingFromURLArgument], @"this$that", @"- dollar-sign should be unescaped"); - STAssertEqualObjects([@"this%2Cthat" gtm_stringByUnescapingFromURLArgument], @"this,that", @"- comma should be unescaped"); - STAssertEqualObjects([@"this%2Fthat" gtm_stringByUnescapingFromURLArgument], @"this/that", @"- slash should be unescaped"); - STAssertEqualObjects([@"this%3Fthat" gtm_stringByUnescapingFromURLArgument], @"this?that", @"- question mark should be unescaped"); - STAssertEqualObjects([@"this%25that" gtm_stringByUnescapingFromURLArgument], @"this%that", @"- percent should be unescaped"); - STAssertEqualObjects([@"this%23that" gtm_stringByUnescapingFromURLArgument], @"this#that", @"- pound should be unescaped"); - STAssertEqualObjects([@"this%5Bthat" gtm_stringByUnescapingFromURLArgument], @"this[that", @"- left bracket should be unescaped"); - STAssertEqualObjects([@"this%5Dthat" gtm_stringByUnescapingFromURLArgument], @"this]that", @"- right bracket should be unescaped"); + XCTAssertEqualObjects([@"this%21that" gtm_stringByUnescapingFromURLArgument], @"this!that", @"- exclamation mark should be unescaped"); + XCTAssertEqualObjects([@"this%2Athat" gtm_stringByUnescapingFromURLArgument], @"this*that", @"- asterisk should be unescaped"); + XCTAssertEqualObjects([@"this%27that" gtm_stringByUnescapingFromURLArgument], @"this'that", @"- single quote should be unescaped"); + XCTAssertEqualObjects([@"this%28that" gtm_stringByUnescapingFromURLArgument], @"this(that", @"- left paren should be unescaped"); + XCTAssertEqualObjects([@"this%29that" gtm_stringByUnescapingFromURLArgument], @"this)that", @"- right paren should be unescaped"); + XCTAssertEqualObjects([@"this%3Bthat" gtm_stringByUnescapingFromURLArgument], @"this;that", @"- semi-colon should be unescaped"); + XCTAssertEqualObjects([@"this%3Athat" gtm_stringByUnescapingFromURLArgument], @"this:that", @"- colon should be unescaped"); + XCTAssertEqualObjects([@"this%40that" gtm_stringByUnescapingFromURLArgument], @"this@that", @"- at sign should be unescaped"); + XCTAssertEqualObjects([@"this%26that" gtm_stringByUnescapingFromURLArgument], @"this&that", @"- ampersand should be unescaped"); + XCTAssertEqualObjects([@"this%3Dthat" gtm_stringByUnescapingFromURLArgument], @"this=that", @"- equals should be unescaped"); + XCTAssertEqualObjects([@"this%2Bthat" gtm_stringByUnescapingFromURLArgument], @"this+that", @"- plus should be unescaped"); + XCTAssertEqualObjects([@"this%24that" gtm_stringByUnescapingFromURLArgument], @"this$that", @"- dollar-sign should be unescaped"); + XCTAssertEqualObjects([@"this%2Cthat" gtm_stringByUnescapingFromURLArgument], @"this,that", @"- comma should be unescaped"); + XCTAssertEqualObjects([@"this%2Fthat" gtm_stringByUnescapingFromURLArgument], @"this/that", @"- slash should be unescaped"); + XCTAssertEqualObjects([@"this%3Fthat" gtm_stringByUnescapingFromURLArgument], @"this?that", @"- question mark should be unescaped"); + XCTAssertEqualObjects([@"this%25that" gtm_stringByUnescapingFromURLArgument], @"this%that", @"- percent should be unescaped"); + XCTAssertEqualObjects([@"this%23that" gtm_stringByUnescapingFromURLArgument], @"this#that", @"- pound should be unescaped"); + XCTAssertEqualObjects([@"this%5Bthat" gtm_stringByUnescapingFromURLArgument], @"this[that", @"- left bracket should be unescaped"); + XCTAssertEqualObjects([@"this%5Dthat" gtm_stringByUnescapingFromURLArgument], @"this]that", @"- right bracket should be unescaped"); // make sure a plus come back out as a space - STAssertEqualObjects([@"this+that" gtm_stringByUnescapingFromURLArgument], @"this that", @"- plus should be unescaped"); + XCTAssertEqualObjects([@"this+that" gtm_stringByUnescapingFromURLArgument], @"this that", @"- plus should be unescaped"); // make sure plus and %2B are handled in the right order - STAssertEqualObjects([@"this+that%2Bthe%20other" gtm_stringByUnescapingFromURLArgument], @"this that+the other", @"- pluses and spaces should be different"); + XCTAssertEqualObjects([@"this+that%2Bthe%20other" gtm_stringByUnescapingFromURLArgument], @"this that+the other", @"- pluses and spaces should be different"); // high char test NSString *tester = [NSString stringWithUTF8String:"caf\xC3\xA9"]; - STAssertNotNil(tester, @"failed to create from utf8 run"); - STAssertEqualObjects([@"caf%C3%A9" gtm_stringByUnescapingFromURLArgument], tester, @"- high chars should work"); + XCTAssertNotNil(tester, @"failed to create from utf8 run"); + XCTAssertEqualObjects([@"caf%C3%A9" gtm_stringByUnescapingFromURLArgument], tester, @"- high chars should work"); } @end diff --git a/Foundation/GTMNSString+XML.m b/Foundation/GTMNSString+XML.m index 2e165e6..a9021ad 100644 --- a/Foundation/GTMNSString+XML.m +++ b/Foundation/GTMNSString+XML.m @@ -19,6 +19,10 @@ #import "GTMDefines.h" #import "GTMNSString+XML.h" +// Export a nonsense symbol to suppress a libtool warning when this is linked alone in a static lib. +__attribute__((visibility("default"))) + char NSString_GTMNSStringXMLAdditionsExportToSuppressLibToolWarning = 0; + enum { kGTMXMLCharModeEncodeQUOT = 0, kGTMXMLCharModeEncodeAMP = 1, diff --git a/Foundation/GTMNSString+XMLTest.m b/Foundation/GTMNSString+XMLTest.m index 7e37e31..1832d90 100644 --- a/Foundation/GTMNSString+XMLTest.m +++ b/Foundation/GTMNSString+XMLTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -39,10 +39,10 @@ [NSString stringWithFormat:@"zzzzz"z&z'z<z>z zzz%Czzz\nz\rz\tz", (unsigned short)0xE000]; - STAssertEqualObjects([string1 gtm_stringBySanitizingAndEscapingForXML], - string2, - @"Sanitize and Escape for XML failed"); - + XCTAssertEqualObjects([string1 gtm_stringBySanitizingAndEscapingForXML], + string2, + @"Sanitize and Escape for XML failed"); + // force the backing store of the NSString to test extraction paths char ascBuffer[] = "a\01bcde\nf"; NSString *ascString = @@ -50,12 +50,12 @@ length:sizeof(ascBuffer) / sizeof(char) encoding:NSASCIIStringEncoding freeWhenDone:NO] autorelease]; - STAssertEqualObjects([ascString gtm_stringBySanitizingAndEscapingForXML], - @"abcde\nf", - @"Sanitize and Escape for XML from asc buffer failed"); + XCTAssertEqualObjects([ascString gtm_stringBySanitizingAndEscapingForXML], + @"abcde\nf", + @"Sanitize and Escape for XML from asc buffer failed"); // test empty string - STAssertEqualObjects([@"" gtm_stringBySanitizingAndEscapingForXML], @"", nil); + XCTAssertEqualObjects([@"" gtm_stringBySanitizingAndEscapingForXML], @""); } - (void)testStringBySanitizingToXMLSpec { @@ -64,16 +64,16 @@ 'z', 0, 'z', 1, 'z', 4, 'z', 5, 'z', 34, 'z', 38, 'z', 39, 'z', 60, 'z', 62, 'z', ' ', 'z', 0xd800, 'z', 0xDFFF, 'z', 0xE000, 'z', 0xFFFE, 'z', 0xFFFF, 'z', '\n', 'z', '\r', 'z', '\t', 'z' }; - + NSString *string1 = [NSString stringWithCharacters:chars length:sizeof(chars) / sizeof(UniChar)]; NSString *string2 = [NSString stringWithFormat:@"zzzzz\"z&z'z<z>z zzz%Czzz\nz\rz\tz", (unsigned short)0xE000]; - - STAssertEqualObjects([string1 gtm_stringBySanitizingToXMLSpec], - string2, - @"Sanitize for XML failed"); + + XCTAssertEqualObjects([string1 gtm_stringBySanitizingToXMLSpec], + string2, + @"Sanitize for XML failed"); // force the backing store of the NSString to test extraction paths char ascBuffer[] = "a\01bcde\nf"; @@ -82,12 +82,12 @@ length:sizeof(ascBuffer) / sizeof(char) encoding:NSASCIIStringEncoding freeWhenDone:NO] autorelease]; - STAssertEqualObjects([ascString gtm_stringBySanitizingToXMLSpec], - @"abcde\nf", - @"Sanitize and Escape for XML from asc buffer failed"); + XCTAssertEqualObjects([ascString gtm_stringBySanitizingToXMLSpec], + @"abcde\nf", + @"Sanitize and Escape for XML from asc buffer failed"); // test empty string - STAssertEqualObjects([@"" gtm_stringBySanitizingToXMLSpec], @"", nil); + XCTAssertEqualObjects([@"" gtm_stringBySanitizingToXMLSpec], @""); } @end diff --git a/Foundation/GTMNSThread+Blocks.h b/Foundation/GTMNSThread+Blocks.h index 23e4e60..e3700bb 100644 --- a/Foundation/GTMNSThread+Blocks.h +++ b/Foundation/GTMNSThread+Blocks.h @@ -38,10 +38,6 @@ #endif // NS_BLOCKS_AVAILABLE -// [NSObject performSelector:onThread:...] 10.5 and later, so this makes no -// sense on any earlier SDK. -#if GTM_IPHONE_SDK || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - // A simple thread that does nothing but handle performBlock and // performSelector calls. @interface GTMSimpleWorkerThread : NSThread { @@ -54,5 +50,3 @@ - (void)stop; @end - -#endif // GTM_IPHONE_SDK || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) diff --git a/Foundation/GTMNSThread+Blocks.m b/Foundation/GTMNSThread+Blocks.m index 2476ad5..4ab3ee5 100644 --- a/Foundation/GTMNSThread+Blocks.m +++ b/Foundation/GTMNSThread+Blocks.m @@ -53,17 +53,6 @@ #endif // NS_BLOCKS_AVAILABLE -#if GTM_IPHONE_SDK || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - -// Only available 10.6 and later. -typedef int (*PThreadSetNameNPPTr)(const char*); -#if !GTM_IPHONE_SDK -static PThreadSetNameNPPTr gPThreadSetNameNP = NULL; -#else -// Defined on iPhone since 3.2 -static PThreadSetNameNPPTr gPThreadSetNameNP = pthread_setname_np; -#endif // !GTM_IPHONE_SDK - enum { kGTMSimpleThreadInitialized = 0, kGTMSimpleThreadStarting, @@ -74,15 +63,6 @@ enum { @implementation GTMSimpleWorkerThread -#if !GTM_IPHONE_SDK -+ (void)initialize { - if (self == [GTMSimpleWorkerThread class]) { - // Resolve pthread_setname_np() on 10.6 and later. - gPThreadSetNameNP = dlsym(RTLD_DEFAULT, "pthread_setname_np"); - } -} -#endif // !GTM_IPHONE_SDK - - (id)init { if ((self = [super init])) { runLock_ = @@ -100,12 +80,10 @@ enum { } - (void)setThreadDebuggerName:(NSString *)name { - if (gPThreadSetNameNP) { - if ([name length]) { - gPThreadSetNameNP([name UTF8String]); - } else { - gPThreadSetNameNP(""); - } + if ([name length]) { + pthread_setname_np([name UTF8String]); + } else { + pthread_setname_np(""); } } @@ -292,5 +270,3 @@ enum { } @end - -#endif // GTM_IPHONE_SDK || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) diff --git a/Foundation/GTMNSThread+BlocksTest.m b/Foundation/GTMNSThread+BlocksTest.m index 606de6d..4b685fd 100644 --- a/Foundation/GTMNSThread+BlocksTest.m +++ b/Foundation/GTMNSThread+BlocksTest.m @@ -20,8 +20,6 @@ #import "GTMSenTestCase.h" #import "GTMNSThread+Blocks.h" -#if GTM_IPHONE_SDK || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) - #import "GTMFoundationUnitTestingUtilities.h" @interface GTMNSThread_BlocksTest : GTMTestCase { @@ -56,8 +54,8 @@ runThread = [NSThread currentThread]; [context setShouldStop:YES]; }]; - STAssertEqualObjects(runThread, currentThread, nil); - STAssertTrue([context shouldStop], nil); + XCTAssertEqualObjects(runThread, currentThread); + XCTAssertTrue([context shouldStop]); // Block with waiting runs immediately as well. runThread = nil; @@ -66,8 +64,8 @@ runThread = [NSThread currentThread]; [context setShouldStop:YES]; }]; - STAssertEqualObjects(runThread, currentThread, nil); - STAssertTrue([context shouldStop], nil); + XCTAssertEqualObjects(runThread, currentThread); + XCTAssertTrue([context shouldStop]); // Block without waiting requires a runloop spin. runThread = nil; @@ -76,10 +74,10 @@ runThread = [NSThread currentThread]; [context setShouldStop:YES]; }]; - STAssertTrue([[NSRunLoop currentRunLoop] - gtm_runUpToSixtySecondsWithContext:context], nil); - STAssertEqualObjects(runThread, currentThread, nil); - STAssertTrue([context shouldStop], nil); + XCTAssertTrue([[NSRunLoop currentRunLoop] + gtm_runUpToSixtySecondsWithContext:context]); + XCTAssertEqualObjects(runThread, currentThread); + XCTAssertTrue([context shouldStop]); } - (void)testPerformBlockInBackground { @@ -90,52 +88,52 @@ runThread = [NSThread currentThread]; [context setShouldStop:YES]; }]; - STAssertTrue([[NSRunLoop currentRunLoop] - gtm_runUpToSixtySecondsWithContext:context], nil); - STAssertNotNil(runThread, nil); - STAssertNotEqualObjects(runThread, [NSThread currentThread], nil); + XCTAssertTrue([[NSRunLoop currentRunLoop] + gtm_runUpToSixtySecondsWithContext:context]); + XCTAssertNotNil(runThread); + XCTAssertNotEqualObjects(runThread, [NSThread currentThread]); } - (void)testWorkerThreadBasics { // Unstarted worker isn't running. GTMSimpleWorkerThread *worker = [[GTMSimpleWorkerThread alloc] init]; - STAssertFalse([worker isExecuting], nil); - STAssertFalse([worker isFinished], nil); + XCTAssertFalse([worker isExecuting]); + XCTAssertFalse([worker isFinished]); // Unstarted worker can be stopped without error. [worker stop]; - STAssertFalse([worker isExecuting], nil); - STAssertTrue([worker isFinished], nil); + XCTAssertFalse([worker isExecuting]); + XCTAssertTrue([worker isFinished]); // And can be stopped again [worker stop]; - STAssertFalse([worker isExecuting], nil); - STAssertTrue([worker isFinished], nil); + XCTAssertFalse([worker isExecuting]); + XCTAssertTrue([worker isFinished]); // A thread we start can be stopped with correct state. worker = [[GTMSimpleWorkerThread alloc] init]; - STAssertFalse([worker isExecuting], nil); - STAssertFalse([worker isFinished], nil); + XCTAssertFalse([worker isExecuting]); + XCTAssertFalse([worker isFinished]); [worker start]; - STAssertTrue([worker isExecuting], nil); - STAssertFalse([worker isFinished], nil); + XCTAssertTrue([worker isExecuting]); + XCTAssertFalse([worker isFinished]); [worker stop]; - STAssertFalse([worker isExecuting], nil); - STAssertTrue([worker isFinished], nil); + XCTAssertFalse([worker isExecuting]); + XCTAssertTrue([worker isFinished]); // A cancel is also honored worker = [[GTMSimpleWorkerThread alloc] init]; - STAssertFalse([worker isExecuting], nil); - STAssertFalse([worker isFinished], nil); + XCTAssertFalse([worker isExecuting]); + XCTAssertFalse([worker isFinished]); [worker start]; - STAssertTrue([worker isExecuting], nil); - STAssertFalse([worker isFinished], nil); + XCTAssertTrue([worker isExecuting]); + XCTAssertFalse([worker isFinished]); [worker cancel]; // And after some time we're done. We're generous here, this needs to // exceed the worker thread's runloop timeout. sleep(5); - STAssertFalse([worker isExecuting], nil); - STAssertTrue([worker isFinished], nil); + XCTAssertFalse([worker isExecuting]); + XCTAssertTrue([worker isFinished]); } - (void)testWorkerThreadStopTiming { @@ -146,14 +144,14 @@ [workerThread_ gtm_performBlock:^{ [threadLock lock]; [threadLock unlockWithCondition:1]; - sleep(10); + [NSThread sleepForTimeInterval:.25]; }]; [threadLock lockWhenCondition:1]; [threadLock unlock]; [workerThread_ stop]; - STAssertFalse([workerThread_ isExecuting], nil); - STAssertTrue([workerThread_ isFinished], nil); - STAssertEqualsWithAccuracy(-[start timeIntervalSinceNow], 10.0, 2.0, nil); + XCTAssertFalse([workerThread_ isExecuting]); + XCTAssertTrue([workerThread_ isFinished]); + XCTAssertEqualWithAccuracy(-[start timeIntervalSinceNow], 0.25, 0.25); } - (void)testPerformBlockOnWorkerThread { @@ -168,10 +166,10 @@ runThread = [NSThread currentThread]; [context setShouldStop:YES]; }]; - STAssertTrue([[NSRunLoop currentRunLoop] - gtm_runUpToSixtySecondsWithContext:context], nil); - STAssertNotNil(runThread, nil); - STAssertEqualObjects(runThread, workerThread_, nil); + XCTAssertTrue([[NSRunLoop currentRunLoop] + gtm_runUpToSixtySecondsWithContext:context]); + XCTAssertNotNil(runThread); + XCTAssertEqualObjects(runThread, workerThread_); // Other thread no wait. runThread = nil; @@ -180,10 +178,10 @@ runThread = [NSThread currentThread]; [context setShouldStop:YES]; }]; - STAssertTrue([[NSRunLoop currentRunLoop] - gtm_runUpToSixtySecondsWithContext:context], nil); - STAssertNotNil(runThread, nil); - STAssertEqualObjects(runThread, workerThread_, nil); + XCTAssertTrue([[NSRunLoop currentRunLoop] + gtm_runUpToSixtySecondsWithContext:context]); + XCTAssertNotNil(runThread); + XCTAssertEqualObjects(runThread, workerThread_); // Waiting requires no runloop spin runThread = nil; @@ -192,9 +190,9 @@ runThread = [NSThread currentThread]; [context setShouldStop:YES]; }]; - STAssertTrue([context shouldStop], nil); - STAssertNotNil(runThread, nil); - STAssertEqualObjects(runThread, workerThread_, nil); + XCTAssertTrue([context shouldStop]); + XCTAssertNotNil(runThread); + XCTAssertEqualObjects(runThread, workerThread_); } - (void)testExitingBlockIsExecuting { @@ -208,10 +206,10 @@ [threadLock lockWhenCondition:1]; [threadLock unlock]; // Give the pthread_exit() a bit of time - sleep(5); + [NSThread sleepForTimeInterval:.25]; // Did we notice the thread died? Does [... isExecuting] clean up? - STAssertFalse([workerThread_ isExecuting], nil); - STAssertTrue([workerThread_ isFinished], nil); + XCTAssertFalse([workerThread_ isExecuting]); + XCTAssertTrue([workerThread_ isFinished]); } - (void)testExitingBlockCancel { @@ -225,12 +223,12 @@ [threadLock lockWhenCondition:1]; [threadLock unlock]; // Give the pthread_exit() a bit of time - sleep(5); + [NSThread sleepForTimeInterval:.25]; // Cancel/stop the thread [workerThread_ stop]; // Did we notice the thread died? Did we clean up? - STAssertFalse([workerThread_ isExecuting], nil); - STAssertTrue([workerThread_ isFinished], nil); + XCTAssertFalse([workerThread_ isExecuting]); + XCTAssertTrue([workerThread_ isFinished]); } - (void)testStopFromThread { @@ -245,23 +243,20 @@ [threadLock lockWhenCondition:1]; [threadLock unlock]; // Still need to give the thread a moment to not be executing - sleep(5); - STAssertFalse([workerThread_ isExecuting], nil); - STAssertTrue([workerThread_ isFinished], nil); + sleep(1); + XCTAssertFalse([workerThread_ isExecuting]); + XCTAssertTrue([workerThread_ isFinished]); } - (void)testPThreadName { NSString *testName = @"InigoMontoya"; [workerThread_ setName:testName]; [workerThread_ gtm_performWaitingUntilDone:NO block:^{ - STAssertEqualObjects([workerThread_ name], testName, nil); + XCTAssertEqualObjects([workerThread_ name], testName); char threadName[100]; pthread_getname_np(pthread_self(), threadName, 100); - STAssertEqualObjects([NSString stringWithUTF8String:threadName], - testName, nil); + XCTAssertEqualObjects([NSString stringWithUTF8String:threadName], testName); }]; } @end - -#endif // GTM_IPHONE_SDK || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) diff --git a/Foundation/GTMObjC2Runtime.h b/Foundation/GTMObjC2Runtime.h index e4e2ac7..e14df70 100644 --- a/Foundation/GTMObjC2Runtime.h +++ b/Foundation/GTMObjC2Runtime.h @@ -16,98 +16,16 @@ // the License. // +// These headers only being pulled in to avoid breaking changes. + +#pragma GCC warning "GTMObjcRuntime.h is deprecated and should no longer be used." + #import <objc/objc-api.h> #import <objc/objc-auto.h> #import "GTMDefines.h" -// These functions exist for code that we want to compile on both the < 10.5 -// sdks and on the >= 10.5 sdks without warnings. It basically reimplements -// certain parts of the objc2 runtime in terms of the objc1 runtime. It is not -// a complete implementation as I've only implemented the routines I know we -// use. Feel free to add more as necessary. -// These functions are not documented because they conform to the documentation -// for the ObjC2 Runtime. - -#if OBJC_API_VERSION >= 2 // Only have optional and req'd keywords in ObjC2. -#define AT_OPTIONAL @optional -#define AT_REQUIRED @required -#else -#define AT_OPTIONAL -#define AT_REQUIRED -#endif - -// The file objc-runtime.h was moved to runtime.h and in Leopard, objc-runtime.h -// was just a wrapper around runtime.h. For the iPhone SDK, this objc-runtime.h -// is removed in the iPhoneOS2.0 SDK. -// -// The |Object| class was removed in the iPhone2.0 SDK too. -#if GTM_IPHONE_SDK #import <objc/message.h> #import <objc/runtime.h> -#else -#import <objc/objc-runtime.h> -#import <objc/Object.h> -#endif #import <libkern/OSAtomic.h> -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) -#import "objc/Protocol.h" - -OBJC_EXPORT Class object_getClass(id obj); -OBJC_EXPORT const char *class_getName(Class cls); -OBJC_EXPORT BOOL class_conformsToProtocol(Class cls, Protocol *protocol); -OBJC_EXPORT BOOL class_respondsToSelector(Class cls, SEL sel); -OBJC_EXPORT Class class_getSuperclass(Class cls); -OBJC_EXPORT Method *class_copyMethodList(Class cls, unsigned int *outCount); -OBJC_EXPORT SEL method_getName(Method m); -OBJC_EXPORT void method_exchangeImplementations(Method m1, Method m2); -OBJC_EXPORT IMP method_getImplementation(Method method); -OBJC_EXPORT IMP method_setImplementation(Method method, IMP imp); -OBJC_EXPORT struct objc_method_description protocol_getMethodDescription(Protocol *p, - SEL aSel, - BOOL isRequiredMethod, - BOOL isInstanceMethod); -OBJC_EXPORT BOOL sel_isEqual(SEL lhs, SEL rhs); - -// If building for 10.4 but using the 10.5 SDK, don't include these. -#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 -// atomics -// On Leopard these are GC aware -// Intentionally did not include the non-barrier versions, because I couldn't -// come up with a case personally where you wouldn't want to use the -// barrier versions. -GTM_INLINE bool OSAtomicCompareAndSwapPtrBarrier(void *predicate, - void *replacement, - void * volatile *theValue) { -#if defined(__LP64__) && __LP64__ - return OSAtomicCompareAndSwap64Barrier((int64_t)predicate, - (int64_t)replacement, - (int64_t *)theValue); -#else // defined(__LP64__) && __LP64__ - return OSAtomicCompareAndSwap32Barrier((int32_t)predicate, - (int32_t)replacement, - (int32_t *)theValue); -#endif // defined(__LP64__) && __LP64__ -} - -#endif // MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 -#endif // GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5) - -GTM_INLINE BOOL objc_atomicCompareAndSwapGlobalBarrier(id predicate, - id replacement, - volatile id *objectLocation) { - return OSAtomicCompareAndSwapPtrBarrier(predicate, - replacement, - (void * volatile *)objectLocation); -} -GTM_INLINE BOOL objc_atomicCompareAndSwapInstanceVariableBarrier(id predicate, - id replacement, - volatile id *objectLocation) { - return OSAtomicCompareAndSwapPtrBarrier(predicate, - replacement, - (void * volatile *)objectLocation); -} -#endif // GTM_MACOS_SDK && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5) diff --git a/Foundation/GTMObjC2Runtime.m b/Foundation/GTMObjC2Runtime.m index 1475103..9bd937c 100644 --- a/Foundation/GTMObjC2Runtime.m +++ b/Foundation/GTMObjC2Runtime.m @@ -16,158 +16,6 @@ // the License. // -#import "GTMObjC2Runtime.h" +// This source file is no longer necessary. -// Export a nonsense symbol to suppress a libtool warning when this is linked alone in a static lib. -__attribute__((visibility("default"))) char GTMObjC2RuntimeExportToSuppressLibToolWarning = 0; - - -#if GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) && !__OBJC2__ -#import <objc/objc-runtime.h> -#import <stdlib.h> -#import <string.h> - -Class object_getClass(id obj) { - if (!obj) return NULL; - return obj->isa; -} - -const char *class_getName(Class cls) { - if (!cls) return "nil"; - return cls->name; -} - -BOOL class_conformsToProtocol(Class cls, Protocol *protocol) { - // We intentionally don't check cls as it crashes on Leopard so we want - // to crash on Tiger as well. - // I logged - // Radar 5572978 class_conformsToProtocol crashes when arg1 is passed as nil - // because it seems odd that this API won't accept nil for cls considering - // all the other apis will accept nil args. - // If this does get fixed, remember to enable the unit tests. - if (!protocol) return NO; - - struct objc_protocol_list *protos; - for (protos = cls->protocols; protos != NULL; protos = protos->next) { - for (long i = 0; i < protos->count; i++) { - if ([protos->list[i] conformsTo:protocol]) { - return YES; - } - } - } - return NO; -} - -Class class_getSuperclass(Class cls) { - if (!cls) return NULL; - return cls->super_class; -} - -BOOL class_respondsToSelector(Class cls, SEL sel) { - return class_getInstanceMethod(cls, sel) != nil; -} - -Method *class_copyMethodList(Class cls, unsigned int *outCount) { - if (!cls) return NULL; - - unsigned int count = 0; - void *iterator = NULL; - struct objc_method_list *mlist; - Method *methods = NULL; - if (outCount) *outCount = 0; - - while ( (mlist = class_nextMethodList(cls, &iterator)) ) { - if (mlist->method_count == 0) continue; - Method *new_methods = (Method *)realloc(methods, - sizeof(Method) * (count + mlist->method_count + 1)); - if (!new_methods) { - // COV_NF_START - //Memory alloc failed, so what can we do? - free(methods); - return NULL; - // COV_NF_END - } else { - methods = new_methods; - } - for (int i = 0; i < mlist->method_count; i++) { - methods[i + count] = &mlist->method_list[i]; - } - count += mlist->method_count; - } - - // List must be NULL terminated - if (methods) { - methods[count] = NULL; - } - if (outCount) *outCount = count; - return methods; -} - -SEL method_getName(Method method) { - if (!method) return NULL; - return method->method_name; -} - -IMP method_getImplementation(Method method) { - if (!method) return NULL; - return method->method_imp; -} - -IMP method_setImplementation(Method method, IMP imp) { - // We intentionally don't test method for nil. - // Leopard fails here, so should we. - // I logged this as Radar: - // 5572981 method_setImplementation crashes if you pass nil for the - // method arg (arg 1) - // because it seems odd that this API won't accept nil for method considering - // all the other apis will accept nil args. - // If this does get fixed, remember to enable the unit tests. - // This method works differently on SnowLeopard than - // on Leopard. If you pass in a nil for IMP on SnowLeopard - // it doesn't change anything. On Leopard it will. Since - // attempting to change a sel to nil is probably an error - // we follow the SnowLeopard way of doing things. - IMP oldImp = NULL; - if (imp) { - oldImp = method->method_imp; - method->method_imp = imp; - } - return oldImp; -} - -void method_exchangeImplementations(Method m1, Method m2) { - if (m1 == m2) return; - if (!m1 || !m2) return; - IMP imp2 = method_getImplementation(m2); - IMP imp1 = method_setImplementation(m1, imp2); - method_setImplementation(m2, imp1); -} - -struct objc_method_description protocol_getMethodDescription(Protocol *p, - SEL aSel, - BOOL isRequiredMethod, - BOOL isInstanceMethod) { - struct objc_method_description *descPtr = NULL; - // No such thing as required in ObjC1. - if (isInstanceMethod) { - descPtr = [p descriptionForInstanceMethod:aSel]; - } else { - descPtr = [p descriptionForClassMethod:aSel]; - } - - struct objc_method_description desc; - if (descPtr) { - desc = *descPtr; - } else { - bzero(&desc, sizeof(desc)); - } - return desc; -} - -BOOL sel_isEqual(SEL lhs, SEL rhs) { - // Apple (informally) promises this will work in the future: - // http://twitter.com/#!/gparker/status/2400099786 - return (lhs == rhs) ? YES : NO; -} - -#endif // GTM_MACOS_SDK && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) +#pragma GCC warning "GTMObjc2Runtime.m is deprecated and should no longer be used." diff --git a/Foundation/GTMObjC2RuntimeTest.m b/Foundation/GTMObjC2RuntimeTest.m deleted file mode 100644 index 2e6362c..0000000 --- a/Foundation/GTMObjC2RuntimeTest.m +++ /dev/null @@ -1,445 +0,0 @@ -// -// GTMObjC2RuntimeTest.m -// -// Copyright 2007-2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMObjC2Runtime.h" -#import "GTMSenTestCase.h" -#import "GTMSystemVersion.h" -#import "GTMTypeCasting.h" - -#import <string.h> - -@protocol GTMObjC2Runtime_TestProtocol -@end - -@protocol GTMObjC2Runtime_Test2Protocol -AT_OPTIONAL -- (NSString*)optional; -AT_REQUIRED -- (NSString*)required; -AT_OPTIONAL -+ (NSString*)class_optional; -AT_REQUIRED -+ (NSString*)class_required; -@end - -@interface GTMObjC2RuntimeTest : GTMTestCase { - Class cls_; -} -@end - -@interface GTMObjC2Runtime_TestClass : NSObject <GTMObjC2Runtime_TestProtocol> -- (NSString*)kwyjibo; - -@end - -@interface GTMObjC2Runtime_TestClass (GMObjC2Runtime_TestClassCategory) -- (NSString*)eatMyShorts; -@end - -@implementation GTMObjC2Runtime_TestClass - -+ (NSString*)dontHaveACow { - return @"dontHaveACow"; -} - -- (NSString*)kwyjibo { - return @"kwyjibo"; -} -@end - -@implementation GTMObjC2Runtime_TestClass (GMObjC2Runtime_TestClassCategory) -- (NSString*)eatMyShorts { - return @"eatMyShorts"; -} - -+ (NSString*)brokeHisBrain { - return @"brokeHisBrain"; -} - -@end - -@interface GTMObjC2NotificationWatcher : NSObject -- (void)startedTest:(NSNotification *)notification; -@end - -@implementation GTMObjC2NotificationWatcher -- (id)init { - if ((self = [super init])) { - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - // We release ourselves when we are notified. - [self retain]; - [nc addObserver:self - selector:@selector(startedTest:) - name:SenTestSuiteDidStartNotification - object:nil]; - - } - return self; -} - -- (void)startedTest:(NSNotification *)notification { - // Logs if we are testing on Tiger or Leopard runtime. - SenTestSuiteRun *suiteRun = GTM_STATIC_CAST(SenTestSuiteRun, - [notification object]); - NSString *testName = [[suiteRun test] name]; - NSString *className = NSStringFromClass([GTMObjC2RuntimeTest class]); - if ([testName isEqualToString:className]) { - NSString *runtimeString; -#ifndef OBJC2_UNAVAILABLE - runtimeString = @"ObjC1"; -#else - runtimeString = @"ObjC2"; -#endif - NSLog(@"Running GTMObjC2RuntimeTests using %@ runtime.", runtimeString); - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc removeObserver:self]; - [self autorelease]; - } -} -@end - -@implementation GTMObjC2RuntimeTest - -+ (void)initialize { - // This allows us to track which runtime we are actually testing. - [[[GTMObjC2NotificationWatcher alloc] init] autorelease]; -} - -- (void)setUp { - cls_ = [[GTMObjC2Runtime_TestClass class] retain]; -} - -- (void)tearDown { - [cls_ release]; -} - -- (void)test_object_getClass { - // Nil Checks - STAssertNil(object_getClass(nil), nil); - - // Standard use check - GTMObjC2Runtime_TestClass *test = [[[cls_ alloc] init] autorelease]; - Class cls = object_getClass(test); - STAssertEqualObjects(cls, cls_, nil); -} - -- (void)test_class_getName { - // Nil Checks - const char *name = class_getName(nil); - STAssertEqualCStrings(name, "nil", nil); - - // Standard use check - STAssertEqualCStrings(class_getName(cls_), "GTMObjC2Runtime_TestClass", nil); -} - -- (void)test_class_conformsToProtocol { - // Nil Checks - STAssertFalse(class_conformsToProtocol(cls_, @protocol(NSObject)), nil); - STAssertFalse(class_conformsToProtocol(cls_, nil), nil); - // The following two tests intentionally commented out as they fail on - // Leopard with a crash, so we fail on Tiger intentionally as well. - // STAssertFalse(class_conformsToProtocol(nil, @protocol(NSObject)), nil); - // STAssertFalse(class_conformsToProtocol(nil, nil), nil); - - // Standard use check - STAssertTrue(class_conformsToProtocol(cls_, - @protocol(GTMObjC2Runtime_TestProtocol)), - nil); -} - -- (void)test_class_respondsToSelector { - // Nil Checks - STAssertFalse(class_respondsToSelector(cls_, @selector(setUp)), nil); - STAssertFalse(class_respondsToSelector(cls_, nil), nil); - - // Standard use check - STAssertTrue(class_respondsToSelector(cls_, @selector(kwyjibo)), nil); -} - -- (void)test_class_getSuperclass { - // Nil Checks - STAssertNil(class_getSuperclass(nil), nil); - - // Standard use check - STAssertEqualObjects(class_getSuperclass(cls_), [NSObject class], nil); -} - -- (void)test_class_copyMethodList { - // Nil Checks - Method *list = class_copyMethodList(nil, nil); - STAssertNULL(list, nil); - - // Standard use check - list = class_copyMethodList(cls_, nil); - STAssertNotNULL(list, nil); - free(list); - unsigned int count = 0; - list = class_copyMethodList(cls_, &count); - STAssertNotNULL(list, nil); - STAssertEquals(count, 2U, nil); - STAssertNULL(list[count], nil); - free(list); - - // Now test meta class - count = 0; - list = class_copyMethodList((Class)objc_getMetaClass(class_getName(cls_)), - &count); - STAssertNotNULL(list, nil); - STAssertEquals(count, 2U, nil); - STAssertNULL(list[count], nil); - free(list); -} - -- (void)test_method_getName { - // Nil Checks - STAssertNULL(method_getName(nil), nil); - - // Standard use check - Method *list = class_copyMethodList(cls_, nil); - STAssertNotNULL(list, nil); - const char* selName1 = sel_getName(method_getName(list[0])); - const char* selName2 = sel_getName(@selector(kwyjibo)); - const char* selName3 = sel_getName(@selector(eatMyShorts)); - BOOL isGood = ((strcmp(selName1, selName2)) == 0 || (strcmp(selName1, selName3) == 0)); - STAssertTrue(isGood, nil); - free(list); -} - -- (void)test_method_exchangeImplementations { - // nil checks - method_exchangeImplementations(nil, nil); - - // Standard use check - GTMObjC2Runtime_TestClass *test = [[GTMObjC2Runtime_TestClass alloc] init]; - STAssertNotNil(test, nil); - - // Get initial values - NSString *val1 = [test kwyjibo]; - STAssertNotNil(val1, nil); - NSString *val2 = [test eatMyShorts]; - STAssertNotNil(val2, nil); - NSString *val3 = [GTMObjC2Runtime_TestClass dontHaveACow]; - STAssertNotNil(val3, nil); - NSString *val4 = [GTMObjC2Runtime_TestClass brokeHisBrain]; - STAssertNotNil(val4, nil); - - // exchange the imps - Method *list = class_copyMethodList(cls_, nil); - STAssertNotNULL(list, nil); - method_exchangeImplementations(list[0], list[1]); - - // test against initial values - NSString *val5 = [test kwyjibo]; - STAssertNotNil(val5, nil); - NSString *val6 = [test eatMyShorts]; - STAssertNotNil(val6, nil); - STAssertEqualStrings(val1, val6, nil); - STAssertEqualStrings(val2, val5, nil); - - // Check that other methods not affected - STAssertEqualStrings([GTMObjC2Runtime_TestClass dontHaveACow], val3, nil); - STAssertEqualStrings([GTMObjC2Runtime_TestClass brokeHisBrain], val4, nil); - - // exchange the imps back - method_exchangeImplementations(list[0], list[1]); - - // and test against initial values again - NSString *val7 = [test kwyjibo]; - STAssertNotNil(val7, nil); - NSString *val8 = [test eatMyShorts]; - STAssertNotNil(val8, nil); - STAssertEqualStrings(val1, val7, nil); - STAssertEqualStrings(val2, val8, nil); - - method_exchangeImplementations(list[0], nil); - method_exchangeImplementations(nil, list[0]); - - val7 = [test kwyjibo]; - STAssertNotNil(val7, nil); - val8 = [test eatMyShorts]; - STAssertNotNil(val8, nil); - STAssertEqualStrings(val1, val7, nil); - STAssertEqualStrings(val2, val8, nil); - - free(list); - [test release]; -} - -- (void)test_method_getImplementation { - // Nil Checks - STAssertNULL(method_getImplementation(nil), nil); - - // Standard use check - Method *list = class_copyMethodList(cls_, nil); - STAssertNotNULL(list, nil); - STAssertNotNULL(method_getImplementation(list[0]), nil); - free(list); -} - -- (void)test_method_setImplementation { - // Standard use check - GTMObjC2Runtime_TestClass *test = [[GTMObjC2Runtime_TestClass alloc] init]; - Method *list = class_copyMethodList(cls_, nil); - - // Get initial value - NSString *str1 = objc_msgSend(test, method_getName(list[0])); - STAssertNotNil(str1, nil); - - // set the imp to something else - IMP oldImp = method_setImplementation(list[0], method_getImplementation(list[1])); - STAssertNotNULL(oldImp, nil); - - // make sure they are different - NSString *str2 = objc_msgSend(test,method_getName(list[0])); - STAssertNotNil(str2, nil); - STAssertNotEqualStrings(str1, str2, nil); - - // reset the imp - IMP newImp = method_setImplementation(list[0], oldImp); - STAssertNotEquals(oldImp, newImp, nil); - - // test nils - // Apparently it was a bug that we could call setImplementation with a nil - // so we now test to make sure that setting to nil works as expected on - // all systems. -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - // Built for less then leopard gives us the behaviors we defined... - // (doesn't take nil) - IMP nullImp = method_setImplementation(list[0], nil); - STAssertNULL(nullImp, nil); - IMP testImp = method_setImplementation(list[0], newImp); - STAssertEquals(testImp, oldImp, nil); -#else - // Built for leopard or later means we get the os runtime behavior... - if ([GTMSystemVersion isLeopard]) { - // (takes nil) - oldImp = method_setImplementation(list[0], nil); - STAssertNotNULL(oldImp, nil); - newImp = method_setImplementation(list[0], oldImp); - STAssertNULL(newImp, nil); - } else { - // (doesn't take nil) - IMP nullImp = method_setImplementation(list[0], nil); - STAssertNULL(nullImp, nil); - IMP testImp = method_setImplementation(list[0], newImp); - STAssertEquals(testImp, oldImp, nil); - } -#endif - - // This case intentionally not tested. Passing nil to method_setImplementation - // on Leopard crashes. It does on Tiger as well. Half works on SnowLeopard. - // We made our Tiger implementation the same as the SnowLeopard - // implementation. - // Logged as radar 5572981. - if (![GTMSystemVersion isLeopardOrGreater]) { - STAssertNULL(method_setImplementation(nil, nil), nil); - } -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - if ([GTMSystemVersion isSnowLeopardOrGreater]) { - STAssertNULL(method_setImplementation(nil, newImp), nil); - } -#endif - - [test release]; - free(list); -} - -- (void)test_protocol_getMethodDescription { - // Check nil cases - struct objc_method_description desc = protocol_getMethodDescription(nil, nil, - YES, YES); - STAssertNULL(desc.name, nil); - desc = protocol_getMethodDescription(nil, @selector(optional), YES, YES); - STAssertNULL(desc.name, nil); - desc = protocol_getMethodDescription(@protocol(GTMObjC2Runtime_Test2Protocol), - nil, YES, YES); - STAssertNULL(desc.name, nil); - - // Instance Methods - // Check Required case. Only OBJC2 supports required. - desc = protocol_getMethodDescription(@protocol(GTMObjC2Runtime_Test2Protocol), - @selector(optional), YES, YES); -#if OBJC_API_VERSION >= 2 - STAssertNULL(desc.name, nil); -#else - STAssertNotNULL(desc.name, nil); -#endif - - // Check Required case. Only OBJC2 supports required. - desc = protocol_getMethodDescription(@protocol(GTMObjC2Runtime_Test2Protocol), - @selector(required), YES, YES); - - STAssertNotNULL(desc.name, nil); - - // Check Optional case. Only OBJC2 supports optional. - desc = protocol_getMethodDescription(@protocol(GTMObjC2Runtime_Test2Protocol), - @selector(optional), NO, YES); - - STAssertNotNULL(desc.name, nil); - - // Check Optional case. Only OBJC2 supports optional. - desc = protocol_getMethodDescription(@protocol(GTMObjC2Runtime_Test2Protocol), - @selector(required), NO, YES); -#if OBJC_API_VERSION >= 2 - STAssertNULL(desc.name, nil); -#else - STAssertNotNULL(desc.name, nil); -#endif - - // Class Methods - // Check Required case. Only OBJC2 supports required. - desc = protocol_getMethodDescription(@protocol(GTMObjC2Runtime_Test2Protocol), - @selector(class_optional), YES, NO); -#if OBJC_API_VERSION >= 2 - STAssertNULL(desc.name, nil); -#else - STAssertNotNULL(desc.name, nil); -#endif - - // Check Required case. Only OBJC2 supports required. - desc = protocol_getMethodDescription(@protocol(GTMObjC2Runtime_Test2Protocol), - @selector(class_required), YES, NO); - - STAssertNotNULL(desc.name, nil); - - // Check Optional case. Only OBJC2 supports optional. - desc = protocol_getMethodDescription(@protocol(GTMObjC2Runtime_Test2Protocol), - @selector(class_optional), NO, NO); - - STAssertNotNULL(desc.name, nil); - - // Check Optional case. Only OBJC2 supports optional. - desc = protocol_getMethodDescription(@protocol(GTMObjC2Runtime_Test2Protocol), - @selector(class_required), NO, NO); -#if OBJC_API_VERSION >= 2 - STAssertNULL(desc.name, nil); -#else - STAssertNotNULL(desc.name, nil); -#endif - -} - -- (void)test_sel_isEqual { - STAssertTrue(sel_isEqual(@selector(kwyjibo), @selector(kwyjibo)), nil); - STAssertFalse(sel_isEqual(@selector(kwyjibo), @selector(dontHaveACow)), nil); - STAssertTrue(sel_isEqual(_cmd, @selector(test_sel_isEqual)), nil); - STAssertTrue(sel_isEqual(_cmd, _cmd), nil); - STAssertFalse(sel_isEqual(_cmd, @selector(kwyjibo)), nil); -} - -@end diff --git a/Foundation/GTMPathTest.m b/Foundation/GTMPathTest.m index 54fa83b..dff1f02 100644 --- a/Foundation/GTMPathTest.m +++ b/Foundation/GTMPathTest.m @@ -18,7 +18,6 @@ #import "GTMSenTestCase.h" #import "GTMPath.h" -#import "GTMUnitTestDevLog.h" #import "GTMNSFileHandle+UniqueName.h" #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 diff --git a/Foundation/GTMRegex.m b/Foundation/GTMRegex.m index 238ca48..7ac4665 100644 --- a/Foundation/GTMRegex.m +++ b/Foundation/GTMRegex.m @@ -133,7 +133,7 @@ static NSString *const kReplacementPattern = - (id)initWithPattern:(NSString *)pattern options:(GTMRegexOptions)options withError:(NSError **)outErrorOrNULL { - + self = [super init]; if (!self) return nil; @@ -275,7 +275,7 @@ static NSString *const kReplacementPattern = - (NSString *)firstSubStringMatchedInString:(NSString *)str { NSString *result = nil; - + regmatch_t regMatch; const char *utf8Str = [str UTF8String]; if ([self runRegexOnUTF8:utf8Str @@ -380,7 +380,7 @@ static NSString *const kReplacementPattern = } else { // spin over the split up replacement GTMRegexStringSegment *replacementSegment = nil; - GTM_FOREACH_OBJECT(replacementSegment, replacements) { + for (replacementSegment in replacements) { if (![replacementSegment isMatch]) { // not a match, raw text to put in [result appendString:[replacementSegment string]]; @@ -687,14 +687,14 @@ static NSString *const kReplacementPattern = return nil; // pick off when it wasn't found - if ((regMatches_[patternIndex].rm_so == -1) && + if ((regMatches_[patternIndex].rm_so == -1) && (regMatches_[patternIndex].rm_eo == -1)) return nil; // fetch the string - const char *base = (const char*)[utf8StrBuf_ bytes] + const char *base = (const char*)[utf8StrBuf_ bytes] + regMatches_[patternIndex].rm_so; - regoff_t len = regMatches_[patternIndex].rm_eo + regoff_t len = regMatches_[patternIndex].rm_eo - regMatches_[patternIndex].rm_so; return [[[NSString alloc] initWithBytes:base length:(NSUInteger)len @@ -707,7 +707,7 @@ static NSString *const kReplacementPattern = [self class], self, (isMatch_ ? "YES" : "NO")]; for (NSUInteger x = 0; x <= numRegMatches_; ++x) { int length = (int)(regMatches_[x].rm_eo - regMatches_[x].rm_so); - const char* string + const char* string = (((const char*)[utf8StrBuf_ bytes]) + regMatches_[x].rm_so); if (x == 0) { [result appendFormat:@" \"%.*s\"", length , string]; diff --git a/Foundation/GTMRegexTest.m b/Foundation/GTMRegexTest.m index 6f41d60..65aadd5 100644 --- a/Foundation/GTMRegexTest.m +++ b/Foundation/GTMRegexTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -18,7 +18,6 @@ #import "GTMSenTestCase.h" #import "GTMRegex.h" -#import "GTMUnitTestDevLog.h" // // NOTE: @@ -36,104 +35,97 @@ @implementation GTMRegexTest - (void)testEscapedPatternForString { - STAssertEqualStrings([GTMRegex escapedPatternForString:@"abcdefghijklmnopqrstuvwxyz0123456789"], - @"abcdefghijklmnopqrstuvwxyz0123456789", - nil); - STAssertEqualStrings([GTMRegex escapedPatternForString:@"^.[$()|*+?{\\"], - @"\\^\\.\\[\\$\\(\\)\\|\\*\\+\\?\\{\\\\", - nil); - STAssertEqualStrings([GTMRegex escapedPatternForString:@"a^b.c[d$e(f)g|h*i+j?k{l\\m"], - @"a\\^b\\.c\\[d\\$e\\(f\\)g\\|h\\*i\\+j\\?k\\{l\\\\m", - nil); - - STAssertNil([GTMRegex escapedPatternForString:nil], nil); - STAssertEqualStrings([GTMRegex escapedPatternForString:@""], @"", nil); + XCTAssertEqualStrings([GTMRegex escapedPatternForString:@"abcdefghijklmnopqrstuvwxyz0123456789"], + @"abcdefghijklmnopqrstuvwxyz0123456789"); + XCTAssertEqualStrings([GTMRegex escapedPatternForString:@"^.[$()|*+?{\\"], + @"\\^\\.\\[\\$\\(\\)\\|\\*\\+\\?\\{\\\\"); + XCTAssertEqualStrings([GTMRegex escapedPatternForString:@"a^b.c[d$e(f)g|h*i+j?k{l\\m"], + @"a\\^b\\.c\\[d\\$e\\(f\\)g\\|h\\*i\\+j\\?k\\{l\\\\m"); + + XCTAssertNil([GTMRegex escapedPatternForString:nil]); + XCTAssertEqualStrings([GTMRegex escapedPatternForString:@""], @""); } - (void)testInit { // fail cases - STAssertNil([[[GTMRegex alloc] init] autorelease], nil); - STAssertNil([[[GTMRegex alloc] initWithPattern:nil] autorelease], nil); - STAssertNil([[[GTMRegex alloc] initWithPattern:nil - options:kGTMRegexOptionIgnoreCase] autorelease], nil); - [GTMUnitTestDevLog expectString:@"Invalid pattern \"(.\", error: \"parentheses not balanced\""]; - STAssertNil([[[GTMRegex alloc] initWithPattern:@"(."] autorelease], nil); - [GTMUnitTestDevLog expectString:@"Invalid pattern \"(.\", error: \"parentheses not balanced\""]; - STAssertNil([[[GTMRegex alloc] initWithPattern:@"(." - options:kGTMRegexOptionIgnoreCase] autorelease], nil); + XCTAssertNil([[[GTMRegex alloc] init] autorelease]); + XCTAssertNil([[[GTMRegex alloc] initWithPattern:nil] autorelease]); + XCTAssertNil([[[GTMRegex alloc] initWithPattern:nil + options:kGTMRegexOptionIgnoreCase] autorelease]); + XCTAssertNil([[[GTMRegex alloc] initWithPattern:@"(."] autorelease]); + XCTAssertNil([[[GTMRegex alloc] initWithPattern:@"(." + options:kGTMRegexOptionIgnoreCase] autorelease]); // fail cases w/ error param NSError *error = nil; - STAssertNil([[[GTMRegex alloc] initWithPattern:nil - options:kGTMRegexOptionIgnoreCase - withError:&error] autorelease], nil); - STAssertNil(error, @"no pattern, shouldn't get error object"); - STAssertNil([[[GTMRegex alloc] initWithPattern:@"(." - options:kGTMRegexOptionIgnoreCase - withError:&error] autorelease], nil); - STAssertNotNil(error, nil); - STAssertEqualObjects([error domain], kGTMRegexErrorDomain, nil); - STAssertEquals([error code], (NSInteger)kGTMRegexPatternParseFailedError, nil); + XCTAssertNil([[[GTMRegex alloc] initWithPattern:nil + options:kGTMRegexOptionIgnoreCase + withError:&error] autorelease]); + XCTAssertNil(error, @"no pattern, shouldn't get error object"); + XCTAssertNil([[[GTMRegex alloc] initWithPattern:@"(." + options:kGTMRegexOptionIgnoreCase + withError:&error] autorelease]); + XCTAssertNotNil(error); + XCTAssertEqualObjects([error domain], kGTMRegexErrorDomain); + XCTAssertEqual([error code], (NSInteger)kGTMRegexPatternParseFailedError); NSDictionary *userInfo = [error userInfo]; - STAssertNotNil(userInfo, @"failed to get userInfo from error"); - STAssertEqualObjects([userInfo objectForKey:kGTMRegexPatternErrorPattern], @"(.", nil); - STAssertNotNil([userInfo objectForKey:kGTMRegexPatternErrorErrorString], nil); + XCTAssertNotNil(userInfo, @"failed to get userInfo from error"); + XCTAssertEqualObjects([userInfo objectForKey:kGTMRegexPatternErrorPattern], @"(."); + XCTAssertNotNil([userInfo objectForKey:kGTMRegexPatternErrorErrorString]); // basic pattern w/ options - STAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)"] autorelease], nil); - STAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" - options:0] autorelease], nil); - STAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" - options:kGTMRegexOptionIgnoreCase] autorelease], nil); + XCTAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)"] autorelease]); + XCTAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" + options:0] autorelease]); + XCTAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" + options:kGTMRegexOptionIgnoreCase] autorelease]); error = nil; - STAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" - options:kGTMRegexOptionIgnoreCase - withError:&error] autorelease], nil); - STAssertNil(error, @"shouldn't have been any error"); + XCTAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" + options:kGTMRegexOptionIgnoreCase + withError:&error] autorelease]); + XCTAssertNil(error, @"shouldn't have been any error"); // fail cases (helper) - STAssertNil([GTMRegex regexWithPattern:nil], nil); - STAssertNil([GTMRegex regexWithPattern:nil - options:0], nil); - [GTMUnitTestDevLog expectString:@"Invalid pattern \"(.\", error: \"parentheses not balanced\""]; - STAssertNil([GTMRegex regexWithPattern:@"(."], nil); - [GTMUnitTestDevLog expectString:@"Invalid pattern \"(.\", error: \"parentheses not balanced\""]; - STAssertNil([GTMRegex regexWithPattern:@"(." - options:0], nil); + XCTAssertNil([GTMRegex regexWithPattern:nil]); + XCTAssertNil([GTMRegex regexWithPattern:nil + options:0]); + XCTAssertNil([GTMRegex regexWithPattern:@"(."]); + XCTAssertNil([GTMRegex regexWithPattern:@"(." + options:0]); // fail cases (helper) w/ error param - STAssertNil([GTMRegex regexWithPattern:nil - options:kGTMRegexOptionIgnoreCase - withError:&error], nil); - STAssertNil(error, @"no pattern, shouldn't get error object"); - STAssertNil([GTMRegex regexWithPattern:@"(." - options:kGTMRegexOptionIgnoreCase - withError:&error], nil); - STAssertNotNil(error, nil); - STAssertEqualObjects([error domain], kGTMRegexErrorDomain, nil); - STAssertEquals([error code], (NSInteger)kGTMRegexPatternParseFailedError, nil); + XCTAssertNil([GTMRegex regexWithPattern:nil + options:kGTMRegexOptionIgnoreCase + withError:&error]); + XCTAssertNil(error, @"no pattern, shouldn't get error object"); + XCTAssertNil([GTMRegex regexWithPattern:@"(." + options:kGTMRegexOptionIgnoreCase + withError:&error]); + XCTAssertNotNil(error); + XCTAssertEqualObjects([error domain], kGTMRegexErrorDomain); + XCTAssertEqual([error code], (NSInteger)kGTMRegexPatternParseFailedError); userInfo = [error userInfo]; - STAssertNotNil(userInfo, @"failed to get userInfo from error"); - STAssertEqualObjects([userInfo objectForKey:kGTMRegexPatternErrorPattern], @"(.", nil); - STAssertNotNil([userInfo objectForKey:kGTMRegexPatternErrorErrorString], nil); - + XCTAssertNotNil(userInfo, @"failed to get userInfo from error"); + XCTAssertEqualObjects([userInfo objectForKey:kGTMRegexPatternErrorPattern], @"(."); + XCTAssertNotNil([userInfo objectForKey:kGTMRegexPatternErrorErrorString]); + // basic pattern w/ options (helper) - STAssertNotNil([GTMRegex regexWithPattern:@"(.*)"], nil); - STAssertNotNil([GTMRegex regexWithPattern:@"(.*)" - options:0], nil); - STAssertNotNil([GTMRegex regexWithPattern:@"(.*)" - options:kGTMRegexOptionIgnoreCase], nil); + XCTAssertNotNil([GTMRegex regexWithPattern:@"(.*)"]); + XCTAssertNotNil([GTMRegex regexWithPattern:@"(.*)" + options:0]); + XCTAssertNotNil([GTMRegex regexWithPattern:@"(.*)" + options:kGTMRegexOptionIgnoreCase]); error = nil; - STAssertNotNil([GTMRegex regexWithPattern:@"(.*)" - options:kGTMRegexOptionIgnoreCase - withError:&error], nil); - STAssertNil(error, @"shouldn't have been any error"); - + XCTAssertNotNil([GTMRegex regexWithPattern:@"(.*)" + options:kGTMRegexOptionIgnoreCase + withError:&error]); + XCTAssertNil(error, @"shouldn't have been any error"); + // not really a test on GTMRegex, but make sure we block attempts to directly // alloc/init a GTMRegexStringSegment. - STAssertThrowsSpecificNamed([[[GTMRegexStringSegment alloc] init] autorelease], - NSException, NSInvalidArgumentException, - @"shouldn't have been able to alloc/init a GTMRegexStringSegment"); + XCTAssertThrowsSpecificNamed([[[GTMRegexStringSegment alloc] init] autorelease], + NSException, NSInvalidArgumentException, + @"shouldn't have been able to alloc/init a GTMRegexStringSegment"); } - (void)testOptions { @@ -142,767 +134,759 @@ // default options GTMRegex *regex = [GTMRegex regexWithPattern:@"a+"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); NSEnumerator *enumerator = [regex segmentEnumeratorForString:testString]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aaa" GTMRegexStringSegment *seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa"); // " AAA\nbbb BBB\n " seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @" AAA\nbbb BBB\n ", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @" AAA\nbbb BBB\n "); // "aaa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa"); // " " seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @" ", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @" "); // "a" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"a", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"a"); // "A" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"A", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"A"); // "a" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"a", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"a"); // "\n bbb BbB" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"\n bbb BbB", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"\n bbb BbB"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // kGTMRegexOptionIgnoreCase regex = [GTMRegex regexWithPattern:@"a+" options:kGTMRegexOptionIgnoreCase]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:testString]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aaa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa"); // " " seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @" ", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @" "); // "AAA" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"AAA", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"AAA"); // "\nbbb BBB\n " seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"\nbbb BBB\n ", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"\nbbb BBB\n "); // "aaa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa"); // " " seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @" ", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @" "); // "aAa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aAa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aAa"); // "\n bbb BbB" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"\n bbb BbB", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"\n bbb BbB"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // defaults w/ '^' regex = [GTMRegex regexWithPattern:@"^a+"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:testString]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aaa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa"); // " AAA\nbbb BBB\n aaa aAa\n bbb BbB" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @" AAA\nbbb BBB\n aaa aAa\n bbb BbB", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @" AAA\nbbb BBB\n aaa aAa\n bbb BbB"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // defaults w/ '$' regex = [GTMRegex regexWithPattern:@"B+$"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:testString]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aaa AAA\nbbb " seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa AAA\nbbb ", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa AAA\nbbb "); // "BBB" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"BBB", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"BBB"); // "\n aaa aAa\n bbb Bb" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"\n aaa aAa\n bbb Bb", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"\n aaa aAa\n bbb Bb"); // "B" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"B", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"B"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // kGTMRegexOptionIgnoreCase w/ '$' regex = [GTMRegex regexWithPattern:@"B+$" - options:kGTMRegexOptionIgnoreCase]; - STAssertNotNil(regex, nil); + options:kGTMRegexOptionIgnoreCase]; + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:testString]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aaa AAA\nbbb " seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa AAA\nbbb ", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa AAA\nbbb "); // "BBB" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"BBB", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"BBB"); // "\n aaa aAa\n bbb " seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"\n aaa aAa\n bbb ", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"\n aaa aAa\n bbb "); // "BbB" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"BbB", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"BbB"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test w/ kGTMRegexOptionSupressNewlineSupport and \n in the string regex = [GTMRegex regexWithPattern:@"a.*b" options:kGTMRegexOptionSupressNewlineSupport]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:testString]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb"); // "B" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"B", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"B"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test w/o kGTMRegexOptionSupressNewlineSupport and \n in the string // (this is no match since it '.' can't match the '\n') regex = [GTMRegex regexWithPattern:@"a.*b"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:testString]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aaa AAA\nbbb BBB\n aaa aAa\n bbb BbB" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb BbB", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb BbB"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); - + XCTAssertNil(seg); + // kGTMRegexOptionSupressNewlineSupport w/ '^' regex = [GTMRegex regexWithPattern:@"^a+" options:kGTMRegexOptionSupressNewlineSupport]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:testString]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aaa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa"); // " AAA\nbbb BBB\n aaa aAa\n bbb BbB" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @" AAA\nbbb BBB\n aaa aAa\n bbb BbB", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @" AAA\nbbb BBB\n aaa aAa\n bbb BbB"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // kGTMRegexOptionSupressNewlineSupport w/ '$' regex = [GTMRegex regexWithPattern:@"B+$" options:kGTMRegexOptionSupressNewlineSupport]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:testString]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb"); // "B" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"B", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"B"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); } - (void)testSubPatternCount { - STAssertEquals((NSUInteger)0, [[GTMRegex regexWithPattern:@".*"] subPatternCount], nil); - STAssertEquals((NSUInteger)1, [[GTMRegex regexWithPattern:@"(.*)"] subPatternCount], nil); - STAssertEquals((NSUInteger)1, [[GTMRegex regexWithPattern:@"[fo]*(.*)[bar]*"] subPatternCount], nil); - STAssertEquals((NSUInteger)3, [[GTMRegex regexWithPattern:@"([fo]*)(.*)([bar]*)"] subPatternCount], nil); - STAssertEquals((NSUInteger)7, [[GTMRegex regexWithPattern:@"(([bar]*)|([fo]*))(.*)(([bar]*)|([fo]*))"] subPatternCount], nil); + XCTAssertEqual((NSUInteger)0, [[GTMRegex regexWithPattern:@".*"] subPatternCount]); + XCTAssertEqual((NSUInteger)1, [[GTMRegex regexWithPattern:@"(.*)"] subPatternCount]); + XCTAssertEqual((NSUInteger)1, [[GTMRegex regexWithPattern:@"[fo]*(.*)[bar]*"] subPatternCount]); + XCTAssertEqual((NSUInteger)3, + [[GTMRegex regexWithPattern:@"([fo]*)(.*)([bar]*)"] subPatternCount]); + XCTAssertEqual((NSUInteger)7, + [[GTMRegex regexWithPattern:@"(([bar]*)|([fo]*))(.*)(([bar]*)|([fo]*))"] subPatternCount]); } - (void)testMatchesString { // simple pattern GTMRegex *regex = [GTMRegex regexWithPattern:@"foo.*bar"]; - STAssertNotNil(regex, nil); - STAssertTrue([regex matchesString:@"foobar"], nil); - STAssertTrue([regex matchesString:@"foobydoo spambar"], nil); - STAssertFalse([regex matchesString:@"zzfoobarzz"], nil); - STAssertFalse([regex matchesString:@"zzfoobydoo spambarzz"], nil); - STAssertFalse([regex matchesString:@"abcdef"], nil); - STAssertFalse([regex matchesString:@""], nil); - STAssertFalse([regex matchesString:nil], nil); + XCTAssertNotNil(regex); + XCTAssertTrue([regex matchesString:@"foobar"]); + XCTAssertTrue([regex matchesString:@"foobydoo spambar"]); + XCTAssertFalse([regex matchesString:@"zzfoobarzz"]); + XCTAssertFalse([regex matchesString:@"zzfoobydoo spambarzz"]); + XCTAssertFalse([regex matchesString:@"abcdef"]); + XCTAssertFalse([regex matchesString:@""]); + XCTAssertFalse([regex matchesString:nil]); // pattern w/ sub patterns regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"]; - STAssertNotNil(regex, nil); - STAssertTrue([regex matchesString:@"foobar"], nil); - STAssertTrue([regex matchesString:@"foobydoo spambar"], nil); - STAssertFalse([regex matchesString:@"zzfoobarzz"], nil); - STAssertFalse([regex matchesString:@"zzfoobydoo spambarzz"], nil); - STAssertFalse([regex matchesString:@"abcdef"], nil); - STAssertFalse([regex matchesString:@""], nil); - STAssertFalse([regex matchesString:nil], nil); + XCTAssertNotNil(regex); + XCTAssertTrue([regex matchesString:@"foobar"]); + XCTAssertTrue([regex matchesString:@"foobydoo spambar"]); + XCTAssertFalse([regex matchesString:@"zzfoobarzz"]); + XCTAssertFalse([regex matchesString:@"zzfoobydoo spambarzz"]); + XCTAssertFalse([regex matchesString:@"abcdef"]); + XCTAssertFalse([regex matchesString:@""]); + XCTAssertFalse([regex matchesString:nil]); } - (void)testSubPatternsOfString { GTMRegex *regex = [GTMRegex regexWithPattern:@"(fo(o+))((bar)|(baz))"]; - STAssertNotNil(regex, nil); - STAssertEquals((NSUInteger)5, [regex subPatternCount], nil); + XCTAssertNotNil(regex); + XCTAssertEqual((NSUInteger)5, [regex subPatternCount]); NSArray *subPatterns = [regex subPatternsOfString:@"foooooobaz"]; - STAssertNotNil(subPatterns, nil); - STAssertEquals((NSUInteger)6, [subPatterns count], nil); - STAssertEqualStrings(@"foooooobaz", [subPatterns objectAtIndex:0], nil); - STAssertEqualStrings(@"foooooo", [subPatterns objectAtIndex:1], nil); - STAssertEqualStrings(@"ooooo", [subPatterns objectAtIndex:2], nil); - STAssertEqualStrings(@"baz", [subPatterns objectAtIndex:3], nil); - STAssertEqualObjects([NSNull null], [subPatterns objectAtIndex:4], nil); - STAssertEqualStrings(@"baz", [subPatterns objectAtIndex:5], nil); + XCTAssertNotNil(subPatterns); + XCTAssertEqual((NSUInteger)6, [subPatterns count]); + XCTAssertEqualStrings(@"foooooobaz", [subPatterns objectAtIndex:0]); + XCTAssertEqualStrings(@"foooooo", [subPatterns objectAtIndex:1]); + XCTAssertEqualStrings(@"ooooo", [subPatterns objectAtIndex:2]); + XCTAssertEqualStrings(@"baz", [subPatterns objectAtIndex:3]); + XCTAssertEqualObjects([NSNull null], [subPatterns objectAtIndex:4]); + XCTAssertEqualStrings(@"baz", [subPatterns objectAtIndex:5]); // not there subPatterns = [regex subPatternsOfString:@"aaa"]; - STAssertNil(subPatterns, nil); + XCTAssertNil(subPatterns); // not extra stuff on either end subPatterns = [regex subPatternsOfString:@"ZZZfoooooobaz"]; - STAssertNil(subPatterns, nil); + XCTAssertNil(subPatterns); subPatterns = [regex subPatternsOfString:@"foooooobazZZZ"]; - STAssertNil(subPatterns, nil); + XCTAssertNil(subPatterns); subPatterns = [regex subPatternsOfString:@"ZZZfoooooobazZZZ"]; - STAssertNil(subPatterns, nil); + XCTAssertNil(subPatterns); } - (void)testFirstSubStringMatchedInString { // simple pattern GTMRegex *regex = [GTMRegex regexWithPattern:@"foo.*bar"]; - STAssertNotNil(regex, nil); - STAssertEqualStrings([regex firstSubStringMatchedInString:@"foobar"], - @"foobar", nil); - STAssertEqualStrings([regex firstSubStringMatchedInString:@"foobydoo spambar"], - @"foobydoo spambar", nil); - STAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobarzz"], - @"foobar", nil); - STAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobydoo spambarzz"], - @"foobydoo spambar", nil); - STAssertNil([regex firstSubStringMatchedInString:@"abcdef"], nil); - STAssertNil([regex firstSubStringMatchedInString:@""], nil); + XCTAssertNotNil(regex); + XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"foobar"], + @"foobar"); + XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"foobydoo spambar"], + @"foobydoo spambar"); + XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobarzz"], + @"foobar"); + XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobydoo spambarzz"], + @"foobydoo spambar"); + XCTAssertNil([regex firstSubStringMatchedInString:@"abcdef"]); + XCTAssertNil([regex firstSubStringMatchedInString:@""]); // pattern w/ sub patterns regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"]; - STAssertNotNil(regex, nil); - STAssertEqualStrings([regex firstSubStringMatchedInString:@"foobar"], - @"foobar", nil); - STAssertEqualStrings([regex firstSubStringMatchedInString:@"foobydoo spambar"], - @"foobydoo spambar", nil); - STAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobarzz"], - @"foobar", nil); - STAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobydoo spambarzz"], - @"foobydoo spambar", nil); - STAssertNil([regex firstSubStringMatchedInString:@"abcdef"], nil); - STAssertNil([regex firstSubStringMatchedInString:@""], nil); + XCTAssertNotNil(regex); + XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"foobar"], + @"foobar"); + XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"foobydoo spambar"], + @"foobydoo spambar"); + XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobarzz"], + @"foobar"); + XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobydoo spambarzz"], + @"foobydoo spambar"); + XCTAssertNil([regex firstSubStringMatchedInString:@"abcdef"]); + XCTAssertNil([regex firstSubStringMatchedInString:@""]); } - (void)testMatchesSubStringInString { // simple pattern GTMRegex *regex = [GTMRegex regexWithPattern:@"foo.*bar"]; - STAssertNotNil(regex, nil); - STAssertTrue([regex matchesSubStringInString:@"foobar"], nil); - STAssertTrue([regex matchesSubStringInString:@"foobydoo spambar"], nil); - STAssertTrue([regex matchesSubStringInString:@"zzfoobarzz"], nil); - STAssertTrue([regex matchesSubStringInString:@"zzfoobydoo spambarzz"], nil); - STAssertFalse([regex matchesSubStringInString:@"abcdef"], nil); - STAssertFalse([regex matchesSubStringInString:@""], nil); + XCTAssertNotNil(regex); + XCTAssertTrue([regex matchesSubStringInString:@"foobar"]); + XCTAssertTrue([regex matchesSubStringInString:@"foobydoo spambar"]); + XCTAssertTrue([regex matchesSubStringInString:@"zzfoobarzz"]); + XCTAssertTrue([regex matchesSubStringInString:@"zzfoobydoo spambarzz"]); + XCTAssertFalse([regex matchesSubStringInString:@"abcdef"]); + XCTAssertFalse([regex matchesSubStringInString:@""]); // pattern w/ sub patterns regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"]; - STAssertNotNil(regex, nil); - STAssertTrue([regex matchesSubStringInString:@"foobar"], nil); - STAssertTrue([regex matchesSubStringInString:@"foobydoo spambar"], nil); - STAssertTrue([regex matchesSubStringInString:@"zzfoobarzz"], nil); - STAssertTrue([regex matchesSubStringInString:@"zzfoobydoo spambarzz"], nil); - STAssertFalse([regex matchesSubStringInString:@"abcdef"], nil); - STAssertFalse([regex matchesSubStringInString:@""], nil); + XCTAssertNotNil(regex); + XCTAssertTrue([regex matchesSubStringInString:@"foobar"]); + XCTAssertTrue([regex matchesSubStringInString:@"foobydoo spambar"]); + XCTAssertTrue([regex matchesSubStringInString:@"zzfoobarzz"]); + XCTAssertTrue([regex matchesSubStringInString:@"zzfoobydoo spambarzz"]); + XCTAssertFalse([regex matchesSubStringInString:@"abcdef"]); + XCTAssertFalse([regex matchesSubStringInString:@""]); } - (void)testSegmentEnumeratorForString { GTMRegex *regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; - STAssertNotNil(regex, nil); - + XCTAssertNotNil(regex); + // test odd input NSEnumerator *enumerator = [regex segmentEnumeratorForString:@""]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); enumerator = [regex segmentEnumeratorForString:nil]; - STAssertNil(enumerator, nil); - + XCTAssertNil(enumerator); + // on w/ the normal tests enumerator = [regex segmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "a" GTMRegexStringSegment *seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"a", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"a"); // "foobar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); // "b" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"b", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"b"); // "fooobaar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"fooobaar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"fooobaar"); // "foobar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); // "zz" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"zz", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"zz"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test no match enumerator = [regex segmentEnumeratorForString:@"aaa"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa"); seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test only match enumerator = [regex segmentEnumeratorForString:@"foobar"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // now test the saved sub segments regex = [GTMRegex regexWithPattern:@"(foo)((bar)|(baz))"]; - STAssertNotNil(regex, nil); - STAssertEquals((NSUInteger)4, [regex subPatternCount], nil); + XCTAssertNotNil(regex); + XCTAssertEqual((NSUInteger)4, [regex subPatternCount]); enumerator = [regex segmentEnumeratorForString:@"foobarxxfoobaz"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "foobar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); - STAssertEqualStrings([seg subPatternString:0], @"foobar", nil); - STAssertEqualStrings([seg subPatternString:1], @"foo", nil); - STAssertEqualStrings([seg subPatternString:2], @"bar", nil); - STAssertEqualStrings([seg subPatternString:3], @"bar", nil); - STAssertNil([seg subPatternString:4], nil); // nothing matched "(baz)" - STAssertNil([seg subPatternString:5], nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); + XCTAssertEqualStrings([seg subPatternString:0], @"foobar"); + XCTAssertEqualStrings([seg subPatternString:1], @"foo"); + XCTAssertEqualStrings([seg subPatternString:2], @"bar"); + XCTAssertEqualStrings([seg subPatternString:3], @"bar"); + XCTAssertNil([seg subPatternString:4]); // nothing matched "(baz)" + XCTAssertNil([seg subPatternString:5]); // "xx" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"xx", nil); - STAssertEqualStrings([seg subPatternString:0], @"xx", nil); - STAssertNil([seg subPatternString:1], nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"xx"); + XCTAssertEqualStrings([seg subPatternString:0], @"xx"); + XCTAssertNil([seg subPatternString:1]); // "foobaz" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobaz", nil); - STAssertEqualStrings([seg subPatternString:0], @"foobaz", nil); - STAssertEqualStrings([seg subPatternString:1], @"foo", nil); - STAssertEqualStrings([seg subPatternString:2], @"baz", nil); - STAssertNil([seg subPatternString:3], nil); // (nothing matched "(bar)" - STAssertEqualStrings([seg subPatternString:4], @"baz", nil); - STAssertNil([seg subPatternString:5], nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobaz"); + XCTAssertEqualStrings([seg subPatternString:0], @"foobaz"); + XCTAssertEqualStrings([seg subPatternString:1], @"foo"); + XCTAssertEqualStrings([seg subPatternString:2], @"baz"); + XCTAssertNil([seg subPatternString:3]); // (nothing matched "(bar)" + XCTAssertEqualStrings([seg subPatternString:4], @"baz"); + XCTAssertNil([seg subPatternString:5]); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test all objects regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); NSArray *allSegments = [enumerator allObjects]; - STAssertNotNil(allSegments, nil); - STAssertEquals((NSUInteger)6, [allSegments count], nil); + XCTAssertNotNil(allSegments); + XCTAssertEqual((NSUInteger)6, [allSegments count]); // test we are getting the flags right for newline regex = [GTMRegex regexWithPattern:@"^a"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:@"aa\naa"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "a" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"a", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"a"); // "a\n" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"a\n", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"a\n"); // "a" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"a", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"a"); // "a" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"a", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"a"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test we are getting the flags right for newline, part 2 regex = [GTMRegex regexWithPattern:@"^a*$"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:@"aa\naa\nbb\naa"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aa"); // "\n" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"\n", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"\n"); // "aa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aa"); // "\nbb\n" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"\nbb\n", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"\nbb\n"); // "aa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aa"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // make sure the enum cleans up if not walked to the end regex = [GTMRegex regexWithPattern:@"b+"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex segmentEnumeratorForString:@"aabbcc"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aa", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aa"); // and done w/o walking the rest } - (void)testMatchSegmentEnumeratorForString { GTMRegex *regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); // test odd input NSEnumerator *enumerator = [regex matchSegmentEnumeratorForString:@""]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); enumerator = [regex matchSegmentEnumeratorForString:nil]; - STAssertNil(enumerator, nil); - + XCTAssertNil(enumerator); + // on w/ the normal tests enumerator = [regex matchSegmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "a" - skipped // "foobar" GTMRegexStringSegment *seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); // "b" - skipped // "fooobaar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"fooobaar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"fooobaar"); // "foobar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); // "zz" - skipped // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test no match enumerator = [regex matchSegmentEnumeratorForString:@"aaa"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); seg = [enumerator nextObject]; - STAssertNil(seg, nil); // should have gotten nothing + XCTAssertNil(seg); // should have gotten nothing // test only match enumerator = [regex matchSegmentEnumeratorForString:@"foobar"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // now test the saved sub segments regex = [GTMRegex regexWithPattern:@"(foo)((bar)|(baz))"]; - STAssertNotNil(regex, nil); - STAssertEquals((NSUInteger)4, [regex subPatternCount], nil); + XCTAssertNotNil(regex); + XCTAssertEqual((NSUInteger)4, [regex subPatternCount]); enumerator = [regex matchSegmentEnumeratorForString:@"foobarxxfoobaz"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "foobar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); - STAssertEqualStrings([seg subPatternString:0], @"foobar", nil); - STAssertEqualStrings([seg subPatternString:1], @"foo", nil); - STAssertEqualStrings([seg subPatternString:2], @"bar", nil); - STAssertEqualStrings([seg subPatternString:3], @"bar", nil); - STAssertNil([seg subPatternString:4], nil); // nothing matched "(baz)" - STAssertNil([seg subPatternString:5], nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); + XCTAssertEqualStrings([seg subPatternString:0], @"foobar"); + XCTAssertEqualStrings([seg subPatternString:1], @"foo"); + XCTAssertEqualStrings([seg subPatternString:2], @"bar"); + XCTAssertEqualStrings([seg subPatternString:3], @"bar"); + XCTAssertNil([seg subPatternString:4]); // nothing matched "(baz)" + XCTAssertNil([seg subPatternString:5]); // "xx" - skipped // "foobaz" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobaz", nil); - STAssertEqualStrings([seg subPatternString:0], @"foobaz", nil); - STAssertEqualStrings([seg subPatternString:1], @"foo", nil); - STAssertEqualStrings([seg subPatternString:2], @"baz", nil); - STAssertNil([seg subPatternString:3], nil); // (nothing matched "(bar)" - STAssertEqualStrings([seg subPatternString:4], @"baz", nil); - STAssertNil([seg subPatternString:5], nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobaz"); + XCTAssertEqualStrings([seg subPatternString:0], @"foobaz"); + XCTAssertEqualStrings([seg subPatternString:1], @"foo"); + XCTAssertEqualStrings([seg subPatternString:2], @"baz"); + XCTAssertNil([seg subPatternString:3]); // (nothing matched "(bar)" + XCTAssertEqualStrings([seg subPatternString:4], @"baz"); + XCTAssertNil([seg subPatternString:5]); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test all objects regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex matchSegmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); NSArray *allSegments = [enumerator allObjects]; - STAssertNotNil(allSegments, nil); - STAssertEquals((NSUInteger)3, [allSegments count], nil); - + XCTAssertNotNil(allSegments); + XCTAssertEqual((NSUInteger)3, [allSegments count]); + // test we are getting the flags right for newline regex = [GTMRegex regexWithPattern:@"^a"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex matchSegmentEnumeratorForString:@"aa\naa"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "a" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"a", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"a"); // "a\n" - skipped // "a" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"a", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"a"); // "a" - skipped // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test we are getting the flags right for newline, part 2 regex = [GTMRegex regexWithPattern:@"^a*$"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); enumerator = [regex matchSegmentEnumeratorForString:@"aa\naa\nbb\naa"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "aa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aa"); // "\n" - skipped // "aa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aa"); // "\nbb\n" - skipped // "aa" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aa", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aa"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); } - (void)testStringByReplacingMatchesInStringWithReplacement { GTMRegex *regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"]; - STAssertNotNil(regex, nil); + XCTAssertNotNil(regex); // the basics - STAssertEqualStrings(@"weeZbarZbydoo spamZfooZdoggies", - [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" - withReplacement:@"Z\\3Z\\2Z\\1Z"], - nil); + XCTAssertEqualStrings(@"weeZbarZbydoo spamZfooZdoggies", + [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" + withReplacement:@"Z\\3Z\\2Z\\1Z"]); // nil/empty replacement - STAssertEqualStrings(@"weedoggies", - [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" - withReplacement:nil], - nil); - STAssertEqualStrings(@"weedoggies", - [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" - withReplacement:@""], - nil); - STAssertEqualStrings(@"", - [regex stringByReplacingMatchesInString:@"" - withReplacement:@"abc"], - nil); - STAssertNil([regex stringByReplacingMatchesInString:nil - withReplacement:@"abc"], - nil); + XCTAssertEqualStrings(@"weedoggies", + [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" + withReplacement:nil]); + XCTAssertEqualStrings(@"weedoggies", + [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" + withReplacement:@""]); + XCTAssertEqualStrings(@"", + [regex stringByReplacingMatchesInString:@"" + withReplacement:@"abc"]); + XCTAssertNil([regex stringByReplacingMatchesInString:nil + withReplacement:@"abc"]); // use optional and invale subexpression parts to confirm that works regex = [GTMRegex regexWithPattern:@"(fo(o+))((bar)|(baz))"]; - STAssertNotNil(regex, nil); - STAssertEqualStrings(@"aaa baz bar bar foo baz aaa", - [regex stringByReplacingMatchesInString:@"aaa foooooobaz fooobar bar foo baz aaa" - withReplacement:@"\\4\\5"], - nil); - STAssertEqualStrings(@"aaa ZZZ ZZZ bar foo baz aaa", - [regex stringByReplacingMatchesInString:@"aaa foooooobaz fooobar bar foo baz aaa" - withReplacement:@"Z\\10Z\\12Z"], - nil); + XCTAssertNotNil(regex); + XCTAssertEqualStrings(@"aaa baz bar bar foo baz aaa", + [regex stringByReplacingMatchesInString:@"aaa foooooobaz fooobar bar foo baz aaa" + withReplacement:@"\\4\\5"]); + XCTAssertEqualStrings(@"aaa ZZZ ZZZ bar foo baz aaa", + [regex stringByReplacingMatchesInString:@"aaa foooooobaz fooobar bar foo baz aaa" + withReplacement:@"Z\\10Z\\12Z"]); // test slashes in replacement that aren't part of the subpattern reference regex = [GTMRegex regexWithPattern:@"a+"]; - STAssertNotNil(regex, nil); - STAssertEqualStrings(@"z\\\\0 \\\\a \\\\\\\\0z", - [regex stringByReplacingMatchesInString:@"zaz" - withReplacement:@"\\\\0 \\\\\\0 \\\\\\\\0"], - nil); - STAssertEqualStrings(@"z\\\\a \\\\\\\\0 \\\\\\\\az", - [regex stringByReplacingMatchesInString:@"zaz" - withReplacement:@"\\\\\\0 \\\\\\\\0 \\\\\\\\\\0"], - nil); - STAssertEqualStrings(@"z\\\\\\\\0 \\\\\\\\a \\\\\\\\\\\\0z", - [regex stringByReplacingMatchesInString:@"zaz" - withReplacement:@"\\\\\\\\0 \\\\\\\\\\0 \\\\\\\\\\\\0"], - nil); + XCTAssertNotNil(regex); + XCTAssertEqualStrings(@"z\\\\0 \\\\a \\\\\\\\0z", + [regex stringByReplacingMatchesInString:@"zaz" + withReplacement:@"\\\\0 \\\\\\0 \\\\\\\\0"]); + XCTAssertEqualStrings(@"z\\\\a \\\\\\\\0 \\\\\\\\az", + [regex stringByReplacingMatchesInString:@"zaz" + withReplacement:@"\\\\\\0 \\\\\\\\0 \\\\\\\\\\0"]); + XCTAssertEqualStrings(@"z\\\\\\\\0 \\\\\\\\a \\\\\\\\\\\\0z", + [regex stringByReplacingMatchesInString:@"zaz" + withReplacement:@"\\\\\\\\0 \\\\\\\\\\0 \\\\\\\\\\\\0"]); } - (void)testDescriptions { // default options GTMRegex *regex = [GTMRegex regexWithPattern:@"a+"]; - STAssertNotNil(regex, nil); - STAssertGreaterThan([[regex description] length], (NSUInteger)10, - @"failed to get a reasonable description for regex"); + XCTAssertNotNil(regex); + XCTAssertGreaterThan([[regex description] length], (NSUInteger)10, + @"failed to get a reasonable description for regex"); // enumerator NSEnumerator *enumerator = [regex segmentEnumeratorForString:@"aaabbbccc"]; - STAssertNotNil(enumerator, nil); - STAssertGreaterThan([[enumerator description] length], (NSUInteger)10, - @"failed to get a reasonable description for regex enumerator"); + XCTAssertNotNil(enumerator); + XCTAssertGreaterThan([[enumerator description] length], (NSUInteger)10, + @"failed to get a reasonable description for regex enumerator"); // string segment GTMRegexStringSegment *seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertGreaterThan([[seg description] length], (NSUInteger)10, - @"failed to get a reasonable description for regex string segment"); + XCTAssertNotNil(seg); + XCTAssertGreaterThan([[seg description] length], (NSUInteger)10, + @"failed to get a reasonable description for regex string segment"); // regex w/ other options regex = [GTMRegex regexWithPattern:@"a+" options:(kGTMRegexOptionIgnoreCase | kGTMRegexOptionSupressNewlineSupport)]; - STAssertNotNil(regex, nil); - STAssertGreaterThan([[regex description] length], (NSUInteger)10, - @"failed to get a reasonable description for regex w/ options"); + XCTAssertNotNil(regex); + XCTAssertGreaterThan([[regex description] length], (NSUInteger)10, + @"failed to get a reasonable description for regex w/ options"); } @end @@ -913,333 +897,324 @@ - (void)testMatchesPattern { // simple pattern - STAssertTrue([@"foobar" gtm_matchesPattern:@"foo.*bar"], nil); - STAssertTrue([@"foobydoo spambar" gtm_matchesPattern:@"foo.*bar"], nil); - STAssertFalse([@"zzfoobarzz" gtm_matchesPattern:@"foo.*bar"], nil); - STAssertFalse([@"zzfoobydoo spambarzz" gtm_matchesPattern:@"foo.*bar"], nil); - STAssertFalse([@"abcdef" gtm_matchesPattern:@"foo.*bar"], nil); - STAssertFalse([@"" gtm_matchesPattern:@"foo.*bar"], nil); + XCTAssertTrue([@"foobar" gtm_matchesPattern:@"foo.*bar"]); + XCTAssertTrue([@"foobydoo spambar" gtm_matchesPattern:@"foo.*bar"]); + XCTAssertFalse([@"zzfoobarzz" gtm_matchesPattern:@"foo.*bar"]); + XCTAssertFalse([@"zzfoobydoo spambarzz" gtm_matchesPattern:@"foo.*bar"]); + XCTAssertFalse([@"abcdef" gtm_matchesPattern:@"foo.*bar"]); + XCTAssertFalse([@"" gtm_matchesPattern:@"foo.*bar"]); // pattern w/ sub patterns - STAssertTrue([@"foobar" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); - STAssertTrue([@"foobydoo spambar" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); - STAssertFalse([@"zzfoobarzz" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); - STAssertFalse([@"zzfoobydoo spambarzz" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); - STAssertFalse([@"abcdef" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); - STAssertFalse([@"" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); + XCTAssertTrue([@"foobar" gtm_matchesPattern:@"(foo)(.*)(bar)"]); + XCTAssertTrue([@"foobydoo spambar" gtm_matchesPattern:@"(foo)(.*)(bar)"]); + XCTAssertFalse([@"zzfoobarzz" gtm_matchesPattern:@"(foo)(.*)(bar)"]); + XCTAssertFalse([@"zzfoobydoo spambarzz" gtm_matchesPattern:@"(foo)(.*)(bar)"]); + XCTAssertFalse([@"abcdef" gtm_matchesPattern:@"(foo)(.*)(bar)"]); + XCTAssertFalse([@"" gtm_matchesPattern:@"(foo)(.*)(bar)"]); } - (void)testSubPatternsOfPattern { NSArray *subPatterns = [@"foooooobaz" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; - STAssertNotNil(subPatterns, nil); - STAssertEquals((NSUInteger)6, [subPatterns count], nil); - STAssertEqualStrings(@"foooooobaz", [subPatterns objectAtIndex:0], nil); - STAssertEqualStrings(@"foooooo", [subPatterns objectAtIndex:1], nil); - STAssertEqualStrings(@"ooooo", [subPatterns objectAtIndex:2], nil); - STAssertEqualStrings(@"baz", [subPatterns objectAtIndex:3], nil); - STAssertEqualObjects([NSNull null], [subPatterns objectAtIndex:4], nil); - STAssertEqualStrings(@"baz", [subPatterns objectAtIndex:5], nil); + XCTAssertNotNil(subPatterns); + XCTAssertEqual((NSUInteger)6, [subPatterns count]); + XCTAssertEqualStrings(@"foooooobaz", [subPatterns objectAtIndex:0]); + XCTAssertEqualStrings(@"foooooo", [subPatterns objectAtIndex:1]); + XCTAssertEqualStrings(@"ooooo", [subPatterns objectAtIndex:2]); + XCTAssertEqualStrings(@"baz", [subPatterns objectAtIndex:3]); + XCTAssertEqualObjects([NSNull null], [subPatterns objectAtIndex:4]); + XCTAssertEqualStrings(@"baz", [subPatterns objectAtIndex:5]); // not there subPatterns = [@"aaa" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; - STAssertNil(subPatterns, nil); + XCTAssertNil(subPatterns); // not extra stuff on either end subPatterns = [@"ZZZfoooooobaz" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; - STAssertNil(subPatterns, nil); + XCTAssertNil(subPatterns); subPatterns = [@"foooooobazZZZ" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; - STAssertNil(subPatterns, nil); + XCTAssertNil(subPatterns); subPatterns = [@"ZZZfoooooobazZZZ" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; - STAssertNil(subPatterns, nil); + XCTAssertNil(subPatterns); } - (void)testFirstSubStringMatchedByPattern { // simple pattern - STAssertEqualStrings([@"foobar" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], - @"foobar", nil); - STAssertEqualStrings([@"foobydoo spambar" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], - @"foobydoo spambar", nil); - STAssertEqualStrings([@"zzfoobarzz" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], - @"foobar", nil); - STAssertEqualStrings([@"zzfoobydoo spambarzz" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], - @"foobydoo spambar", nil); - STAssertNil([@"abcdef" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], nil); - STAssertNil([@"" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], nil); + XCTAssertEqualStrings([@"foobar" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], + @"foobar"); + XCTAssertEqualStrings([@"foobydoo spambar" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], + @"foobydoo spambar"); + XCTAssertEqualStrings([@"zzfoobarzz" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], + @"foobar"); + XCTAssertEqualStrings([@"zzfoobydoo spambarzz" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], + @"foobydoo spambar"); + XCTAssertNil([@"abcdef" gtm_firstSubStringMatchedByPattern:@"foo.*bar"]); + XCTAssertNil([@"" gtm_firstSubStringMatchedByPattern:@"foo.*bar"]); // pattern w/ sub patterns - STAssertEqualStrings([@"foobar" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], - @"foobar", nil); - STAssertEqualStrings([@"foobydoo spambar" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], - @"foobydoo spambar", nil); - STAssertEqualStrings([@"zzfoobarzz" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], - @"foobar", nil); - STAssertEqualStrings([@"zzfoobydoo spambarzz" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], - @"foobydoo spambar", nil); - STAssertNil([@"abcdef" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], nil); - STAssertNil([@"" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], nil); + XCTAssertEqualStrings([@"foobar" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], + @"foobar"); + XCTAssertEqualStrings([@"foobydoo spambar" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], + @"foobydoo spambar"); + XCTAssertEqualStrings([@"zzfoobarzz" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], + @"foobar"); + XCTAssertEqualStrings([@"zzfoobydoo spambarzz" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], + @"foobydoo spambar"); + XCTAssertNil([@"abcdef" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"]); + XCTAssertNil([@"" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"]); } - (void)testSubStringMatchesPattern { // simple pattern - STAssertTrue([@"foobar" gtm_subStringMatchesPattern:@"foo.*bar"], nil); - STAssertTrue([@"foobydoo spambar" gtm_subStringMatchesPattern:@"foo.*bar"], nil); - STAssertTrue([@"zzfoobarzz" gtm_subStringMatchesPattern:@"foo.*bar"], nil); - STAssertTrue([@"zzfoobydoo spambarzz" gtm_subStringMatchesPattern:@"foo.*bar"], nil); - STAssertFalse([@"abcdef" gtm_subStringMatchesPattern:@"foo.*bar"], nil); - STAssertFalse([@"" gtm_subStringMatchesPattern:@"foo.*bar"], nil); + XCTAssertTrue([@"foobar" gtm_subStringMatchesPattern:@"foo.*bar"]); + XCTAssertTrue([@"foobydoo spambar" gtm_subStringMatchesPattern:@"foo.*bar"]); + XCTAssertTrue([@"zzfoobarzz" gtm_subStringMatchesPattern:@"foo.*bar"]); + XCTAssertTrue([@"zzfoobydoo spambarzz" gtm_subStringMatchesPattern:@"foo.*bar"]); + XCTAssertFalse([@"abcdef" gtm_subStringMatchesPattern:@"foo.*bar"]); + XCTAssertFalse([@"" gtm_subStringMatchesPattern:@"foo.*bar"]); // pattern w/ sub patterns - STAssertTrue([@"foobar" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"], nil); - STAssertTrue([@"foobydoo spambar" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"], nil); - STAssertTrue([@"zzfoobarzz" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"], nil); - STAssertTrue([@"zzfoobydoo spambarzz" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"], nil); - STAssertFalse([@"abcdef" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"], nil); - STAssertFalse([@"" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"], nil); + XCTAssertTrue([@"foobar" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); + XCTAssertTrue([@"foobydoo spambar" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); + XCTAssertTrue([@"zzfoobarzz" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); + XCTAssertTrue([@"zzfoobydoo spambarzz" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); + XCTAssertFalse([@"abcdef" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); + XCTAssertFalse([@"" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); } - (void)testSegmentEnumeratorForPattern { NSEnumerator *enumerator = [@"afoobarbfooobaarfoobarzz" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "a" GTMRegexStringSegment *seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"a", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"a"); // "foobar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); // "b" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"b", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"b"); // "fooobaar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"fooobaar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"fooobaar"); // "foobar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); // "zz" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"zz", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"zz"); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test no match enumerator = [@"aaa" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"aaa", nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"aaa"); seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test only match enumerator = [@"foobar" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // now test the saved sub segments enumerator = [@"foobarxxfoobaz" gtm_segmentEnumeratorForPattern:@"(foo)((bar)|(baz))"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "foobar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); - STAssertEqualStrings([seg subPatternString:0], @"foobar", nil); - STAssertEqualStrings([seg subPatternString:1], @"foo", nil); - STAssertEqualStrings([seg subPatternString:2], @"bar", nil); - STAssertEqualStrings([seg subPatternString:3], @"bar", nil); - STAssertNil([seg subPatternString:4], nil); // nothing matched "(baz)" - STAssertNil([seg subPatternString:5], nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); + XCTAssertEqualStrings([seg subPatternString:0], @"foobar"); + XCTAssertEqualStrings([seg subPatternString:1], @"foo"); + XCTAssertEqualStrings([seg subPatternString:2], @"bar"); + XCTAssertEqualStrings([seg subPatternString:3], @"bar"); + XCTAssertNil([seg subPatternString:4]); // nothing matched "(baz)" + XCTAssertNil([seg subPatternString:5]); // "xx" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertFalse([seg isMatch], nil); - STAssertEqualStrings([seg string], @"xx", nil); - STAssertEqualStrings([seg subPatternString:0], @"xx", nil); - STAssertNil([seg subPatternString:1], nil); + XCTAssertNotNil(seg); + XCTAssertFalse([seg isMatch]); + XCTAssertEqualStrings([seg string], @"xx"); + XCTAssertEqualStrings([seg subPatternString:0], @"xx"); + XCTAssertNil([seg subPatternString:1]); // "foobaz" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobaz", nil); - STAssertEqualStrings([seg subPatternString:0], @"foobaz", nil); - STAssertEqualStrings([seg subPatternString:1], @"foo", nil); - STAssertEqualStrings([seg subPatternString:2], @"baz", nil); - STAssertNil([seg subPatternString:3], nil); // (nothing matched "(bar)" - STAssertEqualStrings([seg subPatternString:4], @"baz", nil); - STAssertNil([seg subPatternString:5], nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobaz"); + XCTAssertEqualStrings([seg subPatternString:0], @"foobaz"); + XCTAssertEqualStrings([seg subPatternString:1], @"foo"); + XCTAssertEqualStrings([seg subPatternString:2], @"baz"); + XCTAssertNil([seg subPatternString:3]); // (nothing matched "(bar)" + XCTAssertEqualStrings([seg subPatternString:4], @"baz"); + XCTAssertNil([seg subPatternString:5]); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test all objects enumerator = [@"afoobarbfooobaarfoobarzz" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); NSArray *allSegments = [enumerator allObjects]; - STAssertNotNil(allSegments, nil); - STAssertEquals((NSUInteger)6, [allSegments count], nil); + XCTAssertNotNil(allSegments); + XCTAssertEqual((NSUInteger)6, [allSegments count]); } - (void)testMatchSegmentEnumeratorForPattern { NSEnumerator *enumerator = [@"afoobarbfooobaarfoobarzz" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "a" - skipped // "foobar" GTMRegexStringSegment *seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); // "b" - skipped // "fooobaar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"fooobaar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"fooobaar"); // "foobar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); // "zz" - skipped // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test no match enumerator = [@"aaa" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test only match enumerator = [@"foobar" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // now test the saved sub segments enumerator = [@"foobarxxfoobaz" gtm_matchSegmentEnumeratorForPattern:@"(foo)((bar)|(baz))"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); // "foobar" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobar", nil); - STAssertEqualStrings([seg subPatternString:0], @"foobar", nil); - STAssertEqualStrings([seg subPatternString:1], @"foo", nil); - STAssertEqualStrings([seg subPatternString:2], @"bar", nil); - STAssertEqualStrings([seg subPatternString:3], @"bar", nil); - STAssertNil([seg subPatternString:4], nil); // nothing matched "(baz)" - STAssertNil([seg subPatternString:5], nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobar"); + XCTAssertEqualStrings([seg subPatternString:0], @"foobar"); + XCTAssertEqualStrings([seg subPatternString:1], @"foo"); + XCTAssertEqualStrings([seg subPatternString:2], @"bar"); + XCTAssertEqualStrings([seg subPatternString:3], @"bar"); + XCTAssertNil([seg subPatternString:4]); // nothing matched "(baz)" + XCTAssertNil([seg subPatternString:5]); // "xx" - skipped // "foobaz" seg = [enumerator nextObject]; - STAssertNotNil(seg, nil); - STAssertTrue([seg isMatch], nil); - STAssertEqualStrings([seg string], @"foobaz", nil); - STAssertEqualStrings([seg subPatternString:0], @"foobaz", nil); - STAssertEqualStrings([seg subPatternString:1], @"foo", nil); - STAssertEqualStrings([seg subPatternString:2], @"baz", nil); - STAssertNil([seg subPatternString:3], nil); // (nothing matched "(bar)" - STAssertEqualStrings([seg subPatternString:4], @"baz", nil); - STAssertNil([seg subPatternString:5], nil); + XCTAssertNotNil(seg); + XCTAssertTrue([seg isMatch]); + XCTAssertEqualStrings([seg string], @"foobaz"); + XCTAssertEqualStrings([seg subPatternString:0], @"foobaz"); + XCTAssertEqualStrings([seg subPatternString:1], @"foo"); + XCTAssertEqualStrings([seg subPatternString:2], @"baz"); + XCTAssertNil([seg subPatternString:3]); // (nothing matched "(bar)" + XCTAssertEqualStrings([seg subPatternString:4], @"baz"); + XCTAssertNil([seg subPatternString:5]); // (end) seg = [enumerator nextObject]; - STAssertNil(seg, nil); + XCTAssertNil(seg); // test all objects enumerator = [@"afoobarbfooobaarfoobarzz" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; - STAssertNotNil(enumerator, nil); + XCTAssertNotNil(enumerator); NSArray *allSegments = [enumerator allObjects]; - STAssertNotNil(allSegments, nil); - STAssertEquals((NSUInteger)3, [allSegments count], nil); + XCTAssertNotNil(allSegments); + XCTAssertEqual((NSUInteger)3, [allSegments count]); } - (void)testAllSubstringsMatchedByPattern { NSArray *segments = [@"afoobarbfooobaarfoobarzz" gtm_allSubstringsMatchedByPattern:@"foo+ba+r"]; - STAssertNotNil(segments, nil); - STAssertEquals((NSUInteger)3, [segments count], nil); - STAssertEqualStrings([segments objectAtIndex:0], @"foobar", nil); - STAssertEqualStrings([segments objectAtIndex:1], @"fooobaar", nil); - STAssertEqualStrings([segments objectAtIndex:2], @"foobar", nil); + XCTAssertNotNil(segments); + XCTAssertEqual((NSUInteger)3, [segments count]); + XCTAssertEqualStrings([segments objectAtIndex:0], @"foobar"); + XCTAssertEqualStrings([segments objectAtIndex:1], @"fooobaar"); + XCTAssertEqualStrings([segments objectAtIndex:2], @"foobar"); // test no match segments = [@"aaa" gtm_allSubstringsMatchedByPattern:@"foo+ba+r"]; - STAssertNotNil(segments, nil); - STAssertEquals((NSUInteger)0, [segments count], nil); + XCTAssertNotNil(segments); + XCTAssertEqual((NSUInteger)0, [segments count]); // test only match segments = [@"foobar" gtm_allSubstringsMatchedByPattern:@"foo+ba+r"]; - STAssertNotNil(segments, nil); - STAssertEquals((NSUInteger)1, [segments count], nil); - STAssertEqualStrings([segments objectAtIndex:0], @"foobar", nil); + XCTAssertNotNil(segments); + XCTAssertEqual((NSUInteger)1, [segments count]); + XCTAssertEqualStrings([segments objectAtIndex:0], @"foobar"); } - (void)testStringByReplacingMatchesOfPatternWithReplacement { // the basics - STAssertEqualStrings(@"weeZbarZbydoo spamZfooZdoggies", - [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" - withReplacement:@"Z\\3Z\\2Z\\1Z"], - nil); + XCTAssertEqualStrings(@"weeZbarZbydoo spamZfooZdoggies", + [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" + withReplacement:@"Z\\3Z\\2Z\\1Z"]); // nil/empty replacement - STAssertEqualStrings(@"weedoggies", - [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" - withReplacement:nil], - nil); - STAssertEqualStrings(@"weedoggies", - [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" - withReplacement:@""], - nil); - STAssertEqualStrings(@"", - [@"" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" - withReplacement:@"abc"], - nil); + XCTAssertEqualStrings(@"weedoggies", + [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" + withReplacement:nil]); + XCTAssertEqualStrings(@"weedoggies", + [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" + withReplacement:@""]); + XCTAssertEqualStrings(@"", + [@"" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" + withReplacement:@"abc"]); // use optional and invale subexpression parts to confirm that works - STAssertEqualStrings(@"aaa baz bar bar foo baz aaa", - [@"aaa foooooobaz fooobar bar foo baz aaa" gtm_stringByReplacingMatchesOfPattern:@"(fo(o+))((bar)|(baz))" - withReplacement:@"\\4\\5"], - nil); - STAssertEqualStrings(@"aaa ZZZ ZZZ bar foo baz aaa", - [@"aaa foooooobaz fooobar bar foo baz aaa" gtm_stringByReplacingMatchesOfPattern:@"(fo(o+))((bar)|(baz))" - withReplacement:@"Z\\10Z\\12Z"], - nil); + XCTAssertEqualStrings(@"aaa baz bar bar foo baz aaa", + [@"aaa foooooobaz fooobar bar foo baz aaa" gtm_stringByReplacingMatchesOfPattern:@"(fo(o+))((bar)|(baz))" + withReplacement:@"\\4\\5"]); + XCTAssertEqualStrings(@"aaa ZZZ ZZZ bar foo baz aaa", + [@"aaa foooooobaz fooobar bar foo baz aaa" gtm_stringByReplacingMatchesOfPattern:@"(fo(o+))((bar)|(baz))" + withReplacement:@"Z\\10Z\\12Z"]); // test slashes in replacement that aren't part of the subpattern reference - STAssertEqualStrings(@"z\\\\0 \\\\a \\\\\\\\0z", - [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" - withReplacement:@"\\\\0 \\\\\\0 \\\\\\\\0"], - nil); - STAssertEqualStrings(@"z\\\\a \\\\\\\\0 \\\\\\\\az", - [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" - withReplacement:@"\\\\\\0 \\\\\\\\0 \\\\\\\\\\0"], - nil); - STAssertEqualStrings(@"z\\\\\\\\0 \\\\\\\\a \\\\\\\\\\\\0z", - [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" - withReplacement:@"\\\\\\\\0 \\\\\\\\\\0 \\\\\\\\\\\\0"], - nil); + XCTAssertEqualStrings(@"z\\\\0 \\\\a \\\\\\\\0z", + [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" + withReplacement:@"\\\\0 \\\\\\0 \\\\\\\\0"]); + XCTAssertEqualStrings(@"z\\\\a \\\\\\\\0 \\\\\\\\az", + [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" + withReplacement:@"\\\\\\0 \\\\\\\\0 \\\\\\\\\\0"]); + XCTAssertEqualStrings(@"z\\\\\\\\0 \\\\\\\\a \\\\\\\\\\\\0z", + [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" + withReplacement:@"\\\\\\\\0 \\\\\\\\\\0 \\\\\\\\\\\\0"]); } @end diff --git a/Foundation/GTMSQLite.h b/Foundation/GTMSQLite.h index 0697d5a..0daa02c 100644 --- a/Foundation/GTMSQLite.h +++ b/Foundation/GTMSQLite.h @@ -92,12 +92,6 @@ // or ranges between single UniChars. // -// SQLite is preinstalled on 10.4 only. As long as we're using the OS version -// of the library, limit ourself to Tiger+ -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4 -#error SQLite support is Tiger or later -#endif - #import <Foundation/Foundation.h> #import <sqlite3.h> diff --git a/Foundation/GTMSQLite.m b/Foundation/GTMSQLite.m index 502a5cc..aa5d5f5 100644 --- a/Foundation/GTMSQLite.m +++ b/Foundation/GTMSQLite.m @@ -20,9 +20,6 @@ #import <Foundation/Foundation.h> -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -#import <dlfcn.h> -#endif #import "GTMSQLite.h" #import "GTMMethodCheck.h" #import "GTMDefines.h" @@ -44,22 +41,6 @@ typedef struct { int textRep; } LikeGlobUserArgs; -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -// While we want to be compatible with Tiger, some operations are more -// efficient when implemented with Leopard APIs. We look those up dynamically. -// CFStringCreateWithBytesNoCopy -static const char* const kCFStringCreateWithBytesNoCopySymbolName = - "CFStringCreateWithBytesNoCopy"; - -typedef CFStringRef (*CFStringCreateWithBytesNoCopyPtrType)(CFAllocatorRef, - const UInt8 *, - CFIndex, - CFStringEncoding, - Boolean, - CFAllocatorRef); -static CFStringCreateWithBytesNoCopyPtrType gCFStringCreateWithBytesNoCopySymbol = NULL; -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - // Helper inline for SQLite text type to CF endcoding GTM_INLINE CFStringEncoding SqliteTextEncodingToCFStringEncoding(int enc) { // Default should never happen, but assume UTF 8 @@ -87,14 +68,12 @@ GTM_INLINE CFOptionFlags FilteredStringCompareFlags(CFOptionFlags inOptions) { if (inOptions & kCFCompareNonliteral) outOptions |= kCFCompareNonliteral; if (inOptions & kCFCompareLocalized) outOptions |= kCFCompareLocalized; if (inOptions & kCFCompareNumerically) outOptions |= kCFCompareNumerically; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 if (inOptions & kCFCompareDiacriticInsensitive) { outOptions |= kCFCompareDiacriticInsensitive; } if (inOptions & kCFCompareWidthInsensitive) { outOptions |= kCFCompareWidthInsensitive; } -#endif return outOptions; } @@ -141,14 +120,6 @@ static CFLocaleRef gCurrentLocale = NULL; + (void)initialize { // Need the locale for some CFString enhancements gCurrentLocale = CFLocaleCopyCurrent(); - -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - // Compiling pre-Leopard try to find some symbols dynamically - gCFStringCreateWithBytesNoCopySymbol = - (CFStringCreateWithBytesNoCopyPtrType)dlsym( - RTLD_DEFAULT, - kCFStringCreateWithBytesNoCopySymbolName); -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 } + (int)sqliteVersionNumber { @@ -176,7 +147,7 @@ static CFLocaleRef gCurrentLocale = NULL; #else cfEncoding = kCFStringEncodingUTF16LE; #endif - NSStringEncoding nsEncoding + NSStringEncoding nsEncoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding); NSData *data = [path dataUsingEncoding:nsEncoding]; // Using -[NSString cStringUsingEncoding] causes sqlite3_open16 @@ -420,7 +391,7 @@ static CFLocaleRef gCurrentLocale = NULL; - (CFOptionFlags)likeComparisonOptions { CFOptionFlags flags = 0; - if (hasCFAdditions_) + if (hasCFAdditions_) flags = likeOptions_; return flags; } @@ -510,7 +481,7 @@ static CFLocaleRef gCurrentLocale = NULL; } - (NSString *)description { - return [NSString stringWithFormat:@"<%@: %p - %@>", + return [NSString stringWithFormat:@"<%@: %p - %@>", [self class], self, path_]; } @end @@ -787,7 +758,7 @@ static void CollateNeeded(void *userContext, sqlite3 *db, int textRep, [collationName componentsSeparatedByString:@"_"]; NSString *collationFlag = nil; BOOL atLeastOneValidFlag = NO; - GTM_FOREACH_OBJECT(collationFlag, collationComponents) { + for (collationFlag in collationComponents) { if ([collationFlag isEqualToString:@"reverse"]) { userArgs->reverse = YES; atLeastOneValidFlag = YES; @@ -803,19 +774,12 @@ static void CollateNeeded(void *userContext, sqlite3 *db, int textRep, } else if ([collationFlag isEqualToString:@"numeric"]) { userArgs->compareOptions |= kCFCompareNumerically; atLeastOneValidFlag = YES; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 } else if ([collationFlag isEqualToString:@"nodiacritic"]) { userArgs->compareOptions |= kCFCompareDiacriticInsensitive; atLeastOneValidFlag = YES; } else if ([collationFlag isEqualToString:@"widthinsensitive"]) { userArgs->compareOptions |= kCFCompareWidthInsensitive; atLeastOneValidFlag = YES; -#else - } else if (([collationFlag isEqualToString:@"nodiacritic"]) || - ([collationFlag isEqualToString:@"widthinsensitive"])) { - _GTMDevLog(@"GTMSQLiteDatabase 10.5 collating not " - @"available on 10.4 or earlier"); -#endif } } @@ -874,34 +838,6 @@ static int Collate8(void *userContext, int length1, const void *str1, // creation function, we'll use it when we can but we want to stay compatible // with Tiger. CFStringRef string1 = NULL, string2 = NULL; -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - if (gCFStringCreateWithBytesNoCopySymbol) { - string1 = gCFStringCreateWithBytesNoCopySymbol(kCFAllocatorDefault, - str1, - length1, - kCFStringEncodingUTF8, - false, - kCFAllocatorNull); - string2 = gCFStringCreateWithBytesNoCopySymbol(kCFAllocatorDefault, - str2, - length2, - kCFStringEncodingUTF8, - false, - kCFAllocatorNull); - } else { - // Have to use the copy-based variants - string1 = CFStringCreateWithBytes(kCFAllocatorDefault, - str1, - length1, - kCFStringEncodingUTF8, - false); - string2 = CFStringCreateWithBytes(kCFAllocatorDefault, - str2, - length2, - kCFStringEncodingUTF8, - false); - } -#else // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 string1 = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, str1, length1, @@ -914,7 +850,6 @@ static int Collate8(void *userContext, int length1, const void *str1, kCFStringEncodingUTF8, false, kCFAllocatorNull); -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 GTMCFAutorelease(string1); GTMCFAutorelease(string2); // Allocation failures can't really be sanely handled from a collator @@ -937,7 +872,7 @@ static int Collate8(void *userContext, int length1, const void *str1, if (userArgs->reverse && sqliteResult) { sqliteResult = -sqliteResult; } - + } return sqliteResult; } @@ -1025,7 +960,7 @@ static int Collate16(void *userContext, int length1, const void *str1, string2, userArgs->compareOptions); - sqliteResult = (int)result; + sqliteResult = (int)result; //Reverse if (userArgs->reverse && sqliteResult) { sqliteResult = -sqliteResult; @@ -1052,8 +987,8 @@ static void LikeGlobCompare(sqlite3_context *context, // Setup for pattern walk CFIndex patternLength = CFStringGetLength(pattern); CFStringInlineBuffer patternBuffer; - CFStringInitInlineBuffer(pattern, - &patternBuffer, + CFStringInitInlineBuffer(pattern, + &patternBuffer, CFRangeMake(0, patternLength)); UniChar patternChar; CFIndex patternIndex = 0; @@ -1128,7 +1063,7 @@ static void LikeGlobCompare(sqlite3_context *context, } // There's at least one character, try to match the remainder of the // string using a CFCharacterSet - CFMutableCharacterSetRef charSet + CFMutableCharacterSetRef charSet = CFCharacterSetCreateMutable(kCFAllocatorDefault); GTMCFAutorelease(charSet); if (!charSet) { @@ -1776,8 +1711,8 @@ static void Glob16(sqlite3_context *context, int argc, sqlite3_value **argv) { - (int)bindBlobAtPosition:(int)position data:(NSData *)data { if (!statement_ || !data || !position) return SQLITE_MISUSE; int blobLength = (int)[data length]; - _GTMDevAssert((blobLength < INT_MAX), - @"sqlite methods do not support data lengths " + _GTMDevAssert((blobLength < INT_MAX), + @"sqlite methods do not support data lengths " @"exceeding 32 bit sizes"); return [self bindBlobAtPosition:position bytes:(void *)[data bytes] @@ -1822,8 +1757,8 @@ static void Glob16(sqlite3_context *context, int argc, sqlite3_value **argv) { } return sqlite3_bind_text(statement_, position, - [string UTF8String], - -1, + [string UTF8String], + -1, SQLITE_TRANSIENT); } diff --git a/Foundation/GTMSQLiteTest.m b/Foundation/GTMSQLiteTest.m index 8a5f18d..2537dd6 100644 --- a/Foundation/GTMSQLiteTest.m +++ b/Foundation/GTMSQLiteTest.m @@ -19,7 +19,6 @@ #import "GTMSQLite.h" #import "GTMSenTestCase.h" -#import "GTMUnitTestDevLog.h" @interface GTMSQLiteTest : GTMTestCase @end @@ -48,66 +47,66 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); autorelease]; err = [db executeSQL:@"CREATE TABLE foo (bar TEXT COLLATE NOCASE_NONLITERAL);"]; - STAssertEquals(err, SQLITE_OK, @"Failed to create table"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table"); int changeCount = [db lastChangeCount]; - STAssertEquals(changeCount, 0, + XCTAssertEqual(changeCount, 0, @"Change count was not 0 after creating database/table!"); err = [db executeSQL:@"insert into foo (bar) values ('blah!');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); changeCount = [db lastChangeCount]; - STAssertEquals(changeCount, 1, @"Change count was not 1!"); + XCTAssertEqual(changeCount, 1, @"Change count was not 1!"); // Test last row id! unsigned long long lastRowId; lastRowId = [db lastInsertRowID]; - STAssertEquals(lastRowId, (unsigned long long)1L, + XCTAssertEqual(lastRowId, (unsigned long long)1L, @"First row in database was not 1?"); // Test setting busy and retrieving it! int busyTimeout = 10000; err = [db setBusyTimeoutMS:busyTimeout]; - STAssertEquals(err, SQLITE_OK, @"Error setting busy timeout"); + XCTAssertEqual(err, SQLITE_OK, @"Error setting busy timeout"); int retrievedBusyTimeout; retrievedBusyTimeout = [db busyTimeoutMS]; - STAssertEquals(retrievedBusyTimeout, busyTimeout, + XCTAssertEqual(retrievedBusyTimeout, busyTimeout, @"Retrieved busy time out was not equal to what we set it" @" to!"); BOOL xactOpSucceeded; xactOpSucceeded = [db beginDeferredTransaction]; - STAssertTrue(xactOpSucceeded, @"beginDeferredTransaction failed!"); + XCTAssertTrue(xactOpSucceeded, @"beginDeferredTransaction failed!"); err = [db executeSQL:@"insert into foo (bar) values ('blah!');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); changeCount = [db lastChangeCount]; - STAssertEquals(changeCount, 1, + XCTAssertEqual(changeCount, 1, @"Change count didn't stay the same" @"when inserting during transaction"); xactOpSucceeded = [db rollback]; - STAssertTrue(xactOpSucceeded, @"could not rollback!"); + XCTAssertTrue(xactOpSucceeded, @"could not rollback!"); changeCount = [db lastChangeCount]; - STAssertEquals(changeCount, 1, @"Change count isn't 1 after rollback :-("); + XCTAssertEqual(changeCount, 1, @"Change count isn't 1 after rollback :-("); xactOpSucceeded = [db beginDeferredTransaction]; - STAssertTrue(xactOpSucceeded, @"beginDeferredTransaction failed!"); + XCTAssertTrue(xactOpSucceeded, @"beginDeferredTransaction failed!"); for (unsigned int i = 0; i < 100; i++) { err = [db executeSQL:@"insert into foo (bar) values ('blah!');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); } xactOpSucceeded = [db commit]; - STAssertTrue(xactOpSucceeded, @"could not commit!"); + XCTAssertTrue(xactOpSucceeded, @"could not commit!"); changeCount = [db totalChangeCount]; - STAssertEquals(changeCount, 102, @"Change count isn't 102 after commit :-("); + XCTAssertEqual(changeCount, 102, @"Change count isn't 102 after commit :-("); } - (void)testSQLiteWithoutCFAdditions { @@ -118,14 +117,14 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); errorCode:&err] autorelease]; - STAssertNotNil(dbNoCFAdditions, @"Failed to create DB"); - STAssertEquals(err, SQLITE_OK, @"Failed to create DB"); + XCTAssertNotNil(dbNoCFAdditions, @"Failed to create DB"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create DB"); err = [dbNoCFAdditions executeSQL:nil]; - STAssertEquals(err, SQLITE_MISUSE, @"Nil SQL did not return error"); + XCTAssertEqual(err, SQLITE_MISUSE, @"Nil SQL did not return error"); err = [dbNoCFAdditions executeSQL:@"SELECT UPPER('Fred');"]; - STAssertEquals(err, SQLITE_OK, @"Nil SQL did not return error"); + XCTAssertEqual(err, SQLITE_OK, @"Nil SQL did not return error"); } - (void)testSynchronousAPI { @@ -147,8 +146,8 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); errorCode:&err] autorelease]; - STAssertNotNil(db8, @"Failed to create DB"); - STAssertEquals(err, SQLITE_OK, @"Failed to create DB"); + XCTAssertNotNil(db8, @"Failed to create DB"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create DB"); GTMSQLiteDatabase *db16 = [[[GTMSQLiteDatabase alloc] initInMemoryWithCFAdditions:YES @@ -156,27 +155,27 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); errorCode:&err] autorelease]; - STAssertNotNil(db16, @"Failed to create DB"); - STAssertEquals(err, SQLITE_OK, @"Failed to create DB"); + XCTAssertNotNil(db16, @"Failed to create DB"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create DB"); NSArray *databases = [NSArray arrayWithObjects:db8, db16, nil]; GTMSQLiteDatabase *db; - GTM_FOREACH_OBJECT(db, databases) { + for (db in databases) { err = [db executeSQL: @"CREATE TABLE foo (bar TEXT COLLATE NOCASE_NONLITERAL," @" barrev text collate reverse);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for collation test"); // Create blank rows to test matching inside collation functions err = [db executeSQL:@"insert into foo (bar, barrev) values ('','');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); // Insert one row we want to match err = [db executeSQL: @"INSERT INTO foo (bar, barrev) VALUES " @"('teststring','teststring');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); NSString *matchString = @"foobar"; GTMSQLiteStatement *statement = @@ -184,29 +183,29 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); @"SELECT bar FROM foo WHERE bar == '%@';", matchString] inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); [statement stepRow]; [statement finalizeStatement]; - + statement = [GTMSQLiteStatement statementWithSQL:[NSString stringWithFormat: @"SELECT bar FROM foo WHERE barrev == '%@' order by barrev;", matchString] inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); [statement stepRow]; [statement finalizeStatement]; - + statement = [GTMSQLiteStatement statementWithSQL:[NSString stringWithFormat: @"SELECT bar FROM foo WHERE bar == '';"] inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); [statement stepRow]; [statement finalizeStatement]; @@ -215,8 +214,8 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); @"SELECT bar FROM foo WHERE barrev == '' order by barrev;"] inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); [statement stepRow]; [statement finalizeStatement]; } @@ -230,24 +229,24 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); errorCode:&err] autorelease]; - STAssertNotNil(db, @"Failed to create DB"); - STAssertEquals(err, SQLITE_OK, @"Failed to create DB"); + XCTAssertNotNil(db, @"Failed to create DB"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create DB"); err = [db executeSQL:@"CREATE TABLE foo (bar TEXT COLLATE NOCASE_NONLITERAL);"]; - STAssertEquals(err, SQLITE_OK, @"Failed to create table for collation test"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for collation test"); // Insert one row we want to match err = [db executeSQL:[NSString stringWithFormat: @"INSERT INTO foo (bar) VALUES ('%@');", [NSString stringWithCString:"Frédéric" encoding:NSUTF8StringEncoding]]]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); // Create blank rows to test matching inside collation functions err = [db executeSQL:@"insert into foo (bar) values ('');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); err = [db executeSQL:@"insert into foo (bar) values ('');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); // Loop over a few things all of which should match NSArray *testArray = [NSArray arrayWithObjects: @@ -259,19 +258,19 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); encoding:NSUTF8StringEncoding], nil]; NSString *testString = nil; - GTM_FOREACH_OBJECT(testString, testArray) { + for (testString in testArray) { GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:[NSString stringWithFormat: @"SELECT bar FROM foo WHERE bar == '%@';", testString] inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); int count = 0; while ([statement stepRow] == SQLITE_ROW) { count++; } - STAssertEquals(count, 1, @"Wrong number of collated rows for \"%@\"", + XCTAssertEqual(count, 1, @"Wrong number of collated rows for \"%@\"", testString); [statement finalizeStatement]; } @@ -281,8 +280,8 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); while ([statement stepRow] == SQLITE_ROW) ; [statement finalizeStatement]; @@ -299,33 +298,33 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); utf8:YES errorCode:&err] autorelease]; - STAssertNotNil(db, @"Failed to create DB"); - STAssertEquals(err, SQLITE_OK, @"Failed to create DB"); + XCTAssertNotNil(db, @"Failed to create DB"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create DB"); GTMSQLiteStatement *statement = nil; // Test simple ASCII statement = [GTMSQLiteStatement statementWithSQL:@"SELECT LOWER('Fred');" inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"Failed to step row"); - STAssertEqualObjects([statement resultStringAtPosition:0], - @"fred", - @"LOWER failed for ASCII string"); + XCTAssertEqual(err, SQLITE_ROW, @"Failed to step row"); + XCTAssertEqualObjects([statement resultStringAtPosition:0], + @"fred", + @"LOWER failed for ASCII string"); [statement finalizeStatement]; statement = [GTMSQLiteStatement statementWithSQL:@"SELECT UPPER('Fred');" inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"Failed to step row"); - STAssertEqualObjects([statement resultStringAtPosition:0], - @"FRED", - @"UPPER failed for ASCII string"); + XCTAssertEqual(err, SQLITE_ROW, @"Failed to step row"); + XCTAssertEqualObjects([statement resultStringAtPosition:0], + @"FRED", + @"UPPER failed for ASCII string"); [statement finalizeStatement]; // Test UTF-8, have to do some dancing to make the compiler take @@ -344,13 +343,13 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); [NSString stringWithFormat:@"SELECT LOWER('%@');", utfNormalString] inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"Failed to step row"); - STAssertEqualObjects([statement resultStringAtPosition:0], - utfLowerString, - @"UPPER failed for UTF8 string"); + XCTAssertEqual(err, SQLITE_ROW, @"Failed to step row"); + XCTAssertEqualObjects([statement resultStringAtPosition:0], + utfLowerString, + @"UPPER failed for UTF8 string"); [statement finalizeStatement]; statement = @@ -358,15 +357,15 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); [NSString stringWithFormat:@"SELECT UPPER('%@');", utfNormalString] inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"Failed to step row"); - STAssertEqualObjects([statement resultStringAtPosition:0], - utfUpperString, - @"UPPER failed for UTF8 string"); + XCTAssertEqual(err, SQLITE_ROW, @"Failed to step row"); + XCTAssertEqualObjects([statement resultStringAtPosition:0], + utfUpperString, + @"UPPER failed for UTF8 string"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, @"Should be done"); + XCTAssertEqual(err, SQLITE_DONE, @"Should be done"); [statement finalizeStatement]; } @@ -380,33 +379,33 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql); utf8:NO errorCode:&err] autorelease]; - STAssertNotNil(db, @"Failed to create DB"); - STAssertEquals(err, SQLITE_OK, @"Failed to create DB"); + XCTAssertNotNil(db, @"Failed to create DB"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create DB"); GTMSQLiteStatement *statement = nil; // Test simple ASCII statement = [GTMSQLiteStatement statementWithSQL:@"SELECT LOWER('Fred');" inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"Failed to step row"); - STAssertEqualObjects([statement resultStringAtPosition:0], - @"fred", - @"LOWER failed for ASCII string"); + XCTAssertEqual(err, SQLITE_ROW, @"Failed to step row"); + XCTAssertEqualObjects([statement resultStringAtPosition:0], + @"fred", + @"LOWER failed for ASCII string"); [statement finalizeStatement]; statement = [GTMSQLiteStatement statementWithSQL:@"SELECT UPPER('Fred');" inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"Failed to step row"); - STAssertEqualObjects([statement resultStringAtPosition:0], - @"FRED", - @"UPPER failed for ASCII string"); + XCTAssertEqual(err, SQLITE_ROW, @"Failed to step row"); + XCTAssertEqualObjects([statement resultStringAtPosition:0], + @"FRED", + @"UPPER failed for ASCII string"); [statement finalizeStatement]; } @@ -450,7 +449,7 @@ static void TestUpperLower16Impl(sqlite3_context *context, customUpperLower[i].function, NULL, NULL); - STAssertEquals(rc, SQLITE_OK, + XCTAssertEqual(rc, SQLITE_OK, @"Failed to register upper function" @"with SQLite db"); } @@ -459,12 +458,12 @@ static void TestUpperLower16Impl(sqlite3_context *context, GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:@"SELECT UPPER('Fred');" inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"Failed to step row"); - STAssertTrue(customUpperFunctionCalled, - @"Custom upper function was not called!"); + XCTAssertEqual(err, SQLITE_ROW, @"Failed to step row"); + XCTAssertTrue(customUpperFunctionCalled, + @"Custom upper function was not called!"); [statement finalizeStatement]; } @@ -483,7 +482,7 @@ static void TestUpperLower16Impl(sqlite3_context *context, NSArray *databases = [NSArray arrayWithObjects:db8, db16, nil]; GTMSQLiteDatabase *db; - GTM_FOREACH_OBJECT(db, databases) { + for (db in databases) { CFOptionFlags c = 0, oldFlags; oldFlags = [db likeComparisonOptions]; @@ -492,22 +491,18 @@ static void TestUpperLower16Impl(sqlite3_context *context, // case insensitive [db setLikeComparisonOptions:c]; - STAssertTrue([db likeComparisonOptions] == 0, - @"LIKE Comparison options setter/getter does not work!"); + XCTAssertTrue([db likeComparisonOptions] == 0, + @"LIKE Comparison options setter/getter does not work!"); NSString *createString = nil; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 createString = @"CREATE TABLE foo (bar NODIACRITIC_WIDTHINSENSITIVE TEXT);"; -#else - createString = @"CREATE TABLE foo (bar TEXT);"; -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 err = [db executeSQL:createString]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for like comparison options test"); err = [db executeSQL:@"insert into foo values('test like test');"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create row for like comparison options test"); GTMSQLiteStatement *statement = @@ -515,22 +510,20 @@ static void TestUpperLower16Impl(sqlite3_context *context, inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"failed to create statement"); + XCTAssertNotNil(statement, @"failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, @"failed to retrieve row!"); + XCTAssertEqual(err, SQLITE_DONE, @"failed to retrieve row!"); // Now change it back to case insensitive and rerun the same query c |= kCFCompareCaseInsensitive; [db setLikeComparisonOptions:c]; err = [statement reset]; - STAssertEquals(err, SQLITE_OK, @"failed to reset select statement"); + XCTAssertEqual(err, SQLITE_OK, @"failed to reset select statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"failed to retrieve row!"); + XCTAssertEqual(err, SQLITE_ROW, @"failed to retrieve row!"); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - // Now try adding in 10.5 only flags c |= (kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive); [db setLikeComparisonOptions:c]; // Make a new statement @@ -539,14 +532,13 @@ static void TestUpperLower16Impl(sqlite3_context *context, [GTMSQLiteStatement statementWithSQL:@"select * from foo where bar like '%LIKE%'" inDatabase:db errorCode:&err]; - - STAssertNotNil(statement, @"failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"failed to create statement"); - + + XCTAssertNotNil(statement, @"failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"failed to create statement"); + err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"failed to retrieve row!"); -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - + XCTAssertEqual(err, SQLITE_ROW, @"failed to retrieve row!"); + // Now reset comparison options [db setLikeComparisonOptions:oldFlags]; @@ -567,15 +559,15 @@ static void TestUpperLower16Impl(sqlite3_context *context, [db setGlobComparisonOptions:c]; - STAssertTrue([db globComparisonOptions] == 0, - @"GLOB Comparison options setter/getter does not work!"); + XCTAssertTrue([db globComparisonOptions] == 0, + @"GLOB Comparison options setter/getter does not work!"); err = [db executeSQL:@"CREATE TABLE foo (bar TEXT);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for glob comparison options test"); err = [db executeSQL:@"insert into foo values('test like test');"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create row for glob comparison options test"); GTMSQLiteStatement *statement = @@ -583,19 +575,19 @@ static void TestUpperLower16Impl(sqlite3_context *context, inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"failed to create statement"); + XCTAssertNotNil(statement, @"failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, @"failed to retrieve row!"); + XCTAssertEqual(err, SQLITE_DONE, @"failed to retrieve row!"); // Now change it back to case insensitive and rerun the same query c |= kCFCompareCaseInsensitive; [db setGlobComparisonOptions:c]; err = [statement reset]; - STAssertEquals(err, SQLITE_OK, @"failed to reset select statement"); + XCTAssertEqual(err, SQLITE_OK, @"failed to reset select statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"failed to retrieve row!"); + XCTAssertEqual(err, SQLITE_ROW, @"failed to retrieve row!"); [statement finalizeStatement]; @@ -611,38 +603,38 @@ static void TestUpperLower16Impl(sqlite3_context *context, errorCode:&err] autorelease]; err = [db executeSQL:@"CREATE table foo_reverse (bar TEXT COLLATE REVERSE);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for reverse collation test"); err = [db executeSQL:@"insert into foo_reverse values('a2');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); err = [db executeSQL:@"insert into foo_reverse values('b1');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:@"SELECT bar from foo_reverse order by bar" inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"failed to advance row"); + XCTAssertEqual(err, SQLITE_ROW, @"failed to advance row"); NSString *oneRow = [statement resultStringAtPosition:0]; - STAssertEqualStrings(oneRow, @"b1", @"b did not come first!"); + XCTAssertEqualStrings(oneRow, @"b1", @"b did not come first!"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"failed to advance row!"); + XCTAssertEqual(err, SQLITE_ROW, @"failed to advance row!"); - STAssertEquals(err, [db lastErrorCode], + XCTAssertEqual(err, [db lastErrorCode], @"lastErrorCode API did not match what last API returned!"); // Calling lastErrorCode resets API error, so the next string will not indicate any error - STAssertEqualStrings(@"not an error", [db lastErrorString], - @"lastErrorString API did not match expected string!"); + XCTAssertEqualStrings(@"unknown error", [db lastErrorString], + @"lastErrorString API did not match expected string!"); oneRow = [statement resultStringAtPosition:0]; - STAssertEqualStrings(oneRow, @"a2", @"a did not come second!"); + XCTAssertEqualStrings(oneRow, @"a2", @"a did not come second!"); [statement finalizeStatement]; } @@ -657,32 +649,32 @@ static void TestUpperLower16Impl(sqlite3_context *context, err = [db executeSQL: @"CREATE table numeric_test_table " @"(numeric_sort TEXT COLLATE NUMERIC, lexographic_sort TEXT);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for numeric collation test"); err = [db executeSQL:@"insert into numeric_test_table values('4','17');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); err = [db executeSQL:@"insert into numeric_test_table values('17','4');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:@"SELECT numeric_sort from numeric_test_table order by numeric_sort" inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"failed to advance row"); + XCTAssertEqual(err, SQLITE_ROW, @"failed to advance row"); NSString *oneRow = [statement resultStringAtPosition:0]; - STAssertEqualStrings(oneRow, @"4", @"4 did not come first!"); + XCTAssertEqualStrings(oneRow, @"4", @"4 did not come first!"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"failed to advance row!"); + XCTAssertEqual(err, SQLITE_ROW, @"failed to advance row!"); oneRow = [statement resultStringAtPosition:0]; - STAssertEqualStrings(oneRow, @"17", @"17 did not come second!"); + XCTAssertEqualStrings(oneRow, @"17", @"17 did not come second!"); [statement finalizeStatement]; @@ -693,18 +685,18 @@ static void TestUpperLower16Impl(sqlite3_context *context, inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"failed to create statement for lexographic sort"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"failed to create statement for lexographic sort"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"failed to advance row"); + XCTAssertEqual(err, SQLITE_ROW, @"failed to advance row"); oneRow = [statement resultStringAtPosition:0]; - STAssertEqualStrings(oneRow, @"17", @"17 did not come first!"); + XCTAssertEqualStrings(oneRow, @"17", @"17 did not come first!"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, @"failed to advance row!"); + XCTAssertEqual(err, SQLITE_ROW, @"failed to advance row!"); oneRow = [statement resultStringAtPosition:0]; - STAssertEqualStrings(oneRow, @"4", @"4 did not come second!"); + XCTAssertEqualStrings(oneRow, @"4", @"4 did not come second!"); [statement finalizeStatement]; } @@ -718,18 +710,18 @@ static void TestUpperLower16Impl(sqlite3_context *context, [[GTMSQLiteDatabase alloc] initInMemoryWithCFAdditions:YES utf8:YES errorCode:&err]; - STAssertNotNil(db, @"Failed to create DB"); - STAssertEquals(err, SQLITE_OK, @"Failed to create DB"); + XCTAssertNotNil(db, @"Failed to create DB"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create DB"); err = [db executeSQL: @"CREATE TABLE foo (bar TEXT COLLATE NOCASE_NONLITERAL_LOCALIZED);"]; - STAssertEquals(err, SQLITE_OK, @"Failed to create table for collation test"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for collation test"); // Insert one row we want to match err = [db executeSQL:[NSString stringWithFormat: @"INSERT INTO foo (bar) VALUES ('%@');", [NSString stringWithCString:"Frédéric" encoding:NSUTF8StringEncoding]]]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute SQL"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute SQL"); // Loop over a few things all of which should match NSArray *testArray = [NSArray arrayWithObjects: @@ -742,19 +734,19 @@ static void TestUpperLower16Impl(sqlite3_context *context, nil]; NSString *testString = nil; - GTM_FOREACH_OBJECT(testString, testArray) { + for (testString in testArray) { GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:[NSString stringWithFormat: @"SELECT bar FROM foo WHERE bar == '%@';", testString] inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); int count = 0; while ([statement stepRow] == SQLITE_ROW) { count++; } - STAssertEquals(count, 1, @"Wrong number of collated rows for \"%@\"", + XCTAssertEqual(count, 1, @"Wrong number of collated rows for \"%@\"", testString); [statement finalizeStatement]; } @@ -765,23 +757,20 @@ static void TestUpperLower16Impl(sqlite3_context *context, } - (void)testDiacriticAndWidthInsensitiveCollations { - // Diacritic & width insensitive collations are not supported - // on Tiger, so most of the test is Leopard or later -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 int err; GTMSQLiteDatabase *db = [[[GTMSQLiteDatabase alloc] initInMemoryWithCFAdditions:YES utf8:YES errorCode:&err] autorelease]; - STAssertNotNil(db, @"Failed to create DB"); - STAssertEquals(err, SQLITE_OK, @"Failed to create DB"); + XCTAssertNotNil(db, @"Failed to create DB"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create DB"); NSString *tableSQL = @"CREATE TABLE FOOBAR (collated TEXT COLLATE NODIACRITIC_WIDTHINSENSITIVE, " @" noncollated TEXT);"; err = [db executeSQL:tableSQL]; - STAssertEquals(err, SQLITE_OK, @"error creating table"); + XCTAssertEqual(err, SQLITE_OK, @"error creating table"); NSString *testStringValue = [NSString stringWithCString:"Frédéric" encoding:NSUTF8StringEncoding]; @@ -797,11 +786,11 @@ static void TestUpperLower16Impl(sqlite3_context *context, @" WHERE noncollated == 'Frederic';"] inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); // Make sure the comparison query didn't return a row because // we're doing a comparison on the row without the collation - STAssertEquals([statement stepRow], SQLITE_DONE, + XCTAssertEqual([statement stepRow], SQLITE_DONE, @"Comparison with diacritics did not succeed"); [statement finalizeStatement]; @@ -812,34 +801,11 @@ static void TestUpperLower16Impl(sqlite3_context *context, @" WHERE collated == 'Frederic';"] inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); - STAssertEquals([statement stepRow], SQLITE_ROW, + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertEqual([statement stepRow], SQLITE_ROW, @"Comparison ignoring diacritics did not succeed"); [statement finalizeStatement]; -#else - // On Tiger just make sure it causes the dev log. - int err; - GTMSQLiteDatabase *db = - [[[GTMSQLiteDatabase alloc] initInMemoryWithCFAdditions:YES - utf8:YES - errorCode:&err] autorelease]; - STAssertNotNil(db, @"Failed to create DB"); - STAssertEquals(err, SQLITE_OK, @"Failed to create DB"); - - NSString *tableSQL = - @"CREATE TABLE FOOBAR (collated TEXT" - @" COLLATE NODIACRITIC_WIDTHINSENSITIVE_NOCASE," - @" noncollated TEXT);"; - - // Expect one log for each unsupported flag - [GTMUnitTestDevLog expect:2 - casesOfString:@"GTMSQLiteDatabase 10.5 collating not available " - @"on 10.4 or earlier"]; - err = [db executeSQL:tableSQL]; - STAssertEquals(err, SQLITE_OK, @"error creating table"); - -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 } - (void)testCFStringLikeGlob { @@ -852,8 +818,8 @@ static void TestUpperLower16Impl(sqlite3_context *context, errorCode:&err] autorelease]; - STAssertNotNil(db8, @"Failed to create database"); - STAssertEquals(err, SQLITE_OK, @"Failed to create database"); + XCTAssertNotNil(db8, @"Failed to create database"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create database"); GTMSQLiteDatabase *db16 = [[[GTMSQLiteDatabase alloc] initInMemoryWithCFAdditions:YES @@ -861,164 +827,164 @@ static void TestUpperLower16Impl(sqlite3_context *context, errorCode:&err] autorelease]; - STAssertNotNil(db16, @"Failed to create database"); - STAssertEquals(err, SQLITE_OK, @"Failed to create database"); + XCTAssertNotNil(db16, @"Failed to create database"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create database"); NSArray *databases = [NSArray arrayWithObjects:db8, db16, nil]; GTMSQLiteDatabase *db; - GTM_FOREACH_OBJECT(db, databases) { + for (db in databases) { err = [db executeSQL:@"CREATE TABLE t1 (x TEXT);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for LIKE/GLOB test"); // Insert data set err = [db executeSQL:@"INSERT INTO t1 VALUES ('a');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('ab');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('abc');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('abcd');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('acd');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('abd');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('bc');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('bcd');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('xyz');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('ABC');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('CDE');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t1 VALUES ('ABC abc xyz');"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); // Section 1, case tests - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'abc' ORDER BY 1;"), ([NSArray arrayWithObjects:@"ABC", @"abc", nil]), @"Fail on LIKE test 1.1"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x GLOB 'abc' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", nil]), @"Fail on LIKE test 1.2"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'ABC' ORDER BY 1;"), ([NSArray arrayWithObjects:@"ABC", @"abc", nil]), @"Fail on LIKE test 1.3"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;"), ([NSArray arrayWithObjects:@"ABC", @"ABC abc xyz", @"abc", @"abcd", nil]), @"Fail on LIKE test 3.1"); [db setLikeComparisonOptions:(kCFCompareNonliteral)]; err = [db executeSQL:@"CREATE INDEX i1 ON t1(x);"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); - STAssertEqualObjects( + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @"Fail on LIKE test 3.3"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'a_c' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", nil]), @"Fail on LIKE test 3.5"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'ab%d' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abcd", @"abd", nil]), @"Fail on LIKE test 3.7"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'a_c%' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @"Fail on LIKE test 3.9"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE '%bcd' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abcd", @"bcd", nil]), @"Fail on LIKE test 3.11"); [db setLikeComparisonOptions:(kCFCompareNonliteral | kCFCompareCaseInsensitive)]; - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;"), ([NSArray arrayWithObjects:@"ABC", @"ABC abc xyz", @"abc", @"abcd", nil]), @"Fail on LIKE test 3.13"); [db setLikeComparisonOptions:(kCFCompareNonliteral)]; err = [db executeSQL:@"DROP INDEX i1;"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); - STAssertEqualObjects( + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @"Fail on LIKE test 3.15"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @"Fail on LIKE test 3.17"); err = [db executeSQL:@"CREATE INDEX i1 ON t1(x);"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); - STAssertEqualObjects( + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @"Fail on LIKE test 3.19"); [db setLikeComparisonOptions:(kCFCompareNonliteral)]; - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x GLOB 'abc*' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @"Fail on LIKE test 3.21"); [db setLikeComparisonOptions:(kCFCompareNonliteral | kCFCompareCaseInsensitive)]; - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x GLOB 'a[bc]d' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abd", @"acd", nil]), @"Fail on LIKE test 3.23"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x from t1 where x GLOB 'a[^xyz]d' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abd", @"acd", nil]), @"Fail on glob inverted character set test 3.24"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x from t1 where x GLOB 'a[^' ORDER BY 1;"), ([NSArray array]), @"Fail on glob inverted character set test 3.25"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x from t1 where x GLOB 'a['"), ([NSArray array]), @"Unclosed glob character set did not return empty result set 3.26"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x from t1 where x GLOB 'a[^]'"), ([NSArray array]), @"Unclosed glob inverted character set did not return empty " @"result set 3.27"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x from t1 where x GLOB 'a[^]c]d'"), ([NSArray arrayWithObjects:@"abd", nil]), @"Glob character set with inverted set not matching ] did not " @"return right rows 3.28"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x from t1 where x GLOB 'a[bcdefg'"), ([NSArray array]), @@ -1026,36 +992,36 @@ static void TestUpperLower16Impl(sqlite3_context *context, // Section 4 [db setLikeComparisonOptions:(kCFCompareNonliteral)]; - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @"Fail on LIKE test 4.1"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE +x LIKE 'abc%' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @"Fail on LIKE test 4.2"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE ('ab' || 'c%') ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @"Fail on LIKE test 4.3"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x from t1 where x LIKE 'a[xyz]\%' ESCAPE ''"), ([NSArray array]), @"0-Character escape clause did not return empty set 4.4"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x from t1 where x LIKE " @"'a[xyz]\%' ESCAPE NULL"), ([NSArray array]), @"Null escape did not return empty set 4.5"); - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x from t1 where x LIKE 'a[xyz]\\%' " @"ESCAPE '\\'"), @@ -1066,22 +1032,22 @@ static void TestUpperLower16Impl(sqlite3_context *context, // Section 5 [db setLikeComparisonOptions:(kCFCompareNonliteral | kCFCompareCaseInsensitive)]; - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;"), ([NSArray arrayWithObjects:@"ABC", @"ABC abc xyz", @"abc", @"abcd", nil]), @"Fail on LIKE test 5.1"); err = [db executeSQL:@"CREATE TABLE t2(x COLLATE NOCASE);"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"INSERT INTO t2 SELECT * FROM t1;"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); err = [db executeSQL:@"CREATE INDEX i2 ON t2(x COLLATE NOCASE);"]; - STAssertEquals(err, SQLITE_OK, @"Failed to execute sql"); - STAssertEqualObjects( + XCTAssertEqual(err, SQLITE_OK, @"Failed to execute sql"); + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"ABC", @"ABC abc xyz", @"abcd", nil]), @@ -1089,7 +1055,7 @@ static void TestUpperLower16Impl(sqlite3_context *context, [db setLikeComparisonOptions:(kCFCompareNonliteral)]; - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t2 WHERE x LIKE 'abc%' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @@ -1097,14 +1063,14 @@ static void TestUpperLower16Impl(sqlite3_context *context, [db setLikeComparisonOptions:(kCFCompareNonliteral | kCFCompareCaseInsensitive)]; - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t2 WHERE x GLOB 'abc*' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abc", @"abcd", nil]), @"Fail on LIKE test 5.5"); // Non standard tests not from the SQLite source - STAssertEqualObjects( + XCTAssertEqualObjects( LikeGlobTestHelper(db, @"SELECT x FROM t1 WHERE x GLOB 'a[b-d]d' ORDER BY 1;"), ([NSArray arrayWithObjects:@"abd", @"acd", nil]), @@ -1119,34 +1085,34 @@ static void TestUpperLower16Impl(sqlite3_context *context, utf8:YES errorCode:&err] autorelease]; - - STAssertNotNil(db8, @"Failed to create database"); - STAssertEquals(err, SQLITE_OK, @"Failed to create database"); - STAssertNotNil([db8 description], nil); + + XCTAssertNotNil(db8, @"Failed to create database"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create database"); + XCTAssertNotNil([db8 description]); } // // From GTMSQLite.m // CFStringEncoding SqliteTextEncodingToCFStringEncoding(int enc); // - (void)testEncodingMappingIsCorrect { -// STAssertTrue(SqliteTextEncodingToCFStringEncoding(SQLITE_UTF8) == -// kCFStringEncodingUTF8, -// @"helper method didn't return right encoding for " -// @"kCFStringEncodingUTF8"); - -// STAssertTrue(SqliteTextEncodingToCFStringEncoding(SQLITE_UTF16BE) -// == kCFStringEncodingUTF16BE, -// @"helper method didn't return right encoding for " -// @"kCFStringEncodingUTF16BE"); - -// STAssertTrue(SqliteTextEncodingToCFStringEncoding(SQLITE_UTF16LE) -// == kCFStringEncodingUTF16LE, -// @"helper method didn't return right encoding for " -// @"kCFStringEncodingUTF16LE"); - -// STAssertTrue(SqliteTextEncodingToCFStringEncoding(9999) -// == kCFStringEncodingUTF8, @"helper method didn't " -// @"return default encoding for invalid input"); +// XCTAssertTrue(SqliteTextEncodingToCFStringEncoding(SQLITE_UTF8) == +// kCFStringEncodingUTF8, +// @"helper method didn't return right encoding for " +// @"kCFStringEncodingUTF8"); + +// XCTAssertTrue(SqliteTextEncodingToCFStringEncoding(SQLITE_UTF16BE) +// == kCFStringEncodingUTF16BE, +// @"helper method didn't return right encoding for " +// @"kCFStringEncodingUTF16BE"); + +// XCTAssertTrue(SqliteTextEncodingToCFStringEncoding(SQLITE_UTF16LE) +// == kCFStringEncodingUTF16LE, +// @"helper method didn't return right encoding for " +// @"kCFStringEncodingUTF16LE"); + +// XCTAssertTrue(SqliteTextEncodingToCFStringEncoding(9999) +// == kCFStringEncodingUTF8, @"helper method didn't " +// @"return default encoding for invalid input"); // } @end @@ -1182,8 +1148,8 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:nil inDatabase:nil errorCode:&err]; - STAssertNil(statement, @"Create statement succeeded with nil SQL string"); - STAssertEquals(err, SQLITE_MISUSE, @"Err was not SQLITE_MISUSE on nil " + XCTAssertNil(statement, @"Create statement succeeded with nil SQL string"); + XCTAssertEqual(err, SQLITE_MISUSE, @"Err was not SQLITE_MISUSE on nil " @"SQL string"); GTMSQLiteDatabase *db = @@ -1196,8 +1162,8 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { inDatabase:db errorCode:&err]; - STAssertNil(statement, @"Select statement succeeded with invalid table"); - STAssertNotEquals(err, SQLITE_OK, + XCTAssertNil(statement, @"Select statement succeeded with invalid table"); + XCTAssertNotEqual(err, SQLITE_OK, @"Err was not SQLITE_MISUSE on invalid table"); [statement finalizeStatement]; @@ -1219,7 +1185,7 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { err = [db executeSQL:tableCreateSQL]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for collation test"); NSString *insert = @"insert into foo (tc, ic, rc, bc) values (:tc, :ic, :rc, :bc);"; @@ -1227,9 +1193,9 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:insert inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); - STAssertEquals([statement parameterCount], 4, + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertEqual([statement parameterCount], 4, @"Bound parameter count was not 4"); [statement sqlite3Statement]; @@ -1253,7 +1219,7 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { NSArray *databases = [NSArray arrayWithObjects:dbWithCF, dbWithoutCF, nil]; GTMSQLiteDatabase *db; - GTM_FOREACH_OBJECT(db, databases) { + for (db in databases) { NSString *tableCreateSQL = @"CREATE TABLE foo (tc TEXT," @"ic integer," @@ -1261,7 +1227,7 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { @"bc blob);"; err = [db executeSQL:tableCreateSQL]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for collation test"); NSString *insert = @"insert into foo (tc, ic, rc, bc) " @@ -1270,8 +1236,8 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:insert inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create statement"); + XCTAssertNotNil(statement, @"Failed to create statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create statement"); NSArray *parameterNames = [NSArray arrayWithObjects:@":tc", @":ic", @@ -1280,15 +1246,15 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { for (unsigned int i = 1; i <= [parameterNames count]; i++) { NSString *paramName = [parameterNames objectAtIndex:i-1]; - // Cast to signed int to avoid type errors from STAssertEquals - STAssertEquals((int)i, + // Cast to signed int to avoid type errors from XCTAssertEqual + XCTAssertEqual((int)i, [statement positionOfParameterNamed:paramName], @"positionOfParameterNamed API did not return correct " @"results"); - STAssertEqualStrings(paramName, - [statement nameOfParameterAtPosition:i], - @"nameOfParameterAtPosition API did not return " - @"correct name"); + XCTAssertEqualStrings(paramName, + [statement nameOfParameterAtPosition:i], + @"nameOfParameterAtPosition API did not return " + @"correct name"); } [statement finalizeStatement]; } @@ -1311,21 +1277,21 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { NSArray *databases = [NSArray arrayWithObjects:dbWithCF, dbWithoutCF, nil]; GTMSQLiteDatabase *db; - GTM_FOREACH_OBJECT(db, databases) { + for (db in databases) { // Test strategy is to create a table with 3 columns // Insert some values, and use the result collection APIs // to make sure we get the same values back err = [db executeSQL: @"CREATE TABLE blobby (bc blob);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for BLOB binding test"); NSString *insert = @"insert into blobby (bc) values (:bc);"; GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:insert inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create insert statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create insert statement"); + XCTAssertNotNil(statement, @"Failed to create insert statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create insert statement"); char bytes[] = "DEADBEEF"; NSUInteger bytesLen = strlen(bytes); @@ -1333,10 +1299,10 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { err = [statement bindBlobAtPosition:1 data:originalBytes]; - STAssertEquals(err, SQLITE_OK, @"error binding BLOB at position 1"); + XCTAssertEqual(err, SQLITE_OK, @"error binding BLOB at position 1"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, @"failed to insert BLOB for BLOB test"); + XCTAssertEqual(err, SQLITE_DONE, @"failed to insert BLOB for BLOB test"); [statement finalizeStatement]; @@ -1344,30 +1310,30 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { statement = [GTMSQLiteStatement statementWithSQL:selectSQL inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create select statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create select statement"); + XCTAssertNotNil(statement, @"Failed to create select statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create select statement"); err = [statement stepRow]; // Check that we got at least one row back - STAssertEquals(err, SQLITE_ROW, @"did not retrieve a row from db :-("); - STAssertEquals([statement resultColumnCount], 1, + XCTAssertEqual(err, SQLITE_ROW, @"did not retrieve a row from db :-("); + XCTAssertEqual([statement resultColumnCount], 1, @"result had more columns than the table had?"); - STAssertEqualStrings([statement resultColumnNameAtPosition:BLOB_COLUMN], - @"bc", - @"column name dictionary was not correct"); + XCTAssertEqualStrings([statement resultColumnNameAtPosition:BLOB_COLUMN], + @"bc", + @"column name dictionary was not correct"); - STAssertEquals([statement rowDataCount], + XCTAssertEqual([statement rowDataCount], 1, @"More than one column returned?"); - STAssertEquals([statement resultColumnTypeAtPosition:BLOB_COLUMN], + XCTAssertEqual([statement resultColumnTypeAtPosition:BLOB_COLUMN], SQLITE_BLOB, @"Query for column 1 of test table was not BLOB!"); NSData *returnedbytes = [statement resultBlobDataAtPosition:BLOB_COLUMN]; - STAssertTrue([originalBytes isEqualToData:returnedbytes], - @"Queried data was not equal :-("); + XCTAssertTrue([originalBytes isEqualToData:returnedbytes], + @"Queried data was not equal :-("); [statement finalizeStatement]; } } @@ -1383,22 +1349,22 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { err = [db executeSQL: @"CREATE TABLE foo (tc TEXT);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for NULL binding test"); NSString *insert = @"insert into foo (tc) values (:tc);"; GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:insert inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create insert statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create insert statement"); + XCTAssertNotNil(statement, @"Failed to create insert statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create insert statement"); err = [statement bindSQLNullAtPosition:1]; - STAssertEquals(err, SQLITE_OK, @"error binding NULL at position 1"); + XCTAssertEqual(err, SQLITE_OK, @"error binding NULL at position 1"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, @"failed to insert NULL for Null Binding test"); + XCTAssertEqual(err, SQLITE_DONE, @"failed to insert NULL for Null Binding test"); [statement finalizeStatement]; @@ -1406,12 +1372,12 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { statement = [GTMSQLiteStatement statementWithSQL:selectSQL inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create select statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create select statement"); + XCTAssertNotNil(statement, @"Failed to create select statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create select statement"); err = [statement stepRow]; // Check that we got at least one row back - STAssertEquals(err, SQLITE_ROW, @"did not retrieve a row from db :-("); + XCTAssertEqual(err, SQLITE_ROW, @"did not retrieve a row from db :-("); [statement finalizeStatement]; } @@ -1434,26 +1400,26 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { err = [db executeSQL: @"CREATE TABLE realTable (rc1 REAL, rc2 REAL);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for double binding test"); NSString *insert = @"insert into realTable (rc1, rc2) values (:rc1, :rc2);"; GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:insert inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create insert statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create insert statement"); + XCTAssertNotNil(statement, @"Failed to create insert statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create insert statement"); err = [statement bindDoubleAtPosition:1 value:testVal]; - STAssertEquals(err, SQLITE_OK, @"error binding double at position 1"); + XCTAssertEqual(err, SQLITE_OK, @"error binding double at position 1"); err = [statement bindNumberAsDoubleAtPosition:2 number:doubleValue]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"error binding number as double at " @"position 2"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, + XCTAssertEqual(err, SQLITE_DONE, @"failed to insert doubles for double " @"binding test"); @@ -1463,20 +1429,20 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { statement = [GTMSQLiteStatement statementWithSQL:selectSQL inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create select statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create select statement"); + XCTAssertNotNil(statement, @"Failed to create select statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create select statement"); err = [statement stepRow]; // Check that we got at least one row back - STAssertEquals(err, SQLITE_ROW, @"did not retrieve a row from db :-("); + XCTAssertEqual(err, SQLITE_ROW, @"did not retrieve a row from db :-("); double retrievedValue = [statement resultDoubleAtPosition:0]; - STAssertEquals(retrievedValue, testVal, - @"Retrieved double did not equal " - @"original"); + XCTAssertEqualWithAccuracy(retrievedValue, testVal, 0.01, + @"Retrieved double did not equal " + @"original"); NSNumber *retrievedNumber = [statement resultNumberAtPosition:1]; - STAssertEqualObjects(retrievedNumber, doubleValue, - @"Retrieved NSNumber object did not equal"); + XCTAssertEqualObjects(retrievedNumber, doubleValue, + @"Retrieved NSNumber object did not equal"); [statement finalizeStatement]; } @@ -1497,14 +1463,14 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { NSArray *databases = [NSArray arrayWithObjects:dbWithCF, dbWithoutCF, nil]; GTMSQLiteDatabase *db; - GTM_FOREACH_OBJECT(db, databases) { + for (db in databases) { // Test strategy is to create a table with 3 columns // Insert some values, and use the result collection APIs // to make sure we get the same values back err = [db executeSQL: @"CREATE TABLE test (a integer, b text, c blob, d text);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for result collection test"); NSString *insert = @@ -1514,8 +1480,8 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:insert inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create insert statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create insert statement"); + XCTAssertNotNil(statement, @"Failed to create insert statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create insert statement"); char blobChars[] = "DEADBEEF"; @@ -1523,10 +1489,10 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { NSData *blobData = [NSData dataWithBytes:blobChars length:blobLength]; err = [statement bindBlobAtPosition:1 data:blobData]; - STAssertEquals(err, SQLITE_OK, @"error binding BLOB at position 1"); + XCTAssertEqual(err, SQLITE_OK, @"error binding BLOB at position 1"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, + XCTAssertEqual(err, SQLITE_DONE, @"failed to insert doubles for double " @"binding test"); @@ -1537,16 +1503,16 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { statement = [GTMSQLiteStatement statementWithSQL:selectSQL inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create select statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create select statement"); + XCTAssertNotNil(statement, @"Failed to create select statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create select statement"); err = [statement stepRow]; // Check that we got at least one row back - STAssertEquals(err, SQLITE_ROW, @"did not retrieve a row from db :-("); - STAssertNotNil([statement resultRowArray], - @"Failed to retrieve result array"); - STAssertNotNil([statement resultRowDictionary], - @"Failed to retrieve result dictionary"); + XCTAssertEqual(err, SQLITE_ROW, @"did not retrieve a row from db :-("); + XCTAssertNotNil([statement resultRowArray], + @"Failed to retrieve result array"); + XCTAssertNotNil([statement resultRowDictionary], + @"Failed to retrieve result dictionary"); [statement finalizeStatement]; } } @@ -1570,7 +1536,7 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { err = [db executeSQL: @"CREATE TABLE integerTable (ic1 integer, ic2 integer);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for integer binding test"); NSString *insert = @"insert into integerTable (ic1, ic2) values (:ic1, :ic2);"; @@ -1578,19 +1544,19 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:insert inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create insert statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create insert statement"); + XCTAssertNotNil(statement, @"Failed to create insert statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create insert statement"); err = [statement bindInt32AtPosition:1 value:testVal]; - STAssertEquals(err, SQLITE_OK, @"error binding integer at position 1"); + XCTAssertEqual(err, SQLITE_OK, @"error binding integer at position 1"); err = [statement bindNumberAsInt32AtPosition:2 number:intValue]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"error binding number as integer at " @"position 2"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, + XCTAssertEqual(err, SQLITE_DONE, @"failed to insert integers for integer " @"binding test"); @@ -1600,20 +1566,20 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { statement = [GTMSQLiteStatement statementWithSQL:selectSQL inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create select statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create select statement"); + XCTAssertNotNil(statement, @"Failed to create select statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create select statement"); err = [statement stepRow]; // Check that we got at least one row back - STAssertEquals(err, SQLITE_ROW, @"did not retrieve a row from db :-("); + XCTAssertEqual(err, SQLITE_ROW, @"did not retrieve a row from db :-("); int retrievedValue = [statement resultInt32AtPosition:0]; - STAssertEquals(retrievedValue, testVal, + XCTAssertEqual(retrievedValue, testVal, @"Retrieved integer did not equal " @"original"); NSNumber *retrievedNumber = [statement resultNumberAtPosition:1]; - STAssertEqualObjects(retrievedNumber, intValue, - @"Retrieved NSNumber object did not equal"); + XCTAssertEqualObjects(retrievedNumber, intValue, + @"Retrieved NSNumber object did not equal"); [statement finalizeStatement]; } @@ -1635,9 +1601,9 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { NSNumber *longlongValue = [NSNumber numberWithLongLong:testVal]; err = [db executeSQL: - @"CREATE TABLE longlongTable (llc1 integer, llc2 integer);"]; + @"CREATE TABLE longlongTable (llc1 integer, llc2 integer);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for long long binding test"); NSString *insert = @"insert into longlongTable (llc1, llc2) " @@ -1646,19 +1612,19 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:insert inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create insert statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create insert statement"); + XCTAssertNotNil(statement, @"Failed to create insert statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create insert statement"); err = [statement bindLongLongAtPosition:1 value:testVal]; - STAssertEquals(err, SQLITE_OK, @"error binding long long at position 1"); + XCTAssertEqual(err, SQLITE_OK, @"error binding long long at position 1"); err = [statement bindNumberAsLongLongAtPosition:2 number:longlongValue]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"error binding number as long long at " @"position 2"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, + XCTAssertEqual(err, SQLITE_DONE, @"failed to insert long longs for long long " @"binding test"); @@ -1669,20 +1635,20 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { statement = [GTMSQLiteStatement statementWithSQL:selectSQL inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create select statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create select statement"); + XCTAssertNotNil(statement, @"Failed to create select statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create select statement"); err = [statement stepRow]; // Check that we got at least one row back - STAssertEquals(err, SQLITE_ROW, @"did not retrieve a row from db :-("); + XCTAssertEqual(err, SQLITE_ROW, @"did not retrieve a row from db :-("); long long retrievedValue = [statement resultLongLongAtPosition:0]; - STAssertEquals(retrievedValue, testVal, + XCTAssertEqual(retrievedValue, testVal, @"Retrieved long long did not equal " @"original"); NSNumber *retrievedNumber = [statement resultNumberAtPosition:1]; - STAssertEqualObjects(retrievedNumber, longlongValue, - @"Retrieved NSNumber object did not equal"); + XCTAssertEqualObjects(retrievedNumber, longlongValue, + @"Retrieved NSNumber object did not equal"); [statement finalizeStatement]; } @@ -1701,7 +1667,7 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { err = [db executeSQL: @"CREATE TABLE stringTable (sc1 text);"]; - STAssertEquals(err, SQLITE_OK, + XCTAssertEqual(err, SQLITE_OK, @"Failed to create table for string binding test"); NSString *insert = @@ -1711,15 +1677,15 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { GTMSQLiteStatement *statement = [GTMSQLiteStatement statementWithSQL:insert inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create insert statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create insert statement"); + XCTAssertNotNil(statement, @"Failed to create insert statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create insert statement"); NSString *testVal = @"this is a test string"; err = [statement bindStringAtPosition:1 string:testVal]; - STAssertEquals(err, SQLITE_OK, @"error binding string at position 1"); + XCTAssertEqual(err, SQLITE_OK, @"error binding string at position 1"); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, + XCTAssertEqual(err, SQLITE_DONE, @"failed to insert string for string binding test"); [statement finalizeStatement]; @@ -1731,14 +1697,14 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { statement = [GTMSQLiteStatement statementWithSQL:selectSQL inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create select statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create select statement"); + XCTAssertNotNil(statement, @"Failed to create select statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create select statement"); err = [statement stepRow]; // Check that we got at least one row back - STAssertEquals(err, SQLITE_ROW, @"did not retrieve a row from db :-("); + XCTAssertEqual(err, SQLITE_ROW, @"did not retrieve a row from db :-("); err = [statement stepRow]; - STAssertEquals(err, SQLITE_DONE, @"retrieved more than 1 row from db :-("); + XCTAssertEqual(err, SQLITE_DONE, @"retrieved more than 1 row from db :-("); [statement finalizeStatement]; } @@ -1752,61 +1718,54 @@ static NSArray* LikeGlobTestHelper(GTMSQLiteDatabase *db, NSString *sql) { errorCode:&err] autorelease]; - STAssertNotNil(db, @"Failed to create database"); + XCTAssertNotNil(db, @"Failed to create database"); sqlite3 *sqlite3DB = [db sqlite3DB]; - + NSString *selectSQL = @"select 1"; GTMSQLiteStatement *statement; statement = [GTMSQLiteStatement statementWithSQL:selectSQL inDatabase:db errorCode:&err]; - STAssertNotNil(statement, @"Failed to create select statement"); - STAssertEquals(err, SQLITE_OK, @"Failed to create select statement"); + XCTAssertNotNil(statement, @"Failed to create select statement"); + XCTAssertEqual(err, SQLITE_OK, @"Failed to create select statement"); sqlite3_stmt *sqlite3Statment = [statement sqlite3Statement]; err = [statement stepRow]; - STAssertEquals(err, SQLITE_ROW, + XCTAssertEqual(err, SQLITE_ROW, @"failed to step row for finalize test"); - - NSString *expectedLog = - @"-[GTMSQLiteStatement finalizeStatement] must be called " - @"when statement is no longer needed"; - - [GTMUnitTestDevLog expectString:@"%@", expectedLog]; - [GTMUnitTestDevLog expectPattern:@"Unable to close .*"]; [localPool drain]; - + // Clean up leaks. Since we hadn't finalized the statement above we // were unable to clean up the sqlite databases. Since the pool is drained // all of our objective-c objects are gone, so we have to call the // sqlite3 api directly. - STAssertEquals(sqlite3_finalize(sqlite3Statment), SQLITE_OK, nil); - STAssertEquals(sqlite3_close(sqlite3DB), SQLITE_OK, nil); + XCTAssertEqual(sqlite3_finalize(sqlite3Statment), SQLITE_OK); + XCTAssertEqual(sqlite3_close(sqlite3DB), SQLITE_OK); } - (void)testCompleteSQLString { NSString *str = @"CREATE TABLE longlongTable (llc1 integer, llc2 integer);"; BOOL isComplete = [GTMSQLiteStatement isCompleteStatement:str]; - STAssertTrue(isComplete, nil); + XCTAssertTrue(isComplete); isComplete = [GTMSQLiteStatement isCompleteStatement:@""]; - STAssertTrue(isComplete, nil); + XCTAssertFalse(isComplete); isComplete = [GTMSQLiteStatement isCompleteStatement:@"CR"]; - STAssertFalse(isComplete, nil); + XCTAssertFalse(isComplete); } - (void)testQuotingSQLString { NSString *str = @"This is wild! It's fun!"; NSString *str2 = [GTMSQLiteStatement quoteAndEscapeString:str]; - STAssertEqualObjects(str2, @"'This is wild! It''s fun!'", nil); + XCTAssertEqualObjects(str2, @"'This is wild! It''s fun!'"); str2 = [GTMSQLiteStatement quoteAndEscapeString:@""]; - STAssertEqualObjects(str2, @"''", nil); + XCTAssertEqualObjects(str2, @"''"); } - (void)testVersion { - STAssertGreaterThan([GTMSQLiteDatabase sqliteVersionNumber], 0, nil); - STAssertNotNil([GTMSQLiteDatabase sqliteVersionString], nil); + XCTAssertGreaterThan([GTMSQLiteDatabase sqliteVersionNumber], 0); + XCTAssertNotNil([GTMSQLiteDatabase sqliteVersionString]); } @end diff --git a/Foundation/GTMScriptRunnerTest.m b/Foundation/GTMScriptRunnerTest.m index 07928c2..c8050f5 100644 --- a/Foundation/GTMScriptRunnerTest.m +++ b/Foundation/GTMScriptRunnerTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -20,10 +20,9 @@ #import <unistd.h> #import "GTMSenTestCase.h" #import "GTMScriptRunner.h" -#import "GTMUnitTestDevLog.h" @interface GTMScriptRunnerTest : GTMTestCase { - @private + @private NSString *shScript_; NSString *perlScript_; NSString *shOutputScript_; @@ -45,7 +44,7 @@ @"fi\n" @"echo $i\n" writeToFile:shScript_ atomically:YES encoding:NSUTF8StringEncoding error:nil]; - + perlScript_ = [NSString stringWithFormat:@"/tmp/script_runner_unittest_%d_%d_pl", geteuid(), getpid()]; [@"#!/usr/bin/perl\n" @"use strict;\n" @@ -99,176 +98,179 @@ - (void)testBcCommands { GTMScriptRunner *sr = [GTMScriptRunner runnerWithInterpreter:@"/usr/bin/bc" withArgs:[NSArray arrayWithObject:@"-lq"]]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *output = nil; - + // Simple expression (NOTE that bc requires that commands end with a newline) output = [sr run:@"1 + 2\n"]; - STAssertEqualObjects(output, @"3", @"output should equal '3'"); - + XCTAssertEqualObjects(output, @"3", @"output should equal '3'"); + // Simple expression with variables and multiple statements output = [sr run:@"i=1; i+2\n"]; - STAssertEqualObjects(output, @"3", @"output should equal '3'"); - + XCTAssertEqualObjects(output, @"3", @"output should equal '3'"); + // Simple expression with base conversion output = [sr run:@"obase=2; 2^5\n"]; - STAssertEqualObjects(output, @"100000", @"output should equal '100000'"); - + XCTAssertEqualObjects(output, @"100000", @"output should equal '100000'"); + // Simple expression with sine and cosine functions output = [sr run:@"scale=3;s(0)+c(0)\n"]; - STAssertEqualObjects(output, @"1.000", @"output should equal '1.000'"); + XCTAssertEqualObjects(output, @"1.000", @"output should equal '1.000'"); } - (void)testPerlCommands { GTMScriptRunner *sr = [GTMScriptRunner runnerWithPerl]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *output = nil; - + // Simple print output = [sr run:@"print 'hi'"]; - STAssertEqualObjects(output, @"hi", @"output should equal 'hi'"); - + XCTAssertEqualObjects(output, @"hi", @"output should equal 'hi'"); + // Simple print x4 output = [sr run:@"print 'A'x4"]; - STAssertEqualObjects(output, @"AAAA", @"output should equal 'AAAA'"); - + XCTAssertEqualObjects(output, @"AAAA", @"output should equal 'AAAA'"); + // Simple perl-y stuff output = [sr run:@"my $i=0; until ($i++==41){} print $i"]; - STAssertEqualObjects(output, @"42", @"output should equal '42'"); + XCTAssertEqualObjects(output, @"42", @"output should equal '42'"); } - (void)testPythonCommands { GTMScriptRunner *sr = [GTMScriptRunner runnerWithPython]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *output = nil; - + // Simple print output = [sr run:@"print 'hi'"]; - STAssertEqualObjects(output, @"hi", @"output should equal 'hi'"); - + XCTAssertEqualObjects(output, @"hi", @"output should equal 'hi'"); + // Simple python expression output = [sr run:@"print '-'.join(['a', 'b', 'c'])"]; - STAssertEqualObjects(output, @"a-b-c", @"output should equal 'a-b-c'"); + XCTAssertEqualObjects(output, @"a-b-c", @"output should equal 'a-b-c'"); } - (void)testBashScript { GTMScriptRunner *sr = [GTMScriptRunner runnerWithBash]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *output = nil; - + // Simple sh script output = [sr runScript:shScript_]; - STAssertEqualObjects(output, @"1", @"output should equal '1'"); - + XCTAssertEqualObjects(output, @"1", @"output should equal '1'"); + // Simple sh script with 1 command line argument output = [sr runScript:shScript_ withArgs:[NSArray arrayWithObject:@"2"]]; - STAssertEqualObjects(output, @"2", @"output should equal '2'"); + XCTAssertEqualObjects(output, @"2", @"output should equal '2'"); } - (void)testPerlScript { GTMScriptRunner *sr = [GTMScriptRunner runnerWithPerl]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *output = nil; - + // Simple Perl script output = [sr runScript:perlScript_]; - STAssertEqualObjects(output, @"1", @"output should equal '1'"); - + XCTAssertEqualObjects(output, @"1", @"output should equal '1'"); + // Simple perl script with 1 command line argument output = [sr runScript:perlScript_ withArgs:[NSArray arrayWithObject:@"2"]]; - STAssertEqualObjects(output, @"2", @"output should equal '2'"); + XCTAssertEqualObjects(output, @"2", @"output should equal '2'"); } - (void)testEnvironment { GTMScriptRunner *sr = [GTMScriptRunner runner]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *output = nil; NSString *error = nil; - STAssertNil([sr environment], @"should start w/ empty env"); - + XCTAssertNil([sr environment], @"should start w/ empty env"); + output = [sr run:@"/usr/bin/env | wc -l" standardError:&error]; int numVars = [output intValue]; - STAssertGreaterThan(numVars, 0, - @"numVars should be positive. StdErr %@", error); + XCTAssertGreaterThan(numVars, 0, + @"numVars should be positive. StdErr %@", error); // By default the environment is wiped clean, however shells often add a few - // of their own env vars after things have been wiped. For example, sh will + // of their own env vars after things have been wiped. For example, sh will // add about 3 env vars (PWD, _, and SHLVL). - STAssertLessThan(numVars, 5, @"Our env should be almost empty"); - + XCTAssertLessThan(numVars, 5, @"Our env should be almost empty"); + NSDictionary *newEnv = [NSDictionary dictionaryWithObject:@"bar" forKey:@"foo"]; [sr setEnvironment:newEnv]; output = [sr run:@"/usr/bin/env | wc -l" standardError:&error]; - STAssertEquals([output intValue], numVars + 1, - @"should have one more env var now. StdErr %@", error); - + XCTAssertEqual([output intValue], numVars + 1, + @"should have one more env var now. StdErr %@", error); + [sr setEnvironment:nil]; output = [sr run:@"/usr/bin/env | wc -l" standardError:&error]; - STAssertEquals([output intValue], numVars, - @"should be back down to %d vars. StdErr:%@", numVars, error); - - NSMutableDictionary *currVars + XCTAssertEqual([output intValue], numVars, + @"should be back down to %d vars. StdErr:%@", numVars, error); + + NSMutableDictionary *currVars = [[[[NSProcessInfo processInfo] environment] mutableCopy] autorelease]; - + // When debugging a release build _ was not in the processInfo environment // causing the assert below to fail. Not sure why, but it appeared // to be harmless, and easy to account for. [currVars setObject:@"/usr/bin/env" forKey:@"_"]; [sr setEnvironment:currVars]; - + + // Account for the shell level. + [currVars setObject:@"1" forKey:@"SHLVL"]; + output = [sr run:@"/usr/bin/env | /usr/bin/sort" standardError:&error]; NSArray *lineArray = [output componentsSeparatedByString:@"\n"]; - STAssertEquals([lineArray count], [currVars count], - @"StdErr:%@\nCurrentEnvironment:\n%@\nExpected environment:\n%@", - error, output, currVars); + XCTAssertEqual([lineArray count], [currVars count], + @"StdErr:%@\nCurrentEnvironment:\n%@\nExpected environment:\n%@", + error, output, currVars); } - (void)testDescription { // make sure description doesn't choke GTMScriptRunner *sr = [GTMScriptRunner runner]; - STAssertNotNil(sr, @"Script runner must not be nil"); - STAssertGreaterThan([[sr description] length], (NSUInteger)10, - @"expected a description of at least 10 chars"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertGreaterThan([[sr description] length], (NSUInteger)10, + @"expected a description of at least 10 chars"); } - (void)testRunCommandOutputHandling { // Test whitespace trimming & stdout vs. stderr w/ run command api - + GTMScriptRunner *sr = [GTMScriptRunner runnerWithBash]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *output = nil; NSString *err = nil; - + // w/o whitespace trimming { [sr setTrimsWhitespace:NO]; - STAssertFalse([sr trimsWhitespace], @"setTrimsWhitespace to NO failed"); - + XCTAssertFalse([sr trimsWhitespace], @"setTrimsWhitespace to NO failed"); + // test stdout output = [sr run:@"echo \" on out \"" standardError:&err]; - STAssertEqualObjects(output, @" on out \n", @"failed to get stdout output"); - STAssertNil(err, @"stderr should have been empty"); - + XCTAssertEqualObjects(output, @" on out \n", @"failed to get stdout output"); + XCTAssertNil(err, @"stderr should have been empty"); + // test stderr output = [sr run:@"echo \" on err \" > /dev/stderr" standardError:&err]; - STAssertNil(output, @"stdout should have been empty"); - STAssertEqualObjects(err, @" on err \n", nil); + XCTAssertNil(output, @"stdout should have been empty"); + XCTAssertEqualObjects(err, @" on err \n"); } - + // w/ whitespace trimming { [sr setTrimsWhitespace:YES]; - STAssertTrue([sr trimsWhitespace], @"setTrimsWhitespace to YES failed"); - + XCTAssertTrue([sr trimsWhitespace], @"setTrimsWhitespace to YES failed"); + // test stdout output = [sr run:@"echo \" on out \"" standardError:&err]; - STAssertEqualObjects(output, @"on out", @"failed to get stdout output"); - STAssertNil(err, @"stderr should have been empty"); - + XCTAssertEqualObjects(output, @"on out", @"failed to get stdout output"); + XCTAssertNil(err, @"stderr should have been empty"); + // test stderr output = [sr run:@"echo \" on err \" > /dev/stderr" standardError:&err]; - STAssertNil(output, @"stdout should have been empty"); - STAssertEqualObjects(err, @"on err", nil); + XCTAssertNil(output, @"stdout should have been empty"); + XCTAssertEqualObjects(err, @"on err"); } } @@ -276,102 +278,96 @@ // Test whitespace trimming & stdout vs. stderr w/ script api GTMScriptRunner *sr = [GTMScriptRunner runner]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *output = nil; NSString *err = nil; // w/o whitespace trimming { [sr setTrimsWhitespace:NO]; - STAssertFalse([sr trimsWhitespace], @"setTrimsWhitespace to NO failed"); - + XCTAssertFalse([sr trimsWhitespace], @"setTrimsWhitespace to NO failed"); + // test stdout output = [sr runScript:shOutputScript_ withArgs:[NSArray arrayWithObject:@"out"] standardError:&err]; - STAssertEqualObjects(output, @" on out \n", nil); - STAssertNil(err, @"stderr should have been empty"); - + XCTAssertEqualObjects(output, @" on out \n"); + XCTAssertNil(err, @"stderr should have been empty"); + // test stderr output = [sr runScript:shOutputScript_ withArgs:[NSArray arrayWithObject:@"err"] standardError:&err]; - STAssertNil(output, @"stdout should have been empty"); - STAssertEqualObjects(err, @" on err \n", nil); + XCTAssertNil(output, @"stdout should have been empty"); + XCTAssertEqualObjects(err, @" on err \n"); } - + // w/ whitespace trimming { [sr setTrimsWhitespace:YES]; - STAssertTrue([sr trimsWhitespace], @"setTrimsWhitespace to YES failed"); - + XCTAssertTrue([sr trimsWhitespace], @"setTrimsWhitespace to YES failed"); + // test stdout output = [sr runScript:shOutputScript_ withArgs:[NSArray arrayWithObject:@"out"] standardError:&err]; - STAssertEqualObjects(output, @"on out", nil); - STAssertNil(err, @"stderr should have been empty"); - + XCTAssertEqualObjects(output, @"on out"); + XCTAssertNil(err, @"stderr should have been empty"); + // test stderr output = [sr runScript:shOutputScript_ withArgs:[NSArray arrayWithObject:@"err"] standardError:&err]; - STAssertNil(output, @"stdout should have been empty"); - STAssertEqualObjects(err, @"on err", nil); + XCTAssertNil(output, @"stdout should have been empty"); + XCTAssertEqualObjects(err, @"on err"); } } - (void)testBadRunCommandInput { GTMScriptRunner *sr = [GTMScriptRunner runner]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *err = nil; - - STAssertNil([sr run:nil standardError:&err], nil); - STAssertNil(err, nil); + + XCTAssertNil([sr run:nil standardError:&err]); + XCTAssertNil(err); } - (void)testBadScriptInput { GTMScriptRunner *sr = [GTMScriptRunner runner]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *err = nil; - - STAssertNil([sr runScript:nil withArgs:nil standardError:&err], nil); - STAssertNil(err, nil); - STAssertNil([sr runScript:@"/path/that/does/not/exists/foo/bar/baz" - withArgs:nil standardError:&err], nil); - STAssertNotNil(err, - @"should have gotten something about the path not existing"); + + XCTAssertNil([sr runScript:nil withArgs:nil standardError:&err]); + XCTAssertNil(err); + XCTAssertNil([sr runScript:@"/path/that/does/not/exists/foo/bar/baz" + withArgs:nil standardError:&err]); + XCTAssertNotNil(err, + @"should have gotten something about the path not existing"); } - (void)testBadCmdInterpreter { GTMScriptRunner *sr = [GTMScriptRunner runnerWithInterpreter:@"/path/that/does/not/exists/interpreter"]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *err = nil; - - STAssertNil([sr run:nil standardError:&err], nil); - STAssertNil(err, nil); - [GTMUnitTestDevLog expectString:@"Failed to launch interpreter " - "'/path/that/does/not/exists/interpreter' due to: launch path not accessible"]; - STAssertNil([sr run:@"ls /" standardError:&err], nil); - STAssertNil(err, nil); + + XCTAssertNil([sr run:nil standardError:&err]); + XCTAssertNil(err); + XCTAssertNil([sr run:@"ls /" standardError:&err]); + XCTAssertNil(err); } - (void)testBadScriptInterpreter { GTMScriptRunner *sr = [GTMScriptRunner runnerWithInterpreter:@"/path/that/does/not/exists/interpreter"]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *err = nil; - - [GTMUnitTestDevLog expectString:@"Failed to launch interpreter " - "'/path/that/does/not/exists/interpreter' due to: launch path not accessible"]; - STAssertNil([sr runScript:shScript_ withArgs:nil standardError:&err], nil); - STAssertNil(err, nil); - [GTMUnitTestDevLog expectString:@"Failed to launch interpreter " - "'/path/that/does/not/exists/interpreter' due to: launch path not accessible"]; - STAssertNil([sr runScript:@"/path/that/does/not/exists/foo/bar/baz" - withArgs:nil standardError:&err], nil); - STAssertNil(err, nil); + + XCTAssertNil([sr runScript:shScript_ withArgs:nil standardError:&err]); + XCTAssertNil(err); + XCTAssertNil([sr runScript:@"/path/that/does/not/exists/foo/bar/baz" + withArgs:nil standardError:&err]); + XCTAssertNil(err); } - (void)testLargeOutput { @@ -379,9 +375,9 @@ // http://code.google.com/p/google-toolbox-for-mac/issues/detail?id=25 GTMScriptRunner *sr = [GTMScriptRunner runnerWithPython]; - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *output = nil, *err = nil, *cmd = nil; - + #define GENERATOR_FORMAT_STR \ @"import sys\n" \ @"block = '.' * 512\n" \ @@ -393,33 +389,33 @@ @" sys.stdout.write(block)\n" \ @" if to_where in [ 'e', 'b' ]:\n" \ @" sys.stderr.write(block)\n" - + // Make sure we get both blocks cmd = [NSString stringWithFormat:GENERATOR_FORMAT_STR, @"'b1'"]; - STAssertNotNil(cmd, nil); + XCTAssertNotNil(cmd); output = [sr run:cmd standardError:&err]; - STAssertEquals([output length], (NSUInteger)512, nil); - STAssertEquals([err length], (NSUInteger)512, nil); - + XCTAssertEqual([output length], (NSUInteger)512); + XCTAssertEqual([err length], (NSUInteger)512); + // Test a large amount of data on only one connections at a time. cmd = [NSString stringWithFormat:GENERATOR_FORMAT_STR, @"'b1', 'o200'"]; - STAssertNotNil(cmd, nil); + XCTAssertNotNil(cmd); output = [sr run:cmd standardError:&err]; - STAssertEquals([output length], (NSUInteger)(512 + 512*200), nil); - STAssertEquals([err length], (NSUInteger)512, nil); + XCTAssertEqual([output length], (NSUInteger)(512 + 512*200)); + XCTAssertEqual([err length], (NSUInteger)512); cmd = [NSString stringWithFormat:GENERATOR_FORMAT_STR, @"'b1', 'e200'"]; - STAssertNotNil(cmd, nil); + XCTAssertNotNil(cmd); output = [sr run:cmd standardError:&err]; - STAssertEquals([output length], (NSUInteger)512, nil); - STAssertEquals([err length], (NSUInteger)(512 + 512*200), nil); + XCTAssertEqual([output length], (NSUInteger)512); + XCTAssertEqual([err length], (NSUInteger)(512 + 512*200)); // Now send a large amount down both to make sure we spool it all in. cmd = [NSString stringWithFormat:GENERATOR_FORMAT_STR, @"'b200'"]; - STAssertNotNil(cmd, nil); + XCTAssertNotNil(cmd); output = [sr run:cmd standardError:&err]; - STAssertEquals([output length], (NSUInteger)(512*200), nil); - STAssertEquals([err length], (NSUInteger)(512*200), nil); + XCTAssertEqual([output length], (NSUInteger)(512*200)); + XCTAssertEqual([err length], (NSUInteger)(512*200)); } @@ -428,44 +424,44 @@ @implementation GTMScriptRunnerTest (PrivateMethods) - (void)helperTestBourneShellUsingScriptRunner:(GTMScriptRunner *)sr { - STAssertNotNil(sr, @"Script runner must not be nil"); + XCTAssertNotNil(sr, @"Script runner must not be nil"); NSString *output = nil; - + // Simple command output = [sr run:@"ls /etc/passwd"]; - STAssertEqualObjects(output, @"/etc/passwd", @"output should equal '/etc/passwd'"); - + XCTAssertEqualObjects(output, @"/etc/passwd", @"output should equal '/etc/passwd'"); + // Simple command pipe-line - output = [sr run:@"ls /etc/ | grep passwd | tail -1"]; - STAssertEqualObjects(output, @"passwd", @"output should equal 'passwd'"); - + output = [sr run:@"ls /etc/ | grep cups | tail -1"]; + XCTAssertEqualObjects(output, @"cups", @"output should equal 'cups'"); + // Simple pipe-line with quotes and awk variables output = [sr run:@"ps jaxww | awk '{print $2}' | sort -nr | tail -2 | head -1"]; - STAssertEqualObjects(output, @"1", @"output should equal '1'"); - + XCTAssertEqualObjects(output, @"1", @"output should equal '1'"); + // Simple shell loop with variables output = [sr run:@"i=0; while [ $i -lt 100 ]; do i=$((i+1)); done; echo $i"]; - STAssertEqualObjects(output, @"100", @"output should equal '100'"); - + XCTAssertEqualObjects(output, @"100", @"output should equal '100'"); + // Simple command with newlines output = [sr run:@"i=1\necho $i"]; - STAssertEqualObjects(output, @"1", @"output should equal '1'"); - + XCTAssertEqualObjects(output, @"1", @"output should equal '1'"); + // Simple full shell script output = [sr run:@"#!/bin/sh\ni=1\necho $i\n"]; - STAssertEqualObjects(output, @"1", @"output should equal '1'"); - + XCTAssertEqualObjects(output, @"1", @"output should equal '1'"); + NSString *err = nil; - + // Test getting standard error with no stdout output = [sr run:@"ls /etc/does-not-exist" standardError:&err]; - STAssertNil(output, @"output should be nil due to expected error"); - STAssertEqualObjects(err, @"ls: /etc/does-not-exist: No such file or directory", @""); - + XCTAssertNil(output, @"output should be nil due to expected error"); + XCTAssertEqualObjects(err, @"ls: /etc/does-not-exist: No such file or directory", @""); + // Test getting standard output along with some standard error output = [sr run:@"ls /etc/does-not-exist /etc/passwd" standardError:&err]; - STAssertEqualObjects(output, @"/etc/passwd", @""); - STAssertEqualObjects(err, @"ls: /etc/does-not-exist: No such file or directory", @""); + XCTAssertEqualObjects(output, @"/etc/passwd", @""); + XCTAssertEqualObjects(err, @"ls: /etc/does-not-exist: No such file or directory", @""); } @end diff --git a/Foundation/GTMServiceManagement.c b/Foundation/GTMServiceManagement.c index 5e41ba0..dfd0dc6 100644 --- a/Foundation/GTMServiceManagement.c +++ b/Foundation/GTMServiceManagement.c @@ -382,8 +382,11 @@ CFTypeRef GTMCFTypeCreateFromLaunchData(launch_data_t ldata, } case LAUNCH_DATA_OPAQUE: { - size_t size = launch_data_get_opaque_size(ldata); + // Must get the data before we get the size. + // Otherwise the size will come back faulty on macOS 10.11.6. + // Radar: 28509492 launch_data_get_opaque_size gives wrong size void *data = launch_data_get_opaque(ldata); + size_t size = launch_data_get_opaque_size(ldata); cf_type_ref = CFDataCreate(kCFAllocatorDefault, data, size); break; } @@ -784,46 +787,4 @@ CFDictionaryRef GTMSMCopyAllJobDictionaries(void) { return dict; } -// Some private SPIs defined by apple in the launchd sources -// http://opensource.apple.com/source/launchd/launchd-258.25/launchd/src/ -// and -// http://opensource.apple.com/source/launchd/launchd-329.3/launchd/src/ -// It turns out that they renamed the enum that I need to use between 10.5 and -// 10.6. Luckily if we request the 10_5 value on 10_6 we get an error -// so we just ask for the 10_5 value first, and then the 10_6 value second. - -typedef enum { - VPROC_GSK_ENVIRONMENT_10_5 = 10, - VPROC_GSK_ENVIRONMENT_10_6 = 11 -} vproc_gsk_t; - -extern vproc_err_t vproc_swap_complex(vproc_t vp, - vproc_gsk_t key, - launch_data_t inval, - launch_data_t *outval); - -CFDictionaryRef GTMCopyLaunchdExports(void) { - launch_data_t resp; - CFDictionaryRef dict = NULL; - vproc_err_t err = vproc_swap_complex(NULL, - VPROC_GSK_ENVIRONMENT_10_5, - NULL, - &resp); - if (err) { - err = vproc_swap_complex(NULL, VPROC_GSK_ENVIRONMENT_10_6, NULL, &resp); - } - if (err == NULL) { - CFErrorRef error = NULL; - dict = GTMCFTypeCreateFromLaunchData(resp, false, &error); - if (error) { -#ifdef DEBUG - CFShow(error); -#endif // DEBUG - CFRelease(error); - } - launch_data_free(resp); - } - return dict; -} - #endif // if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 diff --git a/Foundation/GTMServiceManagement.h b/Foundation/GTMServiceManagement.h index 11fc4b5..aea0cbf 100644 --- a/Foundation/GTMServiceManagement.h +++ b/Foundation/GTMServiceManagement.h @@ -68,10 +68,6 @@ CFTypeRef GTMCFTypeCreateFromLaunchData(launch_data_t ldata, bool convert_non_standard_objects, CFErrorRef *error); -// Returns the list of exports defined by launchd. -// Caller is takes ownership of the returned type. -CFDictionaryRef GTMCopyLaunchdExports(); - GTM_EXTERN_C_END #endif // if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 diff --git a/Foundation/GTMServiceManagementTest.m b/Foundation/GTMServiceManagementTest.m index 95ef0b4..79881f3 100644 --- a/Foundation/GTMServiceManagementTest.m +++ b/Foundation/GTMServiceManagementTest.m @@ -23,7 +23,6 @@ #import "GTMSenTestCase.h" #import <servers/bootstrap.h> -#define STANDARD_JOB_LABEL "com.apple.launchctl.Background" #define OUR_JOB_LABEL "com.google.gtm.GTMServiceManagementTest.job" #define BAD_JOB_LABEL "com.google.gtm.GTMServiceManagementTest.badjob" #define TEST_HARNESS_LABEL "com.google.gtm.GTMServiceManagementTestHarness" @@ -58,68 +57,87 @@ static NSString const *kGTMSocketName nil]; CFErrorRef error = NULL; launch_data_t launchDict = GTMLaunchDataCreateFromCFType(topDict, &error); - STAssertNotNULL(launchDict, nil); - STAssertNULL(error, @"Error: %@", error); + XCTAssertNotNULL(launchDict); + XCTAssertNULL(error, @"Error: %@", error); NSDictionary *nsDict = GTMCFAutorelease(GTMCFTypeCreateFromLaunchData(launchDict, NO, &error)); - STAssertNotNil(nsDict, nil); - STAssertNULL(error, @"Error: %@", error); - STAssertEqualObjects(nsDict, topDict, @""); + XCTAssertNotNil(nsDict); + XCTAssertNULL(error, @"Error: %@", error); + XCTAssertEqualObjects(nsDict, topDict, @""); launch_data_free(launchDict); // Test a bad type NSURL *url = [NSURL URLWithString:@"http://www.google.com"]; - STAssertNotNil(url, nil); + XCTAssertNotNil(url); launchDict = GTMLaunchDataCreateFromCFType(url, &error); - STAssertNULL(launchDict, nil); - STAssertNotNULL(error, nil); - STAssertEqualObjects((id)CFErrorGetDomain(error), - (id)kCFErrorDomainPOSIX, nil); - STAssertEquals(CFErrorGetCode(error), (CFIndex)EINVAL, nil); - CFRelease(error); + XCTAssertNULL(launchDict); + XCTAssertNotNULL(error); + XCTAssertEqualObjects((id)CFErrorGetDomain(error), + (id)kCFErrorDomainPOSIX); + XCTAssertEqual(CFErrorGetCode(error), (CFIndex)EINVAL); + if (error) { + CFRelease(error); + } + CFTypeRef cfType = GTMCFTypeCreateFromLaunchData(NULL, YES, &error); - STAssertNULL(cfType, nil); - STAssertNotNULL(error, nil); - CFRelease(error); + XCTAssertNULL(cfType); + XCTAssertNotNULL(error); + if (error) { + CFRelease(error); + } } - (void)testJobDictionaries { NSDictionary *jobs = GTMCFAutorelease(GTMSMCopyAllJobDictionaries()); - STAssertNotNil(jobs, nil); - // A job that should always be around + XCTAssertNotNil(jobs); + + // Grab an existing job + NSString *jobName = [[jobs allKeys] objectAtIndex:0]; NSDictionary *job - = GTMCFAutorelease(GTMSMJobCopyDictionary(CFSTR(STANDARD_JOB_LABEL))); - STAssertNotNil(job, nil); + = GTMCFAutorelease(GTMSMJobCopyDictionary((CFStringRef)jobName)); + XCTAssertNotNil(job); // A job that should never be around CFTypeRef type = GTMSMJobCopyDictionary(CFSTR(BAD_JOB_LABEL)); - STAssertNULL(type, nil); + XCTAssertNULL(type); } - (void)testLaunching { CFErrorRef error = NULL; Boolean isGood = GTMSMJobSubmit(NULL, &error); - STAssertFalse(isGood, nil); - STAssertNotNULL(error, nil); - CFRelease(error); + XCTAssertFalse(isGood); + XCTAssertNotNULL(error); + if (error) { + CFRelease(error); + } + NSDictionary *empty = [NSDictionary dictionary]; isGood = GTMSMJobSubmit((CFDictionaryRef)empty, &error); - STAssertFalse(isGood, nil); - STAssertNotNULL(error, nil); - CFRelease(error); + XCTAssertFalse(isGood); + XCTAssertNotNULL(error); + if (error) { + CFRelease(error); + } + + // Grab an existing job + NSDictionary *jobs = GTMCFAutorelease(GTMSMCopyAllJobDictionaries()); + XCTAssertNotNil(jobs); + NSString *jobName = [[jobs allKeys] objectAtIndex:0]; NSDictionary *alreadyThere - = [NSDictionary dictionaryWithObject:@STANDARD_JOB_LABEL + = [NSDictionary dictionaryWithObject:jobName forKey:@LAUNCH_JOBKEY_LABEL]; isGood = GTMSMJobSubmit((CFDictionaryRef)alreadyThere, &error); - STAssertFalse(isGood, nil); - STAssertEquals([(NSError *)error code], (NSInteger)EEXIST, nil); - CFRelease(error); + XCTAssertFalse(isGood); + XCTAssertEqual([(NSError *)error code], (NSInteger)EEXIST); + if (error) { + CFRelease(error); + } NSDictionary *goodJob = [NSDictionary dictionaryWithObjectsAndKeys: @@ -127,26 +145,20 @@ static NSString const *kGTMSocketName @"/bin/test", @LAUNCH_JOBKEY_PROGRAM, nil]; isGood = GTMSMJobSubmit((CFDictionaryRef)goodJob, &error); - STAssertTrue(isGood, nil); - STAssertNULL(error, nil); + XCTAssertTrue(isGood); + XCTAssertNULL(error); isGood = GTMSMJobRemove(CFSTR(OUR_JOB_LABEL), &error); - STAssertTrue(isGood, - @"You may need to run launchctl remove %s", OUR_JOB_LABEL); - STAssertNULL(error, nil); + XCTAssertTrue(isGood, + @"You may need to run launchctl remove %s", OUR_JOB_LABEL); + XCTAssertNULL(error); isGood = GTMSMJobRemove(CFSTR(OUR_JOB_LABEL), &error); - STAssertFalse(isGood, nil); - STAssertNotNULL(error, nil); - CFRelease(error); -} - -- (void)testCopyExports { - CFDictionaryRef exports = GTMCopyLaunchdExports(); - STAssertNotNULL(exports, nil); - NSString *user = [(NSDictionary *)exports objectForKey:@"USER"]; - STAssertEqualObjects(user, NSUserName(), nil); - CFRelease(exports); + XCTAssertFalse(isGood); + XCTAssertNotNULL(error); + if (error) { + CFRelease(error); + } } - (void)testCheckin { @@ -154,16 +166,19 @@ static NSString const *kGTMSocketName // Can't check ourselves in NSDictionary *badTest = GTMCFAutorelease(GTMSMCopyJobCheckInDictionary(&error)); - STAssertNil(badTest, nil); - STAssertNotNULL(error, nil); - CFRelease(error); + XCTAssertNil(badTest); + XCTAssertNotNULL(error); + if (error) { + CFRelease(error); + } + NSBundle *testBundle = [NSBundle bundleForClass:[self class]]; - STAssertNotNil(testBundle, nil); + XCTAssertNotNil(testBundle); NSString *testHarnessPath = [testBundle pathForResource:@"GTMServiceManagementTestingHarness" ofType:nil]; - STAssertNotNil(testHarnessPath, nil); + XCTAssertNotNil(testHarnessPath); NSDictionary *machServices = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], @GTM_MACH_PORT_NAME, @@ -195,22 +210,7 @@ static NSString const *kGTMSocketName GTMSMJobRemove(CFSTR(TEST_HARNESS_LABEL), NULL); BOOL isGood = GTMSMJobSubmit((CFDictionaryRef)job, &error); - STAssertTrue(isGood, @"Error %@", error); - - NSDictionary* exports = GTMCFAutorelease(GTMCopyLaunchdExports()); - STAssertNotNULL(exports, nil); - NSString *socketPath = [exports objectForKey:kGTMSocketKey]; - STAssertNotNULL(socketPath, nil); - STAssertEqualObjects([socketPath lastPathComponent], kGTMSocketName, nil); - - mach_port_t sp = 0; - kern_return_t rt = bootstrap_look_up(bootstrap_port, - (char*)GTM_MACH_PORT_NAME, - &sp); - STAssertNotEquals(sp, (mach_port_t)0, nil); - STAssertEquals(rt, KERN_SUCCESS, nil); - isGood = GTMSMJobRemove(CFSTR(TEST_HARNESS_LABEL), &error); - STAssertTrue(isGood, @"Error %@", error); + XCTAssertTrue(isGood, @"Error %@", error); } @end diff --git a/Foundation/GTMSignalHandlerTest.m b/Foundation/GTMSignalHandlerTest.m index 5cddcb5..bd70ecf 100644 --- a/Foundation/GTMSignalHandlerTest.m +++ b/Foundation/GTMSignalHandlerTest.m @@ -18,7 +18,6 @@ #import "GTMSenTestCase.h" #import "GTMSignalHandler.h" -#import "GTMUnitTestDevLog.h" #import "GTMFoundationUnitTestingUtilities.h" @interface GTMSignalHandlerTest : GTMTestCase @@ -66,56 +65,54 @@ @implementation GTMSignalHandlerTest - (void)nomnomnom:(int)blah { - STFail(@"Should never be called!"); + XCTFail(@"Should never be called!"); } - (void)testNillage { GTMSignalHandler *handler; // Just an init should return nil. - [GTMUnitTestDevLog expectString:@"Don't call init, use " - @"initWithSignal:target:action:"]; handler = [[[GTMSignalHandler alloc] init] autorelease]; - STAssertNil(handler, nil); + XCTAssertNil(handler); // Zero signal should return nil as well. handler = [[[GTMSignalHandler alloc] initWithSignal:0 target:self action:@selector(nomnomnom:)] autorelease]; - STAssertNil(handler, nil); + XCTAssertNil(handler); } - (void)testSingleHandler { SignalCounter *counter = [SignalCounter signalCounter]; - STAssertNotNil(counter, nil); + XCTAssertNotNil(counter); GTMSignalHandler *handler = [[[GTMSignalHandler alloc] initWithSignal:SIGWINCH target:counter action:@selector(countSignal:)] autorelease]; - STAssertNotNil(handler, nil); + XCTAssertNotNil(handler); raise(SIGWINCH); NSRunLoop *rl = [NSRunLoop currentRunLoop]; [rl gtm_runUpToSixtySecondsWithContext:counter]; - STAssertEquals([counter count], 1, nil); - STAssertEquals([counter lastSeen], SIGWINCH, nil); + XCTAssertEqual([counter count], 1); + XCTAssertEqual([counter lastSeen], SIGWINCH); [counter resetShouldStop]; raise(SIGWINCH); [rl gtm_runUpToSixtySecondsWithContext:counter]; - STAssertEquals([counter count], 2, nil); - STAssertEquals([counter lastSeen], SIGWINCH, nil); + XCTAssertEqual([counter count], 2); + XCTAssertEqual([counter lastSeen], SIGWINCH); [counter resetShouldStop]; // create a second one to make sure we're seding data where we want SignalCounter *counter2 = [SignalCounter signalCounter]; - STAssertNotNil(counter2, nil); + XCTAssertNotNil(counter2); [[[GTMSignalHandler alloc] initWithSignal:SIGUSR1 target:counter2 action:@selector(countSignal:)] autorelease]; @@ -123,10 +120,10 @@ raise(SIGUSR1); [rl gtm_runUpToSixtySecondsWithContext:counter2]; - STAssertEquals([counter count], 2, nil); - STAssertEquals([counter lastSeen], SIGWINCH, nil); - STAssertEquals([counter2 count], 1, nil); - STAssertEquals([counter2 lastSeen], SIGUSR1, nil); + XCTAssertEqual([counter count], 2); + XCTAssertEqual([counter lastSeen], SIGWINCH); + XCTAssertEqual([counter2 count], 1); + XCTAssertEqual([counter2 lastSeen], SIGUSR1); [handler invalidate]; @@ -135,16 +132,16 @@ raise(SIGWINCH); [rl runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.2]]; - STAssertEquals([counter count], 2, nil); - STAssertEquals([counter lastSeen], SIGWINCH, nil); - STAssertEquals([counter2 count], 1, nil); - STAssertEquals([counter2 lastSeen], SIGUSR1, nil); + XCTAssertEqual([counter count], 2); + XCTAssertEqual([counter lastSeen], SIGWINCH); + XCTAssertEqual([counter2 count], 1); + XCTAssertEqual([counter2 lastSeen], SIGUSR1); } - (void)testIgnore { SignalCounter *counter = [SignalCounter signalCounter]; - STAssertNotNil(counter, nil); + XCTAssertNotNil(counter); [[[GTMSignalHandler alloc] initWithSignal:SIGUSR1 target:counter @@ -153,7 +150,7 @@ raise(SIGUSR1); NSRunLoop *rl = [NSRunLoop currentRunLoop]; [rl runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.2]]; - STAssertEquals([counter count], 0, nil); + XCTAssertEqual([counter count], 0); } diff --git a/Foundation/GTMStackTrace.h b/Foundation/GTMStackTrace.h index eb86a66..61398ab 100644 --- a/Foundation/GTMStackTrace.h +++ b/Foundation/GTMStackTrace.h @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -32,10 +32,10 @@ struct GTMAddressDescriptor { }; // Returns a string containing a nicely formatted stack trace. -// +// // This function gets the stack trace for the current thread. It will // be from the caller of GTMStackTrace upwards to the top the calling stack. -// Typically this function will be used along with some logging, +// Typically this function will be used along with some logging, // as in the following: // // MyAppLogger(@"Should never get here:\n%@", GTMStackTrace()); @@ -53,41 +53,18 @@ struct GTMAddressDescriptor { NSString *GTMStackTrace(void); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 || \ - __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_2_0 // Returns a string containing a nicely formatted stack trace from the -// exception. Only available on 10.5 or later, uses +// exception. Only available on 10.5 or later, uses // -[NSException callStackReturnAddresses]. // NSString *GTMStackTraceFromException(NSException *e); -#endif - -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 -// Returns an array of program counters from the current thread's stack. -// *** You should probably use GTMStackTrace() instead of this function *** -// However, if you actually want all the PCs in "void *" form, then this -// funtion is more convenient. This will include PCs of GTMStaceTrace and -// its inner utility functions that you may want to strip out. -// -// You can use +[NSThread callStackReturnAddresses] in 10.5 or later. -// -// Args: -// outPcs - an array of "void *" pointers to the program counters found on the -// current thread's stack. -// count - the number of entries in the outPcs array -// -// Returns: -// The number of program counters actually added to outPcs. -// -NSUInteger GTMGetStackProgramCounters(void *outPcs[], NSUInteger count); -#endif // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 // Returns an array of GTMAddressDescriptors from the current thread's stack. // *** You should probably use GTMStackTrace() instead of this function *** // However, if you actually want all the PCs with symbols, this is the way // to get them. There is no memory allocations done, so no clean up is required // except for the caller to free outDescs if they allocated it themselves. -// This will include PCs of GTMStaceTrace and its inner utility functions that +// This will include PCs of GTMStaceTrace and its inner utility functions that // you may want to strip out. // // Args: @@ -98,7 +75,7 @@ NSUInteger GTMGetStackProgramCounters(void *outPcs[], NSUInteger count); // Returns: // The number of program counters actually added to outPcs. // -NSUInteger GTMGetStackAddressDescriptors(struct GTMAddressDescriptor outDescs[], +NSUInteger GTMGetStackAddressDescriptors(struct GTMAddressDescriptor outDescs[], NSUInteger count); #ifdef __cplusplus diff --git a/Foundation/GTMStackTrace.m b/Foundation/GTMStackTrace.m index 3e34ed0..4470a11 100644 --- a/Foundation/GTMStackTrace.m +++ b/Foundation/GTMStackTrace.m @@ -19,8 +19,9 @@ #include <stdlib.h> #include <dlfcn.h> #include <mach-o/nlist.h> +#include <objc/runtime.h> + #include "GTMStackTrace.h" -#include "GTMObjC2Runtime.h" struct GTMClassDescription { const char *class_name; @@ -202,73 +203,10 @@ static NSString *GTMStackTraceFromAddressDescriptors(struct GTMAddressDescriptor #pragma mark Public functions -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 -// Before 10.5, we have to do this ourselves. 10.5 adds -// +[NSThread callStackReturnAddresses]. - -// Structure representing a small portion of a stack, starting from the saved -// frame pointer, and continuing through the saved program counter. -struct GTMStackFrame { - void *saved_fp; -#if defined (__ppc__) || defined(__ppc64__) - void *padding; -#endif - void *saved_pc; -}; - -// __builtin_frame_address(0) is a gcc builtin that returns a pointer to the -// current frame pointer. We then use the frame pointer to walk the stack -// picking off program counters and other saved frame pointers. This works -// great on i386, but PPC requires a little more work because the PC (or link -// register) isn't always stored on the stack. -// -NSUInteger GTMGetStackProgramCounters(void *outPcs[], NSUInteger count) { - if (!outPcs || (count < 1)) return 0; - - struct GTMStackFrame *fp; -#if defined (__ppc__) || defined(__ppc64__) - outPcs[0] = __builtin_return_address(0); - fp = (struct GTMStackFrame *)__builtin_frame_address(1); -#elif defined (__i386__) || defined(__x86_64__) - fp = (struct GTMStackFrame *)__builtin_frame_address(0); -#else -#error architecture not supported -#endif - - NSUInteger level = 0; - while (level < count) { - if (fp == NULL) { - level--; - break; - } - outPcs[level] = fp->saved_pc; - level++; - fp = (struct GTMStackFrame *)fp->saved_fp; - } - - return level; -} -#endif // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - NSUInteger GTMGetStackAddressDescriptors(struct GTMAddressDescriptor outDescs[], NSUInteger count) { if (count < 1 || !outDescs) return 0; NSUInteger result = 0; - -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - // Before 10.5, we collect the stack ourselves. - - void **pcs = calloc(count, sizeof(void*)); - if (!pcs) return 0; - - NSUInteger newSize = GTMGetStackProgramCounters(pcs, count); - - result = GTMGetStackAddressDescriptorsForAddresses(pcs, outDescs, newSize); - free(pcs); - -#else // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - // Use +[NSThread callStackReturnAddresses] - NSArray *addresses = [NSThread callStackReturnAddresses]; NSUInteger addrCount = [addresses count]; if (addrCount) { @@ -288,7 +226,6 @@ NSUInteger GTMGetStackAddressDescriptors(struct GTMAddressDescriptor outDescs[], } free(pcs); } -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 return result; } @@ -296,27 +233,6 @@ NSUInteger GTMGetStackAddressDescriptors(struct GTMAddressDescriptor outDescs[], NSString *GTMStackTrace(void) { // If we don't have enough frames, return an empty string NSString *result = @""; - -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - // Before 10.5, we collect the stack ourselves. - - // The maximum number of stack frames that we will walk. We limit this so - // that super-duper recursive functions (or bugs) don't send us for an - // infinite loop. - struct GTMAddressDescriptor descs[100]; - size_t depth = sizeof(descs) / sizeof(struct GTMAddressDescriptor); - depth = GTMGetStackAddressDescriptors(descs, depth); - - // Start at the second item so that GTMStackTrace and it's utility calls (of - // which there is currently 1) is not included in the output. - const size_t kTracesToStrip = 2; - if (depth > kTracesToStrip) { - result = GTMStackTraceFromAddressDescriptors(&descs[kTracesToStrip], - (depth - kTracesToStrip)); - } -#else // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - // Use +[NSThread callStackReturnAddresses] - NSArray *addresses = [NSThread callStackReturnAddresses]; NSUInteger count = [addresses count]; if (count) { @@ -344,14 +260,10 @@ NSString *GTMStackTrace(void) { free(pcs); free(descs); } -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 return result; } -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 || \ - (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ - (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_2_0)) NSString *GTMStackTraceFromException(NSException *e) { NSString *trace = @""; @@ -382,5 +294,3 @@ NSString *GTMStackTraceFromException(NSException *e) { return trace; } -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - //__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_2_0 diff --git a/Foundation/GTMStackTraceTest.m b/Foundation/GTMStackTraceTest.m index a581c76..7b1c038 100644 --- a/Foundation/GTMStackTraceTest.m +++ b/Foundation/GTMStackTraceTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -36,27 +36,27 @@ NSString *stacktrace = GTMStackTrace(); NSArray *stacklines = [stacktrace componentsSeparatedByString:@"\n"]; - STAssertGreaterThan([stacklines count], (NSUInteger)3, - @"stack trace must have > 3 lines"); - STAssertLessThan([stacklines count], (NSUInteger)35, - @"stack trace must have < 35 lines"); - + XCTAssertGreaterThan([stacklines count], (NSUInteger)3, + @"stack trace must have > 3 lines"); + XCTAssertLessThan([stacklines count], (NSUInteger)35, + @"stack trace must have < 35 lines"); + NSString *firstFrame = [stacklines objectAtIndex:0]; NSRange range = [firstFrame rangeOfString:@"testStackTraceBasic"]; - STAssertNotEquals(range.location, (NSUInteger)NSNotFound, + XCTAssertNotEqual(range.location, (NSUInteger)NSNotFound, @"First frame should contain testStackTraceBasic," " stack trace: %@", stacktrace); range = [firstFrame rangeOfString:@"#0"]; - STAssertNotEquals(range.location, (NSUInteger)NSNotFound, - @"First frame should contain #0, stack trace: %@", + XCTAssertNotEqual(range.location, (NSUInteger)NSNotFound, + @"First frame should contain #0, stack trace: %@", stacktrace); - + range = [firstFrame rangeOfString:@"-"]; - STAssertNotEquals(range.location, (NSUInteger)NSNotFound, + XCTAssertNotEqual(range.location, (NSUInteger)NSNotFound, @"First frame should contain - since it's " @"an instance method: %@", stacktrace); - STAssertTrue([[self class] classMethodTest], @"First frame should contain" - @"+ since it's a class method"); + XCTAssertTrue([[self class] classMethodTest], @"First frame should contain" + @"+ since it's a class method"); } -(void)testGetStackAddressDescriptors { @@ -64,28 +64,26 @@ size_t depth = sizeof(descs) / sizeof(struct GTMAddressDescriptor); depth = GTMGetStackAddressDescriptors(descs, depth); // Got atleast 4... - STAssertGreaterThan(depth, (size_t)4, nil); + XCTAssertGreaterThan(depth, (size_t)4); // All that we got have symbols for (NSUInteger lp = 0 ; lp < depth ; ++lp) { - STAssertNotNULL(descs[lp].symbol, @"didn't get a symbol at depth %lu", - (unsigned long)lp); + XCTAssertNotNULL(descs[lp].symbol, @"didn't get a symbol at depth %lu", + (unsigned long)lp); } - + // Do it again, but don't give it enough space (to make sure it handles that) size_t fullDepth = depth; - STAssertGreaterThan(fullDepth, (size_t)4, nil); + XCTAssertGreaterThan(fullDepth, (size_t)4); depth -= 2; depth = GTMGetStackAddressDescriptors(descs, depth); - STAssertLessThan(depth, fullDepth, nil); + XCTAssertLessThan(depth, fullDepth); // All that we got have symbols for (NSUInteger lp = 0 ; lp < depth ; ++lp) { - STAssertNotNULL(descs[lp].symbol, @"didn't get a symbol at depth %lu", - (unsigned long)lp); + XCTAssertNotNULL(descs[lp].symbol, @"didn't get a symbol at depth %lu", + (unsigned long)lp); } - -} -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 +} - (void)helperThatThrows { [NSException raise:@"TestException" format:@"TestExceptionDescription"]; @@ -99,67 +97,25 @@ @catch (NSException * e) { exception = e; } - STAssertNotNil(exception, nil); + XCTAssertNotNil(exception); NSString *stacktrace = GTMStackTraceFromException(exception); NSArray *stacklines = [stacktrace componentsSeparatedByString:@"\n"]; - - STAssertGreaterThan([stacklines count], (NSUInteger)4, - @"stack trace must have > 4 lines"); - STAssertLessThan([stacklines count], (NSUInteger)35, - @"stack trace must have < 35 lines"); - STAssertEquals([stacklines count], + + XCTAssertGreaterThan([stacklines count], (NSUInteger)4, + @"stack trace must have > 4 lines\n%@", stacktrace); + XCTAssertLessThan([stacklines count], (NSUInteger)40, + @"stack trace must have < 40 lines\n%@", stacktrace); + XCTAssertEqual([stacklines count], [[exception callStackReturnAddresses] count], @"stack trace should have the same number of lines as the " @" array of return addresses. stack trace: %@", stacktrace); - + // we can't look for it on a specific frame because NSException doesn't // really document how deep the stack will be NSRange range = [stacktrace rangeOfString:@"testStackExceptionTrace"]; - STAssertNotEquals(range.location, (NSUInteger)NSNotFound, + XCTAssertNotEqual(range.location, (NSUInteger)NSNotFound, @"Stack trace should contain testStackExceptionTrace," " stack trace: %@", stacktrace); } -#endif - -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - -- (void)testProgramCountersBasic { - void *pcs[10]; - NSUInteger depth = 10; - depth = GTMGetStackProgramCounters(pcs, depth); - - STAssertGreaterThan(depth, (NSUInteger)3, @"stack trace must have > 3 lines"); - STAssertLessThanOrEqual(depth, (NSUInteger)10, - @"stack trace must have < 10 lines"); - - // pcs is an array of program counters from the stack. pcs[0] should match - // the call into GTMGetStackProgramCounters, which is tough for us to check. - // However, we can verify that pcs[1] is equal to our current return address - // for our current function. - void *current_pc = __builtin_return_address(0); - STAssertEquals(pcs[1], current_pc, @"pcs[1] should equal the current PC"); -} - -- (void)testProgramCountersMore { - void *pcs0[0]; - NSUInteger depth0 = 0; - depth0 = GTMGetStackProgramCounters(pcs0, depth0); - STAssertEquals(depth0, (NSUInteger)0, @"stack trace must have 0 lines"); - - void *pcs1[1]; - NSUInteger depth1 = 1; - depth1 = GTMGetStackProgramCounters(pcs1, depth1); - STAssertEquals(depth1, (NSUInteger)1, @"stack trace must have 1 lines"); - - void *pcs2[2]; - NSUInteger depth2 = 2; - depth2 = GTMGetStackProgramCounters(pcs2, depth2); - STAssertEquals(depth2, (NSUInteger)2, @"stack trace must have 2 lines"); - void *current_pc = __builtin_return_address(0); - STAssertEquals(pcs2[1], current_pc, @"pcs[1] should equal the current PC"); -} - -#endif // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 - @end diff --git a/Foundation/GTMStringEncoding.h b/Foundation/GTMStringEncoding.h index b74f2d9..24fa0bc 100644 --- a/Foundation/GTMStringEncoding.h +++ b/Foundation/GTMStringEncoding.h @@ -78,11 +78,35 @@ - (void)setPaddingChar:(char)c; // Encode a raw binary buffer to a 7-bit ASCII string. -- (NSString *)encode:(NSData *)data; -- (NSString *)encodeString:(NSString *)string; +- (NSString *)encode:(NSData *)data __attribute__((deprecated("Use encode:error:"))); +- (NSString *)encodeString:(NSString *)string __attribute__((deprecated("Use encodeString:error:"))); + +- (NSString *)encode:(NSData *)data error:(NSError **)error; +- (NSString *)encodeString:(NSString *)string error:(NSError **)error; // Decode a 7-bit ASCII string to a raw binary buffer. -- (NSData *)decode:(NSString *)string; -- (NSString *)stringByDecoding:(NSString *)string; +- (NSData *)decode:(NSString *)string __attribute__((deprecated("Use decode:error:"))); +- (NSString *)stringByDecoding:(NSString *)string __attribute__((deprecated("Use stringByDecoding:error:"))); + +- (NSData *)decode:(NSString *)string error:(NSError **)error; +- (NSString *)stringByDecoding:(NSString *)string error:(NSError **)error; @end + +FOUNDATION_EXPORT NSString *const GTMStringEncodingErrorDomain; +FOUNDATION_EXPORT NSString *const GTMStringEncodingBadCharacterIndexKey; // NSNumber + +typedef NS_ENUM(NSInteger, GTMStringEncodingError) { + // Unable to convert a buffer to NSASCIIStringEncoding. + GTMStringEncodingErrorUnableToConverToAscii = 1024, + // Unable to convert a buffer to NSUTF8StringEncoding. + GTMStringEncodingErrorUnableToConverToUTF8, + // Encountered a bad character. + // GTMStringEncodingBadCharacterIndexKey will have the index of the character. + GTMStringEncodingErrorUnknownCharacter, + // The data had a padding character in the middle of the data. Padding characters + // can only be at the end. + GTMStringEncodingErrorExpectedPadding, + // There is unexpected data at the end of the data that could not be decoded. + GTMStringEncodingErrorIncompleteTrailingData, +}; diff --git a/Foundation/GTMStringEncoding.m b/Foundation/GTMStringEncoding.m index 1cd6352..7578e86 100644 --- a/Foundation/GTMStringEncoding.m +++ b/Foundation/GTMStringEncoding.m @@ -18,6 +18,9 @@ #import "GTMStringEncoding.h" +NSString *const GTMStringEncodingErrorDomain = @"com.google.GTMStringEncodingErrorDomain"; +NSString *const GTMStringEncodingBadCharacterIndexKey = @"GTMStringEncodingBadCharacterIndexKey"; + enum { kUnknownChar = -1, kPaddingChar = -2, @@ -174,9 +177,12 @@ GTM_INLINE int lcm(int a, int b) { } - (NSString *)encode:(NSData *)inData { + return [self encode:inData error:NULL]; +} + +- (NSString *)encode:(NSData *)inData error:(NSError **)error { NSUInteger inLen = [inData length]; if (inLen <= 0) { - _GTMDevLog(@"Empty input"); return @""; } unsigned char *inBuf = (unsigned char *)[inData bytes]; @@ -214,21 +220,52 @@ GTM_INLINE int lcm(int a, int b) { outBuf[outPos++] = paddingChar_; } - _GTMDevAssert(outPos == outLen, @"Underflowed output buffer"); [outData setLength:outPos]; - return [[[NSString alloc] initWithData:outData - encoding:NSASCIIStringEncoding] autorelease]; + NSString *value = [[[NSString alloc] initWithData:outData + encoding:NSASCIIStringEncoding] autorelease]; + if (!value) { + if (error) { + *error = [NSError errorWithDomain:GTMStringEncodingErrorDomain + code:GTMStringEncodingErrorUnableToConverToAscii + userInfo:nil]; + + } + } + return value; } - (NSString *)encodeString:(NSString *)inString { - return [self encode:[inString dataUsingEncoding:NSUTF8StringEncoding]]; + return [self encodeString:inString error:NULL]; +} + +- (NSString *)encodeString:(NSString *)inString error:(NSError **)error { + NSData *data = [inString dataUsingEncoding:NSUTF8StringEncoding]; + if (!data) { + if (error) { + *error = [NSError errorWithDomain:GTMStringEncodingErrorDomain + code:GTMStringEncodingErrorUnableToConverToUTF8 + userInfo:nil]; + + } + return nil; + } + return [self encode:data error:error]; } - (NSData *)decode:(NSString *)inString { + return [self decode:inString error:NULL]; +} + +- (NSData *)decode:(NSString *)inString error:(NSError **)error { char *inBuf = (char *)[inString cStringUsingEncoding:NSASCIIStringEncoding]; if (!inBuf) { - _GTMDevLog(@"unable to convert buffer to ASCII"); + if (error) { + *error = [NSError errorWithDomain:GTMStringEncodingErrorDomain + code:GTMStringEncodingErrorUnableToConverToAscii + userInfo:nil]; + + } return nil; } NSUInteger inLen = strlen(inBuf); @@ -249,12 +286,27 @@ GTM_INLINE int lcm(int a, int b) { case kPaddingChar: expectPad = YES; break; - case kUnknownChar: - _GTMDevLog(@"Unexpected data in input pos %lu", (unsigned long)i); + case kUnknownChar: { + if (error) { + NSDictionary *userInfo = + [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInteger:i] + forKey:GTMStringEncodingBadCharacterIndexKey]; + *error = [NSError errorWithDomain:GTMStringEncodingErrorDomain + code:GTMStringEncodingErrorUnknownCharacter + userInfo:userInfo]; + } return nil; + } default: if (expectPad) { - _GTMDevLog(@"Expected further padding characters"); + if (error) { + NSDictionary *userInfo = + [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInteger:i] + forKey:GTMStringEncodingBadCharacterIndexKey]; + *error = [NSError errorWithDomain:GTMStringEncodingErrorDomain + code:GTMStringEncodingErrorExpectedPadding + userInfo:userInfo]; + } return nil; } buffer <<= shift_; @@ -269,21 +321,33 @@ GTM_INLINE int lcm(int a, int b) { } if (bitsLeft && buffer & ((1 << bitsLeft) - 1)) { - _GTMDevLog(@"Incomplete trailing data"); + if (error) { + *error = [NSError errorWithDomain:GTMStringEncodingErrorDomain + code:GTMStringEncodingErrorIncompleteTrailingData + userInfo:nil]; + + } return nil; } // Shorten buffer if needed due to padding chars - _GTMDevAssert(outPos <= outLen, @"Overflowed buffer"); [outData setLength:outPos]; return outData; } - (NSString *)stringByDecoding:(NSString *)inString { - NSData *ret = [self decode:inString]; - return [[[NSString alloc] initWithData:ret - encoding:NSUTF8StringEncoding] autorelease]; + return [self stringByDecoding:inString error:NULL]; +} + +- (NSString *)stringByDecoding:(NSString *)inString error:(NSError **)error { + NSData *ret = [self decode:inString error:error]; + NSString *value = nil; + if (ret) { + value = [[[NSString alloc] initWithData:ret + encoding:NSUTF8StringEncoding] autorelease]; + } + return value; } @end diff --git a/Foundation/GTMStringEncodingTest.m b/Foundation/GTMStringEncodingTest.m index e2cada7..2e843d6 100644 --- a/Foundation/GTMStringEncodingTest.m +++ b/Foundation/GTMStringEncodingTest.m @@ -18,7 +18,6 @@ #import "GTMSenTestCase.h" #import "GTMStringEncoding.h" -#import "GTMUnitTestDevLog.h" @interface GTMStringEncodingTest : GTMTestCase @end @@ -29,22 +28,31 @@ - (void)testEmptyInputs { GTMStringEncoding *coder = [GTMStringEncoding stringEncodingWithString:@"01"]; - [GTMUnitTestDevLog expectString:@"Empty input"]; - STAssertEqualStrings([coder encode:[NSData data]], @"", nil); - [GTMUnitTestDevLog expectString:@"Empty input"]; - STAssertEqualObjects([coder encodeString:@""], @"", nil); - STAssertEqualObjects([coder decode:@""], [NSData data], nil); - STAssertEqualStrings([coder stringByDecoding:@""], @"", nil); + NSError *error = nil; + XCTAssertEqualStrings([coder encode:[NSData data] error:&error], @""); + XCTAssertNil(error); + error = nil; + XCTAssertEqualObjects([coder encodeString:@"" error:&error], @""); + XCTAssertNil(error); + error = nil; + XCTAssertEqualObjects([coder decode:@"" error:&error], [NSData data]); + XCTAssertNil(error); + error = nil; + XCTAssertEqualStrings([coder stringByDecoding:@"" error:&error], @""); + XCTAssertNil(error); } // Invalid inputs should result in nil outputs. - (void)testInvalidInputs { GTMStringEncoding *coder = [GTMStringEncoding stringEncodingWithString:@"01"]; - - [GTMUnitTestDevLog expectString:@"unable to convert buffer to ASCII"]; - STAssertNil([coder decode:nil], nil); - [GTMUnitTestDevLog expectString:@"Unexpected data in input pos 0"]; - STAssertNil([coder decode:@"banana"], nil); + NSError *error = nil; + + XCTAssertNil([coder decode:nil error:&error]); + XCTAssertEqual([error code], GTMStringEncodingErrorUnableToConverToAscii); + XCTAssertNil([coder decode:@"banana" error:&error]); + XCTAssertEqual([error code], GTMStringEncodingErrorUnknownCharacter); + XCTAssertEqualObjects([[error userInfo] objectForKey:GTMStringEncodingBadCharacterIndexKey], + [NSNumber numberWithUnsignedInteger:0]); } // Ignored inputs should be silently ignored. @@ -54,27 +62,42 @@ char aa = 0xaa; NSData *aaData = [NSData dataWithBytes:&aa length:sizeof(aa)]; - STAssertEqualObjects([coder decode:@"10101010"], aaData, nil); + NSError *error = nil; + XCTAssertEqualObjects([coder decode:@"10101010" error:&error], aaData); + XCTAssertNil(error); + error = nil; // Inputs with ignored characters - STAssertEqualObjects([coder decode:@"1010 1010"], aaData, nil); - STAssertEqualObjects([coder decode:@"1010-1010"], aaData, nil); - STAssertEqualObjects([coder decode:@"1010\n1010"], aaData, nil); + XCTAssertEqualObjects([coder decode:@"1010 1010" error:&error], aaData); + XCTAssertNil(error); + error = nil; + XCTAssertEqualObjects([coder decode:@"1010-1010" error:&error], aaData); + XCTAssertNil(error); + error = nil; + XCTAssertEqualObjects([coder decode:@"1010\n1010" error:&error], aaData); + XCTAssertNil(error); + error = nil; // Invalid inputs - [GTMUnitTestDevLog expectString:@"Unexpected data in input pos 4"]; - STAssertNil([coder decode:@"1010+1010"], nil); + XCTAssertNil([coder decode:@"1010+1010" error:&error]); + XCTAssertEqual([error code], GTMStringEncodingErrorUnknownCharacter); + XCTAssertEqualObjects([[error userInfo] objectForKey:GTMStringEncodingBadCharacterIndexKey], + [NSNumber numberWithUnsignedInteger:4]); } #define ASSERT_ENCODE_DECODE_STRING(coder, decoded, encoded) do { \ - STAssertEqualStrings([coder encodeString:decoded], encoded, nil); \ - STAssertEqualStrings([coder stringByDecoding:encoded], decoded, nil); \ + XCTAssertEqualStrings([coder encodeString:decoded error:&error], encoded); \ + XCTAssertNil(error); \ + error = nil; \ + XCTAssertEqualStrings([coder stringByDecoding:encoded error:&error], decoded); \ + XCTAssertNil(error); \ + error = nil; \ } while (0) - (void)testBinary { GTMStringEncoding *coder = [GTMStringEncoding binaryStringEncoding]; + NSError *error = nil; - [GTMUnitTestDevLog expectString:@"Empty input"]; ASSERT_ENCODE_DECODE_STRING(coder, @"", @""); ASSERT_ENCODE_DECODE_STRING(coder, @"f", @"01100110"); ASSERT_ENCODE_DECODE_STRING(coder, @"fo", @"0110011001101111"); @@ -122,15 +145,18 @@ NSData *allValuesData = [NSData dataWithBytes:&allValuesBytes length:sizeof(allValuesBytes)]; - STAssertEqualObjects([coder decode:allValues], allValuesData, nil); - STAssertEqualStrings([coder encode:allValuesData], allValues, nil); + XCTAssertEqualObjects([coder decode:allValues error:&error], allValuesData); + XCTAssertNil(error); + error = nil; + XCTAssertEqualStrings([coder encode:allValuesData error:&error], allValues); + XCTAssertNil(error); } - (void)testBase64 { // RFC4648 test vectors GTMStringEncoding *coder = [GTMStringEncoding rfc4648Base64StringEncoding]; + NSError *error = nil; - [GTMUnitTestDevLog expectString:@"Empty input"]; ASSERT_ENCODE_DECODE_STRING(coder, @"", @""); ASSERT_ENCODE_DECODE_STRING(coder, @"f", @"Zg=="); ASSERT_ENCODE_DECODE_STRING(coder, @"fo", @"Zm8="); @@ -153,8 +179,11 @@ NSData *allValuesData = [NSData dataWithBytes:&allValuesBytes length:sizeof(allValuesBytes)]; - STAssertEqualObjects([coder decode:allValues], allValuesData, nil); - STAssertEqualStrings([coder encode:allValuesData], allValues, nil); + XCTAssertEqualObjects([coder decode:allValues error:&error], allValuesData); + XCTAssertNil(error); + error = nil; + XCTAssertEqualStrings([coder encode:allValuesData error:&error], allValues); + XCTAssertNil(error); } - (void)testBase64Websafe { @@ -162,7 +191,7 @@ GTMStringEncoding *coder = [GTMStringEncoding rfc4648Base64WebsafeStringEncoding]; - [GTMUnitTestDevLog expectString:@"Empty input"]; + NSError *error = nil; ASSERT_ENCODE_DECODE_STRING(coder, @"", @""); ASSERT_ENCODE_DECODE_STRING(coder, @"f", @"Zg=="); ASSERT_ENCODE_DECODE_STRING(coder, @"fo", @"Zm8="); @@ -185,15 +214,18 @@ NSData *allValuesData = [NSData dataWithBytes:&allValuesBytes length:sizeof(allValuesBytes)]; - STAssertEqualObjects([coder decode:allValues], allValuesData, nil); - STAssertEqualStrings([coder encode:allValuesData], allValues, nil); + XCTAssertEqualObjects([coder decode:allValues error:&error], allValuesData); + XCTAssertNil(error); + error = nil; + XCTAssertEqualStrings([coder encode:allValuesData error:&error], allValues); + XCTAssertNil(error); } - (void)testBase32 { // RFC4648 test vectors GTMStringEncoding *coder = [GTMStringEncoding rfc4648Base32StringEncoding]; - [GTMUnitTestDevLog expectString:@"Empty input"]; + NSError *error = nil; ASSERT_ENCODE_DECODE_STRING(coder, @"", @""); ASSERT_ENCODE_DECODE_STRING(coder, @"f", @"MY======"); ASSERT_ENCODE_DECODE_STRING(coder, @"fo", @"MZXQ===="); @@ -217,15 +249,18 @@ NSData *allValuesData = [NSData dataWithBytes:&allValuesBytes length:sizeof(allValuesBytes)]; - STAssertEqualObjects([coder decode:allValues], allValuesData, nil); - STAssertEqualStrings([coder encode:allValuesData], allValues, nil); + XCTAssertEqualObjects([coder decode:allValues error:&error], allValuesData); + XCTAssertNil(error); + error = nil; + XCTAssertEqualStrings([coder encode:allValuesData error:&error], allValues); + XCTAssertNil(error); } - (void)testBase32Hex { // RFC4648 test vectors GTMStringEncoding *coder = [GTMStringEncoding rfc4648Base32HexStringEncoding]; - [GTMUnitTestDevLog expectString:@"Empty input"]; + NSError *error = nil; ASSERT_ENCODE_DECODE_STRING(coder, @"", @""); ASSERT_ENCODE_DECODE_STRING(coder, @"f", @"CO======"); ASSERT_ENCODE_DECODE_STRING(coder, @"fo", @"CPNG===="); @@ -249,15 +284,18 @@ NSData *allValuesData = [NSData dataWithBytes:&allValuesBytes length:sizeof(allValuesBytes)]; - STAssertEqualObjects([coder decode:allValues], allValuesData, nil); - STAssertEqualStrings([coder encode:allValuesData], allValues, nil); + XCTAssertEqualObjects([coder decode:allValues error:&error], allValuesData); + XCTAssertNil(error); + error = nil; + XCTAssertEqualStrings([coder encode:allValuesData error:&error], allValues); + XCTAssertNil(error); } - (void)testHex { // RFC4648 test vectors GTMStringEncoding *coder = [GTMStringEncoding hexStringEncoding]; - [GTMUnitTestDevLog expectString:@"Empty input"]; + NSError *error = nil; ASSERT_ENCODE_DECODE_STRING(coder, @"", @""); ASSERT_ENCODE_DECODE_STRING(coder, @"f", @"66"); ASSERT_ENCODE_DECODE_STRING(coder, @"fo", @"666F"); @@ -282,28 +320,39 @@ NSData *allValuesData = [NSData dataWithBytes:&allValuesBytes length:sizeof(allValuesBytes)]; - STAssertEqualObjects([coder decode:allValues], allValuesData, nil); - STAssertEqualStrings([coder encode:allValuesData], allValues, nil); + XCTAssertEqualObjects([coder decode:allValues error:&error], allValuesData); + XCTAssertNil(error); + error = nil; + XCTAssertEqualStrings([coder encode:allValuesData error:&error], allValues); + XCTAssertNil(error); + error = nil; // Lower case - STAssertEqualObjects([coder decode:[allValues lowercaseString]], - allValuesData, nil); + XCTAssertEqualObjects([coder decode:[allValues lowercaseString] error:&error], + allValuesData); + XCTAssertNil(error); + error = nil; // Extra tests from GTMNSData+HexTest.m NSString *testString = @"1C2F0032F40123456789ABCDEF"; char testBytes[] = { 0x1c, 0x2f, 0x00, 0x32, 0xf4, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; NSData *testData = [NSData dataWithBytes:testBytes length:sizeof(testBytes)]; - STAssertEqualStrings([coder encode:testData], testString, nil); - STAssertEqualObjects([coder decode:testString], testData, nil); + error = nil; + XCTAssertEqualStrings([coder encode:testData error:&error], testString); + XCTAssertEqualObjects([coder decode:testString error:&error], testData); // Invalid inputs - [GTMUnitTestDevLog expectString:@"Incomplete trailing data"]; - STAssertNil([coder decode:@"1c2f003"], nil); - [GTMUnitTestDevLog expectString:@"Unexpected data in input pos 7"]; - STAssertNil([coder decode:@"1c2f00ft"], nil); - [GTMUnitTestDevLog expectString:@"Unexpected data in input pos 4"]; - STAssertNil([coder decode:@"abcd<C3><A9>f"], nil); + XCTAssertNil([coder decode:@"1c2f003" error:&error]); + XCTAssertEqual([error code], GTMStringEncodingErrorIncompleteTrailingData); + XCTAssertNil([coder decode:@"1c2f00ft" error:&error]); + XCTAssertEqual([error code], GTMStringEncodingErrorUnknownCharacter); + XCTAssertEqualObjects([[error userInfo] objectForKey:GTMStringEncodingBadCharacterIndexKey], + [NSNumber numberWithUnsignedInteger:7]); + XCTAssertNil([coder decode:@"abcd<C3><A9>f" error:&error]); + XCTAssertEqual([error code], GTMStringEncodingErrorUnknownCharacter); + XCTAssertEqualObjects([[error userInfo] objectForKey:GTMStringEncodingBadCharacterIndexKey], + [NSNumber numberWithUnsignedInteger:4]); } @end diff --git a/Foundation/GTMSystemVersion.m b/Foundation/GTMSystemVersion.m index f3a8559..5738d78 100644 --- a/Foundation/GTMSystemVersion.m +++ b/Foundation/GTMSystemVersion.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -17,7 +17,9 @@ // #import "GTMSystemVersion.h" -#import "GTMObjC2Runtime.h" + +#import <objc/message.h> + #if GTM_MACOS_SDK #import <CoreServices/CoreServices.h> #else @@ -51,29 +53,11 @@ static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/ require_noerr(Gestalt(gestaltSystemVersionMajor, &sGTMSystemVersionMajor), failedGestalt); require_noerr(Gestalt(gestaltSystemVersionMinor, &sGTMSystemVersionMinor), failedGestalt); require_noerr(Gestalt(gestaltSystemVersionBugFix, &sGTMSystemVersionBugFix), failedGestalt); - + return; failedGestalt: ; -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_3 - // gestaltSystemVersionMajor et al are only on 10.4 and above, so they - // could fail when running on 10.3. - SInt32 binaryCodedDec; - OSStatus err = err = Gestalt(gestaltSystemVersion, &binaryCodedDec); - _GTMDevAssert(!err, @"Unable to get version from Gestalt"); - - // Note that this code will return x.9.9 for any system rev parts that are - // greater than 9 (i.e., 10.10.10 will be 10.9.9). This shouldn't ever be a - // problem as the code above takes care of 10.4+. - SInt32 msb = (binaryCodedDec & 0x0000F000L) >> 12; - msb *= 10; - SInt32 lsb = (binaryCodedDec & 0x00000F00L) >> 8; - sGTMSystemVersionMajor = msb + lsb; - sGTMSystemVersionMinor = (binaryCodedDec & 0x000000F0L) >> 4; - sGTMSystemVersionBugFix = (binaryCodedDec & 0x0000000FL); -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_3 - #else // GTM_MACOS_SDK NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *version = nil; @@ -81,7 +65,7 @@ static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/ // The intent is for this file to be Foundation level, so don't directly // call out to UIDevice, but try to get it at runtime before falling back // to the plist. The problem with using the plist on the Simulator is that - // the path will be on the host system, and give us a MacOS (10.x.y) + // the path will be on the host system, and give us a MacOS (10.x.y) // version number instead of an iOS version number. Class uideviceClass = NSClassFromString(@"UIDevice"); if (uideviceClass) { @@ -98,10 +82,10 @@ static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/ NSArray *versionInfo = [version componentsSeparatedByString:@"."]; NSUInteger length = [versionInfo count]; - _GTMDevAssert(length > 1 && length < 4, + _GTMDevAssert(length > 1 && length < 4, @"Unparseable version %@", version); sGTMSystemVersionMajor = [[versionInfo objectAtIndex:0] intValue]; - _GTMDevAssert(sGTMSystemVersionMajor != 0, + _GTMDevAssert(sGTMSystemVersionMajor != 0, @"Unknown version for %@", version); sGTMSystemVersionMinor = [[versionInfo objectAtIndex:1] intValue]; if (length == 3) { @@ -130,7 +114,7 @@ static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/ // software to want this, and it costs a bit to get at startup. // This will mainly be for unit test cases. if (!sBuild) { - NSDictionary *systemVersionPlist + NSDictionary *systemVersionPlist = [NSDictionary dictionaryWithContentsOfFile:kSystemVersionPlistPath]; sBuild = [[systemVersionPlist objectForKey:@"ProductBuildVersion"] retain]; _GTMDevAssert(sBuild, @"Unable to get build version"); @@ -140,63 +124,51 @@ static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/ } + (BOOL)isBuildLessThan:(NSString*)build { - NSComparisonResult result - = [[self build] compare:build + NSComparisonResult result + = [[self build] compare:build options:NSNumericSearch | NSCaseInsensitiveSearch]; return result == NSOrderedAscending; } - + + (BOOL)isBuildLessThanOrEqualTo:(NSString*)build { - NSComparisonResult result - = [[self build] compare:build + NSComparisonResult result + = [[self build] compare:build options:NSNumericSearch | NSCaseInsensitiveSearch]; return result != NSOrderedDescending; } + (BOOL)isBuildGreaterThan:(NSString*)build { - NSComparisonResult result - = [[self build] compare:build + NSComparisonResult result + = [[self build] compare:build options:NSNumericSearch | NSCaseInsensitiveSearch]; return result == NSOrderedDescending; } + (BOOL)isBuildGreaterThanOrEqualTo:(NSString*)build { - NSComparisonResult result - = [[self build] compare:build + NSComparisonResult result + = [[self build] compare:build options:NSNumericSearch | NSCaseInsensitiveSearch]; return result != NSOrderedAscending; } + (BOOL)isBuildEqualTo:(NSString *)build { - NSComparisonResult result - = [[self build] compare:build + NSComparisonResult result + = [[self build] compare:build options:NSNumericSearch | NSCaseInsensitiveSearch]; return result == NSOrderedSame; } #if GTM_MACOS_SDK + (BOOL)isPanther { -#if defined(__MAC_10_4) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_4 return NO; -#else - return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 3; -#endif } + (BOOL)isTiger { -#if defined(__MAC_10_5) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_5 return NO; -#else - return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 4; -#endif } + (BOOL)isLeopard { -#if defined(__MAC_10_6) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_6 return NO; -#else - return sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor == 5; -#endif } + (BOOL)isSnowLeopard { @@ -208,39 +180,19 @@ static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/ } + (BOOL)isPantherOrGreater { -#if defined(__MAC_10_3) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_3 return YES; -#else - return (sGTMSystemVersionMajor > 10) || - (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 3); -#endif } + (BOOL)isTigerOrGreater { -#if defined(__MAC_10_4) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_4 return YES; -#else - return (sGTMSystemVersionMajor > 10) || - (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 4); -#endif } + (BOOL)isLeopardOrGreater { -#if defined(__MAC_10_5) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_5 return YES; -#else - return (sGTMSystemVersionMajor > 10) || - (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 5); -#endif } + (BOOL)isSnowLeopardOrGreater { -#if defined(__MAC_10_6) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_6 return YES; -#else - return (sGTMSystemVersionMajor > 10) || - (sGTMSystemVersionMajor == 10 && sGTMSystemVersionMinor >= 6); -#endif } #endif // GTM_MACOS_SDK @@ -272,9 +224,9 @@ static NSString *const kSystemVersionPlistPath = @"/System/Library/CoreServices/ architecture = kGTMArch_i386; #endif // __LP64__ #endif // !__POWERPC__ - + #endif // GTM_IPHONE_SDK return architecture; -} +} @end diff --git a/Foundation/GTMSystemVersionTest.m b/Foundation/GTMSystemVersionTest.m index 24e6aa5..b881233 100644 --- a/Foundation/GTMSystemVersionTest.m +++ b/Foundation/GTMSystemVersionTest.m @@ -6,9 +6,9 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -27,67 +27,67 @@ SInt32 major; SInt32 minor; SInt32 bugFix; - + [GTMSystemVersion getMajor:NULL minor:NULL bugFix:NULL]; [GTMSystemVersion getMajor:&major minor:NULL bugFix:NULL]; [GTMSystemVersion getMajor:NULL minor:&minor bugFix:NULL]; [GTMSystemVersion getMajor:NULL minor:NULL bugFix:&bugFix]; [GTMSystemVersion getMajor:&major minor:&minor bugFix:&bugFix]; #if GTM_IPHONE_SDK - STAssertTrue(major >= 2 && minor >= 0 && bugFix >= 0, nil); + XCTAssertTrue(major >= 2 && minor >= 0 && bugFix >= 0); #else - STAssertTrue(major >= 10 && minor >= 3 && bugFix >= 0, nil); + XCTAssertTrue(major >= 10 && minor >= 3 && bugFix >= 0); BOOL isPanther = (major == 10) && (minor == 3); BOOL isTiger = (major == 10) && (minor == 4); BOOL isLeopard = (major == 10) && (minor == 5); BOOL isSnowLeopard = (major == 10) && (minor == 6); - + BOOL isLater = (major > 10) || ((major == 10) && (minor > 6)); - STAssertEquals([GTMSystemVersion isPanther], isPanther, nil); - STAssertEquals([GTMSystemVersion isPantherOrGreater], - (BOOL)(isPanther || isTiger - || isLeopard || isSnowLeopard || isLater), nil); - STAssertEquals([GTMSystemVersion isTiger], isTiger, nil); - STAssertEquals([GTMSystemVersion isTigerOrGreater], - (BOOL)(isTiger || isLeopard || isSnowLeopard || isLater), nil); - STAssertEquals([GTMSystemVersion isLeopard], isLeopard, nil); - STAssertEquals([GTMSystemVersion isLeopardOrGreater], - (BOOL)(isLeopard || isSnowLeopard || isLater), nil); - STAssertEquals([GTMSystemVersion isSnowLeopard], isSnowLeopard, nil); - STAssertEquals([GTMSystemVersion isSnowLeopardOrGreater], - (BOOL)(isSnowLeopard || isLater), nil); -#endif + XCTAssertEqual([GTMSystemVersion isPanther], isPanther); + XCTAssertEqual([GTMSystemVersion isPantherOrGreater], + (BOOL)(isPanther || isTiger + || isLeopard || isSnowLeopard || isLater)); + XCTAssertEqual([GTMSystemVersion isTiger], isTiger); + XCTAssertEqual([GTMSystemVersion isTigerOrGreater], + (BOOL)(isTiger || isLeopard || isSnowLeopard || isLater)); + XCTAssertEqual([GTMSystemVersion isLeopard], isLeopard); + XCTAssertEqual([GTMSystemVersion isLeopardOrGreater], + (BOOL)(isLeopard || isSnowLeopard || isLater)); + XCTAssertEqual([GTMSystemVersion isSnowLeopard], isSnowLeopard); + XCTAssertEqual([GTMSystemVersion isSnowLeopardOrGreater], + (BOOL)(isSnowLeopard || isLater)); +#endif } - (void)testRuntimeArchitecture { // Not sure how to test this short of recoding it and verifying. // This at least executes the code for me. - STAssertNotNil([GTMSystemVersion runtimeArchitecture], nil); + XCTAssertNotNil([GTMSystemVersion runtimeArchitecture]); } - (void)testBuild { // Not sure how to test this short of coding up a large fragile table. // This at least executes the code for me. NSString *systemVersion = [GTMSystemVersion build]; - STAssertNotEquals([systemVersion length], (NSUInteger)0, nil); - + XCTAssertNotEqual([systemVersion length], (NSUInteger)0); + NSString *smallVersion = @"1A00"; NSString *largeVersion = @"100Z100"; - STAssertTrue([GTMSystemVersion isBuildGreaterThan:smallVersion], nil); - STAssertFalse([GTMSystemVersion isBuildGreaterThan:systemVersion], nil); - STAssertFalse([GTMSystemVersion isBuildGreaterThan:largeVersion], nil); - STAssertTrue([GTMSystemVersion isBuildGreaterThanOrEqualTo:smallVersion], nil); - STAssertTrue([GTMSystemVersion isBuildGreaterThanOrEqualTo:systemVersion], nil); - STAssertFalse([GTMSystemVersion isBuildGreaterThanOrEqualTo:largeVersion], nil); - STAssertFalse([GTMSystemVersion isBuildEqualTo:smallVersion], nil); - STAssertTrue([GTMSystemVersion isBuildEqualTo:systemVersion], nil); - STAssertFalse([GTMSystemVersion isBuildEqualTo:largeVersion], nil); - STAssertFalse([GTMSystemVersion isBuildLessThanOrEqualTo:smallVersion], nil); - STAssertTrue([GTMSystemVersion isBuildLessThanOrEqualTo:systemVersion], nil); - STAssertTrue([GTMSystemVersion isBuildLessThanOrEqualTo:largeVersion], nil); - STAssertFalse([GTMSystemVersion isBuildLessThan:smallVersion], nil); - STAssertFalse([GTMSystemVersion isBuildLessThan:systemVersion], nil); - STAssertTrue([GTMSystemVersion isBuildLessThan:largeVersion], nil); - + XCTAssertTrue([GTMSystemVersion isBuildGreaterThan:smallVersion]); + XCTAssertFalse([GTMSystemVersion isBuildGreaterThan:systemVersion]); + XCTAssertFalse([GTMSystemVersion isBuildGreaterThan:largeVersion]); + XCTAssertTrue([GTMSystemVersion isBuildGreaterThanOrEqualTo:smallVersion]); + XCTAssertTrue([GTMSystemVersion isBuildGreaterThanOrEqualTo:systemVersion]); + XCTAssertFalse([GTMSystemVersion isBuildGreaterThanOrEqualTo:largeVersion]); + XCTAssertFalse([GTMSystemVersion isBuildEqualTo:smallVersion]); + XCTAssertTrue([GTMSystemVersion isBuildEqualTo:systemVersion]); + XCTAssertFalse([GTMSystemVersion isBuildEqualTo:largeVersion]); + XCTAssertFalse([GTMSystemVersion isBuildLessThanOrEqualTo:smallVersion]); + XCTAssertTrue([GTMSystemVersion isBuildLessThanOrEqualTo:systemVersion]); + XCTAssertTrue([GTMSystemVersion isBuildLessThanOrEqualTo:largeVersion]); + XCTAssertFalse([GTMSystemVersion isBuildLessThan:smallVersion]); + XCTAssertFalse([GTMSystemVersion isBuildLessThan:systemVersion]); + XCTAssertTrue([GTMSystemVersion isBuildLessThan:largeVersion]); + } @end diff --git a/Foundation/GTMTransientRootPortProxy.h b/Foundation/GTMTransientRootPortProxy.h deleted file mode 100644 index 5dc0a56..0000000 --- a/Foundation/GTMTransientRootPortProxy.h +++ /dev/null @@ -1,50 +0,0 @@ -// -// GTMTransientRootPortProxy.h -// -// Copyright 2006-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> -#import "GTMTransientRootProxy.h" - -@interface GTMTransientRootPortProxy : GTMTransientRootProxy { - @private - NSPort *receivePort_; - NSPort *sendPort_; -} - -// Returns an autoreleased instance. See below for details on args. -+ (id)rootProxyWithReceivePort:(NSPort *)receivePort - sendPort:(NSPort *)sendPort - protocol:(Protocol *)protocol - requestTimeout:(NSTimeInterval)requestTimeout - replyTimeout:(NSTimeInterval)replyTimeout; - -// This function will return a GTMTransientRootProxy that is using NSPorts -// for the connection. The |receivePort| and |sendPort| conventions -// follow the same conventions as -[NSConnection initWithReceivePort:sendPort:]. -// Note that due to Radar 6676818 "NSConnection leaks when initialized with nil -// sendPort" that you will leak a connection if you pass in "nil" for your -// sendPort if you are using NSPorts (mach or socket) to communicate between -// threads. The leak occurs on 10.5.6, and SL 10A286. This simple answer -// is just to always use two ports to communicate. Check out the test to see -// how we do cross thread communication. -- (id)initWithReceivePort:(NSPort *)receivePort - sendPort:(NSPort *)sendPort - protocol:(Protocol *)protocol - requestTimeout:(NSTimeInterval)requestTimeout - replyTimeout:(NSTimeInterval)replyTimeout; - -@end diff --git a/Foundation/GTMTransientRootPortProxy.m b/Foundation/GTMTransientRootPortProxy.m deleted file mode 100644 index ee9093a..0000000 --- a/Foundation/GTMTransientRootPortProxy.m +++ /dev/null @@ -1,80 +0,0 @@ -// -// GTMTransientRootPortProxy.m -// -// Copyright 2006-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMTransientRootPortProxy.h" -#import "GTMObjC2Runtime.h" - -@interface GTMTransientRootPortProxy (ProtectedMethods) -// Returns an NSConnection for NSPorts. This method overrides the one in -// the GTMTransientRootProxy which allows us to create a connection with a -// NSPort. -// -- (NSConnection *)makeConnection; -@end - - -@implementation GTMTransientRootPortProxy - -+ (id)rootProxyWithReceivePort:(NSPort *)receivePort - sendPort:(NSPort *)sendPort - protocol:(Protocol *)protocol - requestTimeout:(NSTimeInterval)requestTimeout - replyTimeout:(NSTimeInterval)replyTimeout { - return [[[self alloc] initWithReceivePort:receivePort - sendPort:sendPort - protocol:protocol - requestTimeout:requestTimeout - replyTimeout:replyTimeout] autorelease]; -} - -- (id)initWithReceivePort:(NSPort *)receivePort - sendPort:(NSPort *)sendPort - protocol:(Protocol *)protocol - requestTimeout:(NSTimeInterval)requestTimeout - replyTimeout:(NSTimeInterval)replyTimeout { - if ((!sendPort && !receivePort) || !protocol) { - [self release]; - return nil; - } - - requestTimeout_ = requestTimeout; - replyTimeout_ = replyTimeout; - - receivePort_ = [receivePort retain]; - sendPort_ = [sendPort retain]; - - protocol_ = protocol; // Protocols can't be retained - return self; -} - -- (void)dealloc { - [receivePort_ release]; - [sendPort_ release]; - [super dealloc]; -} - -@end - -@implementation GTMTransientRootPortProxy (ProtectedMethods) - -- (NSConnection *)makeConnection { - return [NSConnection connectionWithReceivePort:receivePort_ - sendPort:sendPort_]; -} - -@end diff --git a/Foundation/GTMTransientRootPortProxyTest.m b/Foundation/GTMTransientRootPortProxyTest.m deleted file mode 100644 index a85498f..0000000 --- a/Foundation/GTMTransientRootPortProxyTest.m +++ /dev/null @@ -1,182 +0,0 @@ -// -// GTMTransientRootPortProxyTest.m -// -// Copyright 2006-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" -#import "GTMTransientRootPortProxy.h" - -#define kDefaultTimeout 5.0 - -enum { - kGTMTransientThreadConditionStarting = 777, - kGTMTransientThreadConditionStarted, - kGTMTransientThreadConditionQuitting, - kGTMTransientThreadConditionQuitted -}; - -// === Start off declaring some auxillary data structures === - -// The @protocol that we'll use for testing with. -@protocol DOPortTestProtocol -- (oneway void)doOneWayVoid; -- (bycopy NSString *)doReturnStringBycopy; -@end - -// The "server" we'll use to test the DO connection. This server will implement -// our test protocol, and it will run in a separate thread from the main -// unit testing thread, so the DO requests can be serviced. -@interface DOPortTestServer : NSObject <DOPortTestProtocol> { - @private - NSPort *clientSendPort_; - NSPort *clientReceivePort_; -} -- (void)runThread:(NSConditionLock *)lock; -- (NSPort *)clientSendPort; -- (NSPort *)clientReceivePort; -@end - -@implementation DOPortTestServer - -- (void)runThread:(NSConditionLock *)lock { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSDate *future = [NSDate dateWithTimeIntervalSinceNow:kDefaultTimeout]; - if(![lock lockWhenCondition:kGTMTransientThreadConditionStarting - beforeDate:future]) { - _GTMDevLog(@"Unable to acquire lock in runThread! This is BAD!"); - [pool drain]; - [NSThread exit]; - } - - clientSendPort_ = [NSPort port]; - clientReceivePort_ = [NSPort port]; - - NSConnection *conn - = [[NSConnection alloc] initWithReceivePort:clientSendPort_ - sendPort:clientReceivePort_]; - [conn setRootObject:self]; - [lock unlockWithCondition:kGTMTransientThreadConditionStarted]; - while (![lock tryLockWhenCondition:kGTMTransientThreadConditionQuitting]) { - NSDate *runUntil = [NSDate dateWithTimeIntervalSinceNow:0.1]; - [[NSRunLoop currentRunLoop] runUntilDate:runUntil]; - } - [conn setRootObject:nil]; - [clientSendPort_ invalidate]; - [clientReceivePort_ invalidate]; - [conn release]; - [pool drain]; - [lock unlockWithCondition:kGTMTransientThreadConditionQuitted]; -} - -- (NSPort *)clientSendPort { - return clientSendPort_; -} - -- (NSPort *)clientReceivePort { - return clientReceivePort_; -} - -- (oneway void)doOneWayVoid { - // Do nothing -} -- (bycopy NSString *)doReturnStringBycopy { - return @"TestString"; -} - -@end - -// === Done with auxillary data structures, now for the main test class === - -@interface GTMTransientRootPortProxyTest : GTMTestCase { - DOPortTestServer *server_; - NSConditionLock *syncLock_; -} - -@end - -@implementation GTMTransientRootPortProxyTest - -- (void)testTransientRootPortProxy { - syncLock_ = [[[NSConditionLock alloc] - initWithCondition:kGTMTransientThreadConditionStarting] - autorelease]; - - // Setup our server. - server_ = [[[DOPortTestServer alloc] init] autorelease]; - [NSThread detachNewThreadSelector:@selector(runThread:) - toTarget:server_ - withObject:syncLock_]; - NSDate *future = [NSDate dateWithTimeIntervalSinceNow:kDefaultTimeout]; - STAssertTrue([syncLock_ lockWhenCondition:kGTMTransientThreadConditionStarted - beforeDate:future], - @"Unable to start thread"); - [syncLock_ unlockWithCondition:kGTMTransientThreadConditionStarted]; - - NSPort *receivePort = [server_ clientReceivePort]; - NSPort *sendPort = [server_ clientSendPort]; - - GTMTransientRootPortProxy<DOPortTestProtocol> *failProxy = - [GTMTransientRootPortProxy rootProxyWithReceivePort:nil - sendPort:nil - protocol:@protocol(DOPortTestProtocol) - requestTimeout:kDefaultTimeout - replyTimeout:kDefaultTimeout]; - STAssertNil(failProxy, @"should have failed w/o a port"); - failProxy = - [GTMTransientRootPortProxy rootProxyWithReceivePort:receivePort - sendPort:sendPort - protocol:nil - requestTimeout:kDefaultTimeout - replyTimeout:kDefaultTimeout]; - STAssertNil(failProxy, @"should have failed w/o a protocol"); - - GTMTransientRootPortProxy<DOPortTestProtocol> *proxy = - [GTMTransientRootPortProxy rootProxyWithReceivePort:receivePort - sendPort:sendPort - protocol:@protocol(DOPortTestProtocol) - requestTimeout:kDefaultTimeout - replyTimeout:kDefaultTimeout]; - - STAssertEqualObjects([proxy doReturnStringBycopy], - @"TestString", @"proxy should have returned " - @"'TestString'"); - - // Redo the *exact* same test to make sure we can have multiple instances - // in the same app. - proxy = - [GTMTransientRootPortProxy rootProxyWithReceivePort:receivePort - sendPort:sendPort - protocol:@protocol(DOPortTestProtocol) - requestTimeout:kDefaultTimeout - replyTimeout:kDefaultTimeout]; - - STAssertEqualObjects([proxy doReturnStringBycopy], - @"TestString", @"proxy should have returned " - @"'TestString'"); - [syncLock_ tryLockWhenCondition:kGTMTransientThreadConditionStarted]; - [syncLock_ unlockWithCondition:kGTMTransientThreadConditionQuitting]; - - // Wait for the server to shutdown so we clean up nicely. - // The max amount of time we will wait until we abort this test. - NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:kDefaultTimeout]; - // The server did not shutdown and we want to capture this as an error - STAssertTrue([syncLock_ lockWhenCondition:kGTMTransientThreadConditionQuitted - beforeDate:timeout], - @"The server did not shutdown gracefully before the timeout."); - [syncLock_ unlockWithCondition:kGTMTransientThreadConditionQuitted]; -} - -@end diff --git a/Foundation/GTMTransientRootProxy.h b/Foundation/GTMTransientRootProxy.h deleted file mode 100644 index 3ebb501..0000000 --- a/Foundation/GTMTransientRootProxy.h +++ /dev/null @@ -1,114 +0,0 @@ -// -// GTMTransientRootProxy.h -// -// Copyright 2006-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import <Foundation/Foundation.h> -#import "GTMDefines.h" - -// Handle (re-)connecting to a transient root proxy object via DO. -// -// This class is designed to handle connecting and reconnecting to a Distributed -// Objects root proxy (NSDistantObject* instance). It is a replacement for using -// the NSDistantObject returned from NSConnection, directly. When the DO -// connection is up, messages sent to this class are forwarded to the real -// object (the NSDistantObject); when the DO connection is down, messages sent -// to this class are silently swallowed. You can use the -isConnected method on -// this class to see if the DO connection is up or down. -// -// This class may be useful when you need a DO connection, but the -// server you're connected to may be going up and down. For example, the -// web browser plugins in Google Desktop may need to connect to the Google -// Desktop local webserver, but we'd want the browser plugins to be able to -// gracefully handle the local Google Desktop webserver starting and stopping. -// -// === Example Usage === -// -// Old code: -// -// NSDistantObject<MyProto> *o = -// [NSConnection rootProxyForConnectionWithRegisteredName:@"server" -// host:nil]; -// [o setProtocolForProxy:@protocol(MyProto)]; -// [o someMethodInMyProto]; -// // ... write a bunch of code to handle error conditions -// -// New code: -// -// GTMTransientRootProxy<MyProto> *o = -// [GTMTransientRootProxy rootProxyWithRegisteredName:@"server" -// host:nil -// protocol:@protocol(MyProto) -// requestTimeout:5.0 -// replyTimeout:5.0]; -// [o someMethodInMyProto]; -// -// The 'Old code' requires you to handle all the error conditions that may -// arise when using DO (such as the server crashing, or network going down), -// handle properly tearing down the broken connection, and trying to reconnect -// when the server finally comes back online. The 'New code' handles all of -// those details for you. -// -// Also, when creating a GMTransientRootProxy object, you must tell it the -// @protocol that will be used for communication - this is not optional. And -// in order to quiet compiler warnings, you'll also want to staticly type -// the pointer with the protocol as well. -// -@interface GTMTransientRootProxy : NSProxy { - @protected - GTM_WEAK Protocol *protocol_; - NSDistantObject *realProxy_; - - NSString *registeredName_; - NSString *host_; - - NSTimeInterval requestTimeout_; - NSTimeInterval replyTimeout_; -} - -// Returns an autoreleased instance -+ (id)rootProxyWithRegisteredName:(NSString *)name - host:(NSString *)host - protocol:(Protocol *)protocol - requestTimeout:(NSTimeInterval)requestTimeout - replyTimeout:(NSTimeInterval)replyTimeout; - -// This function will return a GTMTransientRootProxy that is using Mach ports -// for the connection. The |name| and |host| arguments will be used to lookup -// the correct information to create the Mach port connection. -// -- (id)initWithRegisteredName:(NSString *)name - host:(NSString *)host - protocol:(Protocol *)protocol - requestTimeout:(NSTimeInterval)requestTimeout - replyTimeout:(NSTimeInterval)replyTimeout; - -// Returns YES if the DO connection is up and working, NO otherwise. -// -- (BOOL)isConnected; - -@end - -// Subclass of GTMTransientRootProxy that catches and ignores ALL exceptions. -// This class overrides GTMTransientRootProxy's -forwardInvocation: -// method, and wraps it in a try/catch block, and ignores all exceptions. -// -@interface GTMRootProxyCatchAll : GTMTransientRootProxy - -// Overridden, and ignores all thrown exceptions. -- (void)forwardInvocation:(NSInvocation *)invocation; - -@end diff --git a/Foundation/GTMTransientRootProxy.m b/Foundation/GTMTransientRootProxy.m deleted file mode 100644 index 2f7dfec..0000000 --- a/Foundation/GTMTransientRootProxy.m +++ /dev/null @@ -1,230 +0,0 @@ -// -// GTMTransientRootProxy.m -// -// Copyright 2006-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMTransientRootProxy.h" -#import "GTMObjC2Runtime.h" - -// Private methods on NSMethodSignature that we need to call. This method has -// been available since 10.0, but Apple didn't add it to the headers until 10.5 -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -@interface NSMethodSignature (UndeclaredMethods) -+ (NSMethodSignature *)signatureWithObjCTypes:(const char *)types; -@end -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - -@interface GTMTransientRootProxy (PrivateMethods) -// Returns an NSConnection for NSMacPorts. This method is broken out to allow -// subclasses to override it to generate different types of NSConnections. -- (NSConnection *)makeConnection; - -// Returns the "real" proxy (stored in the realProxy_ ivar) associated with this -// instance. If realProxy_ is nil, then an attempt is made to make a connection -// to create the realProxy_. -// -- (NSDistantObject *)realProxy; - -// "Releases" the realProxy_ ivar, and removes |self| as an observer from -// the NSNotificationCenter. -// -- (void)releaseRealProxy; - -// Notification that a connection has died. -- (void)connectionDidDie:(NSNotification *)notification; -@end - -@implementation GTMTransientRootProxy - -+ (id)rootProxyWithRegisteredName:(NSString *)name - host:(NSString *)host - protocol:(Protocol *)protocol - requestTimeout:(NSTimeInterval)requestTimeout - replyTimeout:(NSTimeInterval)replyTimeout { - return [[[self alloc] initWithRegisteredName:name - host:host - protocol:protocol - requestTimeout:requestTimeout - replyTimeout:replyTimeout] autorelease]; -} - -- (id)initWithRegisteredName:(NSString *)name - host:(NSString *)host - protocol:(Protocol *)protocol - requestTimeout:(NSTimeInterval)requestTimeout - replyTimeout:(NSTimeInterval)replyTimeout { - if (!name || !protocol) { - [self release]; - return nil; - } - - requestTimeout_ = requestTimeout; - replyTimeout_ = replyTimeout; - - registeredName_ = [name copy]; - host_ = [host copy]; - - protocol_ = protocol; // Protocols can't be retained - - return self; -} - -- (id)init { - return [self initWithRegisteredName:nil - host:nil - protocol:nil - requestTimeout:0.0 - replyTimeout:0.0]; -} - -- (void)dealloc { - [self releaseRealProxy]; - [registeredName_ release]; - [host_ release]; - [super dealloc]; -} - -- (BOOL)isConnected { - BOOL result = NO; - @synchronized (self) { - result = [[[self realProxy] connectionForProxy] isValid]; - } - return result; -} - -- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { - struct objc_method_description mdesc; - mdesc = protocol_getMethodDescription(protocol_, selector, YES, YES); - NSMethodSignature *returnValue = nil; - if (mdesc.types == NULL) { - // COV_NF_START - _GTMDevLog(@"Unable to get the protocol method description. Returning " - @"nil."); - // COV_NF_END - } else { - returnValue = [NSMethodSignature signatureWithObjCTypes:mdesc.types]; - } - return returnValue; -} - -- (void)forwardInvocation:(NSInvocation *)invocation { - @try { - NSDistantObject *target = [self realProxy]; - [invocation invokeWithTarget:target]; - - // We need to catch NSException* here rather than "id" because we need to - // treat |ex| as an NSException when using the -name method. Also, we're - // only looking to catch a few types of exception here, all of which are - // NSException types; the rest we just rethrow. - } @catch (NSException *ex) { - NSString *exName = [ex name]; - // If we catch an exception who's name matches any of the following types, - // it's because the DO connection probably went down. So, we'll just - // release our realProxy_, and attempt to reconnect on the next call. - if ([exName isEqualToString:NSPortTimeoutException] - || [exName isEqualToString:NSInvalidSendPortException] - || [exName isEqualToString:NSInvalidReceivePortException] - || [exName isEqualToString:NSFailedAuthenticationException] - || [exName isEqualToString:NSPortSendException] - || [exName isEqualToString:NSPortReceiveException]) { - [self releaseRealProxy]; // COV_NF_LINE - } else { - // If the exception was any other type (commonly - // NSInvalidArgumentException) then we'll just re-throw it to the caller. - @throw; - } - } // COV_NF_LINE -} - -@end - -@implementation GTMTransientRootProxy (PrivateMethods) - -- (NSConnection *)makeConnection { - return [NSConnection connectionWithRegisteredName:registeredName_ host:host_]; -} - -- (NSDistantObject *)realProxy { - NSDistantObject *returnProxy = nil; - - @synchronized (self) { - // No change so no notification - if (realProxy_) return realProxy_; - - NSConnection *conn = [self makeConnection]; - [conn setRequestTimeout:requestTimeout_]; - [conn setReplyTimeout:replyTimeout_]; - @try { - // Try to get the root proxy for this connection's vended object. - realProxy_ = [conn rootProxy]; - } @catch (id ex) { - // We may fail here if we can't get the root proxy in the amount of time - // specified by the timeout above. This may happen, for example, if the - // server process is stopped (via SIGSTOP). We'll just ignore this, and - // try again at the next message. - [conn invalidate]; - return nil; - } - if (!realProxy_) { - [conn invalidate]; - // Again, no change in connection status - return nil; - } - [realProxy_ retain]; - [realProxy_ setProtocolForProxy:protocol_]; - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:self - selector:@selector(connectionDidDie:) - name:NSConnectionDidDieNotification - object:conn]; - // Retain/autorelease so it lives at least the duration of this synchronize - returnProxy = [[realProxy_ retain] autorelease]; - } // @synchronized (self) - - return returnProxy; -} - -- (void)connectionDidDie:(NSNotification *)notification { - [self releaseRealProxy]; -} - -- (void)releaseRealProxy { - @synchronized (self) { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - // Only trigger if we had a proxy before - if (realProxy_) { - [realProxy_ release]; - realProxy_ = nil; - } - } -} - -@end - -@implementation GTMRootProxyCatchAll - -- (void)forwardInvocation:(NSInvocation *)invocation { - @try { - [super forwardInvocation:invocation]; - } - @catch (id ex) { - // Log for developers, but basically ignore it. - _GTMDevLog(@"Proxy for invoking %@ has caught and is ignoring exception: %@", - NSStringFromSelector([invocation selector]), ex); - } -} - -@end diff --git a/Foundation/GTMTransientRootProxyTest.m b/Foundation/GTMTransientRootProxyTest.m deleted file mode 100644 index 821faac..0000000 --- a/Foundation/GTMTransientRootProxyTest.m +++ /dev/null @@ -1,231 +0,0 @@ -// -// GMTransientRootProxyTest.m -// -// Copyright 2006-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMSenTestCase.h" -#import "GTMTransientRootProxy.h" -#import "GTMUnitTestDevLog.h" - -#define kDefaultTimeout 5.0 - -// === Start off declaring some auxillary data structures === -static NSString *const kTestServerName = @"gtm_test_server"; -static NSString *const kGTMTransientRootNameKey = @"GTMTransientRootNameKey"; -static NSString *const kGTMTransientRootLockKey = @"GTMTransientRootLockKey"; - -enum { - kGTMTransientThreadConditionStarting = 777, - kGTMTransientThreadConditionStarted, - kGTMTransientThreadConditionQuitting, - kGTMTransientThreadConditionQuitted -}; - -// The @protocol that we'll use for testing with. -@protocol DOTestProtocol -- (oneway void)doOneWayVoid; -- (bycopy NSString *)doReturnStringBycopy; -- (void)throwException; -@end - -// The "server" we'll use to test the DO connection. This server will implement -// our test protocol, and it will run in a separate thread from the main -// unit testing thread, so the DO requests can be serviced. -@interface DOTestServer : NSObject <DOTestProtocol> -- (void)runThread:(NSDictionary *)args; -@end - -@implementation DOTestServer - -- (void)runThread:(NSDictionary *)args { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSConditionLock *lock = [args objectForKey:kGTMTransientRootLockKey]; - NSString *serverName = [args objectForKey:kGTMTransientRootNameKey]; - NSDate *future = [NSDate dateWithTimeIntervalSinceNow:kDefaultTimeout]; - if(![lock lockWhenCondition:kGTMTransientThreadConditionStarting - beforeDate:future]) { - _GTMDevLog(@"Unable to acquire lock in runThread! This is BAD!"); - [pool drain]; - [NSThread exit]; - } - - NSConnection *conn = [[[NSConnection alloc] init] autorelease]; - [conn setRootObject:self]; - if (![conn registerName:serverName]) { - _GTMDevLog(@"Failed to register DO root object with name '%@'", - serverName); - [pool drain]; - [NSThread exit]; - } - [lock unlockWithCondition:kGTMTransientThreadConditionStarted]; - while (![lock tryLockWhenCondition:kGTMTransientThreadConditionQuitting]) { - NSDate* runUntil = [NSDate dateWithTimeIntervalSinceNow:0.1]; - [[NSRunLoop currentRunLoop] runUntilDate:runUntil]; - } - [conn setRootObject:nil]; - [conn registerName:nil]; - [pool drain]; - [lock unlockWithCondition:kGTMTransientThreadConditionQuitted]; -} - -- (oneway void)doOneWayVoid { - // Do nothing -} -- (bycopy NSString *)doReturnStringBycopy { - return @"TestString"; -} - -- (void)throwException { - [NSException raise:@"testingException" format:@"for the unittest"]; -} - -@end - -// === Done with auxillary data structures, now for the main test class === - -@interface GTMTransientRootProxy (GTMTransientRootProxyTest) -- (id)init; -@end - -@interface GTMTransientRootProxyTest : GTMTestCase { - @private - DOTestServer *server_; - NSConditionLock *syncLock_; -} -@end - -@implementation GTMTransientRootProxyTest - -- (void)testTransientRootProxy { - // Setup our server and create a unqiue server name every time we run - NSTimeInterval timeStamp = [[NSDate date] timeIntervalSinceReferenceDate]; - NSString *serverName = - [NSString stringWithFormat:@"%@_%f", kTestServerName, timeStamp]; - server_ = [[[DOTestServer alloc] init] autorelease]; - syncLock_ = [[[NSConditionLock alloc] - initWithCondition:kGTMTransientThreadConditionStarting] - autorelease]; - NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys: - syncLock_, kGTMTransientRootLockKey, - serverName, kGTMTransientRootNameKey, - nil]; - [NSThread detachNewThreadSelector:@selector(runThread:) - toTarget:server_ - withObject:args]; - NSDate *future = [NSDate dateWithTimeIntervalSinceNow:kDefaultTimeout]; - STAssertTrue([syncLock_ lockWhenCondition:kGTMTransientThreadConditionStarted - beforeDate:future], - @"Unable to start thread"); - [syncLock_ unlockWithCondition:kGTMTransientThreadConditionStarted]; - - GTMTransientRootProxy *failProxy = - [GTMTransientRootProxy rootProxyWithRegisteredName:nil - host:nil - protocol:@protocol(DOTestProtocol) - requestTimeout:kDefaultTimeout - replyTimeout:kDefaultTimeout]; - STAssertNil(failProxy, @"should have failed w/o a name"); - failProxy = - [GTMTransientRootProxy rootProxyWithRegisteredName:serverName - host:nil - protocol:nil - requestTimeout:kDefaultTimeout - replyTimeout:kDefaultTimeout]; - STAssertNil(failProxy, @"should have failed w/o a protocol"); - failProxy = [[[GTMTransientRootProxy alloc] init] autorelease]; - STAssertNil(failProxy, @"should have failed just calling init"); - - GTMTransientRootProxy<DOTestProtocol> *proxy = - [GTMTransientRootProxy rootProxyWithRegisteredName:serverName - host:nil - protocol:@protocol(DOTestProtocol) - requestTimeout:kDefaultTimeout - replyTimeout:kDefaultTimeout]; - - STAssertEqualObjects([proxy doReturnStringBycopy], @"TestString", - @"proxy should have returned 'TestString'"); - - // Redo the *exact* same test to make sure we can have multiple instances - // in the same app. - proxy = - [GTMTransientRootProxy rootProxyWithRegisteredName:serverName - host:nil - protocol:@protocol(DOTestProtocol) - requestTimeout:kDefaultTimeout - replyTimeout:kDefaultTimeout]; - STAssertEqualObjects([proxy doReturnStringBycopy], - @"TestString", @"proxy should have returned " - @"'TestString'"); - - // Test the GTMRootProxyCatchAll within this test so we don't have to rebuild - // the server again. - - GTMRootProxyCatchAll<DOTestProtocol> *catchProxy = - [GTMRootProxyCatchAll rootProxyWithRegisteredName:serverName - host:nil - protocol:@protocol(DOTestProtocol) - requestTimeout:kDefaultTimeout - replyTimeout:kDefaultTimeout]; - - [GTMUnitTestDevLog expectString:@"Proxy for invoking throwException has " - @"caught and is ignoring exception: [NOTE: this exception originated in " - @"the server.]\nfor the unittest"]; - id e = nil; - @try { - // Has the server throw an exception - [catchProxy throwException]; - } @catch (id ex) { - e = ex; - } - STAssertNil(e, @"The GTMRootProxyCatchAll did not catch the exception: %@.", - e); - - proxy = - [GTMTransientRootProxy rootProxyWithRegisteredName:@"FAKE_SERVER" - host:nil - protocol:@protocol(DOTestProtocol) - requestTimeout:kDefaultTimeout - replyTimeout:kDefaultTimeout]; - STAssertNotNil(proxy, @"proxy shouldn't be nil, even when registered w/ a " - @"fake server"); - STAssertFalse([proxy isConnected], @"the proxy shouldn't be connected due to " - @"the fake server"); - - // Now set up a proxy, and then kill our server. We put a super short time - // out on it, because we are expecting it to fail. - proxy = - [GTMTransientRootProxy rootProxyWithRegisteredName:serverName - host:nil - protocol:@protocol(DOTestProtocol) - requestTimeout:0.01 - replyTimeout:0.01]; - [syncLock_ tryLockWhenCondition:kGTMTransientThreadConditionStarted]; - [syncLock_ unlockWithCondition:kGTMTransientThreadConditionQuitting]; - - // Wait for the server to shutdown so we clean up nicely. - // The max amount of time we will wait until we abort this test. - NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:kDefaultTimeout]; - // The server did not shutdown and we want to capture this as an error - STAssertTrue([syncLock_ lockWhenCondition:kGTMTransientThreadConditionQuitted - beforeDate:timeout], - @"The server did not shutdown gracefully before the timeout."); - [syncLock_ unlockWithCondition:kGTMTransientThreadConditionQuitted]; - - // This should fail gracefully because the server is dead. - STAssertNil([proxy doReturnStringBycopy], @"proxy should have returned nil"); -} - -@end diff --git a/Foundation/GTMURITemplate.h b/Foundation/GTMURITemplate.h deleted file mode 100644 index d0e9cea..0000000 --- a/Foundation/GTMURITemplate.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - -// -// URI Template -// -// http://tools.ietf.org/html/draft-gregorio-uritemplate-04 -// -// NOTE: This implemention is only a subset of the spec. It should be able -// to parse any template that matches the spec, but if the template makes use -// of a feature that is not supported, it will fail with an error. -// - -@interface GTMURITemplate : NSObject - -// Process the template. If the template uses an unsupported feature, it will -// throw an exception to help catch that limitation. Currently unsupported -// feature is partial result modifiers (prefix/suffix). -// -// valueProvider should be anything that implements -objectForKey:. At the -// simplest level, this can be an NSDictionary. However, a custom class that -// implements valueForKey may be better for some uses (like if the values -// are coming out of some other structure). -+ (NSString *)expandTemplate:(NSString *)uriTemplate values:(id)valueProvider; - -@end - -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 diff --git a/Foundation/GTMURITemplate.m b/Foundation/GTMURITemplate.m deleted file mode 100644 index 5938b72..0000000 --- a/Foundation/GTMURITemplate.m +++ /dev/null @@ -1,521 +0,0 @@ -/* Copyright (c) 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "GTMURITemplate.h" - -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - -// Key constants for handling variables. -static NSString *const kVariable = @"variable"; // NSString -static NSString *const kExplode = @"explode"; // NSString -static NSString *const kPartial = @"partial"; // NSString -static NSString *const kPartialValue = @"partialValue"; // NSNumber - -// Help for passing the Expansion info in one shot. -struct ExpansionInfo { - // Constant for the whole expansion. - unichar expressionOperator; - NSString *joiner; - BOOL allowReservedInEscape; - - // Update for each variable. - NSString *explode; -}; - -// Helper just to shorten the lines when needed. -static NSString *UnescapeString(NSString *str) { - return [str stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; -} - -static NSString *EscapeString(NSString *str, BOOL allowReserved) { - static CFStringRef kReservedChars = CFSTR(":/?#[]@!$&'()*+,;="); - CFStringRef allowedChars = allowReserved ? kReservedChars : NULL; - - // NSURL's stringByAddingPercentEscapesUsingEncoding: does not escape - // some characters that should be escaped in URL parameters, like / and ?; - // we'll use CFURL to force the encoding of those - // - // Reference: http://www.ietf.org/rfc/rfc3986.txt - static CFStringRef kCharsToForceEscape = CFSTR("!*'();:@&=+$,/?%#[]"); - static CFStringRef kCharsToForceEscapeSansReserved = CFSTR("%"); - CFStringRef forceEscapedChars = - allowReserved ? kCharsToForceEscapeSansReserved : kCharsToForceEscape; - - NSString *resultStr = str; - CFStringRef escapedStr = - CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, - (CFStringRef)str, - allowedChars, - forceEscapedChars, - kCFStringEncodingUTF8); - if (escapedStr) { - resultStr = [(NSString *)escapedStr autorelease]; - } - return resultStr; -} - -@interface GTMURITemplate () -+ (BOOL)parseExpression:(NSString *)expression - expressionOperator:(unichar*)outExpressionOperator - variables:(NSMutableArray **)outVariables - defaultValues:(NSMutableDictionary **)outDefaultValues; - -+ (NSString *)expandVariables:(NSArray *)variables - expressionOperator:(unichar)expressionOperator - values:(id)valueProvider - defaultValues:(NSMutableDictionary *)defaultValues; - -+ (NSString *)expandString:(NSString *)valueStr - variableName:(NSString *)variableName - expansionInfo:(struct ExpansionInfo *)expansionInfo; -+ (NSString *)expandArray:(NSArray *)valueArray - variableName:(NSString *)variableName - expansionInfo:(struct ExpansionInfo *)expansionInfo; -+ (NSString *)expandDictionary:(NSDictionary *)valueDict - variableName:(NSString *)variableName - expansionInfo:(struct ExpansionInfo *)expansionInfo; -@end - -@implementation GTMURITemplate - -#pragma mark Internal Helpers - -+ (BOOL)parseExpression:(NSString *)expression - expressionOperator:(unichar*)outExpressionOperator - variables:(NSMutableArray **)outVariables - defaultValues:(NSMutableDictionary **)outDefaultValues { - - // Please see the spec for full details, but here are the basics: - // - // URI-Template = *( literals / expression ) - // expression = "{" [ operator ] variable-list "}" - // variable-list = varspec *( "," varspec ) - // varspec = varname [ modifier ] [ "=" default ] - // varname = varchar *( varchar / "." ) - // modifier = explode / partial - // explode = ( "*" / "+" ) - // partial = ( substring / remainder ) offset - // - // Examples: - // http://www.example.com/foo{?query,number} - // http://maps.com/mapper{?address*} - // http://directions.org/directions{?from+,to+} - // http://search.org/query{?terms+=none} - // - - // http://tools.ietf.org/html/draft-gregorio-uritemplate-04#section-2.2 - // Operator and op-reserve characters - static NSCharacterSet *operatorSet = nil; - // http://tools.ietf.org/html/draft-gregorio-uritemplate-04#section-2.4.1 - // Explode characters - static NSCharacterSet *explodeSet = nil; - // http://tools.ietf.org/html/draft-gregorio-uritemplate-04#section-2.4.2 - // Partial (prefix/subset) characters - static NSCharacterSet *partialSet = nil; - - @synchronized(self) { - if (operatorSet == nil) { - operatorSet = [[NSCharacterSet characterSetWithCharactersInString:@"+./;?|!@"] retain]; - } - if (explodeSet == nil) { - explodeSet = [[NSCharacterSet characterSetWithCharactersInString:@"*+"] retain]; - } - if (partialSet == nil) { - partialSet = [[NSCharacterSet characterSetWithCharactersInString:@":^"] retain]; - } - } - - // http://tools.ietf.org/html/draft-gregorio-uritemplate-04#section-3.3 - // Empty expression inlines the expression. - if ([expression length] == 0) return NO; - - // Pull off any operator. - *outExpressionOperator = 0; - unichar firstChar = [expression characterAtIndex:0]; - if ([operatorSet characterIsMember:firstChar]) { - *outExpressionOperator = firstChar; - expression = [expression substringFromIndex:1]; - } - - if ([expression length] == 0) return NO; - - // Need to find at least one varspec for the expresssion to be considered - // valid. - BOOL gotAVarspec = NO; - - // Split the variable list. - NSArray *varspecs = [expression componentsSeparatedByString:@","]; - - // Extract the defaults, explodes and modifiers from the varspecs. - *outVariables = [NSMutableArray arrayWithCapacity:[varspecs count]]; - for (NSString *varspec in varspecs) { - NSString *defaultValue = nil; - - if ([varspec length] == 0) continue; - - NSMutableDictionary *varInfo = - [NSMutableDictionary dictionaryWithCapacity:4]; - - // Check for a default (foo=bar). - NSRange range = [varspec rangeOfString:@"="]; - if (range.location != NSNotFound) { - defaultValue = - UnescapeString([varspec substringFromIndex:range.location + 1]); - varspec = [varspec substringToIndex:range.location]; - - if ([varspec length] == 0) continue; - } - - // Check for explode (foo*). - NSUInteger lenLessOne = [varspec length] - 1; - if ([explodeSet characterIsMember:[varspec characterAtIndex:lenLessOne]]) { - [varInfo setObject:[varspec substringFromIndex:lenLessOne] forKey:kExplode]; - varspec = [varspec substringToIndex:lenLessOne]; - if ([varspec length] == 0) continue; - } else { - // Check for partial (prefix/suffix) (foo:12). - range = [varspec rangeOfCharacterFromSet:partialSet]; - if (range.location != NSNotFound) { - NSString *partialMode = [varspec substringWithRange:range]; - NSString *valueStr = [varspec substringFromIndex:range.location + 1]; - // If there wasn't a value for the partial, ignore it. - if ([valueStr length] > 0) { - [varInfo setObject:partialMode forKey:kPartial]; - // TODO: Should validate valueStr is just a number... - [varInfo setObject:[NSNumber numberWithInteger:[valueStr integerValue]] - forKey:kPartialValue]; - } - varspec = [varspec substringToIndex:range.location]; - if ([varspec length] == 0) continue; - } - } - - // Spec allows percent escaping in names, so undo that. - varspec = UnescapeString(varspec); - - // Save off the cleaned up variable name. - [varInfo setObject:varspec forKey:kVariable]; - [*outVariables addObject:varInfo]; - gotAVarspec = YES; - - // Now that the variable has been cleaned up, store its default. - if (defaultValue) { - if (*outDefaultValues == nil) { - *outDefaultValues = [NSMutableDictionary dictionary]; - } - [*outDefaultValues setObject:defaultValue forKey:varspec]; - } - } - // All done. - return gotAVarspec; -} - -+ (NSString *)expandVariables:(NSArray *)variables - expressionOperator:(unichar)expressionOperator - values:(id)valueProvider - defaultValues:(NSMutableDictionary *)defaultValues { - NSString *prefix = nil; - struct ExpansionInfo expansionInfo; - expansionInfo.expressionOperator = expressionOperator; - expansionInfo.joiner = nil; - expansionInfo.allowReservedInEscape = NO; - switch (expressionOperator) { - case 0: - expansionInfo.joiner = @","; - prefix = @""; - break; - case '+': - expansionInfo.joiner = @","; - prefix = @""; - // The reserved character are safe from escaping. - expansionInfo.allowReservedInEscape = YES; - break; - case '.': - expansionInfo.joiner = @"."; - prefix = @"."; - break; - case '/': - expansionInfo.joiner = @"/"; - prefix = @"/"; - break; - case ';': - expansionInfo.joiner = @";"; - prefix = @";"; - break; - case '?': - expansionInfo.joiner = @"&"; - prefix = @"?"; - break; - default: - [NSException raise:@"GTMURITemplateUnsupported" - format:@"Unknown expression operator '%C'", expressionOperator]; - break; - } - - NSMutableArray *results = [NSMutableArray arrayWithCapacity:[variables count]]; - - for (NSDictionary *varInfo in variables) { - NSString *variable = [varInfo objectForKey:kVariable]; - - expansionInfo.explode = [varInfo objectForKey:kExplode]; - // Look up the variable value. - id rawValue = [valueProvider objectForKey:variable]; - - // If the value is an empty array or dictionary, the default is still used. - if (([rawValue isKindOfClass:[NSArray class]] - || [rawValue isKindOfClass:[NSDictionary class]]) - && [rawValue count] == 0) { - rawValue = nil; - } - - // Got nothing? Check defaults. - if (rawValue == nil) { - rawValue = [defaultValues objectForKey:variable]; - } - - // If we didn't get any value, on to the next thing. - if (!rawValue) { - continue; - } - - // Time do to the work... - NSString *result = nil; - if ([rawValue isKindOfClass:[NSString class]]) { - result = [self expandString:rawValue - variableName:variable - expansionInfo:&expansionInfo]; - } else if ([rawValue isKindOfClass:[NSNumber class]]) { - // Turn the number into a string and send it on its way. - result = [self expandString:[rawValue stringValue] - variableName:variable - expansionInfo:&expansionInfo]; - } else if ([rawValue isKindOfClass:[NSArray class]]) { - result = [self expandArray:rawValue - variableName:variable - expansionInfo:&expansionInfo]; - } else if ([rawValue isKindOfClass:[NSDictionary class]]) { - result = [self expandDictionary:rawValue - variableName:variable - expansionInfo:&expansionInfo]; - } else { - [NSException raise:@"GTMURITemplateUnsupported" - format:@"Variable returned unsupported type (%@)", - NSStringFromClass([rawValue class])]; - } - - // Did it generate anything? - if (!result) - continue; - - // Apply partial. - // Defaults should get partial applied? - // ( http://tools.ietf.org/html/draft-gregorio-uritemplate-04#section-2.5 ) - NSString *partial = [varInfo objectForKey:kPartial]; - if ([partial length] > 0) { - [NSException raise:@"GTMURITemplateUnsupported" - format:@"Unsupported partial on expansion %@", partial]; - } - - // Add the result - [results addObject:result]; - } - - // Join and add any needed prefix. - NSString *joinedResults = - [results componentsJoinedByString:expansionInfo.joiner]; - if (([prefix length] > 0) && ([joinedResults length] > 0)) { - return [prefix stringByAppendingString:joinedResults]; - } - return joinedResults; -} - -+ (NSString *)expandString:(NSString *)valueStr - variableName:(NSString *)variableName - expansionInfo:(struct ExpansionInfo *)expansionInfo { - NSString *escapedValue = - EscapeString(valueStr, expansionInfo->allowReservedInEscape); - switch (expansionInfo->expressionOperator) { - case ';': - case '?': - if ([valueStr length] > 0) { - return [NSString stringWithFormat:@"%@=%@", variableName, escapedValue]; - } - return variableName; - default: - return escapedValue; - } -} - -+ (NSString *)expandArray:(NSArray *)valueArray - variableName:(NSString *)variableName - expansionInfo:(struct ExpansionInfo *)expansionInfo { - NSMutableArray *results = [NSMutableArray arrayWithCapacity:[valueArray count]]; - // When joining variable with value, use "var.val" except for 'path' and - // 'form' style expression, use 'var=val' then. - char variableValueJoiner = '.'; - char expressionOperator = expansionInfo->expressionOperator; - if ((expressionOperator == ';') || (expressionOperator == '?')) { - variableValueJoiner = '='; - } - // Loop over the values. - for (NSString *value in valueArray) { - // Escape it. - value = EscapeString(value, expansionInfo->allowReservedInEscape); - // Should variable names be used? - if ([expansionInfo->explode isEqual:@"+"]) { - value = [NSString stringWithFormat:@"%@%c%@", - variableName, variableValueJoiner, value]; - } - [results addObject:value]; - } - if ([results count] > 0) { - // Use the default joiner unless there was no explode request, then a list - // always gets comma seperated. - NSString *joiner = expansionInfo->joiner; - if (expansionInfo->explode == nil) { - joiner = @","; - } - // Join the values. - NSString *joined = [results componentsJoinedByString:joiner]; - // 'form' style without an explode gets the variable name set to the - // joined list of values. - if ((expressionOperator == '?') && (expansionInfo->explode == nil)) { - return [NSString stringWithFormat:@"%@=%@", variableName, joined]; - } - return joined; - } - return nil; -} - -+ (NSString *)expandDictionary:(NSDictionary *)valueDict - variableName:(NSString *)variableName - expansionInfo:(struct ExpansionInfo *)expansionInfo { - NSMutableArray *results = [NSMutableArray arrayWithCapacity:[valueDict count]]; - // When joining variable with value: - // - Default to the joiner... - // - No explode, always comma... - // - For 'path' and 'form' style expression, use 'var=val'. - NSString *keyValueJoiner = expansionInfo->joiner; - char expressionOperator = expansionInfo->expressionOperator; - if (!expansionInfo->explode) { - keyValueJoiner = @","; - } else if ((expressionOperator == ';') || (expressionOperator == '?')) { - keyValueJoiner = @"="; - } - // Loop over the sorted keys. - NSArray *sortedKeys = - [[valueDict allKeys] sortedArrayUsingSelector:@selector(compare:)]; - for (NSString *key in sortedKeys) { - NSString *value = [valueDict objectForKey:key]; - // Escape them. - key = EscapeString(key, expansionInfo->allowReservedInEscape); - value = EscapeString(value, expansionInfo->allowReservedInEscape); - // Should variable names be used? - if ([expansionInfo->explode isEqual:@"+"]) { - key = [NSString stringWithFormat:@"%@.%@", variableName, key]; - } - if ((expressionOperator == '?' || expressionOperator == ';') - && ([value length] == 0)) { - [results addObject:key]; - } else { - NSString *pair = [NSString stringWithFormat:@"%@%@%@", - key, keyValueJoiner, value]; - [results addObject:pair]; - } - } - if ([results count]) { - // Use the default joiner unless there was no explode request, then a list - // always gets comma seperated. - NSString *joiner = expansionInfo->joiner; - if (!expansionInfo->explode) { - joiner = @","; - } - // Join the values. - NSString *joined = [results componentsJoinedByString:joiner]; - // 'form' style without an explode gets the variable name set to the - // joined list of values. - if ((expressionOperator == '?') && (expansionInfo->explode == nil)) { - return [NSString stringWithFormat:@"%@=%@", variableName, joined]; - } - return joined; - } - return nil; -} - -#pragma mark Public API - -+ (NSString *)expandTemplate:(NSString *)uriTemplate values:(id)valueProvider { - NSMutableString *result = - [NSMutableString stringWithCapacity:[uriTemplate length]]; - - NSScanner *scanner = [NSScanner scannerWithString:uriTemplate]; - [scanner setCharactersToBeSkipped:nil]; - - // Defaults have to live through the full evaluation, so if any are encoured - // they are reused throughout the expansion calls. - NSMutableDictionary *defaultValues = nil; - - // Pull out the expressions for processing. - while (![scanner isAtEnd]) { - NSString *skipped = nil; - // Find the next '{'. - if ([scanner scanUpToString:@"{" intoString:&skipped]) { - // Add anything before it to the result. - [result appendString:skipped]; - } - // Advance over the '{'. - [scanner scanString:@"{" intoString:nil]; - // Collect the expression. - NSString *expression = nil; - if ([scanner scanUpToString:@"}" intoString:&expression]) { - // Collect the trailing '}' on the expression. - BOOL hasTrailingBrace = [scanner scanString:@"}" intoString:nil]; - - // Parse the expression. - NSMutableArray *variables = nil; - unichar expressionOperator = 0; - if ([self parseExpression:expression - expressionOperator:&expressionOperator - variables:&variables - defaultValues:&defaultValues]) { - // Do the expansion. - NSString *substitution = [self expandVariables:variables - expressionOperator:expressionOperator - values:valueProvider - defaultValues:defaultValues]; - if (substitution) { - [result appendString:substitution]; - } - } else { - // Failed to parse, add the raw expression to the output. - if (hasTrailingBrace) { - [result appendFormat:@"{%@}", expression]; - } else { - [result appendFormat:@"{%@", expression]; - } - } - } else if (![scanner isAtEnd]) { - // Empty expression ('{}'). Copy over the opening brace and the trailing - // one will be copied by the next cycle of the loop. - [result appendString:@"{"]; - } - } - - return result; -} - -@end - -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 diff --git a/Foundation/GTMURITemplateTest.m b/Foundation/GTMURITemplateTest.m deleted file mode 100644 index ba2c8fb..0000000 --- a/Foundation/GTMURITemplateTest.m +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright (c) 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "GTMURITemplate.h" - -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 - -#import "GTMSenTestCase.h" -#import "GTMScriptRunner.h" - -@interface GTMURITemplateTest : GTMTestCase -- (NSDictionary *)loadTestSuitesNamed:(NSString *)testSuitesName; -- (NSDictionary *)parseJSONString:(NSString *)json error:(NSError **)error; -- (void)runTestSuites:(NSDictionary *)testSuites; -@end - -@implementation GTMURITemplateTest - -- (NSDictionary *)parseJSONString:(NSString *)json error:(NSError **)error { - NSDictionary *result = nil; - - // If we ever get a JSON parser in GTM (or the system gets one, next cat?), - // then we can skip this conversion dance. - - NSString *fileName = [NSString stringWithFormat:@"URITemplate_%u.plist", arc4random()]; - NSString *tempOutPath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName]; - - GTMScriptRunner *runner = [GTMScriptRunner runnerWithPython]; - NSString *command = [NSString stringWithFormat: - @"import Foundation\n" - @"import json\n" - @"str_of_json = \"\"\"%@\"\"\"\n" - @"Foundation.NSDictionary.dictionaryWithDictionary_(json.loads(str_of_json)).writeToFile_atomically_('%@', True)\n", - json, tempOutPath]; - NSString *errStr = nil; - NSString *outStr = [runner run:command standardError:&errStr]; - - STAssertNil(outStr, @"got something on stdout: %@", outStr); - STAssertNil(errStr, @"got something on stderr: %@", errStr); - result = [NSDictionary dictionaryWithContentsOfFile:tempOutPath]; - - [[NSFileManager defaultManager] removeItemAtPath:tempOutPath - error:NULL]; - - return result; -} - -- (NSDictionary *)loadTestSuitesNamed:(NSString *)testSuitesName { - NSBundle *testBundle = [NSBundle bundleForClass:[self class]]; - STAssertNotNil(testBundle, nil); - - NSString *testSuitesPath = [testBundle pathForResource:testSuitesName - ofType:nil]; - STAssertNotNil(testSuitesPath, @"%@ not found", testSuitesName); - - NSError *error = nil; - NSString *testSuitesStr = [NSString stringWithContentsOfFile:testSuitesPath - encoding:NSUTF8StringEncoding - error:&error]; - STAssertNil(error, @"Loading %@, error %@", testSuitesName, error); - STAssertNotNil(testSuitesStr, @"Loading %@", testSuitesName); - - NSDictionary *testSuites = [self parseJSONString:testSuitesStr - error:&error]; - STAssertNil(error, @"Parsing %@, error %@", testSuitesName, error); - STAssertNotNil(testSuites, @"failed to parse"); - - return testSuites; -} - -- (void)runTestSuites:(NSDictionary *)testSuites { - // The file holds a set of named suites... - for (NSString *suiteName in testSuites) { - NSDictionary *suite = [testSuites objectForKey:suiteName]; - // Each suite has variables and test cases... - NSDictionary *vars = [suite objectForKey:@"variables"]; - NSArray *testCases = [suite objectForKey:@"testcases"]; - STAssertTrue([vars count] != 0, @"'%@' no variables?", suiteName); - STAssertTrue([testCases count] != 0, @"'%@' no testcases?", suiteName); - NSUInteger idx = 0; - for (NSArray *testCase in testCases) { - // Each case is an array of the template and value... - STAssertEquals([testCase count], (NSUInteger)2, - @" test index %lu of '%@'", (unsigned long)idx, suiteName); - - NSString *testTemplate = [testCase objectAtIndex:0]; - NSString *expectedResult = [testCase objectAtIndex:1]; - - NSString *result = [GTMURITemplate expandTemplate:testTemplate - values:vars]; - STAssertEqualObjects(result, expectedResult, - @"template was '%@' (index %lu of '%@')", - testTemplate, (unsigned long)idx, suiteName); - ++idx; - } - } -} - -- (void)testRFCSuite { - // All of the examples from the RFC are in the python impl source as json - // test data. A copy is in the GTM tree as GTMURITemplateJSON.txt. The - // original can be found at: - // http://code.google.com/p/uri-templates/source/browse/trunk/testdata.json - NSDictionary *testSuites = [self loadTestSuitesNamed:@"GTMURITemplateRFCTests.json"]; - STAssertNotNil(testSuites, nil); - [self runTestSuites:testSuites]; -} - -- (void)testExtraSuite { - // These are follow up cases not explictly listed in the spec, but does - // as cases to confirm behaviors. The list was sent to the w3c uri list - // for confirmation: - // http://lists.w3.org/Archives/Public/uri/2010Sep/thread.html - NSDictionary *testSuites = [self loadTestSuitesNamed:@"GTMURITemplateExtraTests.json"]; - STAssertNotNil(testSuites, nil); - [self runTestSuites:testSuites]; -} - -@end - -#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 diff --git a/Foundation/GTMURLBuilder.h b/Foundation/GTMURLBuilder.h index daa8d88..f333ec4 100644 --- a/Foundation/GTMURLBuilder.h +++ b/Foundation/GTMURLBuilder.h @@ -34,6 +34,10 @@ #import <Foundation/Foundation.h> #import "GTMDefines.h" +#if (!TARGET_OS_IPHONE && defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10) \ +|| (TARGET_OS_IPHONE && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0) +__deprecated_msg("GTMURLBuilder is obsolete; update your app to use NSURLComponents queryItems property instead.") +#endif @interface GTMURLBuilder : NSObject { @private NSMutableDictionary *params_; diff --git a/Foundation/GTMURLBuilder.m b/Foundation/GTMURLBuilder.m index 31572e8..4f1a419 100644 --- a/Foundation/GTMURLBuilder.m +++ b/Foundation/GTMURLBuilder.m @@ -27,17 +27,6 @@ @synthesize baseURLString = baseURLString_; -#if (!TARGET_OS_IPHONE && defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10) \ - || (TARGET_OS_IPHONE && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0) -#if DEBUG -+ (void)load { - // Apps targeting iOS 8 and OS X 10.10 and higher should no longer use GTMURLBuilder. - NSLog(@"*** GTMURLBuilder is obsolete; update your app to use NSURLComponents" - @" queryItems property instead."); -} -#endif // DEBUG -#endif // iOS 8+/OS X 10.10+ - + (GTMURLBuilder *)builderWithString:(NSString *)URLString { GTMURLBuilder *URLBuilder = [[[GTMURLBuilder alloc] initWithString:URLString] autorelease]; diff --git a/Foundation/GTMURLBuilderTest.m b/Foundation/GTMURLBuilderTest.m index 4c0f128..0953a9e 100644 --- a/Foundation/GTMURLBuilderTest.m +++ b/Foundation/GTMURLBuilderTest.m @@ -29,34 +29,34 @@ GTMURLBuilder *URLBuilder = [[[GTMURLBuilder alloc] initWithString:@"http://google.com:8080/pathA/pathB?param=val"] autorelease]; - STAssertEqualStrings(@"http://google.com:8080/pathA/pathB?param=val", - [URLBuilder URLString], nil); - STAssertEqualStrings(@"val", [URLBuilder valueForParameter:@"param"], nil); + XCTAssertEqualStrings(@"http://google.com:8080/pathA/pathB?param=val", + [URLBuilder URLString]); + XCTAssertEqualStrings(@"val", [URLBuilder valueForParameter:@"param"]); URLBuilder = [GTMURLBuilder builderWithString: @"http://google.com:8080/pathA/pathB?param=val"]; - STAssertEqualStrings(@"http://google.com:8080/pathA/pathB?param=val", - [URLBuilder URLString], nil); - STAssertEqualStrings(@"val", [URLBuilder valueForParameter:@"param"], nil); + XCTAssertEqualStrings(@"http://google.com:8080/pathA/pathB?param=val", + [URLBuilder URLString]); + XCTAssertEqualStrings(@"val", [URLBuilder valueForParameter:@"param"]); URLBuilder = [GTMURLBuilder builderWithString: @"http://google.com:8080/path%3AA/pathB?param=val"]; - STAssertEqualStrings(@"http://google.com:8080/path%3AA/pathB?param=val", - [URLBuilder URLString], nil); - STAssertEqualStrings(@"val", [URLBuilder valueForParameter:@"param"], nil); + XCTAssertEqualStrings(@"http://google.com:8080/path%3AA/pathB?param=val", + [URLBuilder URLString]); + XCTAssertEqualStrings(@"val", [URLBuilder valueForParameter:@"param"]); URLBuilder = [GTMURLBuilder builderWithString: @"http://google.com:8080/pathA/pathB%2F?param=val"]; - STAssertEqualStrings(@"http://google.com:8080/pathA/pathB%2F?param=val", - [URLBuilder URLString], nil); - STAssertEqualStrings(@"val", [URLBuilder valueForParameter:@"param"], nil); + XCTAssertEqualStrings(@"http://google.com:8080/pathA/pathB%2F?param=val", + [URLBuilder URLString]); + XCTAssertEqualStrings(@"val", [URLBuilder valueForParameter:@"param"]); } - (void)testMailToHandling { GTMURLBuilder *URLBuilder = [GTMURLBuilder builderWithString:@"mailto:ytmapp-ios@google.com"]; [URLBuilder setValue:@"blah" forParameter:@"subject"]; - STAssertEqualStrings(@"mailto:ytmapp-ios@google.com?subject=blah", - [URLBuilder URLString], nil); + XCTAssertEqualStrings(@"mailto:ytmapp-ios@google.com?subject=blah", + [URLBuilder URLString]); } - (void)testIsEqualTo { @@ -66,12 +66,12 @@ [GTMURLBuilder builderWithString:@"http://google.com/pathA/pathB"]; [URLBuilderB setValue:@"d" forParameter:@"c"]; [URLBuilderB setValue:@"b" forParameter:@"a"]; - STAssertTrue([URLBuilderA isEqual:URLBuilderB], nil); + XCTAssertTrue([URLBuilderA isEqual:URLBuilderB]); [URLBuilderB setValue:@"c" forParameter:@"a"]; - STAssertFalse([URLBuilderA isEqual:URLBuilderB], nil); + XCTAssertFalse([URLBuilderA isEqual:URLBuilderB]); [URLBuilderB setValue:@"b" forParameter:@"a"]; [URLBuilderB setValue:@"f" forParameter:@"e"]; - STAssertFalse([URLBuilderA isEqual:URLBuilderB], nil); + XCTAssertFalse([URLBuilderA isEqual:URLBuilderB]); } - (void)testSetParameters { @@ -83,7 +83,7 @@ [NSDictionary dictionaryWithObjectsAndKeys:@"a", @"p1", @"b", @"p2", nil]; [URLBuilderA setParameters:params]; [URLBuilderA setValue:@"x" forParameter:@"p1"]; - STAssertTrue([URLBuilderA isEqual:URLBuilderB], nil); + XCTAssertTrue([URLBuilderA isEqual:URLBuilderB]); } - (void)testReplaceParameters { @@ -95,17 +95,17 @@ [NSDictionary dictionaryWithObjectsAndKeys:@"a", @"p1", @"b", @"p2", nil]; [URLBuilderA setParameters:params]; [URLBuilderA setValue:@"x" forParameter:@"p1"]; - STAssertTrue([URLBuilderA isEqual:URLBuilderB], nil); + XCTAssertTrue([URLBuilderA isEqual:URLBuilderB]); } - (void)testURLPathParsing { GTMURLBuilder *URLBuilder = [GTMURLBuilder builderWithString:@"http://google.com/"]; - STAssertEqualStrings(@"http://google.com/", [URLBuilder URLString], nil); + XCTAssertEqualStrings(@"http://google.com/", [URLBuilder URLString]); URLBuilder = [GTMURLBuilder builderWithString:@"http://google.com/pA/pB"]; - STAssertEqualStrings(@"http://google.com/pA/pB", [URLBuilder URLString], nil); + XCTAssertEqualStrings(@"http://google.com/pA/pB", [URLBuilder URLString]); URLBuilder = [GTMURLBuilder builderWithString:@"http://google.com/p%3AA/pB"]; - STAssertEqualStrings(@"http://google.com/p%3AA/pB", [URLBuilder URLString], nil); + XCTAssertEqualStrings(@"http://google.com/p%3AA/pB", [URLBuilder URLString]); } @end diff --git a/Foundation/GTMValidatingContainers.h b/Foundation/GTMValidatingContainers.h deleted file mode 100644 index e53b541..0000000 --- a/Foundation/GTMValidatingContainers.h +++ /dev/null @@ -1,196 +0,0 @@ -// -// GTMValidatingContainers.h -// -// Mutable containers that do verification of objects being added to them -// at runtime. Support for arrays, dictionaries and sets. -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -// GTMValidatingContainers are a set of mutable container classes that allow -// you to have a selector on a target that is called to verify that the objects -// being put into the container are valid. This can be controlled at compile -// time so that you don't take the performance hit in a release build using the -// GTM_CONTAINERS_VALIDATE macro. -// We have supplied validators for simple cases such as kindOfClass or -// conformsToProtocol. See GTMKindOfClassValidator et al. for details. -// -// Example of usage: -// id target = [GTMKindOfClassValidator validateAgainstClass:[NSString class]]; -// SEL selector = @selector(validateObject:forContainer:); -// GTMValidatingArray *array = [GTMValidatingArray validatingArrayWithTarget:target -// selector:selector]; -// [array addObject:@"foo"]; // Will be good -// [array addObject:[NSNumber numberWithInt:2]]; // Will fail -// -// By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and -// GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens -// when a validation fails. If you implement your own validators, you may want -// to control their internals using the same macros for consistency. -// -// Note that the validating collection types retain their targets. - -#import <Foundation/Foundation.h> -#import "GTMDefines.h" - -// By default we only validate containers in debug. If you want to validate -// in release as well, #define GTM_CONTAINERS_VALIDATE in a prefix or build -// settings. -#ifndef GTM_CONTAINERS_VALIDATE -#if DEBUG -#define GTM_CONTAINERS_VALIDATE 1 -#else // DEBUG -#define GTM_CONTAINERS_VALIDATE 0 -#endif // DEBUG -#endif // GTM_CONTAINERS_VALIDATE - -// If GTM_CONTAINERS_VALIDATE is on, and log and assert are both turned off -// (see below), the object that failed validation will just not be added -// to the container. - -// If you don't want log to occur on validation failure define -// GTM_CONTAINERS_VALIDATION_FAILED_LOG to 0 in a prefix or build settings. -#ifndef GTM_CONTAINERS_VALIDATION_FAILED_LOG -#define GTM_CONTAINERS_VALIDATION_FAILED_LOG GTM_CONTAINERS_VALIDATE -#endif // GTM_CONTAINERS_VALIDATION_FAILED_LOG - -// If you don't want an assert to occur on validation failure define -// GTM_CONTAINERS_VALIDATION_FAILED_ASSERT to 0 in a prefix or build settings. -#ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT -#define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT GTM_CONTAINERS_VALIDATE -#endif // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - -// Sometimes you get a container back from somebody else and want to validate -// that it contains what you think it contains. _GTMValidateContainer -// allows you to do exactly that. _GTMValidateContainer... give you specialty -// functions for doing common types of validations. These all inline to nothing -// if GTM_CONTAINERS_VALIDATE is not defined. -#if GTM_CONTAINERS_VALIDATE -void _GTMValidateContainer(id container, id target, SEL selector); -void _GTMValidateContainerContainsKindOfClass(id container, Class cls); -void _GTMValidateContainerContainsMemberOfClass(id container, Class cls); -void _GTMValidateContainerConformsToProtocol(id container, Protocol *prot); -void _GTMValidateContainerItemsRespondToSelector(id container, SEL sel); -#else -GTM_INLINE void _GTMValidateContainer(id container, id target, SEL selector) { -} -GTM_INLINE void _GTMValidateContainerContainsKindOfClass(id container, - Class cls) { -} -GTM_INLINE void _GTMValidateContainerContainsMemberOfClass(id container, - Class cls) { -} -GTM_INLINE void _GTMValidateContainerConformsToProtocol(id container, - Protocol *prot) { -} -GTM_INLINE void _GTMValidateContainerItemsRespondToSelector(id container, - SEL sel) { -} -#endif - - -// See comments near top of file for class description. -@interface GTMValidatingArray : NSMutableArray { -#if GTM_CONTAINERS_VALIDATE - NSMutableArray *embeddedContainer_; - id target_; - SEL selector_; -#endif // #if GTM_CONTAINERS_VALIDATE -} -+ (id)validatingArrayWithTarget:(id)target selector:(SEL)sel; -+ (id)validatingArrayWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel; -- (id)initValidatingWithTarget:(id)target selector:(SEL)sel; -- (id)initValidatingWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel; -@end - -// See comments near top of file for class description. -@interface GTMValidatingDictionary : NSMutableDictionary { -#if GTM_CONTAINERS_VALIDATE - NSMutableDictionary *embeddedContainer_; - id target_; - SEL selector_; -#endif // #if GTM_CONTAINERS_VALIDATE -} -+ (id)validatingDictionaryWithTarget:(id)target selector:(SEL)sel; -+ (id)validatingDictionaryWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel; -- (id)initValidatingWithTarget:(id)target selector:(SEL)sel; -- (id)initValidatingWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel; -@end - -// See comments near top of file for class description. -@interface GTMValidatingSet : NSMutableSet { -#if GTM_CONTAINERS_VALIDATE - NSMutableSet *embeddedContainer_; - id target_; - SEL selector_; -#endif // #if GTM_CONTAINERS_VALIDATE -} -+ (id)validatingSetWithTarget:(id)target selector:(SEL)sel; -+ (id)validatingSetWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel; -- (id)initValidatingWithTarget:(id)target selector:(SEL)sel; -- (id)initValidatingWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel; -@end - -#pragma mark - -#pragma mark Simple Common Validators -// See comments near top of file for examples of how these are used. -@protocol GTMContainerValidatorProtocol -- (BOOL)validateObject:(id)object forContainer:(id)container; -@end - -// Validates that a given object is a kind of class (instance of class or an -// instance of any class that inherits from that class) -@interface GTMKindOfClassValidator : NSObject <GTMContainerValidatorProtocol> { - Class cls_; -} -+ (id)validateAgainstClass:(Class)cls; -- (id)initWithClass:(Class)cls; -@end - -// Validates that a given object is a member of class (exact instance of class) -@interface GTMMemberOfClassValidator : NSObject <GTMContainerValidatorProtocol> { - Class cls_; -} -+ (id)validateAgainstClass:(Class)cls; -- (id)initWithClass:(Class)cls; -@end - -// Validates that a given object conforms to a protocol -@interface GTMConformsToProtocolValidator : NSObject <GTMContainerValidatorProtocol> { - Protocol* prot_; -} -+ (id)validateAgainstProtocol:(Protocol*)prot; -- (id)initWithProtocol:(Protocol*)prot; -@end - -// Validates that a given object responds to a given selector -@interface GTMRespondsToSelectorValidator : NSObject <GTMContainerValidatorProtocol> { - SEL sel_; -} -+ (id)validateAgainstSelector:(SEL)sel; -- (id)initWithSelector:(SEL)sel; -@end diff --git a/Foundation/GTMValidatingContainers.m b/Foundation/GTMValidatingContainers.m deleted file mode 100644 index a227ad4..0000000 --- a/Foundation/GTMValidatingContainers.m +++ /dev/null @@ -1,491 +0,0 @@ -// -// GTMValidatingContainers.m -// -// Mutable containers that do verification of objects being added to them -// at runtime. Support for arrays, dictionaries and sets. -// -// Documentation on subclassing class clusters (which we are doing) is here: -// http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/chapter_3_section_9.html#//apple_ref/doc/uid/TP40002974-CH4-DontLinkElementID_105 -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMValidatingContainers.h" - -#if GTM_CONTAINERS_VALIDATE - -#import "GTMDebugSelectorValidation.h" -#if GTM_IPHONE_SDK -#import <objc/message.h> -#import <objc/runtime.h> -#else // GTM_IPHONE_SDK -#import <objc/objc-runtime.h> -#endif // GTM_IPHONE_SDK - -GTM_INLINE BOOL VerifyObjectWithTargetAndSelectorForContainer(id anObject, - id target, - SEL selector, - id container) { - // We must take care here, since Intel leaves junk in high bytes of return - // register for predicates that return BOOL. - // For details see: - // http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_23.html - // and - // http://www.red-sweater.com/blog/320/abusing-objective-c-with-class#comment-83187 - BOOL isGood = ((BOOL (*)(id, SEL, id, id))objc_msgSend)(target, selector, - anObject, container); - if (!isGood) { -#if GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - _GTMDevAssert(isGood, @"%@ failed container verification for %@", - anObject, [container description]); -#endif // GTM_CONTAINERS_VALIDATION_FAILED_LOG -#if GTM_CONTAINERS_VALIDATION_FAILED_LOG - _GTMDevLog(@"%@ failed container verification for %@", anObject, - [container description]); -#endif // GTM_CONTAINERS_VALIDATION_FAILED_LOG - } - return isGood; -} - -GTM_INLINE void VerifySelectorOnTarget(SEL sel, id target) { - GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(target, - sel, - @encode(BOOL), - @encode(id), - @encode(id), - nil); -} - -void _GTMValidateContainerContainsKindOfClass(id container, Class cls) { - GTMKindOfClassValidator *validator; - validator = [GTMKindOfClassValidator validateAgainstClass:cls]; - _GTMValidateContainer(container, - validator, - @selector(validateObject:forContainer:)); -} - -void _GTMValidateContainerContainsMemberOfClass(id container, Class cls) { - GTMMemberOfClassValidator *validator; - validator = [GTMMemberOfClassValidator validateAgainstClass:cls]; - _GTMValidateContainer(container, - validator, - @selector(validateObject:forContainer:)); -} - -void _GTMValidateContainerConformsToProtocol(id container, Protocol* prot) { - GTMConformsToProtocolValidator *validator; - validator = [GTMConformsToProtocolValidator validateAgainstProtocol:prot]; - _GTMValidateContainer(container, - validator, - @selector(validateObject:forContainer:)); -} - -void _GTMValidateContainerItemsRespondToSelector(id container, SEL sel) { - GTMRespondsToSelectorValidator *validator; - validator = [GTMRespondsToSelectorValidator validateAgainstSelector:sel]; - _GTMValidateContainer(container, - validator, - @selector(validateObject:forContainer:)); -} - -void _GTMValidateContainer(id container, id target, SEL selector) { - if ([container respondsToSelector:@selector(objectEnumerator)]) { - NSEnumerator *enumerator = [container objectEnumerator]; - id val; - while ((val = [enumerator nextObject])) { - VerifyObjectWithTargetAndSelectorForContainer(val, - target, - selector, - container); - } - } else { -#if GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - _GTMDevAssert(0, @"container %@ does not respond to -objectEnumerator", - [container description]); -#endif // GTM_CONTAINERS_VALIDATION_FAILED_LOG -#if GTM_CONTAINERS_VALIDATION_FAILED_LOG - _GTMDevLog(@"container does not respont to -objectEnumerator: %@", - [container description]); -#endif // GTM_CONTAINERS_VALIDATION_FAILED_LOG - } -} -#endif // GTM_CONTAINERS_VALIDATE - -@implementation GTMValidatingArray - -+ (id)validatingArrayWithTarget:(id)target selector:(SEL)sel { - return [self validatingArrayWithCapacity:0 target:target selector:sel]; -} - -+ (id)validatingArrayWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel { - return [[[self alloc] initValidatingWithCapacity:0 - target:target - selector:sel] autorelease]; -} - -- (id)initValidatingWithTarget:(id)target selector:(SEL)sel { - return [self initValidatingWithCapacity:0 target:target selector:sel]; -} - -#if GTM_CONTAINERS_VALIDATE -- (id)initValidatingWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel { - if ((self = [super init])) { - embeddedContainer_ = [[NSMutableArray alloc] initWithCapacity:capacity]; - target_ = [target retain]; - selector_ = sel; - VerifySelectorOnTarget(selector_, target_); - } - return self; -} - -- (void)dealloc { - [embeddedContainer_ release]; - [target_ release]; - [super dealloc]; -} - -- (NSUInteger)count { - return [embeddedContainer_ count]; -} - -- (id)objectAtIndex:(NSUInteger)idx { - return [embeddedContainer_ objectAtIndex:idx]; -} - -- (void)addObject:(id)anObject { - if (VerifyObjectWithTargetAndSelectorForContainer(anObject, target_, - selector_, self)) { - [embeddedContainer_ addObject:anObject]; - } -} - -- (void)insertObject:(id)anObject atIndex:(NSUInteger)idx { - if (VerifyObjectWithTargetAndSelectorForContainer(anObject, target_, - selector_, self)) { - [embeddedContainer_ insertObject:anObject atIndex:idx]; - } -} - -- (void)removeLastObject { - [embeddedContainer_ removeLastObject]; -} - -- (void)removeObjectAtIndex:(NSUInteger)idx { - [embeddedContainer_ removeObjectAtIndex:idx]; -} - -- (void)replaceObjectAtIndex:(NSUInteger)idx withObject:(id)anObject { - if (VerifyObjectWithTargetAndSelectorForContainer(anObject, target_, - selector_, self)) { - [embeddedContainer_ replaceObjectAtIndex:idx withObject:anObject]; - } -} - -- (NSString*)description { - return [NSString stringWithFormat:@"%@ - %@", - NSStringFromClass([self class]), - [embeddedContainer_ description]]; -} - -#else // GTM_CONTAINERS_VALIDATE -- (id)initValidatingWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel { - if ((self = [super init])) { - [self release]; - } - return (GTMValidatingArray*)[[NSMutableArray alloc] initWithCapacity:capacity]; -} -#endif // GTM_CONTAINERS_VALIDATE -@end - -@implementation GTMValidatingDictionary -+ (id)validatingDictionaryWithTarget:(id)target selector:(SEL)sel { - return [self validatingDictionaryWithCapacity:0 target:target selector:sel]; -} - -+ (id)validatingDictionaryWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel { - return [[[self alloc] initValidatingWithCapacity:0 - target:target - selector:sel] autorelease]; -} - -- (id)initValidatingWithTarget:(id)target selector:(SEL)sel { - return [self initValidatingWithCapacity:0 target:target selector:sel]; -} - -#if GTM_CONTAINERS_VALIDATE -- (id)initValidatingWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel { - if ((self = [super init])) { - embeddedContainer_ = [[NSMutableDictionary alloc] initWithCapacity:capacity]; - target_ = [target retain]; - selector_ = sel; - VerifySelectorOnTarget(selector_, target_); - } - return self; -} - -- (void)dealloc { - [target_ release]; - [embeddedContainer_ release]; - [super dealloc]; -} - -- (NSUInteger)count { - return [embeddedContainer_ count]; -} - -- (NSEnumerator *)keyEnumerator { - return [embeddedContainer_ keyEnumerator]; -} - -- (id)objectForKey:(id)aKey { - return [embeddedContainer_ objectForKey:aKey]; -} - -- (void)removeObjectForKey:(id)aKey { - [embeddedContainer_ removeObjectForKey:aKey]; -} - -- (void)setObject:(id)anObject forKey:(id)aKey { - if (VerifyObjectWithTargetAndSelectorForContainer(anObject, target_, - selector_, self)) { - [embeddedContainer_ setObject:anObject forKey:aKey]; - } -} - -- (NSString*)description { - return [NSString stringWithFormat:@"%@ - %@", - NSStringFromClass([self class]), - [embeddedContainer_ description]]; -} - -#else // GTM_CONTAINERS_VALIDATE -- (id)initValidatingWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel { - if ((self = [super init])) { - [self release]; - } - return (GTMValidatingDictionary*)[[NSMutableDictionary alloc] - initWithCapacity:capacity]; - -} -#endif // GTM_CONTAINERS_VALIDATE -@end - -@implementation GTMValidatingSet -+ (id)validatingSetWithTarget:(id)target selector:(SEL)sel { - return [self validatingSetWithCapacity:0 target:target selector:sel]; -} - -+ (id)validatingSetWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel { - return [[[self alloc] initValidatingWithCapacity:0 - target:target - selector:sel] autorelease]; -} -- (id)initValidatingWithTarget:(id)target selector:(SEL)sel { - return [self initValidatingWithCapacity:0 target:target selector:sel]; -} - -#if GTM_CONTAINERS_VALIDATE -- (id)initValidatingWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel { - if ((self = [super init])) { - embeddedContainer_ = [[NSMutableSet alloc] initWithCapacity:capacity]; - target_ = [target retain]; - selector_ = sel; - VerifySelectorOnTarget(selector_, target_); - } - return self; -} - -- (void)dealloc { - [target_ release]; - [embeddedContainer_ release]; - [super dealloc]; -} - -- (NSUInteger)count { - return [embeddedContainer_ count]; -} - -- (id)member:(id)object { - return [embeddedContainer_ member:object]; -} - -- (NSEnumerator *)objectEnumerator { - return [embeddedContainer_ objectEnumerator]; -} - -- (void)addObject:(id)object { - if (object && VerifyObjectWithTargetAndSelectorForContainer(object, - target_, - selector_, - self)) { - [embeddedContainer_ addObject:object]; - } -} - -- (void)removeObject:(id)object { - [embeddedContainer_ removeObject:object]; -} - -- (NSString*)description { - return [NSString stringWithFormat:@"%@ - %@", - NSStringFromClass([self class]), - [embeddedContainer_ description]]; -} - -#else // GTM_CONTAINERS_VALIDATE -- (id)initValidatingWithCapacity:(NSUInteger)capacity - target:(id)target - selector:(SEL)sel { - if ((self = [super init])) { - [self release]; - } - return (GTMValidatingSet*)[[NSMutableSet alloc] initWithCapacity:capacity]; -} -#endif // GTM_CONTAINERS_VALIDATE -@end - -#pragma mark - -#pragma mark Simple Common Validators -@implementation GTMKindOfClassValidator -+ (id)validateAgainstClass:(Class)cls { - return [[[self alloc] initWithClass:cls] autorelease]; -} - -- (id)initWithClass:(Class)cls { -#if GTM_CONTAINERS_VALIDATE - if ((self = [super init])) { - if (!cls) { - _GTMDevLog(@"nil class"); - [self release]; - return nil; - } - cls_ = cls; - } - return self; -#else // GTM_CONTAINERS_VALIDATE - if ((self = [super init])) { - [self release]; - } - return nil; -#endif // GTM_CONTAINERS_VALIDATE -} - -- (BOOL)validateObject:(id)object forContainer:(id)container { - return [object isKindOfClass:cls_]; -} -@end - -@implementation GTMMemberOfClassValidator -+ (id)validateAgainstClass:(Class)cls { - return [[[self alloc] initWithClass:cls] autorelease]; -} - -- (id)initWithClass:(Class)cls { -#if GTM_CONTAINERS_VALIDATE - if ((self = [super init])) { - if (!cls) { - _GTMDevLog(@"nil class"); - [self release]; - return nil; - } - cls_ = cls; - } - return self; -#else // GTM_CONTAINERS_VALIDATE - if ((self = [super init])) { - [self release]; - } - return nil; -#endif // GTM_CONTAINERS_VALIDATE -} - -- (BOOL)validateObject:(id)object forContainer:(id)container { - return [object isMemberOfClass:cls_]; -} -@end - -@implementation GTMConformsToProtocolValidator -+ (id)validateAgainstProtocol:(Protocol*)prot { - return [[[self alloc] initWithProtocol:prot] autorelease]; -} - -- (id)initWithProtocol:(Protocol*)prot { -#if GTM_CONTAINERS_VALIDATE - if ((self = [super init])) { - if (!prot) { - _GTMDevLog(@"nil protocol"); - [self release]; - return nil; - } - prot_ = prot; - } - return self; -#else // GTM_CONTAINERS_VALIDATE - if ((self = [super init])) { - [self release]; - } - return nil; -#endif // GTM_CONTAINERS_VALIDATE -} - -- (BOOL)validateObject:(id)object forContainer:(id)container { - return [object conformsToProtocol:prot_]; -} -@end - -@implementation GTMRespondsToSelectorValidator -+ (id)validateAgainstSelector:(SEL)sel { - return [[[self alloc] initWithSelector:sel] autorelease]; -} - -- (id)initWithSelector:(SEL)sel { -#if GTM_CONTAINERS_VALIDATE - if ((self = [super init])) { - if (!sel) { - _GTMDevLog(@"nil selector"); - [self release]; - return nil; - } - sel_ = sel; - } - return self; -#else // GTM_CONTAINERS_VALIDATE - if ((self = [super init])) { - [self release]; - } - return nil; -#endif // GTM_CONTAINERS_VALIDATE -} - -- (BOOL)validateObject:(id)object forContainer:(id)container { - return [object respondsToSelector:sel_]; -} -@end diff --git a/Foundation/GTMValidatingContainersTest.m b/Foundation/GTMValidatingContainersTest.m deleted file mode 100644 index 806ecb0..0000000 --- a/Foundation/GTMValidatingContainersTest.m +++ /dev/null @@ -1,378 +0,0 @@ -// -// GTMValidatingContainersTest.m -// -// Copyright 2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMValidatingContainers.h" -#import "GTMSenTestCase.h" -#import "GTMUnitTestDevLog.h" - -#pragma mark Test Support Declarations -@protocol GTMVCTestProtocol -@end - -@interface GTMVCTestClass : NSObject -+ (id)instance; -@end - -@interface GTMVCTestSubClass : GTMVCTestClass <GTMVCTestProtocol> -- (void)foo; -@end - -@interface GTMVCValidatingTests : GTMTestCase { - GTMVCTestClass *testClass_; - GTMVCTestSubClass *testSubClass_; -} -@end - -@interface GTMVCValidatorTests : GTMVCValidatingTests -@end - -@interface GTMVCContainerTests : GTMVCValidatingTests { - GTMConformsToProtocolValidator *validator_; - SEL selector_; -} -@end - -@interface GTMVCArrayTests : GTMVCContainerTests -@end - -@interface GTMVCDictionaryTests : GTMVCContainerTests -@end - -@interface GTMVCSetTests : GTMVCContainerTests -@end - -@interface GTMValidateContainerTests : GTMTestCase -@end - -#pragma mark - -#pragma mark Test Support Definitions - -@implementation GTMVCTestClass -+ (id)instance { - return [[[self alloc] init] autorelease]; -} - -- (NSString*)description { - return NSStringFromClass([self class]); -} -@end - -@implementation GTMVCTestSubClass -- (void)foo { -} -@end - -@implementation GTMVCContainerTests -- (void)setUp { - [super setUp]; - Protocol *prot = @protocol(GTMVCTestProtocol); - validator_ = [[GTMConformsToProtocolValidator alloc] initWithProtocol:prot]; - selector_ = @selector(validateObject:forContainer:); -} - -- (void)tearDown { - [validator_ release]; - [super tearDown]; -} -@end - -@implementation GTMVCValidatingTests - -- (void)setUp { - [super setUp]; - testClass_ = [[GTMVCTestClass alloc] init]; - testSubClass_ = [[GTMVCTestSubClass alloc] init]; -} - -- (void)tearDown { - [testClass_ release]; - [testSubClass_ release]; - [super tearDown]; -} - -@end - -@implementation GTMVCValidatorTests - -- (void)testKindOfClassValidator { -#if GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - [GTMUnitTestDevLog expectString:@"nil class"]; - GTMKindOfClassValidator *validator; - validator = [GTMKindOfClassValidator validateAgainstClass:nil]; - STAssertNil(validator, @"should be nil"); - - Class cls = [GTMVCTestClass class]; - validator = [GTMKindOfClassValidator validateAgainstClass:cls]; - STAssertNotNil(validator, @"should be valid"); - - BOOL isGood = [validator validateObject:testClass_ forContainer:nil]; - STAssertTrue(isGood, @"should be validated"); - - isGood = [validator validateObject:testSubClass_ forContainer:nil]; - STAssertTrue(isGood, @"should be validated"); - - isGood = [validator validateObject:[NSNumber numberWithInt:0] - forContainer:nil]; - STAssertFalse(isGood, @"should fail"); -#else // GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - GTMKindOfClassValidator *validator; - validator = [GTMKindOfClassValidator validateAgainstClass:nil]; - STAssertNil(validator, @"should be nil"); - - Class cls = [GTMVCTestClass class]; - validator = [GTMKindOfClassValidator validateAgainstClass:cls]; - STAssertNil(validator, @"should be nil"); -#endif // GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT -} - -- (void)testMemberOfClassValidator { -#if GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - [GTMUnitTestDevLog expectString:@"nil class"]; - GTMMemberOfClassValidator *validator; - validator = [GTMMemberOfClassValidator validateAgainstClass:nil]; - STAssertNil(validator, @"should be nil"); - - Class cls = [GTMVCTestClass class]; - validator = [GTMMemberOfClassValidator validateAgainstClass:cls]; - STAssertNotNil(validator, @"should be valid"); - - BOOL isGood = [validator validateObject:testClass_ forContainer:nil]; - STAssertTrue(isGood, @"should be validated"); - - isGood = [validator validateObject:testSubClass_ forContainer:nil]; - STAssertFalse(isGood, @"should fail"); - - isGood = [validator validateObject:nil forContainer:nil]; - STAssertFalse(isGood, @"should fail"); - - isGood = [validator validateObject:[NSNumber numberWithInt:0] - forContainer:nil]; - STAssertFalse(isGood, @"should fail"); -#else // GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - GTMMemberOfClassValidator *validator; - validator = [GTMMemberOfClassValidator validateAgainstClass:nil]; - STAssertNil(validator, @"should be nil"); - - Class cls = [GTMVCTestClass class]; - validator = [GTMMemberOfClassValidator validateAgainstClass:cls]; - STAssertNil(validator, @"should be nil"); -#endif // GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT -} - -- (void)testConformsToProtocolValidator { -#if GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - [GTMUnitTestDevLog expectString:@"nil protocol"]; - GTMConformsToProtocolValidator *validator; - validator = [GTMConformsToProtocolValidator validateAgainstProtocol:nil]; - STAssertNil(validator, @"should be nil"); - - Protocol *prot = @protocol(GTMVCTestProtocol); - validator = [GTMConformsToProtocolValidator validateAgainstProtocol:prot]; - STAssertNotNil(validator, @"should be valid"); - - BOOL isGood = [validator validateObject:testClass_ forContainer:nil]; - STAssertFalse(isGood, @"should fail"); - - isGood = [validator validateObject:testSubClass_ forContainer:nil]; - STAssertTrue(isGood, @"should succeed"); - - isGood = [validator validateObject:nil forContainer:nil]; - STAssertFalse(isGood, @"should fail"); -#else // GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - GTMConformsToProtocolValidator *validator; - validator = [GTMConformsToProtocolValidator validateAgainstProtocol:nil]; - STAssertNil(validator, @"should be nil"); - - Protocol *prot = @protocol(GTMVCTestProtocol); - validator = [GTMConformsToProtocolValidator validateAgainstProtocol:prot]; - STAssertNil(validator, @"should be nil"); -#endif // GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT -} - -- (void)testRespondsToSelectorValidator { -#if GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - [GTMUnitTestDevLog expectString:@"nil selector"]; - GTMRespondsToSelectorValidator *validator; - validator = [GTMRespondsToSelectorValidator validateAgainstSelector:nil]; - STAssertNil(validator, @"should be nil"); - - SEL sel = @selector(foo); - validator = [GTMRespondsToSelectorValidator validateAgainstSelector:sel]; - STAssertNotNil(validator, @"should be valid"); - - BOOL isGood = [validator validateObject:testClass_ forContainer:nil]; - STAssertFalse(isGood, @"should fail"); - - isGood = [validator validateObject:testSubClass_ forContainer:nil]; - STAssertTrue(isGood, @"should succeed"); - - isGood = [validator validateObject:nil forContainer:nil]; - STAssertFalse(isGood, @"should fail"); -#else // GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT - GTMRespondsToSelectorValidator *validator; - validator = [GTMRespondsToSelectorValidator validateAgainstSelector:nil]; - STAssertNil(validator, @"should be nil"); - - SEL sel = @selector(foo); - validator = [GTMRespondsToSelectorValidator validateAgainstSelector:sel]; - STAssertNil(validator, @"should be nil"); -#endif // GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT -} - - -@end - -@implementation GTMVCArrayTests -- (void)testContainer { - GTMValidatingArray *array; - array = [GTMValidatingArray validatingArrayWithTarget:validator_ - selector:selector_]; - STAssertNotNil(array, @"should be valid"); - - array = [[[GTMValidatingArray alloc] initValidatingWithTarget:validator_ - selector:selector_] autorelease]; - STAssertNotNil(array, @"should be valid"); - - [GTMUnitTestDevLog expectPattern:@"GTMVCTestClass failed container verification for GTMValidatingArray .*"]; - [array addObject:testSubClass_]; - [array addObject:testClass_]; - STAssertEquals([array objectAtIndex:0], testSubClass_, @""); - - [GTMUnitTestDevLog expectPattern:@"GTMVCTestClass failed container verification for GTMValidatingArray .*"]; - [array insertObject:testClass_ atIndex:0]; - [array insertObject:testSubClass_ atIndex:0]; - [GTMUnitTestDevLog expectPattern:@"GTMVCTestClass failed container verification for GTMValidatingArray .*"]; - [array replaceObjectAtIndex:0 withObject:testClass_]; - [array replaceObjectAtIndex:0 withObject:testSubClass_]; - [array removeLastObject]; - [array removeObjectAtIndex:0]; - NSUInteger expectedCount = 0U; -#if !(GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT) - // If we're not validating, we don't expect any logs - [GTMUnitTestDevLog resetExpectedLogs]; - expectedCount = 2U; -#endif // !(GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT) - STAssertEquals([array count], expectedCount, @"should have no objects left"); - -} -@end - -@implementation GTMVCDictionaryTests -- (void)testContainer { - GTMValidatingDictionary *dictionary; - dictionary = [GTMValidatingDictionary validatingDictionaryWithTarget:validator_ - selector:selector_]; - STAssertNotNil(dictionary, @"should be valid"); - - dictionary = [[[GTMValidatingDictionary alloc] initValidatingWithTarget:validator_ - selector:selector_] autorelease]; - STAssertNotNil(dictionary, @"should be valid"); - - [GTMUnitTestDevLog expectPattern:@"GTMVCTestClass failed container verification for GTMValidatingDictionary .*"]; - [dictionary setObject:testClass_ forKey:@"Key1"]; - [dictionary setObject:testSubClass_ forKey:@"Key2"]; - STAssertEquals([dictionary objectForKey:@"Key2"], testSubClass_, @""); - STAssertNotNil([dictionary keyEnumerator], @""); - - [dictionary removeObjectForKey:@"Key2"]; - [dictionary removeObjectForKey:@"Key1"]; - STAssertEquals([dictionary count], (NSUInteger)0, @"should have no objects left"); - - // So we get full code coverage - [testSubClass_ foo]; -#if !(GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT) - // If we're not validating, we don't expect any logs - [GTMUnitTestDevLog resetExpectedLogs]; -#endif // !(GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT) -} -@end - -@implementation GTMVCSetTests -- (void)testContainer { - GTMValidatingSet *set; - set = [GTMValidatingSet validatingSetWithTarget:validator_ - selector:selector_]; - STAssertNotNil(set, @"should be valid"); - - set = [[[GTMValidatingSet alloc] initValidatingWithTarget:validator_ - selector:selector_] autorelease]; - STAssertNotNil(set, @"should be valid"); - - [GTMUnitTestDevLog expectPattern:@"GTMVCTestClass failed container verification for GTMValidatingSet .*"]; - [set addObject:testClass_]; - [set addObject:testSubClass_]; - STAssertEqualObjects([set member:testSubClass_], testSubClass_, @""); - STAssertNotNil([set objectEnumerator], @""); - - [set removeObject:testClass_]; - [set removeObject:testSubClass_]; -#if !(GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT) - // If we're not validating, we don't expect any logs - [GTMUnitTestDevLog resetExpectedLogs]; -#endif // !(GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT) - STAssertEquals([set count], (NSUInteger)0, @"should have no objects left"); -} -@end - -@implementation GTMValidateContainerTests -- (void)testValidatingContainers { - NSDictionary *homogenousDict = [NSDictionary dictionaryWithObjectsAndKeys: - [GTMVCTestSubClass instance], @"key1", - [GTMVCTestSubClass instance], @"key2", - nil]; - NSDictionary *heterogenousDict = [NSDictionary dictionaryWithObjectsAndKeys: - [GTMVCTestClass instance], @"key1", - [GTMVCTestSubClass instance], @"key2", - nil]; - - // Test bad container - [GTMUnitTestDevLog expectPattern:@"container does not respont to -objectEnumerator: .*"]; - _GTMValidateContainerContainsKindOfClass([NSString string], - [GTMVCTestSubClass class]); - - _GTMValidateContainerContainsKindOfClass(homogenousDict, - [GTMVCTestSubClass class]); - _GTMValidateContainerContainsKindOfClass(heterogenousDict, - [GTMVCTestClass class]); - [GTMUnitTestDevLog expectPattern:@"GTMVCTestClass failed container verification for .*"]; - _GTMValidateContainerContainsKindOfClass(heterogenousDict, - [GTMVCTestSubClass class]); - - _GTMValidateContainerContainsMemberOfClass(homogenousDict, - [GTMVCTestSubClass class]); - [GTMUnitTestDevLog expectPattern:@"GTMVCTestSubClass failed container verification for .*"]; - _GTMValidateContainerContainsMemberOfClass(heterogenousDict, - [GTMVCTestClass class]); - - _GTMValidateContainerConformsToProtocol(homogenousDict, - @protocol(GTMVCTestProtocol)); - [GTMUnitTestDevLog expectPattern:@"GTMVCTestClass failed container verification for .*"]; - _GTMValidateContainerConformsToProtocol(heterogenousDict, - @protocol(GTMVCTestProtocol)); - - _GTMValidateContainerItemsRespondToSelector(homogenousDict, - @selector(foo)); - [GTMUnitTestDevLog expectPattern:@"GTMVCTestClass failed container verification for .*"]; - _GTMValidateContainerItemsRespondToSelector(heterogenousDict, - @selector(foo)); -#if !(GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT) - // If we're not validating, we don't expect any logs - [GTMUnitTestDevLog resetExpectedLogs]; -#endif // !(GTM_CONTAINERS_VALIDATE && GTM_CONTAINERS_VALIDATION_FAILED_LOG && !GTM_CONTAINERS_VALIDATION_FAILED_ASSERT) -} -@end diff --git a/Foundation/TestData/GTMURITemplateExtraTests.json b/Foundation/TestData/GTMURITemplateExtraTests.json deleted file mode 100644 index e84ab90..0000000 --- a/Foundation/TestData/GTMURITemplateExtraTests.json +++ /dev/null @@ -1,222 +0,0 @@ -{ - "No varspec (section 3.3, paragraph 3)" : - { - "variables": { - "var" : "value" - }, - "testcases" : [ - ["{}", "{}"], - ["{,}", "{,}"], - ["{,,}", "{,,}"] - ] - }, - "Missing closing brace (section 3.3 paragraph 4)" : - { - "variables": { - "var" : "value", - "hello" : "Hello World!", - "list" : [ "val1", "val2", "val3" ], - "keys" : {"key1": "val1", "key2": "val2"}, - "x" : "1024", - "y" : "768" - }, - "testcases" : [ - ["{var", "value"], - ["{hello", "Hello%20World%21"], - ["{x,y", "1024,768"], - ["{var=default", "value"], - ["{undef=default", "default"], - ["{list", "val1,val2,val3"], - ["{list*", "val1,val2,val3"], - ["{list+", "list.val1,list.val2,list.val3"], - ["{keys", "key1,val1,key2,val2"], - ["{keys*", "key1,val1,key2,val2"], - ["{keys+", "keys.key1,val1,keys.key2,val2"] - ] - }, - "varspec of only operator and explodes (section 3.3?)" : - { - "variables": { - "var" : "value" - }, - "testcases" : [ - ["{+}", "{+}"], - ["{;}", "{;}"], - ["{?}", "{?}"], - ["{/}", "{/}"], - ["{.}", "{.}"], - ["{+,}", "{+,}"], - ["{;,}", "{;,}"], - ["{?,}", "{?,}"], - ["{/,}", "{/,}"], - ["{.,}", "{.,}"], - ["{++}", "{++}"], - ["{;+}", "{;+}"], - ["{?+}", "{?+}"], - ["{/+}", "{/+}"], - ["{.+}", "{.+}"], - ["{+*}", "{+*}"], - ["{;*}", "{;*}"], - ["{?*}", "{?*}"], - ["{/*}", "{/*}"], - ["{.*}", "{.*}"] - ] - }, - "One good varspec and bad varspecs (section 3.3, paragraph 3?)" : - { - "variables": { - "var" : "value" - }, - "testcases" : [ - ["{var,}", "value"], - ["{,var}", "value"], - ["{,var,,}", "value"], - ["{+var,,}", "value"], - ["{;var,,}", ";var=value"], - ["{?var,,}", "?var=value"], - ["{/var,,}", "/value"], - ["{.var,,}", ".value"], - ["{+,var,}", "value"], - ["{;,var,}", ";var=value"], - ["{?,var,}", "?var=value"], - ["{/,var,}", "/value"], - ["{.,var,}", ".value"], - ["{+,,var}", "value"], - ["{;,,var}", ";var=value"], - ["{?,,var}", "?var=value"], - ["{/,,var}", "/value"], - ["{.,,var}", ".value"] - ] - }, - "Multiple undefined variables (section 3.4)" : - { - "variables": { - "var" : "value" - }, - "testcases" : [ - ["{undef1,undef2}", ""], - ["{+undef1,undef2}", ""], - ["{;undef1,undef2}", ""], - ["{?undef1,undef2}", ""], - ["{/undef1,undef2}", ""], - ["{.undef1,undef2}", ""] - ] - }, - "Default with variable in varspec (just reported like above cases)" : - { - "variables": { - "var" : "value" - }, - "testcases" : [ - ["{=foo}", "{=foo}"] - ] - }, - "varspec with bad partial (partial gets ignored)" : - { - "variables": { - "var" : "value" - }, - "testcases" : [ - ["{var:}", "value"], - ["{var^}", "value"] - ] - }, - "Default of empty string and edge cases with empty strings" : - { - "variables": { - "empty" : "", - "x" : "1024", - "y" : "768" - }, - "testcases" : [ - ["{empty}", ""], - ["{;x,empty,y}", ";x=1024;empty;y=768"], - ["{?x,empty,y}", "?x=1024&empty&y=768"], - ["{x,empty,y}", "1024,,768"], - ["{+x,empty,y}", "1024,,768"], - ["{/x,empty,y}", "/1024//768"], - ["{.x,empty,y}", ".1024..768"], - ["{undef=}", ""], - ["{;x,undef=,y}", ";x=1024;undef;y=768"], - ["{?x,undef=,y}", "?x=1024&undef&y=768"], - ["{x,undef=,y}", "1024,,768"], - ["{+x,undef=,y}", "1024,,768"], - ["{/x,undef=,y}", "/1024//768"], - ["{.x,undef=,y}", ".1024..768"] - ] - }, - "Two defaults for one variable" : - { - "variables": { - "y" : "768" - }, - "testcases" : [ - ["1{undef=a}2{undef=b}3", "1a2b3"], - ["0{undef}1{undef=a}2{undef}3{undef=b}4{undef}5", "01a2a3b4b5"] - ] - }, - "Empty strings within arrays and associative arrays" : - { - "variables": { - "list" : [ "val1", "", "val3" ], - "keysA" : {"key1": "", "key2": "val2"}, - "keysB" : {"key1": "val1", "": "val2"} - }, - "testcases" : [ - ["{list}", "val1,,val3"], - ["{list*}", "val1,,val3"], - ["{list+}", "list.val1,list.,list.val3"], - ["{keysA}", "key1,,key2,val2"], - ["{keysA*}", "key1,,key2,val2"], - ["{keysA+}", "keysA.key1,,keysA.key2,val2"], - ["{keysB}", ",val2,key1,val1"], - ["{keysB*}", ",val2,key1,val1"], - ["{keysB+}", "keysB.,val2,keysB.key1,val1"], - ["{+list}", "val1,,val3"], - ["{+list*}", "val1,,val3"], - ["{+list+}", "list.val1,list.,list.val3"], - ["{+keysA}", "key1,,key2,val2"], - ["{+keysA*}", "key1,,key2,val2"], - ["{+keysA+}", "keysA.key1,,keysA.key2,val2"], - ["{+keysB}", ",val2,key1,val1"], - ["{+keysB*}", ",val2,key1,val1"], - ["{+keysB+}", "keysB.,val2,keysB.key1,val1"], - ["{;list}", ";val1,,val3"], - ["{;list*}", ";val1;;val3"], - ["{;list+}", ";list=val1;list=;list=val3"], - ["{;keysA}", ";key1,key2,val2"], - ["{;keysA*}", ";key1;key2=val2"], - ["{;keysA+}", ";keysA.key1;keysA.key2=val2"], - ["{;keysB}", ";,val2,key1,val1"], - ["{;keysB*}", ";=val2;key1=val1"], - ["{;keysB+}", ";keysB.=val2;keysB.key1=val1"], - ["{?list}", "?list=val1,,val3"], - ["{?list*}", "?val1&&val3"], - ["{?list+}", "?list=val1&list=&list=val3"], - ["{?keysA}", "?keysA=key1,key2,val2"], - ["{?keysA*}", "?key1&key2=val2"], - ["{?keysA+}", "?keysA.key1&keysA.key2=val2"], - ["{?keysB}", "?keysB=,val2,key1,val1"], - ["{?keysB*}", "?=val2&key1=val1"], - ["{?keysB+}", "?keysB.=val2&keysB.key1=val1"], - ["{/list}", "/val1,,val3"], - ["{/list*}", "/val1//val3"], - ["{/list+}", "/list.val1/list./list.val3"], - ["{/keysA}", "/key1,,key2,val2"], - ["{/keysA*}", "/key1//key2/val2"], - ["{/keysA+}", "/keysA.key1//keysA.key2/val2"], - ["{/keysB}", "/,val2,key1,val1"], - ["{/keysB*}", "//val2/key1/val1"], - ["{/keysB+}", "/keysB./val2/keysB.key1/val1"], - ["X{.list}", "X.val1,,val3"], - ["X{.list*}", "X.val1..val3"], - ["X{.list+}", "X.list.val1.list..list.val3"], - ["X{.keysA}", "X.key1,,key2,val2"], - ["X{.keysA*}", "X.key1..key2.val2"], - ["X{.keysA+}", "X.keysA.key1..keysA.key2.val2"], - ["X{.keysB}", "X.,val2,key1,val1"], - ["X{.keysB*}", "X..val2.key1.val1"], - ["X{.keysB+}", "X.keysB..val2.keysB.key1.val1"] - ] - } -} diff --git a/Foundation/TestData/GTMURITemplateRFCTests.json b/Foundation/TestData/GTMURITemplateRFCTests.json deleted file mode 100644 index 03fa22d..0000000 --- a/Foundation/TestData/GTMURITemplateRFCTests.json +++ /dev/null @@ -1,131 +0,0 @@ -{ - "Test Suite 1" : - { - "variables": { - "var" : "value", - "hello" : "Hello World!", - "empty" : "", - "list" : [ "val1", "val2", "val3" ], - "keys" : {"key1": "val1", "key2": "val2"}, - "path" : "/foo/bar", - "x" : "1024", - "y" : "768" - }, - "testcases" : [ - ["{var}", "value"], - ["{hello}", "Hello%20World%21"], - ["{path}/here", "%2Ffoo%2Fbar/here"], - ["{x,y}", "1024,768"], - ["{var=default}", "value"], - ["{undef=default}", "default"], - ["{list}", "val1,val2,val3"], - ["{list*}", "val1,val2,val3"], - ["{list+}", "list.val1,list.val2,list.val3"], - ["{keys}", "key1,val1,key2,val2"], - ["{keys*}", "key1,val1,key2,val2"], - ["{keys+}", "keys.key1,val1,keys.key2,val2"], - ["{+var}", "value"], - ["{+hello}", "Hello%20World!"], - ["{+path}/here", "/foo/bar/here"], - ["{+path,x}/here", "/foo/bar,1024/here"], - ["{+path}{x}/here", "/foo/bar1024/here"], - ["{+empty}/here", "/here"], - ["{+undef}/here", "/here"], - ["{+list}", "val1,val2,val3"], - ["{+list*}", "val1,val2,val3"], - ["{+list+}", "list.val1,list.val2,list.val3"], - ["{+keys}", "key1,val1,key2,val2"], - ["{+keys*}", "key1,val1,key2,val2"], - ["{+keys+}", "keys.key1,val1,keys.key2,val2"], - ["{;x,y}", ";x=1024;y=768"], - ["{;x,y,empty}", ";x=1024;y=768;empty"], - ["{;x,y,undef}", ";x=1024;y=768"], - ["{;list}", ";val1,val2,val3"], - ["{;list*}", ";val1;val2;val3"], - ["{;list+}", ";list=val1;list=val2;list=val3"], - ["{;keys}", ";key1,val1,key2,val2"], - ["{;keys*}", ";key1=val1;key2=val2"], - ["{;keys+}", ";keys.key1=val1;keys.key2=val2"], - ["{?x,y}", "?x=1024&y=768"], - ["{?x,y,empty}", "?x=1024&y=768&empty"], - ["{?x,y,undef}", "?x=1024&y=768"], - ["{?list}", "?list=val1,val2,val3"], - ["{?list*}", "?val1&val2&val3"], - ["{?list+}", "?list=val1&list=val2&list=val3"], - ["{?keys}", "?keys=key1,val1,key2,val2"], - ["{?keys*}", "?key1=val1&key2=val2"], - ["{?keys+}", "?keys.key1=val1&keys.key2=val2"], - ["{/var}", "/value"], - ["{/var,empty}", "/value/"], - ["{/var,undef}", "/value"], - ["{/list}", "/val1,val2,val3"], - ["{/list*}", "/val1/val2/val3"], - ["{/list*,x}", "/val1/val2/val3/1024"], - ["{/list+}", "/list.val1/list.val2/list.val3"], - ["{/keys}", "/key1,val1,key2,val2"], - ["{/keys*}", "/key1/val1/key2/val2"], - ["{/keys+}", "/keys.key1/val1/keys.key2/val2"], - ["X{.var}", "X.value"], - ["X{.empty}", "X"], - ["X{.undef}", "X"], - ["X{.list}", "X.val1,val2,val3"], - ["X{.list*}", "X.val1.val2.val3"], - ["X{.list*,x}", "X.val1.val2.val3.1024"], - ["X{.list+}", "X.list.val1.list.val2.list.val3"], - ["X{.keys}", "X.key1,val1,key2,val2"], - ["X{.keys*}", "X.key1.val1.key2.val2"], - ["X{.keys+}", "X.keys.key1.val1.keys.key2.val2"] - ] - }, - "Test Suite 2" : - { - "variables": { - "var" : "value", - "empty" : "", - "name" : [ "Fred", "Wilma", "Pebbles" ], - "favs" : {"color":"red", "volume": "high"}, - "empty_list" : [], - "empty_keys" : {} - }, - "testcases" : [ - ["{var=default}", "value"], - ["{undef=default}", "default"], - ["x{empty}y", "xy"], - ["x{empty=_}y", "xy"], - ["x{undef}y", "xy"], - ["x{undef=_}y", "x_y"], - ["x{empty_list}y", "xy"], - ["x{empty_list=_}y", "x_y"], - ["x{empty_list*}y", "xy"], - ["x{empty_list*=_}y", "x_y"], - ["x{empty_list+}y", "xy"], - ["x{empty_list+=_}y", "x_y"], - ["x{empty_keys}y", "xy"], - ["x{empty_keys=_}y", "x_y"], - ["x{empty_keys*}y", "xy"], - ["x{empty_keys*=_}y", "x_y"], - ["x{empty_keys+}y", "xy"], - ["x{empty_keys+=_}y", "x_y"], - ["x{?name=none}", "x?name=Fred,Wilma,Pebbles"], - ["x{?favs=none}", "x?favs=color,red,volume,high"], - ["x{?favs*=none}", "x?color=red&volume=high"], - ["x{?favs+=none}", "x?favs.color=red&favs.volume=high"], - ["x{?undef}", "x"], - ["x{?undef=none}", "x?undef=none"], - ["x{?empty}", "x?empty"], - ["x{?empty=none}", "x?empty"], - ["x{?empty_list}", "x"], - ["x{?empty_list=none}", "x?empty_list=none"], - ["x{?empty_list*}", "x"], - ["x{?empty_list*=none}", "x?empty_list=none"], - ["x{?empty_list+}", "x"], - ["x{?empty_list+=none}", "x?empty_list=none"], - ["x{?empty_keys}", "x"], - ["x{?empty_keys=none}", "x?empty_keys=none"], - ["x{?empty_keys*}", "x"], - ["x{?empty_keys*=none}", "x?empty_keys=none"], - ["x{?empty_keys+}", "x"], - ["x{?empty_keys+=none}", "x?empty_keys=none"] - ] - } -} |