TeamCity reporter work

expanded reporting - includes section headers
diff --git a/include/reporters/catch_reporter_bases.hpp b/include/reporters/catch_reporter_bases.hpp
index ddbc63b..25f320b 100644
--- a/include/reporters/catch_reporter_bases.hpp
+++ b/include/reporters/catch_reporter_bases.hpp
@@ -198,6 +198,16 @@
 
     };
 
+    template<char C>
+    char const* getLineOfChars() {
+        static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
+        if( !*line ) {
+            memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
+            line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
+        }
+        return line;
+    }
+
 } // end namespace Catch
 
 #endif // TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
diff --git a/include/reporters/catch_reporter_console.hpp b/include/reporters/catch_reporter_console.hpp
index 7c0a23b..9fde203 100644
--- a/include/reporters/catch_reporter_console.hpp
+++ b/include/reporters/catch_reporter_console.hpp
@@ -445,15 +445,6 @@
         void printSummaryDivider() {
             stream << getLineOfChars<'-'>() << "\n";
         }
-        template<char C>
-        static char const* getLineOfChars() {
-            static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
-            if( !*line ) {
-                memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
-                line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
-            }
-            return line;
-        }
 
     private:
         bool m_headerPrinted;
diff --git a/include/reporters/catch_reporter_teamcity.hpp b/include/reporters/catch_reporter_teamcity.hpp
index f436567..47eafb1 100644
--- a/include/reporters/catch_reporter_teamcity.hpp
+++ b/include/reporters/catch_reporter_teamcity.hpp
@@ -18,7 +18,8 @@
     
     struct TeamCityReporter : StreamingReporterBase {
         TeamCityReporter( ReporterConfig const& _config )
-        :   StreamingReporterBase( _config )
+        :   StreamingReporterBase( _config ),
+            m_headerPrintedForThisSection( false )
         {}
         
         static std::string escape( std::string const& str ) {
@@ -65,23 +66,26 @@
             AssertionResult const& result = assertionStats.assertionResult;
             if( !result.isOk() ) {
                 
-                std::string message;
-                std::string details;
+                std::ostringstream msg;
+                if( !m_headerPrintedForThisSection )
+                    printTestCaseAndSectionHeader( msg );
+                m_headerPrintedForThisSection = true;
+                
                 switch( result.getResultType() ) {
                     case ResultWas::ExpressionFailed:
-                        message = "expression failed";
+                        msg << "expression failed";
                         break;
                     case ResultWas::ThrewException:
-                        message = "unexpected exception";
+                        msg << "unexpected exception";
                         break;
                     case ResultWas::FatalErrorCondition:
-                        message = "fatal error condition";
+                        msg << "fatal error condition";
                         break;
                     case ResultWas::DidntThrowException:
-                        message = "no exception was thrown where one was expected";
+                        msg << "no exception was thrown where one was expected";
                         break;
                     case ResultWas::ExplicitFailure:
-                        message = "explicit failure";
+                        msg << "explicit failure";
                         break;
 
                     // We shouldn't get here because of the isOk() test
@@ -96,38 +100,38 @@
                         CATCH_NOT_IMPLEMENTED;
                 }
                 if( assertionStats.infoMessages.size() == 1 )
-                    message += " with message:";
+                    msg << " with message:";
                 if( assertionStats.infoMessages.size() > 1 )
-                    message += " with messages:";
+                    msg << " with messages:";
                 for( std::vector<MessageInfo>::const_iterator
                         it = assertionStats.infoMessages.begin(),
                         itEnd = assertionStats.infoMessages.end();
                     it != itEnd;
                     ++it )
-                    message += "\n" + it->message;
+                    msg << "\n  \"" << it->message << "\"";
                 
                 
                 if( result.hasExpression() ) {
-                    details =
-                        "  " + result.getExpressionInMacro() + "\n"
-                        "with expansion:\n" +
-                        "  " + result.getExpandedExpression() + "\n";
+                    msg <<
+                        "\n  " << result.getExpressionInMacro() << "\n"
+                        "with expansion:\n" <<
+                        "  " << result.getExpandedExpression() << "\n";
                 }
-                
-                // !TBD: file/ line
+                msg << "\n" << result.getSourceInfo() << "\n";
+                msg << "---------------------------------------";
                 
                 stream << "##teamcity[testFailed"
                     << " name='" << escape( currentTestCaseInfo->name )<< "'"
-                    << " message='" << escape( message ) << "'"
-                    << " details='" << escape( details ) << "'"
+                    << " message='" << escape( msg.str() ) << "'"
                     << "]\n";
             }
             return true;
         }
         
-//        virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
-//            // !TBD
-//        }
+        virtual void sectionStarting( SectionInfo const& sectionInfo ) {
+            m_headerPrintedForThisSection = false;
+            StreamingReporterBase::sectionStarting( sectionInfo );
+        }
 //        virtual void sectionEnded( SectionStats const& _sectionStats ) {
 //            // !TBD
 //        }
@@ -155,6 +159,46 @@
 //        }
         
     private:
+        void printTestCaseAndSectionHeader( std::ostream& os ) {
+            assert( !m_sectionStack.empty() );
+            printOpenHeader( os, currentTestCaseInfo->name );
+            
+            if( m_sectionStack.size() > 1 ) {
+                std::vector<SectionInfo>::const_iterator
+                it = m_sectionStack.begin()+1, // Skip first section (test case)
+                itEnd = m_sectionStack.end();
+                for( ; it != itEnd; ++it )
+                    printHeaderString( os, it->name, 2 );
+            }
+            
+            SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
+            
+            if( !lineInfo.empty() ){
+                os << getLineOfChars<'-'>() << "\n";
+                os << lineInfo << "\n";
+            }
+            os << getLineOfChars<'.'>() << "\n\n";
+        }
+
+        void printOpenHeader( std::ostream& os, std::string const& _name ) {
+            os  << getLineOfChars<'-'>() << "\n";
+            printHeaderString( os, _name );
+        }
+
+        // if string has a : in first line will set indent to follow it on
+        // subsequent lines
+        void printHeaderString( std::ostream& os, std::string const& _string, std::size_t indent = 0 ) {
+            std::size_t i = _string.find( ": " );
+            if( i != std::string::npos )
+                i+=2;
+            else
+                i = 0;
+            os << Text( _string, TextAttributes()
+                           .setIndent( indent+i)
+                           .setInitialIndent( indent ) ) << "\n";
+        }
+    private:
+        bool m_headerPrintedForThisSection;
         
     };
     
diff --git a/projects/SelfTest/TrickyTests.cpp b/projects/SelfTest/TrickyTests.cpp
index a167657..4fe2c0b 100644
--- a/projects/SelfTest/TrickyTests.cpp
+++ b/projects/SelfTest/TrickyTests.cpp
@@ -81,7 +81,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 TEST_CASE
 (
-    "A failing expression with a non streamable type is still captured[failing]",
+    "A failing expression with a non streamable type is still captured",
     "[Tricky][failing][.]"
 )
 {
@@ -97,7 +97,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 TEST_CASE
 (   
-    "string literals of different sizes can be compared[failing]",
+    "string literals of different sizes can be compared",
     "[Tricky][failing][.]"
 )
 {