nevans-iphone_testify 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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