@teamscale/coverage-collector 0.0.1-beta.6 → 0.0.1-beta.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/src/main.js CHANGED
@@ -1,118 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
3
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.Main = void 0;
8
- const package_json_1 = require("../package.json");
9
- const argparse_1 = require("argparse");
10
- const winston_1 = __importDefault(require("winston"));
11
- const DataStorage_1 = require("./storage/DataStorage");
12
- const CollectingServer_1 = require("./receiver/CollectingServer");
13
- /**
14
- * The main class of the Teamscale JavaScript Collector.
15
- * Used to start-up the collector for with a given configuration.
16
- */
17
- class Main {
18
- /**
19
- * Construct the object for parsing the command line arguments.
20
- */
21
- static buildParser() {
22
- const parser = new argparse_1.ArgumentParser({
23
- description: 'Collector of the Teamscale JavaScript Profiler. Collects coverage information from a' +
24
- '(headless) Web browser that executes code instrumented with our instrumenter.'
25
- });
26
- parser.add_argument('-v', '--version', { action: 'version', version: package_json_1.version });
27
- parser.add_argument('-p', '--port', { help: 'The port to receive coverage information on.', default: 54678 });
28
- parser.add_argument('-f', '--dump-to-file', { help: 'Target file', default: './coverage.simple' });
29
- parser.add_argument('-l', '--log-to-file', { help: 'Log file', default: 'logs/collector-combined.log' });
30
- parser.add_argument('-e', '--log-level', { help: 'Log level', default: 'info' });
31
- parser.add_argument('-t', '--dump-after-mins', {
32
- help: 'Dump the coverage information to the target file every N minutes.',
33
- default: 2
34
- });
35
- parser.add_argument('-d', '--debug', {
36
- help: 'Print received coverage information to the terminal?',
37
- default: false
38
- });
39
- return parser;
40
- }
41
- /**
42
- * Parse the given command line arguments into a corresponding options object.
43
- */
44
- static parseArguments() {
45
- const parser = this.buildParser();
46
- return parser.parse_args();
47
- }
48
- /**
49
- * Construct the logger.
50
- */
51
- static buildLogger(config) {
52
- return winston_1.default.createLogger({
53
- level: config.log_level,
54
- format: winston_1.default.format.json(),
55
- defaultMeta: {},
56
- transports: [
57
- new winston_1.default.transports.File({ filename: 'logs/collector-error.log', level: 'error' }),
58
- new winston_1.default.transports.File({ filename: config.log_to_file.trim() }),
59
- new winston_1.default.transports.Console({ format: winston_1.default.format.simple(), level: config.log_level })
60
- ]
61
- });
62
- }
63
- /**
64
- * Entry point of the Teamscale JavaScript Profiler.
65
- */
66
- static run() {
67
- // Parse the command line arguments
68
- const config = this.parseArguments();
69
- // Build the logger
70
- const logger = this.buildLogger(config);
71
- logger.info(`Starting collector in working directory "${process.cwd()}".`);
72
- logger.info(`Logging "${config.log_level}" to "${config.log_to_file}".`);
73
- // Prepare the storage and the server
74
- const storage = new DataStorage_1.DataStorage(logger);
75
- const server = new CollectingServer_1.WebSocketCollectingServer(config.port, storage, logger);
76
- // Start the server socket.
77
- // ATTENTION: The server is executed asynchronously
78
- server.start();
79
- // Optionally, start a timer that dumps the coverage after a N seconds
80
- this.maybeStartDumpTimer(config, storage, logger);
81
- // Say bye bye on CTRL+C and exit the process
82
- process.on('SIGINT', () => {
83
- logger.info('Bye bye.');
84
- process.exit();
85
- });
86
- }
87
- /**
88
- * Start a timer for dumping the data, depending on the configuration.
89
- *
90
- * @param config - The config that determines whether or not to do the timed dump.
91
- * @param storage - The storage with the information to dump.
92
- * @param logger - The logger to use.
93
- */
94
- static maybeStartDumpTimer(config, storage, logger) {
95
- if (config.dump_after_mins > 0) {
96
- const timer = setInterval(() => {
97
- try {
98
- const lines = storage.dumpToSimpleCoverageFile(config.dump_to_file);
99
- logger.info(`Conducted periodic coverage dump with ${lines} lines to ${config.dump_to_file}.`);
100
- }
101
- catch (e) {
102
- logger.error('Timed coverage dump failed.', e);
103
- }
104
- }, config.dump_after_mins * 1000 * 60);
105
- process.on('SIGINT', () => {
106
- // Stop the timed file dump
107
- if (timer) {
108
- clearInterval(timer);
109
- }
110
- // ... and do a final dump
111
- const written = storage.dumpToSimpleCoverageFile(config.dump_to_file);
112
- logger.info(`\nCaught interrupt signal. Written ${written} lines of the latest coverage.`);
113
- });
114
- }
115
- }
116
- }
117
- exports.Main = Main;
118
- Main.run();
4
+ const App_1 = require("./App");
5
+ App_1.App.run();
@@ -1,5 +1,5 @@
1
1
  import { IDataStorage } from '../storage/DataStorage';
