nevans-iphone_testify 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,38 @@
1
+ //
2
+ // GTMIPhoneUnitTestDelegate.h
3
+ //
4
+ // Copyright 2008 Google Inc.
5
+ //
6
+ // Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
+ // use this file except in compliance with the License. You may obtain a copy
8
+ // of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
+ // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
+ // License for the specific language governing permissions and limitations under
16
+ // the License.
17
+ //
18
+
19
+ #import <Foundation/Foundation.h>
20
+
21
+ // Application delegate that runs all test methods in registered classes
22
+ // extending SenTestCase. The application is terminated afterwards.
23
+ // You can also run the tests directly from your application by invoking
24
+ // runTests and clean up, restore data, etc. before the application
25
+ // terminates.
26
+ @interface GTMIPhoneUnitTestDelegate : NSObject {
27
+ @private
28
+ NSUInteger totalFailures_;
29
+ NSUInteger totalSuccesses_;
30
+ }
31
+ // Runs through all the registered classes and runs test methods on any
32
+ // that are subclasses of SenTestCase. Prints results and run time to
33
+ // the default output.
34
+ - (void)runTests;
35
+ // Fetch the number of successes or failures from the last runTests.
36
+ - (NSUInteger)totalSuccesses;
37
+ - (NSUInteger)totalFailures;
38
+ @end
@@ -0,0 +1,206 @@
1
+ //
2
+ // GTMIPhoneUnitTestDelegate.m
3
+ //
4
+ // Copyright 2008 Google Inc.
5
+ //
6
+ // Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
+ // use this file except in compliance with the License. You may obtain a copy
8
+ // of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
+ // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
+ // License for the specific language governing permissions and limitations under
16
+ // the License.
17
+ //
18
+
19
+ #import "GTMIPhoneUnitTestDelegate.h"
20
+
21
+ #import "GTMDefines.h"
22
+ #if !GTM_IPHONE_SDK
23
+ #error GTMIPhoneUnitTestDelegate for iPhone only
24
+ #endif
25
+ #import <objc/runtime.h>
26
+ #import <stdio.h>
27
+ #import <UIKit/UIKit.h>
28
+ #import "GTMSenTestCase.h"
29
+
30
+ // Used for sorting methods below
31
+ static int MethodSort(const void *a, const void *b) {
32
+ const char *nameA = sel_getName(method_getName(*(Method*)a));
33
+ const char *nameB = sel_getName(method_getName(*(Method*)b));
34
+ return strcmp(nameA, nameB);
35
+ }
36
+
37
+ // Return YES if class is subclass (1 or more generations) of SenTestCase
38
+ static BOOL IsTestFixture(Class aClass) {
39
+ BOOL iscase = NO;
40
+ Class testCaseClass = [SenTestCase class];
41
+ Class superclass;
42
+ for (superclass = aClass;
43
+ !iscase && superclass;
44
+ superclass = class_getSuperclass(superclass)) {
45
+ iscase = superclass == testCaseClass ? YES : NO;
46
+ }
47
+ return iscase;
48
+ }
49
+
50
+ @implementation GTMIPhoneUnitTestDelegate
51
+
52
+ // Run through all the registered classes and run test methods on any
53
+ // that are subclasses of SenTestCase. Terminate the application upon
54
+ // test completion.
55
+ - (void)applicationDidFinishLaunching:(UIApplication *)application {
56
+ [self runTests];
57
+
58
+ if (!getenv("GTM_DISABLE_TERMINATION")) {
59
+ // To help using xcodebuild, make the exit status 0/1 to signal the tests
60
+ // success/failure.
61
+ int exitStatus = (([self totalFailures] == 0U) ? 0 : 1);
62
+ exit(exitStatus);
63
+ }
64
+ }
65
+
66
+ // Run through all the registered classes and run test methods on any
67
+ // that are subclasses of SenTestCase. Print results and run time to
68
+ // the default output.
69
+ - (void)runTests {
70
+ int count = objc_getClassList(NULL, 0);
71
+ NSMutableData *classData
72
+ = [NSMutableData dataWithLength:sizeof(Class) * count];
73
+ Class *classes = (Class*)[classData mutableBytes];
74
+ _GTMDevAssert(classes, @"Couldn't allocate class list");
75
+ objc_getClassList(classes, count);
76
+ totalFailures_ = 0;
77
+ totalSuccesses_ = 0;
78
+ NSString *suiteName = [[NSBundle mainBundle] bundlePath];
79
+ NSDate *suiteStartDate = [NSDate date];
80
+ NSString *suiteStartString
81
+ = [NSString stringWithFormat:@"Test Suite '%@' started at %@\n",
82
+ suiteName, suiteStartDate];
83
+ fputs([suiteStartString UTF8String], stderr);
84
+ fflush(stderr);
85
+ for (int i = 0; i < count; ++i) {
86
+ Class currClass = classes[i];
87
+ if (IsTestFixture(currClass)) {
88
+ NSDate *fixtureStartDate = [NSDate date];
89
+ NSString *fixtureName = NSStringFromClass(currClass);
90
+ NSString *fixtureStartString
91
+ = [NSString stringWithFormat:@"Test Suite '%@' started at %@\n",
92
+ fixtureName, fixtureStartDate];
93
+ int fixtureSuccesses = 0;
94
+ int fixtureFailures = 0;
95
+ fputs([fixtureStartString UTF8String], stderr);
96
+ fflush(stderr);
97
+ id testcase = [[currClass alloc] init];
98
+ _GTMDevAssert(testcase, @"Unable to instantiate Test Suite: '%@'\n",
99
+ fixtureName);
100
+ unsigned int methodCount;
101
+ Method *methods = class_copyMethodList(currClass, &methodCount);
102
+ if (!methods) {
103
+ // If the class contains no methods, head on to the next class
104
+ NSString *output = [NSString stringWithFormat:@"Test Suite '%@' "
105
+ @"finished at %@.\nExecuted 0 tests, with 0 "
106
+ @"failures (0 unexpected) in 0 (0) seconds\n",
107
+ fixtureName, fixtureStartDate];
108
+
109
+ fputs([output UTF8String], stderr);
110
+ continue;
111
+ }
112
+ // This handles disposing of methods for us even if an
113
+ // exception should fly.
114
+ [NSData dataWithBytesNoCopy:methods
115
+ length:sizeof(Method) * methodCount];
116
+ // Sort our methods so they are called in Alphabetical order just
117
+ // because we can.
118
+ qsort(methods, methodCount, sizeof(Method), MethodSort);
119
+ for (size_t j = 0; j < methodCount; ++j) {
120
+ Method currMethod = methods[j];
121
+ SEL sel = method_getName(currMethod);
122
+ char *returnType = NULL;
123
+ const char *name = sel_getName(sel);
124
+ // If it starts with test, takes 2 args (target and sel) and returns
125
+ // void run it.
126
+ if (strstr(name, "test") == name) {
127
+ returnType = method_copyReturnType(currMethod);
128
+ if (returnType) {
129
+ // This handles disposing of returnType for us even if an
130
+ // exception should fly. Length +1 for the terminator, not that
131
+ // the length really matters here, as we never reference inside
132
+ // the data block.
133
+ [NSData dataWithBytesNoCopy:returnType
134
+ length:strlen(returnType) + 1];
135
+ }
136
+ }
137
+ if (returnType // True if name starts with "test"
138
+ && strcmp(returnType, @encode(void)) == 0
139
+ && method_getNumberOfArguments(currMethod) == 2) {
140
+ BOOL failed = NO;
141
+ NSDate *caseStartDate = [NSDate date];
142
+ @try {
143
+ [testcase performTest:sel];
144
+ } @catch (NSException *exception) {
145
+ failed = YES;
146
+ }
147
+ if (failed) {
148
+ fixtureFailures += 1;
149
+ } else {
150
+ fixtureSuccesses += 1;
151
+ }
152
+ NSTimeInterval caseEndTime
153
+ = [[NSDate date] timeIntervalSinceDate:caseStartDate];
154
+ NSString *caseEndString
155
+ = [NSString stringWithFormat:@"Test Case '-[%@ %s]' %@ (%0.3f "
156
+ @"seconds).\n",
157
+ fixtureName, name,
158
+ failed ? @"failed" : @"passed",
159
+ caseEndTime];
160
+ fputs([caseEndString UTF8String], stderr);
161
+ fflush(stderr);
162
+ }
163
+ }
164
+ [testcase release];
165
+ NSDate *fixtureEndDate = [NSDate date];
166
+ NSTimeInterval fixtureEndTime
167
+ = [fixtureEndDate timeIntervalSinceDate:fixtureStartDate];
168
+ NSString *fixtureEndString
169
+ = [NSString stringWithFormat:@"Test Suite '%@' finished at %@.\n"
170
+ @"Executed %d tests, with %d failures (%d "
171
+ @"unexpected) in %0.3f (%0.3f) seconds\n\n",
172
+ fixtureName, fixtureEndDate,
173
+ fixtureSuccesses + fixtureFailures,
174
+ fixtureFailures, fixtureFailures,
175
+ fixtureEndTime, fixtureEndTime];
176
+
177
+ fputs([fixtureEndString UTF8String], stderr);
178
+ fflush(stderr);
179
+ totalSuccesses_ += fixtureSuccesses;
180
+ totalFailures_ += fixtureFailures;
181
+ }
182
+ }
183
+ NSDate *suiteEndDate = [NSDate date];
184
+ NSTimeInterval suiteEndTime
185
+ = [suiteEndDate timeIntervalSinceDate:suiteStartDate];
186
+ NSString *suiteEndString
187
+ = [NSString stringWithFormat:@"Test Suite '%@' finished at %@.\n"
188
+ @"Executed %d tests, with %d failures (%d "
189
+ @"unexpected) in %0.3f (%0.3f) seconds\n\n",
190
+ suiteName, suiteEndDate,
191
+ totalSuccesses_ + totalFailures_,
192
+ totalFailures_, totalFailures_,
193
+ suiteEndTime, suiteEndTime];
194
+ fputs([suiteEndString UTF8String], stderr);
195
+ fflush(stderr);
196
+ }
197
+
198
+ - (NSUInteger)totalSuccesses {
199
+ return totalSuccesses_;
200
+ }
201
+
202
+ - (NSUInteger)totalFailures {
203
+ return totalFailures_;
204
+ }
205
+
206
+ @end
@@ -0,0 +1,33 @@
1
+ //
2
+ // GTMIPhoneUnitTestMain.m
3
+ //
4
+ // Copyright 2008 Google Inc.
5
+ //
6
+ // Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
+ // use this file except in compliance with the License. You may obtain a copy
8
+ // of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
+ // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
+ // License for the specific language governing permissions and limitations under
16
+ // the License.
17
+ //
18
+
19
+ #import "GTMDefines.h"
20
+ #if !GTM_IPHONE_SDK
21
+ #error GTMIPhoneUnitTestMain for iPhone only
22
+ #endif
23
+ #import <UIKit/UIKit.h>
24
+
25
+ // Creates an application that runs all tests from classes extending
26
+ // SenTestCase, outputs results and test run time, and terminates right
27
+ // afterwards.
28
+ int main(int argc, char *argv[]) {
29
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
30
+ int retVal = UIApplicationMain(argc, argv, nil, @"GTMIPhoneUnitTestDelegate");
31
+ [pool release];
32
+ return retVal;
33
+ }
@@ -0,0 +1,1011 @@
1
+ //
2
+ // GTMSenTestCase.h
3
+ //
4
+ // Copyright 2007-2008 Google Inc.
5
+ //
6
+ // Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
+ // use this file except in compliance with the License. You may obtain a copy
8
+ // of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing, software
13
+ // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
+ // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
+ // License for the specific language governing permissions and limitations under
16
+ // the License.
17
+ //
18
+
19
+ // Portions of this file fall under the following license, marked with
20
+ // SENTE_BEGIN - SENTE_END
21
+ //
22
+ // Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
23
+ //
24
+ // Use of this source code is governed by the following license:
25
+ //
26
+ // Redistribution and use in source and binary forms, with or without modification,
27
+ // are permitted provided that the following conditions are met:
28
+ //
29
+ // (1) Redistributions of source code must retain the above copyright notice,
30
+ // this list of conditions and the following disclaimer.
31
+ //
32
+ // (2) Redistributions in binary form must reproduce the above copyright notice,
33
+ // this list of conditions and the following disclaimer in the documentation
34
+ // and/or other materials provided with the distribution.
35
+ //
36
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
37
+ // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38
+ // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
39
+ // IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
41
+ // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42
+ // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
43
+ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
44
+ // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45
+ //
46
+ // Note: this license is equivalent to the FreeBSD license.
47
+ //
48
+ // This notice may not be removed from this file.
49
+
50
+ // Some extra test case macros that would have been convenient for SenTestingKit
51
+ // to provide. I didn't stick GTM in front of the Macro names, so that they would
52
+ // be easy to remember.
53
+
54
+ #import "GTMDefines.h"
55
+
56
+ #if (!GTM_IPHONE_SDK)
57
+ #import <SenTestingKit/SenTestingKit.h>
58
+ #else
59
+ #import <Foundation/Foundation.h>
60
+ #ifdef __cplusplus
61
+ extern "C" {
62
+ #endif
63
+ NSString *STComposeString(NSString *, ...);
64
+ #ifdef __cplusplus
65
+ }
66
+ #endif
67
+
68
+ #endif // !GTM_IPHONE_SDK
69
+
70
+ // Generates a failure when a1 != noErr
71
+ // Args:
72
+ // a1: should be either an OSErr or an OSStatus
73
+ // description: A format string as in the printf() function. Can be nil or
74
+ // an empty string but must be present.
75
+ // ...: A variable number of arguments to the format string. Can be absent.
76
+ #define STAssertNoErr(a1, description, ...) \
77
+ do { \
78
+ @try {\
79
+ OSStatus a1value = (a1); \
80
+ if (a1value != noErr) { \
81
+ NSString *_expression = [NSString stringWithFormat:@"Expected noErr, got %ld for (%s)", a1value, #a1]; \
82
+ if (description) { \
83
+ _expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
84
+ } \
85
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
86
+ atLine:__LINE__ \
87
+ withDescription:_expression]]; \
88
+ } \
89
+ }\
90
+ @catch (id anException) {\
91
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == noErr fails", #a1] \
92
+ exception:anException \
93
+ inFile:[NSString stringWithUTF8String:__FILE__] \
94
+ atLine:__LINE__ \
95
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
96
+ }\
97
+ } while(0)
98
+
99
+ // Generates a failure when a1 != a2
100
+ // Args:
101
+ // a1: received value. Should be either an OSErr or an OSStatus
102
+ // a2: expected value. Should be either an OSErr or an OSStatus
103
+ // description: A format string as in the printf() function. Can be nil or
104
+ // an empty string but must be present.
105
+ // ...: A variable number of arguments to the format string. Can be absent.
106
+ #define STAssertErr(a1, a2, description, ...) \
107
+ do { \
108
+ @try {\
109
+ OSStatus a1value = (a1); \
110
+ OSStatus a2value = (a2); \
111
+ if (a1value != a2value) { \
112
+ NSString *_expression = [NSString stringWithFormat:@"Expected %s(%ld) but got %ld for (%s)", #a2, a2value, a1value, #a1]; \
113
+ if (description) { \
114
+ _expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
115
+ } \
116
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
117
+ atLine:__LINE__ \
118
+ withDescription:_expression]]; \
119
+ } \
120
+ }\
121
+ @catch (id anException) {\
122
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s) fails", #a1, #a2] \
123
+ exception:anException \
124
+ inFile:[NSString stringWithUTF8String:__FILE__] \
125
+ atLine:__LINE__ \
126
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
127
+ }\
128
+ } while(0)
129
+
130
+
131
+ // Generates a failure when a1 is NULL
132
+ // Args:
133
+ // a1: should be a pointer (use STAssertNotNil for an object)
134
+ // description: A format string as in the printf() function. Can be nil or
135
+ // an empty string but must be present.
136
+ // ...: A variable number of arguments to the format string. Can be absent.
137
+ #define STAssertNotNULL(a1, description, ...) \
138
+ do { \
139
+ @try {\
140
+ const void* a1value = (a1); \
141
+ if (a1value == NULL) { \
142
+ NSString *_expression = [NSString stringWithFormat:@"(%s) != NULL", #a1]; \
143
+ if (description) { \
144
+ _expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
145
+ } \
146
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
147
+ atLine:__LINE__ \
148
+ withDescription:_expression]]; \
149
+ } \
150
+ }\
151
+ @catch (id anException) {\
152
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != NULL fails", #a1] \
153
+ exception:anException \
154
+ inFile:[NSString stringWithUTF8String:__FILE__] \
155
+ atLine:__LINE__ \
156
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
157
+ }\
158
+ } while(0)
159
+
160
+ // Generates a failure when a1 is not NULL
161
+ // Args:
162
+ // a1: should be a pointer (use STAssertNil for an object)
163
+ // description: A format string as in the printf() function. Can be nil or
164
+ // an empty string but must be present.
165
+ // ...: A variable number of arguments to the format string. Can be absent.
166
+ #define STAssertNULL(a1, description, ...) \
167
+ do { \
168
+ @try {\
169
+ const void* a1value = (a1); \
170
+ if (a1value != NULL) { \
171
+ NSString *_expression = [NSString stringWithFormat:@"(%s) == NULL", #a1]; \
172
+ if (description) { \
173
+ _expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
174
+ } \
175
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
176
+ atLine:__LINE__ \
177
+ withDescription:_expression]]; \
178
+ } \
179
+ }\
180
+ @catch (id anException) {\
181
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == NULL fails", #a1] \
182
+ exception:anException \
183
+ inFile:[NSString stringWithUTF8String:__FILE__] \
184
+ atLine:__LINE__ \
185
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
186
+ }\
187
+ } while(0)
188
+
189
+ // Generates a failure when a1 is equal to a2. This test is for C scalars,
190
+ // structs and unions.
191
+ // Args:
192
+ // a1: argument 1
193
+ // a2: argument 2
194
+ // description: A format string as in the printf() function. Can be nil or
195
+ // an empty string but must be present.
196
+ // ...: A variable number of arguments to the format string. Can be absent.
197
+ #define STAssertNotEquals(a1, a2, description, ...) \
198
+ do { \
199
+ @try {\
200
+ if (@encode(__typeof__(a1)) != @encode(__typeof__(a2))) { \
201
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
202
+ atLine:__LINE__ \
203
+ withDescription:[@"Type mismatch -- " stringByAppendingString:STComposeString(description, ##__VA_ARGS__)]]]; \
204
+ } else { \
205
+ __typeof__(a1) a1value = (a1); \
206
+ __typeof__(a2) a2value = (a2); \
207
+ NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
208
+ NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
209
+ if ([a1encoded isEqualToValue:a2encoded]) { \
210
+ NSString *_expression = [NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2]; \
211
+ if (description) { \
212
+ _expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
213
+ } \
214
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
215
+ atLine:__LINE__ \
216
+ withDescription:_expression]]; \
217
+ } \
218
+ } \
219
+ } \
220
+ @catch (id anException) {\
221
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
222
+ exception:anException \
223
+ inFile:[NSString stringWithUTF8String:__FILE__] \
224
+ atLine:__LINE__ \
225
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
226
+ }\
227
+ } while(0)
228
+
229
+ // Generates a failure when a1 is equal to a2. This test is for objects.
230
+ // Args:
231
+ // a1: argument 1. object.
232
+ // a2: argument 2. object.
233
+ // description: A format string as in the printf() function. Can be nil or
234
+ // an empty string but must be present.
235
+ // ...: A variable number of arguments to the format string. Can be absent.
236
+ #define STAssertNotEqualObjects(a1, a2, desc, ...) \
237
+ do { \
238
+ @try {\
239
+ id a1value = (a1); \
240
+ id a2value = (a2); \
241
+ if ( (@encode(__typeof__(a1value)) == @encode(id)) && \
242
+ (@encode(__typeof__(a2value)) == @encode(id)) && \
243
+ ![(id)a1value isEqual:(id)a2value] ) continue; \
244
+ NSString *_expression = [NSString stringWithFormat:@"%s('%@') != %s('%@')", #a1, [a1 description], #a2, [a2 description]]; \
245
+ if (desc) { \
246
+ _expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(desc, ##__VA_ARGS__)]; \
247
+ } \
248
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
249
+ atLine:__LINE__ \
250
+ withDescription:_expression]]; \
251
+ }\
252
+ @catch (id anException) {\
253
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) != (%s)", #a1, #a2] \
254
+ exception:anException \
255
+ inFile:[NSString stringWithUTF8String:__FILE__] \
256
+ atLine:__LINE__ \
257
+ withDescription:STComposeString(desc, ##__VA_ARGS__)]]; \
258
+ }\
259
+ } while(0)
260
+
261
+ // Generates a failure when a1 is not 'op' to a2. This test is for C scalars.
262
+ // Args:
263
+ // a1: argument 1
264
+ // a2: argument 2
265
+ // op: operation
266
+ // description: A format string as in the printf() function. Can be nil or
267
+ // an empty string but must be present.
268
+ // ...: A variable number of arguments to the format string. Can be absent.
269
+ #define STAssertOperation(a1, a2, op, description, ...) \
270
+ do { \
271
+ @try {\
272
+ if (@encode(__typeof__(a1)) != @encode(__typeof__(a2))) { \
273
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
274
+ atLine:__LINE__ \
275
+ withDescription:[@"Type mismatch -- " stringByAppendingString:STComposeString(description, ##__VA_ARGS__)]]]; \
276
+ } else { \
277
+ __typeof__(a1) a1value = (a1); \
278
+ __typeof__(a2) a2value = (a2); \
279
+ if (!(a1value op a2value)) { \
280
+ double a1DoubleValue = a1value; \
281
+ double a2DoubleValue = a2value; \
282
+ NSString *_expression = [NSString stringWithFormat:@"%s (%lg) %s %s (%lg)", #a1, a1DoubleValue, #op, #a2, a2DoubleValue]; \
283
+ if (description) { \
284
+ _expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
285
+ } \
286
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
287
+ atLine:__LINE__ \
288
+ withDescription:_expression]]; \
289
+ } \
290
+ } \
291
+ } \
292
+ @catch (id anException) {\
293
+ [self failWithException:[NSException \
294
+ failureInRaise:[NSString stringWithFormat:@"(%s) %s (%s)", #a1, #op, #a2] \
295
+ exception:anException \
296
+ inFile:[NSString stringWithUTF8String:__FILE__] \
297
+ atLine:__LINE__ \
298
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
299
+ }\
300
+ } while(0)
301
+
302
+ // Generates a failure when a1 is not > a2. This test is for C scalars.
303
+ // Args:
304
+ // a1: argument 1
305
+ // a2: argument 2
306
+ // op: operation
307
+ // description: A format string as in the printf() function. Can be nil or
308
+ // an empty string but must be present.
309
+ // ...: A variable number of arguments to the format string. Can be absent.
310
+ #define STAssertGreaterThan(a1, a2, description, ...) \
311
+ STAssertOperation(a1, a2, >, description, ##__VA_ARGS__)
312
+
313
+ // Generates a failure when a1 is not >= a2. This test is for C scalars.
314
+ // Args:
315
+ // a1: argument 1
316
+ // a2: argument 2
317
+ // op: operation
318
+ // description: A format string as in the printf() function. Can be nil or
319
+ // an empty string but must be present.
320
+ // ...: A variable number of arguments to the format string. Can be absent.
321
+ #define STAssertGreaterThanOrEqual(a1, a2, description, ...) \
322
+ STAssertOperation(a1, a2, >=, description, ##__VA_ARGS__)
323
+
324
+ // Generates a failure when a1 is not < a2. This test is for C scalars.
325
+ // Args:
326
+ // a1: argument 1
327
+ // a2: argument 2
328
+ // op: operation
329
+ // description: A format string as in the printf() function. Can be nil or
330
+ // an empty string but must be present.
331
+ // ...: A variable number of arguments to the format string. Can be absent.
332
+ #define STAssertLessThan(a1, a2, description, ...) \
333
+ STAssertOperation(a1, a2, <, description, ##__VA_ARGS__)
334
+
335
+ // Generates a failure when a1 is not <= a2. This test is for C scalars.
336
+ // Args:
337
+ // a1: argument 1
338
+ // a2: argument 2
339
+ // op: operation
340
+ // description: A format string as in the printf() function. Can be nil or
341
+ // an empty string but must be present.
342
+ // ...: A variable number of arguments to the format string. Can be absent.
343
+ #define STAssertLessThanOrEqual(a1, a2, description, ...) \
344
+ STAssertOperation(a1, a2, <=, description, ##__VA_ARGS__)
345
+
346
+ // Generates a failure when string a1 is not equal to string a2. This call
347
+ // differs from STAssertEqualObjects in that strings that are different in
348
+ // composition (precomposed vs decomposed) will compare equal if their final
349
+ // representation is equal.
350
+ // ex O + umlaut decomposed is the same as O + umlaut composed.
351
+ // Args:
352
+ // a1: string 1
353
+ // a2: string 2
354
+ // description: A format string as in the printf() function. Can be nil or
355
+ // an empty string but must be present.
356
+ // ...: A variable number of arguments to the format string. Can be absent.
357
+ #define STAssertEqualStrings(a1, a2, description, ...) \
358
+ do { \
359
+ @try {\
360
+ id a1value = (a1); \
361
+ id a2value = (a2); \
362
+ if (a1value == a2value) continue; \
363
+ if ([a1value isKindOfClass:[NSString class]] && \
364
+ [a2value isKindOfClass:[NSString class]] && \
365
+ [a1value compare:a2value options:0] == NSOrderedSame) continue; \
366
+ [self failWithException:[NSException failureInEqualityBetweenObject: a1value \
367
+ andObject: a2value \
368
+ inFile: [NSString stringWithUTF8String:__FILE__] \
369
+ atLine: __LINE__ \
370
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
371
+ }\
372
+ @catch (id anException) {\
373
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \
374
+ exception:anException \
375
+ inFile:[NSString stringWithUTF8String:__FILE__] \
376
+ atLine:__LINE__ \
377
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
378
+ }\
379
+ } while(0)
380
+
381
+ // Generates a failure when string a1 is equal to string a2. This call
382
+ // differs from STAssertEqualObjects in that strings that are different in
383
+ // composition (precomposed vs decomposed) will compare equal if their final
384
+ // representation is equal.
385
+ // ex O + umlaut decomposed is the same as O + umlaut composed.
386
+ // Args:
387
+ // a1: string 1
388
+ // a2: string 2
389
+ // description: A format string as in the printf() function. Can be nil or
390
+ // an empty string but must be present.
391
+ // ...: A variable number of arguments to the format string. Can be absent.
392
+ #define STAssertNotEqualStrings(a1, a2, description, ...) \
393
+ do { \
394
+ @try {\
395
+ id a1value = (a1); \
396
+ id a2value = (a2); \
397
+ if ([a1value isKindOfClass:[NSString class]] && \
398
+ [a2value isKindOfClass:[NSString class]] && \
399
+ [a1value compare:a2value options:0] != NSOrderedSame) continue; \
400
+ [self failWithException:[NSException failureInEqualityBetweenObject: a1value \
401
+ andObject: a2value \
402
+ inFile: [NSString stringWithUTF8String:__FILE__] \
403
+ atLine: __LINE__ \
404
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
405
+ }\
406
+ @catch (id anException) {\
407
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) != (%s)", #a1, #a2] \
408
+ exception:anException \
409
+ inFile:[NSString stringWithUTF8String:__FILE__] \
410
+ atLine:__LINE__ \
411
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
412
+ }\
413
+ } while(0)
414
+
415
+ // Generates a failure when c-string a1 is not equal to c-string a2.
416
+ // Args:
417
+ // a1: string 1
418
+ // a2: string 2
419
+ // description: A format string as in the printf() function. Can be nil or
420
+ // an empty string but must be present.
421
+ // ...: A variable number of arguments to the format string. Can be absent.
422
+ #define STAssertEqualCStrings(a1, a2, description, ...) \
423
+ do { \
424
+ @try {\
425
+ const char* a1value = (a1); \
426
+ const char* a2value = (a2); \
427
+ if (a1value == a2value) continue; \
428
+ if (strcmp(a1value, a2value) == 0) continue; \
429
+ [self failWithException:[NSException failureInEqualityBetweenObject: [NSString stringWithUTF8String:a1value] \
430
+ andObject: [NSString stringWithUTF8String:a2value] \
431
+ inFile: [NSString stringWithUTF8String:__FILE__] \
432
+ atLine: __LINE__ \
433
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
434
+ }\
435
+ @catch (id anException) {\
436
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \
437
+ exception:anException \
438
+ inFile:[NSString stringWithUTF8String:__FILE__] \
439
+ atLine:__LINE__ \
440
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
441
+ }\
442
+ } while(0)
443
+
444
+ // Generates a failure when c-string a1 is equal to c-string a2.
445
+ // Args:
446
+ // a1: string 1
447
+ // a2: string 2
448
+ // description: A format string as in the printf() function. Can be nil or
449
+ // an empty string but must be present.
450
+ // ...: A variable number of arguments to the format string. Can be absent.
451
+ #define STAssertNotEqualCStrings(a1, a2, description, ...) \
452
+ do { \
453
+ @try {\
454
+ const char* a1value = (a1); \
455
+ const char* a2value = (a2); \
456
+ if (strcmp(a1value, a2value) != 0) continue; \
457
+ [self failWithException:[NSException failureInEqualityBetweenObject: [NSString stringWithUTF8String:a1value] \
458
+ andObject: [NSString stringWithUTF8String:a2value] \
459
+ inFile: [NSString stringWithUTF8String:__FILE__] \
460
+ atLine: __LINE__ \
461
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
462
+ }\
463
+ @catch (id anException) {\
464
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) != (%s)", #a1, #a2] \
465
+ exception:anException \
466
+ inFile:[NSString stringWithUTF8String:__FILE__] \
467
+ atLine:__LINE__ \
468
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
469
+ }\
470
+ } while(0)
471
+
472
+ #if GTM_IPHONE_SDK
473
+
474
+ // SENTE_BEGIN
475
+ /*" Generates a failure when !{ [a1 isEqualTo:a2] } is false
476
+ (or one is nil and the other is not).
477
+ _{a1 The object on the left.}
478
+ _{a2 The object on the right.}
479
+ _{description A format string as in the printf() function. Can be nil or
480
+ an empty string but must be present.}
481
+ _{... A variable number of arguments to the format string. Can be absent.}
482
+ "*/
483
+ #define STAssertEqualObjects(a1, a2, description, ...) \
484
+ do { \
485
+ @try {\
486
+ id a1value = (a1); \
487
+ id a2value = (a2); \
488
+ if (a1value == a2value) continue; \
489
+ if ( (@encode(__typeof__(a1value)) == @encode(id)) && \
490
+ (@encode(__typeof__(a2value)) == @encode(id)) && \
491
+ [(id)a1value isEqual: (id)a2value] ) continue; \
492
+ [self failWithException:[NSException failureInEqualityBetweenObject: a1value \
493
+ andObject: a2value \
494
+ inFile: [NSString stringWithUTF8String:__FILE__] \
495
+ atLine: __LINE__ \
496
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
497
+ }\
498
+ @catch (id anException) {\
499
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \
500
+ exception:anException \
501
+ inFile:[NSString stringWithUTF8String:__FILE__] \
502
+ atLine:__LINE__ \
503
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
504
+ }\
505
+ } while(0)
506
+
507
+
508
+ /*" Generates a failure when a1 is not equal to a2. This test is for
509
+ C scalars, structs and unions.
510
+ _{a1 The argument on the left.}
511
+ _{a2 The argument on the right.}
512
+ _{description A format string as in the printf() function. Can be nil or
513
+ an empty string but must be present.}
514
+ _{... A variable number of arguments to the format string. Can be absent.}
515
+ "*/
516
+ #define STAssertEquals(a1, a2, description, ...) \
517
+ do { \
518
+ @try {\
519
+ if (@encode(__typeof__(a1)) != @encode(__typeof__(a2))) { \
520
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
521
+ atLine:__LINE__ \
522
+ withDescription:[@"Type mismatch -- " stringByAppendingString:STComposeString(description, ##__VA_ARGS__)]]]; \
523
+ } else { \
524
+ __typeof__(a1) a1value = (a1); \
525
+ __typeof__(a2) a2value = (a2); \
526
+ NSValue *a1encoded = [NSValue value:&a1value withObjCType: @encode(__typeof__(a1))]; \
527
+ NSValue *a2encoded = [NSValue value:&a2value withObjCType: @encode(__typeof__(a2))]; \
528
+ if (![a1encoded isEqualToValue:a2encoded]) { \
529
+ [self failWithException:[NSException failureInEqualityBetweenValue: a1encoded \
530
+ andValue: a2encoded \
531
+ withAccuracy: nil \
532
+ inFile: [NSString stringWithUTF8String:__FILE__] \
533
+ atLine: __LINE__ \
534
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
535
+ } \
536
+ } \
537
+ } \
538
+ @catch (id anException) {\
539
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \
540
+ exception:anException \
541
+ inFile:[NSString stringWithUTF8String:__FILE__] \
542
+ atLine:__LINE__ \
543
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
544
+ }\
545
+ } while(0)
546
+
547
+ #define STAbsoluteDifference(left,right) (MAX(left,right)-MIN(left,right))
548
+
549
+
550
+ /*" Generates a failure when a1 is not equal to a2 within + or - accuracy is false.
551
+ This test is for scalars such as floats and doubles where small differences
552
+ could make these items not exactly equal, but also works for all scalars.
553
+ _{a1 The scalar on the left.}
554
+ _{a2 The scalar on the right.}
555
+ _{accuracy The maximum difference between a1 and a2 for these values to be
556
+ considered equal.}
557
+ _{description A format string as in the printf() function. Can be nil or
558
+ an empty string but must be present.}
559
+ _{... A variable number of arguments to the format string. Can be absent.}
560
+ "*/
561
+
562
+ #define STAssertEqualsWithAccuracy(a1, a2, accuracy, description, ...) \
563
+ do { \
564
+ @try {\
565
+ if (@encode(__typeof__(a1)) != @encode(__typeof__(a2))) { \
566
+ [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
567
+ atLine:__LINE__ \
568
+ withDescription:[@"Type mismatch -- " stringByAppendingString:STComposeString(description, ##__VA_ARGS__)]]]; \
569
+ } else { \
570
+ __typeof__(a1) a1value = (a1); \
571
+ __typeof__(a2) a2value = (a2); \
572
+ __typeof__(accuracy) accuracyvalue = (accuracy); \
573
+ if (STAbsoluteDifference(a1value, a2value) > accuracyvalue) { \
574
+ NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
575
+ NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
576
+ NSValue *accuracyencoded = [NSValue value:&accuracyvalue withObjCType:@encode(__typeof__(accuracy))]; \
577
+ [self failWithException:[NSException failureInEqualityBetweenValue: a1encoded \
578
+ andValue: a2encoded \
579
+ withAccuracy: accuracyencoded \
580
+ inFile: [NSString stringWithUTF8String:__FILE__] \
581
+ atLine: __LINE__ \
582
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
583
+ } \
584
+ } \
585
+ } \
586
+ @catch (id anException) {\
587
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \
588
+ exception:anException \
589
+ inFile:[NSString stringWithUTF8String:__FILE__] \
590
+ atLine:__LINE__ \
591
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
592
+ }\
593
+ } while(0)
594
+
595
+
596
+
597
+ /*" Generates a failure unconditionally.
598
+ _{description A format string as in the printf() function. Can be nil or
599
+ an empty string but must be present.}
600
+ _{... A variable number of arguments to the format string. Can be absent.}
601
+ "*/
602
+ #define STFail(description, ...) \
603
+ [self failWithException:[NSException failureInFile: [NSString stringWithUTF8String:__FILE__] \
604
+ atLine: __LINE__ \
605
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]
606
+
607
+
608
+
609
+ /*" Generates a failure when a1 is not nil.
610
+ _{a1 An object.}
611
+ _{description A format string as in the printf() function. Can be nil or
612
+ an empty string but must be present.}
613
+ _{... A variable number of arguments to the format string. Can be absent.}
614
+ "*/
615
+ #define STAssertNil(a1, description, ...) \
616
+ do { \
617
+ @try {\
618
+ id a1value = (a1); \
619
+ if (a1value != nil) { \
620
+ NSString *_a1 = [NSString stringWithUTF8String: #a1]; \
621
+ NSString *_expression = [NSString stringWithFormat:@"((%@) == nil)", _a1]; \
622
+ [self failWithException:[NSException failureInCondition: _expression \
623
+ isTrue: NO \
624
+ inFile: [NSString stringWithUTF8String:__FILE__] \
625
+ atLine: __LINE__ \
626
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
627
+ } \
628
+ }\
629
+ @catch (id anException) {\
630
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == nil fails", #a1] \
631
+ exception:anException \
632
+ inFile:[NSString stringWithUTF8String:__FILE__] \
633
+ atLine:__LINE__ \
634
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
635
+ }\
636
+ } while(0)
637
+
638
+
639
+ /*" Generates a failure when a1 is nil.
640
+ _{a1 An object.}
641
+ _{description A format string as in the printf() function. Can be nil or
642
+ an empty string but must be present.}
643
+ _{... A variable number of arguments to the format string. Can be absent.}
644
+ "*/
645
+ #define STAssertNotNil(a1, description, ...) \
646
+ do { \
647
+ @try {\
648
+ id a1value = (a1); \
649
+ if (a1value == nil) { \
650
+ NSString *_a1 = [NSString stringWithUTF8String: #a1]; \
651
+ NSString *_expression = [NSString stringWithFormat:@"((%@) != nil)", _a1]; \
652
+ [self failWithException:[NSException failureInCondition: _expression \
653
+ isTrue: NO \
654
+ inFile: [NSString stringWithUTF8String:__FILE__] \
655
+ atLine: __LINE__ \
656
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
657
+ } \
658
+ }\
659
+ @catch (id anException) {\
660
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) != nil fails", #a1] \
661
+ exception:anException \
662
+ inFile:[NSString stringWithUTF8String:__FILE__] \
663
+ atLine:__LINE__ \
664
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
665
+ }\
666
+ } while(0)
667
+
668
+
669
+ /*" Generates a failure when expression evaluates to false.
670
+ _{expr The expression that is tested.}
671
+ _{description A format string as in the printf() function. Can be nil or
672
+ an empty string but must be present.}
673
+ _{... A variable number of arguments to the format string. Can be absent.}
674
+ "*/
675
+ #define STAssertTrue(expr, description, ...) \
676
+ do { \
677
+ BOOL _evaluatedExpression = (expr);\
678
+ if (!_evaluatedExpression) {\
679
+ NSString *_expression = [NSString stringWithUTF8String: #expr];\
680
+ [self failWithException:[NSException failureInCondition: _expression \
681
+ isTrue: NO \
682
+ inFile: [NSString stringWithUTF8String:__FILE__] \
683
+ atLine: __LINE__ \
684
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
685
+ } \
686
+ } while (0)
687
+
688
+
689
+ /*" Generates a failure when expression evaluates to false and in addition will
690
+ generate error messages if an exception is encountered.
691
+ _{expr The expression that is tested.}
692
+ _{description A format string as in the printf() function. Can be nil or
693
+ an empty string but must be present.}
694
+ _{... A variable number of arguments to the format string. Can be absent.}
695
+ "*/
696
+ #define STAssertTrueNoThrow(expr, description, ...) \
697
+ do { \
698
+ @try {\
699
+ BOOL _evaluatedExpression = (expr);\
700
+ if (!_evaluatedExpression) {\
701
+ NSString *_expression = [NSString stringWithUTF8String: #expr];\
702
+ [self failWithException:[NSException failureInCondition: _expression \
703
+ isTrue: NO \
704
+ inFile: [NSString stringWithUTF8String:__FILE__] \
705
+ atLine: __LINE__ \
706
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
707
+ } \
708
+ } \
709
+ @catch (id anException) {\
710
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) ", #expr] \
711
+ exception:anException \
712
+ inFile:[NSString stringWithUTF8String:__FILE__] \
713
+ atLine:__LINE__ \
714
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
715
+ }\
716
+ } while (0)
717
+
718
+
719
+ /*" Generates a failure when the expression evaluates to true.
720
+ _{expr The expression that is tested.}
721
+ _{description A format string as in the printf() function. Can be nil or
722
+ an empty string but must be present.}
723
+ _{... A variable number of arguments to the format string. Can be absent.}
724
+ "*/
725
+ #define STAssertFalse(expr, description, ...) \
726
+ do { \
727
+ BOOL _evaluatedExpression = (expr);\
728
+ if (_evaluatedExpression) {\
729
+ NSString *_expression = [NSString stringWithUTF8String: #expr];\
730
+ [self failWithException:[NSException failureInCondition: _expression \
731
+ isTrue: YES \
732
+ inFile: [NSString stringWithUTF8String:__FILE__] \
733
+ atLine: __LINE__ \
734
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
735
+ } \
736
+ } while (0)
737
+
738
+
739
+ /*" Generates a failure when the expression evaluates to true and in addition
740
+ will generate error messages if an exception is encountered.
741
+ _{expr The expression that is tested.}
742
+ _{description A format string as in the printf() function. Can be nil or
743
+ an empty string but must be present.}
744
+ _{... A variable number of arguments to the format string. Can be absent.}
745
+ "*/
746
+ #define STAssertFalseNoThrow(expr, description, ...) \
747
+ do { \
748
+ @try {\
749
+ BOOL _evaluatedExpression = (expr);\
750
+ if (_evaluatedExpression) {\
751
+ NSString *_expression = [NSString stringWithUTF8String: #expr];\
752
+ [self failWithException:[NSException failureInCondition: _expression \
753
+ isTrue: YES \
754
+ inFile: [NSString stringWithUTF8String:__FILE__] \
755
+ atLine: __LINE__ \
756
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
757
+ } \
758
+ } \
759
+ @catch (id anException) {\
760
+ [self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"!(%s) ", #expr] \
761
+ exception:anException \
762
+ inFile:[NSString stringWithUTF8String:__FILE__] \
763
+ atLine:__LINE__ \
764
+ withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
765
+ }\
766
+ } while (0)
767
+
768
+
769
+ /*" Generates a failure when expression does not throw an exception.
770
+ _{expression The expression that is evaluated.}
771
+ _{description A format string as in the printf() function. Can be nil or
772
+ an empty string but must be present.}
773
+ _{... A variable number of arguments to the format string. Can be absent.
774
+ "*/
775
+ #define STAssertThrows(expr, description, ...) \
776
+ do { \
777
+ @try { \
778
+ (expr);\
779
+ } \
780
+ @catch (id anException) { \
781
+ continue; \
782
+ }\
783
+ [self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
784
+ exception: nil \
785
+ inFile: [NSString stringWithUTF8String:__FILE__] \
786
+ atLine: __LINE__ \
787
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
788
+ } while (0)
789
+
790
+
791
+ /*" Generates a failure when expression does not throw an exception of a
792
+ specific class.
793
+ _{expression The expression that is evaluated.}
794
+ _{specificException The specified class of the exception.}
795
+ _{description A format string as in the printf() function. Can be nil or
796
+ an empty string but must be present.}
797
+ _{... A variable number of arguments to the format string. Can be absent.}
798
+ "*/
799
+ #define STAssertThrowsSpecific(expr, specificException, description, ...) \
800
+ do { \
801
+ @try { \
802
+ (expr);\
803
+ } \
804
+ @catch (specificException *anException) { \
805
+ continue; \
806
+ }\
807
+ @catch (id anException) {\
808
+ NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\
809
+ [self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
810
+ exception: anException \
811
+ inFile: [NSString stringWithUTF8String:__FILE__] \
812
+ atLine: __LINE__ \
813
+ withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
814
+ continue; \
815
+ }\
816
+ NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\
817
+ [self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
818
+ exception: nil \
819
+ inFile: [NSString stringWithUTF8String:__FILE__] \
820
+ atLine: __LINE__ \
821
+ withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
822
+ } while (0)
823
+
824
+
825
+ /*" Generates a failure when expression does not throw an exception of a
826
+ specific class with a specific name. Useful for those frameworks like
827
+ AppKit or Foundation that throw generic NSException w/specific names
828
+ (NSInvalidArgumentException, etc).
829
+ _{expression The expression that is evaluated.}
830
+ _{specificException The specified class of the exception.}
831
+ _{aName The name of the specified exception.}
832
+ _{description A format string as in the printf() function. Can be nil or
833
+ an empty string but must be present.}
834
+ _{... A variable number of arguments to the format string. Can be absent.}
835
+
836
+ "*/
837
+ #define STAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) \
838
+ do { \
839
+ @try { \
840
+ (expr);\
841
+ } \
842
+ @catch (specificException *anException) { \
843
+ if ([aName isEqualToString: [anException name]]) continue; \
844
+ NSString *_descrip = STComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description);\
845
+ [self failWithException: \
846
+ [NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
847
+ exception: anException \
848
+ inFile: [NSString stringWithUTF8String:__FILE__] \
849
+ atLine: __LINE__ \
850
+ withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
851
+ continue; \
852
+ }\
853
+ @catch (id anException) {\
854
+ NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\
855
+ [self failWithException: \
856
+ [NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
857
+ exception: anException \
858
+ inFile: [NSString stringWithUTF8String:__FILE__] \
859
+ atLine: __LINE__ \
860
+ withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
861
+ continue; \
862
+ }\
863
+ NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\
864
+ [self failWithException: \
865
+ [NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
866
+ exception: nil \
867
+ inFile: [NSString stringWithUTF8String:__FILE__] \
868
+ atLine: __LINE__ \
869
+ withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
870
+ } while (0)
871
+
872
+
873
+ /*" Generates a failure when expression does throw an exception.
874
+ _{expression The expression that is evaluated.}
875
+ _{description A format string as in the printf() function. Can be nil or
876
+ an empty string but must be present.}
877
+ _{... A variable number of arguments to the format string. Can be absent.}
878
+ "*/
879
+ #define STAssertNoThrow(expr, description, ...) \
880
+ do { \
881
+ @try { \
882
+ (expr);\
883
+ } \
884
+ @catch (id anException) { \
885
+ [self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
886
+ exception: anException \
887
+ inFile: [NSString stringWithUTF8String:__FILE__] \
888
+ atLine: __LINE__ \
889
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
890
+ }\
891
+ } while (0)
892
+
893
+
894
+ /*" Generates a failure when expression does throw an exception of the specitied
895
+ class. Any other exception is okay (i.e. does not generate a failure).
896
+ _{expression The expression that is evaluated.}
897
+ _{specificException The specified class of the exception.}
898
+ _{description A format string as in the printf() function. Can be nil or
899
+ an empty string but must be present.}
900
+ _{... A variable number of arguments to the format string. Can be absent.}
901
+ "*/
902
+ #define STAssertNoThrowSpecific(expr, specificException, description, ...) \
903
+ do { \
904
+ @try { \
905
+ (expr);\
906
+ } \
907
+ @catch (specificException *anException) { \
908
+ [self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
909
+ exception: anException \
910
+ inFile: [NSString stringWithUTF8String:__FILE__] \
911
+ atLine: __LINE__ \
912
+ withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
913
+ }\
914
+ @catch (id anythingElse) {\
915
+ ; \
916
+ }\
917
+ } while (0)
918
+
919
+
920
+ /*" Generates a failure when expression does throw an exception of a
921
+ specific class with a specific name. Useful for those frameworks like
922
+ AppKit or Foundation that throw generic NSException w/specific names
923
+ (NSInvalidArgumentException, etc).
924
+ _{expression The expression that is evaluated.}
925
+ _{specificException The specified class of the exception.}
926
+ _{aName The name of the specified exception.}
927
+ _{description A format string as in the printf() function. Can be nil or
928
+ an empty string but must be present.}
929
+ _{... A variable number of arguments to the format string. Can be absent.}
930
+
931
+ "*/
932
+ #define STAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) \
933
+ do { \
934
+ @try { \
935
+ (expr);\
936
+ } \
937
+ @catch (specificException *anException) { \
938
+ if ([aName isEqualToString: [anException name]]) { \
939
+ NSString *_descrip = STComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description);\
940
+ [self failWithException: \
941
+ [NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
942
+ exception: anException \
943
+ inFile: [NSString stringWithUTF8String:__FILE__] \
944
+ atLine: __LINE__ \
945
+ withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
946
+ } \
947
+ continue; \
948
+ }\
949
+ @catch (id anythingElse) {\
950
+ ; \
951
+ }\
952
+ } while (0)
953
+
954
+
955
+
956
+ @interface NSException (GTMSenTestAdditions)
957
+ + (NSException *)failureInFile:(NSString *)filename
958
+ atLine:(int)lineNumber
959
+ withDescription:(NSString *)formatString, ...;
960
+ + (NSException *)failureInCondition:(NSString *)condition
961
+ isTrue:(BOOL)isTrue
962
+ inFile:(NSString *)filename
963
+ atLine:(int)lineNumber
964
+ withDescription:(NSString *)formatString, ...;
965
+ + (NSException *)failureInEqualityBetweenObject:(id)left
966
+ andObject:(id)right
967
+ inFile:(NSString *)filename
968
+ atLine:(int)lineNumber
969
+ withDescription:(NSString *)formatString, ...;
970
+ + (NSException *)failureInEqualityBetweenValue:(NSValue *)left
971
+ andValue:(NSValue *)right
972
+ withAccuracy:(NSValue *)accuracy
973
+ inFile:(NSString *)filename
974
+ atLine:(int) ineNumber
975
+ withDescription:(NSString *)formatString, ...;
976
+ + (NSException *)failureInRaise:(NSString *)expression
977
+ inFile:(NSString *)filename
978
+ atLine:(int)lineNumber
979
+ withDescription:(NSString *)formatString, ...;
980
+ + (NSException *)failureInRaise:(NSString *)expression
981
+ exception:(NSException *)exception
982
+ inFile:(NSString *)filename
983
+ atLine:(int)lineNumber
984
+ withDescription:(NSString *)formatString, ...;
985
+ @end
986
+
987
+ // SENTE_END
988
+
989
+ @interface SenTestCase : NSObject {
990
+ SEL currentSelector_;
991
+ }
992
+
993
+ - (void)setUp;
994
+ - (void)invokeTest;
995
+ - (void)tearDown;
996
+ - (void)performTest:(SEL)sel;
997
+ - (void)failWithException:(NSException*)exception;
998
+ @end
999
+
1000
+ GTM_EXTERN NSString *const SenTestFailureException;
1001
+
1002
+ GTM_EXTERN NSString *const SenTestFilenameKey;
1003
+ GTM_EXTERN NSString *const SenTestLineNumberKey;
1004
+
1005
+ #endif // GTM_IPHONE_SDK
1006
+
1007
+ // All unittest cases in GTM should inherit from GTMTestCase. It makes sure
1008
+ // to set up our logging system correctly to verify logging calls.
1009
+ // See GTMUnitTestDevLog.h for details
1010
+ @interface GTMTestCase : SenTestCase
1011
+ @end