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.
9 from compile import Checker
10 from processor
import FileCache
, Processor
13 _SCRIPT_DIR
= os
.path
.dirname(os
.path
.abspath(__file__
))
14 _SRC_DIR
= os
.path
.join(_SCRIPT_DIR
, os
.pardir
, os
.pardir
)
15 _RESOURCES_DIR
= os
.path
.join(_SRC_DIR
, "ui", "webui", "resources", "js")
16 _ASSERT_JS
= os
.path
.join(_RESOURCES_DIR
, "assert.js")
17 _CR_JS
= os
.path
.join(_RESOURCES_DIR
, "cr.js")
18 _CR_UI_JS
= os
.path
.join(_RESOURCES_DIR
, "cr", "ui.js")
21 class CompilerCustomizationTest(unittest
.TestCase
):
22 _ASSERT_DEFINITION
= Processor(_ASSERT_JS
).contents
23 _CR_DEFINE_DEFINITION
= Processor(_CR_JS
).contents
24 _CR_UI_DECORATE_DEFINITION
= Processor(_CR_UI_JS
).contents
27 self
._checker
= Checker()
29 def _runChecker(self
, source_code
):
30 file_path
= "/script.js"
31 FileCache
._cache
[file_path
] = source_code
32 return self
._checker
.check(file_path
)
34 def _runCheckerTestExpectError(self
, source_code
, expected_error
):
35 _
, stderr
= self
._runChecker
(source_code
)
37 self
.assertTrue(expected_error
in stderr
,
38 msg
="Expected chunk: \n%s\n\nOutput:\n%s\n" % (
39 expected_error
, stderr
))
41 def _runCheckerTestExpectSuccess(self
, source_code
):
42 found_errors
, stderr
= self
._runChecker
(source_code
)
44 self
.assertFalse(found_errors
,
45 msg
="Expected success, but got failure\n\nOutput:\n%s\n" % stderr
)
47 def testGetInstance(self
):
48 self
._runCheckerTestExpectError
("""
50 /** @param {!Function} ctor */
51 addSingletonGetter: function(ctor) {
52 ctor.getInstance = function() {
53 return ctor.instance_ || (ctor.instance_ = new ctor());
60 /** @param {number} num */
61 this.needsNumber = function(num) {};
64 cr.addSingletonGetter(Class);
65 Class.getInstance().needsNumber("wrong type");
66 """, "ERROR - actual parameter 1 of Class.needsNumber does not match formal "
69 def testCrDefineFunctionDefinition(self
):
70 self
._runCheckerTestExpectError
(self
._CR
_DEFINE
_DEFINITION
+ """
71 cr.define('a.b.c', function() {
72 /** @param {number} num */
73 function internalName(num) {}
76 needsNumber: internalName
80 a.b.c.needsNumber("wrong type");
81 """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal "
84 def testCrDefineFunctionAssignment(self
):
85 self
._runCheckerTestExpectError
(self
._CR
_DEFINE
_DEFINITION
+ """
86 cr.define('a.b.c', function() {
87 /** @param {number} num */
88 var internalName = function(num) {};
91 needsNumber: internalName
95 a.b.c.needsNumber("wrong type");
96 """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal "
99 def testCrDefineConstructorDefinitionPrototypeMethod(self
):
100 self
._runCheckerTestExpectError
(self
._CR
_DEFINE
_DEFINITION
+ """
101 cr.define('a.b.c', function() {
103 function ClassInternalName() {}
105 ClassInternalName.prototype = {
106 /** @param {number} num */
107 method: function(num) {}
111 ClassExternalName: ClassInternalName
115 new a.b.c.ClassExternalName().method("wrong type");
116 """, "ERROR - actual parameter 1 of a.b.c.ClassExternalName.prototype.method "
117 "does not match formal parameter")
119 def testCrDefineConstructorAssignmentPrototypeMethod(self
):
120 self
._runCheckerTestExpectError
(self
._CR
_DEFINE
_DEFINITION
+ """
121 cr.define('a.b.c', function() {
123 var ClassInternalName = function() {};
125 ClassInternalName.prototype = {
126 /** @param {number} num */
127 method: function(num) {}
131 ClassExternalName: ClassInternalName
135 new a.b.c.ClassExternalName().method("wrong type");
136 """, "ERROR - actual parameter 1 of a.b.c.ClassExternalName.prototype.method "
137 "does not match formal parameter")
139 def testCrDefineEnum(self
):
140 self
._runCheckerTestExpectError
(self
._CR
_DEFINE
_DEFINITION
+ """
141 cr.define('a.b.c', function() {
142 /** @enum {string} */
143 var internalNameForEnum = {key: 'wrong_type'};
146 exportedEnum: internalNameForEnum
150 /** @param {number} num */
151 function needsNumber(num) {}
153 needsNumber(a.b.c.exportedEnum.key);
154 """, "ERROR - actual parameter 1 of needsNumber does not match formal "
157 def testObjectDefineProperty(self
):
158 self
._runCheckerTestExpectSuccess
("""
162 Object.defineProperty(Class.prototype, 'myProperty', {});
164 alert(new Class().myProperty);
167 def testCrDefineProperty(self
):
168 self
._runCheckerTestExpectSuccess
(self
._CR
_DEFINE
_DEFINITION
+ """
172 cr.defineProperty(Class.prototype, 'myProperty', cr.PropertyKind.JS);
174 alert(new Class().myProperty);
177 def testCrDefinePropertyTypeChecking(self
):
178 self
._runCheckerTestExpectError
(self
._CR
_DEFINE
_DEFINITION
+ """
182 cr.defineProperty(Class.prototype, 'booleanProp', cr.PropertyKind.BOOL_ATTR);
184 /** @param {number} num */
185 function needsNumber(num) {}
187 needsNumber(new Class().booleanProp);
188 """, "ERROR - actual parameter 1 of needsNumber does not match formal "
191 def testCrDefineOnCrWorks(self
):
192 self
._runCheckerTestExpectSuccess
(self
._CR
_DEFINE
_DEFINITION
+ """
193 cr.define('cr', function() {
198 def testAssertWorks(self
):
199 self
._runCheckerTestExpectSuccess
(self
._ASSERT
_DEFINITION
+ """
200 /** @return {?string} */
205 /** @type {!string} */
209 def testAssertInstanceofWorks(self
):
210 self
._runCheckerTestExpectSuccess
(self
._ASSERT
_DEFINITION
+ """
214 /** @return {Class} */
216 var a = document.createElement('div');
217 return assertInstanceof(a, Class);
221 def testCrUiDecorateWorks(self
):
222 self
._runCheckerTestExpectSuccess
(self
._CR
_DEFINE
_DEFINITION
+
223 self
._CR
_UI
_DECORATE
_DEFINITION
+ """
227 /** @return {Class} */
229 var a = document.createElement('div');
230 cr.ui.decorate(a, Class);
236 if __name__
== "__main__":