2
- import { Logger } from 'winston';
2
+ import Logger from 'bunyan';
3
3
  /**
4
4
  * Various constants that are used to exchange data between
5
5
  * the instrumented application and the coverage collector.
@@ -18,7 +18,7 @@ export declare class WebSocketCollectingServer {
18
18
  /**
19
19
  * The WebSocket server component.
20
20
  */
21
- private readonly server;
21
+ private server;
22
22
  /**
23
23
  * The storage to put the received coverage information to for aggregation and further processing.
24
24
  */
@@ -38,7 +38,9 @@ export declare class WebSocketCollectingServer {
38
38
  /**
39
39
  * Start the server socket, handle sessions and dispatch messages.
40
40
  */
41
- start(): void;
41
+ start(): {
42
+ stop: () => void;
43
+ };
42
44
  /**
43
45
  * Handle a message from a client.
44
46
  *
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -33,7 +37,7 @@ var ProtocolMessageTypes;
33
37
  ProtocolMessageTypes["TYPE_SOURCEMAP"] = "s";
34
38
  /** A message that provides coverage information */
35
39
  ProtocolMessageTypes["TYPE_COVERAGE"] = "c";
36
- })(ProtocolMessageTypes = exports.ProtocolMessageTypes || (exports.ProtocolMessageTypes = {}));
40
+ })(ProtocolMessageTypes || (exports.ProtocolMessageTypes = ProtocolMessageTypes = {}));
37
41
  /**
38
42
  * Separates the instrumentation subject from the coverage information.
39
43
  */
@@ -54,15 +58,16 @@ class WebSocketCollectingServer {
54
58
  commons_1.Contract.require(port > 0 && port < 65536, 'Port must be valid (range).');
55
59
  this.storage = commons_1.Contract.requireDefined(storage);
56
60
  this.logger = commons_1.Contract.requireDefined(logger);
57
- this.server = new WebSocket.Server({ port: port });
61
+ this.server = new WebSocket.Server({ port });
58
62
  }
59
63
  /**
60
64
  * Start the server socket, handle sessions and dispatch messages.
61
65
  */
