diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8df5387 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,24 @@ +name: Semantic Release + +on: + push: + branches: + - master + +jobs: + release: + runs-on: ubuntu-latest + concurrency: release + permissions: + id-token: write + contents: write + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Python Semantic Release + uses: python-semantic-release/python-semantic-release@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..f4a1546 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,56 @@ +on: + push: + branches: + - "**" + tags-ignore: + - "*.*.*" + +name: tests + +concurrency: + group: tests + +env: + poetry-version: 1.4.0 + python-version: 3.11.2 + +jobs: + poetry: + name: Prepare Poetry Environment + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + name: Checkout + + - uses: actions/setup-python@v4 + name: Setup Python + with: + python-version: ${{ env.python-version }} + + - uses: abatilo/actions-poetry@v3 + name: Install Poetry + with: + poetry-version: ${{ env.poetry-version }} + + - name: Update Poetry cache location + run: poetry config virtualenvs.in-project true + + - id: venv_cache + uses: actions/cache@v3 + name: Cache or Restore venv + with: + path: .venv + key: venv-${{ env.python-version }}-${{ env.poetry-version }}-lock-${{ hashFiles('poetry.lock') }} + + - name: Install Poetry Dependencies + run: poetry install + if: steps.venv_cache.outputs.cache-hit != 'true' + + - name: Run ruff + run: poetry run ruff check . + + - name: Run ruff format + run: poetry run ruff format --check . + + - name: Run tests + run: poetry run pytest diff --git a/tests/test_formatter.py b/tests/test_formatter.py index 973704d..1e42fc1 100644 --- a/tests/test_formatter.py +++ b/tests/test_formatter.py @@ -1,6 +1,9 @@ +import json import logging +from dataclasses import dataclass from decimal import Decimal from functools import lru_cache +from typing import Any import pytest @@ -8,48 +11,52 @@ from remote_log_formatter import setup_logging as _setup -@pytest.fixture() -@lru_cache() -def setup_logging() -> None: - _setup() - - @lru_cache() @pytest.fixture() -def logger(setup_logging: None) -> None: +def logger_json(setup_logging: None) -> None: + _setup() return _logger() -def test_logging_string( - logger: logging.Logger, caplog: pytest.LogCaptureFixture -) -> None: - logger.info("foo") - assert [r.message for r in caplog.records] == ["foo"] - - -def test_logging_number( - logger: logging.Logger, caplog: pytest.LogCaptureFixture -) -> None: - logger.info(42) - assert [r.message for r in caplog.records] == ["42"] - - -def test_logging_decimal( - logger: logging.Logger, caplog: pytest.LogCaptureFixture -) -> None: - logger.info(Decimal(17)) - assert [r.message for r in caplog.records] == ["17"] +@dataclass(frozen=True) +class Foo: + bar: str -def test_logging_dataclass( - logger: logging.Logger, caplog: pytest.LogCaptureFixture +@lru_cache() +@pytest.mark.parametrize( + "message,expected", + [ + pytest.param("foo", "foo", id="str"), + pytest.param(42, 42, id="integer"), + pytest.param(Decimal(42), "42", id="decimal"), + pytest.param(42.0, 42.0, id="float"), + pytest.param(Foo(bar=42), "Foo(bar=42)", id="dataclass"), + ], +) +def test_logger( + logger_json: logging.Logger, + caplog: pytest.LogCaptureFixture, + message: Any, + expected: str, ) -> None: - from dataclasses import dataclass - - @dataclass - class Foo: - bar: str - - o = Foo(15) - logger.info(o) - assert [r.message for r in caplog.records] == [str(o)] + logger_json.info(message) + assert caplog.records + r = caplog.records[0] + + data = json.loads(logger_json.handlers[0].format(r)) + assert data == { + "datetime": data["datetime"], + "level": "INFO", + "message": expected, + "channel": "remote", + "pid": data["pid"], + "context": { + "processname": "MainProcess", + "pathname": data["context"]["pathname"], + "module": "test_formatter", + "function": "test_logger", + "lineno": 48, + }, + "extra": {"type": "log"}, + }