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

Annotation of /trunk/jscoverage.jsm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 441 - (hide annotations)
Tue Jul 14 16:14:24 2009 UTC (10 years, 3 months ago) by siliconforks
File size: 8157 byte(s)
Store report in directory containing the firefox executable instead of the current directory.
1 siliconforks 361 /*
2     jscoverage.jsm - Firefox module
3 siliconforks 427 Copyright (C) 2008, 2009 siliconforks.com
4 siliconforks 361
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 siliconforks 439
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 siliconforks 441 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 siliconforks 439 readExistingCoverage: function() {
79     try {
80     const Cc = Components.classes;
81     const Ci = Components.interfaces;
82    
83 siliconforks 441 var reportDirectory = this.getReportDirectory();
84 siliconforks 439 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 siliconforks 441 var reportDirectory = this.getReportDirectory();
130 siliconforks 439 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 siliconforks 440 jscoverage_observerService.addObserver(JSCoverageUtils, 'quit-application', false);
245 siliconforks 439
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