62
66
  start() {
63
- this.logger.info(`Starting server on port ${this.server.options.port}.`);
67
+ var _a, _b;
68
+ this.logger.info(`Starting server on port ${(_a = this.server) === null || _a === void 0 ? void 0 : _a.options.port}.`);
64
69
  // Handle new connections from clients
65
- this.server.on('connection', (webSocket, req) => {
70
+ (_b = this.server) === null || _b === void 0 ? void 0 : _b.on('connection', (webSocket, req) => {
66
71
  let session = new Session_1.Session(req.socket, this.storage, this.logger);
67
72
  this.logger.debug(`Connection from: ${req.socket.remoteAddress}`);
68
73
  // Handle disconnecting clients
@@ -76,8 +81,8 @@ class WebSocketCollectingServer {
76
81
  });
77
82
  // Handle incoming messages
78
83
  webSocket.on('message', (message) => {
79
- if (session && typeof message === 'string') {
80
- this.handleMessage(session, message);
84
+ if (session && Buffer.isBuffer(message)) {
85
+ void this.handleMessage(session, message);
81
86
  }
82
87
  });
83
88
  // Handle errors
@@ -85,6 +90,13 @@ class WebSocketCollectingServer {
85
90
  this.logger.error('Error on server socket triggered.', e);
86
91
  });
87
92
  });
93
+ return {
94
+ stop: () => {
95
+ var _a;
96
+ (_a = this.server) === null || _a === void 0 ? void 0 : _a.close();
97
+ this.server = null;
98
+ }
99
+ };
88
100
  }
89
101
  /**
90
102
  * Handle a message from a client.
@@ -92,17 +104,18 @@ class WebSocketCollectingServer {
92
104
  * @param session - The session that has been started for the client.
93
105
  * @param message - The message to handle.
94
106
  */
95
- handleMessage(session, message) {
107
+ async handleMessage(session, message) {
96
108
  try {
97
- if (message.startsWith(ProtocolMessageTypes.TYPE_SOURCEMAP)) {
98
- this.handleSourcemapMessage(session, message.substring(1));
109
+ const messageType = message.toString('utf8', 0, 1);
110
+ if (messageType.startsWith(ProtocolMessageTypes.TYPE_SOURCEMAP)) {
111
+ await this.handleSourcemapMessage(session, message.subarray(1));
99
112
  }
100
- else if (message.startsWith(ProtocolMessageTypes.TYPE_COVERAGE)) {
101
- this.handleCoverageMessage(session, message.substring(1));
113
+ else if (messageType.startsWith(ProtocolMessageTypes.TYPE_COVERAGE)) {
114
+ await this.handleCoverageMessage(session, message.subarray(1));
102
115
  }
103
116
  }
104
117
  catch (e) {
105
- this.logger.error(`Error while processing message starting with ${message.substring(0, Math.min(50, message.length))}`);
118
+ this.logger.error(`Error while processing message starting with ${message.toString('utf8', 0, Math.min(50, message.length))}`);
106
119
  this.logger.error(e.message);
107
120
  }
108
121
  }
@@ -112,13 +125,13 @@ class WebSocketCollectingServer {
112
125
  * @param session - The session to handle the message for.
113
126
  * @param body - The body of the message (to be parsed).
114
127
  */
115
- handleSourcemapMessage(session, body) {
116
- const fileIdSeparatorPosition = body.indexOf(INSTRUMENTATION_SUBJECT_SEPARATOR);
128
+ async handleSourcemapMessage(session, body) {
129
+ const fileIdSeparatorPosition = body.indexOf(INSTRUMENTATION_SUBJECT_SEPARATOR.charCodeAt(0));
117
130
  if (fileIdSeparatorPosition > -1) {
118
- const fileId = body.substring(0, fileIdSeparatorPosition).trim();
131
+ const fileId = body.toString('utf8', 0, fileIdSeparatorPosition).trim();
119
132
  this.logger.debug(`Received source map information for ${fileId}`);
120
- const sourcemap = body.substring(fileIdSeparatorPosition + 1);
121
- session.putSourcemap(fileId, sourcemap);
133
+ const sourcemap = body.subarray(fileIdSeparatorPosition + 1);
134
+ await session.putSourcemap(fileId, sourcemap);
122
135
  }
123
136
  }
124
137
  /**
@@ -127,16 +140,21 @@ class WebSocketCollectingServer {
127
140
  * @param session - The session to handle the message for.
128
141
  * @param body - The body of the message (to be parsed).
129
142
  */
130
- handleCoverageMessage(session, body) {
143
+ async handleCoverageMessage(session, body) {
131
144
  var _a;
132
- const bodyPattern = /(?<fileId>\S+) (?<positions>((\d+:\d+)\s+)*(\d+:\d+))/;
133
- const matches = bodyPattern.exec(body);
145
+ const bodyPattern = /(?<fileId>\S+) (?<positions>((\d+:\d+(:\d+:\d+)?\s+)*(\d+:\d+(:\d+:\d+)?)))/;
146
+ const matches = bodyPattern.exec(body.toString());
134
147
  if (matches === null || matches === void 0 ? void 0 : matches.groups) {
135
148
  const fileId = matches.groups.fileId;
136
149
  const positions = ((_a = matches.groups.positions) !== null && _a !== void 0 ? _a : '').split(/\s+/);
137
150
  for (const position of positions) {
138
- const [line, column] = position.split(':');
139
- session.putCoverage(fileId, Number.parseInt(line), Number.parseInt(column));
151
+ const positionParts = position.split(':');
152
+ if (positionParts.length === 2) {
153
+ session.putCoverage(fileId, Number.parseInt(positionParts[0]), Number.parseInt(positionParts[1]), Number.parseInt(positionParts[1]), Number.parseInt(positionParts[2]));
154
+ }
155
+ else if (positionParts.length === 4) {
156
+ session.putCoverage(fileId, Number.parseInt(positionParts[0]), Number.parseInt(positionParts[1]), Number.parseInt(positionParts[2]), Number.parseInt(positionParts[3]));
157
+ }
140
158
  }
141
159
  }
142
160
  }
@@ -1,7 +1,19 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { Socket } from 'net';
3
4
  import { IDataStorage } from '../storage/DataStorage';
4
- import { Logger } from 'winston';
5
+ import Logger from 'bunyan';
6
+ /**
7
+ * Coverage information that has not been mapped back to the
8
+ * original code using a source map.
9
+ */
10
+ export type UnmappedCoverage = {
11
+ fileId: string;
12
+ startLine: number;
13
+ startColumn: number;
14
+ endLine: number;
15
+ endColumn: number;
16
+ };
5
17
  /**
6
18
  * The session maintains the relevant information for a client.
7
19
  * One session is created for each client.
@@ -22,6 +34,10 @@ export declare class Session {
22
34
  * server per browser window.
23
35
  */
24
36
  private readonly sourceMaps;
37
+ /**
38
+ * Unmapped coverage information.
39
+ */
40
+ private readonly unmappedCoverage;
25
41
  /**
26
42
  * The logger to use.
27
43
  */
@@ -43,10 +59,12 @@ export declare class Session {
43
59
  * This method also conducts the mapping based on the source map.
44
60
  *
45
61
  * @param fileId - The identifier of the instrumented bundle (file).
46
- * @param line - The line number within the bundle.
47
- * @param column - The column within the bundle.
62
+ * @param startLine - The line number within the bundle the range starts.
63
+ * @param startColumn - The column in the given `startLine` on that the range starts (inclusive).
64
+ * @param endLine - The line number within the bundle the range ends.
65
+ * @param endColumn - The column in the given `startLine` on that the range ends (inclusive).
48
66
  */
49
- putCoverage(fileId: string, line: number, column: number): void;
67
+ putCoverage(fileId: string, startLine: number, startColumn: number, endLine: number, endColumn: number): boolean;
50
68
  /**
51
69
  * Map to the original file position.
52
70
  *
@@ -61,7 +79,8 @@ export declare class Session {
61
79
  * @param fileId - The identifier of the file bundle.
62
80
  * @param sourceMapText - The actual source map.
63
81
  */
64
- putSourcemap(fileId: string, sourceMapText: string): void;
82
+ putSourcemap(fileId: string, sourceMapText: Buffer): Promise<void>;
83
+ private processUnmappedCoverageOf;
65
84
  /**
66
85
  * Destroy the session and free the memory it allocates.
67
86
  * In particular the sourcemaps are freed (important to not run out of memory!).
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -40,6 +44,7 @@ class Session {
40
44
  this.storage = commons_1.Contract.requireDefined(storage);
41
45
  this.logger = commons_1.Contract.requireDefined(logger);
42
46
  this.sourceMaps = new Map();
47
+ this.unmappedCoverage = new Map();
43
48
  this.projectId = ''; // We currently only support coverage for one project.
44
49
  }
45
50
  /**
@@ -47,17 +52,66 @@ class Session {
47
52
  * This method also conducts the mapping based on the source map.
48
53
  *
49
54
  * @param fileId - The identifier of the instrumented bundle (file).
50
- * @param line - The line number within the bundle.
51
- * @param column - The column within the bundle.
55
+ * @param startLine - The line number within the bundle the range starts.
56
+ * @param startColumn - The column in the given `startLine` on that the range starts (inclusive).
57
+ * @param endLine - The line number within the bundle the range ends.
58
+ * @param endColumn - The column in the given `startLine` on that the range ends (inclusive).
52
59
  */
53
- putCoverage(fileId, line, column) {
54
- const originalPosition = this.mapToOriginal(fileId, line, column);
55
- if (originalPosition.line && originalPosition.source) {
56
- this.storage.putCoverage(this.projectId, originalPosition.source, [originalPosition.line]);
60
+ putCoverage(fileId, startLine, startColumn, endLine, endColumn) {
61
+ var _a, _b;
62
+ // Delay the mapping if the sourcemap has not yet arrived
63
+ if (!this.sourceMaps.has(fileId)) {
64
+ let unmappedForFile = this.unmappedCoverage.get(fileId);
65
+ if (!unmappedForFile) {
66
+ unmappedForFile = [];
67
+ this.unmappedCoverage.set(fileId, unmappedForFile);
68
+ }
69
+ unmappedForFile.push({ endColumn, endLine, fileId, startColumn, startLine });
70
+ return false;
57
71
  }
58
- else {
59
- this.storage.signalUnmappedCoverage(this.projectId);
72
+ let mapped = false;
73
+ // Iterate over the lines to scan
74
+ let line = startLine;
75
+ while (line <= endLine) {
76
+ // Determine the column range to consider for this line
77
+ let scanFromColumn;
78
+ if (line === startLine) {
79
+ scanFromColumn = startColumn;
80
+ }
81
+ else {
82
+ scanFromColumn = 0;
83
+ }
84
+ let scanToColumn;
85
+ if (line === endLine) {
86
+ scanToColumn = endColumn;
87
+ }
88
+ else {
89
+ // Since we do not know the length of the different lines, we assume
90
+ // all to end in the lager of `endColumn` and `startColumn`.
91
+ // A better estimate (or the correct value) is supposed to be implemented
92
+ // in context of TS-30077.
93
+ scanToColumn = Math.max(endColumn, startColumn);
94
+ }
95
+ let column = scanFromColumn;
96
+ let lastCoveredLine = -1;
97
+ while (column <= scanToColumn) {
98
+ const originalPosition = this.mapToOriginal(fileId, line, column);
99
+ if (originalPosition.line && originalPosition.source) {
100
+ if (lastCoveredLine !== originalPosition.line) {
101
+ this.storage.putCoverage(this.projectId, originalPosition.source, [originalPosition.line]);
102
+ mapped = true;
103
+ lastCoveredLine = originalPosition.line;
104
+ }
105
+ }
106
+ // Step to the next column to map back to the original.
107
+ // `originalPosition.name` is the token on the position, that is, if it is present
108
+ // we increment the column by its length.
109
+ column = column + Math.max(1, (_b = (_a = originalPosition.name) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 1);
110
+ }
111
+ // And the next line
112
+ line++;
60
113
  }
114
+ return mapped;
61
115
  }
62
116
  /**
63
117
  * Map to the original file position.
@@ -82,14 +136,24 @@ class Session {
82
136
  * @param fileId - The identifier of the file bundle.
83
137
  * @param sourceMapText - The actual source map.
84
138
  */
85
- putSourcemap(fileId, sourceMapText) {
86
- const rawSourceMap = JSON.parse(sourceMapText);
87
- new sourceMap.SourceMapConsumer(rawSourceMap)
88
- .then(consumer => {
89
- this.sourceMaps.set(fileId, consumer);
90
- })
91
- .catch(e => {
139
+ async putSourcemap(fileId, sourceMapText) {
140
+ const rawSourceMap = JSON.parse(sourceMapText.toString());
141
+ try {
142
+ const sourceMapConsumer = await new sourceMap.SourceMapConsumer(rawSourceMap);
143
+ this.sourceMaps.set(fileId, sourceMapConsumer);
144
+ this.processUnmappedCoverageOf(fileId);
145
+ }
146
+ catch (e) {
92
147
  this.logger.error(`Consuming source map failed! ${e}`);
148
+ }
149
+ }
150
+ processUnmappedCoverageOf(fileId) {
151
+ var _a;
152
+ const unmapped = (_a = this.unmappedCoverage.get(fileId)) !== null && _a !== void 0 ? _a : [];
153
+ unmapped.forEach(entry => {
154
+ if (!this.putCoverage(entry.fileId, entry.startLine, entry.startColumn, entry.endLine, entry.endColumn)) {
155
+ this.storage.signalUnmappedCoverage(this.projectId);
156
+ }
93
157
  });
94
158
  }
95
159
  /**
@@ -1,8 +1,8 @@
1
- import { Logger } from 'winston';
1
+ import Logger from 'bunyan';
2
2
  /**
3
3
  * Lines covered for the specified file.
4
4
  */
5
- export declare type FileCoverage = {
5
+ export type FileCoverage = {
6
6
  /** Name of the file in the origin */
7
7
  sourceFile: string;
8
8
  /** Lines covered */
@@ -21,11 +21,14 @@ export interface IReadableStorage {
21
21
  */
22
22
  getCoverageBySourceFile(project: string): IterableIterator<FileCoverage> | undefined;
23
23
  /**
24
- * Write the coverage to the specified file.
24
+ * Write the coverage to the specified file. A timestamp will be appended to the provided file path.
25
25
  *
26
- * @param filePath - Full path of the file to write the coverage to.
26
+ * @param coverageFolder - Full path of the file to write the coverage to.
27
+ * @param date - Date to use for the appended timestamp
28
+ *
29
+ * @return The number of lines written
27
30
  */
28
- dumpToSimpleCoverageFile(filePath: string): void;
31
+ dumpToSimpleCoverageFile(coverageFolder: string, date: Date): [string, number];
29
32
  }
30
33
  /**
31
34
  * Storage interface for writing information.
@@ -46,6 +49,10 @@ export interface IWriteableStorage {
46
49
  * @param project - The project to add the information to.
47
50
  */
48
51
  signalUnmappedCoverage(project: string): void;
52
+ /**
53
+ * Discard the coverage information that has been collected up to this point.
54
+ */
55
+ discardCollectedCoverage(): void;
49
56
  }
50
57
  /**
51
58
  * Union of write and read interface.
@@ -89,7 +96,7 @@ export declare class DataStorage implements IDataStorage {
89
96
  /**
90
97
  * Coverage information by project.
91
98
  */
92
- private readonly coverageByProject;
99
+ private coverageByProject;
93
100
  /**
94
101
  * Logger to use.
95
102
  */
@@ -98,6 +105,10 @@ export declare class DataStorage implements IDataStorage {
98
105
  * Times unmapped coverage received.
99
106
  */
100
107
  private timesUnmappedCoverage;
108
+ /**
109
+ * Date format for the timestamp appended to the coverage files
110
+ */
111
+ readonly DATE_FORMAT = "YYYY-MM-DD-HH-mm-ss.SSS";
101
112
  /**
102
113
  * Constructs the data storage.
103
114
  *
@@ -118,7 +129,7 @@ export declare class DataStorage implements IDataStorage {
118
129
  *
119
130
  * @param sourceFile - The file name to normalize, produced by the instrumenter.
120
131
  */
121
- private normalizeSourceFileName;
132
+ private static normalizeSourceFileName;
122
133
  /**
123
134
  * {@inheritDoc IWriteableStorage.signalUnmappedCoverage}
124
135
  */
@@ -128,11 +139,31 @@ export declare class DataStorage implements IDataStorage {
128
139
  */
129
140
  getCoverageBySourceFile(project: string): IterableIterator<FileCoverage> | undefined;
130
141
  /**
131
- * {@inheritDoc IReadableStorage.writeToSimpleCoverageFile}
142
+ * @inheritDoc
143
+ */
144
+ dumpToSimpleCoverageFile(coverageFolder: string, date: Date): [string, number];
145
+ /**
146
+ * Set the collected coverage to 0 for all projects
147
+ * @private
132
148
  */
133
- dumpToSimpleCoverageFile(filePath: string): number;
149
+ private resetCoverage;
150
+ /**
151
+ * Appends the timestamp given with date to the coverageFolder (before the file ending if there is one)
152
+ * @param coverageFolder Path to the coverage file
153
+ * @param date Represents the timestamp to be appended with the format {@link DataStorage.DATE_FORMAT}
154
+ * @private
155
+ */
156
+ private initCoverageFile;
157
+ /**
158
+ * Generate simple coverage format for the collected coverage
159
+ */
160
+ private toSimpleCoverage;
134
161
  /**
135
162
  * {@inheritDoc IReadableStorage.getProjects}
136
163
  */
137
164
  getProjects(): string[];
165
+ /**
166
+ * {@inheritDoc IWritableStorage.discardCollectedCoverage}
167
+ */
168
+ discardCollectedCoverage(): void;
138
169
  }