0
# Coverage Data Model
1
2
The coverage data model provides the core data structures for representing coverage information including statements, classes, methods, packages, and files with comprehensive coverage metrics. This model forms the foundation for all coverage analysis and reporting functionality.
3
4
## Core Data Structures
5
6
### Coverage Class
7
8
The main container for all coverage data and analysis.
9
10
```scala { .api }
11
case class Coverage() extends CoverageMetrics
12
with MethodBuilders
13
with ClassBuilders
14
with PackageBuilders
15
with FileBuilders {
16
17
def add(stmt: Statement): Unit
18
def addIgnoredStatement(stmt: Statement): Unit
19
def apply(ids: Iterable[(Int, String)]): Unit
20
def invoked(id: (Int, String)): Unit
21
22
// Aggregation methods
23
def avgClassesPerPackage: Double
24
def avgClassesPerPackageFormatted: String
25
def avgMethodsPerClass: Double
26
def avgMethodsPerClassFormatted: String
27
def loc: Int
28
def linesPerFile: Double
29
def linesPerFileFormatted: String
30
def risks(limit: Int): Seq[MeasuredClass]
31
}
32
```
33
34
**Key Methods:**
35
- `add(stmt: Statement)` - Add a statement to coverage tracking
36
- `addIgnoredStatement(stmt: Statement)` - Add a statement that should be ignored
37
- `apply(ids: Iterable[(Int, String)])` - Apply measurement data to mark statements as invoked
38
- `invoked(id: (Int, String))` - Mark a specific statement as invoked
39
- `risks(limit: Int)` - Get classes with lowest coverage (highest risk)
40
41
### Statement Class
42
43
Represents a single instrumented statement in the source code.
44
45
```scala { .api }
46
case class Statement(
47
location: Location,
48
id: Int,
49
start: Int,
50
end: Int,
51
line: Int,
52
desc: String,
53
symbolName: String,
54
treeName: String,
55
branch: Boolean,
56
count: Int = 0,
57
ignored: Boolean = false,
58
tests: mutable.Set[String] = mutable.Set[String]()
59
) {
60
def source: String
61
def invoked(test: String): Unit
62
def isInvoked: Boolean
63
}
64
```
65
66
**Parameters:**
67
- `location` - Source code location information
68
- `id` - Unique identifier for the statement
69
- `start` - Character offset start position in source file
70
- `end` - Character offset end position in source file
71
- `line` - Line number in source file
72
- `desc` - Human-readable description of the statement
73
- `symbolName` - Scala symbol name (e.g., "scala.Predef.println")
74
- `treeName` - Scala compiler tree type (e.g., "Apply", "Select")
75
- `branch` - Whether this statement represents a branch point
76
- `count` - Number of times statement was executed
77
- `ignored` - Whether statement should be excluded from coverage
78
- `tests` - Set of test names that executed this statement
79
80
### Location Class
81
82
Contains source code location information for statements.
83
84
```scala { .api }
85
case class Location(
86
packageName: String,
87
className: String,
88
fullClassName: String,
89
classType: ClassType,
90
method: String,
91
sourcePath: String
92
)
93
```
94
95
**Parameters:**
96
- `packageName` - Package containing the statement
97
- `className` - Simple class name
98
- `fullClassName` - Fully qualified class name
99
- `classType` - Type of class (Class, Object, or Trait)
100
- `method` - Method containing the statement
101
- `sourcePath` - Absolute path to source file
102
103
## Measured Coverage Types
104
105
### MeasuredClass
106
107
Represents coverage metrics for a single class.
108
109
```scala { .api }
110
case class MeasuredClass(
111
fullClassName: String,
112
statements: Iterable[Statement]
113
) extends CoverageMetrics with MethodBuilders {
114
115
def source: String
116
def loc: Int
117
def displayClassName: String
118
}
119
```
120
121
**Key Properties:**
122
- `source` - Path to source file containing the class
123
- `loc` - Lines of code (highest line number with a statement)
124
- `displayClassName` - Class name without package prefix for display
125
126
### MeasuredMethod
127
128
Represents coverage metrics for a single method.
129
130
```scala { .api }
131
case class MeasuredMethod(
132
name: String,
133
statements: Iterable[Statement]
134
) extends CoverageMetrics
135
```
136
137
**Parameters:**
138
- `name` - Method name with signature information
139
- `statements` - All statements contained in this method
140
141
### MeasuredPackage
142
143
Represents coverage metrics for a package.
144
145
```scala { .api }
146
case class MeasuredPackage(
147
name: String,
148
statements: Iterable[Statement]
149
) extends CoverageMetrics with ClassCoverage with ClassBuilders with FileBuilders
150
```
151
152
**Parameters:**
153
- `name` - Package name (fully qualified)
154
- `statements` - All statements in the package
155
156
### MeasuredFile
157
158
Represents coverage metrics for a source file.
159
160
```scala { .api }
161
case class MeasuredFile(
162
source: String,
163
statements: Iterable[Statement]
164
) extends CoverageMetrics with ClassCoverage with ClassBuilders {
165
166
def filename: String
167
def loc: Int
168
}
169
```
170
171
**Key Properties:**
172
- `filename` - Just the filename without path
173
- `loc` - Lines of code (highest line number with a statement)
174
175
## Coverage Metrics Trait
176
177
All measured types implement the CoverageMetrics trait providing standard coverage calculations.
178
179
```scala { .api }
180
trait CoverageMetrics {
181
def statements: Iterable[Statement]
182
def ignoredStatements: Iterable[Statement]
183
184
// Statement metrics
185
def statementCount: Int
186
def ignoredStatementCount: Int
187
def invokedStatements: Iterable[Statement]
188
def invokedStatementCount: Int
189
def statementCoverage: Double
190
def statementCoveragePercent: Double
191
def statementCoverageFormatted: String
192
193
// Branch metrics
194
def branches: Iterable[Statement]
195
def branchCount: Int
196
def invokedBranches: Iterable[Statement]
197
def invokedBranchesCount: Int
198
def branchCoverage: Double
199
def branchCoveragePercent: Double
200
def branchCoverageFormatted: String
201
}
202
```
203
204
**Statement Metrics:**
205
- `statementCount` - Total statements
206
- `invokedStatementCount` - Statements that were executed
207
- `statementCoverage` - Coverage as decimal (0.0 to 1.0)
208
- `statementCoveragePercent` - Coverage as percentage (0.0 to 100.0)
209
- `statementCoverageFormatted` - Formatted percentage string (e.g., "85.67")
210
211
**Branch Metrics:**
212
- `branchCount` - Total branch points
213
- `invokedBranchesCount` - Branch points that were executed
214
- `branchCoverage` - Branch coverage as decimal (0.0 to 1.0)
215
- `branchCoveragePercent` - Branch coverage as percentage (0.0 to 100.0)
216
- `branchCoverageFormatted` - Formatted branch coverage percentage
217
218
## Supporting Types
219
220
### ClassType
221
222
Enumeration for different types of Scala classes.
223
224
```scala { .api }
225
sealed trait ClassType
226
227
object ClassType {
228
case object Object extends ClassType
229
case object Class extends ClassType
230
case object Trait extends ClassType
231
232
def fromString(str: String): ClassType
233
}
234
```
235
236
### CodeGrid
237
238
Generates highlighted source code display with coverage information for HTML reports.
239
240
```scala { .api }
241
class CodeGrid(mFile: MeasuredFile, sourceEncoding: Option[String]) {
242
val highlighted: String
243
}
244
245
// Backward compatibility constructor
246
class CodeGrid(mFile: MeasuredFile)
247
```
248
249
**Key Properties:**
250
- `highlighted: String` - HTML string with source code and coverage highlighting
251
252
### StatementStatus
253
254
Represents the execution status of a statement for display purposes.
255
256
```scala { .api }
257
sealed trait StatementStatus
258
case object Invoked extends StatementStatus
259
case object NotInvoked extends StatementStatus
260
case object NoData extends StatementStatus
261
```
262
263
### ClassRef
264
265
Utility class for working with class references.
266
267
```scala { .api }
268
case class ClassRef(name: String) {
269
lazy val simpleName: String
270
lazy val getPackage: String
271
}
272
273
object ClassRef {
274
def fromFilepath(path: String): ClassRef
275
def apply(_package: String, className: String): ClassRef
276
}
277
```
278
279
## Builder Traits
280
281
### MethodBuilders
282
283
Provides method aggregation functionality.
284
285
```scala { .api }
286
trait MethodBuilders {
287
def statements: Iterable[Statement]
288
def methods: Seq[MeasuredMethod]
289
def methodCount: Int
290
}
291
```
292
293
### PackageBuilders
294
295
Provides package aggregation functionality.
296
297
```scala { .api }
298
trait PackageBuilders {
299
def statements: Iterable[Statement]
300
def packages: Seq[MeasuredPackage]
301
def packageCount: Int
302
}
303
```
304
305
### ClassBuilders
306
307
Provides class aggregation functionality.
308
309
```scala { .api }
310
trait ClassBuilders {
311
def statements: Iterable[Statement]
312
def classes: Iterable[MeasuredClass]
313
def classCount: Int
314
}
315
```
316
317
### FileBuilders
318
319
Provides file aggregation functionality.
320
321
```scala { .api }
322
trait FileBuilders {
323
def statements: Iterable[Statement]
324
def files: Iterable[MeasuredFile]
325
def fileCount: Int
326
}
327
```
328
329
## Usage Examples
330
331
### Creating Coverage Data
332
333
```scala
334
import scoverage.domain._
335
336
// Create a new coverage container
337
val coverage = Coverage()
338
339
// Create a statement
340
val location = Location(
341
packageName = "com.example",
342
className = "MyClass",
343
fullClassName = "com.example.MyClass",
344
classType = ClassType.Class,
345
method = "myMethod",
346
sourcePath = "/path/to/MyClass.scala"
347
)
348
349
val statement = Statement(
350
location = location,
351
id = 1,
352
start = 100,
353
end = 120,
354
line = 10,
355
desc = "println(\"Hello\")",
356
symbolName = "scala.Predef.println",
357
treeName = "Apply",
358
branch = false
359
)
360
361
// Add statement to coverage
362
coverage.add(statement)
363
```
364
365
### Applying Measurement Data
366
367
```scala
368
// Measurement data represents which statements were executed
369
val measurements = Set(
370
(1, "com.example.MyTest"), // Statement 1 was hit by MyTest
371
(2, "com.example.MyTest"), // Statement 2 was hit by MyTest
372
(3, "") // Statement 3 was hit but test name unknown
373
)
374
375
// Apply measurements to coverage
376
coverage.apply(measurements)
377
378
// Check coverage metrics
379
println(s"Statement coverage: ${coverage.statementCoverageFormatted}%")
380
println(s"Branch coverage: ${coverage.branchCoverageFormatted}%")
381
```
382
383
### Analyzing Coverage
384
385
```scala
386
// Get classes with lowest coverage (highest risk)
387
val riskyClasses = coverage.risks(10)
388
riskyClasses.foreach { cls =>
389
println(s"${cls.fullClassName}: ${cls.statementCoverageFormatted}% coverage")
390
}
391
392
// Analyze by package
393
coverage.packages.foreach { pkg =>
394
println(s"Package ${pkg.name}: ${pkg.statementCoverageFormatted}% coverage")
395
396
// Analyze classes in package
397
pkg.classes.foreach { cls =>
398
println(s" Class ${cls.displayClassName}: ${cls.statementCoverageFormatted}%")
399
}
400
}
401
```
402
403
### Working with Files and Methods
404
405
```scala
406
// Analyze file-level coverage
407
coverage.files.foreach { file =>
408
println(s"File ${file.filename}: ${file.statementCoverageFormatted}% coverage, ${file.loc} LOC")
409
410
// Check methods in file
411
file.methods.foreach { method =>
412
println(s" Method ${method.name}: ${method.statementCoverageFormatted}% coverage")
413
}
414
}
415
```
416
417
## Error Handling
418
419
**Data Integrity:**
420
- Statements with duplicate IDs will overwrite previous statements
421
- Invalid coverage data may result in calculation errors
422
- Missing measurement data results in 0% coverage
423
424
**Common Issues:**
425
- Ensure statement IDs are unique within a coverage instance
426
- Verify that measurement data matches existing statement IDs
427
- Handle cases where source files may have been moved or deleted