test(harness): reorganize regression suites and preserve contract coverage
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
"""Shared review fixtures; no unittest test cases or TestCase imports."""
|
||||
import copy
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
|
||||
from harness.tests._support.paths import ROOT
|
||||
|
||||
SPEC_SCRIPT = ROOT / 'harness/agents/spec/skills/gitea-implementation-spec-review/scripts/review_support.py'
|
||||
|
||||
|
||||
def _load(path, name):
|
||||
spec = importlib.util.spec_from_file_location(name, path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
support = _load(SPEC_SCRIPT, 'spec_support_fixture')
|
||||
|
||||
|
||||
def plan_fixture():
|
||||
target = {'owner': 'acme', 'repository': 'repo', 'issue': 3, 'pull': 7,
|
||||
'head': 'a' * 40, 'base': 'c' * 40}
|
||||
digest = __import__('hashlib').sha256(b'approved contract').hexdigest()
|
||||
marker = ('<!-- gitea-agent:code-review/v1 owner=acme repository=repo issue=3 pr=7 '
|
||||
f'head={target["head"]} contract-sha256={digest} -->')
|
||||
return {'schema': 'gitea-agent.code-review-publication/v1', 'target': target,
|
||||
'contract_sha256': digest, 'reviewer': {'id': 42, 'login': 'gitea-review-agent'},
|
||||
'spec_reviewer': {'id': 5, 'login': 'gitea-spec-agent'}, 'spec_review_id': 9, 'spec_paths': ['src/a.py'],
|
||||
'verdict': 'approve', 'body': marker + '\n- Verdict: `approve`\n검토 완료.\n',
|
||||
'provider_contract': {'supersede_same_author': True, 'retouch_dismissed': True,
|
||||
'unordered_commit_files': True,
|
||||
'evidence': ['saved observed Gitea projection and ordering']}}
|
||||
|
||||
|
||||
def publication_fixture():
|
||||
p = plan_fixture(); t = p['target']
|
||||
spec_result = {'schema': support.SCHEMA,
|
||||
'target': {k: t[k] for k in ['owner', 'repository', 'issue', 'pull', 'head']},
|
||||
'contract_sha256': p['contract_sha256'], 'verdict': 'approve',
|
||||
'criteria': [{'criterion': 'REQ-1', 'contract': '계약',
|
||||
'implementation_paths': ['src/a.py'], 'test_paths': [],
|
||||
'evidence': '직접 검증', 'result': 'satisfied', 'reason': '충족'}],
|
||||
'scope': {'missing': [], 'excess': [], 'spec_conflicts': []}, 'conclusion': '충족'}
|
||||
url = 'https://gitea.jsfamily.quest/acme/repo/pulls/7'
|
||||
old_time = '2026-10-04T00:00:00Z'; new_time = '2026-10-04T00:01:00Z'
|
||||
def review(rid, user, body, head, state):
|
||||
return {'id': rid, 'user': copy.deepcopy(user), 'body': body, 'commit_id': head, 'state': state,
|
||||
'official': True, 'dismissed': False, 'stale': head != t['head'],
|
||||
'submitted_at': old_time, 'updated_at': old_time, 'comments_count': 0,
|
||||
'pull_request_url': url}
|
||||
sr = review(9, p['spec_reviewer'], support.render_review(spec_result, {'src/a.py'}, declaration={'mode': 'none'}),
|
||||
t['head'], 'APPROVED')
|
||||
previous = review(8, p['reviewer'], 'old review body', 'd' * 40, 'REQUEST_CHANGES')
|
||||
s = {'identity': copy.deepcopy(p['reviewer']), 'spec_user': copy.deepcopy(p['spec_reviewer']),
|
||||
'repository': {'full_name': 'acme/repo', 'default_branch': 'main'},
|
||||
'issue': {'number': 3, 'body': 'approved contract', 'state': 'open',
|
||||
'updated_at': old_time, 'repository': {'full_name': 'acme/repo'}},
|
||||
'pr': {'number': 7, 'html_url': url, 'body': 'Closes #3', 'user': {'id': 99},
|
||||
'state': 'open', 'merged': False, 'updated_at': old_time,
|
||||
'review_comments': 2, 'requested_reviewers': [],
|
||||
'base': {'sha': t['base'], 'ref': 'main', 'repo': {'full_name': 'acme/repo'}},
|
||||
'head': {'sha': t['head'], 'ref': 'feature', 'repo': {'full_name': 'acme/repo'}}},
|
||||
'files': [{'filename': 'src/a.py', 'status': 'modified'}],
|
||||
'commits': [{'sha': t['head'], 'files': [{'filename': 'src/a.py', 'status': 'modified'},
|
||||
{'filename': 'docs/x.md', 'status': 'added'}]}],
|
||||
'reviews': [previous, sr], 'review_comments': {'8': [], '9': []},
|
||||
'issue_comments': [], 'pr_comments': [], 'statuses': [], 'pagination': {}}
|
||||
exact = review(10, p['reviewer'], p['body'], t['head'], 'APPROVED')
|
||||
exact['submitted_at'] = exact['updated_at'] = new_time
|
||||
after = copy.deepcopy(s); after['reviews'].append(exact); after['review_comments']['10'] = []
|
||||
after['pr']['updated_at'] = new_time; after['pr']['review_comments'] += 1
|
||||
for snap in [s, after]:
|
||||
for name in ['files', 'commits', 'reviews', 'issue_comments', 'pr_comments', 'statuses']:
|
||||
snap['pagination'][name] = [{'page': 1, 'count': len(snap[name]),
|
||||
'declared_total': len(snap[name]), 'link': None}]
|
||||
for rid, comments in snap['review_comments'].items():
|
||||
snap['pagination']['review_comments_' + rid] = [{'page': 1, 'count': len(comments),
|
||||
'declared_total': len(comments), 'link': None}]
|
||||
return p, s, after, copy.deepcopy(exact)
|
||||
|
||||
|
||||
class FakeAPI:
|
||||
def __init__(self, plan, before, after, exact):
|
||||
self.plan = plan; self.before = before; self.after = after; self.exact = exact
|
||||
self.created = False; self.posts = 0; self.timeout = False; self.apply = True
|
||||
self.events = []
|
||||
|
||||
def identity(self):
|
||||
self.events.append('identity')
|
||||
return copy.deepcopy(self.plan['reviewer'])
|
||||
|
||||
def snapshot(self, target):
|
||||
self.events.append('snapshot')
|
||||
return copy.deepcopy(self.after if self.created else self.before)
|
||||
|
||||
def create_review(self, target, payload):
|
||||
self.events.append('create'); self.posts += 1
|
||||
if self.apply: self.created = True
|
||||
if self.timeout: raise TimeoutError('secret transport detail must not escape')
|
||||
return copy.deepcopy(self.exact)
|
||||
|
||||
def read_review(self, target, rid):
|
||||
self.events.append('exact')
|
||||
return copy.deepcopy(self.exact)
|
||||
|
||||
|
||||
class FakeLease:
|
||||
def __init__(self): self.valid = True; self.checks = 0
|
||||
def check(self, plan):
|
||||
self.checks += 1
|
||||
if not self.valid: raise support.ValidationError('expired lease')
|
||||
Reference in New Issue
Block a user