| OLD | NEW |
| (Empty) |
| 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. | |
| 5 | |
| 6 import os | |
| 7 import unittest | |
| 8 | |
| 9 from compile import Checker | |
| 10 from processor import FileCache, Processor | |
| 11 | |
| 12 | |
| 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") | |
| 19 _POLYMER_EXTERNS = os.path.join(_SRC_DIR, "third_party", "polymer", "v0_8", | |
| 20 "components-chromium", "polymer-externs", | |
| 21 "polymer.externs.js") | |
| 22 | |
| 23 | |
| 24 class CompilerCustomizationTest(unittest.TestCase): | |
| 25 _ASSERT_DEFINITION = Processor(_ASSERT_JS).contents | |
| 26 _CR_DEFINE_DEFINITION = Processor(_CR_JS).contents | |
| 27 _CR_UI_DECORATE_DEFINITION = Processor(_CR_UI_JS).contents | |
| 28 | |
| 29 def setUp(self): | |
| 30 self._checker = Checker() | |
| 31 | |
| 32 def _runChecker(self, source_code): | |
| 33 file_path = "/script.js" | |
| 34 FileCache._cache[file_path] = source_code | |
| 35 return self._checker.check(file_path, externs=[_POLYMER_EXTERNS]) | |
| 36 | |
| 37 def _runCheckerTestExpectError(self, source_code, expected_error): | |
| 38 _, stderr = self._runChecker(source_code) | |
| 39 | |
| 40 self.assertTrue(expected_error in stderr, | |
| 41 msg="Expected chunk: \n%s\n\nOutput:\n%s\n" % ( | |
| 42 expected_error, stderr)) | |
| 43 | |
| 44 def _runCheckerTestExpectSuccess(self, source_code): | |
| 45 found_errors, stderr = self._runChecker(source_code) | |
| 46 | |
| 47 self.assertFalse(found_errors, | |
| 48 msg="Expected success, but got failure\n\nOutput:\n%s\n" % stderr) | |
| 49 | |
| 50 def testGetInstance(self): | |
| 51 self._runCheckerTestExpectError(""" | |
| 52 var cr = { | |
| 53 /** @param {!Function} ctor */ | |
| 54 addSingletonGetter: function(ctor) { | |
| 55 ctor.getInstance = function() { | |
| 56 return ctor.instance_ || (ctor.instance_ = new ctor()); | |
| 57 }; | |
| 58 } | |
| 59 }; | |
| 60 | |
| 61 /** @constructor */ | |
| 62 function Class() { | |
| 63 /** @param {number} num */ | |
| 64 this.needsNumber = function(num) {}; | |
| 65 } | |
| 66 | |
| 67 cr.addSingletonGetter(Class); | |
| 68 Class.getInstance().needsNumber("wrong type"); | |
| 69 """, "ERROR - actual parameter 1 of Class.needsNumber does not match formal " | |
| 70 "parameter") | |
| 71 | |
| 72 def testCrDefineFunctionDefinition(self): | |
| 73 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ | |
| 74 cr.define('a.b.c', function() { | |
| 75 /** @param {number} num */ | |
| 76 function internalName(num) {} | |
| 77 | |
| 78 return { | |
| 79 needsNumber: internalName | |
| 80 }; | |
| 81 }); | |
| 82 | |
| 83 a.b.c.needsNumber("wrong type"); | |
| 84 """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal " | |
| 85 "parameter") | |
| 86 | |
| 87 def testCrDefineFunctionAssignment(self): | |
| 88 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ | |
| 89 cr.define('a.b.c', function() { | |
| 90 /** @param {number} num */ | |
| 91 var internalName = function(num) {}; | |
| 92 | |
| 93 return { | |
| 94 needsNumber: internalName | |
| 95 }; | |
| 96 }); | |
| 97 | |
| 98 a.b.c.needsNumber("wrong type"); | |
| 99 """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal " | |
| 100 "parameter") | |
| 101 | |
| 102 def testCrDefineConstructorDefinitionPrototypeMethod(self): | |
| 103 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ | |
| 104 cr.define('a.b.c', function() { | |
| 105 /** @constructor */ | |
| 106 function ClassInternalName() {} | |
| 107 | |
| 108 ClassInternalName.prototype = { | |
| 109 /** @param {number} num */ | |
| 110 method: function(num) {} | |
| 111 }; | |
| 112 | |
| 113 return { | |
| 114 ClassExternalName: ClassInternalName | |
| 115 }; | |
| 116 }); | |
| 117 | |
| 118 new a.b.c.ClassExternalName().method("wrong type"); | |
| 119 """, "ERROR - actual parameter 1 of a.b.c.ClassExternalName.prototype.method " | |
| 120 "does not match formal parameter") | |
| 121 | |
| 122 def testCrDefineConstructorAssignmentPrototypeMethod(self): | |
| 123 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ | |
| 124 cr.define('a.b.c', function() { | |
| 125 /** @constructor */ | |
| 126 var ClassInternalName = function() {}; | |
| 127 | |
| 128 ClassInternalName.prototype = { | |
| 129 /** @param {number} num */ | |
| 130 method: function(num) {} | |
| 131 }; | |
| 132 | |
| 133 return { | |
| 134 ClassExternalName: ClassInternalName | |
| 135 }; | |
| 136 }); | |
| 137 | |
| 138 new a.b.c.ClassExternalName().method("wrong type"); | |
| 139 """, "ERROR - actual parameter 1 of a.b.c.ClassExternalName.prototype.method " | |
| 140 "does not match formal parameter") | |
| 141 | |
| 142 def testCrDefineEnum(self): | |
| 143 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ | |
| 144 cr.define('a.b.c', function() { | |
| 145 /** @enum {string} */ | |
| 146 var internalNameForEnum = {key: 'wrong_type'}; | |
| 147 | |
| 148 return { | |
| 149 exportedEnum: internalNameForEnum | |
| 150 }; | |
| 151 }); | |
| 152 | |
| 153 /** @param {number} num */ | |
| 154 function needsNumber(num) {} | |
| 155 | |
| 156 needsNumber(a.b.c.exportedEnum.key); | |
| 157 """, "ERROR - actual parameter 1 of needsNumber does not match formal " | |
| 158 "parameter") | |
| 159 | |
| 160 def testObjectDefineProperty(self): | |
| 161 self._runCheckerTestExpectSuccess(""" | |
| 162 /** @constructor */ | |
| 163 function Class() {} | |
| 164 | |
| 165 Object.defineProperty(Class.prototype, 'myProperty', {}); | |
| 166 | |
| 167 alert(new Class().myProperty); | |
| 168 """) | |
| 169 | |
| 170 def testCrDefineProperty(self): | |
| 171 self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION + """ | |
| 172 /** @constructor */ | |
| 173 function Class() {} | |
| 174 | |
| 175 cr.defineProperty(Class.prototype, 'myProperty', cr.PropertyKind.JS); | |
| 176 | |
| 177 alert(new Class().myProperty); | |
| 178 """) | |
| 179 | |
| 180 def testCrDefinePropertyTypeChecking(self): | |
| 181 self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ | |
| 182 /** @constructor */ | |
| 183 function Class() {} | |
| 184 | |
| 185 cr.defineProperty(Class.prototype, 'booleanProp', cr.PropertyKind.BOOL_ATTR); | |
| 186 | |
| 187 /** @param {number} num */ | |
| 188 function needsNumber(num) {} | |
| 189 | |
| 190 needsNumber(new Class().booleanProp); | |
| 191 """, "ERROR - actual parameter 1 of needsNumber does not match formal " | |
| 192 "parameter") | |
| 193 | |
| 194 def testCrDefineOnCrWorks(self): | |
| 195 self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION + """ | |
| 196 cr.define('cr', function() { | |
| 197 return {}; | |
| 198 }); | |
| 199 """) | |
| 200 | |
| 201 def testAssertWorks(self): | |
| 202 self._runCheckerTestExpectSuccess(self._ASSERT_DEFINITION + """ | |
| 203 /** @return {?string} */ | |
| 204 function f() { | |
| 205 return "string"; | |
| 206 } | |
| 207 | |
| 208 /** @type {!string} */ | |
| 209 var a = assert(f()); | |
| 210 """) | |
| 211 | |
| 212 def testAssertInstanceofWorks(self): | |
| 213 self._runCheckerTestExpectSuccess(self._ASSERT_DEFINITION + """ | |
| 214 /** @constructor */ | |
| 215 function Class() {} | |
| 216 | |
| 217 /** @return {Class} */ | |
| 218 function f() { | |
| 219 var a = document.createElement('div'); | |
| 220 return assertInstanceof(a, Class); | |
| 221 } | |
| 222 """) | |
| 223 | |
| 224 def testCrUiDecorateWorks(self): | |
| 225 self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION + | |
| 226 self._CR_UI_DECORATE_DEFINITION + """ | |
| 227 /** @constructor */ | |
| 228 function Class() {} | |
| 229 | |
| 230 /** @return {Class} */ | |
| 231 function f() { | |
| 232 var a = document.createElement('div'); | |
| 233 cr.ui.decorate(a, Class); | |
| 234 return a; | |
| 235 } | |
| 236 """) | |
| 237 | |
| 238 | |
| 239 if __name__ == "__main__": | |
| 240 unittest.main() | |
| OLD | NEW |