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 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/blink/renderer/core/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([], errors)
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 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 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 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 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 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 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 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 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 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 testAddFileSameNameAcrossResDirectories(self): # Adding a file to a res/ directory with the same file name as a file in a # different res/ directory is illegal. MOCK_FILE_SYSTEM_FILES = ['shell_apk/res/values/colors.xml', 'libs/common/res_splash/values/dimens.xml'] input_api = CustomMockInputApi() input_api.os_walk = MockOsWalkFileSystem(MOCK_FILE_SYSTEM_FILES).walk input_api.files = input_api.makeMockAffectedFiles([ 'shell_apk/res/values-v17/dimens.xml', 'libs/common/res_splash/values-v22/colors.xml']) errors = PRESUBMIT._CheckNoOverlappingFileNamesInResourceDirsRule( input_api, MockOutputApi()) self.assertEqual(1, len(errors)) self.assertEqual(self.RESOURCES_SHOULD_HAVE_DIFFERENT_FILE_NAMES_MESSAGE, errors[0].message) errors[0].items.sort() self.assertEqual(['colors.xml', 'dimens.xml'], errors[0].items)
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 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 _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 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 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)
def _testExternalReferenceInPackage(self, package): """Tests that an illegal external path within |package| is flagged.""" buildfile = _PACKAGE_BUILDFILES[package] mock_input_api = self.inputApiContainingFileWithPaths( buildfile, [ self.non_whitelisted_external_path, self.whitelisted_external_path ]) warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) if package == 'EDK': # All external paths are allowed in the EDK. self.assertEqual(0, len(warnings)) return self.assertEqual(1, len(warnings)) expected_message = PRESUBMIT._ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE self.checkWarningWithSingleItem(warnings[0], expected_message, buildfile, 1, self.non_whitelisted_external_path)
def testSuccess(self): """ Examples of when SplitCompatUtils.getIdentifierName() should not be flagged. """ mock_input = MockInputApi() mock_input.files = [ MockFile( 'path/One.java', ['SplitCompatUtils.getIdentifierName("foo")', 'A new line.']), MockFile('path/Two.java', ['SplitCompatUtils.getIdentifierName( "foo")']), MockFile('path/Three.java', ['SplitCompatUtils.getIdentifierName(', ' "bar")']), MockFile( 'path/Four.java', [' super(SplitCompatUtils.getIdentifierName(', '"bar"))']), ] errors = PRESUBMIT._CheckSplitCompatUtilsIdentifierName( mock_input, MockOutputApi()) self.assertEqual(0, len(errors))