NOBUG: Fixed file access permissions
[moodle.git] / lib / yuilib / 3.13.0 / test-console / test-console-debug.js
blob3d686bcab8d864cccc1bc9429db8e28317539f08
1 /*
2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
8 YUI.add('test-console', function (Y, NAME) {
10 /**
11 Provides a specialized log console widget that's pre-configured to display YUI
12 Test output with no extra configuration.
14 @example
16     <div id="log" class="yui3-skin-sam"></div>
18     <script>
19     YUI().use('test-console', function (Y) {
20         // ... set up your test cases here ...
22         // Render the console inside the #log div, then run the tests.
23         new Y.Test.Console().render('#log');
24         Y.Test.Runner.run();
25     });
26     </script>
28 @module test-console
29 @namespace Test
30 @class Console
31 @extends Console
32 @constructor
34 @param {Object} [config] Config attributes.
35     @param {Object} [config.filters] Category filter configuration.
37 @since 3.5.0
38 **/
40 function TestConsole() {
41     TestConsole.superclass.constructor.apply(this, arguments);
44 Y.namespace('Test').Console = Y.extend(TestConsole, Y.Console, {
45     initializer: function (config) {
46         this.on('entry', this._onEntry);
48         this.plug(Y.Plugin.ConsoleFilters, {
49             category: Y.merge({
50                 info  : true,
51                 pass  : false,
52                 fail  : true,
53                 status: false
54             }, (config && config.filters) || {}),
56             defaultVisibility: false,
58             source: {
59                 TestRunner: true
60             }
61         });
63         Y.Test.Runner.on('complete', Y.bind(this._parseCoverage, this));
64     },
66     // -- Protected Coverage Parser ---------------------------------------------
67     /**
68     * Scans the coverage data to determine if it's an Istanbul coverage object.
69     * @method _isIstanbul
70     * @param {Object} json The coverage data to scan
71     * @return {Boolean} True if this is Istanbul Coverage
72     */
73     _isIstanbul: function(json) {
74         var first = Y.Object.keys(json)[0],
75             ret = false;
77         if (json[first].s !== undefined && json[first].fnMap !== undefined) {
78             ret = true;
79         }
81         if (json.s !== undefined && json.fnMap !== undefined) {
82             ret = true;
83         }
84         return ret;
85     },
86     /**
87     * Parses and logs a summary of YUITest coverage data.
88     * @method parseYUITest
89     * @param {Object} coverage The YUITest Coverage JSON data
90     */
91     parseYUITestCoverage: function (coverage) {
92         var cov = {
93             lines: {
94                 hit: 0,
95                 miss: 0,
96                 total: 0,
97                 percent: 0
98             },
99             functions: {
100                 hit: 0,
101                 miss: 0,
102                 total: 0,
103                 percent: 0
104             }
105         }, coverageLog;
107         Y.Object.each(coverage, function(info) {
108             cov.lines.total += info.coveredLines;
109             cov.lines.hit += info.calledLines;
110             cov.lines.miss += (info.coveredLines - info.calledLines);
111             cov.lines.percent = Math.floor((cov.lines.hit / cov.lines.total) * 100);
113             cov.functions.total += info.coveredFunctions;
114             cov.functions.hit += info.calledFunctions;
115             cov.functions.miss += (info.coveredFunctions - info.calledFunctions);
116             cov.functions.percent = Math.floor((cov.functions.hit / cov.functions.total) * 100);
117         });
120         coverageLog = 'Lines: Hit:' + cov.lines.hit + ' Missed:' + cov.lines.miss + ' Total:' + cov.lines.total + ' Percent:' + cov.lines.percent + '%\n';
121         coverageLog += 'Functions: Hit:' + cov.functions.hit + ' Missed:' + cov.functions.miss + ' Total:' + cov.functions.total + ' Percent:' + cov.functions.percent + '%';
123         this.log('Coverage: ' + coverageLog, 'info', 'TestRunner');
124     },
125     /**
126     * Generates a generic summary object used for Istanbul conversions.
127     * @method _blankSummary
128     * @return {Object} Generic summary object
129     */
130     _blankSummary: function () {
131         return {
132             lines: {
133                 total: 0,
134                 covered: 0,
135                 pct: 'Unknown'
136             },
137             statements: {
138                 total: 0,
139                 covered: 0,
140                 pct: 'Unknown'
141             },
142             functions: {
143                 total: 0,
144                 covered: 0,
145                 pct: 'Unknown'
146             },
147             branches: {
148                 total: 0,
149                 covered: 0,
150                 pct: 'Unknown'
151             }
152         };
153     },
154     /**
155     * Calculates line numbers from statement coverage
156     * @method _addDerivedInfoForFile
157     * @private
158     * @param {Object} fileCoverage JSON coverage data
159     */
160     _addDerivedInfoForFile: function (fileCoverage) {
161         var statementMap = fileCoverage.statementMap,
162             statements = fileCoverage.s,
163             lineMap;
165         if (!fileCoverage.l) {
166             fileCoverage.l = lineMap = {};
167             Y.Object.each(statements, function (value, st) {
168                 var line = statementMap[st].start.line,
169                     count = statements[st],
170                     prevVal = lineMap[line];
171                 if (typeof prevVal === 'undefined' || prevVal < count) {
172                     lineMap[line] = count;
173                 }
174             });
175         }
176     },
177     /**
178     * Generic percent calculator
179     * @method _percent
180     * @param {Number} covered The covered amount
181     * @param {Number} total The total
182     * @private
183     */
184     _percent: function (covered, total) {
185         var tmp, pct = 100.00;
186         if (total > 0) {
187             tmp = 1000 * 100 * covered / total + 5;
188             pct = Math.floor(tmp / 10) / 100;
189         }
190         return pct;
191     },
192     /**
193     * Summarize simple properties in the coverage data
194     * @method _computSimpleTotals
195     * @private
196     * @param {Object} fileCoverage JSON coverage data
197     * @param {String} property The property to summarize
198     */
199     _computeSimpleTotals: function (fileCoverage, property) {
200         var stats = fileCoverage[property],
201             ret = { total: 0, covered: 0 };
203         Y.Object.each(stats, function(val) {
204             ret.total += 1;
205             if (val) {
206                 ret.covered += 1;
207             }
208         });
209         ret.pct = this._percent(ret.covered, ret.total);
210         return ret;
211     },
212     /**
213     * Noramlizes branch data from Istanbul
214     * @method _computeBranchTotals
215     * @private
216     * @param {Object} fileCoverage JSON coverage data
217     */
218     _computeBranchTotals: function (fileCoverage) {
219         var stats = fileCoverage.b,
220             ret = { total: 0, covered: 0 };
222         Y.Object.each(stats, function (branches) {
223             var covered = Y.Array.filter(branches, function (num) { return num > 0; });
224             ret.total += branches.length;
225             ret.covered += covered.length;
226         });
227         ret.pct = this._percent(ret.covered, ret.total);
228         return ret;
229     },
230     /**
231     * Takes an Istanbul coverage object, normalizes it and prints a log with a summary
232     * @method parseInstanbul
233     * @param {Object} coverage The coverage object to normalize and log
234     */
235     parseIstanbul: function (coverage) {
236         var self = this,
237             str = 'Coverage Report:\n';
239         Y.Object.each(coverage, function(fileCoverage, file) {
240             var ret = self._blankSummary();
242             self._addDerivedInfoForFile(fileCoverage);
243             ret.lines = self._computeSimpleTotals(fileCoverage, 'l');
244             ret.functions = self._computeSimpleTotals(fileCoverage, 'f');
245             ret.statements = self._computeSimpleTotals(fileCoverage, 's');
246             ret.branches = self._computeBranchTotals(fileCoverage);
247             str += file + ':\n';
248             Y.Array.each(['lines','functions','statements','branches'], function(key) {
249                 str += '    ' + key +': ' + ret[key].covered + '/' + ret[key].total + ' : ' + ret[key].pct + '%\n';
250             });
252         });
253         this.log(str, 'info', 'TestRunner');
255     },
256     /**
257     * Parses YUITest or Istanbul coverage results if they are available and logs them.
258     * @method _parseCoverage
259     * @private
260     */
261     _parseCoverage: function() {
262         var coverage = Y.Test.Runner.getCoverage();
263         if (!coverage) {
264             return;
265         }
266         if (this._isIstanbul(coverage)) {
267             this.parseIstanbul(coverage);
268         } else {
269             this.parseYUITestCoverage(coverage);
270         }
271     },
273     // -- Protected Event Handlers ---------------------------------------------
274     _onEntry: function (e) {
275         var msg = e.message;
277         if (msg.category === 'info'
278                 && /\s(?:case|suite)\s|yuitests\d+|began/.test(msg.message)) {
279             msg.category = 'status';
280         } else if (msg.category === 'fail') {
281             this.printBuffer();
282         }
283     }
284 }, {
285     NAME: 'testConsole',
287     ATTRS: {
288         entryTemplate: {
289             value:
290                 '<div class="{entry_class} {cat_class} {src_class}">' +
291                     '<div class="{entry_content_class}">{message}</div>' +
292                 '</div>'
293         },
295         height: {
296             value: '350px'
297         },
299         newestOnTop: {
300             value: false
301         },
303         style: {
304             value: 'block'
305         },
307         width: {
308             value: Y.UA.ie && Y.UA.ie < 9 ? '100%' : 'inherit'
309         }
310     }
314 }, '3.13.0', {"requires": ["console-filters", "test", "array-extras"], "skinnable": true});