1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | var fs = require('fs-extra');
|
11 | var istanbul = require('istanbul');
|
12 | var path = require('path');
|
13 | var glob = require('glob');
|
14 |
|
15 | var runTestsuite = require('./test').runTests;
|
16 |
|
17 |
|
18 | var dir = path.join(__dirname, '../src');
|
19 | var backupDir = path.join(__dirname, '../src-backup');
|
20 | var instrumentedDir = path.join(__dirname, '../src-instrumented');
|
21 | var coverageDir = path.join(__dirname, '../coverage');
|
22 |
|
23 | fs.mkdirSync(coverageDir);
|
24 |
|
25 |
|
26 | var instrumenter = new istanbul.Instrumenter();
|
27 | var reporter = new istanbul.Reporter(false, coverageDir);
|
28 | var collector = new istanbul.Collector();
|
29 |
|
30 |
|
31 | var copyOpts = {
|
32 |
|
33 | clobber: true,
|
34 |
|
35 | preserveTimestamps: true
|
36 | };
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 | var log = function(msg) {
|
43 | process.stdout.write(msg + '\n');
|
44 | };
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 | var setupBackupAndInstrumentationDir = function() {
|
51 | if (!fs.existsSync(backupDir)) {
|
52 | log('• create directory for backup of src: ' + backupDir);
|
53 | fs.mkdirSync(backupDir);
|
54 | }
|
55 |
|
56 | if (!fs.existsSync(instrumentedDir)) {
|
57 | log('• create directory for instrumented src: ' + instrumentedDir);
|
58 | fs.mkdirSync(instrumentedDir);
|
59 | }
|
60 |
|
61 | log('• copy src files to backup folder');
|
62 | fs.copySync(dir, backupDir, copyOpts);
|
63 | log('• copy src files to instrumentation folder');
|
64 | fs.copySync(dir, instrumentedDir, copyOpts);
|
65 | };
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 | var revertBackupAndInstrumentationDir = function() {
|
73 | log('• copy original src back to src folder');
|
74 | fs.copySync(backupDir, dir, copyOpts);
|
75 | log('• delete backup directory');
|
76 | fs.removeSync(backupDir);
|
77 | log('• delete instrumentation directory');
|
78 | fs.removeSync(instrumentedDir);
|
79 | };
|
80 |
|
81 |
|
82 |
|
83 |
|
84 | var collectAndWriteCoverageData = function() {
|
85 | log('• collect data from coverage *.json files');
|
86 |
|
87 | var coverageFiles = [
|
88 | path.join(__dirname, '..', 'coverage', 'coverage.json'),
|
89 | path.join(__dirname, '..', 'coverage', 'coverage-rendering.json')
|
90 | ];
|
91 | coverageFiles.forEach(function(coverageFile) {
|
92 | if (fs.existsSync(coverageFile)) {
|
93 | log(' • collect data from ' + path.basename(coverageFile));
|
94 | var coverageJson = JSON.parse(fs.readFileSync(coverageFile, 'utf8'));
|
95 | collector.add(coverageJson);
|
96 | }
|
97 | });
|
98 |
|
99 | reporter.addAll(['lcovonly', 'html']);
|
100 |
|
101 | revertBackupAndInstrumentationDir();
|
102 |
|
103 | log('• write report from collected data');
|
104 | reporter.write(collector, true, function() {
|
105 | process.exit(0);
|
106 | });
|
107 | };
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 | var runRenderingTestsuite = function(callback) {
|
118 | var spawn = require('child_process').spawn;
|
119 | var child = spawn('make', ['test-rendering'], {stdio: 'inherit'});
|
120 | child.on('exit', function(code) {
|
121 | callback(code);
|
122 | });
|
123 | };
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 | var outputFilenameByFilename = function(file) {
|
133 | var search = '/src/';
|
134 | var replace = '/src-instrumented/';
|
135 | var re = new RegExp(search, 'g');
|
136 | var m, match;
|
137 | while ((m = re.exec(file)) !== null) {
|
138 | match = m;
|
139 | }
|
140 | var idx = match.index;
|
141 | var outfile = file.substr(0, idx) + replace +
|
142 | file.substr(idx + search.length);
|
143 |
|
144 | return outfile;
|
145 | };
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 | var foundAllJavaScriptSourceFiles = function(err, files) {
|
154 | if (err) {
|
155 | process.stderr.write(err.message + '\n');
|
156 | process.exit(1);
|
157 | }
|
158 | log('• instrumenting every src file');
|
159 | var cnt = 0;
|
160 | files.forEach(function(file) {
|
161 | cnt++;
|
162 | var content = fs.readFileSync(file, 'utf-8');
|
163 | var outfile = outputFilenameByFilename(file);
|
164 | var instrumented = instrumenter.instrumentSync(content, file);
|
165 | fs.writeFileSync(outfile, instrumented);
|
166 | if (cnt % 10 === 0) {
|
167 | log(' • instrumented ' + cnt + ' files');
|
168 | }
|
169 | });
|
170 | log(' • done. ' + cnt + ' files instrumented');
|
171 | log('• copy instrumented src back to src folder');
|
172 |
|
173 | fs.copySync(instrumentedDir, dir, copyOpts);
|
174 |
|
175 | log('• run test suites on instrumented code');
|
176 |
|
177 | log(' • run rendering test suite');
|
178 | runRenderingTestsuite(function(codeRendering) {
|
179 | if (codeRendering === 0) {
|
180 | log(' • run standard test suite');
|
181 | runTestsuite({coverage: true, reporter: 'dot'}, function(code) {
|
182 | if (code === 0) {
|
183 | collectAndWriteCoverageData();
|
184 | } else {
|
185 | process.stderr.write('Trouble running the standard testsuite\n');
|
186 | process.exit(1);
|
187 | }
|
188 | });
|
189 | } else {
|
190 | process.stderr.write('Trouble running the rendering testsuite\n');
|
191 | process.exit(1);
|
192 | }
|
193 | });
|
194 | };
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 | var main = function() {
|
202 | setupBackupAndInstrumentationDir();
|
203 | glob(dir + '/**/*.js', {}, foundAllJavaScriptSourceFiles);
|
204 | };
|
205 |
|
206 | if (require.main === module) {
|
207 | main();
|
208 | }
|
209 |
|
210 | module.exports = main;
|