@@ -1290,17 +1290,88 @@ namespace
12901290 failure.assertion = trim_copy (match[4 ].str ());
12911291 }
12921292
1293+ static void enrich_failure_from_gtest_failure (
1294+ ParsedTestFailure &failure,
1295+ const std::vector<std::string> &lines,
1296+ std::size_t index)
1297+ {
1298+ static const std::regex failureRe (
1299+ R"( (/[^:\n]+?\.(?:c|cc|cpp|cxx|h|hpp|hh|hxx)):(\d+):\s*Failure)" ,
1300+ std::regex::ECMAScript);
1301+
1302+ std::smatch match;
1303+
1304+ if (!std::regex_search (lines[index], match, failureRe))
1305+ return ;
1306+
1307+ failure.file = fs::path (match[1 ].str ());
1308+
1309+ try
1310+ {
1311+ failure.line = static_cast <std::size_t >(std::stoul (match[2 ].str ()));
1312+ }
1313+ catch (...)
1314+ {
1315+ failure.line = 0 ;
1316+ }
1317+
1318+ failure.column = 1 ;
1319+
1320+ std::string valueOf;
1321+ std::string actual;
1322+ std::string expected;
1323+
1324+ for (std::size_t i = index + 1 ; i < lines.size () && i < index + 8 ; ++i)
1325+ {
1326+ const std::string current = trim_copy (lines[i]);
1327+
1328+ if (current.rfind (" Value of:" , 0 ) == 0 )
1329+ valueOf = trim_copy (current.substr (std::string (" Value of:" ).size ()));
1330+
1331+ else if (current.rfind (" Actual:" , 0 ) == 0 )
1332+ actual = trim_copy (current.substr (std::string (" Actual:" ).size ()));
1333+
1334+ else if (current.rfind (" Expected:" , 0 ) == 0 )
1335+ expected = trim_copy (current.substr (std::string (" Expected:" ).size ()));
1336+
1337+ else if (current.rfind (" [ FAILED ]" , 0 ) == 0 ||
1338+ current.rfind (" [ RUN ]" , 0 ) == 0 )
1339+ break ;
1340+ }
1341+
1342+ if (!valueOf.empty ())
1343+ {
1344+ failure.assertion = valueOf;
1345+ failure.message = " expected `" + valueOf + " ` to be true" ;
1346+
1347+ if (!actual.empty ())
1348+ failure.message += " \n actual: " + actual;
1349+
1350+ if (!expected.empty ())
1351+ failure.message += " \n expected: " + expected;
1352+ }
1353+ }
1354+
12931355 static void enrich_failure_from_message (ParsedTestFailure &failure)
12941356 {
12951357 if (failure.message .empty ())
12961358 return ;
12971359
1298- std::istringstream lines (failure.message );
1360+ std::vector<std::string> lines;
1361+ std::istringstream input (failure.message );
12991362 std::string line;
13001363
1301- while (std::getline (lines, line))
1364+ while (std::getline (input, line))
1365+ lines.push_back (line);
1366+
1367+ for (std::size_t i = 0 ; i < lines.size (); ++i)
13021368 {
1303- enrich_failure_from_assertion_line (failure, line);
1369+ enrich_failure_from_assertion_line (failure, lines[i]);
1370+
1371+ if (failure.has_location ())
1372+ return ;
1373+
1374+ enrich_failure_from_gtest_failure (failure, lines, i);
13041375
13051376 if (failure.has_location ())
13061377 return ;
@@ -1320,8 +1391,15 @@ namespace
13201391
13211392 if (failure.has_assertion ())
13221393 {
1323- diagnostic.error =
1324- " assertion failed: " + failure.assertion ;
1394+ if (failure.message .find (" actual:" ) != std::string::npos ||
1395+ failure.message .find (" expected:" ) != std::string::npos)
1396+ {
1397+ diagnostic.error = failure.message ;
1398+ }
1399+ else
1400+ {
1401+ diagnostic.error = " assertion failed: " + failure.assertion ;
1402+ }
13251403 }
13261404 else if (!failure.message .empty ())
13271405 {
0 commit comments