diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef79e43d5..a239e7e14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,3 +90,38 @@ jobs: - name: Run style checks run: uv run tox -e style + + windows: + # Service containers do not run on Windows runners, so this job starts the + # PostgreSQL the image ships (service disabled, user postgres, password + # root). Unit tests only: behave drives pgcli through pexpect.spawn, which + # does not exist on Windows. + runs-on: windows-latest + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: astral-sh/setup-uv@c7f87aa956e4c323abf06d5dec078e358f6b4d04 # v6.0.0 + with: + version: "latest" + + - name: Set up Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: "3.13" + + - name: Start PostgreSQL + run: | + $pg = Get-Service -Name "postgresql*" + Set-Service -InputObject $pg -StartupType Manual + Start-Service -InputObject $pg + & "$env:PGBIN\pg_isready.exe" --timeout 30 + + - name: Install requirements + run: uv sync --all-extras -p 3.13 + + - name: Run unit tests + env: + PGHOST: localhost + PGUSER: postgres + PGPASSWORD: root + run: uv run tox -e py3.13 diff --git a/tests/test_main.py b/tests/test_main.py index 319a7672f..baf0300a9 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -939,7 +939,8 @@ def test_edit_named_query(): """Test \\ne edits/creates a named query via the external editor.""" from pgspecial.namedqueries import NamedQueries - with tempfile.TemporaryDirectory() as tmpdir: + # pgcli keeps its log open, which Windows will not delete at cleanup. + with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmpdir: config_file = os.path.join(tmpdir, "config") with open(config_file, "w") as f: f.write("[main]\n") diff --git a/tests/test_pgcompleter.py b/tests/test_pgcompleter.py index bf38db236..f3ea46f60 100644 --- a/tests/test_pgcompleter.py +++ b/tests/test_pgcompleter.py @@ -1,7 +1,6 @@ import json import pytest from pgcli import pgcompleter -import tempfile from prompt_toolkit.document import Document @@ -87,17 +86,17 @@ def test_generate_alias_can_use_alias_map(table_name, alias_map, alias): ("some_table", {"some_table": "my_alias"}, "my_alias"), ], ) -def test_pgcompleter_alias_uses_configured_alias_map(table_name, alias_map, alias): - with tempfile.NamedTemporaryFile(mode="w", suffix=".json") as alias_map_file: - alias_map_file.write(json.dumps(alias_map)) - alias_map_file.seek(0) - completer = pgcompleter.PGCompleter( - settings={ - "generate_aliases": True, - "alias_map_file": alias_map_file.name, - } - ) - assert completer.alias(table_name, []) == alias +def test_pgcompleter_alias_uses_configured_alias_map(table_name, alias_map, alias, tmp_path): + # A plain file: Windows cannot reopen an open NamedTemporaryFile by name. + alias_map_file = tmp_path / "alias_map.json" + alias_map_file.write_text(json.dumps(alias_map)) + completer = pgcompleter.PGCompleter( + settings={ + "generate_aliases": True, + "alias_map_file": str(alias_map_file), + } + ) + assert completer.alias(table_name, []) == alias @pytest.mark.parametrize( diff --git a/tox.ini b/tox.ini index 15f952f23..39f8e35a4 100644 --- a/tox.ini +++ b/tox.ini @@ -12,6 +12,8 @@ passenv = PGHOST PGUSER PGPASSWORD PYTHONIOENCODING + # getpass.getuser() reads it on Windows, which has no pwd module + USERNAME setenv = PYTHONIOENCODING = utf-8