/[jscoverage]/trunk/jscoverage.jsm
ViewVC logotype

Contents of /trunk/jscoverage.jsm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 441 - (show annotations)
Tue Jul 14 16:14:24 2009 UTC (9 years, 5 months ago) by siliconforks
File size: 8157 byte(s)
Store report in directory containing the firefox executable instead of the current directory.
1 /*
2 jscoverage.jsm - Firefox module
3 Copyright (C) 2008, 2009 siliconforks.com
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 var EXPORTED_SYMBOLS = ['_$jscoverage'];
21
22 var _$jscoverage = {};
23
24 function jscoverage_pad(s) {
25 return '0000'.substr(s.length) + s;
26 }
27
28 function jscoverage_quote(s) {
29 return '"' + s.replace(/[\u0000-\u001f"\\\u007f-\uffff]/g, function (c) {
30 switch (c) {
31 case '\b':
32 return '\\b';
33 case '\f':
34 return '\\f';
35 case '\n':
36 return '\\n';
37 case '\r':
38 return '\\r';
39 case '\t':
40 return '\\t';
41 case '\v':
42 return '\\v';
43 case '"':
44 return '\\"';
45 case '\\':
46 return '\\\\';
47 default:
48 return '\\u' + jscoverage_pad(c.charCodeAt(0).toString(16));
49 }
50 }) + '"';
51 }
52
53 var JSCoverageUtils = {
54 QueryInterface: function (aIID) {
55 if (! aIID.equals(nsIObserver) && ! aIID.equals(nsISupports)) {
56 throw Components.results.NS_ERROR_NO_INTERFACE;
57 }
58 return this;
59 },
60
61 getReportDirectory: function() {
62 const Cc = Components.classes;
63 const Ci = Components.interfaces;
64
65 var directoryService = Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties);
66 /*
67 CurProcD - directory in which the firefox process was started
68 CurWorkD - current working directory
69 Home - home directory
70 TmpD - temp directory
71 See xpcom/io/nsDirectoryServiceDefs.h
72 */
73 var reportDirectory = directoryService.get('CurProcD', Ci.nsILocalFile);
74 reportDirectory.appendRelativePath('jscoverage-report');
75 return reportDirectory;
76 },
77
78 readExistingCoverage: function() {
79 try {
80 const Cc = Components.classes;
81 const Ci = Components.interfaces;
82
83 var reportDirectory = this.getReportDirectory();
84 if (! reportDirectory.exists()) {
85 return;
86 }
87 var jsonFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
88 jsonFile.initWithFile(reportDirectory);
89 jsonFile.appendRelativePath('jscoverage.json');
90 if (! jsonFile.exists()) {
91 return;
92 }
93 var fileInputStream = Cc['@mozilla.org/network/file-input-stream;1'].createInstance(Ci.nsIFileInputStream);
94 var json = null;
95 try {
96 fileInputStream.init(jsonFile, 1, 0, 0);
97 var scriptableInputStream = Cc['@mozilla.org/scriptableinputstream;1'].createInstance(Ci.nsIScriptableInputStream);
98 scriptableInputStream.init(fileInputStream);
99 try {
100 json = scriptableInputStream.read(-1);
101 }
102 finally {
103 scriptableInputStream.close();
104 }
105 }
106 finally {
107 fileInputStream.close();
108 }
109 var coverage = eval('(' + json + ')');
110 for (var file in coverage) {
111 _$jscoverage[file] = coverage[file].coverage;
112 _$jscoverage[file].source = coverage[file].source;
113 }
114 }
115 catch (e) {
116 dump('jscoverage.jsm: error reading existing coverage report\n');
117 dump(e);
118 dump('\n');
119 }
120 },
121
122 observe: function (aSubject, aTopic, aData) {
123 try {
124 dump('jscoverage.jsm: storing coverage data ...\n');
125
126 const Cc = Components.classes;
127 const Ci = Components.interfaces;
128
129 var reportDirectory = this.getReportDirectory();
130 if (! reportDirectory.exists()) {
131 reportDirectory.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
132 }
133
134 var ioService = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
135 var copyChrome = function(filename) {
136 var channel = ioService.newChannel('chrome://jscoverage/content/' + filename, null, null);
137 var binaryInputStream = Cc['@mozilla.org/binaryinputstream;1'].createInstance(Ci.nsIBinaryInputStream);
138 try {
139 binaryInputStream.setInputStream(channel.open());
140
141 var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
142 file.initWithFile(reportDirectory);
143 file.appendRelativePath(filename);
144 var fileOutputStream = Cc['@mozilla.org/network/file-output-stream;1'].createInstance(Ci.nsIFileOutputStream);
145 fileOutputStream.init(file, 0x02 | 0x08 | 0x20, 0644, 0);
146 var binaryOutputStream = Cc['@mozilla.org/binaryoutputstream;1'].createInstance(Ci.nsIBinaryOutputStream);
147 try {
148 binaryOutputStream.setOutputStream(fileOutputStream);
149
150 for (;;) {
151 var available = binaryInputStream.available();
152 if (available === 0) {
153 break;
154 }
155 var bytes = binaryInputStream.readBytes(available);
156 binaryOutputStream.writeBytes(bytes, bytes.length);
157 }
158
159 if (filename === 'jscoverage.js') {
160 var s = 'jscoverage_isReport = true;\n';
161 binaryOutputStream.write(s, s.length);
162 }
163 }
164 finally {
165 binaryOutputStream.close();
166 }
167 }
168 finally {
169 binaryInputStream.close();
170 }
171 };
172 copyChrome('jscoverage.html');
173 copyChrome('jscoverage.js');
174 copyChrome('jscoverage.css');
175 copyChrome('jscoverage-throbber.gif');
176 copyChrome('jscoverage-highlight.css');
177
178 // write the coverage data
179 var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
180 file.initWithFile(reportDirectory);
181 file.appendRelativePath('jscoverage.json');
182 var fileOutputStream = Cc['@mozilla.org/network/file-output-stream;1'].createInstance(Ci.nsIFileOutputStream);
183 try {
184 fileOutputStream.init(file, 0x02 | 0x08 | 0x20, 0644, 0);
185 function write(s) {
186 fileOutputStream.write(s, s.length);
187 }
188 write('{');
189 var first = true;
190 for (var file in _$jscoverage) {
191 dump('jscoverage.jsm: storing coverage data for file ' + file + ' ...\n');
192 if (first) {
193 first = false;
194 }
195 else {
196 write(',');
197 }
198 write(jscoverage_quote(file));
199 write(':{"coverage":[');
200 var coverage = _$jscoverage[file];
201 var length = coverage.length;
202 for (var line = 0; line < length; line++) {
203 if (line > 0) {
204 write(',');
205 }
206 var value = coverage[line];
207 if (value === undefined || value === null) {
208 value = 'null';
209 }
210 write(value.toString());
211 }
212 write('],"source":[');
213 var source = coverage.source;
214 length = source.length;
215 for (line = 0; line < length; line++) {
216 if (line > 0) {
217 write(',');
218 }
219 write(jscoverage_quote(source[line]));
220 }
221 write(']}');
222 }
223 write('}');
224 dump('jscoverage.jsm: coverage data stored\n');
225 }
226 finally {
227 fileOutputStream.close();
228 }
229 }
230 catch (e) {
231 dump('jscoverage.jsm: error saving coverage report\n');
232 dump(e);
233 dump('\n');
234 }
235 }
236 };
237
238 try {
239 JSCoverageUtils.readExistingCoverage();
240
241 const Cc = Components.classes;
242 const Ci = Components.interfaces;
243 const jscoverage_observerService = Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
244 jscoverage_observerService.addObserver(JSCoverageUtils, 'quit-application', false);
245
246 dump('jscoverage.jsm: initialized\n');
247 }
248 catch (e) {
249 dump('jscoverage.jsm: initialization error\n');
250 dump(e);
251 dump('\n');
252 }

  ViewVC Help
Powered by ViewVC 1.1.24