diff --git a/.coverage b/.coverage index 80c2a68..43a4e1e 100644 Binary files a/.coverage and b/.coverage differ diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 36f57a2..d651ed1 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -1,6 +1,17 @@ name: Json2xml -on: [push, pull_request] +on: + push: + branches: [main, master] + paths-ignore: + - 'docs/**' + - '*.md' + - '*.rst' + pull_request: + paths-ignore: + - 'docs/**' + - '*.md' + - '*.rst' permissions: contents: read @@ -25,12 +36,19 @@ jobs: macos-latest, ] include: - # Add exact version 3.14.0-alpha.0 for ubuntu-latest only + # Add exact version 3.14.0-beta.1 for ubuntu-latest only - python-version: 3.14.0-beta.1 tox-python-version: py314-full os: ubuntu-latest + # Add special linting and type-checking jobs + - python-version: '3.12' + tox-python-version: lint + os: ubuntu-latest + - python-version: '3.12' + tox-python-version: typecheck + os: ubuntu-latest exclude: - # Exclude other OSes with Python 3.14.0-alpha.0 + # Exclude other OSes with Python 3.14.0-beta.1 - python-version: 3.14.0-beta.1 tox-python-version: py314-full os: windows-latest @@ -48,25 +66,35 @@ jobs: with: python-version: ${{ matrix.python-version }} allow-prereleases: true + cache: 'pip' + cache-dependency-path: | + requirements*.txt + requirements-dev.in + - name: install uv - uses: astral-sh/setup-uv@v3 + uses: astral-sh/setup-uv@v6 with: enable-cache: true - cache-dependency-glob: requirements-dev.txt + cache-dependency-glob: requirements*.txt - name: Install dependencies - run: uv pip install --system tox tox-uv + run: | + uv pip install --system tox tox-uv + uv pip install --system pytest pytest-xdist pytest-cov - name: Run tox targets for ${{ matrix.python-version }} - run: tox -e ${{matrix.tox-python-version}} + run: tox -e ${{matrix.tox-python-version}} --parallel auto + env: + PYTHONPATH: ${{ github.workspace }} - name: Upload coverage to Codecov uses: codecov/codecov-action@v5 + if: success() && matrix.tox-python-version != 'lint' && matrix.tox-python-version != 'typecheck' with: directory: ./coverage/reports/ env_vars: OS,PYTHON fail_ci_if_error: true - files: ./coverage.xml,./coverage2.xml,!./cache + files: ./coverage.xml flags: unittests token: ${{ secrets.CODECOV_TOKEN }} name: codecov-umbrella diff --git a/pyproject.toml b/pyproject.toml index 008f220..f1871f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,9 @@ test = [ [tool.pytest.ini_options] testpaths = ["tests"] +python_files = ["test_*.py"] +xvs = true +addopts = "--cov=json2xml --cov-report=xml:coverage/reports/coverage.xml --cov-report=term" [tool.ruff] exclude = [ ".env", diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..aa5b29b --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,85 @@ +"""Pytest configuration for json2xml tests.""" +from __future__ import annotations + +import json +import os +from pathlib import Path +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union + +import pytest + +if TYPE_CHECKING: + from _pytest.capture import CaptureFixture + from _pytest.fixtures import FixtureRequest + from _pytest.logging import LogCaptureFixture + from _pytest.monkeypatch import MonkeyPatch + from pytest_mock.plugin import MockerFixture + + +@pytest.fixture +def sample_json_string() -> str: + """Return a sample JSON string for testing. + + Returns: + str: A sample JSON string + """ + return '{"login":"mojombo","id":1,"avatar_url":"https://avatars0.githubusercontent.com/u/1?v=4"}' + + +@pytest.fixture +def sample_json_dict() -> Dict[str, Any]: + """Return a sample JSON dictionary for testing. + + Returns: + Dict[str, Any]: A sample JSON dictionary + """ + return { + "login": "mojombo", + "id": 1, + "avatar_url": "https://avatars0.githubusercontent.com/u/1?v=4", + } + + +@pytest.fixture +def sample_json_list() -> List[Dict[str, Any]]: + """Return a sample JSON list for testing. + + Returns: + List[Dict[str, Any]]: A sample list of JSON dictionaries + """ + return [ + { + "login": "mojombo", + "id": 1, + "avatar_url": "https://avatars0.githubusercontent.com/u/1?v=4", + }, + { + "login": "defunkt", + "id": 2, + "avatar_url": "https://avatars0.githubusercontent.com/u/2?v=4", + }, + ] + + +@pytest.fixture +def sample_json_file(tmp_path: Path) -> Path: + """Create a sample JSON file for testing. + + Args: + tmp_path (Path): Pytest temporary path fixture + + Returns: + Path: Path to the created JSON file + """ + file_path = tmp_path / "sample.json" + + data = { + "login": "mojombo", + "id": 1, + "avatar_url": "https://avatars0.githubusercontent.com/u/1?v=4", + } + + with open(file_path, "w") as f: + json.dump(data, f) + + return file_path diff --git a/tests/test_dict2xml.py b/tests/test_dict2xml.py index 88e472e..aac5a7d 100644 --- a/tests/test_dict2xml.py +++ b/tests/test_dict2xml.py @@ -388,7 +388,7 @@ def test_with_custom_attributes(self): def test_valid_key(self): xml = dicttoxml.convert_bool('valid_key', False, False) - assert xml == 'false' + assert xml == 'false' def test_convert_kv_with_cdata(self): result = dicttoxml.convert_kv("key", "value", attr_type=False, cdata=True) diff --git a/tox.ini b/tox.ini index ecb51f6..82af3dc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,12 +1,51 @@ [tox] envlist = py310, py311, py312, py313, pypy310, pypy311, py314-full +isolated_build = True +skip_missing_interpreters = True +parallel_show_output = True [testenv] +passenv = + CI + GITHUB_* + PYTHONPATH deps = + pytest>=8.0.0 + pytest-cov>=6.0.0 + pytest-xdist>=3.5.0 + ruff>=0.3.0 + mypy>=1.0.0 + types-setuptools + +allowlist_externals = pytest - pytest-cov + ruff + mypy -allowlist_externals = pytest +commands = + pytest --cov=json2xml --cov-report=xml:coverage/reports/coverage.xml --cov-report=term -xvs {posargs:tests} -n auto +[testenv:lint] +deps = + ruff>=0.3.0 +commands = + ruff check json2xml tests + +[testenv:typecheck] +deps = + mypy>=1.0.0 + types-setuptools commands = - pytest --cov --cov-report=xml + mypy json2xml tests + +[testenv:py314-full] +deps = + {[testenv]deps} +commands = + {[testenv]commands} + ruff check json2xml tests + mypy json2xml tests + +[pytest] +testpaths = tests +python_files = test_*.py