source: frontend/node_modules/istanbul-lib-instrument/src/instrumenter.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*
2 Copyright 2012-2015, Yahoo Inc.
3 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
4 */
5const { transformSync } = require('@babel/core');
6const { defaults } = require('@istanbuljs/schema');
7const programVisitor = require('./visitor');
8const readInitialCoverage = require('./read-coverage');
9
10/**
11 * Instrumenter is the public API for the instrument library.
12 * It is typically used for ES5 code. For ES6 code that you
13 * are already running under `babel` use the coverage plugin
14 * instead.
15 * @param {Object} opts optional.
16 * @param {string} [opts.coverageVariable=__coverage__] name of global coverage variable.
17 * @param {boolean} [opts.reportLogic=false] report boolean value of logical expressions.
18 * @param {boolean} [opts.preserveComments=false] preserve comments in output.
19 * @param {boolean} [opts.compact=true] generate compact code.
20 * @param {boolean} [opts.esModules=false] set to true to instrument ES6 modules.
21 * @param {boolean} [opts.autoWrap=false] set to true to allow `return` statements outside of functions.
22 * @param {boolean} [opts.produceSourceMap=false] set to true to produce a source map for the instrumented code.
23 * @param {Array} [opts.ignoreClassMethods=[]] set to array of class method names to ignore for coverage.
24 * @param {Function} [opts.sourceMapUrlCallback=null] a callback function that is called when a source map URL
25 * is found in the original code. This function is called with the source file name and the source map URL.
26 * @param {boolean} [opts.debug=false] - turn debugging on.
27 * @param {array} [opts.parserPlugins] - set babel parser plugins, see @istanbuljs/schema for defaults.
28 * @param {string} [opts.coverageGlobalScope=this] the global coverage variable scope.
29 * @param {boolean} [opts.coverageGlobalScopeFunc=true] use an evaluated function to find coverageGlobalScope.
30 */
31class Instrumenter {
32 constructor(opts = {}) {
33 this.opts = {
34 ...defaults.instrumenter,
35 ...opts
36 };
37 this.fileCoverage = null;
38 this.sourceMap = null;
39 }
40 /**
41 * instrument the supplied code and track coverage against the supplied
42 * filename. It throws if invalid code is passed to it. ES5 and ES6 syntax
43 * is supported. To instrument ES6 modules, make sure that you set the
44 * `esModules` property to `true` when creating the instrumenter.
45 *
46 * @param {string} code - the code to instrument
47 * @param {string} filename - the filename against which to track coverage.
48 * @param {object} [inputSourceMap] - the source map that maps the not instrumented code back to it's original form.
49 * Is assigned to the coverage object and therefore, is available in the json output and can be used to remap the
50 * coverage to the untranspiled source.
51 * @returns {string} the instrumented code.
52 */
53 instrumentSync(code, filename, inputSourceMap) {
54 if (typeof code !== 'string') {
55 throw new Error('Code must be a string');
56 }
57 filename = filename || String(new Date().getTime()) + '.js';
58 const { opts } = this;
59 let output = {};
60 const babelOpts = {
61 configFile: false,
62 babelrc: false,
63 ast: true,
64 filename: filename || String(new Date().getTime()) + '.js',
65 inputSourceMap,
66 sourceMaps: opts.produceSourceMap,
67 compact: opts.compact,
68 comments: opts.preserveComments,
69 parserOpts: {
70 allowReturnOutsideFunction: opts.autoWrap,
71 sourceType: opts.esModules ? 'module' : 'script',
72 plugins: opts.parserPlugins
73 },
74 plugins: [
75 [
76 ({ types }) => {
77 const ee = programVisitor(types, filename, {
78 coverageVariable: opts.coverageVariable,
79 reportLogic: opts.reportLogic,
80 coverageGlobalScope: opts.coverageGlobalScope,
81 coverageGlobalScopeFunc:
82 opts.coverageGlobalScopeFunc,
83 ignoreClassMethods: opts.ignoreClassMethods,
84 inputSourceMap
85 });
86
87 return {
88 visitor: {
89 Program: {
90 enter: ee.enter,
91 exit(path) {
92 output = ee.exit(path);
93 }
94 }
95 }
96 };
97 }
98 ]
99 ]
100 };
101
102 const codeMap = transformSync(code, babelOpts);
103
104 if (!output || !output.fileCoverage) {
105 const initialCoverage =
106 readInitialCoverage(codeMap.ast) ||
107 /* istanbul ignore next: paranoid check */ {};
108 this.fileCoverage = initialCoverage.coverageData;
109 this.sourceMap = inputSourceMap;
110 return code;
111 }
112
113 this.fileCoverage = output.fileCoverage;
114 this.sourceMap = codeMap.map;
115 const cb = this.opts.sourceMapUrlCallback;
116 if (cb && output.sourceMappingURL) {
117 cb(filename, output.sourceMappingURL);
118 }
119
120 return codeMap.code;
121 }
122 /**
123 * callback-style instrument method that calls back with an error
124 * as opposed to throwing one. Note that in the current implementation,
125 * the callback will be called in the same process tick and is not asynchronous.
126 *
127 * @param {string} code - the code to instrument
128 * @param {string} filename - the filename against which to track coverage.
129 * @param {Function} callback - the callback
130 * @param {Object} inputSourceMap - the source map that maps the not instrumented code back to it's original form.
131 * Is assigned to the coverage object and therefore, is available in the json output and can be used to remap the
132 * coverage to the untranspiled source.
133 */
134 instrument(code, filename, callback, inputSourceMap) {
135 if (!callback && typeof filename === 'function') {
136 callback = filename;
137 filename = null;
138 }
139 try {
140 const out = this.instrumentSync(code, filename, inputSourceMap);
141 callback(null, out);
142 } catch (ex) {
143 callback(ex);
144 }
145 }
146 /**
147 * returns the file coverage object for the last file instrumented.
148 * @returns {Object} the file coverage object.
149 */
150 lastFileCoverage() {
151 return this.fileCoverage;
152 }
153 /**
154 * returns the source map produced for the last file instrumented.
155 * @returns {null|Object} the source map object.
156 */
157 lastSourceMap() {
158 return this.sourceMap;
159 }
160}
161
162module.exports = Instrumenter;
Note: See TracBrowser for help on using the repository browser.