Exemple #1
0
    def test_parse_errors(self):
        test_string = """\
<?xml version="1.0" encoding="UTF-8"?>
<pmd version="5.5.0" timestamp="2016-07-06T11:29:03.360">
    <file name="{0}/DriverRideDrivingToWaypointController.java">
        <violation beginline="287" endline="287" begincolumn="58" endcolumn="61" rule="UnusedFormalParameter" ruleset="Unused Code" package="me.lyft.android.ui.driver.ridescreens" class="DriverRideDrivingToWaypointController" method="displayWaypointAddress" variable="ride" externalInfoUrl="https://pmd.github.io/pmd-5.5.0/pmd-java/rules/java/unusedcode.html#UnusedFormalParameter" priority="3">
        Avoid unused method parameters such as 'ride'.
    </violation>
    </file>
    <file name="{0}/AddCouponView.java">
        <violation beginline="24" endline="24" begincolumn="1" endcolumn="38" rule="UnusedImports" ruleset="Import Statements" package="me.lyft.android.ui.payment" externalInfoUrl="https://pmd.github.io/pmd-5.5.0/pmd-java/rules/java/imports.html#UnusedImports" priority="4">
        Avoid unused imports such as 'me.lyft.android.common.Strings'
        </violation>
    </file>
</pmd>
    """.format(os.path.curdir)

        result = pmd.parse(test_string)
        self.assertEqual(2, len(result))
        self.assertIn(
            Problem(
                './DriverRideDrivingToWaypointController.java', 287,
                'UnusedFormalParameter: Avoid unused method'
                " parameters such as 'ride'."), result)

        self.assertIn(
            Problem(
                './AddCouponView.java', 24,
                'UnusedImports: Avoid unused imports such as'
                " 'me.lyft.android.common.Strings'"), result)
Exemple #2
0
    def test_parse_errors(self):
        test_string = """\
<?xml version='1.0' encoding='UTF-8'?>
    <checkstyle version='4.3'>
        <file name='scripts/run&#95;tests.sh' >
            <error line='31'
             column='26' severity='info'
             message='Double quote to prevent globbing and word splitting.'
             source='ShellCheck.SC2086' />
        </file>
        <file name='scripts/setup.sh' >
            <error
             line='3'
             column='1'
             severity='warning'
             message='FOO appears unused. Verify it or export it.'
             source='ShellCheck.SC2034' />
        </file>
</checkstyle>
"""

        result = checkstyle.parse(test_string)
        self.assertEqual(2, len(result))
        self.assertIn(
            Problem(
                'scripts/run_tests.sh', 31,
                'ShellCheck.SC2086: Double quote to prevent '
                'globbing and word splitting.'), result)

        self.assertIn(
            Problem(
                'scripts/setup.sh', 3,
                'ShellCheck.SC2034: FOO appears unused. '
                'Verify it or export it.'), result)
Exemple #3
0
    def test_parse_errors(self):
        test_string = [
            '{}/Classes/Foo + Bar/Foo + Menu/Controllers/'
            'SomeController.swift:42: warning: '
            'Documentation Comment Violation: Needs documentation '
            'comment'.format(os.path.curdir),
            '{}/Classes/Foo + Bar/Foo + Menu/Controllers/'
            'AnotherController.swift:50:5: warning: '
            'Documentation Comment Violation: Needs documentation '
            'comment'.format(os.path.curdir)
        ]
        result = swiftlint.parse('\n'.join(test_string))
        self.assertEqual(2, len(result))

        self.assertIn(
            Problem(
                'Classes/Foo + Bar/Foo + Menu/Controllers/'
                'SomeController.swift', 42, 'Documentation Comment Violation: '
                'Needs documentation comment'), result)

        self.assertIn(
            Problem(
                'Classes/Foo + Bar/Foo + Menu/Controllers/'
                'AnotherController.swift', 50,
                'Documentation Comment Violation: '
                'Needs documentation comment'), result)
Exemple #4
0
    def test_parse_errors(self):
        test_string = [
            'Something happened!',
            "More stuff 'happened'",
        ]

        result = passthrough.parse('\n'.join(test_string))
        self.assertEqual(2, len(result))

        self.assertIn(Problem('', 0, 'Something happened!'), result)
        self.assertIn(Problem('', 0, "More stuff 'happened'"), result)
Exemple #5
0
    def test_parse_errors(self):
        test_string = '''
src/linters/pylint.py:10: [E302] expected 2 blank lines, found 1
tests/linters/pylint.py:42: [E302] expected 2 blank lines, found 1
'''
        result = pylint.parse(test_string)
        self.assertEqual(2, len(result))

        self.assertIn(
            Problem('src/linters/pylint.py', 10,
                    '[E302] expected 2 blank lines, found 1'), result)

        self.assertIn(
            Problem('tests/linters/pylint.py', 42,
                    '[E302] expected 2 blank lines, found 1'), result)
Exemple #6
0
    def test_comment_overflow(self, mock_getenv, mock_client_session):
        mock_args, fake_client_session = self.create_mock_pr(
            mock_getenv, mock_client_session)

        reporter = github_reporter.create_reporter(mock_args)

        problems = [Problem('another_file', x, 'Wat') for x in range(1, 13)]

        async_report = reporter.report('unit-test-linter', problems)

        loop = asyncio.get_event_loop()
        loop.run_until_complete(async_report)

        overflow_message = textwrap.dedent('''\
            unit-test-linter says:

            Too many lint errors to report inline!  12 lines have a problem.
            Only reporting the first 10.''')
        overflow_call = call.post(
            'https://api.github.com/repos/foo/bar/issues/1234/comments',
            headers={'Authorization': 'token MY_TOKEN'},
            data=json.dumps({
                'body': overflow_message,
            }, sort_keys=True))

        self.assertIn(overflow_call, fake_client_session.calls)
        self.assertEqual(3 + github_reporter.MAX_LINT_ERROR_REPORTS,
                         len(fake_client_session.calls))
Exemple #7
0
    def test_parse_errors(self):
        test_string = '''
src/linters/pylint.py: note: expected 2 blank lines, found 1
tests/linters/pylint.py:42: error: "module" has no attribute "foo"
tests/linters/pylint.py:33: error: "module" has no attribute "bar"
'''

        result = mypy.parse(test_string)
        self.assertEqual(2, len(result))
        self.assertIn(
            Problem('tests/linters/pylint.py', 42,
                    'error: "module" has no attribute "foo"'), result)

        self.assertIn(
            Problem('tests/linters/pylint.py', 33,
                    'error: "module" has no attribute "bar"'), result)
    def test_parse_all(self):
        result = android.parse(test_string, pass_warnings=False)
        self.assertEqual(2, len(result))
        self.assertIn(Problem('scripts/run_tests.sh',
                                      15,
                                      'ScrollView size validation: This LinearLayout '
                                      'should use '
                                      '`android:layout_height="wrap_content"`'),
                      result)

        self.assertIn(Problem('scripts/setup.sh',
                              238,
                              'Implied default locale in case conversion: '
                              'Implicitly using the default locale is a '
                              'common source of bugs: Use '
                              '`toLowerCase(Locale)` instead'),
                      result)
Exemple #9
0
def parse(contents: str, **kwargs) -> Set[Problem]:
    result = set()  # type: Set[Problem]
    for line in contents.splitlines():
        match = PYLINT_LINE_REGEX.match(line)
        if match:
            groups = match.groupdict()
            result.add(
                Problem(groups['path'], groups['line'], groups['message']))
    return result
 def test_parse_errors_only(self):
     result = android.parse(test_string, pass_warnings=True)
     self.assertEqual(1, len(result))
     self.assertIn(Problem('scripts/run_tests.sh',
                                   15,
                                   'ScrollView size validation: This LinearLayout '
                                   'should use '
                                   '`android:layout_height="wrap_content"`'),
                   result)
    def test_parse_errors(self):
        test_string = [
            "<unknown>:0: error: no such file or directory: 'foo.swift'",
            "<unknown>:0: ERROR: no such file or directory: 'case.swift'",
            "{}/Classes/foo/bar baz/qux.swift:201:21: "
            "error: use of unresolved identifier 'FooBar'".format(
                os.path.curdir),
            "{}/Classes/foo/bar/Protocols/SomeProtocol.swift:7:10: "
            "note: did you mean 'SomeOtherProtocol'?".format(os.path.curdir),
            "{}/Resources/Storyboards & XIBs/Foo.storyboard:kB7-Bl-wC0: "
            "warning: Unsupported configuration of constraint attributes. "
            "This may produce unexpected results at runtime before Xcode 5.1".
            format(os.path.curdir),
        ]

        result = xcodebuild.parse('\n'.join(test_string))
        self.assertEqual(5, len(result))

        self.assertIn(
            Problem('<unknown>', 0, "no such file or directory: 'foo.swift'"),
            result)

        self.assertIn(
            Problem('<unknown>', 0, "no such file or directory: 'case.swift'"),
            result)

        self.assertIn(
            Problem('Classes/foo/bar baz/'
                    'qux.swift', 201, "use of unresolved identifier 'FooBar'"),
            result)

        self.assertIn(
            Problem('Classes/foo/bar/Protocols/'
                    'SomeProtocol.swift', 7,
                    "did you mean 'SomeOtherProtocol'?"), result)

        self.assertIn(
            Problem(
                'Resources/Storyboards & XIBs/'
                'Foo.storyboard', 0,
                'kB7-Bl-wC0: Unsupported configuration of '
                'constraint attributes. This may produce unexpected '
                'results at runtime before Xcode 5.1'), result)
Exemple #12
0
def parse(contents: str) -> Set[Problem]:
    result = set()  # type: Set[Problem]
    for line in contents.splitlines():
        match = MYPY_LINE_REGEX.match(line)
        if match:
            groups = match.groupdict()
            if groups['code'] != 'note':
                result.add(
                    Problem(groups['path'], groups['line'],
                            '{}: {}'.format(groups['code'],
                                            groups['message'])))
    return result
Exemple #13
0
def parse(contents: str) -> Set[Problem]:
    result = set()  # type: Set[Problem]
    try:
        root = ElementTree.fromstring(contents)
    except ElementTree.ParseError:
        return result
    for file in root.findall('file'):
        file_name = file.get('name')
        for error in file.findall('error'):
            result.add(
                Problem(
                    file_name,
                    error.get('line'), '{}: {}'.format(error.get('source'),
                                                       error.get('message'))))
    return result
Exemple #14
0
def parse(contents: str, **kwargs) -> Set[Problem]:
    result = set()  # type: Set[Problem]
    try:
        root = ElementTree.fromstring(contents)
    except ElementTree.ParseError:
        return result
    for file in root.findall('file'):
        file_name = file.get('name')
        for violation in file.findall('violation'):
            result.add(
                Problem(
                    file_name, violation.get('beginline'),
                    '{}: {}'.format(violation.get('rule'),
                                    violation.text.strip())))
    return result
Exemple #15
0
def parse(contents: str, **kwargs) -> Set[Problem]:
    result = set()  # type: Set[Problem]
    for line in contents.splitlines():
        match = XCODEBUILD_LINE_REGEX.match(line)
        if match:
            groups = match.groupdict()
            line = groups['line'] or 0
            message = groups['message']
            reference = groups['reference']
            if reference:
                message = '{}: {}'.format(reference, message)

            result.add(Problem(os.path.relpath(groups['path']),
                               line, message))
    return result
Exemple #16
0
    def test_comment_on_pr(self, mock_getenv, mock_client_session):
        mock_args, fake_client_session = self.create_mock_pr(
            mock_getenv, mock_client_session)

        reporter = github_reporter.create_reporter(mock_args)
        async_report = reporter.report('unit-test-linter', [
            Problem('some_dir/some_file', 40, 'this made me sad'),
            Problem('some_dir/some_file', 40, 'really sad'),
            Problem('another_file', 2, 'This is OK'),
            Problem('another_file', 2, 'This is OK'),
            Problem('another_file', 3, 'I am a duplicate!'),
            Problem('another_file', 52, "#close_enough!!!"),
            Problem('missing_file', 42, "Missing file comment!!!"),
        ])

        loop = asyncio.get_event_loop()
        loop.run_until_complete(async_report)

        diff_request = call.get(
            'https://api.github.com/repos/foo/bar/pulls/1234',
            headers={
                'Accept': 'application/vnd.github.diff',
                'Authorization': 'token MY_TOKEN'
            })
        existing_comments_request = call.get(
            'https://api.github.com/repos/foo/bar/pulls/1234/comments',
            headers={'Authorization': 'token MY_TOKEN'})
        first_comment = call.post(
            'https://api.github.com/repos/foo/bar/pulls/1234/comments',
            headers={'Authorization': 'token MY_TOKEN'},
            data=json.dumps(
                {
                    'commit_id':
                    'abc123',
                    'path':
                    'another_file',
                    'body':
                    textwrap.dedent('''\
                    unit-test-linter says:

                    ```
                    This is OK
                    ```'''),
                    'position':
                    2
                },
                sort_keys=True))
        second_comment = call.post(
            'https://api.github.com/repos/foo/bar/pulls/1234/comments',
            headers={'Authorization': 'token MY_TOKEN'},
            data=json.dumps(
                {
                    'commit_id':
                    'abc123',
                    'path':
                    'some_dir/some_file',
                    'body':
                    textwrap.dedent('''\
                    unit-test-linter says:

                    ```
                    this made me sad
                    really sad
                    ```'''),
                    'position':
                    3
                },
                sort_keys=True))
        close_enough_comment = call.post(
            'https://api.github.com/repos/foo/bar/pulls/1234/comments',
            headers={'Authorization': 'token MY_TOKEN'},
            data=json.dumps(
                {
                    'commit_id':
                    'abc123',
                    'path':
                    'another_file',
                    'body':
                    textwrap.dedent('''\
                    unit-test-linter says:

                    (From line 52)
                    ```
                    #close_enough!!!
                    ```'''),
                    'position':
                    12
                },
                sort_keys=True))
        missing_file_call = call.post(
            'https://api.github.com/repos/foo/bar/issues/1234/comments',
            headers={'Authorization': 'token MY_TOKEN'},
            data=json.dumps(
                {
                    'body':
                    textwrap.dedent('''\
                    unit-test-linter found some problems with lines not modified by this commit:
                    ```
                    missing_file:42:
                    \tMissing file comment!!!
                    ```'''),
                },
                sort_keys=True))

        self.assertEqual(6, len(fake_client_session.calls))
        self.assertIn(diff_request, fake_client_session.calls)
        self.assertIn(existing_comments_request, fake_client_session.calls)
        self.assertIn(first_comment, fake_client_session.calls)
        self.assertIn(second_comment, fake_client_session.calls)
        self.assertIn(close_enough_comment, fake_client_session.calls)
        self.assertIn(missing_file_call, fake_client_session.calls)
Exemple #17
0
def parse(contents: str, **kwargs) -> Set[Problem]:
    if contents:
        return set([Problem('', 0, contents.strip())])
    else:
        return set()
Exemple #18
0
    def test_comment_on_pr(self, mock_getenv, mock_client_session):
        mock_args, fake_client_session = self.create_mock_pr(
            mock_getenv, mock_client_session)

        reporter = github_reporter.create_reporter(mock_args)
        async_report = reporter.report([
            Problem('some_dir/some_file', 40, 'this made me sad'),
            Problem('some_dir/some_file', 40, 'really sad'),
            Problem('another_file', 2, 'This is OK'),
            Problem('another_file', 2, 'This is OK'),
            Problem('another_file', 3, 'I am a duplicate!'),
            Problem('missing_file', 42, "Don't report me!!!"),
        ])

        loop = asyncio.get_event_loop()
        loop.run_until_complete(async_report)

        diff_request = call.get(
            'https://api.github.com/repos/foo/bar/pulls/1234',
            headers={
                'Accept': 'application/vnd.github.diff',
                'Authorization': 'token MY_TOKEN'
            })
        existing_comments_request = call.get(
            'https://api.github.com/repos/foo/bar/pulls/1234/comments',
            headers={'Authorization': 'token MY_TOKEN'})
        first_comment = call.post(
            'https://api.github.com/repos/foo/bar/pulls/1234/comments',
            headers={'Authorization': 'token MY_TOKEN'},
            data=json.dumps(
                {
                    'commit_id':
                    'abc123',
                    'path':
                    'another_file',
                    'body':
                    textwrap.dedent('''\
                    :sparkles:Linty Fresh Says:sparkles::

                    ```
                    This is OK
                    ```'''),
                    'position':
                    2
                },
                sort_keys=True))
        second_comment = call.post(
            'https://api.github.com/repos/foo/bar/pulls/1234/comments',
            headers={'Authorization': 'token MY_TOKEN'},
            data=json.dumps(
                {
                    'commit_id':
                    'abc123',
                    'path':
                    'some_dir/some_file',
                    'body':
                    textwrap.dedent('''\
                    :sparkles:Linty Fresh Says:sparkles::

                    ```
                    this made me sad
                    really sad
                    ```'''),
                    'position':
                    3
                },
                sort_keys=True))

        self.assertEqual(4, len(fake_client_session.calls))
        self.assertIn(diff_request, fake_client_session.calls)
        self.assertIn(existing_comments_request, fake_client_session.calls)
        self.assertIn(first_comment, fake_client_session.calls)
        self.assertIn(second_comment, fake_client_session.calls)
def parse(contents: str, **kwargs) -> Set[Problem]:
    return set(Problem('', 0, x) for x in contents.splitlines())