@@ -3498,6 +3498,125 @@ std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(
3498
3498
// </testsuite>
3499
3499
// </testsuites>
3500
3500
3501
+ class TapUnitTestResultPrinter : public EmptyTestEventListener {
3502
+ public:
3503
+ TapUnitTestResultPrinter ();
3504
+ explicit TapUnitTestResultPrinter (const char * output_file);
3505
+ virtual void OnTestIterationEnd (const UnitTest& unit_test, int iteration);
3506
+
3507
+ private:
3508
+ static void PrintTapUnitTest (::std::ostream* stream,
3509
+ const UnitTest& unit_test);
3510
+ static void PrintTapTestCase (int * count,
3511
+ ::std::ostream* stream,
3512
+ const TestCase& test_case);
3513
+ static void OutputTapTestInfo (int * count,
3514
+ ::std::ostream* stream,
3515
+ const char * test_case_name,
3516
+ const TestInfo& test_info);
3517
+ static void OutputTapComment (::std::ostream* stream, const char * comment);
3518
+
3519
+ const std::string output_file_;
3520
+ GTEST_DISALLOW_COPY_AND_ASSIGN_ (TapUnitTestResultPrinter);
3521
+ };
3522
+
3523
+ TapUnitTestResultPrinter::TapUnitTestResultPrinter () {}
3524
+
3525
+ TapUnitTestResultPrinter::TapUnitTestResultPrinter (const char * output_file)
3526
+ : output_file_(output_file) {
3527
+ if (output_file_.c_str () == NULL || output_file_.empty ()) {
3528
+ fprintf (stderr, " TAP output file may not be null\n " );
3529
+ fflush (stderr);
3530
+ exit (EXIT_FAILURE);
3531
+ }
3532
+ }
3533
+
3534
+ void TapUnitTestResultPrinter::OnTestIterationEnd (const UnitTest& unit_test,
3535
+ int /* iteration*/ ) {
3536
+ FILE* tapout = stdout;
3537
+
3538
+ if (!output_file_.empty ()) {
3539
+ FilePath output_file (output_file_);
3540
+ FilePath output_dir (output_file.RemoveFileName ());
3541
+
3542
+ tapout = NULL ;
3543
+ if (output_dir.CreateDirectoriesRecursively ())
3544
+ tapout = posix::FOpen (output_file_.c_str (), " w" );
3545
+
3546
+ if (tapout == NULL ) {
3547
+ fprintf (stderr, " Unable to open file \" %s\"\n " , output_file_.c_str ());
3548
+ fflush (stderr);
3549
+ exit (EXIT_FAILURE);
3550
+ }
3551
+ }
3552
+
3553
+ std::stringstream stream;
3554
+ PrintTapUnitTest (&stream, unit_test);
3555
+ fprintf (tapout, " %s" , StringStreamToString (&stream).c_str ());
3556
+ fflush (tapout);
3557
+
3558
+ if (tapout != stdout)
3559
+ fclose (tapout);
3560
+ }
3561
+
3562
+ void TapUnitTestResultPrinter::PrintTapUnitTest (std::ostream* stream,
3563
+ const UnitTest& unit_test) {
3564
+ *stream << " TAP version 13\n " ;
3565
+ *stream << " 1.." << unit_test.reportable_test_count () << " \n " ;
3566
+
3567
+ int count = 1 ;
3568
+ for (int i = 0 ; i < unit_test.total_test_case_count (); ++i) {
3569
+ const TestCase& test_case = *unit_test.GetTestCase (i);
3570
+ if (test_case.reportable_test_count () > 0 )
3571
+ PrintTapTestCase (&count, stream, test_case);
3572
+ }
3573
+
3574
+ *stream << " # failures: " << unit_test.failed_test_count () << " \n " ;
3575
+ }
3576
+
3577
+ void TapUnitTestResultPrinter::PrintTapTestCase (int * count,
3578
+ std::ostream* stream,
3579
+ const TestCase& test_case) {
3580
+ for (int i = 0 ; i < test_case.total_test_count (); ++i) {
3581
+ const TestInfo& test_info = *test_case.GetTestInfo (i);
3582
+ if (test_info.is_reportable ())
3583
+ OutputTapTestInfo (count, stream, test_case.name (), test_info);
3584
+ }
3585
+ }
3586
+
3587
+ void TapUnitTestResultPrinter::OutputTapTestInfo (int * count,
3588
+ ::std::ostream* stream,
3589
+ const char * test_case_name,
3590
+ const TestInfo& test_info) {
3591
+ const TestResult& result = *test_info.result ();
3592
+ const char * status = result.Passed () ? " ok" : " not ok" ;
3593
+
3594
+ *stream << status << " " << *count << " - " <<
3595
+ test_case_name << " ." << test_info.name () << " \n " ;
3596
+ *stream << " ---\n " ;
3597
+ *stream << " duration_ms: " <<
3598
+ FormatTimeInMillisAsSeconds (result.elapsed_time ()) << " \n " ;
3599
+ *stream << " ...\n " ;
3600
+
3601
+ for (int i = 0 ; i < result.total_part_count (); ++i) {
3602
+ const TestPartResult& part = result.GetTestPartResult (i);
3603
+ OutputTapComment (stream, part.message ());
3604
+ }
3605
+
3606
+ *count += 1 ;
3607
+ }
3608
+
3609
+ void TapUnitTestResultPrinter::OutputTapComment (::std::ostream* stream,
3610
+ const char * comment) {
3611
+ const char * start = comment;
3612
+ while (const char * end = strchr (start, ' \n ' )) {
3613
+ *stream << " # " << std::string (start, end) << " \n " ;
3614
+ start = end + 1 ;
3615
+ }
3616
+ if (*start)
3617
+ *stream << " # " << start << " \n " ;
3618
+ }
3619
+
3501
3620
// Formats the given time in milliseconds as seconds.
3502
3621
std::string FormatTimeInMillisAsSeconds (TimeInMillis ms) {
3503
3622
::std::stringstream ss;
@@ -4314,7 +4433,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
4314
4433
#endif
4315
4434
// Will be overridden by the flag before first use.
4316
4435
catch_exceptions_ (false ) {
4317
- listeners ()->SetDefaultResultPrinter (new PrettyUnitTestResultPrinter );
4436
+ listeners ()->SetDefaultResultPrinter (new TapUnitTestResultPrinter );
4318
4437
}
4319
4438
4320
4439
UnitTestImpl::~UnitTestImpl () {
@@ -4365,6 +4484,9 @@ void UnitTestImpl::ConfigureXmlOutput() {
4365
4484
if (output_format == " xml" ) {
4366
4485
listeners ()->SetDefaultXmlGenerator (new XmlUnitTestResultPrinter (
4367
4486
UnitTestOptions::GetAbsolutePathToOutputFile ().c_str ()));
4487
+ } else if (output_format == " tap" ) {
4488
+ listeners ()->SetDefaultXmlGenerator (new TapUnitTestResultPrinter (
4489
+ UnitTestOptions::GetAbsolutePathToOutputFile ().c_str ()));
4368
4490
} else if (output_format != " " ) {
4369
4491
printf (" WARNING: unrecognized output format \" %s\" ignored.\n " ,
4370
4492
output_format.c_str ());
0 commit comments