Skip to content

Commit

Permalink
Merge pull request #6 from dan1elt0m/add-cov
Browse files Browse the repository at this point in the history
Add cov report
  • Loading branch information
dan1elt0m authored Aug 2, 2024
2 parents c5725ba + 8c500ae commit b5c0297
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 23 deletions.
14 changes: 4 additions & 10 deletions .github/workflows/pr.yaml → .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: pr
name: test
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
types: [opened, reopened, synchronize]
jobs:
test:
Expand All @@ -13,15 +16,6 @@ jobs:
- uses: eifinger/setup-rye@v3
- run: rye pin ${{ matrix.py }} # pin Python version
- run: rye sync
# - run: |
# diff=$(git diff requirements.lock)
# if [[ -n $diff ]]; then
# echo "requirements.lock file has changed:"
# echo "$diff"
# exit 1
# else
# echo "requirements.lock file has not changed"
# fi
- run: rye fmt --check # check formatting is correct
- run: rye lint # and linting
- run: rye run check # typecheck too
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ dist/
wheels/
*.egg-info
.pytest_cache
.coverage
coverage.xml
junit/

# venv
.venv
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ from sqlmodel import Field, create_engine, select, or_
from sqlmodel.ext.asyncio.session import AsyncSession

class Hero(Sadel, table=True):
__tablename__ = "hero" # type: ignore
__tablename__ = "hero"
_upsert_index_elements = {"id"}

id: int | None = Field(default=None, primary_key=True)
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ dev-dependencies = [
"pytest-asyncio~=0.23.8",
"aiosqlite~=0.20.0",
"greenlet~=3.0.3",
"pytest-cov~=5.0.0",
]

[tool.rye.scripts]
fmt = "rye fmt"
lint = "rye lint --fix"
check = "pyright"
test = "rye test"
test = "rye test -- --cov sadel --cov-report term-missing --cov-report xml:coverage.xml --junitxml=junit/report.xml"
all = { chain = ["fmt", "lint", "check", "test"] }


Expand Down
4 changes: 4 additions & 0 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
aiosqlite==0.20.0
annotated-types==0.7.0
# via pydantic
coverage==7.6.0
# via pytest-cov
greenlet==3.0.3
iniconfig==2.0.0
# via pytest
Expand All @@ -28,7 +30,9 @@ pydantic-core==2.20.1
pyright==1.1.374
pytest==8.3.2
# via pytest-asyncio
# via pytest-cov
pytest-asyncio==0.23.8
pytest-cov==5.0.0
setuptools==72.1.0
sqlalchemy==2.0.31
# via sqlmodel
Expand Down
11 changes: 1 addition & 10 deletions sadel/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@

import sqlalchemy as sa
from pydantic import ConfigDict
from pydantic.v1 import validate_model
from sqlalchemy.dialects.postgresql import Insert, insert
from sqlmodel import Field, SQLModel


class Sadel(SQLModel):
"""Base class for SQL models."""

model_config = ConfigDict(validate_assignment=True) # type: ignore
model_config = ConfigDict(validate_assignment=True) # pyright: ignore
created_on: datetime | None = Field(
default=None,
sa_type=sa.DateTime(timezone=True), # type: ignore
Expand All @@ -37,14 +36,6 @@ class Sadel(SQLModel):
),
)

def __init__(self, **data: Any) -> None:
super().__init__(**data)
# Workaround to validate the model on init, which is not supported by SQLModel
if hasattr(self, "__config__"):
_, _, validation_error = validate_model(self.__class__, data) # pyright: ignore
if validation_error:
raise validation_error

# Specifies the set of index elements which represent the ON CONFLICT target
_upsert_index_elements: ClassVar[set[str]] = set()

Expand Down
20 changes: 19 additions & 1 deletion tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


class Hero(Sadel, table=True):
__tablename__ = "hero" # type: ignore
__tablename__ = "hero"
_upsert_index_elements = {"id"}

id: Optional[int] = Field(default=None, primary_key=True)
Expand Down Expand Up @@ -90,3 +90,21 @@ async def test_modified_on_upsert(temp_db):
async def test_validate():
with pytest.raises(ValidationError, match="Input should be a valid integer"):
Hero(name="Deadpond", secret_name="Dive Wilson", age=datetime.now())


@pytest.mark.asyncio()
async def test_missing_upsert_identifier(temp_db):
class Woops(Sadel, table=True):
__tablename__ = "woops"

id: Optional[int] = Field(default=None, primary_key=True)
name: str
secret_name: str
age: Optional[int] = None

sqlite_url_async = f"sqlite+aiosqlite:///{temp_db}"
async_engine = create_async_engine(sqlite_url_async, echo=True, future=True)
loser_1 = Woops(id=1, name="Deadpond", secret_name="Dive Wilson")
with pytest.raises(ValueError, match="No upsert index elements specified for the model."):
async with AsyncSession(async_engine) as session:
await Woops.upsert(loser_1, session)

0 comments on commit b5c0297

Please sign in to comment.