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.
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", "v0_8",
21 "components-chromium", "polymer-externs",
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
31 self
._checker
= Checker()
35 for file in self
._tmp
_files
:
36 if os
.path
.exists(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
],
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,
61 found_errors
, stderr
, out_file
, out_map
= self
._runChecker
(source_code
,
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
))
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
("""
84 /** @param {!Function} ctor */
85 addSingletonGetter: function(ctor) {
86 ctor.getInstance = function() {
87 return ctor.instance_ || (ctor.instance_ = new ctor());
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 "
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) {}
110 needsNumber: internalName
114 a.b.c.needsNumber("wrong type");
115 """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal "
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) {};
125 needsNumber: internalName
129 a.b.c.needsNumber("wrong type");
130 """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal "
133 def testCrDefineConstructorDefinitionPrototypeMethod(self
):
134 self
._runCheckerTestExpectError
(self
._CR
_DEFINE
_DEFINITION
+ """
135 cr.define('a.b.c', function() {
137 function ClassInternalName() {}
139 ClassInternalName.prototype = {
140 /** @param {number} num */
141 method: function(num) {}
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() {
157 var ClassInternalName = function() {};
159 ClassInternalName.prototype = {
160 /** @param {number} num */
161 method: function(num) {}
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'};
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 "
191 def testObjectDefineProperty(self
):
192 self
._runCheckerTestExpectSuccess
("""
196 Object.defineProperty(Class.prototype, 'myProperty', {});
198 alert(new Class().myProperty);
201 def testCrDefineProperty(self
):
202 self
._runCheckerTestExpectSuccess
(self
._CR
_DEFINE
_DEFINITION
+ """
206 cr.defineProperty(Class.prototype, 'myProperty', cr.PropertyKind.JS);
208 alert(new Class().myProperty);
211 def testCrDefinePropertyTypeChecking(self
):
212 self
._runCheckerTestExpectError
(self
._CR
_DEFINE
_DEFINITION
+ """
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 "
225 def testCrDefineOnCrWorks(self
):
226 self
._runCheckerTestExpectSuccess
(self
._CR
_DEFINE
_DEFINITION
+ """
227 cr.define('cr', function() {
232 def testAssertWorks(self
):
233 self
._runCheckerTestExpectSuccess
(self
._ASSERT
_DEFINITION
+ """
234 /** @return {?string} */
239 /** @type {!string} */
243 def testAssertInstanceofWorks(self
):
244 self
._runCheckerTestExpectSuccess
(self
._ASSERT
_DEFINITION
+ """
248 /** @return {Class} */
250 var a = document.createElement('div');
251 return assertInstanceof(a, Class);
255 def testCrUiDecorateWorks(self
):
256 self
._runCheckerTestExpectSuccess
(self
._CR
_DEFINE
_DEFINITION
+
257 self
._CR
_UI
_DECORATE
_DEFINITION
+ """
261 /** @return {Class} */
263 var a = document.createElement('div');
264 cr.ui.decorate(a, Class);
269 def testValidScriptCompilation(self
):
270 self
._runCheckerTestExpectSuccess
("""
271 var testScript = function() {
272 console.log("hello world")
275 """'use strict';var testScript=function(){console.log("hello world")};\n""")
277 def testOutputWrapper(self
):
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
:
293 goog.provide('testScript');
295 var testScript = function() {};
297 self
._tmp
_files
.append(source_file1
.name
)
299 source_file2
= tempfile
.NamedTemporaryFile(delete
=False)
300 with
open(source_file2
.name
, "w") as f
:
302 goog.require('testScript');
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
,
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__":