Share a fake pull request database across connections
Because connections can be recreated, ensure that the fake pull request database (really a dictionary) is shared across instances of connections and fake github classes. Also, move the fake github3 classes to their own file -- they were getting larger and unruly. Change-Id: I471c1487039c8b25a0bab95d918f31b92b9cd32b
This commit is contained in:
parent
f2c12d69ec
commit
6bacffb122
216
tests/base.py
216
tests/base.py
@ -40,7 +40,6 @@ import time
|
|||||||
import uuid
|
import uuid
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
|
|
||||||
import git
|
import git
|
||||||
import gear
|
import gear
|
||||||
import fixtures
|
import fixtures
|
||||||
@ -53,6 +52,7 @@ import testtools.content_type
|
|||||||
from git.exc import NoSuchPathError
|
from git.exc import NoSuchPathError
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
import tests.fakegithub
|
||||||
import zuul.driver.gerrit.gerritsource as gerritsource
|
import zuul.driver.gerrit.gerritsource as gerritsource
|
||||||
import zuul.driver.gerrit.gerritconnection as gerritconnection
|
import zuul.driver.gerrit.gerritconnection as gerritconnection
|
||||||
import zuul.driver.github.githubconnection as githubconnection
|
import zuul.driver.github.githubconnection as githubconnection
|
||||||
@ -601,194 +601,6 @@ class GithubChangeReference(git.Reference):
|
|||||||
_points_to_commits_only = True
|
_points_to_commits_only = True
|
||||||
|
|
||||||
|
|
||||||
class FakeGithub(object):
|
|
||||||
|
|
||||||
class FakeUser(object):
|
|
||||||
def __init__(self, login):
|
|
||||||
self.login = login
|
|
||||||
self.name = "Github User"
|
|
||||||
self.email = "github.user@example.com"
|
|
||||||
|
|
||||||
class FakeBranch(object):
|
|
||||||
def __init__(self, branch='master'):
|
|
||||||
self.name = branch
|
|
||||||
|
|
||||||
class FakeStatus(object):
|
|
||||||
def __init__(self, state, url, description, context, user):
|
|
||||||
self._state = state
|
|
||||||
self._url = url
|
|
||||||
self._description = description
|
|
||||||
self._context = context
|
|
||||||
self._user = user
|
|
||||||
|
|
||||||
def as_dict(self):
|
|
||||||
return {
|
|
||||||
'state': self._state,
|
|
||||||
'url': self._url,
|
|
||||||
'description': self._description,
|
|
||||||
'context': self._context,
|
|
||||||
'creator': {
|
|
||||||
'login': self._user
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeCommit(object):
|
|
||||||
def __init__(self):
|
|
||||||
self._statuses = []
|
|
||||||
|
|
||||||
def set_status(self, state, url, description, context, user):
|
|
||||||
status = FakeGithub.FakeStatus(
|
|
||||||
state, url, description, context, user)
|
|
||||||
# always insert a status to the front of the list, to represent
|
|
||||||
# the last status provided for a commit.
|
|
||||||
self._statuses.insert(0, status)
|
|
||||||
|
|
||||||
def statuses(self):
|
|
||||||
return self._statuses
|
|
||||||
|
|
||||||
class FakeRepository(object):
|
|
||||||
def __init__(self):
|
|
||||||
self._branches = [FakeGithub.FakeBranch()]
|
|
||||||
self._commits = {}
|
|
||||||
|
|
||||||
def branches(self, protected=False):
|
|
||||||
if protected:
|
|
||||||
# simulate there is no protected branch
|
|
||||||
return []
|
|
||||||
return self._branches
|
|
||||||
|
|
||||||
def create_status(self, sha, state, url, description, context,
|
|
||||||
user='zuul'):
|
|
||||||
# Since we're bypassing github API, which would require a user, we
|
|
||||||
# default the user as 'zuul' here.
|
|
||||||
commit = self._commits.get(sha, None)
|
|
||||||
if commit is None:
|
|
||||||
commit = FakeGithub.FakeCommit()
|
|
||||||
self._commits[sha] = commit
|
|
||||||
commit.set_status(state, url, description, context, user)
|
|
||||||
|
|
||||||
def commit(self, sha):
|
|
||||||
commit = self._commits.get(sha, None)
|
|
||||||
if commit is None:
|
|
||||||
commit = FakeGithub.FakeCommit()
|
|
||||||
self._commits[sha] = commit
|
|
||||||
return commit
|
|
||||||
|
|
||||||
class FakeLabel(object):
|
|
||||||
def __init__(self, name):
|
|
||||||
self.name = name
|
|
||||||
|
|
||||||
class FakeIssue(object):
|
|
||||||
def __init__(self, fake_pull_request):
|
|
||||||
self._fake_pull_request = fake_pull_request
|
|
||||||
|
|
||||||
def pull_request(self):
|
|
||||||
return FakeGithub.FakePull(self._fake_pull_request)
|
|
||||||
|
|
||||||
def labels(self):
|
|
||||||
return [FakeGithub.FakeLabel(l)
|
|
||||||
for l in self._fake_pull_request.labels]
|
|
||||||
|
|
||||||
class FakeFile(object):
|
|
||||||
def __init__(self, filename):
|
|
||||||
self.filename = filename
|
|
||||||
|
|
||||||
class FakePull(object):
|
|
||||||
def __init__(self, fake_pull_request):
|
|
||||||
self._fake_pull_request = fake_pull_request
|
|
||||||
|
|
||||||
def issue(self):
|
|
||||||
return FakeGithub.FakeIssue(self._fake_pull_request)
|
|
||||||
|
|
||||||
def files(self):
|
|
||||||
return [FakeGithub.FakeFile(fn)
|
|
||||||
for fn in self._fake_pull_request.files]
|
|
||||||
|
|
||||||
def as_dict(self):
|
|
||||||
pr = self._fake_pull_request
|
|
||||||
connection = pr.github
|
|
||||||
data = {
|
|
||||||
'number': pr.number,
|
|
||||||
'title': pr.subject,
|
|
||||||
'url': 'https://%s/%s/pull/%s' % (
|
|
||||||
connection.server, pr.project, pr.number
|
|
||||||
),
|
|
||||||
'updated_at': pr.updated_at,
|
|
||||||
'base': {
|
|
||||||
'repo': {
|
|
||||||
'full_name': pr.project
|
|
||||||
},
|
|
||||||
'ref': pr.branch,
|
|
||||||
},
|
|
||||||
'mergeable': True,
|
|
||||||
'state': pr.state,
|
|
||||||
'head': {
|
|
||||||
'sha': pr.head_sha,
|
|
||||||
'repo': {
|
|
||||||
'full_name': pr.project
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'merged': pr.is_merged,
|
|
||||||
'body': pr.body
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
|
|
||||||
class FakeIssueSearchResult(object):
|
|
||||||
def __init__(self, issue):
|
|
||||||
self.issue = issue
|
|
||||||
|
|
||||||
def __init__(self, connection):
|
|
||||||
self._fake_github_connection = connection
|
|
||||||
self._repos = {}
|
|
||||||
|
|
||||||
def user(self, login):
|
|
||||||
return self.FakeUser(login)
|
|
||||||
|
|
||||||
def repository(self, owner, proj):
|
|
||||||
return self._repos.get((owner, proj), None)
|
|
||||||
|
|
||||||
def repo_from_project(self, project):
|
|
||||||
# This is a convenience method for the tests.
|
|
||||||
owner, proj = project.split('/')
|
|
||||||
return self.repository(owner, proj)
|
|
||||||
|
|
||||||
def addProject(self, project):
|
|
||||||
owner, proj = project.name.split('/')
|
|
||||||
self._repos[(owner, proj)] = self.FakeRepository()
|
|
||||||
|
|
||||||
def pull_request(self, owner, project, number):
|
|
||||||
fake_pr = self._fake_github_connection.pull_requests[number - 1]
|
|
||||||
return self.FakePull(fake_pr)
|
|
||||||
|
|
||||||
def search_issues(self, query):
|
|
||||||
def tokenize(s):
|
|
||||||
return re.findall(r'[\w]+', s)
|
|
||||||
|
|
||||||
parts = tokenize(query)
|
|
||||||
terms = set()
|
|
||||||
results = []
|
|
||||||
for part in parts:
|
|
||||||
kv = part.split(':', 1)
|
|
||||||
if len(kv) == 2:
|
|
||||||
if kv[0] in set('type', 'is', 'in'):
|
|
||||||
# We only perform one search now and these aren't
|
|
||||||
# important; we can honor these terms later if
|
|
||||||
# necessary.
|
|
||||||
continue
|
|
||||||
terms.add(part)
|
|
||||||
|
|
||||||
for pr in self._fake_github_connection.pull_requests:
|
|
||||||
if not pr.body:
|
|
||||||
body = set()
|
|
||||||
else:
|
|
||||||
body = set(tokenize(pr.body))
|
|
||||||
if terms.intersection(body):
|
|
||||||
issue = FakeGithub.FakeIssue(pr)
|
|
||||||
results.append(FakeGithub.FakeIssueSearchResult(issue))
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
class FakeGithubPullRequest(object):
|
class FakeGithubPullRequest(object):
|
||||||
|
|
||||||
def __init__(self, github, number, project, branch,
|
def __init__(self, github, number, project, branch,
|
||||||
@ -1114,18 +926,18 @@ class FakeGithubConnection(githubconnection.GithubConnection):
|
|||||||
log = logging.getLogger("zuul.test.FakeGithubConnection")
|
log = logging.getLogger("zuul.test.FakeGithubConnection")
|
||||||
|
|
||||||
def __init__(self, driver, connection_name, connection_config,
|
def __init__(self, driver, connection_name, connection_config,
|
||||||
upstream_root=None):
|
changes_db=None, upstream_root=None):
|
||||||
super(FakeGithubConnection, self).__init__(driver, connection_name,
|
super(FakeGithubConnection, self).__init__(driver, connection_name,
|
||||||
connection_config)
|
connection_config)
|
||||||
self.connection_name = connection_name
|
self.connection_name = connection_name
|
||||||
self.pr_number = 0
|
self.pr_number = 0
|
||||||
self.pull_requests = []
|
self.pull_requests = changes_db
|
||||||
self.statuses = {}
|
self.statuses = {}
|
||||||
self.upstream_root = upstream_root
|
self.upstream_root = upstream_root
|
||||||
self.merge_failure = False
|
self.merge_failure = False
|
||||||
self.merge_not_allowed_count = 0
|
self.merge_not_allowed_count = 0
|
||||||
self.reports = []
|
self.reports = []
|
||||||
self.github_client = FakeGithub(self)
|
self.github_client = tests.fakegithub.FakeGithub(changes_db)
|
||||||
|
|
||||||
def getGithubClient(self,
|
def getGithubClient(self,
|
||||||
project=None,
|
project=None,
|
||||||
@ -1138,7 +950,7 @@ class FakeGithubConnection(githubconnection.GithubConnection):
|
|||||||
pull_request = FakeGithubPullRequest(
|
pull_request = FakeGithubPullRequest(
|
||||||
self, self.pr_number, project, branch, subject, self.upstream_root,
|
self, self.pr_number, project, branch, subject, self.upstream_root,
|
||||||
files=files, body=body)
|
files=files, body=body)
|
||||||
self.pull_requests.append(pull_request)
|
self.pull_requests[self.pr_number] = pull_request
|
||||||
return pull_request
|
return pull_request
|
||||||
|
|
||||||
def getPushEvent(self, project, ref, old_rev=None, new_rev=None,
|
def getPushEvent(self, project, ref, old_rev=None, new_rev=None,
|
||||||
@ -1186,7 +998,7 @@ class FakeGithubConnection(githubconnection.GithubConnection):
|
|||||||
self.getGithubClient(project).addProject(project)
|
self.getGithubClient(project).addProject(project)
|
||||||
|
|
||||||
def getPullBySha(self, sha, project):
|
def getPullBySha(self, sha, project):
|
||||||
prs = list(set([p for p in self.pull_requests if
|
prs = list(set([p for p in self.pull_requests.values() if
|
||||||
sha == p.head_sha and project == p.project]))
|
sha == p.head_sha and project == p.project]))
|
||||||
if len(prs) > 1:
|
if len(prs) > 1:
|
||||||
raise Exception('Multiple pulls found with head sha: %s' % sha)
|
raise Exception('Multiple pulls found with head sha: %s' % sha)
|
||||||
@ -1194,12 +1006,12 @@ class FakeGithubConnection(githubconnection.GithubConnection):
|
|||||||
return self.getPull(pr.project, pr.number)
|
return self.getPull(pr.project, pr.number)
|
||||||
|
|
||||||
def _getPullReviews(self, owner, project, number):
|
def _getPullReviews(self, owner, project, number):
|
||||||
pr = self.pull_requests[number - 1]
|
pr = self.pull_requests[number]
|
||||||
return pr.reviews
|
return pr.reviews
|
||||||
|
|
||||||
def getRepoPermission(self, project, login):
|
def getRepoPermission(self, project, login):
|
||||||
owner, proj = project.split('/')
|
owner, proj = project.split('/')
|
||||||
for pr in self.pull_requests:
|
for pr in self.pull_requests.values():
|
||||||
pr_owner, pr_project = pr.project.split('/')
|
pr_owner, pr_project = pr.project.split('/')
|
||||||
if (pr_owner == owner and proj == pr_project):
|
if (pr_owner == owner and proj == pr_project):
|
||||||
if login in pr.writers:
|
if login in pr.writers:
|
||||||
@ -1216,13 +1028,13 @@ class FakeGithubConnection(githubconnection.GithubConnection):
|
|||||||
def commentPull(self, project, pr_number, message):
|
def commentPull(self, project, pr_number, message):
|
||||||
# record that this got reported
|
# record that this got reported
|
||||||
self.reports.append((project, pr_number, 'comment'))
|
self.reports.append((project, pr_number, 'comment'))
|
||||||
pull_request = self.pull_requests[pr_number - 1]
|
pull_request = self.pull_requests[pr_number]
|
||||||
pull_request.addComment(message)
|
pull_request.addComment(message)
|
||||||
|
|
||||||
def mergePull(self, project, pr_number, commit_message='', sha=None):
|
def mergePull(self, project, pr_number, commit_message='', sha=None):
|
||||||
# record that this got reported
|
# record that this got reported
|
||||||
self.reports.append((project, pr_number, 'merge'))
|
self.reports.append((project, pr_number, 'merge'))
|
||||||
pull_request = self.pull_requests[pr_number - 1]
|
pull_request = self.pull_requests[pr_number]
|
||||||
if self.merge_failure:
|
if self.merge_failure:
|
||||||
raise Exception('Pull request was not merged')
|
raise Exception('Pull request was not merged')
|
||||||
if self.merge_not_allowed_count > 0:
|
if self.merge_not_allowed_count > 0:
|
||||||
@ -1242,13 +1054,13 @@ class FakeGithubConnection(githubconnection.GithubConnection):
|
|||||||
def labelPull(self, project, pr_number, label):
|
def labelPull(self, project, pr_number, label):
|
||||||
# record that this got reported
|
# record that this got reported
|
||||||
self.reports.append((project, pr_number, 'label', label))
|
self.reports.append((project, pr_number, 'label', label))
|
||||||
pull_request = self.pull_requests[pr_number - 1]
|
pull_request = self.pull_requests[pr_number]
|
||||||
pull_request.addLabel(label)
|
pull_request.addLabel(label)
|
||||||
|
|
||||||
def unlabelPull(self, project, pr_number, label):
|
def unlabelPull(self, project, pr_number, label):
|
||||||
# record that this got reported
|
# record that this got reported
|
||||||
self.reports.append((project, pr_number, 'unlabel', label))
|
self.reports.append((project, pr_number, 'unlabel', label))
|
||||||
pull_request = self.pull_requests[pr_number - 1]
|
pull_request = self.pull_requests[pr_number]
|
||||||
pull_request.removeLabel(label)
|
pull_request.removeLabel(label)
|
||||||
|
|
||||||
|
|
||||||
@ -2218,6 +2030,7 @@ class ZuulTestCase(BaseTestCase):
|
|||||||
# Set a changes database so multiple FakeGerrit's can report back to
|
# Set a changes database so multiple FakeGerrit's can report back to
|
||||||
# a virtual canonical database given by the configured hostname
|
# a virtual canonical database given by the configured hostname
|
||||||
self.gerrit_changes_dbs = {}
|
self.gerrit_changes_dbs = {}
|
||||||
|
self.github_changes_dbs = {}
|
||||||
|
|
||||||
def getGerritConnection(driver, name, config):
|
def getGerritConnection(driver, name, config):
|
||||||
db = self.gerrit_changes_dbs.setdefault(config['server'], {})
|
db = self.gerrit_changes_dbs.setdefault(config['server'], {})
|
||||||
@ -2233,7 +2046,10 @@ class ZuulTestCase(BaseTestCase):
|
|||||||
getGerritConnection))
|
getGerritConnection))
|
||||||
|
|
||||||
def getGithubConnection(driver, name, config):
|
def getGithubConnection(driver, name, config):
|
||||||
|
server = config.get('server', 'github.com')
|
||||||
|
db = self.github_changes_dbs.setdefault(server, {})
|
||||||
con = FakeGithubConnection(driver, name, config,
|
con = FakeGithubConnection(driver, name, config,
|
||||||
|
changes_db=db,
|
||||||
upstream_root=self.upstream_root)
|
upstream_root=self.upstream_root)
|
||||||
self.event_queues.append(con.event_queue)
|
self.event_queues.append(con.event_queue)
|
||||||
setattr(self, 'fake_' + name, con)
|
setattr(self, 'fake_' + name, con)
|
||||||
|
214
tests/fakegithub.py
Normal file
214
tests/fakegithub.py
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Copyright 2018 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class FakeUser(object):
|
||||||
|
def __init__(self, login):
|
||||||
|
self.login = login
|
||||||
|
self.name = "Github User"
|
||||||
|
self.email = "github.user@example.com"
|
||||||
|
|
||||||
|
|
||||||
|
class FakeBranch(object):
|
||||||
|
def __init__(self, branch='master'):
|
||||||
|
self.name = branch
|
||||||
|
|
||||||
|
|
||||||
|
class FakeStatus(object):
|
||||||
|
def __init__(self, state, url, description, context, user):
|
||||||
|
self._state = state
|
||||||
|
self._url = url
|
||||||
|
self._description = description
|
||||||
|
self._context = context
|
||||||
|
self._user = user
|
||||||
|
|
||||||
|
def as_dict(self):
|
||||||
|
return {
|
||||||
|
'state': self._state,
|
||||||
|
'url': self._url,
|
||||||
|
'description': self._description,
|
||||||
|
'context': self._context,
|
||||||
|
'creator': {
|
||||||
|
'login': self._user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class FakeCommit(object):
|
||||||
|
def __init__(self):
|
||||||
|
self._statuses = []
|
||||||
|
|
||||||
|
def set_status(self, state, url, description, context, user):
|
||||||
|
status = FakeStatus(
|
||||||
|
state, url, description, context, user)
|
||||||
|
# always insert a status to the front of the list, to represent
|
||||||
|
# the last status provided for a commit.
|
||||||
|
self._statuses.insert(0, status)
|
||||||
|
|
||||||
|
def statuses(self):
|
||||||
|
return self._statuses
|
||||||
|
|
||||||
|
|
||||||
|
class FakeRepository(object):
|
||||||
|
def __init__(self):
|
||||||
|
self._branches = [FakeBranch()]
|
||||||
|
self._commits = {}
|
||||||
|
|
||||||
|
def branches(self, protected=False):
|
||||||
|
if protected:
|
||||||
|
# simulate there is no protected branch
|
||||||
|
return []
|
||||||
|
return self._branches
|
||||||
|
|
||||||
|
def create_status(self, sha, state, url, description, context,
|
||||||
|
user='zuul'):
|
||||||
|
# Since we're bypassing github API, which would require a user, we
|
||||||
|
# default the user as 'zuul' here.
|
||||||
|
commit = self._commits.get(sha, None)
|
||||||
|
if commit is None:
|
||||||
|
commit = FakeCommit()
|
||||||
|
self._commits[sha] = commit
|
||||||
|
commit.set_status(state, url, description, context, user)
|
||||||
|
|
||||||
|
def commit(self, sha):
|
||||||
|
commit = self._commits.get(sha, None)
|
||||||
|
if commit is None:
|
||||||
|
commit = FakeCommit()
|
||||||
|
self._commits[sha] = commit
|
||||||
|
return commit
|
||||||
|
|
||||||
|
|
||||||
|
class FakeLabel(object):
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
|
||||||
|
class FakeIssue(object):
|
||||||
|
def __init__(self, fake_pull_request):
|
||||||
|
self._fake_pull_request = fake_pull_request
|
||||||
|
|
||||||
|
def pull_request(self):
|
||||||
|
return FakePull(self._fake_pull_request)
|
||||||
|
|
||||||
|
def labels(self):
|
||||||
|
return [FakeLabel(l)
|
||||||
|
for l in self._fake_pull_request.labels]
|
||||||
|
|
||||||
|
|
||||||
|
class FakeFile(object):
|
||||||
|
def __init__(self, filename):
|
||||||
|
self.filename = filename
|
||||||
|
|
||||||
|
|
||||||
|
class FakePull(object):
|
||||||
|
def __init__(self, fake_pull_request):
|
||||||
|
self._fake_pull_request = fake_pull_request
|
||||||
|
|
||||||
|
def issue(self):
|
||||||
|
return FakeIssue(self._fake_pull_request)
|
||||||
|
|
||||||
|
def files(self):
|
||||||
|
return [FakeFile(fn)
|
||||||
|
for fn in self._fake_pull_request.files]
|
||||||
|
|
||||||
|
def as_dict(self):
|
||||||
|
pr = self._fake_pull_request
|
||||||
|
connection = pr.github
|
||||||
|
data = {
|
||||||
|
'number': pr.number,
|
||||||
|
'title': pr.subject,
|
||||||
|
'url': 'https://%s/%s/pull/%s' % (
|
||||||
|
connection.server, pr.project, pr.number
|
||||||
|
),
|
||||||
|
'updated_at': pr.updated_at,
|
||||||
|
'base': {
|
||||||
|
'repo': {
|
||||||
|
'full_name': pr.project
|
||||||
|
},
|
||||||
|
'ref': pr.branch,
|
||||||
|
},
|
||||||
|
'mergeable': True,
|
||||||
|
'state': pr.state,
|
||||||
|
'head': {
|
||||||
|
'sha': pr.head_sha,
|
||||||
|
'repo': {
|
||||||
|
'full_name': pr.project
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'merged': pr.is_merged,
|
||||||
|
'body': pr.body
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class FakeIssueSearchResult(object):
|
||||||
|
def __init__(self, issue):
|
||||||
|
self.issue = issue
|
||||||
|
|
||||||
|
|
||||||
|
class FakeGithub(object):
|
||||||
|
def __init__(self, pull_requests):
|
||||||
|
self._pull_requests = pull_requests
|
||||||
|
self._repos = {}
|
||||||
|
|
||||||
|
def user(self, login):
|
||||||
|
return FakeUser(login)
|
||||||
|
|
||||||
|
def repository(self, owner, proj):
|
||||||
|
return self._repos.get((owner, proj), None)
|
||||||
|
|
||||||
|
def repo_from_project(self, project):
|
||||||
|
# This is a convenience method for the tests.
|
||||||
|
owner, proj = project.split('/')
|
||||||
|
return self.repository(owner, proj)
|
||||||
|
|
||||||
|
def addProject(self, project):
|
||||||
|
owner, proj = project.name.split('/')
|
||||||
|
self._repos[(owner, proj)] = FakeRepository()
|
||||||
|
|
||||||
|
def pull_request(self, owner, project, number):
|
||||||
|
fake_pr = self._pull_requests[number]
|
||||||
|
return FakePull(fake_pr)
|
||||||
|
|
||||||
|
def search_issues(self, query):
|
||||||
|
def tokenize(s):
|
||||||
|
return re.findall(r'[\w]+', s)
|
||||||
|
|
||||||
|
parts = tokenize(query)
|
||||||
|
terms = set()
|
||||||
|
results = []
|
||||||
|
for part in parts:
|
||||||
|
kv = part.split(':', 1)
|
||||||
|
if len(kv) == 2:
|
||||||
|
if kv[0] in set('type', 'is', 'in'):
|
||||||
|
# We only perform one search now and these aren't
|
||||||
|
# important; we can honor these terms later if
|
||||||
|
# necessary.
|
||||||
|
continue
|
||||||
|
terms.add(part)
|
||||||
|
|
||||||
|
for pr in self._pull_requests.values():
|
||||||
|
if not pr.body:
|
||||||
|
body = set()
|
||||||
|
else:
|
||||||
|
body = set(tokenize(pr.body))
|
||||||
|
if terms.intersection(body):
|
||||||
|
issue = FakeIssue(pr)
|
||||||
|
results.append(FakeIssueSearchResult(issue))
|
||||||
|
|
||||||
|
return results
|
Loading…
Reference in New Issue
Block a user