mirror of
https://github.com/gnustep/tools-make.git
synced 2025-04-23 22:33:28 +00:00
Important change to the START_SET and END_SET macros to stop their use
being confusing. They now both take a simple C-string argument which names the set, and the macros check that each end matches a start of the same name. Since tis means that a START_SET no longer takes an argument sayng whether or notthe set is to be skipped, we now have a SKIP macro to be used inside a set to skip to the end of it. This is actually more versatile as we can have multiple SKIP macros in the same set, each providing a different reason for the set being skipped. Also removed a few obsolete/unused functions and macros. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/tools/make/trunk@32355 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
3895ad8c89
commit
21c545b319
12 changed files with 291 additions and 255 deletions
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
|||
2011-01-24 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* TestFramework/example9.m:
|
||||
* TestFramework/ObjectTesting.h:
|
||||
* TestFramework/README:
|
||||
* TestFramework/Testing.h:
|
||||
* TestFramework/example2.m:
|
||||
* TestFramework/example3.m:
|
||||
* TestFramework/example4.m:
|
||||
* TestFramework/example5.m:
|
||||
* TestFramework/example6.m:
|
||||
* TestFramework/example7.m:
|
||||
* TestFramework/example8.m:
|
||||
Important change to the START_SET and END_SET macros to stop their use
|
||||
being confusing. They now both take a simple C-string argument which
|
||||
names the set, and the macros check that each end matches a start of
|
||||
the same name. Since tis means that a START_SET no longer takes an
|
||||
argument sayng whether or notthe set is to be skipped, we now have a
|
||||
SKIP macro to be used inside a set to skip to the end of it. This
|
||||
is actually more versatile as we can have multiple SKIP macros in the
|
||||
same set, each providing a different reason for the set being skipped.
|
||||
Also removed a few obsolete/unused functions and macros.
|
||||
|
||||
2011-01-23 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* TestFramework/gnustep-tests.in:
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
/* Quick test to check that we have the class we expect.
|
||||
*/
|
||||
#define TEST_FOR_CLASS(aClassName, aClass, TestDescription) \
|
||||
pass([aClass isKindOfClass: NSClassFromString(aClassName)], TestDescription)
|
||||
PASS([aClass isKindOfClass: NSClassFromString(aClassName)], TestDescription)
|
||||
|
||||
/* Quick test to check for a non-empty string in the case where we don't
|
||||
* actually know what value we should be expecting.
|
||||
|
@ -54,23 +54,14 @@
|
|||
&& [_testString length], description); \
|
||||
}
|
||||
|
||||
/* DEPRECATED
|
||||
* This is for backward compatibility, the original havng been replaced
|
||||
* by two clearer/simpler macros.
|
||||
* Please use PASS_EXCEPTION() for a test which is supposed to raise,
|
||||
* or PASS_RUNS() to test that code runs without raising an exception.
|
||||
*/
|
||||
#define TEST_EXCEPTION(code, exceptionName, shouldRaise, description) \
|
||||
if (shouldRaise) { PASS_EXCEPTION(code, exceptionName, description) } \
|
||||
else { PASS_RUNS(code, description) }
|
||||
|
||||
/* DEPRECATED
|
||||
/* DEPRECATED ... please use the START_SET/END_SET and PASS macros instead.
|
||||
START_TEST/END_TEST can be used if the code being tested could raise
|
||||
and the exception should be considered a test failure. The exception
|
||||
is not reraised to allow subsequent tests to execute. The START_TEST
|
||||
macro takes an argument which will skip the test as Skipped if it
|
||||
evaluates to 0, allowing runtime control of whether the code block
|
||||
should be executed. */
|
||||
should be executed.
|
||||
*/
|
||||
#define START_TEST(supported) if ((supported)) { NS_DURING
|
||||
#define END_TEST(result, desc, args...) \
|
||||
pass(result, desc, ## args); \
|
||||
|
@ -80,7 +71,12 @@
|
|||
[[localException reason] UTF8String], \
|
||||
[[[localException userInfo] description] UTF8String]); \
|
||||
pass (NO, desc, ## args); NS_ENDHANDLER } \
|
||||
else unsupported (desc, ## args)
|
||||
else { fprintf(stderr, "Failed test: " desc, ## args); \
|
||||
fprintf(stderr, "\n"); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Functions to test basic capabilities expected of most classes.
|
||||
*/
|
||||
|
@ -215,31 +211,33 @@ static void test_NSCoding(NSArray *objects)
|
|||
int i;
|
||||
for (i = 0; i < [objects count]; i++)
|
||||
{
|
||||
char buf[100];
|
||||
id obj = [objects objectAtIndex: i];
|
||||
const char *prefix;
|
||||
NSMutableData *data;
|
||||
NSArchiver *archiver;
|
||||
id decoded;
|
||||
|
||||
START_SET(YES);
|
||||
pass([[[obj class] description] length],
|
||||
"I can extract a class name for object");
|
||||
sprintf(buf, "test_NSCoding object %u", i);
|
||||
START_SET(buf)
|
||||
pass([[[obj class] description] length],
|
||||
"I can extract a class name for object");
|
||||
|
||||
prefix = [[NSString stringWithFormat: @"Object %i of class '%s'", i,
|
||||
[NSStringFromClass([obj class]) UTF8String]] UTF8String];
|
||||
pass([obj conformsToProtocol: @protocol(NSCoding)],
|
||||
"conforms to NSCoding protocol");
|
||||
data = (NSMutableData *)[NSMutableData data];
|
||||
archiver = [[NSArchiver alloc] initForWritingWithMutableData: data];
|
||||
pass(archiver != nil, "I am able to set up an archiver");
|
||||
data = nil;
|
||||
[archiver encodeRootObject: obj];
|
||||
data = [archiver archiverData];
|
||||
pass(data && [data length] > 0, "%s can be encoded", prefix);
|
||||
decoded = [NSUnarchiver unarchiveObjectWithData: data];
|
||||
pass(decoded != nil, "can be decoded");
|
||||
pass([decoded isEqual: obj], "decoded object equals the original");
|
||||
END_SET("test_NSCoding object %u", i);
|
||||
prefix = [[NSString stringWithFormat: @"Object %i of class '%s'", i,
|
||||
[NSStringFromClass([obj class]) UTF8String]] UTF8String];
|
||||
pass([obj conformsToProtocol: @protocol(NSCoding)],
|
||||
"conforms to NSCoding protocol");
|
||||
data = (NSMutableData *)[NSMutableData data];
|
||||
archiver = [[NSArchiver alloc] initForWritingWithMutableData: data];
|
||||
pass(archiver != nil, "I am able to set up an archiver");
|
||||
data = nil;
|
||||
[archiver encodeRootObject: obj];
|
||||
data = [archiver archiverData];
|
||||
pass(data && [data length] > 0, "%s can be encoded", prefix);
|
||||
decoded = [NSUnarchiver unarchiveObjectWithData: data];
|
||||
pass(decoded != nil, "can be decoded");
|
||||
pass([decoded isEqual: obj], "decoded object equals the original");
|
||||
END_SET(buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,25 +246,27 @@ static void test_keyed_NSCoding(NSArray *objects)
|
|||
int i;
|
||||
for (i = 0; i < [objects count]; i++)
|
||||
{
|
||||
char buf[100];
|
||||
id obj = [objects objectAtIndex: i];
|
||||
const char *prefix;
|
||||
NSData *data;
|
||||
id decoded;
|
||||
|
||||
START_SET(YES);
|
||||
pass([[[obj class] description] length],
|
||||
"I can extract a class name for object");
|
||||
sprintf(buf, "test_keyed_NSCoding object %u", i);
|
||||
START_SET(buf)
|
||||
pass([[[obj class] description] length],
|
||||
"I can extract a class name for object");
|
||||
|
||||
prefix = [[NSString stringWithFormat: @"Object %i of class '%s'", i,
|
||||
[NSStringFromClass([obj class]) UTF8String]] UTF8String];
|
||||
pass([obj conformsToProtocol: @protocol(NSCoding)],
|
||||
"conforms to NSCoding protocol");
|
||||
data = [NSKeyedArchiver archivedDataWithRootObject: obj];
|
||||
pass([data length] > 0, "%s can be encoded", prefix);
|
||||
decoded = [NSKeyedUnarchiver unarchiveObjectWithData: data];
|
||||
pass (decoded != nil, "can be decoded");
|
||||
PASS_EQUAL(decoded, obj, "decoded object equals the original");
|
||||
END_SET("test_keyed_NSCoding object %u", i);
|
||||
prefix = [[NSString stringWithFormat: @"Object %i of class '%s'", i,
|
||||
[NSStringFromClass([obj class]) UTF8String]] UTF8String];
|
||||
pass([obj conformsToProtocol: @protocol(NSCoding)],
|
||||
"conforms to NSCoding protocol");
|
||||
data = [NSKeyedArchiver archivedDataWithRootObject: obj];
|
||||
pass([data length] > 0, "%s can be encoded", prefix);
|
||||
decoded = [NSKeyedUnarchiver unarchiveObjectWithData: data];
|
||||
pass (decoded != nil, "can be decoded");
|
||||
PASS_EQUAL(decoded, obj, "decoded object equals the original")
|
||||
END_SET(buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,6 +286,7 @@ static void test_NSCopying(NSString *iClassName,
|
|||
|
||||
for (i = 0; i < [objects count]; i++)
|
||||
{
|
||||
char buf[100];
|
||||
BOOL immutable;
|
||||
NSString *theName;
|
||||
const char *prefix;
|
||||
|
@ -293,71 +294,73 @@ static void test_NSCopying(NSString *iClassName,
|
|||
Class theClass = Nil;
|
||||
id theObj = [objects objectAtIndex: i];
|
||||
|
||||
START_SET(YES);
|
||||
if (iClass != mClass && [theObj isKindOfClass: mClass])
|
||||
{
|
||||
immutable = NO;
|
||||
theName = iClassName;
|
||||
theClass = iClass;
|
||||
}
|
||||
else
|
||||
{
|
||||
immutable = YES;
|
||||
theName = mClassName;
|
||||
theClass = mClass;
|
||||
}
|
||||
|
||||
prefix = [[NSString stringWithFormat: @"Object %i of class '%s'",
|
||||
i, [theName UTF8String]] UTF8String];
|
||||
pass([theObj conformsToProtocol: @protocol(NSCopying)],
|
||||
"conforms to NSCopying");
|
||||
theCopy = [theObj copy];
|
||||
pass(theCopy != nil, "%s understands -copy", prefix);
|
||||
pass([theCopy isKindOfClass: iClass],
|
||||
"%s copy is of correct type", prefix);
|
||||
pass([theObj isEqual: theCopy], "%s original and copy are equal", prefix);
|
||||
if (immutable)
|
||||
{
|
||||
if (YES == mustRetain)
|
||||
{
|
||||
pass(theCopy == theObj,
|
||||
"%s is retained by copy with same zone", prefix);
|
||||
}
|
||||
else if (YES == mustCopy)
|
||||
{
|
||||
pass(theCopy != theObj,
|
||||
"%s is not retained by copy with same zone", prefix);
|
||||
}
|
||||
}
|
||||
if (theClass != iClass)
|
||||
{
|
||||
pass(![theCopy isKindOfClass: theClass],
|
||||
"%s result of copy is not immutable", prefix);
|
||||
}
|
||||
|
||||
theCopy = [theObj copyWithZone: testZone];
|
||||
pass(theCopy != nil, "%s understands -copyWithZone", prefix);
|
||||
pass([theCopy isKindOfClass: iClass],
|
||||
"%s zCopy has correct type", prefix);
|
||||
pass([theObj isEqual: theCopy],
|
||||
"%s copy and original are equal", prefix);
|
||||
if (immutable)
|
||||
{
|
||||
if (YES == mustRetain)
|
||||
{
|
||||
pass(theCopy == theObj,
|
||||
"%s is retained by copy with other zone", prefix);
|
||||
}
|
||||
else if (YES == mustCopy)
|
||||
{
|
||||
pass(theCopy != theObj,
|
||||
"%s is not retained by copy with other zone", prefix);
|
||||
}
|
||||
}
|
||||
if (theClass != iClass)
|
||||
pass(![theCopy isKindOfClass: theClass],
|
||||
"%s result of copyWithZone: is not immutable", prefix);
|
||||
END_SET("test_NSCopying object %u", i);
|
||||
sprintf(buf, "test_NSCopying object %u", i);
|
||||
START_SET(buf)
|
||||
if (iClass != mClass && [theObj isKindOfClass: mClass])
|
||||
{
|
||||
immutable = NO;
|
||||
theName = iClassName;
|
||||
theClass = iClass;
|
||||
}
|
||||
else
|
||||
{
|
||||
immutable = YES;
|
||||
theName = mClassName;
|
||||
theClass = mClass;
|
||||
}
|
||||
|
||||
prefix = [[NSString stringWithFormat: @"Object %i of class '%s'",
|
||||
i, [theName UTF8String]] UTF8String];
|
||||
pass([theObj conformsToProtocol: @protocol(NSCopying)],
|
||||
"conforms to NSCopying");
|
||||
theCopy = [theObj copy];
|
||||
pass(theCopy != nil, "%s understands -copy", prefix);
|
||||
pass([theCopy isKindOfClass: iClass],
|
||||
"%s copy is of correct type", prefix);
|
||||
pass([theObj isEqual: theCopy],
|
||||
"%s original and copy are equal", prefix);
|
||||
if (immutable)
|
||||
{
|
||||
if (YES == mustRetain)
|
||||
{
|
||||
pass(theCopy == theObj,
|
||||
"%s is retained by copy with same zone", prefix);
|
||||
}
|
||||
else if (YES == mustCopy)
|
||||
{
|
||||
pass(theCopy != theObj,
|
||||
"%s is not retained by copy with same zone", prefix);
|
||||
}
|
||||
}
|
||||
if (theClass != iClass)
|
||||
{
|
||||
pass(![theCopy isKindOfClass: theClass],
|
||||
"%s result of copy is not immutable", prefix);
|
||||
}
|
||||
|
||||
theCopy = [theObj copyWithZone: testZone];
|
||||
pass(theCopy != nil, "%s understands -copyWithZone", prefix);
|
||||
pass([theCopy isKindOfClass: iClass],
|
||||
"%s zCopy has correct type", prefix);
|
||||
pass([theObj isEqual: theCopy],
|
||||
"%s copy and original are equal", prefix);
|
||||
if (immutable)
|
||||
{
|
||||
if (YES == mustRetain)
|
||||
{
|
||||
pass(theCopy == theObj,
|
||||
"%s is retained by copy with other zone", prefix);
|
||||
}
|
||||
else if (YES == mustCopy)
|
||||
{
|
||||
pass(theCopy != theObj,
|
||||
"%s is not retained by copy with other zone", prefix);
|
||||
}
|
||||
}
|
||||
if (theClass != iClass)
|
||||
pass(![theCopy isKindOfClass: theClass],
|
||||
"%s result of copyWithZone: is not immutable", prefix);
|
||||
END_SET(buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,6 +381,7 @@ static void test_NSMutableCopying(NSString *iClassName,
|
|||
|
||||
for (i = 0; i < [objects count]; i++)
|
||||
{
|
||||
char buf[100];
|
||||
id theObj = [objects objectAtIndex: i];
|
||||
NSString *theName = nil;
|
||||
const char *prefix;
|
||||
|
@ -385,42 +389,43 @@ static void test_NSMutableCopying(NSString *iClassName,
|
|||
id theCopy = nil;
|
||||
Class theClass = Nil;
|
||||
|
||||
START_SET(YES);
|
||||
if (iClass == mClass && [theObj isKindOfClass: mClass])
|
||||
immutable = NO;
|
||||
else
|
||||
immutable = YES;
|
||||
|
||||
if (immutable)
|
||||
{
|
||||
theName = iClassName;
|
||||
theClass = iClass;
|
||||
}
|
||||
else
|
||||
{
|
||||
theName = mClassName;
|
||||
theClass = mClass;
|
||||
}
|
||||
|
||||
prefix = [[NSString stringWithFormat:
|
||||
@"Object %i of class '%s'", i, [theName UTF8String]] UTF8String];
|
||||
pass([theObj conformsToProtocol: @protocol(NSMutableCopying)],
|
||||
"%s conforms to NSMutableCopying protocol", prefix);
|
||||
theCopy = [theObj mutableCopy];
|
||||
pass(theCopy != nil, "%s understands -mutableCopy", prefix);
|
||||
pass([theCopy isKindOfClass: mClass],
|
||||
"%s mutable copy is of correct type", prefix);
|
||||
pass([theCopy isEqual: theObj], "%s copy equals original", prefix);
|
||||
pass(theCopy != theObj,
|
||||
"%s not retained by mutable copy in the same zone",
|
||||
[mClassName UTF8String]);
|
||||
|
||||
theCopy = [theObj mutableCopyWithZone: testZone];
|
||||
pass(theCopy != nil,
|
||||
"%s understands mutableCopyWithZone", [mClassName UTF8String]);
|
||||
pass(theCopy != theObj, "%s not retained by mutable copy in other zone",
|
||||
[mClassName UTF8String]);
|
||||
END_SET("test_NSMutableCopying object %u", i);
|
||||
sprintf(buf, "test_NSMutableCopying object %u", i);
|
||||
START_SET(buf);
|
||||
if (iClass == mClass && [theObj isKindOfClass: mClass])
|
||||
immutable = NO;
|
||||
else
|
||||
immutable = YES;
|
||||
|
||||
if (immutable)
|
||||
{
|
||||
theName = iClassName;
|
||||
theClass = iClass;
|
||||
}
|
||||
else
|
||||
{
|
||||
theName = mClassName;
|
||||
theClass = mClass;
|
||||
}
|
||||
|
||||
prefix = [[NSString stringWithFormat:
|
||||
@"Object %i of class '%s'", i, [theName UTF8String]] UTF8String];
|
||||
pass([theObj conformsToProtocol: @protocol(NSMutableCopying)],
|
||||
"%s conforms to NSMutableCopying protocol", prefix);
|
||||
theCopy = [theObj mutableCopy];
|
||||
pass(theCopy != nil, "%s understands -mutableCopy", prefix);
|
||||
pass([theCopy isKindOfClass: mClass],
|
||||
"%s mutable copy is of correct type", prefix);
|
||||
pass([theCopy isEqual: theObj], "%s copy equals original", prefix);
|
||||
pass(theCopy != theObj,
|
||||
"%s not retained by mutable copy in the same zone",
|
||||
[mClassName UTF8String]);
|
||||
|
||||
theCopy = [theObj mutableCopyWithZone: testZone];
|
||||
pass(theCopy != nil,
|
||||
"%s understands mutableCopyWithZone", [mClassName UTF8String]);
|
||||
pass(theCopy != theObj, "%s not retained by mutable copy in other zone",
|
||||
[mClassName UTF8String]);
|
||||
END_SET(buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -181,8 +181,8 @@ paired calls to the START_SET and END_SET macros. Any setting of testHopeful
|
|||
within a set is automatically restored at the end of a set, so it makes sense
|
||||
to group hopes together in a set.
|
||||
|
||||
You can skip an entire set by supplying NO as the argument to the START_SET
|
||||
macro, in which case the entire set will be reported as being Skipped.
|
||||
You can skip an entire set by calling the SKIP() macro just after the start,
|
||||
in which case the entire set will be reported as being Skipped.
|
||||
It is appropriate to skip sets of tests if you have checked and found that
|
||||
some feature you are testing is not available in the version of the package
|
||||
under test.
|
||||
|
|
|
@ -120,42 +120,6 @@ static void testStart()
|
|||
return;
|
||||
}
|
||||
|
||||
/* The unresolved() function is called with a single string argument to
|
||||
* notify the testsuite that a test failed to complete for some reason.
|
||||
* eg. You might call this if an earlier testcase failed and it makes no
|
||||
* sense to run subsequent tests.
|
||||
* This is called if a set is terminated before all the tests in it have
|
||||
* been run.
|
||||
*/
|
||||
static void unresolved(const char *format, ...) __attribute__((unused)) __attribute__ ((format(printf, 1, 2), unused));
|
||||
static void unresolved(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
fprintf(stderr, "Failed set: ");
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(args);
|
||||
#if defined(FAILFAST)
|
||||
exit(1); // Abandon testing now.
|
||||
#endif
|
||||
}
|
||||
|
||||
/* The unsupported() function is called with a single string argument to
|
||||
* notify the testsuite that a test could not be run because the capability
|
||||
* it is testing does not exist on the current platform.
|
||||
*/
|
||||
static void unsupported(const char *format, ...) __attribute__((unused)) __attribute__ ((format(printf, 1, 2), unused));
|
||||
static void unsupported(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
fprintf(stderr, "Skipped set: ");
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/* Tests a code expression which evaluates to an integer value.
|
||||
* The expression may not contain commas unless it is bracketed.
|
||||
* The format must be a literal string printf style format.
|
||||
|
@ -295,62 +259,93 @@ static void unsupported(const char *format, ...)
|
|||
* the scope of the current test but could raise exceptions that should
|
||||
* be caught to allow further tests to run.
|
||||
*
|
||||
* You must pass a 'supported' flag to say whether the code should be run
|
||||
* or not, if not then the set is reported as unsupported.
|
||||
* You must pass a short description to identify the set at both its
|
||||
* start and its end. This allows the seat to be easily identified in the
|
||||
* log, and also allows for checking to be sure that each start if a set
|
||||
* is matched by a corresponding end.
|
||||
*
|
||||
* The state of the 'testHopeful' flag is saved at the start of the set and
|
||||
* restored at the end of the set, so you can start your code by setting
|
||||
* 'testHopeful=YES;' to mark any tests within the set as being part of a group
|
||||
* of tests we don't expect to pass.
|
||||
* 'testHopeful=YES;' to mark any tests within the set as being part of a
|
||||
* group of tests we don't expect to pass.
|
||||
*
|
||||
* Importantly, you may skip some or all of the tests in a set if those
|
||||
* tests are not supported in the package being tested (eg. testing of
|
||||
* functionality which depends on some external library which was not
|
||||
* available when the package being tested was buit).
|
||||
*
|
||||
* Any uncaught exception occurring inside a set will abort the entire set
|
||||
* so that remaining tests in the set will not be executed, but you may
|
||||
* also abandon remaining tests upon any test failure.
|
||||
*
|
||||
* The tests within the set are enclosed in an autorelease pool, and any
|
||||
* temporary objects are cleaned up at the end of the set.
|
||||
*/
|
||||
|
||||
/* The START_SET() macro starts a set of grouped tests or, if the argument
|
||||
* is false, skips the set and reports the set as unsupported.
|
||||
/* The START_SET() macro starts a set of grouped tests. It must be matched
|
||||
* by a corresponding END_SET() with the same string as an argument.
|
||||
* The argument is a short description to be printed in the log on entry.
|
||||
*/
|
||||
#define START_SET(supported) \
|
||||
if ((supported)) \
|
||||
{ \
|
||||
BOOL save_hopeful = testHopeful; \
|
||||
NS_DURING \
|
||||
NSAutoreleasePool *_setPool = [NSAutoreleasePool new]; \
|
||||
{
|
||||
#define START_SET(setName) \
|
||||
{ \
|
||||
BOOL _save_hopeful = testHopeful; \
|
||||
int _save_line = __LINE__; \
|
||||
char *_save_set = malloc(strlen(setName) + 1); \
|
||||
strcpy(_save_set, setName); \
|
||||
fprintf(stderr, "Start set: %s:%d ... %s\n", \
|
||||
__FILE__, __LINE__, _save_set); \
|
||||
fprintf(stderr, "\n"); \
|
||||
NS_DURING \
|
||||
NSAutoreleasePool *_setPool = [NSAutoreleasePool new]; \
|
||||
{
|
||||
|
||||
|
||||
/* The END_SET() macro terminates a set of grouped tests. It's argument is
|
||||
* a literal printf style format string and variable arguments to print a
|
||||
* message giving the reason for skipping the set. This should be a short
|
||||
* message (for immediate display), preferably with a more detailed
|
||||
* explanation on subsequent lines.
|
||||
/* The END_SET() macro terminates a set of grouped tests. It must be matched
|
||||
* by a corresponding START_SET() with the same string as an argument.
|
||||
* The argument is a short description to be printed in the log on entry.
|
||||
*/
|
||||
#define END_SET(format, ...) \
|
||||
#define END_SET(setName) \
|
||||
} \
|
||||
[_setPool release]; \
|
||||
NS_HANDLER \
|
||||
if (YES == [[localException name] isEqualToString: @"SkipSet"]) \
|
||||
{ \
|
||||
fprintf(stderr, "Skipped set: %s\n", \
|
||||
[[localException reason] UTF8String]); \
|
||||
} \
|
||||
[_setPool release]; \
|
||||
NS_HANDLER \
|
||||
if (NO == [[localException name] isEqualToString: @"CheckSet"]) \
|
||||
{ \
|
||||
fprintf(stderr, "EXCEPTION: %s %s %s\n", \
|
||||
[[localException name] UTF8String], \
|
||||
[[localException reason] UTF8String], \
|
||||
[[[localException userInfo] description] UTF8String]); \
|
||||
} \
|
||||
unresolved("%s:%d ... problem occurred inside set.", \
|
||||
__FILE__, __LINE__); \
|
||||
NS_ENDHANDLER \
|
||||
testHopeful = save_hopeful; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
unsupported("%s:%d ... " format, __FILE__, __LINE__, ## __VA_ARGS__); \
|
||||
}
|
||||
else \
|
||||
{ \
|
||||
if (YES == [[localException name] isEqualToString: @"FailSet"]) \
|
||||
{ \
|
||||
fprintf(stderr, \
|
||||
"Failed set: %s:%d ... need not met in %s.\n", \
|
||||
__FILE__, _save_line, _save_set); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fprintf(stderr, "EXCEPTION: %s %s %s\n", \
|
||||
[[localException name] UTF8String], \
|
||||
[[localException reason] UTF8String], \
|
||||
[[[localException userInfo] description] UTF8String]); \
|
||||
fprintf(stderr, "Failed set: %s:%d ... problem in %s.\n", \
|
||||
__FILE__, _save_line, _save_set); \
|
||||
} \
|
||||
} \
|
||||
NS_ENDHANDLER \
|
||||
fprintf(stderr, "End set: %s:%d ... %s\n", \
|
||||
__FILE__, __LINE__, _save_set); \
|
||||
if (strcmp(_save_set, setName) != 0) \
|
||||
fprintf(stderr, "Failed set: %s:%d ... END(%s) with START(%s).\n", \
|
||||
__FILE__, __LINE__, setName, _save_set); \
|
||||
free(_save_set); \
|
||||
testHopeful = _save_hopeful; \
|
||||
}
|
||||
|
||||
/* The NEED macro takes a test macro as an argument and breaks out of a set
|
||||
* and reports it as failed if the test does not pass.
|
||||
*/
|
||||
#define NEED(testToTry) \
|
||||
testToTry \
|
||||
{testToTry;} \
|
||||
if (NO == testPassed) \
|
||||
{ \
|
||||
if (nil != testRaised) \
|
||||
|
@ -359,10 +354,20 @@ static void unsupported(const char *format, ...)
|
|||
} \
|
||||
else \
|
||||
{ \
|
||||
[NSException raise: @"CheckSet" format: @"Test did not pass"]; \
|
||||
[NSException raise: @"FailSet" format: @"Test did not pass"]; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* The SKIP() macro skips the remainder of a set of grouped tests.
|
||||
* Its argument is a literal printf style format string and variable
|
||||
* arguments to print a message giving the reason for skipping the set.
|
||||
* This should be a short one line message (for immediate display),
|
||||
* preferably with a more detailed explanation on subsequent lines.
|
||||
*/
|
||||
#define SKIP(fmt, ...) \
|
||||
[NSException raise: @"SkipSet" format: @"%s %d ... " fmt, \
|
||||
__FILE__, __LINE__, ## __VA_ARGS__];
|
||||
|
||||
|
||||
/* some good macros to compare floating point numbers */
|
||||
#import <math.h>
|
||||
|
|
|
@ -11,7 +11,7 @@ main()
|
|||
/* We start a set here ...
|
||||
* Having a set means we do not need to bother creating an autorelease pool.
|
||||
*/
|
||||
START_SET(YES)
|
||||
START_SET("example set")
|
||||
|
||||
pass(1 == 1, "integer equality works");
|
||||
pass([[NSObject new] autorelease] != nil, "+new creates an object");
|
||||
|
|
|
@ -16,7 +16,7 @@ main()
|
|||
/* We start a set here ...
|
||||
* Having a set means we do not need to bother creating an autorelease pool.
|
||||
*/
|
||||
START_SET(YES)
|
||||
START_SET("example set")
|
||||
|
||||
/* We use a macro here so that any exception in the expression we use
|
||||
* will not break out of the set, and the two remaining tests will be
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
int
|
||||
main()
|
||||
{
|
||||
START_SET(YES)
|
||||
START_SET("example set")
|
||||
|
||||
/* We test for the code fragment raising an exception. We don't care
|
||||
* about the particular exception, so we pass nil as the expected exception
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
int
|
||||
main()
|
||||
{
|
||||
START_SET(YES)
|
||||
START_SET("example set")
|
||||
|
||||
/* First set a flag to say that we are not expecting tests to
|
||||
* actually pass.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
int
|
||||
main()
|
||||
{
|
||||
START_SET(YES)
|
||||
START_SET("example set")
|
||||
|
||||
/* First set a flag to say that we are not expecting tests to
|
||||
* actually pass.
|
||||
|
|
|
@ -10,7 +10,7 @@ main()
|
|||
{
|
||||
/* Start a set.
|
||||
*/
|
||||
START_SET(YES)
|
||||
START_SET("outer set")
|
||||
|
||||
/* Our first test in this set will pass.
|
||||
*/
|
||||
|
@ -18,7 +18,7 @@ main()
|
|||
|
||||
/* Now we start a set nested inside the first one.
|
||||
*/
|
||||
START_SET(YES)
|
||||
START_SET("inner set")
|
||||
|
||||
/* And we say we need a test to pass, but it's actually a faulty one
|
||||
* which will fail, causing the set to be terminated.
|
||||
|
|
|
@ -11,7 +11,7 @@ main()
|
|||
{
|
||||
/* Start a set.
|
||||
*/
|
||||
START_SET(YES)
|
||||
START_SET("example set")
|
||||
|
||||
/* Here we demonstrate that the 'expression' evaluated by the PASS
|
||||
* macro can actually be an arbitrarily complex piece of code as
|
||||
|
@ -27,7 +27,7 @@ main()
|
|||
NSEqualRanges(r, NSMakeRange(1, 10));
|
||||
}), "a long code-fragment/expression works")
|
||||
|
||||
END_SET("test set")
|
||||
END_SET("example set")
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#import "Testing.h"
|
||||
#import <NSFoundation/NSGeometry.h>
|
||||
|
||||
/* A ninth test ... unsupported tests
|
||||
/* A ninth test ... skipping unsupported tests
|
||||
*
|
||||
* If you run the test with 'gnustep-tests example9.m' it should
|
||||
* report one set skipped.
|
||||
|
@ -11,31 +11,34 @@ main()
|
|||
{
|
||||
#define HAVE_XXX NO
|
||||
|
||||
/* Start a set, but only if we have the XXX library.
|
||||
/* Start a set.
|
||||
*/
|
||||
START_SET(HAVE_XXX)
|
||||
START_SET("example set")
|
||||
|
||||
/* Here we demonstrate that the 'expression' evaluated by the PASS
|
||||
* macro can actually be an arbitrarily complex piece of code as
|
||||
* long as the last statement returns an integral value which can
|
||||
* be used to represent a pass (non zero) or fail (if zero).
|
||||
* Where such a code fragment contains commas, it must be written
|
||||
* inside brackets to let the macro preprocessor know that the whole
|
||||
* code fragement is the first parameter to the macro.
|
||||
*/
|
||||
PASS(({
|
||||
NSRange r = NSMakeRange(1, 10);
|
||||
|
||||
NSEqualRanges(r, NSMakeRange(1, 10));
|
||||
}), "a long code-fragment/expression works")
|
||||
/* Here we conditionally skip the set with a message to be displayed.
|
||||
* The first line will be displayed immediately when the set
|
||||
* is skipped, and lets the user know that some functionality is missing.
|
||||
* The remainder of the message is written to the log file so the user
|
||||
* can find out what to do about the problem.
|
||||
*/
|
||||
if (!HAVE_XXX)
|
||||
SKIP("Feature 'foo' is unsupported.\nThis is because the package was built without the 'XXX' library.\nIf you need 'foo' then please obtain 'XXX' and build and install the package again before re-running this testsuite.")
|
||||
|
||||
/* Here we end the set with a message to be displayed if the set is
|
||||
* skipped. The first line will be displayed immediately when the set
|
||||
* is skipped, and lets the user know that some functionality is missing.
|
||||
* The remainder of the message is written to the log file so the user
|
||||
* can find out what to do about the problem.
|
||||
*/
|
||||
END_SET("Feature 'foo' is unsupported.\nThis is because the 'XXX' package was built without the 'YYY' library.\nIf you need 'foo' then please obtain 'YYY' and build and install 'XXX' again before re-running this testsuite.")
|
||||
/* Here we demonstrate that the 'expression' evaluated by the PASS
|
||||
* macro can actually be an arbitrarily complex piece of code as
|
||||
* long as the last statement returns an integral value which can
|
||||
* be used to represent a pass (non zero) or fail (if zero).
|
||||
* Where such a code fragment contains commas, it must be written
|
||||
* inside brackets to let the macro preprocessor know that the whole
|
||||
* code fragement is the first parameter to the macro.
|
||||
*/
|
||||
PASS(({
|
||||
NSRange r = NSMakeRange(1, 10);
|
||||
|
||||
NSEqualRanges(r, NSMakeRange(1, 10));
|
||||
}), "a long code-fragment/expression works")
|
||||
|
||||
END_SET("example set")
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue