mirror of
https://github.com/catchorg/Catch2.git
synced 2025-05-25 14:09:26 +00:00
Merges objc top level headers into main headers (using #ifdef __OBJC__)
This commit is contained in:
parent
38edb9fa95
commit
95419e935c
8 changed files with 28 additions and 38 deletions
184
include/internal/catch_objc.hpp
Normal file
184
include/internal/catch_objc.hpp
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* catch_objc.hpp
|
||||
* Catch
|
||||
*
|
||||
* Created by Phil on 14/11/2010.
|
||||
* Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
|
||||
|
||||
#import <objc/runtime.h>
|
||||
#include <string>
|
||||
|
||||
#include "internal/catch_test_case_info.hpp"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// This protocol is really only here for (self) documenting purposes, since
|
||||
// all its methods are optional.
|
||||
@protocol OcFixture
|
||||
|
||||
@optional
|
||||
|
||||
-(void) setUp;
|
||||
-(void) tearDown;
|
||||
|
||||
@end
|
||||
|
||||
namespace Catch
|
||||
{
|
||||
class OcMethod : public ITestCase
|
||||
{
|
||||
public:
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
OcMethod
|
||||
(
|
||||
Class cls,
|
||||
SEL sel
|
||||
)
|
||||
: m_cls( cls ),
|
||||
m_sel( sel )
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
virtual void invoke
|
||||
()
|
||||
const
|
||||
{
|
||||
id obj = class_createInstance( m_cls, 0 );
|
||||
obj = [obj init];
|
||||
|
||||
if( [obj respondsToSelector: @selector(setUp) ] )
|
||||
[obj performSelector: @selector(setUp)];
|
||||
|
||||
if( [obj respondsToSelector: m_sel] )
|
||||
[obj performSelector: m_sel];
|
||||
|
||||
if( [obj respondsToSelector: @selector(tearDown) ] )
|
||||
[obj performSelector: @selector(tearDown)];
|
||||
|
||||
[obj release];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
virtual ITestCase* clone
|
||||
()
|
||||
const
|
||||
{
|
||||
return new OcMethod( m_cls, m_sel );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
virtual bool operator ==
|
||||
(
|
||||
const ITestCase& other
|
||||
)
|
||||
const
|
||||
{
|
||||
const OcMethod* ocmOther = dynamic_cast<const OcMethod*> ( &other );
|
||||
return ocmOther && ocmOther->m_sel == m_sel;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
virtual bool operator <
|
||||
(
|
||||
const ITestCase& other
|
||||
)
|
||||
const
|
||||
{
|
||||
const OcMethod* ocmOther = dynamic_cast<const OcMethod*> ( &other );
|
||||
return ocmOther && ocmOther->m_sel < m_sel;
|
||||
}
|
||||
|
||||
private:
|
||||
Class m_cls;
|
||||
SEL m_sel;
|
||||
};
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
inline bool startsWith
|
||||
(
|
||||
const std::string& str,
|
||||
const std::string& sub
|
||||
)
|
||||
{
|
||||
return str.length() > sub.length() && str.substr( 0, sub.length() ) == sub;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
inline const char* getAnnotation
|
||||
(
|
||||
Class cls,
|
||||
const std::string& annotationName,
|
||||
const std::string& testCaseName
|
||||
)
|
||||
{
|
||||
NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
|
||||
SEL sel = NSSelectorFromString( selStr );
|
||||
[selStr release];
|
||||
if( [cls respondsToSelector: sel] )
|
||||
return (const char*)[cls performSelector: sel];
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
inline size_t registerTestMethods
|
||||
()
|
||||
{
|
||||
size_t noTestMethods = 0;
|
||||
int noClasses = objc_getClassList( NULL, 0 );
|
||||
|
||||
std::vector<Class> classes( noClasses );
|
||||
objc_getClassList( &classes[0], noClasses );
|
||||
|
||||
for( int c = 0; c < noClasses; c++ )
|
||||
{
|
||||
Class cls = classes[c];
|
||||
{
|
||||
u_int count;
|
||||
Method* methods = class_copyMethodList( cls, &count );
|
||||
for( int m = 0; m < count ; m++ )
|
||||
{
|
||||
SEL selector = method_getName(methods[m]);
|
||||
std::string methodName = sel_getName(selector);
|
||||
if( Detail::startsWith( methodName, "Catch_TestCase_" ) )
|
||||
{
|
||||
std::string testCaseName = methodName.substr( 15 );
|
||||
const char* name = Detail::getAnnotation( cls, "Name", testCaseName );
|
||||
const char* desc = Detail::getAnnotation( cls, "Description", testCaseName );
|
||||
|
||||
Hub::getTestCaseRegistry().registerTest( TestCaseInfo( new OcMethod( cls, selector ), name, desc, "", 0 ) );
|
||||
noTestMethods++;
|
||||
|
||||
}
|
||||
}
|
||||
free(methods);
|
||||
}
|
||||
}
|
||||
return noTestMethods;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define OC_TEST_CASE( name, desc )\
|
||||
+(const char*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
|
||||
{\
|
||||
return name; \
|
||||
}\
|
||||
+(const char*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
|
||||
{ \
|
||||
return desc; \
|
||||
} \
|
||||
-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
|
Loading…
Add table
Add a link
Reference in a new issue