migratron / code_migration /tests /conftest.py
amrithanandini's picture
integrated backend and frontend
1b35d41
"""Shared fixtures for Code Migration environment tests."""
from __future__ import annotations
import json
import os
import tempfile
from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
from code_migration.dataset_loader import Task
# ---------------------------------------------------------------------------
# Sample Task factory
# ---------------------------------------------------------------------------
def make_task(**overrides) -> Task:
"""Create a Task with sensible defaults. Override any field via kwargs."""
defaults = {
"repo_name": "test-owner/test-repo",
"repo_url": "https://github.com/test-owner/test-repo.git",
"commit_hash": "abc123def456",
"patch": "--- a.txt\n+++ a.txt\n@@ -1 +1 @@\n-old\n+new\n",
"test_patch": "",
"gold_patch": "--- src/main.py\n+++ src/main.py\n@@ -1 +1 @@\n-broken\n+fixed\n",
"reproduction_target_date": "2020-01-01",
"reproduction_target_version": "3.8.1",
"migration_target_date": "2025-07-31",
"migration_target_version": "3.12.11",
"dockerfile": (
"FROM python:3.12.11\nWORKDIR /work\nCOPY . .\n"
"RUN pip install -r requirements.txt\nCMD [\"python\", \"-m\", \"pytest\"]\n"
),
"version_source": "default",
"script_source": "requirements.txt",
"dependency_versions": "numpy==1.26.0\npandas==2.1.0\n",
"test_type": "pytest",
"test_files": "tests/test_main.py",
"test_count": 5,
"related_modules": "numpy",
"py_file_count": 10,
"total_loc_python": 500,
"difficulty": "Easy",
"license": "MIT",
}
defaults.update(overrides)
return Task(**defaults)
@pytest.fixture
def sample_task() -> Task:
"""A single sample Task."""
return make_task()
# ---------------------------------------------------------------------------
# Fixture JSONL file
# ---------------------------------------------------------------------------
def _task_to_dict(task: Task) -> dict:
"""Convert a Task dataclass to a plain dict."""
from dataclasses import asdict
return asdict(task)
@pytest.fixture
def fixture_jsonl(tmp_path: Path) -> Path:
"""Write a small JSONL fixture with 3 tasks of varying difficulty."""
tasks = [
make_task(repo_name="owner/easy-repo", difficulty="Easy"),
make_task(repo_name="owner/medium-repo", difficulty="Medium"),
make_task(repo_name="owner/hard-repo", difficulty="Hard"),
]
jsonl_path = tmp_path / "test_dataset.jsonl"
with open(jsonl_path, "w") as fh:
for t in tasks:
fh.write(json.dumps(_task_to_dict(t)) + "\n")
return jsonl_path
@pytest.fixture
def malformed_jsonl(tmp_path: Path) -> Path:
"""Write a JSONL file with a malformed line at line 2."""
good = json.dumps(_task_to_dict(make_task()))
jsonl_path = tmp_path / "bad_dataset.jsonl"
with open(jsonl_path, "w") as fh:
fh.write(good + "\n")
fh.write("{this is not valid json}\n")
fh.write(good + "\n")
return jsonl_path
# ---------------------------------------------------------------------------
# Temp workspace helpers
# ---------------------------------------------------------------------------
@pytest.fixture
def workspace_dir(tmp_path: Path) -> Path:
"""Create a temporary workspace directory mimicking /work structure."""
ws = tmp_path / "workspace"
ws.mkdir()
# Create some sample files
(ws / "src").mkdir()
(ws / "src" / "main.py").write_text("print('hello')\n")
(ws / "tests").mkdir()
(ws / "tests" / "test_main.py").write_text("def test_one(): pass\n")
(ws / "setup.py").write_text("from setuptools import setup\nsetup()\n")
(ws / ".hidden_file").write_text("secret\n")
(ws / "setup_test-owner__test-repo.sh").write_text("#!/bin/bash\n")
(ws / "test_test-owner__test-repo.sh").write_text("#!/bin/bash\n")
return ws
# ---------------------------------------------------------------------------
# Mock subprocess helpers
# ---------------------------------------------------------------------------
@pytest.fixture
def mock_subprocess_run():
"""Patch subprocess.run to prevent real process execution."""
with patch("subprocess.run") as mock_run:
mock_run.return_value = MagicMock(
returncode=0, stdout="", stderr=""
)
yield mock_run