CodeBench: combined-readme.md — todo + blog golden example 8b:lle
Molemmat esimerkit (single entity + FK relaatio) yhdessä tiedostossa. 1699 tokenia, 10.4% kontekstista. 8b näkee konkreettisen FK-patternen.
This commit is contained in:
204
kipina-codebench/golden-examples/combined-readme.md
Normal file
204
kipina-codebench/golden-examples/combined-readme.md
Normal file
@@ -0,0 +1,204 @@
|
||||
# Example 1: Todo App (single entity)
|
||||
|
||||
## models.py
|
||||
|
||||
```python
|
||||
"""Tietokantamallit — SQLAlchemy 2.0, Mapped-tyypitys, SQLite."""
|
||||
from datetime import date
|
||||
from sqlalchemy import String, Text, Date, create_engine
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, sessionmaker
|
||||
|
||||
DATABASE_URL = "sqlite:///./app.db"
|
||||
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
pass
|
||||
|
||||
class Todo(Base):
|
||||
__tablename__ = "todos"
|
||||
id: Mapped[int] = mapped_column(primary_key=True, index=True)
|
||||
title: Mapped[str] = mapped_column(String(255))
|
||||
description: Mapped[str | None] = mapped_column(Text, default=None)
|
||||
due_date: Mapped[date | None] = mapped_column(Date, default=None)
|
||||
priority: Mapped[int] = mapped_column(default=1)
|
||||
status: Mapped[str] = mapped_column(String(20), default="pending")
|
||||
|
||||
Base.metadata.create_all(bind=engine)
|
||||
```
|
||||
|
||||
## schemas.py
|
||||
|
||||
```python
|
||||
from datetime import date
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
class TodoCreate(BaseModel):
|
||||
title: str
|
||||
description: str | None = None
|
||||
due_date: date | None = None
|
||||
priority: int = 1
|
||||
status: str = "pending"
|
||||
|
||||
class TodoResponse(TodoCreate):
|
||||
id: int
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
```
|
||||
|
||||
## test_main.py — exactly 6 tests per entity
|
||||
|
||||
```python
|
||||
from fastapi.testclient import TestClient
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from main import app, get_db
|
||||
from models import Base
|
||||
|
||||
test_engine = create_engine("sqlite:///./test.db", connect_args={"check_same_thread": False})
|
||||
TestSession = sessionmaker(autocommit=False, autoflush=False, bind=test_engine)
|
||||
Base.metadata.create_all(bind=test_engine)
|
||||
|
||||
def override_get_db():
|
||||
db = TestSession()
|
||||
try: yield db
|
||||
finally: db.close()
|
||||
|
||||
app.dependency_overrides[get_db] = override_get_db
|
||||
client = TestClient(app)
|
||||
|
||||
def test_create_todo():
|
||||
response = client.post("/todos/", json={"title": "Osta maitoa", "priority": 2})
|
||||
assert response.status_code == 201
|
||||
assert "id" in response.json()
|
||||
|
||||
def test_list_todos():
|
||||
client.post("/todos/", json={"title": "Listattava"})
|
||||
response = client.get("/todos/")
|
||||
assert response.status_code == 200
|
||||
assert len(response.json()) >= 1
|
||||
|
||||
def test_get_todo_by_id():
|
||||
created = client.post("/todos/", json={"title": "Haettava"}).json()
|
||||
response = client.get(f"/todos/{created['id']}")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_get_todo_not_found():
|
||||
response = client.get("/todos/99999")
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_update_todo():
|
||||
created = client.post("/todos/", json={"title": "Vanha"}).json()
|
||||
response = client.put(f"/todos/{created['id']}", json={"title": "Uusi"})
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_delete_todo():
|
||||
created = client.post("/todos/", json={"title": "Poistettava"}).json()
|
||||
response = client.delete(f"/todos/{created['id']}")
|
||||
assert response.status_code == 204
|
||||
```
|
||||
|
||||
# Example 2: Blog (two entities with ForeignKey)
|
||||
|
||||
NOTE: ForeignKey is imported from sqlalchemy, NOT from sqlalchemy.orm!
|
||||
|
||||
## models.py
|
||||
|
||||
```python
|
||||
from datetime import datetime
|
||||
from sqlalchemy import String, Text, DateTime, ForeignKey, create_engine
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, sessionmaker
|
||||
|
||||
DATABASE_URL = "sqlite:///./app.db"
|
||||
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
pass
|
||||
|
||||
class Author(Base):
|
||||
__tablename__ = "authors"
|
||||
id: Mapped[int] = mapped_column(primary_key=True, index=True)
|
||||
name: Mapped[str] = mapped_column(String(255))
|
||||
email: Mapped[str] = mapped_column(String(255), unique=True)
|
||||
bio: Mapped[str | None] = mapped_column(Text, default=None)
|
||||
posts: Mapped[list["Post"]] = relationship(back_populates="author")
|
||||
|
||||
class Post(Base):
|
||||
__tablename__ = "posts"
|
||||
id: Mapped[int] = mapped_column(primary_key=True, index=True)
|
||||
title: Mapped[str] = mapped_column(String(255))
|
||||
content: Mapped[str] = mapped_column(Text)
|
||||
author_id: Mapped[int] = mapped_column(ForeignKey("authors.id"))
|
||||
published_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
|
||||
status: Mapped[str] = mapped_column(String(20), default="draft")
|
||||
author: Mapped["Author"] = relationship(back_populates="posts")
|
||||
|
||||
Base.metadata.create_all(bind=engine)
|
||||
```
|
||||
|
||||
## schemas.py
|
||||
|
||||
```python
|
||||
from datetime import datetime
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
class AuthorCreate(BaseModel):
|
||||
name: str
|
||||
email: str
|
||||
bio: str | None = None
|
||||
|
||||
class AuthorResponse(AuthorCreate):
|
||||
id: int
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class PostCreate(BaseModel):
|
||||
title: str
|
||||
content: str
|
||||
author_id: int
|
||||
published_at: datetime | None = None
|
||||
status: str = "draft"
|
||||
|
||||
class PostResponse(PostCreate):
|
||||
id: int
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
```
|
||||
|
||||
## test_main.py — 6 tests per entity, create parent FIRST for child tests
|
||||
|
||||
```python
|
||||
client = TestClient(app) # same setup as above
|
||||
|
||||
def _create_author(name="Kirjailija", email=None):
|
||||
if email is None:
|
||||
email = f"{name.lower().replace(' ', '.')}@example.com"
|
||||
return client.post("/authors/", json={"name": name, "email": email}).json()
|
||||
|
||||
def test_create_author():
|
||||
response = client.post("/authors/", json={"name": "Aleksis Kivi", "email": "aleksis@example.com"})
|
||||
assert response.status_code == 201
|
||||
|
||||
def test_list_authors():
|
||||
_create_author("Minna Canth", "minna@example.com")
|
||||
response = client.get("/authors/")
|
||||
assert response.status_code == 200
|
||||
assert len(response.json()) >= 1
|
||||
|
||||
# ... (same pattern: get_by_id, not_found, update, delete)
|
||||
|
||||
def test_create_post():
|
||||
author = _create_author("Tove Jansson", "tove@example.com")
|
||||
response = client.post("/posts/", json={"title": "Artikkeli", "content": "Sisältö", "author_id": author["id"]})
|
||||
assert response.status_code == 201
|
||||
|
||||
def test_update_post():
|
||||
author = _create_author("Joel Lehtonen", "joel@example.com")
|
||||
created = client.post("/posts/", json={"title": "Vanha", "content": "Teksti", "author_id": author["id"]}).json()
|
||||
response = client.put(f"/posts/{created['id']}", json={"title": "Uusi", "content": "Muokattu", "author_id": author["id"]})
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_delete_post():
|
||||
author = _create_author("Aino Kallas", "aino@example.com")
|
||||
created = client.post("/posts/", json={"title": "Poistettava", "content": "Poistetaan", "author_id": author["id"]}).json()
|
||||
response = client.delete(f"/posts/{created['id']}")
|
||||
assert response.status_code == 204
|
||||
```
|
||||
Reference in New Issue
Block a user