e0af3f70515695e49fc47e242cd112dd73f9b7c1
[platform/framework/web/crosswalk-tizen.git] /
1 #!/usr/bin/env node
2 /*
3   Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions are met:
7
8     * Redistributions of source code must retain the above copyright
9       notice, this list of conditions and the following disclaimer.
10     * Redistributions in binary form must reproduce the above copyright
11       notice, this list of conditions and the following disclaimer in the
12       documentation and/or other materials provided with the distribution.
13
14   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17   ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
18   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 /*jslint sloppy:true plusplus:true node:true rhino:true */
27
28 var fs, esprima, options, fnames, count;
29
30 if (typeof require === 'function') {
31     fs = require('fs');
32     esprima = require('esprima');
33 } else if (typeof load === 'function') {
34     try {
35         load('esprima.js');
36     } catch (e) {
37         load('../esprima.js');
38     }
39 }
40
41 // Shims to Node.js objects when running under Rhino.
42 if (typeof console === 'undefined' && typeof process === 'undefined') {
43     console = { log: print };
44     fs = { readFileSync: readFile };
45     process = { argv: arguments, exit: quit };
46     process.argv.unshift('esvalidate.js');
47     process.argv.unshift('rhino');
48 }
49
50 function showUsage() {
51     console.log('Usage:');
52     console.log('   esvalidate [options] file.js');
53     console.log();
54     console.log('Available options:');
55     console.log();
56     console.log('  --format=type  Set the report format, plain (default) or junit');
57     console.log('  -v, --version  Print program version');
58     console.log();
59     process.exit(1);
60 }
61
62 if (process.argv.length <= 2) {
63     showUsage();
64 }
65
66 options = {
67     format: 'plain'
68 };
69
70 fnames = [];
71
72 process.argv.splice(2).forEach(function (entry) {
73
74     if (entry === '-h' || entry === '--help') {
75         showUsage();
76     } else if (entry === '-v' || entry === '--version') {
77         console.log('ECMAScript Validator (using Esprima version', esprima.version, ')');
78         console.log();
79         process.exit(0);
80     } else if (entry.slice(0, 9) === '--format=') {
81         options.format = entry.slice(9);
82         if (options.format !== 'plain' && options.format !== 'junit') {
83             console.log('Error: unknown report format ' + options.format + '.');
84             process.exit(1);
85         }
86     } else if (entry.slice(0, 2) === '--') {
87         console.log('Error: unknown option ' + entry + '.');
88         process.exit(1);
89     } else {
90         fnames.push(entry);
91     }
92 });
93
94 if (fnames.length === 0) {
95     console.log('Error: no input file.');
96     process.exit(1);
97 }
98
99 if (options.format === 'junit') {
100     console.log('<?xml version="1.0" encoding="UTF-8"?>');
101     console.log('<testsuites>');
102 }
103
104 count = 0;
105 fnames.forEach(function (fname) {
106     var content, timestamp, syntax, name;
107     try {
108         content = fs.readFileSync(fname, 'utf-8');
109
110         if (content[0] === '#' && content[1] === '!') {
111             content = '//' + content.substr(2, content.length);
112         }
113
114         timestamp = Date.now();
115         syntax = esprima.parse(content, { tolerant: true });
116
117         if (options.format === 'junit') {
118
119             name = fname;
120             if (name.lastIndexOf('/') >= 0) {
121                 name = name.slice(name.lastIndexOf('/') + 1);
122             }
123
124             console.log('<testsuite name="' + fname + '" errors="0" ' +
125                 ' failures="' + syntax.errors.length + '" ' +
126                 ' tests="' + syntax.errors.length + '" ' +
127                 ' time="' + Math.round((Date.now() - timestamp) / 1000) +
128                 '">');
129
130             syntax.errors.forEach(function (error) {
131                 var msg = error.message;
132                 msg = msg.replace(/^Line\ [0-9]*\:\ /, '');
133                 console.log('  <testcase name="Line ' + error.lineNumber + ': ' + msg + '" ' +
134                     ' time="0">');
135                 console.log('    <error type="SyntaxError" message="' + error.message + '">' +
136                     error.message + '(' + name + ':' + error.lineNumber + ')' +
137                     '</error>');
138                 console.log('  </testcase>');
139             });
140
141             console.log('</testsuite>');
142
143         } else if (options.format === 'plain') {
144
145             syntax.errors.forEach(function (error) {
146                 var msg = error.message;
147                 msg = msg.replace(/^Line\ [0-9]*\:\ /, '');
148                 msg = fname + ':' + error.lineNumber + ': ' + msg;
149                 console.log(msg);
150                 ++count;
151             });
152
153         }
154     } catch (e) {
155         ++count;
156         if (options.format === 'junit') {
157             console.log('<testsuite name="' + fname + '" errors="1" failures="0" tests="1" ' +
158                 ' time="' + Math.round((Date.now() - timestamp) / 1000) + '">');
159             console.log(' <testcase name="' + e.message + '" ' + ' time="0">');
160             console.log(' <error type="ParseError" message="' + e.message + '">' +
161                 e.message + '(' + fname + ((e.lineNumber) ? ':' + e.lineNumber : '') +
162                 ')</error>');
163             console.log(' </testcase>');
164             console.log('</testsuite>');
165         } else {
166             console.log('Error: ' + e.message);
167         }
168     }
169 });
170
171 if (options.format === 'junit') {
172     console.log('</testsuites>');
173 }
174
175 if (count > 0) {
176     process.exit(1);
177 }