@@ -77,6 +77,9 @@ public class TeamCityPlugin implements EventListener {
77
77
+ "[testFinished timestamp = '%s' duration = '%s' name = '%s']" ;
78
78
private static final String TEMPLATE_TEST_FAILED = TEAMCITY_PREFIX
79
79
+ "[testFailed timestamp = '%s' duration = '%s' message = '%s' details = '%s' name = '%s']" ;
80
+
81
+ private static final String TEMPLATE_TEST_COMPARISON_FAILED = TEAMCITY_PREFIX
82
+ + "[testFailed timestamp = '%s' duration = '%s' message = '%s' details = '%s' expected = '%s' actual = '%s' name = '%s']" ;
80
83
private static final String TEMPLATE_TEST_IGNORED = TEAMCITY_PREFIX
81
84
+ "[testIgnored timestamp = '%s' duration = '%s' message = '%s' name = '%s']" ;
82
85
@@ -101,6 +104,11 @@ public class TeamCityPlugin implements EventListener {
101
104
private static final Pattern ANNOTATION_GLUE_CODE_LOCATION_PATTERN = Pattern .compile ("^(.*)\\ .(.*)\\ ([^:]*\\ )" );
102
105
private static final Pattern LAMBDA_GLUE_CODE_LOCATION_PATTERN = Pattern .compile ("^(.*)\\ .(.*)\\ (.*:.*\\ )" );
103
106
107
+ private static final Pattern [] COMPARE_PATTERNS = new Pattern [] {
108
+ Pattern .compile ("^expected:\\ s*(.*)\\ s+but was:\\ s*(.*)" ,
109
+ Pattern .DOTALL | Pattern .CASE_INSENSITIVE ),
110
+ };
111
+
104
112
private final PrintStream out ;
105
113
private final List <SnippetsSuggestedEvent > suggestions = new ArrayList <>();
106
114
private final Map <URI , Collection <Node >> parsedTestSources = new HashMap <>();
@@ -281,7 +289,16 @@ private void printTestStepFinished(TestStepFinished event) {
281
289
case AMBIGUOUS :
282
290
case FAILED : {
283
291
String details = printStackTrace (error );
284
- print (TEMPLATE_TEST_FAILED , timeStamp , duration , "Step failed" , details , name );
292
+ String message = error .getMessage ();
293
+ ComparisonFailureData comparisonFailureData = message != null
294
+ ? createExceptionNotification (message .trim ())
295
+ : null ;
296
+ if (comparisonFailureData != null ) {
297
+ print (TEMPLATE_TEST_COMPARISON_FAILED , timeStamp , duration , "Step failed" , details ,
298
+ comparisonFailureData .getExpected (), comparisonFailureData .getActual (), name );
299
+ } else {
300
+ print (TEMPLATE_TEST_FAILED , timeStamp , duration , "Step failed" , details , name );
301
+ }
285
302
break ;
286
303
}
287
304
default :
@@ -290,6 +307,26 @@ private void printTestStepFinished(TestStepFinished event) {
290
307
print (TEMPLATE_TEST_FINISHED , timeStamp , duration , name );
291
308
}
292
309
310
+ private static ComparisonFailureData createExceptionNotification (String message , Pattern pattern ) {
311
+ final Matcher matcher = pattern .matcher (message );
312
+ if (matcher .find ()) {
313
+ String expected = matcher .group (1 );
314
+ String actual = matcher .group (2 );
315
+ return new ComparisonFailureData (expected , actual );
316
+ }
317
+ return null ;
318
+ }
319
+
320
+ private static ComparisonFailureData createExceptionNotification (String message ) {
321
+ for (Pattern pattern : COMPARE_PATTERNS ) {
322
+ ComparisonFailureData result = createExceptionNotification (message , pattern );
323
+ if (result != null ) {
324
+ return result ;
325
+ }
326
+ }
327
+ return null ;
328
+ }
329
+
293
330
private String extractName (TestStep step ) {
294
331
if (step instanceof PickleStepTestStep ) {
295
332
PickleStepTestStep pickleStepTestStep = (PickleStepTestStep ) step ;
@@ -420,4 +457,39 @@ private String escape(String source) {
420
457
.replace ("]" , "|]" );
421
458
}
422
459
460
+ private static class ComparisonFailureData {
461
+ private final String expected ;
462
+
463
+ private final String actual ;
464
+
465
+ ComparisonFailureData (String expected , String actual ) {
466
+ if (isWrappedWith (expected , '<' , '>' ) && isWrappedWith (actual , '<' , '>' )) {
467
+ expected = unwrap (expected );
468
+ actual = unwrap (actual );
469
+ }
470
+ if (isWrappedWith (expected , '[' , ']' ) && isWrappedWith (actual , '[' , ']' )) {
471
+ expected = unwrap (expected );
472
+ actual = unwrap (actual );
473
+ }
474
+ this .expected = expected ;
475
+ this .actual = actual ;
476
+ }
477
+
478
+ private static boolean isWrappedWith (String text , char startChar , char endChar ) {
479
+ return !text .isEmpty () &&
480
+ text .charAt (0 ) == startChar && text .charAt (text .length () - 1 ) == endChar ;
481
+ }
482
+
483
+ private static String unwrap (String text ) {
484
+ return text .substring (1 , text .length () - 1 );
485
+ }
486
+
487
+ public String getExpected () {
488
+ return expected ;
489
+ }
490
+
491
+ public String getActual () {
492
+ return actual ;
493
+ }
494
+ }
423
495
}
0 commit comments