• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) || (GTM_IPHONE_USE_SENTEST)
57 #import <SenTestingKit/SenTestingKit.h>
58 #else
59 #import <Foundation/Foundation.h>
60 #ifdef __cplusplus
61 extern "C" {
62 #endif
63 
64 #if defined __clang__
65 // gcc and gcc-llvm do not allow you to use STAssert(blah, nil) with nil
66 // as a description if you have the NS_FORMAT_FUNCTION on.
67 // clang however will not compile without warnings if you don't have it.
68 NSString *STComposeString(NSString *, ...) NS_FORMAT_FUNCTION(1, 2);
69 #else
70 NSString *STComposeString(NSString *, ...);
71 #endif  // __clang__
72 
73 #ifdef __cplusplus
74 }
75 #endif
76 
77 #endif  // !GTM_IPHONE_SDK || GTM_IPHONE_USE_SENTEST
78 
79 // Generates a failure when a1 != noErr
80 //  Args:
81 //    a1: should be either an OSErr or an OSStatus
82 //    description: A format string as in the printf() function. Can be nil or
83 //                 an empty string but must be present.
84 //    ...: A variable number of arguments to the format string. Can be absent.
85 #define STAssertNoErr(a1, description, ...) \
86 do { \
87   @try { \
88     OSStatus a1value = (a1); \
89     if (a1value != noErr) { \
90       NSString *_expression = [NSString stringWithFormat:@"Expected noErr, got %ld for (%s)", (long)a1value, #a1]; \
91       [self failWithException:([NSException failureInCondition:_expression \
92                        isTrue:NO \
93                        inFile:[NSString stringWithUTF8String:__FILE__] \
94                        atLine:__LINE__ \
95               withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
96     } \
97   } \
98   @catch (id anException) { \
99     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == noErr fails", #a1] \
100                                               exception:anException \
101                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
102                                                  atLine:__LINE__ \
103                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
104   } \
105 } while(0)
106 
107 // Generates a failure when a1 != a2
108 //  Args:
109 //    a1: received value. Should be either an OSErr or an OSStatus
110 //    a2: expected value. Should be either an OSErr or an OSStatus
111 //    description: A format string as in the printf() function. Can be nil or
112 //                 an empty string but must be present.
113 //    ...: A variable number of arguments to the format string. Can be absent.
114 #define STAssertErr(a1, a2, description, ...) \
115 do { \
116   @try { \
117     OSStatus a1value = (a1); \
118     OSStatus a2value = (a2); \
119     if (a1value != a2value) { \
120       NSString *_expression = [NSString stringWithFormat:@"Expected %s(%ld) but got %ld for (%s)", #a2, (long)a2value, (long)a1value, #a1]; \
121       [self failWithException:([NSException failureInCondition:_expression \
122                        isTrue:NO \
123                        inFile:[NSString stringWithUTF8String:__FILE__] \
124                        atLine:__LINE__ \
125               withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
126     } \
127   } \
128   @catch (id anException) { \
129     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s) fails", #a1, #a2] \
130                                               exception:anException \
131                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
132                                                  atLine:__LINE__ \
133                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
134   } \
135 } while(0)
136 
137 
138 // Generates a failure when a1 is NULL
139 //  Args:
140 //    a1: should be a pointer (use STAssertNotNil for an object)
141 //    description: A format string as in the printf() function. Can be nil or
142 //                 an empty string but must be present.
143 //    ...: A variable number of arguments to the format string. Can be absent.
144 #define STAssertNotNULL(a1, description, ...) \
145 do { \
146   @try { \
147     __typeof__(a1) a1value = (a1); \
148     if (a1value == (__typeof__(a1))NULL) { \
149       NSString *_expression = [NSString stringWithFormat:@"((%s) != NULL)", #a1]; \
150       [self failWithException:([NSException failureInCondition:_expression \
151                        isTrue:NO \
152                        inFile:[NSString stringWithUTF8String:__FILE__] \
153                        atLine:__LINE__ \
154               withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
155     } \
156   } \
157   @catch (id anException) { \
158     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != NULL fails", #a1] \
159                                               exception:anException \
160                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
161                                                  atLine:__LINE__ \
162                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
163   } \
164 } while(0)
165 
166 // Generates a failure when a1 is not NULL
167 //  Args:
168 //    a1: should be a pointer (use STAssertNil for an object)
169 //    description: A format string as in the printf() function. Can be nil or
170 //                 an empty string but must be present.
171 //    ...: A variable number of arguments to the format string. Can be absent.
172 #define STAssertNULL(a1, description, ...) \
173 do { \
174   @try { \
175     __typeof__(a1) a1value = (a1); \
176     if (a1value != (__typeof__(a1))NULL) { \
177       NSString *_expression = [NSString stringWithFormat:@"((%s) == NULL)", #a1]; \
178       [self failWithException:([NSException failureInCondition:_expression \
179                                                         isTrue:NO \
180                                                         inFile:[NSString stringWithUTF8String:__FILE__] \
181                                                         atLine:__LINE__ \
182                                                withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
183     } \
184   } \
185   @catch (id anException) { \
186     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == NULL fails", #a1] \
187                                               exception:anException \
188                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
189                                                  atLine:__LINE__ \
190                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
191   } \
192 } while(0)
193 
194 // Generates a failure when a1 is equal to a2. This test is for C scalars,
195 // structs and unions.
196 //  Args:
197 //    a1: argument 1
198 //    a2: argument 2
199 //    description: A format string as in the printf() function. Can be nil or
200 //                 an empty string but must be present.
201 //    ...: A variable number of arguments to the format string. Can be absent.
202 #define STAssertNotEquals(a1, a2, description, ...) \
203 do { \
204   @try { \
205     if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
206       [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
207                                                   atLine:__LINE__ \
208                                          withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
209     } else { \
210       __typeof__(a1) a1value = (a1); \
211       __typeof__(a2) a2value = (a2); \
212       NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
213       NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
214       if ([a1encoded isEqualToValue:a2encoded]) { \
215         NSString *_expression = [NSString stringWithFormat:@"((%s) != (%s))", #a1, #a2]; \
216         [self failWithException:([NSException failureInCondition:_expression \
217                          isTrue:NO \
218                          inFile:[NSString stringWithUTF8String:__FILE__] \
219                          atLine:__LINE__ \
220                 withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
221       }\
222     } \
223   } \
224   @catch (id anException) { \
225     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
226                                               exception:anException \
227                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
228                                                  atLine:__LINE__ \
229             withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
230   } \
231 } while(0)
232 
233 // Generates a failure when a1 is equal to a2. This test is for objects.
234 //  Args:
235 //    a1: argument 1. object.
236 //    a2: argument 2. object.
237 //    description: A format string as in the printf() function. Can be nil or
238 //                 an empty string but must be present.
239 //    ...: A variable number of arguments to the format string. Can be absent.
240 #define STAssertNotEqualObjects(a1, a2, description, ...) \
241 do { \
242   @try {\
243     id a1value = (a1); \
244     id a2value = (a2); \
245     if ( (strcmp(@encode(__typeof__(a1value)), @encode(id)) == 0) && \
246          (strcmp(@encode(__typeof__(a2value)), @encode(id)) == 0) && \
247          (![(id)a1value isEqual:(id)a2value]) ) continue; \
248     [self failWithException:([NSException failureInEqualityBetweenObject:a1value \
249                   andObject:a2value \
250                      inFile:[NSString stringWithUTF8String:__FILE__] \
251                      atLine:__LINE__ \
252             withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
253   }\
254   @catch (id anException) {\
255     [self failWithException:([NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
256                                                exception:anException \
257                                                   inFile:[NSString stringWithUTF8String:__FILE__] \
258                                                   atLine:__LINE__ \
259                                          withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
260   }\
261 } while(0)
262 
263 // Generates a failure when a1 is not 'op' to a2. This test is for C scalars.
264 //  Args:
265 //    a1: argument 1
266 //    a2: argument 2
267 //    op: operation
268 //    description: A format string as in the printf() function. Can be nil or
269 //                 an empty string but must be present.
270 //    ...: A variable number of arguments to the format string. Can be absent.
271 #define STAssertOperation(a1, a2, op, description, ...) \
272 do { \
273   @try { \
274     if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
275       [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
276                                                   atLine:__LINE__ \
277                                          withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
278     } else { \
279       __typeof__(a1) a1value = (a1); \
280       __typeof__(a2) a2value = (a2); \
281       if (!(a1value op a2value)) { \
282         double a1DoubleValue = a1value; \
283         double a2DoubleValue = a2value; \
284         NSString *_expression = [NSString stringWithFormat:@"(%s (%lg) %s %s (%lg))", #a1, a1DoubleValue, #op, #a2, a2DoubleValue]; \
285         [self failWithException:([NSException failureInCondition:_expression \
286                          isTrue:NO \
287                          inFile:[NSString stringWithUTF8String:__FILE__] \
288                          atLine:__LINE__ \
289                 withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \
290       } \
291     } \
292   } \
293   @catch (id anException) { \
294     [self failWithException:[NSException \
295              failureInRaise:[NSString stringWithFormat:@"(%s) %s (%s)", #a1, #op, #a2] \
296                   exception:anException \
297                      inFile:[NSString stringWithUTF8String:__FILE__] \
298                      atLine:__LINE__ \
299             withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
300   } \
301 } while(0)
302 
303 // Generates a failure when a1 is not > a2. This test is for C scalars.
304 //  Args:
305 //    a1: argument 1
306 //    a2: argument 2
307 //    op: operation
308 //    description: A format string as in the printf() function. Can be nil or
309 //                 an empty string but must be present.
310 //    ...: A variable number of arguments to the format string. Can be absent.
311 #define STAssertGreaterThan(a1, a2, description, ...) \
312   STAssertOperation(a1, a2, >, description, ##__VA_ARGS__)
313 
314 // Generates a failure when a1 is not >= a2. This test is for C scalars.
315 //  Args:
316 //    a1: argument 1
317 //    a2: argument 2
318 //    op: operation
319 //    description: A format string as in the printf() function. Can be nil or
320 //                 an empty string but must be present.
321 //    ...: A variable number of arguments to the format string. Can be absent.
322 #define STAssertGreaterThanOrEqual(a1, a2, description, ...) \
323   STAssertOperation(a1, a2, >=, description, ##__VA_ARGS__)
324 
325 // Generates a failure when a1 is not < a2. This test is for C scalars.
326 //  Args:
327 //    a1: argument 1
328 //    a2: argument 2
329 //    op: operation
330 //    description: A format string as in the printf() function. Can be nil or
331 //                 an empty string but must be present.
332 //    ...: A variable number of arguments to the format string. Can be absent.
333 #define STAssertLessThan(a1, a2, description, ...) \
334   STAssertOperation(a1, a2, <, description, ##__VA_ARGS__)
335 
336 // Generates a failure when a1 is not <= a2. This test is for C scalars.
337 //  Args:
338 //    a1: argument 1
339 //    a2: argument 2
340 //    op: operation
341 //    description: A format string as in the printf() function. Can be nil or
342 //                 an empty string but must be present.
343 //    ...: A variable number of arguments to the format string. Can be absent.
344 #define STAssertLessThanOrEqual(a1, a2, description, ...) \
345   STAssertOperation(a1, a2, <=, description, ##__VA_ARGS__)
346 
347 // Generates a failure when string a1 is not equal to string a2. This call
348 // differs from STAssertEqualObjects in that strings that are different in
349 // composition (precomposed vs decomposed) will compare equal if their final
350 // representation is equal.
351 // ex O + umlaut decomposed is the same as O + umlaut composed.
352 //  Args:
353 //    a1: string 1
354 //    a2: string 2
355 //    description: A format string as in the printf() function. Can be nil or
356 //                 an empty string but must be present.
357 //    ...: A variable number of arguments to the format string. Can be absent.
358 #define STAssertEqualStrings(a1, a2, description, ...) \
359 do { \
360   @try { \
361     id a1value = (a1); \
362     id a2value = (a2); \
363     if (a1value == a2value) continue; \
364     if ([a1value isKindOfClass:[NSString class]] && \
365         [a2value isKindOfClass:[NSString class]] && \
366         [a1value compare:a2value options:0] == NSOrderedSame) continue; \
367      [self failWithException:[NSException failureInEqualityBetweenObject:a1value \
368                                                                andObject:a2value \
369                                                                   inFile:[NSString stringWithUTF8String:__FILE__] \
370                                                                   atLine:__LINE__ \
371                                                          withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
372   } \
373   @catch (id anException) { \
374     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
375                                               exception:anException \
376                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
377                                                  atLine:__LINE__ \
378                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
379   } \
380 } while(0)
381 
382 // Generates a failure when string a1 is equal to string a2. This call
383 // differs from STAssertEqualObjects in that strings that are different in
384 // composition (precomposed vs decomposed) will compare equal if their final
385 // representation is equal.
386 // ex O + umlaut decomposed is the same as O + umlaut composed.
387 //  Args:
388 //    a1: string 1
389 //    a2: string 2
390 //    description: A format string as in the printf() function. Can be nil or
391 //                 an empty string but must be present.
392 //    ...: A variable number of arguments to the format string. Can be absent.
393 #define STAssertNotEqualStrings(a1, a2, description, ...) \
394 do { \
395   @try { \
396     id a1value = (a1); \
397     id a2value = (a2); \
398     if ([a1value isKindOfClass:[NSString class]] && \
399         [a2value isKindOfClass:[NSString class]] && \
400         [a1value compare:a2value options:0] != NSOrderedSame) continue; \
401      [self failWithException:[NSException failureInEqualityBetweenObject:a1value \
402                                                                andObject:a2value \
403                                                                   inFile:[NSString stringWithUTF8String:__FILE__] \
404                                                                   atLine:__LINE__ \
405                                                          withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
406   } \
407   @catch (id anException) { \
408     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
409                                               exception:anException \
410                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
411                                                  atLine:__LINE__ \
412                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
413   } \
414 } while(0)
415 
416 // Generates a failure when c-string a1 is not equal to c-string a2.
417 //  Args:
418 //    a1: string 1
419 //    a2: string 2
420 //    description: A format string as in the printf() function. Can be nil or
421 //                 an empty string but must be present.
422 //    ...: A variable number of arguments to the format string. Can be absent.
423 #define STAssertEqualCStrings(a1, a2, description, ...) \
424 do { \
425   @try { \
426     const char* a1value = (a1); \
427     const char* a2value = (a2); \
428     if (a1value == a2value) continue; \
429     if (strcmp(a1value, a2value) == 0) continue; \
430     [self failWithException:[NSException failureInEqualityBetweenObject:[NSString stringWithUTF8String:a1value] \
431                                                               andObject:[NSString stringWithUTF8String:a2value] \
432                                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
433                                                                  atLine:__LINE__ \
434                                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
435   } \
436   @catch (id anException) { \
437     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
438                                               exception:anException \
439                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
440                                                  atLine:__LINE__ \
441                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
442   } \
443 } while(0)
444 
445 // Generates a failure when c-string a1 is equal to c-string a2.
446 //  Args:
447 //    a1: string 1
448 //    a2: string 2
449 //    description: A format string as in the printf() function. Can be nil or
450 //                 an empty string but must be present.
451 //    ...: A variable number of arguments to the format string. Can be absent.
452 #define STAssertNotEqualCStrings(a1, a2, description, ...) \
453 do { \
454   @try { \
455     const char* a1value = (a1); \
456     const char* a2value = (a2); \
457     if (strcmp(a1value, a2value) != 0) continue; \
458     [self failWithException:[NSException failureInEqualityBetweenObject:[NSString stringWithUTF8String:a1value] \
459                                                               andObject:[NSString stringWithUTF8String:a2value] \
460                                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
461                                                                  atLine:__LINE__ \
462                                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
463   } \
464   @catch (id anException) { \
465     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
466                                               exception:anException \
467                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
468                                                  atLine:__LINE__ \
469                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
470   } \
471 } while(0)
472 
473 /*" Generates a failure when a1 is not equal to a2 within + or - accuracy is false.
474   This test is for GLKit types (GLKVector, GLKMatrix) where small differences
475   could  make these items not exactly equal. Do not use this version directly.
476   Use the explicit STAssertEqualGLKVectors and STAssertEqualGLKMatrices defined
477   below.
478   _{a1    The GLKType on the left.}
479   _{a2    The GLKType on the right.}
480   _{accuracy  The maximum difference between a1 and a2 for these values to be
481   considered equal.}
482   _{description A format string as in the printf() function. Can be nil or
483                       an empty string but must be present.}
484   _{... A variable number of arguments to the format string. Can be absent.}
485 "*/
486 
487 #define STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ...) \
488 do { \
489   @try { \
490     if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
491       [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
492                                                                                  atLine:__LINE__ \
493                                                                         withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
494     } else { \
495       __typeof__(a1) a1GLKValue = (a1); \
496       __typeof__(a2) a2GLKValue = (a2); \
497       __typeof__(accuracy) accuracyvalue = (accuracy); \
498       float *a1FloatValue = ((float*)&a1GLKValue); \
499       float *a2FloatValue = ((float*)&a2GLKValue); \
500       for (size_t i = 0; i < sizeof(__typeof__(a1)) / sizeof(float); ++i) { \
501         float a1value = a1FloatValue[i]; \
502         float a2value = a2FloatValue[i]; \
503         if (STAbsoluteDifference(a1value, a2value) > accuracyvalue) { \
504           NSMutableArray *strings = [NSMutableArray arrayWithCapacity:sizeof(a1) / sizeof(float)]; \
505           NSString *string; \
506           for (size_t j = 0; j < sizeof(__typeof__(a1)) / sizeof(float); ++j) { \
507             string = [NSString stringWithFormat:@"(%0.3f == %0.3f)", a1FloatValue[j], a2FloatValue[j]]; \
508             [strings addObject:string]; \
509           } \
510           string = [strings componentsJoinedByString:@", "]; \
511           NSString *desc = STComposeString(description, ##__VA_ARGS__); \
512           desc = [NSString stringWithFormat:@"%@ With Accuracy %0.3f: %@", string, (float)accuracyvalue, desc]; \
513           [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
514                                                       atLine:__LINE__ \
515                                              withDescription:@"%@", desc]]; \
516           break; \
517         } \
518       } \
519     } \
520   } \
521   @catch (id anException) { \
522     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
523                                               exception:anException \
524                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
525                                                  atLine:__LINE__ \
526                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
527   } \
528 } while(0)
529 
530 #define STAssertEqualGLKVectors(a1, a2, accuracy, description, ...) \
531      STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__)
532 
533 #define STAssertEqualGLKMatrices(a1, a2, accuracy, description, ...) \
534      STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__)
535 
536 #define STAssertEqualGLKQuaternions(a1, a2, accuracy, description, ...) \
537      STInternalAssertEqualGLKVectorsOrMatrices(a1, a2, accuracy, description, ##__VA_ARGS__)
538 
539 #if GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST
540 // When not using the Xcode provided version, define everything ourselves.
541 
542 // SENTE_BEGIN
543 /*" Generates a failure when !{ [a1 isEqualTo:a2] } is false
544 	(or one is nil and the other is not).
545 	_{a1    The object on the left.}
546 	_{a2    The object on the right.}
547 	_{description A format string as in the printf() function. Can be nil or
548 		an empty string but must be present.}
549 	_{... A variable number of arguments to the format string. Can be absent.}
550 "*/
551 #define STAssertEqualObjects(a1, a2, description, ...) \
552 do { \
553   @try { \
554     id a1value = (a1); \
555     id a2value = (a2); \
556     if (a1value == a2value) continue; \
557     if ((strcmp(@encode(__typeof__(a1value)), @encode(id)) == 0) && \
558         (strcmp(@encode(__typeof__(a2value)), @encode(id)) == 0) && \
559         [(id)a1value isEqual:(id)a2value]) continue; \
560     [self failWithException:[NSException failureInEqualityBetweenObject:a1value \
561                                                               andObject:a2value \
562                                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
563                                                                  atLine:__LINE__ \
564                                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
565   } \
566   @catch (id anException) { \
567     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
568                                               exception:anException \
569                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
570                                                  atLine:__LINE__ \
571                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
572   } \
573 } while(0)
574 
575 
576 /*" Generates a failure when a1 is not equal to a2. This test is for
577     C scalars, structs and unions.
578     _{a1    The argument on the left.}
579     _{a2    The argument on the right.}
580     _{description A format string as in the printf() function. Can be nil or
581                         an empty string but must be present.}
582     _{... A variable number of arguments to the format string. Can be absent.}
583 "*/
584 #define STAssertEquals(a1, a2, description, ...) \
585 do { \
586   @try { \
587     if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
588       [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
589                                                                                  atLine:__LINE__ \
590                                                                         withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
591     } else { \
592       __typeof__(a1) a1value = (a1); \
593       __typeof__(a2) a2value = (a2); \
594       NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
595       NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
596       if (![a1encoded isEqualToValue:a2encoded]) { \
597         [self failWithException:[NSException failureInEqualityBetweenValue:a1encoded \
598                                                                   andValue:a2encoded \
599                                                               withAccuracy:nil \
600                                                                     inFile:[NSString stringWithUTF8String:__FILE__] \
601                                                                     atLine:__LINE__ \
602                                                            withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
603       } \
604     } \
605   } \
606   @catch (id anException) { \
607     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
608                                               exception:anException \
609                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
610                                                  atLine:__LINE__ \
611                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
612   } \
613 } while(0)
614 
615 #define STAbsoluteDifference(left,right) (MAX(left,right)-MIN(left,right))
616 
617 
618 /*" Generates a failure when a1 is not equal to a2 within + or - accuracy is false.
619   This test is for scalars such as floats and doubles where small differences
620   could make these items not exactly equal, but also works for all scalars.
621   _{a1    The scalar on the left.}
622   _{a2    The scalar on the right.}
623   _{accuracy  The maximum difference between a1 and a2 for these values to be
624   considered equal.}
625   _{description A format string as in the printf() function. Can be nil or
626                       an empty string but must be present.}
627   _{... A variable number of arguments to the format string. Can be absent.}
628 "*/
629 
630 #define STAssertEqualsWithAccuracy(a1, a2, accuracy, description, ...) \
631 do { \
632   @try { \
633     if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2)))) { \
634       [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
635                                                                                  atLine:__LINE__ \
636                                                                         withDescription:@"Type mismatch -- %@", STComposeString(description, ##__VA_ARGS__)]]; \
637     } else { \
638       __typeof__(a1) a1value = (a1); \
639       __typeof__(a2) a2value = (a2); \
640       __typeof__(accuracy) accuracyvalue = (accuracy); \
641       if (STAbsoluteDifference(a1value, a2value) > accuracyvalue) { \
642               NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
643               NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
644               NSValue *accuracyencoded = [NSValue value:&accuracyvalue withObjCType:@encode(__typeof__(accuracy))]; \
645               [self failWithException:[NSException failureInEqualityBetweenValue:a1encoded \
646                                                                         andValue:a2encoded \
647                                                                     withAccuracy:accuracyencoded \
648                                                                           inFile:[NSString stringWithUTF8String:__FILE__] \
649                                                                           atLine:__LINE__ \
650                                                                  withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
651       } \
652     } \
653   } \
654   @catch (id anException) { \
655     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == (%s)", #a1, #a2] \
656                                                                          exception:anException \
657                                                                             inFile:[NSString stringWithUTF8String:__FILE__] \
658                                                                             atLine:__LINE__ \
659                                                                    withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
660   } \
661 } while(0)
662 
663 
664 
665 /*" Generates a failure unconditionally.
666   _{description A format string as in the printf() function. Can be nil or
667                       an empty string but must be present.}
668   _{... A variable number of arguments to the format string. Can be absent.}
669 "*/
670 #define STFail(description, ...) \
671 [self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
672                                             atLine:__LINE__ \
673                                    withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]
674 
675 
676 
677 /*" Generates a failure when a1 is not nil.
678   _{a1    An object.}
679   _{description A format string as in the printf() function. Can be nil or
680     an empty string but must be present.}
681   _{... A variable number of arguments to the format string. Can be absent.}
682 "*/
683 #define STAssertNil(a1, description, ...) \
684 do { \
685   @try { \
686     id a1value = (a1); \
687     if (a1value != nil) { \
688       NSString *_a1 = [NSString stringWithUTF8String:#a1]; \
689       NSString *_expression = [NSString stringWithFormat:@"((%@) == nil)", _a1]; \
690       [self failWithException:[NSException failureInCondition:_expression \
691                                                        isTrue:NO \
692                                                        inFile:[NSString stringWithUTF8String:__FILE__] \
693                                                        atLine:__LINE__ \
694                                               withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
695     } \
696   } \
697   @catch (id anException) { \
698     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == nil fails", #a1] \
699                                               exception:anException \
700                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
701                                                  atLine:__LINE__ \
702                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
703   } \
704 } while(0)
705 
706 
707 /*" Generates a failure when a1 is nil.
708   _{a1    An object.}
709   _{description A format string as in the printf() function. Can be nil or
710   an empty string but must be present.}
711   _{... A variable number of arguments to the format string. Can be absent.}
712 "*/
713 #define STAssertNotNil(a1, description, ...) \
714 do { \
715   @try { \
716     id a1value = (a1); \
717     if (a1value == nil) { \
718       NSString *_a1 = [NSString stringWithUTF8String:#a1]; \
719       NSString *_expression = [NSString stringWithFormat:@"((%@) != nil)", _a1]; \
720       [self failWithException:[NSException failureInCondition:_expression \
721                                                        isTrue:NO \
722                                                        inFile:[NSString stringWithUTF8String:__FILE__] \
723                                                        atLine:__LINE__ \
724                                               withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
725     } \
726   } \
727   @catch (id anException) { \
728     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != nil fails", #a1] \
729                                               exception:anException \
730                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
731                                                  atLine:__LINE__ \
732                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
733   } \
734 } while(0)
735 
736 
737 /*" Generates a failure when expression evaluates to false.
738   _{expr    The expression that is tested.}
739   _{description A format string as in the printf() function. Can be nil or
740   an empty string but must be present.}
741   _{... A variable number of arguments to the format string. Can be absent.}
742 "*/
743 #define STAssertTrue(expr, description, ...) \
744 do { \
745   BOOL _evaluatedExpression = (expr); \
746   if (!_evaluatedExpression) { \
747     NSString *_expression = [NSString stringWithUTF8String:#expr]; \
748     [self failWithException:[NSException failureInCondition:_expression \
749                                                      isTrue:NO \
750                                                      inFile:[NSString stringWithUTF8String:__FILE__] \
751                                                      atLine:__LINE__ \
752                                             withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
753   } \
754 } while (0)
755 
756 
757 /*" Generates a failure when expression evaluates to false and in addition will
758   generate error messages if an exception is encountered.
759   _{expr    The expression that is tested.}
760   _{description A format string as in the printf() function. Can be nil or
761   an empty string but must be present.}
762   _{... A variable number of arguments to the format string. Can be absent.}
763 "*/
764 #define STAssertTrueNoThrow(expr, description, ...) \
765 do { \
766   @try { \
767     BOOL _evaluatedExpression = (expr); \
768     if (!_evaluatedExpression) { \
769       NSString *_expression = [NSString stringWithUTF8String:#expr]; \
770       [self failWithException:[NSException failureInCondition:_expression \
771                                                        isTrue:NO \
772                                                        inFile:[NSString stringWithUTF8String:__FILE__] \
773                                                        atLine:__LINE__ \
774                                               withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
775     } \
776   } \
777   @catch (id anException) { \
778     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) ", #expr] \
779                                               exception:anException \
780                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
781                                                  atLine:__LINE__ \
782                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
783   } \
784 } while (0)
785 
786 
787 /*" Generates a failure when the expression evaluates to true.
788   _{expr    The expression that is tested.}
789   _{description A format string as in the printf() function. Can be nil or
790   an empty string but must be present.}
791   _{... A variable number of arguments to the format string. Can be absent.}
792 "*/
793 #define STAssertFalse(expr, description, ...) \
794 do { \
795   BOOL _evaluatedExpression = (expr); \
796   if (_evaluatedExpression) { \
797     NSString *_expression = [NSString stringWithUTF8String:#expr]; \
798     [self failWithException:[NSException failureInCondition:_expression \
799                                                      isTrue:YES \
800                                                      inFile:[NSString stringWithUTF8String:__FILE__] \
801                                                      atLine:__LINE__ \
802                                             withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
803   } \
804 } while (0)
805 
806 
807 /*" Generates a failure when the expression evaluates to true and in addition
808   will generate error messages if an exception is encountered.
809   _{expr    The expression that is tested.}
810   _{description A format string as in the printf() function. Can be nil or
811   an empty string but must be present.}
812   _{... A variable number of arguments to the format string. Can be absent.}
813 "*/
814 #define STAssertFalseNoThrow(expr, description, ...) \
815 do { \
816   @try { \
817     BOOL _evaluatedExpression = (expr); \
818     if (_evaluatedExpression) { \
819       NSString *_expression = [NSString stringWithUTF8String:#expr]; \
820       [self failWithException:[NSException failureInCondition:_expression \
821                                                        isTrue:YES \
822                                                        inFile:[NSString stringWithUTF8String:__FILE__] \
823                                                        atLine:__LINE__ \
824                                               withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
825     } \
826   } \
827   @catch (id anException) { \
828     [self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"!(%s) ", #expr] \
829                                               exception:anException \
830                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
831                                                  atLine:__LINE__ \
832                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
833   } \
834 } while (0)
835 
836 
837 /*" Generates a failure when expression does not throw an exception.
838   _{expression    The expression that is evaluated.}
839   _{description A format string as in the printf() function. Can be nil or
840   an empty string but must be present.}
841   _{... A variable number of arguments to the format string. Can be absent.
842 "*/
843 #define STAssertThrows(expr, description, ...) \
844 do { \
845   @try { \
846     (expr); \
847   } \
848   @catch (id anException) { \
849     continue; \
850   } \
851   [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
852                                             exception:nil \
853                                                inFile:[NSString stringWithUTF8String:__FILE__] \
854                                                atLine:__LINE__ \
855                                       withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
856 } while (0)
857 
858 
859 /*" Generates a failure when expression does not throw an exception of a
860   specific class.
861   _{expression    The expression that is evaluated.}
862   _{specificException    The specified class of the exception.}
863   _{description A format string as in the printf() function. Can be nil or
864   an empty string but must be present.}
865   _{... A variable number of arguments to the format string. Can be absent.}
866 "*/
867 #define STAssertThrowsSpecific(expr, specificException, description, ...) \
868 do { \
869   @try { \
870     (expr); \
871   } \
872   @catch (specificException *anException) { \
873     continue; \
874   } \
875   @catch (id anException) { \
876     NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \
877     [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
878                                               exception:anException \
879                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
880                                                  atLine:__LINE__ \
881                                         withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
882                                             continue; \
883   } \
884   NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \
885   [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
886                                             exception:nil \
887                                                inFile:[NSString stringWithUTF8String:__FILE__] \
888                                                atLine:__LINE__ \
889                                       withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
890 } while (0)
891 
892 
893 /*" Generates a failure when expression does not throw an exception of a
894   specific class with a specific name.  Useful for those frameworks like
895   AppKit or Foundation that throw generic NSException w/specific names
896   (NSInvalidArgumentException, etc).
897   _{expression    The expression that is evaluated.}
898   _{specificException    The specified class of the exception.}
899   _{aName    The name of the specified exception.}
900   _{description A format string as in the printf() function. Can be nil or
901   an empty string but must be present.}
902   _{... A variable number of arguments to the format string. Can be absent.}
903 
904 "*/
905 #define STAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) \
906 do { \
907   @try { \
908     (expr); \
909   } \
910   @catch (specificException *anException) { \
911     if ([aName isEqualToString:[anException name]]) continue; \
912     NSString *_descrip = STComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description); \
913     [self failWithException: \
914       [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
915                         exception:anException \
916                            inFile:[NSString stringWithUTF8String:__FILE__] \
917                            atLine:__LINE__ \
918                   withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
919     continue; \
920   } \
921   @catch (id anException) { \
922     NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \
923     [self failWithException: \
924       [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
925                         exception:anException \
926                            inFile:[NSString stringWithUTF8String:__FILE__] \
927                            atLine:__LINE__ \
928                   withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
929     continue; \
930   } \
931   NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description); \
932   [self failWithException: \
933     [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
934                       exception:nil \
935                          inFile:[NSString stringWithUTF8String:__FILE__] \
936                          atLine:__LINE__ \
937                 withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
938 } while (0)
939 
940 
941 /*" Generates a failure when expression does throw an exception.
942   _{expression    The expression that is evaluated.}
943   _{description A format string as in the printf() function. Can be nil or
944   an empty string but must be present.}
945   _{... A variable number of arguments to the format string. Can be absent.}
946 "*/
947 #define STAssertNoThrow(expr, description, ...) \
948 do { \
949   @try { \
950     (expr); \
951   } \
952   @catch (id anException) { \
953     [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
954                                               exception:anException \
955                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
956                                                  atLine:__LINE__ \
957                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
958   } \
959 } while (0)
960 
961 
962 /*" Generates a failure when expression does throw an exception of the specitied
963   class. Any other exception is okay (i.e. does not generate a failure).
964   _{expression    The expression that is evaluated.}
965   _{specificException    The specified class of the exception.}
966   _{description A format string as in the printf() function. Can be nil or
967   an empty string but must be present.}
968   _{... A variable number of arguments to the format string. Can be absent.}
969 "*/
970 #define STAssertNoThrowSpecific(expr, specificException, description, ...) \
971 do { \
972   @try { \
973     (expr); \
974   } \
975   @catch (specificException *anException) { \
976     [self failWithException:[NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
977                                               exception:anException \
978                                                  inFile:[NSString stringWithUTF8String:__FILE__] \
979                                                  atLine:__LINE__ \
980                                         withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)]]; \
981   } \
982   @catch (id anythingElse) { \
983     ; \
984   } \
985 } while (0)
986 
987 
988 /*" Generates a failure when expression does throw an exception of a
989   specific class with a specific name.  Useful for those frameworks like
990   AppKit or Foundation that throw generic NSException w/specific names
991   (NSInvalidArgumentException, etc).
992   _{expression    The expression that is evaluated.}
993   _{specificException    The specified class of the exception.}
994   _{aName    The name of the specified exception.}
995   _{description A format string as in the printf() function. Can be nil or
996   an empty string but must be present.}
997   _{... A variable number of arguments to the format string. Can be absent.}
998 
999 "*/
1000 #define STAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) \
1001 do { \
1002   @try { \
1003     (expr); \
1004   } \
1005   @catch (specificException *anException) { \
1006     if ([aName isEqualToString:[anException name]]) { \
1007       NSString *_descrip = STComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description); \
1008       [self failWithException: \
1009         [NSException failureInRaise:[NSString stringWithUTF8String:#expr] \
1010                           exception:anException \
1011                              inFile:[NSString stringWithUTF8String:__FILE__] \
1012                              atLine:__LINE__ \
1013                     withDescription:@"%@", STComposeString(_descrip, ##__VA_ARGS__)]]; \
1014     } \
1015     continue; \
1016   } \
1017   @catch (id anythingElse) { \
1018     ; \
1019   } \
1020 } while (0)
1021 
1022 
1023 
1024 @interface NSException (GTMSenTestAdditions)
1025 + (NSException *)failureInFile:(NSString *)filename
1026                         atLine:(int)lineNumber
1027                withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(3, 4);
1028 + (NSException *)failureInCondition:(NSString *)condition
1029                              isTrue:(BOOL)isTrue
1030                              inFile:(NSString *)filename
1031                              atLine:(int)lineNumber
1032                     withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(5, 6);
1033 + (NSException *)failureInEqualityBetweenObject:(id)left
1034                                       andObject:(id)right
1035                                          inFile:(NSString *)filename
1036                                          atLine:(int)lineNumber
1037                                 withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(5, 6);
1038 + (NSException *)failureInEqualityBetweenValue:(NSValue *)left
1039                                       andValue:(NSValue *)right
1040                                   withAccuracy:(NSValue *)accuracy
1041                                         inFile:(NSString *)filename
1042                                         atLine:(int) ineNumber
1043                                withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(6, 7);
1044 + (NSException *)failureInRaise:(NSString *)expression
1045                          inFile:(NSString *)filename
1046                          atLine:(int)lineNumber
1047                 withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(4, 5);
1048 + (NSException *)failureInRaise:(NSString *)expression
1049                       exception:(NSException *)exception
1050                          inFile:(NSString *)filename
1051                          atLine:(int)lineNumber
1052                 withDescription:(NSString *)formatString, ... NS_FORMAT_FUNCTION(5, 6);
1053 @end
1054 
1055 // SENTE_END
1056 
1057 @protocol SenTestCase
1058 + (id)testCaseWithInvocation:(NSInvocation *)anInvocation;
1059 - (id)initWithInvocation:(NSInvocation *)anInvocation;
1060 - (void)setUp;
1061 - (void)invokeTest;
1062 - (void)tearDown;
1063 - (void)performTest;
1064 - (void)failWithException:(NSException*)exception;
1065 - (NSInvocation *)invocation;
1066 - (SEL)selector;
1067 + (NSArray *)testInvocations;
1068 @end
1069 
1070 @interface SenTestCase : NSObject<SenTestCase> {
1071  @private
1072   NSInvocation *invocation_;
1073 }
1074 @end
1075 
1076 GTM_EXTERN NSString *const SenTestFailureException;
1077 
1078 GTM_EXTERN NSString *const SenTestFilenameKey;
1079 GTM_EXTERN NSString *const SenTestLineNumberKey;
1080 
1081 #endif // GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST
1082 
1083 // All unittest cases in GTM should inherit from GTMTestCase. It makes sure
1084 // to set up our logging system correctly to verify logging calls.
1085 // See GTMUnitTestDevLog.h for details
1086 @interface GTMTestCase : SenTestCase
1087 
1088 // Returns YES if this is an abstract testCase class as opposed to a concrete
1089 // testCase class that you want tests run against. SenTestCase is not designed
1090 // out of the box to handle an abstract class hierarchy descending from it with
1091 // some concrete subclasses.  In some cases we want all the "concrete"
1092 // subclasses of an abstract subclass of SenTestCase to run a test, but we don't
1093 // want that test to be run against an instance of an abstract subclass itself.
1094 // By returning "YES" here, the tests defined by this class won't be run against
1095 // an instance of this class. As an example class hierarchy:
1096 //
1097 //                                            FooExtensionTestCase
1098 // GTMTestCase <- ExtensionAbstractTestCase <
1099 //                                            BarExtensionTestCase
1100 //
1101 // So FooExtensionTestCase and BarExtensionTestCase inherit from
1102 // ExtensionAbstractTestCase (and probably FooExtension and BarExtension inherit
1103 // from a class named Extension). We want the tests in ExtensionAbstractTestCase
1104 // to be run as part of FooExtensionTestCase and BarExtensionTestCase, but we
1105 // don't want them run against ExtensionAbstractTestCase. The default
1106 // implementation checks to see if the name of the class contains the word
1107 // "AbstractTest" (case sensitive).
1108 + (BOOL)isAbstractTestCase;
1109 
1110 @end
1111