From d5da71bb037b003ba81af1147ae09f26f2eb7884 Mon Sep 17 00:00:00 2001 From: Ivan Dubograi Date: Fri, 1 May 2026 13:23:35 +0200 Subject: [PATCH 1/2] Added e2e tests --- .github/workflows/ci.yml | 81 ++++++++++++++++++++++++++++++++++ src/specode/__init__.py | 1 - tests/e2e/test_cli_process.py | 8 +++- tests/e2e/test_terminal_pty.py | 4 +- tests/test_config.py | 4 +- 5 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..64e094a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,81 @@ +name: CI + +on: + push: + pull_request: + +permissions: + contents: read + +jobs: + lint-format: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.10" + + - name: Set up uv + uses: astral-sh/setup-uv@v8 + + - name: Install dependencies + run: uv sync --all-extras --dev + + - name: Run Ruff lint + run: uv run ruff check . + + - name: Check Ruff formatting + run: uv run ruff format --check . + + unit-tests: + runs-on: ubuntu-latest + + env: + OPENAI_API_KEY: test-key + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.10" + + - name: Set up uv + uses: astral-sh/setup-uv@v8 + + - name: Install dependencies + run: uv sync --all-extras --dev + + - name: Run unit tests + run: uv run pytest tests --ignore=tests/e2e + + e2e-tests: + runs-on: ubuntu-latest + + env: + OPENAI_API_KEY: test-key + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.10" + + - name: Set up uv + uses: astral-sh/setup-uv@v8 + + - name: Install dependencies + run: uv sync --all-extras --dev + + - name: Run e2e tests + run: uv run pytest tests/e2e -o addopts='' diff --git a/src/specode/__init__.py b/src/specode/__init__.py index b8c6ad5..4f237bc 100644 --- a/src/specode/__init__.py +++ b/src/specode/__init__.py @@ -3,4 +3,3 @@ __all__ = ["__version__"] __version__ = "0.1.0" - diff --git a/tests/e2e/test_cli_process.py b/tests/e2e/test_cli_process.py index 816ca92..3f430fe 100644 --- a/tests/e2e/test_cli_process.py +++ b/tests/e2e/test_cli_process.py @@ -79,7 +79,9 @@ def test_specode_exits_with_configuration_error_when_openai_api_key_is_missing( tmp_path: Path, ) -> None: result, env = _run_specode(tmp_path, stdin="", extra_env={"OPENAI_API_KEY": ""}) - diagnostics = _format_diagnostics(env, result.stdout, result.stderr, returncode=result.returncode) + diagnostics = _format_diagnostics( + env, result.stdout, result.stderr, returncode=result.returncode + ) assert result.returncode == 1, diagnostics assert "Configuration Error" in result.stdout, diagnostics @@ -92,7 +94,9 @@ def test_specode_handles_help_then_exit_without_calling_a_model(tmp_path: Path) stdin="/help\n/exit\n", extra_env={"OPENAI_API_KEY": "test-key"}, ) - diagnostics = _format_diagnostics(env, result.stdout, result.stderr, returncode=result.returncode) + diagnostics = _format_diagnostics( + env, result.stdout, result.stderr, returncode=result.returncode + ) assert result.returncode == 0, diagnostics assert "Type / for commands" in result.stdout, diagnostics diff --git a/tests/e2e/test_terminal_pty.py b/tests/e2e/test_terminal_pty.py index 4a0cb29..4bf43bf 100644 --- a/tests/e2e/test_terminal_pty.py +++ b/tests/e2e/test_terminal_pty.py @@ -21,9 +21,7 @@ REPO_ROOT = Path(__file__).resolve().parents[2] COMMAND = "uv run specode" PTY_TIMEOUT_SECONDS = 4 -ANSI_ESCAPE_PATTERN = re.compile( - r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1B\\))" -) +ANSI_ESCAPE_PATTERN = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1B\\))") def _isolated_env(tmp_path: Path) -> dict[str, str]: diff --git a/tests/test_config.py b/tests/test_config.py index eee327a..bb5fd3a 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -9,7 +9,9 @@ ) -def test_raises_a_clear_error_when_openai_api_key_is_missing(monkeypatch: pytest.MonkeyPatch) -> None: +def test_raises_a_clear_error_when_openai_api_key_is_missing( + monkeypatch: pytest.MonkeyPatch, +) -> None: monkeypatch.setenv("OPENAI_API_KEY", "") with pytest.raises(ConfigurationError) as exc_info: From 825ce2212f4ce00c6b9db6cc6540669c6200abe4 Mon Sep 17 00:00:00 2001 From: Ivan Dubograi Date: Fri, 1 May 2026 13:30:39 +0200 Subject: [PATCH 2/2] Fix CI --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 64e094a..a47119c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,10 +21,10 @@ jobs: python-version: "3.10" - name: Set up uv - uses: astral-sh/setup-uv@v8 + uses: astral-sh/setup-uv@v5 - name: Install dependencies - run: uv sync --all-extras --dev + run: uv sync --frozen --all-extras --dev - name: Run Ruff lint run: uv run ruff check . @@ -48,10 +48,10 @@ jobs: python-version: "3.10" - name: Set up uv - uses: astral-sh/setup-uv@v8 + uses: astral-sh/setup-uv@v5 - name: Install dependencies - run: uv sync --all-extras --dev + run: uv sync --frozen --all-extras --dev - name: Run unit tests run: uv run pytest tests --ignore=tests/e2e @@ -72,10 +72,10 @@ jobs: python-version: "3.10" - name: Set up uv - uses: astral-sh/setup-uv@v8 + uses: astral-sh/setup-uv@v5 - name: Install dependencies - run: uv sync --all-extras --dev + run: uv sync --frozen --all-extras --dev - name: Run e2e tests run: uv run pytest tests/e2e -o addopts=''