1 | 1 | var parseAndModify = (typeof exports === 'undefined' ? window.falafel : require("/Users/alexsouthern/Dropbox/blanket/lib/./falafel").falafel); |
2 | | |
3 | 1 | (typeof exports === 'undefined' ? window : exports).blanket = (function(){ |
4 | 1 | var linesToAddTracking = [ |
5 | | "ExpressionStatement", |
6 | | "LabeledStatement" , |
7 | | "BreakStatement" , |
8 | | "ContinueStatement" , |
9 | | "VariableDeclaration", |
10 | | "ReturnStatement" , |
11 | | "ThrowStatement" , |
12 | | "Line", |
13 | | "TryStatement" , |
14 | | "FunctionDeclaration" , |
15 | | "IfStatement" , |
16 | | "WhileStatement" , |
17 | | "DoWhileStatement" , |
18 | | "ForStatement" , |
19 | | "ForInStatement" , |
20 | | "SwitchStatement" , |
21 | | "WithStatement" |
22 | | ], |
23 | | linesToAddBrackets = [ |
24 | | "IfStatement" , |
25 | | |
26 | | "WhileStatement" , |
27 | | "DoWhileStatement" , |
28 | | "ForStatement" , |
29 | | "ForInStatement" , |
30 | | "WithStatement" |
31 | | ], |
32 | | covVar = (typeof window === 'undefined' ? "_$jscoverage" : "window._$blanket" ), |
33 | | reporter,instrumentFilter, |
34 | | blanket = { |
35 | | setFilter: function(filter){ |
36 | 2 | instrumentFilter = filter; |
37 | | }, |
38 | | getFilter: function(){ |
39 | 3 | return instrumentFilter; |
40 | | }, |
41 | | setReporter: function(reporterFcn){ |
42 | 0 | reporter = reporterFcn; |
43 | | }, |
44 | | instrument: function(config, next){ |
45 | 2 | var inFile = config.inputFile, |
46 | | inFileName = config.inputFileName; |
47 | 2 | var sourceArray = this._prepareSource(inFile); |
48 | 2 | blanket._trackingArraySetup=[]; |
49 | 2 | var instrumented = parseAndModify(inFile,{loc:true,comment:true}, this._addTracking,inFileName); |
50 | 2 | instrumented = this._trackingSetup(inFileName,sourceArray)+instrumented; |
51 | 2 | next(instrumented); |
52 | | }, |
53 | | _trackingArraySetup: [], |
54 | | _prepareSource: function(source){ |
55 | 3 | return source.replace(/'/g,"\'").replace(/(
|
|
)/gm,"
").split('
'); |
56 | | }, |
57 | | _trackingSetup: function(filename,sourceArray){ |
58 | | |
59 | 3 | var sourceString = sourceArray.join("',
'"); |
60 | 3 | var intro = "if (typeof "+covVar+" === 'undefined') "+covVar+" = {};
"; |
61 | 3 | intro += "if (typeof "+covVar+"['"+filename+"'] === 'undefined'){"; |
62 | | |
63 | 3 | intro += covVar+"['"+filename+"']=[];
"; |
64 | 3 | intro += covVar+"['"+filename+"'].source=['"+sourceString+"'];
"; |
65 | 1 | //initialize array values |
66 | 3 | blanket._trackingArraySetup.sort().forEach(function(item){ |
67 | 12 | intro += covVar+"['"+filename+"']["+item+"]=0;
"; |
68 | | }); |
69 | | |
70 | 3 | intro += "}"; |
71 | 3 | return intro; |
72 | | }, |
73 | | _blockifyIf: function(node){ |
74 | | |
75 | 87 | if (linesToAddBrackets.indexOf(node.type) > -1){ |
76 | 7 | var bracketsExistObject = node.consequent || node.body; |
77 | 7 | var bracketsExistAlt = node.alternate; |
78 | 7 | if( bracketsExistAlt && bracketsExistAlt.type != "BlockStatement") { |
79 | 2 | bracketsExistAlt.update("{
"+bracketsExistAlt.source()+"}
"); |
80 | | } |
81 | 7 | if( bracketsExistObject && bracketsExistObject.type != "BlockStatement") { |
82 | 6 | bracketsExistObject.update("{
"+bracketsExistObject.source()+"}
"); |
83 | | } |
84 | | } |
85 | | }, |
86 | | _addTracking: function (node,filename) { |
87 | 87 | blanket._blockifyIf(node); |
88 | 87 | if (linesToAddTracking.indexOf(node.type) > -1){ |
89 | 23 | if (node.type == "VariableDeclaration" && |
90 | | (node.parent.type == "ForStatement" || node.parent.type == "ForInStatement")){ |
91 | 0 | return; |
92 | | } |
93 | 23 | if (node.loc && node.loc.start){ |
94 | 23 | node.update(covVar+"['"+filename+"']["+node.loc.start.line+"]++;
"+node.source()); |
95 | 23 | blanket._trackingArraySetup.push(node.loc.start.line); |
96 | | }else{ |
97 | 1 | //I don't think we can handle a node with no location |
98 | 0 | throw new Error("The instrumenter encountered a node with no location: "+Object.keys(node)); |
99 | | } |
100 | | |
101 | | } |
102 | | }, |
103 | | report: function(coverage_data){ |
104 | 0 | coverage_data.files = (typeof window === 'undefined' ? _$jscoverage : window._$blanket ); |
105 | 0 | if (reporter){ |
106 | 0 | require([reporter.replace(".js","")],function(r){ |
107 | 0 | r(coverage_data); |
108 | | }); |
109 | | }else{ |
110 | 0 | Reporter(coverage_data); |
111 | | } |
112 | | } |
113 | | }; |
114 | 1 | return blanket; |
115 | | })(); |
116 | | |
117 | | |
118 | | |