Delete unused downloads page asset.
[chromium-blink-merge.git] / third_party / closure_compiler / compiler_test.py
blob2a8cfd411ed05480e1ee8bb11f3baadd152f009a
1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 from ast import literal_eval
7 import os
8 import tempfile
9 import unittest
11 from compile import Checker
12 from processor import FileCache, Processor
15 _SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
16 _SRC_DIR = os.path.join(_SCRIPT_DIR, os.pardir, os.pardir)
17 _RESOURCES_DIR = os.path.join(_SRC_DIR, "ui", "webui", "resources", "js")
18 _ASSERT_JS = os.path.join(_RESOURCES_DIR, "assert.js")
19 _CR_JS = os.path.join(_RESOURCES_DIR, "cr.js")
20 _CR_UI_JS = os.path.join(_RESOURCES_DIR, "cr", "ui.js")
21 _POLYMER_EXTERNS = os.path.join(_SRC_DIR, "third_party", "polymer", "v1_0",
22 "components-chromium", "polymer-externs",
23 "polymer.externs.js")
24 _CHROME_SEND_EXTERNS = os.path.join(_SRC_DIR, "third_party", "closure_compiler",
25 "externs", "chrome_send.js")
26 _CLOSURE_ARGS_GYPI = os.path.join(_SCRIPT_DIR, "closure_args.gypi")
27 _GYPI_DICT = literal_eval(open(_CLOSURE_ARGS_GYPI).read())
28 _COMMON_CLOSURE_ARGS = _GYPI_DICT["closure_args"] + \
29 _GYPI_DICT["default_disabled_closure_args"]
32 class CompilerTest(unittest.TestCase):
33 _ASSERT_DEFINITION = Processor(_ASSERT_JS).contents
34 _CR_DEFINE_DEFINITION = Processor(_CR_JS).contents
35 _CR_UI_DECORATE_DEFINITION = Processor(_CR_UI_JS).contents
37 def setUp(self):
38 self._checker = Checker()
39 self._tmp_files = []
41 def tearDown(self):
42 for file in self._tmp_files:
43 if os.path.exists(file):
44 os.remove(file)
46 def _runChecker(self, source_code, closure_args=None):
47 file_path = "/script.js"
48 FileCache._cache[file_path] = source_code
49 out_file, out_map = self._createOutFiles()
50 args = _COMMON_CLOSURE_ARGS + (closure_args or [])
52 externs = [_POLYMER_EXTERNS, _CHROME_SEND_EXTERNS]
53 found_errors, stderr = self._checker.check(file_path,
54 externs=externs,
55 out_file=out_file,
56 closure_args=args)
57 return found_errors, stderr, out_file, out_map
59 def _runCheckerTestExpectError(self, source_code, expected_error):
60 _, stderr, out_file, out_map = self._runChecker(source_code)
62 self.assertTrue(expected_error in stderr,
63 msg="Expected chunk: \n%s\n\nOutput:\n%s\n" % (
64 expected_error, stderr))
65 self.assertFalse(os.path.exists(out_file))
66 self.assertFalse(os.path.exists(out_map))
68 def _runCheckerTestExpectSuccess(self, source_code, expected_output=None,
69 closure_args=None):
70 found_errors, stderr, out_file, out_map = self._runChecker(source_code,
71 closure_args)
73 self.assertFalse(found_errors,
74 msg="Expected success, but got failure\n\nOutput:\n%s\n" % stderr)
76 self.assertTrue(os.path.exists(out_map))
77 self.assertTrue(os.path.exists(out_file))
78 if expected_output:
79 with open(out_file, "r") as file:
80 self.assertEquals(file.read(), expected_output)
82 def _createOutFiles(self):
83 out_file = tempfile.NamedTemporaryFile(delete=False)
84 out_map = "%s.map" % out_file.name
86 self._tmp_files.append(out_file.name)
87 self._tmp_files.append(out_map)
88 return out_file.name, out_map
90 def testGetInstance(self):
91 self._runCheckerTestExpectError("""
92 var cr = {
93 /** @param {!Function} ctor */
94 addSingletonGetter: function(ctor) {
95 ctor.getInstance = function() {
96 return ctor.instance_ || (ctor.instance_ = new ctor());
101 /** @constructor */
102 function Class() {
103 /** @param {number} num */
104 this.needsNumber = function(num) {};
107 cr.addSingletonGetter(Class);
108 Class.getInstance().needsNumber("wrong type");
109 """, "ERROR - actual parameter 1 of Class.needsNumber does not match formal "
110 "parameter")
112 def testCrDefineFunctionDefinition(self):
113 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
114 cr.define('a.b.c', function() {
115 /** @param {number} num */
116 function internalName(num) {}
118 return {
119 needsNumber: internalName
123 a.b.c.needsNumber("wrong type");
124 """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal "
125 "parameter")
127 def testCrDefineFunctionAssignment(self):
128 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
129 cr.define('a.b.c', function() {
130 /** @param {number} num */
131 var internalName = function(num) {};
133 return {
134 needsNumber: internalName
138 a.b.c.needsNumber("wrong type");
139 """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal "
140 "parameter")
142 def testCrDefineConstructorDefinitionPrototypeMethod(self):
143 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
144 cr.define('a.b.c', function() {
145 /** @constructor */
146 function ClassInternalName() {}
148 ClassInternalName.prototype = {
149 /** @param {number} num */
150 method: function(num) {}
153 return {
154 ClassExternalName: ClassInternalName
158 new a.b.c.ClassExternalName().method("wrong type");
159 """, "ERROR - actual parameter 1 of a.b.c.ClassExternalName.prototype.method "
160 "does not match formal parameter")
162 def testCrDefineConstructorAssignmentPrototypeMethod(self):
163 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
164 cr.define('a.b.c', function() {
165 /** @constructor */
166 var ClassInternalName = function() {};
168 ClassInternalName.prototype = {
169 /** @param {number} num */
170 method: function(num) {}
173 return {
174 ClassExternalName: ClassInternalName
178 new a.b.c.ClassExternalName().method("wrong type");
179 """, "ERROR - actual parameter 1 of a.b.c.ClassExternalName.prototype.method "
180 "does not match formal parameter")
182 def testCrDefineEnum(self):
183 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
184 cr.define('a.b.c', function() {
185 /** @enum {string} */
186 var internalNameForEnum = {key: 'wrong_type'};
188 return {
189 exportedEnum: internalNameForEnum
193 /** @param {number} num */
194 function needsNumber(num) {}
196 needsNumber(a.b.c.exportedEnum.key);
197 """, "ERROR - actual parameter 1 of needsNumber does not match formal "
198 "parameter")
200 def testObjectDefineProperty(self):
201 self._runCheckerTestExpectSuccess("""
202 /** @constructor */
203 function Class() {}
205 Object.defineProperty(Class.prototype, 'myProperty', {});
207 alert(new Class().myProperty);
208 """)
210 def testCrDefineProperty(self):
211 self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION + """
212 /** @constructor */
213 function Class() {}
215 cr.defineProperty(Class.prototype, 'myProperty', cr.PropertyKind.JS);
217 alert(new Class().myProperty);
218 """)
220 def testCrDefinePropertyTypeChecking(self):
221 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
222 /** @constructor */
223 function Class() {}
225 cr.defineProperty(Class.prototype, 'booleanProp', cr.PropertyKind.BOOL_ATTR);
227 /** @param {number} num */
228 function needsNumber(num) {}
230 needsNumber(new Class().booleanProp);
231 """, "ERROR - actual parameter 1 of needsNumber does not match formal "
232 "parameter")
234 def testCrDefineOnCrWorks(self):
235 self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION + """
236 cr.define('cr', function() {
237 return {};
239 """)
241 def testAssertWorks(self):
242 self._runCheckerTestExpectSuccess(self._ASSERT_DEFINITION + """
243 /** @return {?string} */
244 function f() {
245 return "string";
248 /** @type {!string} */
249 var a = assert(f());
250 """)
252 def testAssertInstanceofWorks(self):
253 self._runCheckerTestExpectSuccess(self._ASSERT_DEFINITION + """
254 /** @constructor */
255 function Class() {}
257 /** @return {Class} */
258 function f() {
259 var a = document.createElement('div');
260 return assertInstanceof(a, Class);
262 """)
264 def testCrUiDecorateWorks(self):
265 self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION +
266 self._CR_UI_DECORATE_DEFINITION + """
267 /** @constructor */
268 function Class() {}
270 /** @return {Class} */
271 function f() {
272 var a = document.createElement('div');
273 cr.ui.decorate(a, Class);
274 return a;
276 """)
278 def testValidScriptCompilation(self):
279 self._runCheckerTestExpectSuccess("""
280 var testScript = function() {
281 console.log("hello world")
283 """,
284 """'use strict';var testScript=function(){console.log("hello world")};\n""")
286 def testOutputWrapper(self):
287 source_code = """
288 var testScript = function() {
289 console.log("hello world");
292 expected_output = ("""(function(){'use strict';var testScript=function()"""
293 """{console.log("hello world")};})();\n""")
294 closure_args=["output_wrapper='(function(){%output%})();'"]
295 self._runCheckerTestExpectSuccess(source_code, expected_output,
296 closure_args)
298 def testCheckMultiple(self):
299 source_file1 = tempfile.NamedTemporaryFile(delete=False)
300 with open(source_file1.name, "w") as f:
301 f.write("""
302 goog.provide('testScript');
304 var testScript = function() {};
305 """)
306 self._tmp_files.append(source_file1.name)
308 source_file2 = tempfile.NamedTemporaryFile(delete=False)
309 with open(source_file2.name, "w") as f:
310 f.write("""
311 goog.require('testScript');
313 testScript();
314 """)
315 self._tmp_files.append(source_file2.name)
317 out_file, out_map = self._createOutFiles()
318 sources = [source_file1.name, source_file2.name]
319 externs = [_POLYMER_EXTERNS]
320 found_errors, stderr = self._checker.check_multiple(
321 sources, externs=externs, out_file=out_file,
322 closure_args=_COMMON_CLOSURE_ARGS)
323 self.assertFalse(found_errors,
324 msg="Expected success, but got failure\n\nOutput:\n%s\n" % stderr)
326 expected_output = "'use strict';var testScript=function(){};testScript();\n"
327 self.assertTrue(os.path.exists(out_map))
328 self.assertTrue(os.path.exists(out_file))
329 with open(out_file, "r") as file:
330 self.assertEquals(file.read(), expected_output)
333 if __name__ == "__main__":
334 unittest.main()