From b6523d28b387f6d016b8f7a94eb1ad9764bc098d Mon Sep 17 00:00:00 2001 From: Sharoon Thomas Date: Tue, 7 May 2024 17:17:09 +0200 Subject: [PATCH] Add ci.yml and add tests for serialization [sc-74126] --- .github/workflows/ci.yml | 50 ++++++++++++ requirements_dev.txt | 1 + tests/test_serialization.py | 152 ++++++++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 tests/test_serialization.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b7f17f1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,50 @@ +name: CI (pip) +on: [push, pull_request] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: psf/black@stable + - uses: chartboost/ruff-action@v1 + build: + strategy: + matrix: + python-version: ["3.11"] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements_dev.txt + - name: Install from source (required for the pre-commit tests) + run: pip install . + - name: Test with pytest + run: pytest --cov=./ --cov-report=xml tests/test_serialization.py + release: + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Set up Python 3.11 + uses: actions/setup-python@v1 + with: + python-version: 3.11 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements_dev.txt + make dist + - name: Publish package + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@master + with: + user: __token__ + password: ${{ secrets.pypi_password }} diff --git a/requirements_dev.txt b/requirements_dev.txt index 837b7af..78f4562 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,3 +1,4 @@ pytest bumpversion mock +redis diff --git a/tests/test_serialization.py b/tests/test_serialization.py new file mode 100644 index 0000000..7b07fbd --- /dev/null +++ b/tests/test_serialization.py @@ -0,0 +1,152 @@ +# -*- coding: UTF-8 -*- +from datetime import datetime, date, time, timedelta +from decimal import Decimal +import json +from fulfil_client.serialization import ( + dumps, + loads, + JSONDecoder, + JSONEncoder, +) + +import pytest + +# name, python object, v2 serialization, v3 serialization +SPECIFICATION = { + "datetime": { + "python_object": datetime(2020, 1, 1, 10, 20, 30, 10), + "v1": { + "__class__": "datetime", + "year": 2020, + "month": 1, + "day": 1, + "hour": 10, + "minute": 20, + "second": 30, + "microsecond": 10, + }, + "v2": { + "__class__": "datetime", + "year": 2020, + "month": 1, + "day": 1, + "hour": 10, + "minute": 20, + "second": 30, + "microsecond": 10, + "iso_string": "2020-01-01T10:20:30.000010", + }, + "v3": { + "__class__": "datetime", + "iso_string": "2020-01-01T10:20:30.000010", + }, + }, + "date": { + "python_object": date(2020, 1, 1), + "v1": { + "__class__": "date", + "year": 2020, + "month": 1, + "day": 1, + }, + "v2": { + "__class__": "date", + "year": 2020, + "month": 1, + "day": 1, + "iso_string": "2020-01-01", + }, + "v3": { + "__class__": "date", + "iso_string": "2020-01-01", + }, + }, + "time": { + "python_object": time(10, 20, 30, 15), + "v1": { + "__class__": "time", + "hour": 10, + "minute": 20, + "second": 30, + "microsecond": 15, + }, + "v2": { + "__class__": "time", + "hour": 10, + "minute": 20, + "second": 30, + "microsecond": 15, + "iso_string": "10:20:30.000015", + }, + "v3": { + "__class__": "time", + "iso_string": "10:20:30.000015", + }, + }, + "timedelta": { + "python_object": timedelta(hours=25), + "v1": { + "__class__": "timedelta", + "seconds": 90000, + }, + "v2": { + "__class__": "timedelta", + "seconds": 90000, + "iso_string": "P1DT1H", + }, + "v3": { + "__class__": "timedelta", + "iso_string": "P1DT1H", + }, + }, + "decimal": { + "python_object": Decimal("101.123456789"), + "v1": { + "__class__": "Decimal", + "decimal": "101.123456789", + }, + "v2": { + "__class__": "Decimal", + "decimal": "101.123456789", + }, + "v3": { + "__class__": "Decimal", + "decimal": "101.123456789", + }, + }, +} + + +PARAMS = [] +V3_PARAMS = [] +for klass, spec in SPECIFICATION.items(): + PARAMS.extend( + [ + pytest.param(spec["python_object"], spec["v1"], id="{}.v1".format(klass)), + pytest.param(spec["python_object"], spec["v2"], id="{}.v2".format(klass)), + pytest.param(spec["python_object"], spec["v3"], id="{}.v3".format(klass)), + ] + ) + V3_PARAMS.append( + pytest.param(spec["python_object"], spec["v3"], id="{}.v3".format(klass)), + ) + + +@pytest.mark.parametrize("python_object,serialized_object", V3_PARAMS) +def test_serialization_v3(python_object, serialized_object): + """ + Test the serialization v3 works + """ + # Create a dict from the serialized representation of the fulfil object + deserialized_hash = json.loads(dumps(python_object)) + for key, value in serialized_object.items(): + assert key in deserialized_hash + assert deserialized_hash[key] == value + + +@pytest.mark.parametrize("python_object,serialized_object", PARAMS) +def test_deserialization(python_object, serialized_object): + """ + Deserializing the object should return the python object + """ + assert python_object == loads(json.dumps(serialized_object))