113 lines
4.3 KiB
Python
113 lines
4.3 KiB
Python
import json
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
INSTALL = ROOT / 'scripts' / 'install_into_repo.sh'
|
|
|
|
|
|
class ArnesCoreTests(unittest.TestCase):
|
|
def run_cmd(self, args, cwd=None, input_text=None, check=True):
|
|
result = subprocess.run(
|
|
args,
|
|
cwd=cwd or ROOT,
|
|
input=input_text,
|
|
text=True,
|
|
capture_output=True,
|
|
)
|
|
if check and result.returncode != 0:
|
|
raise AssertionError(
|
|
f"Command failed: {args}\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}"
|
|
)
|
|
return result
|
|
|
|
def test_install_refuses_source_repo(self):
|
|
result = self.run_cmd([str(INSTALL), str(ROOT)], check=False)
|
|
self.assertNotEqual(result.returncode, 0)
|
|
self.assertIn('Refusing to install ARNES into its own source repository', result.stdout)
|
|
|
|
def test_install_start_verify_and_publish_in_external_repo(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
tmp_path = Path(tmp)
|
|
target = tmp_path / 'project-repo'
|
|
remote = tmp_path / 'remote.git'
|
|
|
|
self.run_cmd([str(INSTALL), str(target)])
|
|
self.assertTrue((target / 'scripts' / 'start.sh').is_file())
|
|
self.assertFalse((target / 'tests').exists(), 'source self-tests must not be installed into project repo')
|
|
|
|
self.run_cmd(['git', 'config', 'user.name', 'ARNES Bot'], cwd=target)
|
|
self.run_cmd(['git', 'config', 'user.email', 'arnes@example.com'], cwd=target)
|
|
self.run_cmd(['git', 'init', '--bare', str(remote)])
|
|
self.run_cmd(['git', 'remote', 'add', 'origin', str(remote)], cwd=target)
|
|
|
|
wizard_input = '\n'.join([
|
|
'demo-project',
|
|
'Demo project',
|
|
'project',
|
|
'1',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
]) + '\n'
|
|
self.run_cmd(['./scripts/start.sh'], cwd=target, input_text=wizard_input)
|
|
|
|
self.assertTrue((target / 'project' / 'tests').is_dir())
|
|
cfg = json.loads((target / 'harness' / 'project.config.json').read_text(encoding='utf-8'))
|
|
self.assertEqual(cfg['app_dir'], 'project')
|
|
self.assertEqual(cfg['commands']['test'], 'python3 -m unittest discover -s project/tests -v')
|
|
|
|
verify_result = self.run_cmd(['./scripts/verify.sh'], cwd=target)
|
|
self.assertIn('Harness verificado', verify_result.stdout)
|
|
|
|
self.run_cmd(['python3', 'scripts/new_ticket.py'], cwd=target, input_text='\n'.join([
|
|
'fix',
|
|
'Repair docs',
|
|
'Need docs repair',
|
|
'Make docs clear',
|
|
'Docs flow',
|
|
'No redesign',
|
|
'low',
|
|
'med',
|
|
'Docs clear',
|
|
'Verify green',
|
|
'',
|
|
]) + '\n')
|
|
|
|
with (target / 'project' / 'README.md').open('a', encoding='utf-8') as fh:
|
|
fh.write('\nchange\n')
|
|
|
|
publish_result = self.run_cmd(
|
|
['python3', 'scripts/publish_ticket.py', '--feature-id', 'F-001'],
|
|
cwd=target,
|
|
)
|
|
self.assertIn('done ->', publish_result.stdout)
|
|
|
|
publish_path = target / 'work' / 'artifacts' / 'F-001' / 'publish.json'
|
|
payload = json.loads(publish_path.read_text(encoding='utf-8'))
|
|
self.assertEqual(payload['verdict'], 'PUBLISHED')
|
|
self.assertTrue(payload['pushed'])
|
|
self.assertEqual(payload['remote'], 'origin')
|
|
|
|
status_result = self.run_cmd(['git', 'status', '--short'], cwd=target)
|
|
self.assertEqual(status_result.stdout.strip(), '')
|
|
|
|
remote_refs = self.run_cmd(['git', 'ls-remote', 'origin'], cwd=target)
|
|
self.assertIn('refs/heads/master', remote_refs.stdout)
|
|
|
|
def test_agent_status_rejects_invalid_agent(self):
|
|
result = self.run_cmd(
|
|
['python3', 'scripts/agent_status.py', 'set', '--agent', 'nope'],
|
|
check=False,
|
|
)
|
|
self.assertNotEqual(result.returncode, 0)
|
|
combined = (result.stdout + result.stderr)
|
|
self.assertIn('Invalid agent: nope', combined)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|