123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /*
- * 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
- #include "catch_objc_arc.hpp"
- #import <objc/runtime.h>
- #include <string>
- // NB. Any general catch headers included here must be included
- // in catch.hpp first to make sure they are included by the single
- // header for non obj-usage
- #include "catch_test_case_info.h"
- #include "catch_string_manip.h"
- #include "catch_tostring.h"
- ///////////////////////////////////////////////////////////////////////////////
- // 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 ITestInvoker {
- public:
- OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
- virtual void invoke() const {
- id obj = [[m_cls alloc] init];
- performOptionalSelector( obj, @selector(setUp) );
- performOptionalSelector( obj, m_sel );
- performOptionalSelector( obj, @selector(tearDown) );
- arcSafeRelease( obj );
- }
- private:
- virtual ~OcMethod() {}
- Class m_cls;
- SEL m_sel;
- };
- namespace Detail{
- inline std::string getAnnotation( Class cls,
- std::string const& annotationName,
- std::string const& testCaseName ) {
- NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
- SEL sel = NSSelectorFromString( selStr );
- arcSafeRelease( selStr );
- id value = performOptionalSelector( cls, sel );
- if( value )
- return [(NSString*)value UTF8String];
- return "";
- }
- }
- inline std::size_t registerTestMethods() {
- std::size_t noTestMethods = 0;
- int noClasses = objc_getClassList( nullptr, 0 );
- Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
- objc_getClassList( classes, noClasses );
- for( int c = 0; c < noClasses; c++ ) {
- Class cls = classes[c];
- {
- u_int count;
- Method* methods = class_copyMethodList( cls, &count );
- for( u_int m = 0; m < count ; m++ ) {
- SEL selector = method_getName(methods[m]);
- std::string methodName = sel_getName(selector);
- if( startsWith( methodName, "Catch_TestCase_" ) ) {
- std::string testCaseName = methodName.substr( 15 );
- std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
- std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
- const char* className = class_getName( cls );
- getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
- noTestMethods++;
- }
- }
- free(methods);
- }
- }
- return noTestMethods;
- }
- #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
- namespace Matchers {
- namespace Impl {
- namespace NSStringMatchers {
- struct StringHolder : MatcherBase<NSString*>{
- StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
- StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
- StringHolder() {
- arcSafeRelease( m_substr );
- }
- bool match( NSString* str ) const override {
- return false;
- }
- NSString* CATCH_ARC_STRONG m_substr;
- };
- struct Equals : StringHolder {
- Equals( NSString* substr ) : StringHolder( substr ){}
- bool match( NSString* str ) const override {
- return (str != nil || m_substr == nil ) &&
- [str isEqualToString:m_substr];
- }
- std::string describe() const override {
- return "equals string: " + Catch::Detail::stringify( m_substr );
- }
- };
- struct Contains : StringHolder {
- Contains( NSString* substr ) : StringHolder( substr ){}
- bool match( NSString* str ) const override {
- return (str != nil || m_substr == nil ) &&
- [str rangeOfString:m_substr].location != NSNotFound;
- }
- std::string describe() const override {
- return "contains string: " + Catch::Detail::stringify( m_substr );
- }
- };
- struct StartsWith : StringHolder {
- StartsWith( NSString* substr ) : StringHolder( substr ){}
- bool match( NSString* str ) const override {
- return (str != nil || m_substr == nil ) &&
- [str rangeOfString:m_substr].location == 0;
- }
- std::string describe() const override {
- return "starts with: " + Catch::Detail::stringify( m_substr );
- }
- };
- struct EndsWith : StringHolder {
- EndsWith( NSString* substr ) : StringHolder( substr ){}
- bool match( NSString* str ) const override {
- return (str != nil || m_substr == nil ) &&
- [str rangeOfString:m_substr].location == [str length] - [m_substr length];
- }
- std::string describe() const override {
- return "ends with: " + Catch::Detail::stringify( m_substr );
- }
- };
- } // namespace NSStringMatchers
- } // namespace Impl
- inline Impl::NSStringMatchers::Equals
- Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
- inline Impl::NSStringMatchers::Contains
- Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
- inline Impl::NSStringMatchers::StartsWith
- StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
- inline Impl::NSStringMatchers::EndsWith
- EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
- } // namespace Matchers
- using namespace Matchers;
- #endif // CATCH_CONFIG_DISABLE_MATCHERS
- } // namespace Catch
- ///////////////////////////////////////////////////////////////////////////////
- #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
- #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
- +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
- { \
- return @ name; \
- } \
- +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
- { \
- return @ desc; \
- } \
- -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
- #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
- #endif // TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
|