mirror of https://github.com/catchorg/Catch2.git
ARC support for Object-C projects
This commit is contained in:
parent
8d18d1648a
commit
53c990a7e1
|
@ -639,6 +639,25 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
template<typename MatcherT, typename ArgT>
|
||||||
|
ResultBuilder& acceptMatcher
|
||||||
|
(
|
||||||
|
const MatcherT& matcher,
|
||||||
|
ArgT* arg,
|
||||||
|
const std::string& matcherCallAsString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::string matcherAsString = Catch::toString( matcher );
|
||||||
|
if( matcherAsString == "{?}" )
|
||||||
|
matcherAsString = matcherCallAsString;
|
||||||
|
m_result.setLhs( Catch::toString( arg ) );
|
||||||
|
m_result.setRhs( matcherAsString );
|
||||||
|
m_result.setOp( "matches" );
|
||||||
|
m_result.setResultType( matcher( arg ) ? ResultWas::Ok : ResultWas::ExpressionFailed );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
ResultBuilder& setResultType
|
ResultBuilder& setResultType
|
||||||
(
|
(
|
||||||
|
|
|
@ -17,13 +17,17 @@ int main (int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
|
|
||||||
|
#if !CATCH_ARC_ENABLED
|
||||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
#endif
|
||||||
|
|
||||||
Catch::registerTestMethods();
|
Catch::registerTestMethods();
|
||||||
|
|
||||||
int result = Catch::Main( argc, (char* const*)argv );
|
int result = Catch::Main( argc, (char* const*)argv );
|
||||||
|
|
||||||
|
#if !CATCH_ARC_ENABLED
|
||||||
[pool drain];
|
[pool drain];
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,39 @@
|
||||||
// header for non obj-usage
|
// header for non obj-usage
|
||||||
#include "internal/catch_test_case_info.hpp"
|
#include "internal/catch_test_case_info.hpp"
|
||||||
|
|
||||||
|
#ifdef __has_feature
|
||||||
|
#define CATCH_ARC_ENABLED __has_feature(objc_arc)
|
||||||
|
#else
|
||||||
|
#define CATCH_ARC_ENABLED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void arcSafeRelease( NSObject* obj );
|
||||||
|
id performOptionalSelector( id obj, SEL sel );
|
||||||
|
|
||||||
|
#if !CATCH_ARC_ENABLED
|
||||||
|
inline void arcSafeRelease( NSObject* obj )
|
||||||
|
{
|
||||||
|
[obj release];
|
||||||
|
}
|
||||||
|
inline id performOptionalSelector( id obj, SEL sel )
|
||||||
|
{
|
||||||
|
if( [obj respondsToSelector: sel] )
|
||||||
|
return [obj performSelector: sel];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline void arcSafeRelease( NSObject* ){}
|
||||||
|
inline id performOptionalSelector( id obj, SEL sel )
|
||||||
|
{
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
||||||
|
if( [obj respondsToSelector: sel] )
|
||||||
|
return [obj performSelector: sel];
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// This protocol is really only here for (self) documenting purposes, since
|
// This protocol is really only here for (self) documenting purposes, since
|
||||||
// all its methods are optional.
|
// all its methods are optional.
|
||||||
|
@ -56,19 +89,13 @@ namespace Catch
|
||||||
()
|
()
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
id obj = class_createInstance( m_cls, 0 );
|
id obj = [[m_cls alloc] init];
|
||||||
obj = [obj init];
|
|
||||||
|
|
||||||
if( [obj respondsToSelector: @selector(setUp) ] )
|
performOptionalSelector( obj, @selector(setUp) );
|
||||||
[obj performSelector: @selector(setUp)];
|
performOptionalSelector( obj, m_sel );
|
||||||
|
performOptionalSelector( obj, @selector(tearDown) );
|
||||||
if( [obj respondsToSelector: m_sel] )
|
|
||||||
[obj performSelector: m_sel];
|
|
||||||
|
|
||||||
if( [obj respondsToSelector: @selector(tearDown) ] )
|
|
||||||
[obj performSelector: @selector(tearDown)];
|
|
||||||
|
|
||||||
[obj release];
|
arcSafeRelease( obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
@ -120,7 +147,7 @@ namespace Catch
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
inline const char* getAnnotation
|
inline std::string getAnnotation
|
||||||
(
|
(
|
||||||
Class cls,
|
Class cls,
|
||||||
const std::string& annotationName,
|
const std::string& annotationName,
|
||||||
|
@ -129,9 +156,10 @@ namespace Catch
|
||||||
{
|
{
|
||||||
NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
|
NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
|
||||||
SEL sel = NSSelectorFromString( selStr );
|
SEL sel = NSSelectorFromString( selStr );
|
||||||
[selStr release];
|
arcSafeRelease( selStr );
|
||||||
if( [cls respondsToSelector: sel] )
|
id value = performOptionalSelector( cls, sel );
|
||||||
return (const char*)[cls performSelector: sel];
|
if( value )
|
||||||
|
return [(NSString*)value UTF8String];
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,8 +171,8 @@ namespace Catch
|
||||||
size_t noTestMethods = 0;
|
size_t noTestMethods = 0;
|
||||||
int noClasses = objc_getClassList( NULL, 0 );
|
int noClasses = objc_getClassList( NULL, 0 );
|
||||||
|
|
||||||
std::vector<Class> classes( noClasses );
|
Class* classes = (__unsafe_unretained Class *)malloc( sizeof(Class) * noClasses);
|
||||||
objc_getClassList( &classes[0], noClasses );
|
objc_getClassList( classes, noClasses );
|
||||||
|
|
||||||
for( int c = 0; c < noClasses; c++ )
|
for( int c = 0; c < noClasses; c++ )
|
||||||
{
|
{
|
||||||
|
@ -159,10 +187,10 @@ namespace Catch
|
||||||
if( Detail::startsWith( methodName, "Catch_TestCase_" ) )
|
if( Detail::startsWith( methodName, "Catch_TestCase_" ) )
|
||||||
{
|
{
|
||||||
std::string testCaseName = methodName.substr( 15 );
|
std::string testCaseName = methodName.substr( 15 );
|
||||||
const char* name = Detail::getAnnotation( cls, "Name", testCaseName );
|
std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
|
||||||
const char* desc = Detail::getAnnotation( cls, "Description", testCaseName );
|
std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
|
||||||
|
|
||||||
Hub::getTestCaseRegistry().registerTest( TestCaseInfo( new OcMethod( cls, selector ), name, desc, "", 0 ) );
|
Hub::getTestCaseRegistry().registerTest( TestCaseInfo( new OcMethod( cls, selector ), name.c_str(), desc.c_str(), "", 0 ) );
|
||||||
noTestMethods++;
|
noTestMethods++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -173,8 +201,7 @@ namespace Catch
|
||||||
return noTestMethods;
|
return noTestMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
inline std::string toString( NSString* const& nsstring )
|
||||||
inline std::string toString<NSString*>( NSString* const& nsstring )
|
|
||||||
{
|
{
|
||||||
return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
|
return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
|
||||||
}
|
}
|
||||||
|
@ -190,7 +217,7 @@ namespace Catch
|
||||||
StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
|
StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
|
||||||
StringHolder()
|
StringHolder()
|
||||||
{
|
{
|
||||||
[m_substr release];
|
arcSafeRelease( m_substr );
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString* m_substr;
|
NSString* m_substr;
|
||||||
|
@ -282,13 +309,13 @@ namespace Catch
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define OC_TEST_CASE( name, desc )\
|
#define OC_TEST_CASE( name, desc )\
|
||||||
+(const char*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
|
+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
|
||||||
{\
|
{\
|
||||||
return name; \
|
return @ name; \
|
||||||
}\
|
}\
|
||||||
+(const char*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
|
+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
|
||||||
{ \
|
{ \
|
||||||
return desc; \
|
return @ desc; \
|
||||||
} \
|
} \
|
||||||
-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
|
-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ inline const char* testStringForMatching()
|
||||||
using namespace Catch::Matchers;
|
using namespace Catch::Matchers;
|
||||||
|
|
||||||
TEST_CASE("./succeeding/matchers", "")
|
TEST_CASE("./succeeding/matchers", "")
|
||||||
{
|
{
|
||||||
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
|
REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
|
||||||
CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
|
CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
4A3D7DD01503869D005F9203 /* catch_matchers.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_matchers.hpp; sourceTree = "<group>"; };
|
||||||
4A6D0C20149B3D3B00DB3EAA /* CatchSelfTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = CatchSelfTest; sourceTree = BUILT_PRODUCTS_DIR; };
|
4A6D0C20149B3D3B00DB3EAA /* CatchSelfTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = CatchSelfTest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
4A6D0C26149B3D3B00DB3EAA /* CatchSelfTest.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = CatchSelfTest.1; sourceTree = "<group>"; };
|
4A6D0C26149B3D3B00DB3EAA /* CatchSelfTest.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = CatchSelfTest.1; sourceTree = "<group>"; };
|
||||||
4A6D0C2D149B3D9E00DB3EAA /* ApproxTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ApproxTests.cpp; path = ../../../SelfTest/ApproxTests.cpp; sourceTree = "<group>"; };
|
4A6D0C2D149B3D9E00DB3EAA /* ApproxTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ApproxTests.cpp; path = ../../../SelfTest/ApproxTests.cpp; sourceTree = "<group>"; };
|
||||||
|
@ -193,6 +194,7 @@
|
||||||
4A7ADB4314F631E10094FE10 /* catch_totals.hpp */,
|
4A7ADB4314F631E10094FE10 /* catch_totals.hpp */,
|
||||||
4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */,
|
4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */,
|
||||||
4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */,
|
4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */,
|
||||||
|
4A3D7DD01503869D005F9203 /* catch_matchers.hpp */,
|
||||||
);
|
);
|
||||||
name = internal;
|
name = internal;
|
||||||
path = ../../../../include/internal;
|
path = ../../../../include/internal;
|
||||||
|
|
|
@ -193,6 +193,7 @@
|
||||||
4A63D2B014E3C1A900F615CB /* Debug */ = {
|
4A63D2B014E3C1A900F615CB /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
|
@ -200,6 +201,7 @@
|
||||||
4A63D2B114E3C1A900F615CB /* Release */ = {
|
4A63D2B114E3C1A900F615CB /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
@ -223,6 +225,7 @@
|
||||||
4A63D2B114E3C1A900F615CB /* Release */,
|
4A63D2B114E3C1A900F615CB /* Release */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
-(void) tearDown
|
-(void) tearDown
|
||||||
{
|
{
|
||||||
[obj release];
|
arcSafeRelease( obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
OC_TEST_CASE( "OCTest/test1", "This is a test case" )
|
OC_TEST_CASE( "OCTest/test1", "This is a test case" )
|
||||||
|
@ -41,6 +41,12 @@ OC_TEST_CASE( "OCTest/test2", "This is another test case" )
|
||||||
|
|
||||||
REQUIRE( obj.int_val == 2 );
|
REQUIRE( obj.int_val == 2 );
|
||||||
}
|
}
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
template<typename T>
|
||||||
|
void useObject( const T& object ){}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void useObject( const T* object ){}
|
||||||
|
|
||||||
using namespace Catch::Matchers;
|
using namespace Catch::Matchers;
|
||||||
OC_TEST_CASE( "OCTest/matchers", "Matches work with OC types (NSString so far)" )
|
OC_TEST_CASE( "OCTest/matchers", "Matches work with OC types (NSString so far)" )
|
||||||
|
|
|
@ -24,5 +24,5 @@ TEST_CASE( "OCTest/TestObj", "tests TestObj" )
|
||||||
|
|
||||||
REQUIRE( obj.int_val == 1 );
|
REQUIRE( obj.int_val == 1 );
|
||||||
|
|
||||||
[obj release];
|
arcSafeRelease( obj );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1913,6 +1913,25 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
template<typename MatcherT, typename ArgT>
|
||||||
|
ResultBuilder& acceptMatcher
|
||||||
|
(
|
||||||
|
const MatcherT& matcher,
|
||||||
|
ArgT* arg,
|
||||||
|
const std::string& matcherCallAsString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::string matcherAsString = Catch::toString( matcher );
|
||||||
|
if( matcherAsString == "{?}" )
|
||||||
|
matcherAsString = matcherCallAsString;
|
||||||
|
m_result.setLhs( Catch::toString( arg ) );
|
||||||
|
m_result.setRhs( matcherAsString );
|
||||||
|
m_result.setOp( "matches" );
|
||||||
|
m_result.setResultType( matcher( arg ) ? ResultWas::Ok : ResultWas::ExpressionFailed );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
ResultBuilder& setResultType
|
ResultBuilder& setResultType
|
||||||
(
|
(
|
||||||
|
@ -3034,6 +3053,39 @@ using namespace Matchers;
|
||||||
// in catch.hpp first to make sure they are included by the single
|
// in catch.hpp first to make sure they are included by the single
|
||||||
// header for non obj-usage
|
// header for non obj-usage
|
||||||
|
|
||||||
|
#ifdef __has_feature
|
||||||
|
#define CATCH_ARC_ENABLED __has_feature(objc_arc)
|
||||||
|
#else
|
||||||
|
#define CATCH_ARC_ENABLED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void arcSafeRelease( NSObject* obj );
|
||||||
|
id performOptionalSelector( id obj, SEL sel );
|
||||||
|
|
||||||
|
#if !CATCH_ARC_ENABLED
|
||||||
|
inline void arcSafeRelease( NSObject* obj )
|
||||||
|
{
|
||||||
|
[obj release];
|
||||||
|
}
|
||||||
|
inline id performOptionalSelector( id obj, SEL sel )
|
||||||
|
{
|
||||||
|
if( [obj respondsToSelector: sel] )
|
||||||
|
return [obj performSelector: sel];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline void arcSafeRelease( NSObject* ){}
|
||||||
|
inline id performOptionalSelector( id obj, SEL sel )
|
||||||
|
{
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
||||||
|
if( [obj respondsToSelector: sel] )
|
||||||
|
return [obj performSelector: sel];
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// This protocol is really only here for (self) documenting purposes, since
|
// This protocol is really only here for (self) documenting purposes, since
|
||||||
// all its methods are optional.
|
// all its methods are optional.
|
||||||
|
@ -3067,19 +3119,13 @@ namespace Catch
|
||||||
()
|
()
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
id obj = class_createInstance( m_cls, 0 );
|
id obj = [[m_cls alloc] init];
|
||||||
obj = [obj init];
|
|
||||||
|
|
||||||
if( [obj respondsToSelector: @selector(setUp) ] )
|
performOptionalSelector( obj, @selector(setUp) );
|
||||||
[obj performSelector: @selector(setUp)];
|
performOptionalSelector( obj, m_sel );
|
||||||
|
performOptionalSelector( obj, @selector(tearDown) );
|
||||||
|
|
||||||
if( [obj respondsToSelector: m_sel] )
|
arcSafeRelease( obj );
|
||||||
[obj performSelector: m_sel];
|
|
||||||
|
|
||||||
if( [obj respondsToSelector: @selector(tearDown) ] )
|
|
||||||
[obj performSelector: @selector(tearDown)];
|
|
||||||
|
|
||||||
[obj release];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
@ -3131,7 +3177,7 @@ namespace Catch
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
inline const char* getAnnotation
|
inline std::string getAnnotation
|
||||||
(
|
(
|
||||||
Class cls,
|
Class cls,
|
||||||
const std::string& annotationName,
|
const std::string& annotationName,
|
||||||
|
@ -3140,9 +3186,10 @@ namespace Catch
|
||||||
{
|
{
|
||||||
NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
|
NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
|
||||||
SEL sel = NSSelectorFromString( selStr );
|
SEL sel = NSSelectorFromString( selStr );
|
||||||
[selStr release];
|
arcSafeRelease( selStr );
|
||||||
if( [cls respondsToSelector: sel] )
|
id value = performOptionalSelector( cls, sel );
|
||||||
return (const char*)[cls performSelector: sel];
|
if( value )
|
||||||
|
return [(NSString*)value UTF8String];
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3154,8 +3201,8 @@ namespace Catch
|
||||||
size_t noTestMethods = 0;
|
size_t noTestMethods = 0;
|
||||||
int noClasses = objc_getClassList( NULL, 0 );
|
int noClasses = objc_getClassList( NULL, 0 );
|
||||||
|
|
||||||
std::vector<Class> classes( noClasses );
|
Class* classes = (__unsafe_unretained Class *)malloc( sizeof(Class) * noClasses);
|
||||||
objc_getClassList( &classes[0], noClasses );
|
objc_getClassList( classes, noClasses );
|
||||||
|
|
||||||
for( int c = 0; c < noClasses; c++ )
|
for( int c = 0; c < noClasses; c++ )
|
||||||
{
|
{
|
||||||
|
@ -3170,10 +3217,10 @@ namespace Catch
|
||||||
if( Detail::startsWith( methodName, "Catch_TestCase_" ) )
|
if( Detail::startsWith( methodName, "Catch_TestCase_" ) )
|
||||||
{
|
{
|
||||||
std::string testCaseName = methodName.substr( 15 );
|
std::string testCaseName = methodName.substr( 15 );
|
||||||
const char* name = Detail::getAnnotation( cls, "Name", testCaseName );
|
std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
|
||||||
const char* desc = Detail::getAnnotation( cls, "Description", testCaseName );
|
std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
|
||||||
|
|
||||||
Hub::getTestCaseRegistry().registerTest( TestCaseInfo( new OcMethod( cls, selector ), name, desc, "", 0 ) );
|
Hub::getTestCaseRegistry().registerTest( TestCaseInfo( new OcMethod( cls, selector ), name.c_str(), desc.c_str(), "", 0 ) );
|
||||||
noTestMethods++;
|
noTestMethods++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3184,8 +3231,7 @@ namespace Catch
|
||||||
return noTestMethods;
|
return noTestMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
inline std::string toString( NSString* const& nsstring )
|
||||||
inline std::string toString<NSString*>( NSString* const& nsstring )
|
|
||||||
{
|
{
|
||||||
return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
|
return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
|
||||||
}
|
}
|
||||||
|
@ -3201,7 +3247,7 @@ namespace Catch
|
||||||
StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
|
StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
|
||||||
StringHolder()
|
StringHolder()
|
||||||
{
|
{
|
||||||
[m_substr release];
|
arcSafeRelease( m_substr );
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString* m_substr;
|
NSString* m_substr;
|
||||||
|
@ -3293,13 +3339,13 @@ namespace Catch
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define OC_TEST_CASE( name, desc )\
|
#define OC_TEST_CASE( name, desc )\
|
||||||
+(const char*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
|
+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
|
||||||
{\
|
{\
|
||||||
return name; \
|
return @ name; \
|
||||||
}\
|
}\
|
||||||
+(const char*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
|
+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
|
||||||
{ \
|
{ \
|
||||||
return desc; \
|
return @ desc; \
|
||||||
} \
|
} \
|
||||||
-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
|
-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
|
||||||
|
|
||||||
|
@ -6804,13 +6850,17 @@ int main (int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
|
|
||||||
|
#if !CATCH_ARC_ENABLED
|
||||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
#endif
|
||||||
|
|
||||||
Catch::registerTestMethods();
|
Catch::registerTestMethods();
|
||||||
|
|
||||||
int result = Catch::Main( argc, (char* const*)argv );
|
int result = Catch::Main( argc, (char* const*)argv );
|
||||||
|
|
||||||
|
#if !CATCH_ARC_ENABLED
|
||||||
[pool drain];
|
[pool drain];
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue