This repository has been archived by the owner on Nov 13, 2023. It is now read-only.
forked from renatoathaydes/spock-reports
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TemplateReportCreator.groovy
126 lines (110 loc) · 5.24 KB
/
TemplateReportCreator.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package com.athaydes.spockframework.report.template
import com.athaydes.spockframework.report.IReportCreator
import com.athaydes.spockframework.report.internal.FeatureRun
import com.athaydes.spockframework.report.internal.SpecData
import com.athaydes.spockframework.report.internal.StringFormatHelper
import com.athaydes.spockframework.report.internal.StringTemplateProcessor
import com.athaydes.spockframework.report.util.Utils
import groovy.text.GStringTemplateEngine
import groovy.util.logging.Slf4j
import org.spockframework.runtime.model.BlockInfo
import org.spockframework.runtime.model.FeatureInfo
import org.spockframework.runtime.model.IterationInfo
/**
* IReportCreator which uses a user-provided template to generate spock-reports.
*/
@Slf4j
class TemplateReportCreator implements IReportCreator {
final stringProcessor = new StringTemplateProcessor()
// IReportCreator shared properties
String outputDir
boolean hideEmptyBlocks
// TemplateReportCreator properties
String specTemplateFile
String reportFileExtension
String summaryTemplateFile
String summaryFileName
void done() {
def reportsDir = Utils.createDir( outputDir )
TemplateReportAggregator.instance
.writeOut( new File( reportsDir, summaryFileName ), summaryTemplateFile )
}
@Override
void createReportFor( SpecData data ) {
def specClassName = data.info.description.className
def reportsDir = Utils.createDir( outputDir )
def reportFile = new File( reportsDir, specClassName + '.' + reportFileExtension )
reportFile.delete()
try {
if ( reportsDir.isDirectory() ) {
reportFile.write( reportFor( data ) )
TemplateReportAggregator.instance.addData( data )
} else {
log.warn "${this.class.name} cannot create output directory: ${reportsDir.absolutePath}"
}
} catch ( e ) {
log.warn "Unexpected error creating report", e
}
}
String reportFor( SpecData data ) {
def templateFileUrl = this.class.getResource( specTemplateFile )
if ( !templateFileUrl ) {
throw new RuntimeException( "Template File does not exist: $specTemplateFile" )
}
def engine = new GStringTemplateEngine()
def featuresCallback = createFeaturesCallback data
engine.createTemplate( templateFileUrl )
.make( [ reportCreator: this,
'utils' : Utils,
'fmt' : new StringFormatHelper(),
data : data,
features : featuresCallback ] )
.toString()
}
def createFeaturesCallback( SpecData data ) {
return [ eachFeature: { Closure callback ->
for ( feature in data.info.allFeatures ) {
callback.delegate = feature
FeatureRun run = data.featureRuns.find { it.feature == feature }
if ( run && Utils.isUnrolled( feature ) ) {
handleUnrolledFeature( run, feature, callback )
} else {
handleRegularFeature( run, callback, feature )
}
}
} ]
}
protected void handleRegularFeature( FeatureRun run, Closure callback, FeatureInfo feature ) {
final failures = run ? Utils.countProblems( [ run ], Utils.&isFailure ) : 0
final errors = run ? Utils.countProblems( [ run ], Utils.&isError ) : 0
final result = errors ? 'ERROR' : failures ? 'FAIL' : !run ? 'IGNORED' : 'PASS'
final problemsByIteration = run ? Utils.problemsByIteration( run.failuresByIteration ) : [ : ]
callback.call( feature.name, result, processedBlocks( feature ), problemsByIteration, feature.parameterNames )
}
protected void handleUnrolledFeature( FeatureRun run, FeatureInfo feature, Closure callback ) {
run.failuresByIteration.each { iteration, problems ->
final name = feature.iterationNameProvider.getName( iteration )
final result = problems.any( Utils.&isError ) ? 'ERROR' :
problems.any( Utils.&isFailure ) ? 'FAILURE' :
feature.skipped ? 'IGNORED' : 'PASS'
final problemsByIteration = Utils.problemsByIteration( [ ( iteration ): problems ] )
callback.call( name, result, processedBlocks( feature, iteration ), problemsByIteration, feature.parameterNames )
}
}
protected List processedBlocks( FeatureInfo feature, IterationInfo iteration = null ) {
feature.blocks.collect { BlockInfo block ->
if ( !Utils.isEmptyOrContainsOnlyEmptyStrings( block.texts ) ) {
int index = 0
block.texts.collect { blockText ->
if ( iteration ) {
blockText = stringProcessor.process( blockText, feature.dataVariables, iteration )
}
[ kind: Utils.block2String[ ( index++ ) == 0 ? block.kind : 'AND' ], text: blockText ]
}
} else if ( !hideEmptyBlocks )
[ kind: Utils.block2String[ block.kind ], text: '----' ]
else
[ : ]
}.findAll { !it.empty }.flatten()
}
}