#!/usr/bin/env python # Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import js_checker from os import path as os_path import re from sys import path as sys_path import test_util import unittest _HERE = os_path.dirname(os_path.abspath(__file__)) sys_path.append(os_path.join(_HERE, '..', '..', '..', 'build')) import find_depot_tools # pylint: disable=W0611 from testing_support.super_mox import SuperMoxTestBase class JsCheckerTest(SuperMoxTestBase): def setUp(self): SuperMoxTestBase.setUp(self) input_api = self.mox.CreateMockAnything() input_api.re = re output_api = self.mox.CreateMockAnything() self.checker = js_checker.JSChecker(input_api, output_api) def ShouldFailConstCheck(self, line): """Checks that the 'const' checker flags |line| as a style error.""" error = self.checker.ConstCheck(1, line) self.assertNotEqual('', error, 'Should be flagged as style error: ' + line) self.assertEqual(test_util.GetHighlight(line, error), 'const') def ShouldPassConstCheck(self, line): """Checks that the 'const' checker doesn't flag |line| as a style error.""" self.assertEqual('', self.checker.ConstCheck(1, line), 'Should not be flagged as style error: ' + line) def testConstFails(self): lines = [ "const foo = 'bar';", " const bar = 'foo';", # Trying to use |const| as a variable name "var const = 0;", "var x = 5; const y = 6;", "for (var i=0, const e=10; i} */", "var a = /** @type {Object.} */({});", "* @return {!Promise.}" ] for line in lines: self.ShouldFailExtraDotInGenericCheck(line) def ShouldFailGetElementByIdCheck(self, line): """Checks that the 'getElementById' checker flags |line| as a style error. """ error = self.checker.GetElementByIdCheck(1, line) self.assertNotEqual('', error, 'Should be flagged as style error: ' + line) self.assertEqual(test_util.GetHighlight(line, error), 'document.getElementById') def ShouldPassGetElementByIdCheck(self, line): """Checks that the 'getElementById' checker doesn't flag |line| as a style error. """ self.assertEqual('', self.checker.GetElementByIdCheck(1, line), 'Should not be flagged as style error: ' + line) def testGetElementByIdFails(self): lines = [ "document.getElementById('foo');", " document.getElementById('foo');", "var x = document.getElementById('foo');", "if (document.getElementById('foo').hidden) {", ] for line in lines: self.ShouldFailGetElementByIdCheck(line) def testGetElementByIdPasses(self): lines = [ "elem.ownerDocument.getElementById('foo');", " elem.ownerDocument.getElementById('foo');", "var x = elem.ownerDocument.getElementById('foo');", "if (elem.ownerDocument.getElementById('foo').hidden) {", "doc.getElementById('foo');", " doc.getElementById('foo');", "cr.doc.getElementById('foo');", " cr.doc.getElementById('foo');", "var x = doc.getElementById('foo');", "if (doc.getElementById('foo').hidden) {", ] for line in lines: self.ShouldPassGetElementByIdCheck(line) def ShouldFailInheritDocCheck(self, line): """Checks that the '@inheritDoc' checker flags |line| as a style error.""" error = self.checker.InheritDocCheck(1, line) self.assertNotEqual('', error, msg='Should be flagged as style error: ' + line) self.assertEqual(test_util.GetHighlight(line, error), '@inheritDoc') def ShouldPassInheritDocCheck(self, line): """Checks that the '@inheritDoc' checker doesn't flag |line| as a style error. """ self.assertEqual('', self.checker.InheritDocCheck(1, line), msg='Should not be flagged as style error: ' + line) def testInheritDocFails(self): lines = [ " /** @inheritDoc */", " * @inheritDoc", ] for line in lines: self.ShouldFailInheritDocCheck(line) def testInheritDocPasses(self): lines = [ "And then I said, but I won't @inheritDoc! Hahaha!", " If your dad's a doctor, do you inheritDoc?", " What's up, inherit doc?", " this.inheritDoc(someDoc)", ] for line in lines: self.ShouldPassInheritDocCheck(line) def ShouldFailWrapperTypeCheck(self, line): """Checks that the use of wrapper types (i.e. new Number(), @type {Number}) is a style error. """ error = self.checker.WrapperTypeCheck(1, line) self.assertNotEqual('', error, msg='Should be flagged as style error: ' + line) highlight = test_util.GetHighlight(line, error) self.assertTrue(highlight in ('Boolean', 'Number', 'String')) def ShouldPassWrapperTypeCheck(self, line): """Checks that the wrapper type checker doesn't flag |line| as a style error. """ self.assertEqual('', self.checker.WrapperTypeCheck(1, line), msg='Should not be flagged as style error: ' + line) def testWrapperTypePasses(self): lines = [ "/** @param {!ComplexType} */", " * @type {Object}", " * @param {Function=} opt_callback", " * @param {} num Number of things to add to {blah}.", " * @return {!print_preview.PageNumberSet}", " /* @returns {Number} */", # Should be /** @return {Number} */ "* @param {!LocalStrings}" " Your type of Boolean is false!", " Then I parameterized her Number from her friend!", " A String of Pearls", " types.params.aBoolean.typeString(someNumber)", ] for line in lines: self.ShouldPassWrapperTypeCheck(line) def testWrapperTypeFails(self): lines = [ " /**@type {String}*/(string)", " * @param{Number=} opt_blah A number", "/** @private @return {!Boolean} */", " * @param {number|String}", ] for line in lines: self.ShouldFailWrapperTypeCheck(line) def ShouldFailVarNameCheck(self, line): """Checks that var unix_hacker, $dollar are style errors.""" error = self.checker.VarNameCheck(1, line) self.assertNotEqual('', error, msg='Should be flagged as style error: ' + line) highlight = test_util.GetHighlight(line, error) self.assertFalse('var ' in highlight); def ShouldPassVarNameCheck(self, line): """Checks that variableNamesLikeThis aren't style errors.""" self.assertEqual('', self.checker.VarNameCheck(1, line), msg='Should not be flagged as style error: ' + line) def testVarNameFails(self): lines = [ "var private_;", " var _super_private", " var unix_hacker = someFunc();", ] for line in lines: self.ShouldFailVarNameCheck(line) def testVarNamePasses(self): lines = [ " var namesLikeThis = [];", " for (var i = 0; i < 10; ++i) { ", "for (var i in obj) {", " var one, two, three;", " var magnumPI = {};", " var g_browser = 'da browzer';", "/** @const */ var Bla = options.Bla;", # goog.scope() replacement. " var $ = function() {", # For legacy reasons. " var StudlyCaps = cr.define('bla')", # Classes. " var SCARE_SMALL_CHILDREN = [", # TODO(dbeam): add @const in # front of all these vars like "/** @const */ CONST_VAR = 1;", # this line has (<--). ] for line in lines: self.ShouldPassVarNameCheck(line) if __name__ == '__main__': unittest.main()