Skip to content

Commit

Permalink
Merge pull request #15 from kurtmckee/expand-testing
Browse files Browse the repository at this point in the history
Expand testing
  • Loading branch information
Pevtrick authored Jul 30, 2024
2 parents 1ec9993 + 3d76eed commit 288f896
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 4 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ jobs:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand All @@ -38,7 +41,7 @@ jobs:
ruff check --output-format=github --select=E9,F63,F7,F82 .
# default set of ruff rules with GitHub Annotations
ruff check --output-format=github .
- name: Test with pytest
- name: Test with tox
run: |
pip install pytest
python -m pytest
pip install tox
tox run -e py${{ matrix.python-version }},coverage_report
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# CHANGELOG

**Unreleased**
- Support Python 3.12 and 3.13.

**v0.4.1**
- Compatibility with Python 3.6 (not officially supported)

Expand Down
32 changes: 32 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ license = { file = "LICENSE" }
classifiers = [
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
keywords = ["sqids", "encode", "generate", "ids", "hashids"]
requires-python = ">=3.6"
Expand All @@ -28,3 +31,32 @@ packages = ["sqids"]

[tool.setuptools.package-data]
sqids = ["py.typed"]

[tool.coverage.run]
relative_files = true
parallel = true
branch = true
source = [
"sqids",
"tests",
]

[tool.coverage.paths]
source = [
"sqids",
"*/site-packages",
]

[tool.coverage.report]
skip_covered = true
fail_under = 99

[tool.coverage.html]
directory = "htmlcov/"
skip_covered = false

[tool.pytest.ini_options]
addopts = "--color=yes"
filterwarnings = [
"error",
]
2 changes: 1 addition & 1 deletion sqids/sqids.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def __init__(
if len(set(alphabet)) != len(alphabet):
raise ValueError("Alphabet must contain unique characters")

if not isinstance(min_length, int):
if not isinstance(min_length, int) or isinstance(min_length, bool):
raise TypeError("Minimum length must be an int")

MIN_LENGTH_LIMIT = 255
Expand Down
11 changes: 11 additions & 0 deletions tests/test_minlength.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,14 @@ def test_out_of_range_invalid_min_length():

with pytest.raises(ValueError):
Sqids(min_length=256)


@pytest.mark.parametrize("min_length", ("bogus", {}, True))
def test_min_length_type(min_length):
"""Verify that non-integer min_length values are rejected.
`True` is a unique case; Python bools are subclasses of int.
"""

with pytest.raises(TypeError, match="must be an int"):
Sqids(min_length=min_length)
24 changes: 24 additions & 0 deletions tests/test_round_trip.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import sys

import sqids

from hypothesis import given, target, assume
import hypothesis.strategies as st


lists_of_integers = st.lists(elements=st.integers(min_value=0, max_value=sys.maxsize))
min_lengths = st.integers(min_value=1, max_value=100)
alphabets = st.text(
alphabet=st.characters(min_codepoint=0, max_codepoint=0x7f),
min_size=3,
)


@given(numbers=lists_of_integers, min_length=min_lengths, alphabet=alphabets)
def test_round_trip_encoding(numbers, min_length, alphabet):
# Encourage hypothesis to find ideal alphabets.
target(len(alphabet) / len(set(alphabet)))
assume(len(alphabet) == len(set(alphabet)))

sqid = sqids.Sqids(min_length=min_length, alphabet=alphabet, blocklist=[])
assert sqid.decode(sqid.encode(numbers)) == numbers
40 changes: 40 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[tox]
envlist =
coverage_erase
py{3.13, 3.12, 3.11, 3.10, 3.9, 3.8, 3.7, 3.6}
coverage_report

skip_missing_interpreters = True
isolated_build = True


[testenv]
depends =
py{3.13, 3.12, 3.11, 3.10, 3.9, 3.8, 3.7, 3.6}: coverage_erase
deps =
pytest
hypothesis
coverage[toml]
commands =
coverage run -m pytest


[testenv:coverage_erase]
skipsdist = true
skip_install = true
deps =
coverage[toml]
commands = coverage erase


[testenv:coverage_report]
depends =
py{3.13, 3.12, 3.11, 3.10, 3.9, 3.8, 3.7, 3.6}
skipsdist = true
skip_install = true
deps =
coverage[toml]
commands_pre =
coverage combine
coverage html --fail-under=0
commands = coverage report

0 comments on commit 288f896

Please sign in to comment.