def setUp(self): self._checker = Checker() self._tmp_files = []
class CompilerTest(unittest.TestCase): _ASSERT_DEFINITION = Processor(_ASSERT_JS).contents _CR_DEFINE_DEFINITION = Processor(_CR_JS).contents _CR_UI_DECORATE_DEFINITION = Processor(_CR_UI_JS).contents def setUp(self): self._checker = Checker() self._tmp_files = [] def tearDown(self): for file in self._tmp_files: if os.path.exists(file): os.remove(file) def _runChecker(self, source_code, output_wrapper=None): file_path = "/script.js" FileCache._cache[file_path] = source_code out_file, out_map = self._createOutFiles() externs = [_POLYMER_EXTERNS, _CHROME_SEND_EXTERNS] found_errors, stderr = self._checker.check(file_path, externs=externs, out_file=out_file, output_wrapper=output_wrapper) return found_errors, stderr, out_file, out_map def _runCheckerTestExpectError(self, source_code, expected_error): _, stderr, out_file, out_map = self._runChecker(source_code) self.assertTrue(expected_error in stderr, msg="Expected chunk: \n%s\n\nOutput:\n%s\n" % ( expected_error, stderr)) self.assertFalse(os.path.exists(out_file)) self.assertFalse(os.path.exists(out_map)) def _runCheckerTestExpectSuccess(self, source_code, expected_output=None, output_wrapper=None): found_errors, stderr, out_file, out_map = self._runChecker(source_code, output_wrapper) self.assertFalse(found_errors, msg="Expected success, but got failure\n\nOutput:\n%s\n" % stderr) self.assertTrue(os.path.exists(out_map)) self.assertTrue(os.path.exists(out_file)) if expected_output: with open(out_file, "r") as file: self.assertEquals(file.read(), expected_output) def _createOutFiles(self): out_file = tempfile.NamedTemporaryFile(delete=False) out_map = "%s.map" % out_file.name self._tmp_files.append(out_file.name) self._tmp_files.append(out_map) return out_file.name, out_map def testGetInstance(self): self._runCheckerTestExpectError(""" var cr = { /** @param {!Function} ctor */ addSingletonGetter: function(ctor) { ctor.getInstance = function() { return ctor.instance_ || (ctor.instance_ = new ctor()); }; } }; /** @constructor */ function Class() { /** @param {number} num */ this.needsNumber = function(num) {}; } cr.addSingletonGetter(Class); Class.getInstance().needsNumber("wrong type"); """, "ERROR - actual parameter 1 of Class.needsNumber does not match formal " "parameter") def testCrDefineFunctionDefinition(self): self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ cr.define('a.b.c', function() { /** @param {number} num */ function internalName(num) {} return { needsNumber: internalName }; }); a.b.c.needsNumber("wrong type"); """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal " "parameter") def testCrDefineFunctionAssignment(self): self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ cr.define('a.b.c', function() { /** @param {number} num */ var internalName = function(num) {}; return { needsNumber: internalName }; }); a.b.c.needsNumber("wrong type"); """, "ERROR - actual parameter 1 of a.b.c.needsNumber does not match formal " "parameter") def testCrDefineConstructorDefinitionPrototypeMethod(self): self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ cr.define('a.b.c', function() { /** @constructor */ function ClassInternalName() {} ClassInternalName.prototype = { /** @param {number} num */ method: function(num) {} }; return { ClassExternalName: ClassInternalName }; }); new a.b.c.ClassExternalName().method("wrong type"); """, "ERROR - actual parameter 1 of a.b.c.ClassExternalName.prototype.method " "does not match formal parameter") def testCrDefineConstructorAssignmentPrototypeMethod(self): self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ cr.define('a.b.c', function() { /** @constructor */ var ClassInternalName = function() {}; ClassInternalName.prototype = { /** @param {number} num */ method: function(num) {} }; return { ClassExternalName: ClassInternalName }; }); new a.b.c.ClassExternalName().method("wrong type"); """, "ERROR - actual parameter 1 of a.b.c.ClassExternalName.prototype.method " "does not match formal parameter") def testCrDefineEnum(self): self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ cr.define('a.b.c', function() { /** @enum {string} */ var internalNameForEnum = {key: 'wrong_type'}; return { exportedEnum: internalNameForEnum }; }); /** @param {number} num */ function needsNumber(num) {} needsNumber(a.b.c.exportedEnum.key); """, "ERROR - actual parameter 1 of needsNumber does not match formal " "parameter") def testObjectDefineProperty(self): self._runCheckerTestExpectSuccess(""" /** @constructor */ function Class() {} Object.defineProperty(Class.prototype, 'myProperty', {}); alert(new Class().myProperty); """) def testCrDefineProperty(self): self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION + """ /** @constructor */ function Class() {} cr.defineProperty(Class.prototype, 'myProperty', cr.PropertyKind.JS); alert(new Class().myProperty); """) def testCrDefinePropertyTypeChecking(self): self._runCheckerTestExpectError(self._CR_DEFINE_DEFINITION + """ /** @constructor */ function Class() {} cr.defineProperty(Class.prototype, 'booleanProp', cr.PropertyKind.BOOL_ATTR); /** @param {number} num */ function needsNumber(num) {} needsNumber(new Class().booleanProp); """, "ERROR - actual parameter 1 of needsNumber does not match formal " "parameter") def testCrDefineOnCrWorks(self): self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION + """ cr.define('cr', function() { return {}; }); """) def testAssertWorks(self): self._runCheckerTestExpectSuccess(self._ASSERT_DEFINITION + """ /** @return {?string} */ function f() { return "string"; } /** @type {!string} */ var a = assert(f()); """) def testAssertInstanceofWorks(self): self._runCheckerTestExpectSuccess(self._ASSERT_DEFINITION + """ /** @constructor */ function Class() {} /** @return {Class} */ function f() { var a = document.createElement('div'); return assertInstanceof(a, Class); } """) def testCrUiDecorateWorks(self): self._runCheckerTestExpectSuccess(self._CR_DEFINE_DEFINITION + self._CR_UI_DECORATE_DEFINITION + """ /** @constructor */ function Class() {} /** @return {Class} */ function f() { var a = document.createElement('div'); cr.ui.decorate(a, Class); return a; } """) def testValidScriptCompilation(self): self._runCheckerTestExpectSuccess(""" var testScript = function() { console.log("hello world") }; """, """'use strict';var testScript=function(){console.log("hello world")};\n""") def testOutputWrapper(self): source_code = """ var testScript = function() { console.log("hello world"); }; """ expected_output = ("""(function(){'use strict';var testScript=function()""" """{console.log("hello world")};})();\n""") output_wrapper="(function(){%output%})();" self._runCheckerTestExpectSuccess(source_code, expected_output, output_wrapper=output_wrapper) def testCheckMultiple(self): source_file1 = tempfile.NamedTemporaryFile(delete=False) with open(source_file1.name, "w") as f: f.write(""" goog.provide('testScript'); var testScript = function() {}; """) self._tmp_files.append(source_file1.name) source_file2 = tempfile.NamedTemporaryFile(delete=False) with open(source_file2.name, "w") as f: f.write(""" goog.require('testScript'); testScript(); """) self._tmp_files.append(source_file2.name) out_file, out_map = self._createOutFiles() sources = [source_file1.name, source_file2.name] externs = [_POLYMER_EXTERNS] found_errors, stderr = self._checker.check_multiple(sources, externs=externs, out_file=out_file) self.assertFalse(found_errors, msg="Expected success, but got failure\n\nOutput:\n%s\n" % stderr) expected_output = "'use strict';var testScript=function(){};testScript();\n" self.assertTrue(os.path.exists(out_map)) self.assertTrue(os.path.exists(out_file)) with open(out_file, "r") as file: self.assertEquals(file.read(), expected_output)