From b213202ad72ad8266af50b8d57e90abccb9af07e Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Fri, 4 May 2012 07:55:11 +0100 Subject: [PATCH] Added self-test for section ordering Added MockReporter for tracking test runs. Added intrusive smart pointer. Config holds reporter by smart pointer, so we can route the mock reporter through multiple test runs --- include/internal/catch_config.hpp | 13 +- include/internal/catch_interfaces_reporter.h | 3 +- include/internal/catch_list.hpp | 4 +- include/internal/catch_ptr.hpp | 100 ++++++++ include/internal/catch_resultinfo.hpp | 10 +- include/internal/catch_runner_impl.hpp | 8 +- include/reporters/catch_reporter_basic.hpp | 4 +- include/reporters/catch_reporter_junit.hpp | 2 +- include/reporters/catch_reporter_xml.hpp | 4 +- projects/SelfTest/ExceptionTests.cpp | 14 +- projects/SelfTest/MiscTests.cpp | 49 ++++ projects/SelfTest/TestMain.cpp | 2 +- projects/SelfTest/catch_self_test.cpp | 23 +- projects/SelfTest/catch_self_test.hpp | 238 +++++++++++++++++- .../CatchSelfTest.xcodeproj/project.pbxproj | 4 +- .../xcdebugger/Breakpoints.xcbkptlist | 21 -- 16 files changed, 432 insertions(+), 67 deletions(-) create mode 100644 include/internal/catch_ptr.hpp delete mode 100644 projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/xcuserdata/Phil.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist diff --git a/include/internal/catch_config.hpp b/include/internal/catch_config.hpp index e23f40b..8596189 100644 --- a/include/internal/catch_config.hpp +++ b/include/internal/catch_config.hpp @@ -56,8 +56,7 @@ namespace Catch /////////////////////////////////////////////////////////////////////////// Config() - : m_reporter( NULL ), - m_listSpec( List::None ), + : m_listSpec( List::None ), m_shouldDebugBreak( false ), m_showHelp( false ), m_streambuf( NULL ), @@ -137,15 +136,15 @@ namespace Catch /////////////////////////////////////////////////////////////////////////// void setReporter( IReporter* reporter ) { - m_reporter = std::auto_ptr( reporter ); + m_reporter = reporter; } /////////////////////////////////////////////////////////////////////////// - IReporter* getReporter() const + Ptr getReporter() { if( !m_reporter.get() ) const_cast( this )->setReporter( Hub::getReporterRegistry().create( "basic", *this ) ); - return m_reporter.get(); + return m_reporter; } /////////////////////////////////////////////////////////////////////////// @@ -221,7 +220,7 @@ namespace Catch setStreamBuf( newBuf ); delete m_streambuf; m_streambuf = newBuf; - } + } /////////////////////////////////////////////////////////////////////////// virtual bool includeSuccessfulResults() const @@ -230,7 +229,7 @@ namespace Catch } private: - std::auto_ptr m_reporter; + Ptr m_reporter; std::string m_filename; std::string m_message; List::What m_listSpec; diff --git a/include/internal/catch_interfaces_reporter.h b/include/internal/catch_interfaces_reporter.h index f7690d5..fd0e87b 100644 --- a/include/internal/catch_interfaces_reporter.h +++ b/include/internal/catch_interfaces_reporter.h @@ -15,6 +15,7 @@ #include "catch_common.h" #include "catch_totals.hpp" +#include "catch_ptr.hpp" #include #include @@ -43,7 +44,7 @@ namespace Catch class ResultInfo; /////////////////////////////////////////////////////////////////////////// - struct IReporter : NonCopyable + struct IReporter : IShared { virtual ~IReporter (){} diff --git a/include/internal/catch_list.hpp b/include/internal/catch_list.hpp index 255df91..e024605 100644 --- a/include/internal/catch_list.hpp +++ b/include/internal/catch_list.hpp @@ -21,7 +21,7 @@ namespace Catch /////////////////////////////////////////////////////////////////////////// inline int List ( - const Config& config + Config& config ) { if( config.listWhat() & Config::List::Reports ) @@ -54,7 +54,7 @@ namespace Catch return (std::numeric_limits::max)(); } - if( config.getReporter() ) + if( config.getReporter().get() ) { std::cerr << "Reporters ignored when listing" << std::endl; } diff --git a/include/internal/catch_ptr.hpp b/include/internal/catch_ptr.hpp new file mode 100644 index 0000000..97cc507 --- /dev/null +++ b/include/internal/catch_ptr.hpp @@ -0,0 +1,100 @@ +/* + * catch_ptr.hpp + * Catch + * + * Created by Phil on 02/05/2012. + * Copyright 2012 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_PTR_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED + +#include "catch_common.h" + +namespace Catch +{ + // An intrusive reference counting smart pointer. + // T must implement addRef() and release() methods + // typically implementing the IShared interface + template + class Ptr + { + public: + Ptr() : m_p( NULL ){} + Ptr( T* p ) : m_p( p ){ + m_p->addRef(); + } + Ptr( const Ptr& other ) : m_p( other.m_p ){ + m_p->addRef(); + } + ~Ptr(){ + if( m_p ) + m_p->release(); + } + Ptr& operator = ( T* p ){ + Ptr temp( p ); + swap( temp ); + return *this; + } + Ptr& operator = ( Ptr& other ){ + Ptr temp( other ); + swap( temp ); + return *this; + } + void swap( Ptr& other ){ + std::swap( m_p, other.m_p ); + } + + T* get(){ + return m_p; + } + const T* get() const{ + return m_p; + } + + T& operator*(){ + return *m_p; + } + const T& operator*() const{ + return *m_p; + } + + T* operator->(){ + return m_p; + } + const T* operator->() const{ + return m_p; + } + + private: + T* m_p; + }; + + struct IShared : NonCopyable { + virtual ~IShared(){} + virtual void addRef() = 0; + virtual void release() = 0; + }; + + template + struct SharedImpl : T { + + SharedImpl() : m_rc( 0 ){} + + virtual void addRef(){ + ++m_rc; + } + virtual void release(){ + if( --m_rc == 0 ) + delete this; + } + + int m_rc; + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED diff --git a/include/internal/catch_resultinfo.hpp b/include/internal/catch_resultinfo.hpp index 1e504e4..9119bd4 100644 --- a/include/internal/catch_resultinfo.hpp +++ b/include/internal/catch_resultinfo.hpp @@ -108,6 +108,14 @@ namespace Catch return m_expr; } + /////////////////////////////////////////////////////////////////////////// + bool hasExpandedExpression + () + const + { + return hasExpression() && getExpandedExpressionInternal() != m_expr; + } + /////////////////////////////////////////////////////////////////////////// std::string getExpandedExpression () @@ -162,7 +170,7 @@ namespace Catch else if( m_op != "!" ) return m_lhs + " " + m_op + " " + m_rhs; else - return "{can't expand - use " + m_macroName + "_NOT( " + m_expr.substr(1) + " ) instead of " + m_macroName + "( " + m_expr + " ) for better diagnostics}"; + return "{can't expand - use " + m_macroName + "_FALSE( " + m_expr.substr(1) + " ) instead of " + m_macroName + "( " + m_expr + " ) for better diagnostics}"; } /////////////////////////////////////////////////////////////////////////// diff --git a/include/internal/catch_runner_impl.hpp b/include/internal/catch_runner_impl.hpp index 45bd9e4..7267f44 100644 --- a/include/internal/catch_runner_impl.hpp +++ b/include/internal/catch_runner_impl.hpp @@ -300,11 +300,11 @@ namespace Catch /////////////////////////////////////////////////////////////////////////// explicit Runner ( - const Config& config + Config& config ) : m_runningTest( NULL ), m_config( config ), - m_reporter( m_config.getReporter() ), + m_reporter( config.getReporter() ), m_prevRunner( &Hub::getRunner() ), m_prevResultCapture( &Hub::getResultCapture() ) { @@ -376,9 +376,11 @@ namespace Catch { do { + m_reporter->StartGroup( "test case run" ); m_currentResult.setFileAndLine( m_runningTest->getTestCaseInfo().getFilename(), m_runningTest->getTestCaseInfo().getLine() ); runCurrentTest( redirectedCout, redirectedCerr ); + m_reporter->EndGroup( "test case run", m_totals - prevTotals ); } while( m_runningTest->hasUntestedSections() ); } @@ -608,7 +610,7 @@ namespace Catch const Config& m_config; Totals m_totals; - IReporter* m_reporter; + Ptr m_reporter; std::vector m_scopedInfos; std::vector m_info; IRunner* m_prevRunner; diff --git a/include/reporters/catch_reporter_basic.hpp b/include/reporters/catch_reporter_basic.hpp index 6bca6b9..7db7273 100644 --- a/include/reporters/catch_reporter_basic.hpp +++ b/include/reporters/catch_reporter_basic.hpp @@ -38,7 +38,7 @@ namespace Catch std::string m_label; }; - class BasicReporter : public IReporter + class BasicReporter : public SharedImpl { struct SpanInfo { @@ -311,7 +311,7 @@ namespace Catch break; } - if( resultInfo.hasExpression() && resultInfo.getExpression() != resultInfo.getExpandedExpression() ) + if( resultInfo.hasExpandedExpression() ) { m_config.stream() << " for: "; TextColour colour( TextColour::ReconstructedExpression ); diff --git a/include/reporters/catch_reporter_junit.hpp b/include/reporters/catch_reporter_junit.hpp index e2238d7..0314901 100644 --- a/include/reporters/catch_reporter_junit.hpp +++ b/include/reporters/catch_reporter_junit.hpp @@ -19,7 +19,7 @@ namespace Catch { - class JunitReporter : public Catch::IReporter + class JunitReporter : public SharedImpl { struct TestStats { diff --git a/include/reporters/catch_reporter_xml.hpp b/include/reporters/catch_reporter_xml.hpp index 910932c..4414101 100644 --- a/include/reporters/catch_reporter_xml.hpp +++ b/include/reporters/catch_reporter_xml.hpp @@ -19,7 +19,7 @@ namespace Catch { - class XmlReporter : public Catch::IReporter + class XmlReporter : public SharedImpl { public: /////////////////////////////////////////////////////////////////////////// @@ -29,7 +29,7 @@ namespace Catch ) : m_config( config ) { - } + } /////////////////////////////////////////////////////////////////////////// static std::string getDescription diff --git a/projects/SelfTest/ExceptionTests.cpp b/projects/SelfTest/ExceptionTests.cpp index 7bc0138..376ce80 100644 --- a/projects/SelfTest/ExceptionTests.cpp +++ b/projects/SelfTest/ExceptionTests.cpp @@ -126,22 +126,22 @@ TEST_CASE( "./failing/exceptions/in-section", "Exceptions thrown from sections r TEST_CASE( "./succeeding/exceptions/error messages", "The error messages produced by exceptions caught by Catch matched the expected form" ) { Catch::EmbeddedRunner runner; + using namespace Catch::Matchers; SECTION( "custom, unexpected", "" ) { runner.runMatching( "./failing/exceptions/custom" ); - INFO( runner.getOutput() ); - CHECK( runner.getOutput().find( "Unexpected exception" ) != std::string::npos ); - CHECK( runner.getOutput().find( "custom exception" ) != std::string::npos ); +// CHECK_THAT( runner.getLog(), Contains( "Unexpected exception" ) ); // Mock reporter doesn't say this + CHECK_THAT( runner.getLog(), Contains( "custom exception" ) ); } SECTION( "in section", "" ) { runner.runMatching( "./failing/exceptions/in-section" ); - INFO( runner.getOutput() ); - CHECK( runner.getOutput().find( "Unexpected exception" ) != std::string::npos ); - CHECK( runner.getOutput().find( "Exception from section" ) != std::string::npos ); - CHECK( runner.getOutput().find( CATCH_GET_LINE_INFO( "the section2" ) ) != std::string::npos ); + INFO( runner.getLog() ); +// CHECK( runner.getLog().find( "Unexpected exception" ) != std::string::npos ); // Mock reporter doesn't say this + CHECK_THAT( runner.getLog(), Contains( "Exception from section" ) ); +// CHECK( runner.getLog().find( CATCH_GET_LINE_INFO( "the section2" ) ) != std::string::npos ); // Mock reporter doesn't say this } } diff --git a/projects/SelfTest/MiscTests.cpp b/projects/SelfTest/MiscTests.cpp index d4b814a..d759514 100644 --- a/projects/SelfTest/MiscTests.cpp +++ b/projects/SelfTest/MiscTests.cpp @@ -11,6 +11,8 @@ */ #include "catch.hpp" +#include "catch_self_test.hpp" + #include TEST_CASE( "./succeeding/Misc/Sections", "random SECTION tests" ) @@ -70,6 +72,53 @@ TEST_CASE( "./mixed/Misc/Sections/nested2", "nested SECTION tests" ) } } +TEST_CASE( "./Sections/nested/a/b", "nested SECTION tests" ) +{ + SECTION( "c", "" ) + { + SECTION( "d (leaf)", "" ) + { + } + + SECTION( "e (leaf)", "" ) + { + } + } + + SECTION( "f (leaf)", "" ) + { + } +} + +TEST_CASE( "Sections/nested3", "nested SECTION tests" ) +{ + Catch::EmbeddedRunner runner; + + runner.runMatching( "./Sections/nested/a/b", "mock" ); + CHECK( runner.getLog() == + "[tc]( ./Sections/nested/a/b ){ " + + "[g]( test case run ){ " + "[s]( c ){ " + "[s]( d (leaf) ){ } [s]( d (leaf) ) " + "} [s]( c ) " + "} [g]( test case run )" + + "[g]( test case run ){ " + "[s]( c ){ " + "[s]( e (leaf) ){ } [s]( e (leaf) ) " + "} [s]( c ) " + "} [g]( test case run )" + + "[g]( test case run ){ " + "[s]( c ){ } [s]( c ) " + "[s]( f (leaf) ){ } [s]( f (leaf) ) " + "} [g]( test case run ) " + + "} [tc]( ./Sections/nested/a/b )" ); + +} + TEST_CASE( "./mixed/Misc/Sections/loops", "looped SECTION tests" ) { int a = 1; diff --git a/projects/SelfTest/TestMain.cpp b/projects/SelfTest/TestMain.cpp index 97bdb6a..a95402d 100644 --- a/projects/SelfTest/TestMain.cpp +++ b/projects/SelfTest/TestMain.cpp @@ -43,7 +43,7 @@ TEST_CASE( "selftest/main", "Runs all Catch self tests and checks their results" "Number of 'succeeding' tests is fixed" ) { runner.runMatching( "./succeeding/*" ); - CHECK( runner.getTotals().assertions.passed == 276 ); + CHECK( runner.getTotals().assertions.passed == 273 ); CHECK( runner.getTotals().assertions.failed == 0 ); } diff --git a/projects/SelfTest/catch_self_test.cpp b/projects/SelfTest/catch_self_test.cpp index 73a4da5..7c9a3b5 100644 --- a/projects/SelfTest/catch_self_test.cpp +++ b/projects/SelfTest/catch_self_test.cpp @@ -13,18 +13,18 @@ #define CATCH_CONFIG_MAIN #include "catch_self_test.hpp" -namespace Catch -{ - /////////////////////////////////////////////////////////////////////////// - std::size_t EmbeddedRunner::runMatching - ( - const std::string& rawTestSpec - ) +namespace Catch{ + + std::size_t EmbeddedRunner::runMatching( + const std::string& rawTestSpec, + const std::string& reporter ) { std::ostringstream oss; Config config; config.setStreamBuf( oss.rdbuf() ); - config.setReporter( "basic" ); + + //if( reporter == "mock" ) // !TBD + config.setReporter( m_reporter.get() ); std::size_t result; @@ -37,4 +37,11 @@ namespace Catch m_output = oss.str(); return result; } + + const std::string MockReporter::recordGroups = "[g]"; + const std::string MockReporter::recordTestCases = "[tc]"; + const std::string MockReporter::recordSections =" [s]"; + + INTERNAL_CATCH_REGISTER_REPORTER( "mock", MockReporter ) + } diff --git a/projects/SelfTest/catch_self_test.hpp b/projects/SelfTest/catch_self_test.hpp index 9b7fa1f..ca18077 100644 --- a/projects/SelfTest/catch_self_test.hpp +++ b/projects/SelfTest/catch_self_test.hpp @@ -14,19 +14,223 @@ #include "catch.hpp" +#include "set" + namespace Catch { + class MockReporter : public SharedImpl + { + public: + + static const std::string recordGroups; + static const std::string recordTestCases; + static const std::string recordSections; + + void recordAll + () + { + addRecorder( recordGroups ); + addRecorder( recordTestCases ); + addRecorder( recordSections ); + } + + MockReporter + ( + const IReporterConfig& config + ) + { + recordAll(); + } + + MockReporter + () + { + recordAll(); + } + + void addRecorder + ( + const std::string& recorder + ) + { + m_recorders.insert( recorder ); + } + + static std::string getDescription + () + { + return "mock reporter"; + } + + std::string getLog + () + const + { + return m_log.str(); + } + + private: // IReporter + + virtual bool shouldRedirectStdout + () + const + { + return false; + } + + virtual void StartTesting + () + { + } + + virtual void EndTesting + ( + const Totals& totals + ) + { + } + + virtual void StartGroup + ( + const std::string& groupName + ) + { + if( shouldRecord( recordGroups ) ) + m_log << recordGroups << "( " << groupName << " ){ "; + } + + virtual void EndGroup + ( + const std::string& groupName, + const Totals& totals + ) + { + if( shouldRecord( recordGroups ) ) + m_log << " } " << recordGroups << "( " << groupName << " )"; + } + + virtual void StartSection + ( + const std::string& sectionName, + const std::string description + ) + { + if( shouldRecord( recordSections ) ) + m_log << recordSections << "( " << sectionName << " ){ "; + } + + virtual void EndSection + ( + const std::string& sectionName, + const Counts& assertions + ) + { + if( shouldRecord( recordSections ) ) + m_log << " } " << recordSections << "( " << sectionName << " )"; + } + + virtual void StartTestCase + ( + const TestCaseInfo& testInfo + ) + { + if( shouldRecord( recordTestCases ) ) + m_log << recordTestCases << "( " << testInfo.getName() << " ){ "; + } + + virtual void EndTestCase + ( + const TestCaseInfo& testInfo, + const Totals& totals, + const std::string& stdOut, + const std::string& stdErr + ) + { + if( shouldRecord( recordTestCases ) ) + m_log << " } " << recordTestCases << "( " << testInfo.getName() << " )"; + } + + virtual void Result + ( + const ResultInfo& resultInfo + ) + { + if( resultInfo.getResultType() == ResultWas::Ok ) + return; + + + switch( resultInfo.getResultType() ) + { + case ResultWas::Info: + m_log << "Info"; + break; + case ResultWas::Warning: + m_log << "Warning"; + break; + case ResultWas::ExplicitFailure: + m_log << "ExplicitFailure"; + break; + case ResultWas::ExpressionFailed: + m_log << "ExpressionFailed"; + break; + case ResultWas::Unknown: + m_log << "Unknown"; + break; + case ResultWas::ThrewException: + m_log << "ThrewException"; + break; + case ResultWas::DidntThrowException: + m_log << "DidntThrowException"; + break; + + // We shouldn't ever see these + case ResultWas::Ok: + m_log << "Ok"; + break; + case ResultWas::FailureBit: + m_log << "FailureBit"; + break; + case ResultWas::Exception: + m_log << "Exception"; + break; + default: + m_log << "{unrecognised ResultType enum value}"; + break; + } + + if( resultInfo.hasExpression() ) + m_log << resultInfo.getExpression(); + + if( resultInfo.hasMessage() ) + m_log << "'" << resultInfo.getMessage() << "'"; + + if( resultInfo.hasExpandedExpression() ) + m_log << resultInfo.getExpandedExpression(); + } + + private: + + bool shouldRecord( const std::string& recorder ) const + { + return m_recorders.find( recorder ) != m_recorders.end(); + } + std::ostringstream m_log; + std::set m_recorders; + }; + class EmbeddedRunner { public: /////////////////////////////////////////////////////////////////////////// EmbeddedRunner () + : m_reporter( new MockReporter() ) { } std::size_t runMatching - ( const std::string& rawTestSpec ); + ( const std::string& rawTestSpec, + const std::string& reporter = "basic" ); /////////////////////////////////////////////////////////////////////////// std::string getOutput @@ -42,10 +246,23 @@ namespace Catch { return m_totals; } + + /////////////////////////////////////////////////////////////////////////// + void addRecorder( const std::string& recorder ) + { + m_reporter->addRecorder( recorder ); + } + + /////////////////////////////////////////////////////////////////////////// + std::string getLog() const + { + return m_reporter->getLog(); + } private: Totals m_totals; std::string m_output; + Ptr m_reporter; }; class MetaTestRunner @@ -60,6 +277,15 @@ namespace Catch }; }; + /////////////////////////////////////////////////////////////////////////// + MetaTestRunner + ( + Expected::Result expectedResult + ) + : m_expectedResult( expectedResult ) + { + } + /////////////////////////////////////////////////////////////////////////// static void runMatching ( @@ -71,15 +297,6 @@ namespace Catch MetaTestRunner( expectedResult ) ); } - /////////////////////////////////////////////////////////////////////////// - MetaTestRunner - ( - Expected::Result expectedResult - ) - : m_expectedResult( expectedResult ) - { - } - /////////////////////////////////////////////////////////////////////////// void operator() ( @@ -163,6 +380,7 @@ namespace Catch LineInfoRegistry::get().registerLineInfo( name, lineInfo ); } }; + } #define CATCH_REGISTER_LINE_INFO( name ) ::Catch::LineInfoRegistrar INTERNAL_CATCH_UNIQUE_NAME( lineRegistrar )( name, ::Catch::SourceLineInfo( __FILE__, __LINE__ ) ); diff --git a/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj b/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj index d3cc91a..44613af 100644 --- a/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj +++ b/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj @@ -87,6 +87,7 @@ 4A7ADB4314F631E10094FE10 /* catch_totals.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_totals.hpp; sourceTree = ""; }; 4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_console_colour_impl.hpp; sourceTree = ""; }; 4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_console_colour.hpp; sourceTree = ""; }; + 4AB77CB51551AEA200857BF0 /* catch_ptr.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_ptr.hpp; sourceTree = ""; }; 4AE1840A14EE4F230066340D /* catch_self_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_self_test.cpp; path = ../../../SelfTest/catch_self_test.cpp; sourceTree = ""; }; /* End PBXFileReference section */ @@ -195,6 +196,7 @@ 4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */, 4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */, 4A3D7DD01503869D005F9203 /* catch_matchers.hpp */, + 4AB77CB51551AEA200857BF0 /* catch_ptr.hpp */, ); name = internal; path = ../../../../include/internal; @@ -237,7 +239,7 @@ 4A6D0C17149B3D3B00DB3EAA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0420; + LastUpgradeCheck = 0430; }; buildConfigurationList = 4A6D0C1A149B3D3B00DB3EAA /* Build configuration list for PBXProject "CatchSelfTest" */; compatibilityVersion = "Xcode 3.2"; diff --git a/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/xcuserdata/Phil.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/xcuserdata/Phil.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist deleted file mode 100644 index 3cc315e..0000000 --- a/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/xcuserdata/Phil.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - -