def test_publish_summary(self): problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( IssueComment('Terrible things'), Comment(filename_1, 117, 117, 'Something bad'), Comment(filename_1, 119, 119, 'Something bad'), ) problems.add_many(errors) problems.set_changes([1]) review = Review(self.repo, self.pr, self.config) review.publish_summary(problems) assert self.pr.create_comment.called self.assertEqual(1, self.pr.create_comment.call_count) msg = """There are 3 errors: * Terrible things * Console/Command/Task/AssetBuildTask.php, line 117 - Something bad * Console/Command/Task/AssetBuildTask.php, line 119 - Something bad """ self.pr.create_comment.assert_called_with(msg)
def test_publish_problems_remove_ok_label(self): problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( (filename_1, 117, 'Something bad'), (filename_1, 119, 'Something bad'), ) problems.add_many(errors) sha = 'abc123' review = Review(self.gh, 3) label = 'No lint errors' with add_ok_label(self.gh, 3, review, label): sha = 'abc123' review.publish_problems(problems, sha) assert self.issue.remove_label.called, 'Label should be removed' assert self.pr.create_review_comment.called, 'Comments should be added' eq_(2, self.pr.create_review_comment.call_count) self.issue.remove_label.assert_called_with(label) assert_review_comments_created( self.pr.create_review_comment.call_args_list, errors, sha)
def test_publish_problems(self): gh = Mock() problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( (filename_1, 117, 'Something bad'), (filename_1, 119, 'Something bad'), ) problems.add_many(errors) sha = 'abc123' review = Review(gh, 3) review.publish_problems(problems, sha) assert gh.pull_requests.comments.create.called eq_(2, gh.pull_requests.comments.create.call_count) calls = gh.pull_requests.comments.create.call_args_list expected = call(3, { 'commit_id': sha, 'path': errors[0][0], 'position': errors[0][1], 'body': errors[0][2] }) eq_(calls[0], expected) expected = call(3, { 'commit_id': sha, 'path': errors[1][0], 'position': errors[1][1], 'body': errors[1][2] }) eq_(calls[1], expected)
class Processor(object): def __init__(self, client, number, head, target_path): self._client = client self._number = number self._head = head self._target_path = target_path self._changes = None self._problems = Problems(target_path) self._review = Review(client, number) def load_changes(self): log.info('Loading pull request patches from github.') files = self._client.pull_requests.list_files(self._number) pull_request_patches = files.all() self._changes = DiffCollection(pull_request_patches) self._problems.set_changes(self._changes) def run_tools(self, review_config): if self._changes is None: raise RuntimeError('No loaded changes, cannot run tools. ' 'Try calling load_changes first.') files_to_check = self._changes.get_files( append_base=self._target_path, ignore_patterns=review_config.ignore_patterns()) tools.run( review_config, self._problems, files_to_check, self._target_path) def publish(self, wait_time=0): self._problems.limit_to_changes() self._review.publish(self._problems, self._head, wait_time)
def test_filter_existing__removes_duplicates(self): fixture_data = load_fixture('comments_current.json') self.pr.review_comments.return_value = map( lambda f: GhIssueComment(f), json.loads(fixture_data)) problems = Problems() review = Review(self.gh, 2) filename_1 = "Routing/Filter/AssetCompressor.php" filename_2 = "View/Helper/AssetCompressHelper.php" problems.add(filename_1, 87, 'A pithy remark') problems.add(filename_1, 87, 'Something different') problems.add(filename_2, 88, 'I <3 it') problems.add(filename_2, 89, 'Not such a good comment') review.load_comments() review.remove_existing(problems) res = problems.all(filename_1) eq_(1, len(res)) expected = Comment(filename_1, 87, 87, 'Something different') eq_(res[0], expected) res = problems.all(filename_2) eq_(1, len(res)) expected = Comment(filename_2, 88, 88, 'I <3 it') eq_(res[0], expected)
def test_publish_checkrun(self): self.repo.create_checkrun = Mock() tst_config = build_review_config(fixer_ini, {'PULLREQUEST_STATUS': True}) problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( Comment(filename_1, 117, 8, 'Something bad'), Comment(filename_1, 119, 9, 'Something worse'), ) problems.add_many(errors) run_id = 42 review = Review(self.repo, self.pr, tst_config) review.publish_checkrun(problems, run_id) assert self.repo.update_checkrun.called self.assertEqual(1, self.repo.update_checkrun.call_count) assert_checkrun( self, self.repo.update_checkrun.call_args, errors, run_id) assert self.repo.create_status.called is False, 'no status required'
def test_filter_existing__removes_duplicates(self): fixture_data = load_fixture('comments_current.json') self.pr.review_comments.return_value = [ GhIssueComment(f, self.session) for f in json.loads(fixture_data) ] problems = Problems() review = Review(self.repo, self.pr, self.config) filename_1 = "Routing/Filter/AssetCompressor.php" filename_2 = "View/Helper/AssetCompressHelper.php" problems.add(filename_1, 87, 'A pithy remark') problems.add(filename_1, 87, 'Something different') problems.add(filename_2, 88, 'I <3 it') problems.add(filename_2, 89, 'Not such a good comment') review.load_comments() review.remove_existing(problems) res = problems.all(filename_1) self.assertEqual(1, len(res)) expected = Comment(filename_1, 87, 87, 'A pithy remark\nSomething different') self.assertEqual(res[0], expected) res = problems.all(filename_2) self.assertEqual(1, len(res)) expected = Comment(filename_2, 88, 88, 'I <3 it') self.assertEqual(res[0], expected)
def test_filter_existing__removes_duplicates(self, http): fixture_data = load_fixture('comments_current.json') response = Response() response._content = fixture_data http.return_value = response gh = Github() problems = Problems() review = Review(gh, 2) filename_1 = "Routing/Filter/AssetCompressor.php" filename_2 = "View/Helper/AssetCompressHelper.php" problems.add(filename_1, 87, 'A pithy remark') problems.add(filename_1, 87, 'Something different') problems.add(filename_2, 88, 'I <3 it') problems.add(filename_2, 89, 'Not such a good comment') review.load_comments() review.remove_existing(problems) res = problems.all(filename_1) eq_(1, len(res)) expected = Comment(filename_1, 87, 87, 'Something different') eq_(res[0], expected) res = problems.all(filename_2) eq_(1, len(res)) expected = Comment(filename_2, 88, 88, 'I <3 it') eq_(res[0], expected)
def test_publish_empty_comment_add_ok_label(self): gh = Mock() problems = Problems(changes=[]) review = Review(gh, 3) label = config.get('OK_LABEL', 'No lint errors') with add_ok_label(gh, 3, label): sha = 'abc123' review.publish(problems, sha) assert not gh.pull_requests.comments.create.called assert gh.issues.comments.create.called assert gh.issues.labels.remove_from_issue.called assert_add_to_issue(gh) calls = gh.issues.labels.remove_from_issue.call_args_list expected = call(3, label) eq_(calls, [expected]) calls = gh.issues.comments.create.call_args_list msg = ('Could not review pull request. ' 'It may be too large, or contain no reviewable changes.') expected = call(3, msg) eq_(calls[0], expected)
def test_publish_pull_review_remove_ok_label(self): problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( Comment(filename_1, 117, 117, 'Something bad'), Comment(filename_1, 119, 119, 'Something bad'), ) problems.add_many(errors) tst_config = build_review_config(fixer_ini, {'OK_LABEL': 'No lint'}) review = Review(self.repo, self.pr, tst_config) sha = 'abc123' review.publish_pull_review(problems, sha) assert self.pr.remove_label.called, 'Label should be removed' assert self.pr.create_review.called, 'Review should be added' self.assertEqual(1, self.pr.create_review.call_count) self.pr.remove_label.assert_called_with(tst_config['OK_LABEL']) assert_review( self, self.pr.create_review.call_args, errors, sha)
def test_publish_summary(self): gh = Mock() problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( (filename_1, 117, 'Something bad'), (filename_1, 119, 'Something bad'), ) problems.add_many(errors) problems.set_changes([1]) sha = 'abc123' review = Review(gh, 3) review.publish_summary(problems) assert gh.issues.comments.create.called eq_(1, gh.issues.comments.create.call_count) calls = gh.issues.comments.create.call_args_list msg = """There are 2 errors: * Console/Command/Task/AssetBuildTask.php, line 117 - Something bad * Console/Command/Task/AssetBuildTask.php, line 119 - Something bad """ expected = call(3, msg) eq_(calls[0], expected)
def test_publish_problems_remove_ok_label(self): problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( (filename_1, 117, 'Something bad'), (filename_1, 119, 'Something bad'), ) problems.add_many(errors) sha = 'abc123' config = {'OK_LABEL': 'No lint'} review = Review(self.repo, self.pr, config) sha = 'abc123' review.publish_problems(problems, sha) assert self.pr.remove_label.called, 'Label should be removed' assert self.pr.create_review_comment.called, 'Comments should be added' eq_(2, self.pr.create_review_comment.call_count) self.pr.remove_label.assert_called_with(config['OK_LABEL']) assert_review_comments_created( self.pr.create_review_comment.call_args_list, errors, sha)
def test_load_comments__none_active(self): fixture_data = load_fixture('comments_none_current.json') self.pr.review_comments.return_value = [GhIssueComment(f) for f in json.loads(fixture_data)] review = Review(self.gh, 2) review.load_comments() eq_(0, len(review.comments("View/Helper/AssetCompressHelper.php")))
def test_publish_status__ok_no_comment_or_label(self): config = {'OK_COMMENT': None, 'OK_LABEL': None} review = Review(self.gh, 3, config) review.publish_status(0) assert self.gh.create_status.called, 'Create status not called' assert not self.issue.create_comment.called, 'Comment not created' assert not self.issue.add_labels.called, 'Label added created'
def test_publish_pull_review__no_comments(self): problems = Problems() sha = 'abc123' review = Review(self.repo, self.pr, self.config) review.publish_pull_review(problems, sha) assert self.pr.create_review.called is False
def test_load_comments__none_active(self): fixture_data = load_fixture('comments_none_current.json') self.pr.review_comments.return_value = map( lambda f: GhIssueComment(f), json.loads(fixture_data)) review = Review(self.repo, self.pr) review.load_comments() eq_(0, len(review.comments("View/Helper/AssetCompressHelper.php")))
def test_load_comments__none_active(self): fixture_data = load_fixture('comments_none_current.json') self.pr.review_comments.return_value = [ GhIssueComment(f, self.session) for f in json.loads(fixture_data) ] review = Review(self.repo, self.pr, self.config) review.load_comments() filename = "View/Helper/AssetCompressHelper.php" self.assertEqual(0, len(review.comments(filename)))
def test_load_comments__none_active(self, http): fixture_data = load_fixture('comments_none_current.json') response = Response() response._content = fixture_data http.return_value = response gh = Github() review = Review(gh, 2) review.load_comments() eq_(0, len(review.comments("View/Helper/AssetCompressHelper.php")))
class Processor(object): _client = None _number = None _head = None _target_path = None _changes = None _problems = None _review = None _config = None def __init__(self, client, number, head, target_path, config=None): self._client = client self._number = number self._head = head self._target_path = target_path self._problems = Problems(target_path) self._review = Review(client, number) if config is None: config = {} self._config = config def load_changes(self): log.info('Loading pull request patches from github.') files = self._client.pull_requests.list_files(self._number) pull_request_patches = files.all() self._changes = DiffCollection(pull_request_patches) self._problems.set_changes(self._changes) def run_tools(self, review_config): if self._changes is None: raise RuntimeError('No loaded changes, cannot run tools. ' 'Try calling load_changes first.') files_to_check = self._changes.get_files( append_base=self._target_path, ignore_patterns=review_config.ignore_patterns()) commits_to_check = self.get_commits(self._number) tools.run( review_config, self._problems, files_to_check, commits_to_check, self._target_path) def publish(self): self._problems.limit_to_changes() self._review.publish( self._problems, self._head, self._config.get('SUMMARY_THRESHOLD')) def get_commits(self, number): return self._client.pull_requests.list_commits(number).all()
def test_publish_status__ok_no_comment_label_or_status(self): config = { 'OK_COMMENT': None, 'OK_LABEL': None, 'PULLREQUEST_STATUS': False, } review = Review(self.repo, self.pr, config) review.publish_status(0) assert not self.repo.create_status.called, 'Create status called' assert not self.pr.create_comment.called, 'Comment not created' assert not self.pr.add_label.called, 'Label added created'
def test_publish_review_empty_comment(self): problems = Problems(changes=DiffCollection([])) review = Review(self.repo, self.pr, self.config) sha = 'abc123' review.publish_review(problems, sha) assert self.pr.create_comment.called, 'Should create a comment' msg = ('Could not review pull request. ' 'It may be too large, or contain no reviewable changes.') self.pr.create_comment.assert_called_with(msg)
def test_publish_empty_comment(self): problems = Problems(changes=[]) review = Review(self.gh, 3) sha = 'abc123' review.publish(problems, sha) assert self.issue.create_comment.called, 'Should create a comment' msg = ('Could not review pull request. ' 'It may be too large, or contain no reviewable changes.') self.issue.create_comment.assert_called_with(msg)
def test_publish_status__ok_no_comment_or_label(self): app_config = { 'OK_COMMENT': None, 'OK_LABEL': None, 'PULLREQUEST_STATUS': False, } tst_config = build_review_config(fixer_ini, app_config) review = Review(self.repo, self.pr, tst_config) review.publish_status(False) assert self.repo.create_status.called, 'Create status called' assert not self.pr.create_comment.called, 'Comment not created' assert not self.pr.add_label.called, 'Label added created'
class Processor(object): _repository = None _pull_request = None _target_path = None _changes = None _problems = None _review = None _config = None def __init__(self, repository, pull_request, target_path, config=None): config = config if config else {} self._config = config self._repository = repository self._pull_request = pull_request self._target_path = target_path self._problems = Problems(target_path) self._review = Review(repository, pull_request, config) def load_changes(self): log.info('Loading pull request patches from github.') files = self._pull_request.files() self._changes = DiffCollection(files) self._problems.set_changes(self._changes) def run_tools(self, review_config): if self._changes is None: raise RuntimeError('No loaded changes, cannot run tools. ' 'Try calling load_changes first.') files_to_check = self._changes.get_files( append_base=self._target_path, ignore_patterns=review_config.ignore_patterns()) commits_to_check = self._pull_request.commits() log.debug("_problems before tools: %s" % len(self._problems)) self._problems = tools.run( review_config, self._problems, files_to_check, commits_to_check, self._target_path) log.debug("_problems after tools: %s" % len(self._problems)) def publish(self): self._problems.limit_to_changes() self._review.publish( self._problems, self._pull_request.head, self._config.get('SUMMARY_THRESHOLD'))
def test_publish_review_empty_comment_add_ok_label(self): problems = Problems(changes=DiffCollection([])) tst_config = build_review_config(fixer_ini, {'OK_LABEL': 'No lint'}) review = Review(self.repo, self.pr, tst_config) sha = 'abc123' review.publish_review(problems, sha) assert self.pr.create_comment.called, 'ok comment should be added.' assert self.pr.remove_label.called, 'label should be removed.' self.pr.remove_label.assert_called_with(tst_config['OK_LABEL']) msg = ('Could not review pull request. ' 'It may be too large, or contain no reviewable changes.') self.pr.create_comment.assert_called_with(msg)
def test_publish_pull_review__only_issue_comment(self): problems = Problems() problems.add(IssueComment('Very bad')) sha = 'abc123' review = Review(self.repo, self.pr, self.config) review.publish_pull_review(problems, sha) assert self.pr.create_review.called assert_review( self, self.pr.create_review.call_args, [], sha, body='Very bad')
def test_publish_empty_comment_add_ok_label(self): problems = Problems(changes=[]) config = {'OK_LABEL': 'No lint'} review = Review(self.repo, self.pr, config) sha = 'abc123' review.publish(problems, sha) assert self.pr.create_comment.called, 'ok comment should be added.' assert self.pr.remove_label.called, 'label should be removed.' self.pr.remove_label.assert_called_with(config['OK_LABEL']) msg = ('Could not review pull request. ' 'It may be too large, or contain no reviewable changes.') self.pr.create_comment.assert_called_with(msg)
def test_publish_ok_comment(self): gh = Mock() problems = Problems() review = Review(gh, 3) sha = 'abc123' review.publish(problems, sha) assert not(gh.pull_requests.comments.create.called) assert gh.issues.comments.create.called calls = gh.issues.comments.create.call_args_list expected = call(3, ':+1: No lint errors found.') eq_(calls[0], expected)
def test_factory_generates_tools(self): gh = Mock(spec=github3.GitHub) config = build_review_config(sample_ini) linters = tools.factory(config, Review(gh, None, config), '') self.assertEqual(2, len(linters)) self.assertIsInstance(linters[0], pep8.Pep8) self.assertIsInstance(linters[1], jshint.Jshint)
def test_publish_status__ok_with_comment_and_label(self): config = {'OK_COMMENT': 'Great job!', 'OK_LABEL': 'No lint errors'} review = Review(self.repo, self.pr, config) review.publish_status(0) assert self.repo.create_status.called, 'Create status not called' self.repo.create_status.assert_called_with( self.pr.head, 'success', 'No lint errors found.') assert self.pr.create_comment.called, 'Issue comment created' self.pr.create_comment.assert_called_with('Great job!') assert self.pr.add_label.called, 'Label added created' self.pr.add_label.assert_called_with('No lint errors')
def test_publish_ok_comment(self): gh = Mock() problems = Problems(changes=[1]) review = Review(gh, 3) sha = 'abc123' review.publish(problems, sha) assert not (gh.pull_requests.comments.create.called) assert gh.issues.comments.create.called calls = gh.issues.comments.create.call_args_list expected = call(3, config.get('OK_COMMENT', ':+1: No lint errors found.')) eq_(calls[0], expected)
def __init__(self, repository, pull_request, target_path, config): self._config = config self._repository = repository self._pull_request = pull_request self._target_path = target_path self.problems = Problems() self._review = Review(repository, pull_request, config)
def test_publish_status__has_errors(self): config = { 'OK_COMMENT': 'Great job!', 'OK_LABEL': 'No lint errors', 'APP_NAME': 'custom-name' } review = Review(self.repo, self.pr, config) review.publish_status(1) assert self.repo.create_status.called, 'Create status not called' self.repo.create_status.assert_called_with( self.pr.head, 'failure', 'Lint errors found, see pull request comments.') assert not self.pr.create_comment.called, 'Comment not created' assert not self.pr.add_label.called, 'Label added created'
def setUp(self): repo = Mock(spec=GithubRepository) pr = Mock(spec=GithubPullRequest, head='abc123', number=2) repo.pull_request.return_value = pr self.repo, self.pr = repo, pr self.review = Review(repo, pr)
def test_factory_generates_tools(): gh = Mock(spec=github3.GitHub) config = build_review_config(sample_ini) linters = tools.factory(Review(gh, None), config, '') eq_(2, len(linters)) assert isinstance(linters[0], tools.pep8.Pep8) assert isinstance(linters[1], tools.jshint.Jshint)
def test_publish_empty_comment_add_ok_label(self): problems = Problems(changes=[]) review = Review(self.gh, 3) label = 'No lint errors' with add_ok_label(self.gh, 3, review, label): sha = 'abc123' review.publish(problems, sha) assert self.issue.create_comment.called, 'ok comment should be added.' assert self.issue.remove_label.called, 'label should be removed.' self.issue.remove_label.assert_called_with(label) msg = ('Could not review pull request. ' 'It may be too large, or contain no reviewable changes.') self.issue.create_comment.assert_called_with(msg)
def test_publish_empty_comment(self): gh = Mock() problems = Problems(changes=[]) review = Review(gh, 3) sha = 'abc123' review.publish(problems, sha) assert not (gh.pull_requests.comments.create.called) assert gh.issues.comments.create.called calls = gh.issues.comments.create.call_args_list msg = ('Could not review pull request. ' 'It may be too large, or contain no reviewable changes.') expected = call(3, msg) eq_(calls[0], expected)
def test_publish_checkrun__multiple_chunks(self): self.repo.create_checkrun = Mock() tst_config = build_review_config(fixer_ini, {'PULLREQUEST_STATUS': True}) problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = [ Comment(filename_1, i, i, 'Something worse') for i in range(0, 70) ] problems.add_many(errors) problems.add(IssueComment('In the body')) run_id = 42 review = Review(self.repo, self.pr, tst_config) review.publish_checkrun(problems, run_id) assert self.repo.update_checkrun.call_count == 2 assert self.repo.create_status.called is False, 'no status required' first_call = self.repo.update_checkrun.call_args_list[0] assert run_id == first_call[0][0] first_payload = first_call[0][1] assert 'failure' == first_payload['conclusion'] assert 'completed_at' in first_payload assert 'title' in first_payload['output'] assert 'summary' in first_payload['output'] assert 'annotations' in first_payload['output'] assert 'In the body' == first_payload['output']['summary'] assert 50 == len(first_payload['output']['annotations']) second_call = self.repo.update_checkrun.call_args_list[1] assert run_id == second_call[0][0] # The second payload should only contain additional annotations. second_payload = second_call[0][1] assert 'completed_at' not in second_payload assert 'title' in second_payload['output'] assert 'summary' in second_payload['output'] assert 'annotations' in second_payload['output'] assert 'In the body' == second_payload['output']['summary'] assert 20 == len(second_payload['output']['annotations'])
def test_publish_status__ok_with_comment_label_and_status(self): config = { 'OK_COMMENT': 'Great job!', 'OK_LABEL': 'No lint errors', 'PULLREQUEST_STATUS': True, } review = Review(self.repo, self.pr, config) review.publish_status(0) assert self.repo.create_status.called, 'Create status not called' self.repo.create_status.assert_called_with(self.pr.head, 'success', 'No lint errors found.') assert self.pr.create_comment.called, 'Issue comment created' self.pr.create_comment.assert_called_with('Great job!') assert self.pr.add_label.called, 'Label added created' self.pr.add_label.assert_called_with('No lint errors')
def test_publish_status__ok_with_comment_and_label(self): config = {'OK_COMMENT': 'Great job!', 'OK_LABEL': 'No lint errors'} review = Review(self.gh, 3, config) review.publish_status(0) assert self.gh.create_status.called, 'Create status not called' self.gh.create_status.assert_called_with( self.pr.head.sha, 'success', None, 'No lint errors found.', 'lintreview') assert self.issue.create_comment.called, 'Issue comment created' self.issue.create_comment.assert_called_with('Great job!') assert self.issue.add_labels.called, 'Label added created' self.issue.add_labels.assert_called_with('No lint errors')
def test_publish_empty_comment_with_comment_status(self): config = build_review_config(fixer_ini, {'PULLREQUEST_STATUS': True}) problems = Problems(changes=[]) review = Review(self.repo, self.pr, config) sha = 'abc123' review.publish(problems, sha) assert self.pr.create_comment.called, 'Should create a comment' msg = ('Could not review pull request. ' 'It may be too large, or contain no reviewable changes.') self.repo.create_status.assert_called_with(self.pr.head, 'success', msg) self.pr.create_comment.assert_called_with(msg)
def test_publish_checkrun__no_problems(self): self.repo.create_checkrun = Mock() config = build_review_config(fixer_ini, {'PULLREQUEST_STATUS': True}) problems = Problems() run_id = 42 review = Review(self.repo, self.pr, config) review.publish_checkrun(problems, run_id) assert self.repo.update_checkrun.called eq_(1, self.repo.update_checkrun.call_count) assert_checkrun( self.repo.update_checkrun.call_args, [], run_id) assert self.repo.create_status.called is False, 'no status required'
def test_publish_review(self): problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( Comment(filename_1, 117, 117, 'Something bad'), Comment(filename_1, 119, 119, 'Something bad'), ) problems.add_many(errors) sha = 'abc123' review = Review(self.repo, self.pr, self.config) review.publish_review(problems, sha) assert self.pr.create_review.called eq_(1, self.pr.create_review.call_count) assert_review(self.pr.create_review.call_args, errors, sha)
def setUp(self): pr = Mock() issue = Mock() gh = Mock() gh.pull_request.return_value = pr gh.issue.return_value = issue self.gh, self.pr, self.issue = gh, pr, issue self.review = Review(self.gh, 2)
def test_publish_problems(self): problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( (filename_1, 117, 'Something bad'), (filename_1, 119, 'Something bad'), ) problems.add_many(errors) sha = 'abc123' review = Review(self.repo, self.pr) review.publish_problems(problems, sha) assert self.pr.create_review_comment.called eq_(2, self.pr.create_review_comment.call_count) assert_review_comments_created( self.pr.create_review_comment.call_args_list, errors, sha)
def test_publish_status__has_errors__success_status(self): app_config = { 'PULLREQUEST_STATUS': False, 'OK_COMMENT': 'Great job!', 'OK_LABEL': 'No lint errors', 'APP_NAME': 'custom-name' } config = build_review_config(fixer_ini, app_config) eq_('success', config.failed_review_status(), 'config object changed') review = Review(self.repo, self.pr, config) review.publish_status(True) assert self.repo.create_status.called, 'Create status not called' self.repo.create_status.assert_called_with( self.pr.head, 'success', 'Lint errors found, see pull request comments.') assert not self.pr.create_comment.called, 'Comment not created' assert not self.pr.add_label.called, 'Label added created'
def test_publish_comment_threshold_checks(self): fixture = load_fixture('comments_current.json') self.pr.review_comments.return_value = [GhIssueComment(f) for f in json.loads(fixture)] problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( (filename_1, 117, 'Something bad'), (filename_1, 119, 'Something bad'), ) problems.add_many(errors) problems.set_changes([1]) sha = 'abc123' review = Review(self.gh, 3) review.publish_summary = Mock() review.publish(problems, sha, 1) assert review.publish_summary.called, 'Should have been called.'
def test_publish_checkrun(self): tst_config = build_review_config(fixer_ini, {'PULLREQUEST_STATUS': True}) problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( Comment(filename_1, 117, 8, 'Something bad'), Comment(filename_1, 119, 9, 'Something worse'), ) problems.add_many(errors) run_id = 42 review = Review(self.repo, self.pr, tst_config) review.publish_checkrun(problems, run_id) assert self.repo.update_checkrun.called self.assertEqual(1, self.repo.update_checkrun.call_count) assert_checkrun(self.repo.update_checkrun.call_args, errors, run_id) assert self.repo.create_status.called is False, 'no status required'
def test_publish_checks_api(self): self.repo.create_checkrun = Mock() config = build_review_config(checks_ini, {'PULLREQUEST_STATUS': True}) problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( Comment(filename_1, 117, 8, 'Something bad'), Comment(filename_1, 119, 9, 'Something worse'), ) problems.add_many(errors) sha = 'abc123' review = Review(self.repo, self.pr, config) review.publish_checkrun(problems, True, sha) assert self.repo.create_checkrun.called eq_(1, self.repo.create_checkrun.call_count) assert_checkrun(self.repo.create_checkrun.call_args, errors, sha)
def test_publish_pull_review_remove_ok_label(self): problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( Comment(filename_1, 117, 117, 'Something bad'), Comment(filename_1, 119, 119, 'Something bad'), ) problems.add_many(errors) tst_config = build_review_config(fixer_ini, {'OK_LABEL': 'No lint'}) review = Review(self.repo, self.pr, tst_config) sha = 'abc123' review.publish_pull_review(problems, sha) assert self.pr.remove_label.called, 'Label should be removed' assert self.pr.create_review.called, 'Review should be added' self.assertEqual(1, self.pr.create_review.call_count) self.pr.remove_label.assert_called_with(tst_config['OK_LABEL']) assert_review(self, self.pr.create_review.call_args, errors, sha)
def test_publish__join_issue_comments(self): problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( IssueComment('First'), Comment(filename_1, 119, 119, 'Something bad'), IssueComment('Second'), ) problems.add_many(errors) sha = 'abc123' review = Review(self.repo, self.pr, self.config) review.publish_review(problems, sha) assert self.pr.create_review.called eq_(1, self.pr.create_review.call_count) assert_review(self.pr.create_review.call_args, [errors[1]], sha, body='First\n\nSecond')
def test_publish_with__wait_time(self, time): gh = Mock() problems = Problems() review = Review(gh, 3) filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( (filename_1, 117, 'Something bad'), (filename_1, 119, 'Something bad'), ) problems.add_many(errors) sha = 'abc123' review.publish_problems(problems, sha, 1) assert time.sleep.called eq_(2, time.sleep.call_count) calls = time.sleep.call_args_list expected = call(1) eq_(calls[0], expected) eq_(calls[1], expected)
def test_filter_existing__removes_duplicates(self): fixture_data = load_fixture('comments_current.json') self.pr.review_comments.return_value = [ GhIssueComment(f) for f in json.loads(fixture_data) ] problems = Problems() review = Review(self.repo, self.pr, self.config) filename_1 = "Routing/Filter/AssetCompressor.php" filename_2 = "View/Helper/AssetCompressHelper.php" problems.add(filename_1, 87, 'A pithy remark') problems.add(filename_1, 87, 'Something different') problems.add(filename_2, 88, 'I <3 it') problems.add(filename_2, 89, 'Not such a good comment') review.load_comments() review.remove_existing(problems) res = problems.all(filename_1) eq_(1, len(res)) expected = Comment(filename_1, 87, 87, 'A pithy remark\nSomething different') eq_(res[0], expected) res = problems.all(filename_2) eq_(1, len(res)) expected = Comment(filename_2, 88, 88, 'I <3 it') eq_(res[0], expected)
def test_publish_review_no_count_change(self): fixture = load_fixture('comments_current.json') self.pr.review_comments.return_value = [ GhIssueComment(f) for f in json.loads(fixture) ] problems = Problems() # Match the line/positions in comments_current.json filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( Comment(filename_1, 40, 40, '2. Something bad'), Comment(filename_1, 87, 87, '1. Something bad'), Comment(filename_1, 89, 89, '2. Something bad'), ) problems.add_many(errors) problems.set_changes([1]) sha = 'abc123' config = build_review_config(fixer_ini, {'SUMMARY_THRESHOLD': 1}) review = Review(self.repo, self.pr, config) review.publish_summary = Mock() review.publish_status = Mock() review.publish_review(problems, sha) # Ensure publish_status(True) means the status=failed review.publish_status.assert_called_with(True)
class Processor(object): _repository = None _pull_request = None _target_path = None _changes = None _problems = None _review = None _config = None def __init__(self, repository, pull_request, target_path, config=None): config = config if config else {} self._config = config self._repository = repository self._pull_request = pull_request self._target_path = target_path self._problems = Problems(target_path) self._review = Review(repository, pull_request, config) def load_changes(self): log.info('Loading pull request patches from github.') files = self._pull_request.files() self._changes = DiffCollection(files) self._problems.set_changes(self._changes) def run_tools(self, review_config): if self._changes is None: raise RuntimeError('No loaded changes, cannot run tools. ' 'Try calling load_changes first.') files_to_check = self._changes.get_files( append_base=self._target_path, ignore_patterns=review_config.ignore_patterns()) commits_to_check = self._pull_request.commits() tools.run(review_config, self._problems, files_to_check, commits_to_check, self._target_path) def publish(self): self._problems.limit_to_changes() self._review.publish(self._problems, self._pull_request.head, self._config.get('SUMMARY_THRESHOLD'))
def test_publish_review_comment_threshold_checks(self): fixture = load_fixture('comments_current.json') self.pr.review_comments.return_value = [ GhIssueComment(f) for f in json.loads(fixture)] problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( Comment(filename_1, 117, 117, 'Something bad'), Comment(filename_1, 119, 119, 'Something bad'), ) problems.add_many(errors) problems.set_changes([1]) sha = 'abc123' config = build_review_config(fixer_ini, {'SUMMARY_THRESHOLD': 1}) review = Review(self.repo, self.pr, config) review.publish_summary = Mock() review.publish_review(problems, sha) assert review.publish_summary.called, 'Should have been called.'
def test_publish_checkrun__has_errors_force_success_status(self): self.repo.create_checkrun = Mock() config = build_review_config(fixer_ini, {'PULLREQUEST_STATUS': False}) eq_('success', config.failed_review_status(), 'config object changed') review = Review(self.repo, self.pr, config) problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( Comment(filename_1, 117, 8, 'Something bad'), Comment(filename_1, 119, 9, 'Something worse'), ) problems.add_many(errors) run_id = 42 review.publish_checkrun(problems, run_id) assert self.repo.create_status.called is False, 'no status required' checkrun = self.repo.update_checkrun.call_args[0][1] eq_('success', checkrun['conclusion']) assert len(checkrun['output']['annotations']) > 0
def test_publish_summary(self): problems = Problems() filename_1 = 'Console/Command/Task/AssetBuildTask.php' errors = ( (filename_1, 117, 'Something bad'), (filename_1, 119, 'Something bad'), ) problems.add_many(errors) problems.set_changes([1]) review = Review(self.repo, self.pr) review.publish_summary(problems) assert self.pr.create_comment.called eq_(1, self.pr.create_comment.call_count) msg = """There are 2 errors: * Console/Command/Task/AssetBuildTask.php, line 117 - Something bad * Console/Command/Task/AssetBuildTask.php, line 119 - Something bad """ self.pr.create_comment.assert_called_with(msg)