Fixes for Android GN build input/outputs
[chromium-blink-merge.git] / third_party / closure_compiler / compiler_test.py
bloba39776a4193851d81b3b671186fa22f4601de292
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 import os
7 import tempfile
8 import unittest
10 from compile import Checker
11 from processor import FileCache, Processor
14 _SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
15 _SRC_DIR = os.path.join(_SCRIPT_DIR, os.pardir, os.pardir)
16 _RESOURCES_DIR = os.path.join(_SRC_DIR, "ui", "webui", "resources", "js")
17 _ASSERT_JS = os.path.join(_RESOURCES_DIR, "assert.js")
18 _CR_JS = os.path.join(_RESOURCES_DIR, "cr.js")
19 _CR_UI_JS = os.path.join(_RESOURCES_DIR, "cr", "ui.js")
20 _POLYMER_EXTERNS = os.path.join(_SRC_DIR, "third_party", "polymer", "v1_0",
21 "components-chromium", "polymer-externs",
22 "polymer.externs.js")
25 class CompilerTest(unittest.TestCase):
26 _ASSERT_DEFINITION = Processor(_ASSERT_JS).contents
27 _CR_DEFINE_DEFINITION = Processor(_CR_JS).contents
28 _CR_UI_DECORATE_DEFINITION = Processor(_CR_UI_JS).contents
30 def setUp(self):
31 self._checker = Checker()
32 self._tmp_files = []
34 def tearDown(self):
35 for file in self._tmp_files:
36 if os.path.exists(file):
37 os.remove(file)
39 def _runChecker(self, source_code, output_wrapper=None):
40 file_path = "/script.js"
41 FileCache._cache[file_path] = source_code
42 out_file, out_map = self._createOutFiles()
44 found_errors, stderr = self._checker.check(file_path,
45 externs=[_POLYMER_EXTERNS],
46 out_file=out_file,
47 output_wrapper=output_wrapper)
48 return found_errors, stderr, out_file, out_map
50 def _runCheckerTestExpectError(self, source_code, expected_error):
51 _, stderr, out_file, out_map = self._runChecker(source_code)
53 self.assertTrue(expected_error in stderr,
54 msg="Expected chunk: \n%s\n\nOutput:\n%s\n" % (
55 expected_error, stderr))
56 self.assertFalse(os.path.exists(out_file))
57 self.assertFalse(os.path.exists(out_map))
59 def _runCheckerTestExpectSuccess(self, source_code, expected_output=None,
60 output_wrapper=None):
61 found_errors, stderr, out_file, out_map = self._runChecker(source_code,
62 output_wrapper)
64 self.assertFalse(found_errors,
65 msg="Expected success, but got failure\n\nOutput:\n%s\n" % stderr)
67 self.assertTrue(os.path.exists(out_map))
68 self.assertTrue(os.path.exists(out_file))
69 if expected_output:
70 with open(out_file, "r") as file:
71 self.assertEquals(file.read(), expected_output)
73 def _createOutFiles(self):
74 out_file = tempfile.NamedTemporaryFile(delete=False)
75 out_map = "%s.map" % out_file.name
77 self._tmp_files.append(out_file.name)
78 self._tmp_files.append(out_map)
79 return out_file.name, out_map
81 def testGetInstance(self):
82 self._runCheckerTestExpectError("""
83 var cr = {
84 /** @param {!Function} ctor */
85 addSingletonGetter: function(ctor) {
86 ctor.getInstance = function() {
87 return ctor.instance_ || (ctor.instance_ = new ctor());
92 /** @constructor */
93 function Class() {
94 /** @param {number} num */
95 this.needsNumber = function(num) {};
98 cr.addSingletonGetter(Class);
99 Class.getInstance().needsNumber("wrong type");
100 """, "ERROR - actual parameter 1 of Class.needsNumber does not match formal "
101 "parameter")
103 def testCrDefineFunctionDefinition(self):
104 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
105 cr.define('a.b.c', function() {
106 /** @param {number} num */
107 function internalName(num) {}
109 return {
110 needsNumber: internalName
114 a.b.c.needsNumber("wrong type");
115 """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal "
116 "parameter")
118 def testCrDefineFunctionAssignment(self):
119 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
120 cr.define('a.b.c', function() {
121 /** @param {number} num */
122 var internalName = function(num) {};
124 return {
125 needsNumber: internalName
129 a.b.c.needsNumber("wrong type");
130 """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal "
131 "parameter")
133 def testCrDefineConstructorDefinitionPrototypeMethod(self):
134 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
135 cr.define('a.b.c', function() {
136 /** @constructor */
137 function ClassInternalName() {}
139 ClassInternalName.prototype = {
140 /** @param {number} num */
141 method: function(num) {}
144 return {
145 ClassExternalName: ClassInternalName
149 new a.b.c.ClassExternalName().method("wrong type");
150 """, "ERROR - actual parameter 1 of a.b.c.ClassExternalName.prototype.method "
151 "does not match formal parameter")
153 def testCrDefineConstructorAssignmentPrototypeMethod(self):
154 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
155 cr.define('a.b.c', function() {
156 /** @constructor */
157 var ClassInternalName = function() {};
159 ClassInternalName.prototype = {
160 /** @param {number} num */
161 method: function(num) {}
164 return {
165 ClassExternalName: ClassInternalName
169 new a.b.c.ClassExternalName().method("wrong type");
170 """, "ERROR - actual parameter 1 of a.b.c.ClassExternalName.prototype.method "
171 "does not match formal parameter")
173 def testCrDefineEnum(self):
174 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
175 cr.define('a.b.c', function() {
176 /** @enum {string} */
177 var internalNameForEnum = {key: 'wrong_type'};
179 return {
180 exportedEnum: internalNameForEnum
184 /** @param {number} num */
185 function needsNumber(num) {}
187 needsNumber(a.b.c.exportedEnum.key);
188 """, "ERROR - actual parameter 1 of needsNumber does not match formal "
189 "parameter")
191 def testObjectDefineProperty(self):
192 self._runCheckerTestExpectSuccess("""
193 /** @constructor */
194 function Class() {}
196 Object.defineProperty(Class.prototype, 'myProperty', {});
198 alert(new Class().myProperty);
199 """)
201 def testCrDefineProperty(self):
202 self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION + """
203 /** @constructor */
204 function Class() {}
206 cr.defineProperty(Class.prototype, 'myProperty', cr.PropertyKind.JS);
208 alert(new Class().myProperty);
209 """)
211 def testCrDefinePropertyTypeChecking(self):
212 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """
213 /** @constructor */
214 function Class() {}
216 cr.defineProperty(Class.prototype, 'booleanProp', cr.PropertyKind.BOOL_ATTR);
218 /** @param {number} num */
219 function needsNumber(num) {}
221 needsNumber(new Class().booleanProp);
222 """, "ERROR - actual parameter 1 of needsNumber does not match formal "
223 "parameter")
225 def testCrDefineOnCrWorks(self):
226 self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION + """
227 cr.define('cr', function() {
228 return {};
230 """)
232 def testAssertWorks(self):
233 self._runCheckerTestExpectSuccess(self._ASSERT_DEFINITION + """
234 /** @return {?string} */
235 function f() {
236 return "string";
239 /** @type {!string} */
240 var a = assert(f());
241 """)
243 def testAssertInstanceofWorks(self):
244 self._runCheckerTestExpectSuccess(self._ASSERT_DEFINITION + """
245 /** @constructor */
246 function Class() {}
248 /** @return {Class} */
249 function f() {
250 var a = document.createElement('div');
251 return assertInstanceof(a, Class);
253 """)
255 def testCrUiDecorateWorks(self):
256 self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION +
257 self._CR_UI_DECORATE_DEFINITION + """
258 /** @constructor */
259 function Class() {}
261 /** @return {Class} */
262 function f() {
263 var a = document.createElement('div');
264 cr.ui.decorate(a, Class);
265 return a;
267 """)
269 def testValidScriptCompilation(self):
270 self._runCheckerTestExpectSuccess("""
271 var testScript = function() {
272 console.log("hello world")
274 """,
275 """'use strict';var testScript=function(){console.log("hello world")};\n""")
277 def testOutputWrapper(self):
278 source_code = """
279 var testScript = function() {
280 console.log("hello world");
283 expected_output = ("""(function(){'use strict';var testScript=function()"""
284 """{console.log("hello world")};})();\n""")
285 output_wrapper="(function(){%output%})();"
286 self._runCheckerTestExpectSuccess(source_code, expected_output,
287 output_wrapper=output_wrapper)
289 def testCheckMultiple(self):
290 source_file1 = tempfile.NamedTemporaryFile(delete=False)
291 with open(source_file1.name, "w") as f:
292 f.write("""
293 goog.provide('testScript');
295 var testScript = function() {};
296 """)
297 self._tmp_files.append(source_file1.name)
299 source_file2 = tempfile.NamedTemporaryFile(delete=False)
300 with open(source_file2.name, "w") as f:
301 f.write("""
302 goog.require('testScript');
304 testScript();
305 """)
306 self._tmp_files.append(source_file2.name)
308 out_file, out_map = self._createOutFiles()
309 sources = [source_file1.name, source_file2.name]
310 externs = [_POLYMER_EXTERNS]
311 found_errors, stderr = self._checker.check_multiple(sources,
312 externs=externs,
313 out_file=out_file)
314 self.assertFalse(found_errors,
315 msg="Expected success, but got failure\n\nOutput:\n%s\n" % stderr)
317 expected_output = "'use strict';var testScript=function(){};testScript();\n"
318 self.assertTrue(os.path.exists(out_map))
319 self.assertTrue(os.path.exists(out_file))
320 with open(out_file, "r") as file:
321 self.assertEquals(file.read(), expected_output)
324 if __name__ == "__main__":
325 unittest.main()