Home | History | Annotate | Download | only in testing
      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