Skip to content

Instantly share code, notes, and snippets.

@jangia
Created April 10, 2024 05:41
Show Gist options
  • Save jangia/9fa5a0c1e67b0acc93260820e2336c06 to your computer and use it in GitHub Desktop.
Save jangia/9fa5a0c1e67b0acc93260820e2336c06 to your computer and use it in GitHub Desktop.
Test behavior, not implementation details - part 3
from dataclasses import dataclass
from enum import Enum
class TaskStatus(str, Enum):
OPEN = "OPEN"
CLOSED = "CLOSED"
@dataclass
class Task:
title: str
status: TaskStatus
owner: str
import sqlite3
from abc import ABC
from models import Task, TaskStatus
class TaskStore(ABC):
def add_task(self, task: Task) -> None:
raise NotImplementedError
def list_open(self, owner: str) -> list[Task]:
raise NotImplementedError
class TaskStoreSQLite(TaskStore):
def __init__(self, connection: sqlite3.Connection):
self._connection = connection
def add_task(self, task: Task) -> None:
self._connection.execute(
"INSERT INTO tasks (title, status, owner) VALUES (?, ?, ?)",
(task.title, task.status.name, task.owner),
)
def list_open(self, owner: str) -> list[Task]:
cursor = self._connection.execute(
"SELECT title, status, owner FROM tasks WHERE status = 'OPEN' AND owner = ?",
(owner,),
)
return [
Task(title, TaskStatus(status), owner)
for title, status, owner in cursor.fetchall()
]
class TaskStoreInMemory(TaskStore):
def __init__(self):
self._tasks = []
def add_task(self, task: Task) -> None:
self._tasks.append(task)
def list_open(self, owner: str) -> list[Task]:
return [
task
for task in self._tasks
if task.status == TaskStatus.OPEN and task.owner == owner
]
import sqlite3
import pytest
from models import Task, TaskStatus
from store import TaskStoreSQLite, TaskStore, TaskStoreInMemory
class TaskStoreContract:
@pytest.fixture
def store(self) -> TaskStore:
raise NotImplementedError
def test_added_task_listed(self, store: TaskStore):
task = Task(title="Do the dishes", status=TaskStatus.OPEN, owner="johndoe")
store.add_task(task)
assert store.list_open(owner=task.owner) == [task]
def test_closed_task_not_listed_in_open_tasks(self, store: TaskStore):
task = Task(title="Do the dishes", status=TaskStatus.CLOSED, owner="johndoe")
store.add_task(task)
assert store.list_open(owner=task.owner) == []
def test_task_from_other_owner_not_listed_in_open_tasks(self, store: TaskStore):
task = Task(title="Do the dishes", status=TaskStatus.OPEN, owner="johndoe")
store.add_task(task)
assert store.list_open(owner="anotherowner") == []
class TestTaskStoreSQLite(TaskStoreContract):
@pytest.fixture
def connection(self, tmp_path) -> sqlite3.Connection:
connection = sqlite3.connect(tmp_path / "test.db")
connection.execute("CREATE TABLE tasks (title TEXT, status TEXT, owner TEXT)")
return connection
@pytest.fixture
def store(self, connection) -> TaskStore:
return TaskStoreSQLite(connection)
class TestTaskStoreInMemory(TaskStoreContract):
@pytest.fixture
def store(self) -> TaskStore:
return TaskStoreInMemory()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment