def testReferenceInColorPalette(self): mock_input_api = MockInputApi() mock_input_api.files = [ MockFile(helpers.COLOR_PALETTE_PATH, ['<resources><color name="foo">#f0f0f0</color></resources>']), MockFile('ui/android/java/res/values/semantic_colors_adaptive.xml', ['<color name="b">@color/foo<color>']), MockFile('ui/android/java/res/values/colors.xml', [ '<color name="c">@color/b</color>', '<color name="d">@color/b</color>', '<color name="e">@color/foo</color>' ]) ] warnings = checkxmlstyle._CheckColorPaletteReferences( mock_input_api, MockOutputApi()) self.assertEqual(1, len(warnings))
def testSucess_WrongBuilderCheck(self): """Use of OS-dependent AlertDialog should not be flagged.""" mock_input = MockInputApi() mock_input.files = [ MockFile('path/One.java', [ 'import android.app.AlertDialog;', 'new AlertDialog.Builder()' ]), MockFile('path/Two.java', [ 'import android.app.AlertDialog;', 'new AlertDialog.Builder(context);' ]), ] errors = PRESUBMIT._CheckAlertDialogBuilder(mock_input, MockOutputApi()) self.assertEqual(1, len(errors)) self.assertEqual(2, len(errors[0].items))
def testReferenceInSemanticColors(self): mock_input_api = MockInputApi() mock_input_api.files = [ MockFile(helpers.COLOR_PALETTE_PATH, ['<resources><color name="a">#f0f0f0</color></resources>']), MockFile('ui/android/java/res/values/semantic_colors_non_adaptive.xml', [ '<color name="b">@color/hello<color>', '<color name="c">@color/a<color>' ]), MockFile('ui/android/java/res/values/semantic_colors_adaptive.xml', ['<color name="c">@color/a<color>']) ] errors = checkxmlstyle._CheckSemanticColorsReferences( mock_input_api, MockOutputApi()) self.assertEqual(1, len(errors))
def testCheckInternalHeaderWithBlinkMojo(self): """This verifies that _CheckForWrongMojomIncludes accepts -blink mojo headers in blink internal files. """ mock_input_api = MockInputApi() potentially_bad_content = '#include "public/platform/modules/cache_storage.mojom-blink.h"' mock_input_api.files = [ MockAffectedFile('third_party/WebKit/Source/public/AHeader.h', [potentially_bad_content], None) ] # Access to a protected member _CheckForWrongMojomIncludes # pylint: disable=W0212 errors = PRESUBMIT._CheckForWrongMojomIncludes(mock_input_api, MockOutputApi()) self.assertEquals([], errors)
def testBannedIosObcjFunctions(self): input_api = MockInputApi() input_api.files = [ MockFile('some/ios/file.mm', ['TEST(SomeClassTest, SomeInteraction) {', '}']), MockFile('some/mac/file.mm', ['TEST(SomeClassTest, SomeInteraction) {', '}']), MockFile('another/ios_file.mm', ['class SomeTest : public testing::Test {};']), ] errors = PRESUBMIT._CheckNoBannedFunctions(input_api, MockOutputApi()) self.assertEqual(1, len(errors)) self.assertTrue('some/ios/file.mm' in errors[0].message) self.assertTrue('another/ios_file.mm' in errors[0].message) self.assertTrue('some/mac/file.mm' not in errors[0].message)
def testCheckChangeOnUploadWithEmptyAffectedFileList(self, _): """This verifies that CheckChangeOnUpload will skip calling check-webkit-style if the affected file list is empty. """ diff_file_chromium1_h = ['some diff'] diff_file_chromium2_h = ['another diff'] mock_input_api = MockInputApi() mock_input_api.files = [ MockAffectedFile('first_file_chromium.h', diff_file_chromium1_h), MockAffectedFile('second_file_chromium.h', diff_file_chromium2_h) ] # Access to a protected member _CheckStyle # pylint: disable=W0212 PRESUBMIT._CheckStyle(mock_input_api, MockOutputApi()) # pylint: disable=E1101 subprocess.Popen.assert_not_called()
def testSingletonInArbitraryHeader(self): diff_singleton_h = ['base::subtle::AtomicWord ' 'Singleton<Type, Traits, DifferentiatingType>::'] diff_foo_h = ['// Singleton<Foo> in comment.', 'friend class Singleton<Foo>'] diff_bad_h = ['Foo* foo = Singleton<Foo>::get();'] mock_input_api = MockInputApi() mock_input_api.files = [MockAffectedFile('base/memory/singleton.h', diff_singleton_h), MockAffectedFile('foo.h', diff_foo_h), MockAffectedFile('bad.h', diff_bad_h)] warnings = PRESUBMIT._CheckSingletonInHeaders(mock_input_api, MockOutputApi()) self.assertEqual(1, len(warnings)) self.assertEqual('error', warnings[0].type) self.assertTrue('Found Singleton<T>' in warnings[0].message)
def testColorFormatLowerCase(self): lines = [ '<color name="color1">#61000000</color>', '<color name="color2">#EFFFFFFF</color>', '<color name="color3">#CcCcCC</color>' ] mock_input_api = MockInputApi() mock_input_api.files = [ MockFile('chrome/java/res_test/test.xml', lines) ] errors = checkxmlstyle._CheckColorFormat(mock_input_api, MockOutputApi()) self.assertEqual(1, len(errors)) self.assertEqual(1, len(errors[0].items)) self.assertEqual(' chrome/java/res_test/test.xml:3', errors[0].items[0].splitlines()[0])
def testSuccess_Widget(self): lines = [ '<RelativeLayout', 'xmlns:android="http://schemas.android.com/apk/res/android"', 'android:layout_width="match_parent"', 'android:layout_height="wrap_content">', '<View', 'android:background="@drawable/infobar_shadow_top"', 'android:visibility="gone" />', '</RelativeLayout>' ] mock_input_api = MockInputApi() mock_input_api.files = [ MockFile('chrome/java/res_test/test.xml', lines) ] errors = checkxmlstyle._CheckTextAppearance(mock_input_api, MockOutputApi()) self.assertEqual(0, len(errors))
def testExcludedIncludes(self): # #include <sys/...>'s can appear in any order. mock_input_api = MockInputApi() contents = ['#include <sys/b.h>', '#include <sys/a.h>'] mock_file = MockFile('', contents) warnings = PRESUBMIT._CheckIncludeOrderInFile( mock_input_api, mock_file, range(1, len(contents) + 1)) self.assertEqual(0, len(warnings)) contents = ['#include "build/build_config.h"', '#include "aaa.h"'] mock_file = MockFile('', contents) warnings = PRESUBMIT._CheckIncludeOrderInFile( mock_input_api, mock_file, range(1, len(contents) + 1)) self.assertEqual(0, len(warnings))
def testTypicalNotMatchedChangeViaSuffixes(self): diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)'] diff_xml = [ '<histogram_suffixes name="SuperHistogram">', ' <suffix name="Dummy"/>', ' <affected-histogram name="Snafu.Dummy"/>', '</histogram>' ] mock_input_api = MockInputApi() mock_input_api.files = [ MockFile('some/path/foo.cc', diff_cc), MockFile('tools/metrics/histograms/histograms.xml', diff_xml), ] warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api, MockOutputApi()) self.assertEqual(1, len(warnings)) self.assertEqual('warning', warnings[0].type)
def testFailure_Widget(self): lines_top_level = [ '<TextView', 'xmlns:android="http://schemas.android.com/apk/res/android"', 'android:layout_width="match_parent"', 'android:layout_height="@dimen/snippets_article_header_height"', 'android:textColor="@color/snippets_list_header_text_color"', 'android:textSize="14sp" />'] lines_subcomponent_widget = [ '<RelativeLayout', 'xmlns:android="http://schemas.android.com/apk/res/android"', 'android:layout_width="match_parent"', 'android:layout_height="wrap_content">', '<View', 'android:textColor="@color/error_text_color"', 'android:textSize="@dimen/text_size_medium"', 'android:textAllCaps="true"', 'android:background="@drawable/infobar_shadow_top"', 'android:visibility="gone" />', '</RelativeLayout>'] mock_input_api = MockInputApi() mock_input_api.files = [ MockFile('chrome/java/res_test/test1.xml', lines_top_level), MockFile('chrome/java/res_test/test2.xml', lines_subcomponent_widget)] errors = checkxmlstyle._CheckTextAppearance(mock_input_api, MockOutputApi()) self.assertEqual(1, len(errors)) self.assertEqual(5, len(errors[0].items)) self.assertEqual( (' chrome/java/res_test/test1.xml:5 contains attribute ' 'android:textColor'), errors[0].items[0].splitlines()[0]) self.assertEqual( (' chrome/java/res_test/test1.xml:6 contains attribute ' 'android:textSize'), errors[0].items[1].splitlines()[0]) self.assertEqual( (' chrome/java/res_test/test2.xml:6 contains attribute ' 'android:textColor'), errors[0].items[2].splitlines()[0]) self.assertEqual( (' chrome/java/res_test/test2.xml:7 contains attribute ' 'android:textSize'), errors[0].items[3].splitlines()[0]) self.assertEqual( (' chrome/java/res_test/test2.xml:8 contains attribute ' 'android:textAllCaps'), errors[0].items[4].splitlines()[0])
def testAndroidChangeIncluded(self): mock_input_api = MockInputApi() mock_input_api.files = [ MockAffectedFile('content/test/data/accessibility/event/foo.html', [''], action='A'), MockAffectedFile( 'accessibility/WebContentsAccessibilityEventsTest.java', [''], action='M') ] msgs = PRESUBMIT.CheckAccessibilityEventsTestIncludesAndroid( mock_input_api, MockOutputApi()) self.assertEqual( 0, len(msgs), 'Expected %d messages, found %d: %s' % (0, len(msgs), msgs))
def testCheckCrbugLinksHaveHttps(self): input_api = MockInputApi() input_api.files = [ MockFile('somewhere/file.cc', [ '// TODO(developer): crbug.com should be linkified', '// TODO(developer): (crbug.com) should be linkified', '// TODO(developer): crbug/123 should be well formed', '// TODO(developer): http://crbug.com it\'s OK', '// TODO(developer): https://crbug.com is just great', '// TODO(crbug.com/123456): this pattern it\'s also OK' ]), ] warnings = PRESUBMIT._CheckCrbugLinksHaveHttps(input_api, MockOutputApi()) self.assertEqual(1, len(warnings)) self.assertEqual(3, warnings[0].message.count('\n'))
def testSuccess_Style(self): lines = [ '<resource>', '<style name="TextAppearance.Test">', '<item name="android:textColor">@color/default_text_color_link</item>', '<item name="android:textSize">14sp</item>', '<item name="android:textStyle">bold</item>', '<item name="android:fontFamily">some-font</item>', '<item name="android:textAllCaps">true</item>', '</style>', '<style name="TestStyle">', '<item name="android:background">some_background</item>', '</style>', '</resource>' ] mock_input_api = MockInputApi() mock_input_api.files = [MockFile('chrome/path/test.xml', lines)] errors = PRESUBMIT._CheckTextAppearance(mock_input_api, MockOutputApi()) self.assertEqual(0, len(errors))
def testFailure(self): lines = [ '<color name="color1">#61000000</color>', '<color name="color2">#61000000</color>' ] mock_input_api = MockInputApi() mock_input_api.files = [ MockFile(helpers.COLOR_PALETTE_RELATIVE_PATH, lines) ] errors = checkxmlstyle._CheckDuplicateColors(mock_input_api, MockOutputApi()) self.assertEqual(1, len(errors)) self.assertEqual(2, len(errors[0].items)) self.assertEqual(' %s:1' % helpers.COLOR_PALETTE_RELATIVE_PATH, errors[0].items[0].splitlines()[0]) self.assertEqual(' %s:2' % helpers.COLOR_PALETTE_RELATIVE_PATH, errors[0].items[1].splitlines()[0])
def testUserMetricsActionNotAddedToActions(self): input_api = MockInputApi() file_with_user_action = 'file_with_user_action.cc' contents_with_user_action = [ 'base::UserMetricsAction("NotInActionsXml")' ] input_api.files = [MockFile(file_with_user_action, contents_with_user_action)] output = PRESUBMIT._CheckUserActionUpdate(input_api, MockOutputApi()) self.assertEqual( ('File %s line %d: %s is missing in ' 'tools/metrics/actions/actions.xml. Please run ' 'tools/metrics/actions/extract_actions.py to update.' % (file_with_user_action, 1, 'NotInActionsXml')), output[0].message)
def testCatchAnswerUrlId(self): input_api = MockInputApi() input_api.files = [ MockFile('somewhere/file.cc', [ 'char* host = ' ' "https://support.google.com/chrome/answer/123456";' ]), MockFile('somewhere_else/file.cc', [ 'char* host = ' ' "https://support.google.com/chrome/a/answer/123456";' ]), ] warnings = PRESUBMIT._CheckGoogleSupportAnswerUrl( input_api, MockOutputApi()) self.assertEqual(1, len(warnings)) self.assertEqual(2, len(warnings[0].items))
def testFailure(self): lines = [ '<resource>', '<style name="TextAppearance.Test">', '<item name="android:textColor">@color/default_text_color_link</item>', '<item name="android:textSize">14sp</item>', '</style>', '</resource>' ] mock_input_api = MockInputApi() mock_input_api.files = [ MockFile('chrome/java/res_test/test.xml', lines) ] errors = checkxmlstyle._CheckNewTextAppearance(mock_input_api, MockOutputApi()) self.assertEqual(1, len(errors)) self.assertEqual(1, len(errors[0].items)) self.assertEqual(' chrome/java/res_test/test.xml:2', errors[0].items[0].splitlines()[0])
def testFailure(self): lines = [ '<color name="color1">#61000000</color>', '<color name="color2">#61000000</color>' ] mock_input_api = MockInputApi() mock_input_api.files = [ MockFile('chrome/java/res_test/colors.xml', lines) ] errors = checkxmlstyle._CheckDuplicateColors(mock_input_api, MockOutputApi()) self.assertEqual(1, len(errors)) self.assertEqual(2, len(errors[0].items)) self.assertEqual(' chrome/java/res_test/colors.xml:1', errors[0].items[0].splitlines()[0]) self.assertEqual(' chrome/java/res_test/colors.xml:2', errors[0].items[1].splitlines()[0])
def testCheckPublicHeaderWithBlinkMojo(self): """This verifies that _CheckForWrongMojomIncludes detects -blink mojo headers in public files. """ mock_input_api = MockInputApi() potentially_bad_content = '#include "public/platform/modules/cache_storage.mojom-blink.h"' mock_input_api.files = [ MockAffectedFile('third_party/blink/public/a_header.h', [potentially_bad_content], None) ] # Access to a protected member _CheckForWrongMojomIncludes # pylint: disable=W0212 errors = PRESUBMIT._CheckForWrongMojomIncludes(mock_input_api, MockOutputApi()) self.assertEquals( 'Public blink headers using Blink variant mojoms found. ' + 'You must include .mojom-shared.h instead:', errors[0].message)
def testFailure_WrongBuilderCheck(self): """Use of AppCompat AlertDialog.Builder is correctly flagged.""" mock_input = MockInputApi() mock_input.files = [ MockFile('path/One.java', [ 'import android.support.v7.app.AlertDialog;', 'new AlertDialog.Builder()' ]), MockFile('path/Two.java', [ 'import android.app.AlertDialog;', 'new AlertDialog.Builder(context);' ]), ] errors = PRESUBMIT._CheckAlertDialogBuilder(mock_input, MockOutputApi()) self.assertEqual(2, len(errors)) self.assertEqual(1, len(errors[1].items)) self.assertIn('One.java', errors[1].items[0])
def testFalsePositives(self): """Examples of when AlertDialog.Builder should not be flagged.""" mock_input = MockInputApi() mock_input.files = [ MockFile('path/One.java', ['AlertDialog.Builder']), MockFile('path/Two.java', ['// do not: new AlertDialog.Builder()']), MockFile('path/Three.java', [ '/** ChromeAlertDialogBuilder', ' * replaces: new AlertDialog.Builder()' ]), MockFile('path/PRESUBMIT.py', ['new AlertDialog.Builder()']), MockFile('path/Four.java', ['new AlertDialog.Builder()'], action='D'), ] errors = PRESUBMIT._CheckAlertDialogBuilder(mock_input, MockOutputApi()) self.assertEqual(0, len(errors))
def testCheckWamMintTriggerRule(self): COMMON_SRC_FILE_PATH = ( 'libs/common/src/org/chromium/webapk/lib/common/A.java') COMMON_JUNIT_FILE_PATH = ( 'libs/common/junit/src/org/chromium/webapk/lib/common/B.java') SHELL_APK_SRC_FILE_PATH = ( 'shell_apk/src/org/chromium/webapk/shell_apk/C.java') SHELL_APK_JUNIT_FILE_PATH = ( 'shell_apk/junit/src/org/chromium/webapk/shell_apk/D.java') changed_java_file_paths = [ COMMON_SRC_FILE_PATH, COMMON_JUNIT_FILE_PATH, SHELL_APK_SRC_FILE_PATH, SHELL_APK_JUNIT_FILE_PATH ] SHELL_APK_RES_FILE_PATH = 'shell_apk/res/mipmap-xxxxxxhdpi/app_icon.png' SHELL_APK_VERSION_FILE_PATH = 'shell_apk/shell_apk_version.gni' # template_shell_apk_version not updated. There should be a warning about # template_shell_apk_version needing to be updated. input_api = MockInputApi() input_api.files = self.makeMockAffectedFiles( changed_java_file_paths + [SHELL_APK_RES_FILE_PATH]) input_api.files += [ MockAffectedFile(SHELL_APK_VERSION_FILE_PATH, 'variable=O', 'variable=N', action='M') ] warnings = PRESUBMIT._CheckWamMintTriggerRule(input_api, MockOutputApi()) self.assertEqual(1, len(warnings)) self.assertEqual(self.UPDATE_TEMPLATE_SHELL_APK_VERSION_MESSAGE, warnings[0].message) self.assertEqual([COMMON_SRC_FILE_PATH, SHELL_APK_SRC_FILE_PATH, SHELL_APK_RES_FILE_PATH], warnings[0].items) # template_shell_apk_version updated. There should be no warnings. input_api.files = self.makeMockAffectedFiles( changed_java_file_paths + [SHELL_APK_RES_FILE_PATH]) input_api.files += [ MockAffectedFile(SHELL_APK_VERSION_FILE_PATH, ['template_shell_apk_version=1'], ['template_shell_apk_version=2'], action='M') ] warnings = PRESUBMIT._CheckWamMintTriggerRule(input_api, MockOutputApi()) self.assertEqual([], warnings)
def testCheckAndroidTestAnnotationUsage(self): mock_input_api = MockInputApi() mock_output_api = MockOutputApi() mock_input_api.files = [ MockAffectedFile('LalaLand.java', ['random stuff']), MockAffectedFile('CorrectUsage.java', [ 'import android.support.test.filters.LargeTest;', 'import android.support.test.filters.MediumTest;', 'import android.support.test.filters.SmallTest;', ]), MockAffectedFile('UsedDeprecatedLargeTestAnnotation.java', [ 'import android.test.suitebuilder.annotation.LargeTest;', ]), MockAffectedFile('UsedDeprecatedMediumTestAnnotation.java', [ 'import android.test.suitebuilder.annotation.MediumTest;', ]), MockAffectedFile('UsedDeprecatedSmallTestAnnotation.java', [ 'import android.test.suitebuilder.annotation.SmallTest;', ]), MockAffectedFile('UsedDeprecatedSmokeAnnotation.java', [ 'import android.test.suitebuilder.annotation.Smoke;', ]) ] msgs = PRESUBMIT._CheckAndroidTestAnnotationUsage( mock_input_api, mock_output_api) self.assertEqual( 1, len(msgs), 'Expected %d items, found %d: %s' % (1, len(msgs), msgs)) self.assertEqual( 4, len(msgs[0].items), 'Expected %d items, found %d: %s' % (4, len(msgs[0].items), msgs[0].items)) self.assertTrue( 'UsedDeprecatedLargeTestAnnotation.java:1' in msgs[0].items, 'UsedDeprecatedLargeTestAnnotation not found in errors') self.assertTrue( 'UsedDeprecatedMediumTestAnnotation.java:1' in msgs[0].items, 'UsedDeprecatedMediumTestAnnotation not found in errors') self.assertTrue( 'UsedDeprecatedSmallTestAnnotation.java:1' in msgs[0].items, 'UsedDeprecatedSmallTestAnnotation not found in errors') self.assertTrue( 'UsedDeprecatedSmokeAnnotation.java:1' in msgs[0].items, 'UsedDeprecatedSmokeAnnotation not found in errors')
def testIfElifElseEndif(self): mock_input_api = MockInputApi() contents = ['#include "e.h"', '#define foo', '#include "f.h"', '#undef foo', '#include "e.h"', '#if foo', '#include "d.h"', '#elif bar', '#include "c.h"', '#else', '#include "b.h"', '#endif', '#include "a.h"'] mock_file = MockFile('', contents) warnings = PRESUBMIT._CheckIncludeOrderInFile( mock_input_api, mock_file, range(1, len(contents) + 1)) self.assertEqual(0, len(warnings))
def testIgnoreNonRelatedHtmlFiles(self): mock_input_api = MockInputApi() mock_input_api.files = [ MockAffectedFile('content/test/data/accessibility/aria/foo.html', [''], action='A'), MockAffectedFile('content/test/data/accessibility/html/foo.html', [''], action='A'), MockAffectedFile('chrome/tests/data/accessibility/foo.html', [''], action='A') ] msgs = PRESUBMIT.CheckAccessibilityEventsTestIncludesAndroid( mock_input_api, MockOutputApi()) self.assertEqual( 0, len(msgs), 'Expected %d messages, found %d: %s' % (0, len(msgs), msgs))
def testCheckChangeOnUploadWithWebKitAndChromiumFiles(self, _): """This verifies that CheckChangeOnUpload will only call check-webkit-style on WebKit files. """ diff_file_webkit_h = ['some diff'] diff_file_chromium_h = ['another diff'] mock_input_api = MockInputApi() mock_input_api.files = [ MockAffectedFile('FileWebkit.h', diff_file_webkit_h), MockAffectedFile('file_chromium.h', diff_file_chromium_h) ] # Access to a protected member _CheckStyle # pylint: disable=W0212 PRESUBMIT._CheckStyle(mock_input_api, MockOutputApi()) capture = Capture() # pylint: disable=E1101 subprocess.Popen.assert_called_with(capture, stderr=-1) self.assertEqual(4, len(capture.value)) self.assertEqual('../../FileWebkit.h', capture.value[3])
def _runChecks(self, file_contents): tmp_args = {'suffix': '.js', 'dir': _HERE_PATH, 'delete': False} with tempfile.NamedTemporaryFile(**tmp_args) as f: self._tmp_file = f.name f.write(file_contents) input_api = MockInputApi() input_api.files = [MockFile(os.path.abspath(self._tmp_file), '')] input_api.presubmit_local_path = _HERE_PATH checker = js_checker.JSChecker(input_api, MockOutputApi()) try: return checker.RunEsLintChecks(input_api.AffectedFiles(), format='json') except RuntimeError as err: # Extract ESLint's JSON error output from the error message. json_error = err.message[err.message.index('['):] return json.loads(json_error)[0].get('messages')
def testMojoManifestChangeNeedsSecurityOwner(self): mock_input_api = MockInputApi() mock_input_api.files = [ MockAffectedFile('services/goat/manifest.json', [ '{', ' "name": "teleporter",', ' "display_name": "Goat Teleporter",' ' "interface_provider_specs": {', ' }', '}', ]) ] mock_output_api = MockOutputApi() errors = PRESUBMIT._CheckIpcOwners(mock_input_api, mock_output_api) self.assertEqual(1, len(errors)) self.assertEqual( 'Found OWNERS files that need to be updated for IPC security review ' + 'coverage.\nPlease update the OWNERS files below:', errors[0].message)