diff options
-rw-r--r-- | Foundation/GTMHTTPFetcher.h | 4 | ||||
-rw-r--r-- | Foundation/GTMNSDictionary+URLArguments.h | 30 | ||||
-rw-r--r-- | Foundation/GTMNSDictionary+URLArguments.m | 40 | ||||
-rw-r--r-- | Foundation/GTMNSDictionary+URLArgumentsTest.m | 54 | ||||
-rw-r--r-- | Foundation/GTMNSString+URLArguments.h | 41 | ||||
-rw-r--r-- | Foundation/GTMNSString+URLArguments.m | 45 | ||||
-rw-r--r-- | Foundation/GTMNSString+URLArgumentsTest.m | 94 | ||||
-rw-r--r-- | Foundation/GTMRegex.h | 2 | ||||
-rw-r--r-- | GTM.xcodeproj/project.pbxproj | 24 | ||||
-rw-r--r-- | ReleaseNotes.txt | 2 | ||||
-rw-r--r-- | UnitTesting/GTMIPhoneUnitTestMain.m | 15 |
11 files changed, 344 insertions, 7 deletions
diff --git a/Foundation/GTMHTTPFetcher.h b/Foundation/GTMHTTPFetcher.h index 181283a..bd9c70e 100644 --- a/Foundation/GTMHTTPFetcher.h +++ b/Foundation/GTMHTTPFetcher.h @@ -207,8 +207,8 @@ #endif // notifications & errors -_EXTERN NSString* const kGTMHTTPFetcherErrorDomain _INITIALIZE_AS(@"com.google.GTMHTTPFetcher"); -_EXTERN NSString* const kGTMHTTPFetcherStatusDomain _INITIALIZE_AS(@"com.google.HTTPStatus"); +_EXTERN NSString* const kGTMHTTPFetcherErrorDomain _INITIALIZE_AS(@"com.google.mactoolbox.HTTPFetcher"); +_EXTERN NSString* const kGTMHTTPFetcherStatusDomain _INITIALIZE_AS(@"com.google.mactoolbox.HTTPStatus"); _EXTERN NSString* const kGTMHTTPFetcherErrorChallengeKey _INITIALIZE_AS(@"challenge"); _EXTERN NSString* const kGTMHTTPFetcherStatusDataKey _INITIALIZE_AS(@"data"); // any data returns w/ a kGTMHTTPFetcherStatusDomain error diff --git a/Foundation/GTMNSDictionary+URLArguments.h b/Foundation/GTMNSDictionary+URLArguments.h new file mode 100644 index 0000000..4bc896d --- /dev/null +++ b/Foundation/GTMNSDictionary+URLArguments.h @@ -0,0 +1,30 @@ +// +// GTMNSDictionary+URLArguments.h +// +// 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> + +/// Utility for building a URL or POST argument string. +@interface NSDictionary (GTMNSDictionaryURLArgumentsAdditions) + +/// Gets a string representation of the dictionary in the form +/// key1=value1&key2&value2&...&keyN=valueN, suitable for use as either +/// URL arguments (after a '?') or POST body. Keys and values will be escaped +/// automatically, so should be unescaped in the dictionary. +- (NSString *)gtm_httpArgumentsString; + +@end diff --git a/Foundation/GTMNSDictionary+URLArguments.m b/Foundation/GTMNSDictionary+URLArguments.m new file mode 100644 index 0000000..d67572c --- /dev/null +++ b/Foundation/GTMNSDictionary+URLArguments.m @@ -0,0 +1,40 @@ +// +// GTMNSDictionary+URLArguments.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 "GTMNSDictionary+URLArguments.h" +#import "GTMNSString+URLArguments.h" +#import "GTMMethodCheck.h" + +@implementation NSDictionary (GTMNSDictionaryURLArgumentsAdditions) + +GTM_METHOD_CHECK(NSString, gtm_stringByEscapingForURLArgument); + +- (NSString *)gtm_httpArgumentsString { + NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:[self count]]; + NSEnumerator* keyEnumerator = [self keyEnumerator]; + NSString* key; + while ((key = [keyEnumerator nextObject])) { + [arguments addObject:[NSString stringWithFormat:@"%@=%@", + [key gtm_stringByEscapingForURLArgument], + [[[self objectForKey:key] description] gtm_stringByEscapingForURLArgument]]]; + } + + return [arguments componentsJoinedByString:@"&"]; +} + +@end diff --git a/Foundation/GTMNSDictionary+URLArgumentsTest.m b/Foundation/GTMNSDictionary+URLArgumentsTest.m new file mode 100644 index 0000000..94d06b9 --- /dev/null +++ b/Foundation/GTMNSDictionary+URLArgumentsTest.m @@ -0,0 +1,54 @@ +// +// GTMNSDictionary+URLArgumentsTest.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 "GTMSenTestCase.h" +#import "GTMNSDictionary+URLArguments.h" +#import "GTMDefines.h" + +@interface GTMNSDictionary_URLArgumentsTest : SenTestCase +@end + +@implementation GTMNSDictionary_URLArgumentsTest + +- (void)testArgumentsString { + STAssertEqualObjects([[NSDictionary dictionary] gtm_httpArgumentsString], @"", + @"- empty dictionary should give an empty string"); + STAssertEqualObjects([[NSDictionary dictionaryWithObject:@"123" forKey:@"abc"] gtm_httpArgumentsString], + @"abc=123", + @"- simple one-pair dictionary should work"); + NSDictionary* arguments = [NSDictionary dictionaryWithObjectsAndKeys: + @"1+1!=3 & 2*6/3=4", @"complex", + @"specialkey", @"a+b", + nil]; + NSString* argumentString = [arguments gtm_httpArgumentsString]; + // 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, + @"- '%@' not found in '%@'", component1, argumentString); + STAssertNotEquals([argumentString rangeOfString:component2].location, (NSUInteger)NSNotFound, + @"- '%@' not found in '%@'", component2, argumentString); + STAssertNotEquals([argumentString rangeOfString:@"&"].location, (NSUInteger)NSNotFound, + @"- special characters should be escaped"); + STAssertNotEquals([argumentString characterAtIndex:0], (unichar)'&', + @"- there should be no & at the beginning of the string"); + STAssertNotEquals([argumentString characterAtIndex:([argumentString length] - 1)], (unichar)'&', + @"- there should be no & at the end of the string"); +} + +@end diff --git a/Foundation/GTMNSString+URLArguments.h b/Foundation/GTMNSString+URLArguments.h new file mode 100644 index 0000000..d4c7e09 --- /dev/null +++ b/Foundation/GTMNSString+URLArguments.h @@ -0,0 +1,41 @@ +// +// GTMNSString+URLArguments.h +// +// 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> + +/// Utilities for encoding and decoding URL arguments. +@interface NSString (GTMNSStringURLArgumentsAdditions) + +/// Returns a string that is escaped properly to be a URL argument. +// +/// This differs from stringByAddingPercentEscapesUsingEncoding: in that it +/// will escape all the reserved characters (per RFC 3986 +/// <http://www.ietf.org/rfc/rfc3986.txt>) which +/// stringByAddingPercentEscapesUsingEncoding would leave. +/// +/// This will also escape '%', so this should not be used on a string that has +/// already been escaped unless double-escaping is the desired result. +- (NSString*)gtm_stringByEscapingForURLArgument; + +/// Returns the unescaped version of a URL argument +// +/// This has the same behavior as stringByReplacingPercentEscapesUsingEncoding:, +/// except that it will also convert '+' to space. +- (NSString*)gtm_stringByUnescapingFromURLArgument; + +@end diff --git a/Foundation/GTMNSString+URLArguments.m b/Foundation/GTMNSString+URLArguments.m new file mode 100644 index 0000000..564b943 --- /dev/null +++ b/Foundation/GTMNSString+URLArguments.m @@ -0,0 +1,45 @@ +// +// GTMNSString+URLArguments.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 "GTMNSString+URLArguments.h" +#import "GTMGarbageCollection.h" + +@implementation NSString (GTMNSStringURLArgumentsAdditions) + +- (NSString*)gtm_stringByEscapingForURLArgument { + // Encode all the reserved characters, per RFC 3986 + // (<http://www.ietf.org/rfc/rfc3986.txt>) + CFStringRef escaped = + CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, + (CFStringRef)self, + NULL, + (CFStringRef)@"!*'();:@&=+$,/?%#[]", + kCFStringEncodingUTF8); + return [GTMNSMakeCollectable(escaped) autorelease]; +} + +- (NSString*)gtm_stringByUnescapingFromURLArgument { + NSMutableString *resultString = [NSMutableString stringWithString:self]; + [resultString replaceOccurrencesOfString:@"+" + withString:@" " + options:NSLiteralSearch + range:NSMakeRange(0, [resultString length])]; + return [resultString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; +} + +@end diff --git a/Foundation/GTMNSString+URLArgumentsTest.m b/Foundation/GTMNSString+URLArgumentsTest.m new file mode 100644 index 0000000..c87847e --- /dev/null +++ b/Foundation/GTMNSString+URLArgumentsTest.m @@ -0,0 +1,94 @@ +// +// GTMNSString+URLArgumentsTest.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 "GTMSenTestCase.h" +#import "GTMNSString+URLArguments.h" + +@interface GTMNSString_URLArgumentsTest : SenTestCase +@end + +@implementation GTMNSString_URLArgumentsTest + + +- (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"); + // 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"); + // 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"); + // 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"); +} + +- (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"); + // 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"); + // make sure a plus come back out as a space + STAssertEqualObjects([[NSString stringWithString:@"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"); + // high char test + NSString *tester = [NSString stringWithUTF8String:"caf\xC3\xA9"]; + STAssertNotNil(tester, @"failed to create from utf8 run"); + STAssertEqualObjects([[NSString stringWithString:@"caf%C3%A9"] gtm_stringByUnescapingFromURLArgument], tester, @"- high chars should work"); +} + +@end diff --git a/Foundation/GTMRegex.h b/Foundation/GTMRegex.h index 75cffe2..3313e0e 100644 --- a/Foundation/GTMRegex.h +++ b/Foundation/GTMRegex.h @@ -64,7 +64,7 @@ typedef NSUInteger GTMRegexOptions; #define _INITIALIZE_AS(x) #endif -_EXTERN NSString* kGTMRegexErrorDomain _INITIALIZE_AS(@"com.google_toolbox_for_mac.GTMRegexDomain"); +_EXTERN NSString* kGTMRegexErrorDomain _INITIALIZE_AS(@"com.google.mactoolbox.RegexDomain"); enum { kGTMRegexPatternParseFailedError = -100 diff --git a/GTM.xcodeproj/project.pbxproj b/GTM.xcodeproj/project.pbxproj index d0f94cf..2407639 100644 --- a/GTM.xcodeproj/project.pbxproj +++ b/GTM.xcodeproj/project.pbxproj @@ -23,6 +23,12 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 33C372A60DD8A88500E97817 /* GTMNSString+URLArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 33C372A40DD8A88500E97817 /* GTMNSString+URLArguments.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 33C372A70DD8A88500E97817 /* GTMNSString+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = 33C372A50DD8A88500E97817 /* GTMNSString+URLArguments.m */; }; + 33C372B40DD8A93000E97817 /* GTMNSString+URLArgumentsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33C372AE0DD8A8D700E97817 /* GTMNSString+URLArgumentsTest.m */; }; + 33C374380DD8D44800E97817 /* GTMNSDictionary+URLArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = 33C374360DD8D44800E97817 /* GTMNSDictionary+URLArguments.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 33C374390DD8D44800E97817 /* GTMNSDictionary+URLArguments.m in Sources */ = {isa = PBXBuildFile; fileRef = 33C374370DD8D44800E97817 /* GTMNSDictionary+URLArguments.m */; }; + 33C3745F0DD8D85B00E97817 /* GTMNSDictionary+URLArgumentsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33C3745E0DD8D85B00E97817 /* GTMNSDictionary+URLArgumentsTest.m */; }; 8B2A9B200D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B2A9B1D0D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.m */; }; 8B2A9B220D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B2A9B1F0D8270DA00599386 /* GTMNSWorkspace+ScreenSaver.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8B2A9B240D8270DA00599386 /* GTMNSWorkspace+ScreenSaverTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B2A9B1E0D8270DA00599386 /* GTMNSWorkspace+ScreenSaverTest.m */; }; @@ -209,6 +215,12 @@ 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 32DBCF5E0370ADEE00C91783 /* GTM_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTM_Prefix.pch; sourceTree = "<group>"; }; + 33C372A40DD8A88500E97817 /* GTMNSString+URLArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSString+URLArguments.h"; sourceTree = "<group>"; }; + 33C372A50DD8A88500E97817 /* GTMNSString+URLArguments.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSString+URLArguments.m"; sourceTree = "<group>"; }; + 33C372AE0DD8A8D700E97817 /* GTMNSString+URLArgumentsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSString+URLArgumentsTest.m"; sourceTree = "<group>"; }; + 33C374360DD8D44800E97817 /* GTMNSDictionary+URLArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSDictionary+URLArguments.h"; sourceTree = "<group>"; }; + 33C374370DD8D44800E97817 /* GTMNSDictionary+URLArguments.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSDictionary+URLArguments.m"; sourceTree = "<group>"; }; + 33C3745E0DD8D85B00E97817 /* GTMNSDictionary+URLArgumentsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSDictionary+URLArgumentsTest.m"; sourceTree = "<group>"; }; 8B1A14E90D900BC800CA1E8E /* GTMNSObject+BindingUnitTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSObject+BindingUnitTesting.m"; sourceTree = "<group>"; }; 8B1A14EA0D900BC800CA1E8E /* GTMNSObject+BindingUnitTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSObject+BindingUnitTesting.h"; sourceTree = "<group>"; }; 8B1A16050D90344B00CA1E8E /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = "<group>"; }; @@ -558,6 +570,9 @@ F435E0870DC63F6D0069CDE8 /* GTMHTTPFetcher.h */, F435E0880DC63F6D0069CDE8 /* GTMHTTPFetcher.m */, F435E3930DC8CAAF0069CDE8 /* GTMHTTPFetcherTest.m */, + 33C374360DD8D44800E97817 /* GTMNSDictionary+URLArguments.h */, + 33C374370DD8D44800E97817 /* GTMNSDictionary+URLArguments.m */, + 33C3745E0DD8D85B00E97817 /* GTMNSDictionary+URLArgumentsTest.m */, F43E4DD60D4E56320041161F /* GTMNSEnumerator+Filter.h */, F43E4DD70D4E56320041161F /* GTMNSEnumerator+Filter.m */, F43E4DD80D4E56320041161F /* GTMNSEnumerator+FilterTest.m */, @@ -567,6 +582,9 @@ F48FE28E0D198D24009257D2 /* GTMNSString+HTML.h */, F48FE28F0D198D24009257D2 /* GTMNSString+HTML.m */, F48FE2900D198D24009257D2 /* GTMNSString+HTMLTest.m */, + 33C372A40DD8A88500E97817 /* GTMNSString+URLArguments.h */, + 33C372A50DD8A88500E97817 /* GTMNSString+URLArguments.m */, + 33C372AE0DD8A8D700E97817 /* GTMNSString+URLArgumentsTest.m */, F43E4C250D4E361D0041161F /* GTMNSString+XML.h */, F43E4C260D4E361D0041161F /* GTMNSString+XML.m */, F43E4C270D4E361D0041161F /* GTMNSString+XMLTest.m */, @@ -692,6 +710,8 @@ F435E0890DC63F6D0069CDE8 /* GTMHTTPFetcher.h in Headers */, F435E27F0DC7B0630069CDE8 /* GTMProgressMonitorInputStream.h in Headers */, F431221D0DD4E3B800F45252 /* GTMStackTrace.h in Headers */, + 33C372A60DD8A88500E97817 /* GTMNSString+URLArguments.h in Headers */, + 33C374380DD8D44800E97817 /* GTMNSDictionary+URLArguments.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -961,6 +981,8 @@ F41D258F0DBD21B900774EEB /* GTMBase64Test.m in Sources */, F435E3940DC8CAAF0069CDE8 /* GTMHTTPFetcherTest.m in Sources */, F431221F0DD4E3C900F45252 /* GTMStackTraceTest.m in Sources */, + 33C372B40DD8A93000E97817 /* GTMNSString+URLArgumentsTest.m in Sources */, + 33C3745F0DD8D85B00E97817 /* GTMNSDictionary+URLArgumentsTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -991,6 +1013,8 @@ F435E08A0DC63F6D0069CDE8 /* GTMHTTPFetcher.m in Sources */, F435E2800DC7B0630069CDE8 /* GTMProgressMonitorInputStream.m in Sources */, F431221C0DD4E3B800F45252 /* GTMStackTrace.c in Sources */, + 33C372A70DD8A88500E97817 /* GTMNSString+URLArguments.m in Sources */, + 33C374390DD8D44800E97817 /* GTMNSDictionary+URLArguments.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt index 65af31d..e6e565d 100644 --- a/ReleaseNotes.txt +++ b/ReleaseNotes.txt @@ -103,6 +103,8 @@ Changes since 1.0.0 - Added GTMStackTrace. +- Added NSString+URLArguments and NSDictionary+URLArguments + Release 1.0.0 14-January-2008 diff --git a/UnitTesting/GTMIPhoneUnitTestMain.m b/UnitTesting/GTMIPhoneUnitTestMain.m index 16a3907..981c48b 100644 --- a/UnitTesting/GTMIPhoneUnitTestMain.m +++ b/UnitTesting/GTMIPhoneUnitTestMain.m @@ -118,20 +118,27 @@ static int MethodSort(const void *a, const void *b) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @try { [testcase setUp]; - [testcase performSelector:sel]; + @try { + [testcase performSelector:sel]; + } @catch (NSException *exception) { + failed = YES; + [self printError:[exception reason]]; + } [testcase tearDown]; - fixtureSuccesses += 1; } @catch (NSException *exception) { - fixtureFailures += 1; failed = YES; [self printError:[exception reason]]; } [pool release]; } @catch (NSException *exception) { - fixtureFailures += 1; failed = YES; [self printError:[exception reason]]; } + if (failed) { + fixtureFailures += 1; + } else { + fixtureSuccesses += 1; + } NSTimeInterval caseEndTime = [[NSDate date] timeIntervalSinceDate:caseStartDate]; NSString *caseEndString = [NSString stringWithFormat:@"Test Case '-[%@ %s]' %s (%0.3f seconds).\n", fixtureName, name, |