Compare commits
107 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
238a8d6258
|
|||
|
ecd75ba61f
|
|||
|
45762726c0
|
|||
|
bac13a3dee
|
|||
|
bffcbfc5fe
|
|||
|
cd6d6d03d2
|
|||
|
7c65a6460b
|
|||
|
e9adb38be0
|
|||
|
4654ff7637
|
|||
|
76adf01e1b
|
|||
|
4032d528af
|
|||
|
385ff2711e
|
|||
|
5f223b3ce2
|
|||
|
0c43a4a95d
|
|||
|
fe59de3392
|
|||
|
06d99a7f04
|
|||
|
878bcb78c0
|
|||
|
4a4a4745dd
|
|||
|
afc8a4b0d7
|
|||
|
bc8912d934
|
|||
|
d917c4d125
|
|||
|
edfa3d456c
|
|||
|
af0ba5c13e
|
|||
|
beb5ac331a
|
|||
|
67c8932c14
|
|||
|
31c74f177b
|
|||
|
03db344fb2
|
|||
|
eb21fc7435
|
|||
|
99741d481b
|
|||
|
7d40d61c50
|
|||
|
1851072d80
|
|||
|
68e5e95dda
|
|||
|
21227628fa
|
|||
|
e5ebe7b188
|
|||
|
f6d4bc3a03
|
|||
|
b1fc2f4e99
|
|||
|
f2e4149e52
|
|||
|
7fd9e2a632
|
|||
|
2360727e11
|
|||
|
b4e23cc641
|
|||
|
9f412516b7
|
|||
|
6bed0a6787
|
|||
|
89b5dd1457
|
|||
|
50f5be841e
|
|||
|
2f18d3f215
|
|||
|
d6e9a689e3
|
|||
|
d712b2de02
|
|||
|
65a8d525f5
|
|||
|
9e6c6d256f
|
|||
|
85fea3a4bb
|
|||
|
d2b74b6863
|
|||
|
c580bda6ed
|
|||
|
36163bda10
|
|||
|
28cca84f46
|
|||
|
bdccf50362
|
|||
|
276318cbd4
|
|||
|
33e9e281d0
|
|||
|
c0cef0c2d3
|
|||
|
64e5f8b3b6
|
|||
|
35f4cf43cc
|
|||
|
a16e316f2f
|
|||
|
041a877295
|
|||
|
ddceeec07e
|
|||
|
5dbe52df0d
|
|||
|
798e0ba1df
|
|||
|
e028167a47
|
|||
|
2123791ec3
|
|||
|
f757e28b24
|
|||
|
e8898841cf
|
|||
|
1e4aafaff2
|
|||
|
815ed3161e
|
|||
|
00923e273b
|
|||
|
7d789ba82f
|
|||
|
f74f1d89b6
|
|||
|
82f80b929f
|
|||
|
7490304f62
|
|||
|
6fab0674dd
|
|||
|
e11f9a5ded
|
|||
|
2ed47746c6
|
|||
|
1851362e8e
|
|||
|
48ab814ffc
|
|||
|
cdeb13fca9
|
|||
|
6537a978c3
|
|||
|
0ae8356341
|
|||
|
4ccf2af346
|
|||
|
503f0de241
|
|||
|
70dbc30262
|
|||
|
c58b0b60aa
|
|||
|
be754e41a4
|
|||
|
011c3ee6d4
|
|||
|
88121dfdeb
|
|||
|
d15dafe7ba
|
|||
|
9fb2d24833
|
|||
|
2aee8e73cb
|
|||
|
203f22194b
|
|||
|
d710cd34a7
|
|||
|
dae4efcd08
|
|||
|
a49d8e5c02
|
|||
|
999296006c
|
|||
|
cccdad8768
|
|||
|
3ed51bce74
|
|||
|
eca1503be5
|
|||
|
3f357764bd
|
|||
|
0b0efb71eb
|
|||
|
bb91be6848
|
|||
|
9006fbabe2
|
|||
|
1fe19f38b6
|
@@ -177,3 +177,92 @@ async def test_get_stats(client: AsyncClient, db_session: AsyncSession) -> None:
|
||||
assert data["by_difficulty"]["easy"] == 1
|
||||
assert len(data["by_category"]) == 1
|
||||
assert len(data["by_pattern"]) == 1
|
||||
|
||||
|
||||
async def test_get_pattern_tutorial(client: AsyncClient, db_session: AsyncSession) -> None:
|
||||
await create_sample_data(db_session)
|
||||
response = await client.get("/api/patterns/two-pointers/tutorial")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["name"] == "Two Pointers"
|
||||
assert data["learning_progression"]["warmup"][0]["title"] == "Two Sum"
|
||||
assert len(data["learning_progression"]["core"]) == 0
|
||||
|
||||
|
||||
async def test_get_pattern_tutorial_not_found(client: AsyncClient) -> None:
|
||||
response = await client.get("/api/patterns/nonexistent/tutorial")
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
async def test_submit_passing(client: AsyncClient, db_session: AsyncSession) -> None:
|
||||
data = await create_sample_data(db_session)
|
||||
q = data["question"]
|
||||
q.test_cases = {
|
||||
"visible": [{"input": {"nums": [2, 7], "target": 9}, "expected": [0, 1]}],
|
||||
"hidden": [{"input": {"nums": [3, 2, 4], "target": 6}, "expected": [1, 2]}],
|
||||
}
|
||||
await db_session.commit()
|
||||
|
||||
response = await client.post(
|
||||
"/api/questions/two-sum/submit",
|
||||
json={
|
||||
"code": "def solve(nums, t): pass",
|
||||
"hidden_outputs": [{"test_id": 1, "output": [1, 2]}],
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
result = response.json()
|
||||
assert result["passed"] is True
|
||||
assert result["total_passed"] == 1
|
||||
|
||||
|
||||
async def test_submit_wrong_output(client: AsyncClient, db_session: AsyncSession) -> None:
|
||||
data = await create_sample_data(db_session)
|
||||
data["question"].test_cases = {
|
||||
"visible": [],
|
||||
"hidden": [{"input": {"nums": [1, 2], "target": 3}, "expected": [0, 1]}],
|
||||
}
|
||||
await db_session.commit()
|
||||
|
||||
response = await client.post(
|
||||
"/api/questions/two-sum/submit",
|
||||
json={
|
||||
"code": "def solve(nums, t): pass",
|
||||
"hidden_outputs": [{"test_id": 0, "output": [9, 9]}],
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["passed"] is False
|
||||
|
||||
|
||||
async def test_submit_missing_output(client: AsyncClient, db_session: AsyncSession) -> None:
|
||||
data = await create_sample_data(db_session)
|
||||
data["question"].test_cases = {
|
||||
"visible": [],
|
||||
"hidden": [{"input": {"nums": [1, 2], "target": 3}, "expected": [0, 1]}],
|
||||
}
|
||||
await db_session.commit()
|
||||
|
||||
response = await client.post(
|
||||
"/api/questions/two-sum/submit",
|
||||
json={"code": "def solve(nums, t): pass", "hidden_outputs": []},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["hidden_results"][0]["error"] == "No output provided"
|
||||
|
||||
|
||||
async def test_submit_no_test_cases(client: AsyncClient, db_session: AsyncSession) -> None:
|
||||
await create_sample_data(db_session)
|
||||
response = await client.post(
|
||||
"/api/questions/two-sum/submit",
|
||||
json={"code": "pass", "hidden_outputs": []},
|
||||
)
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
async def test_submit_not_found(client: AsyncClient) -> None:
|
||||
response = await client.post(
|
||||
"/api/questions/nonexistent/submit",
|
||||
json={"code": "pass", "hidden_outputs": []},
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
@@ -215,6 +215,55 @@ class TestPatternService:
|
||||
|
||||
assert result is None
|
||||
|
||||
async def test_get_tutorial(self, db_session: AsyncSession) -> None:
|
||||
related = Pattern(name="BFS", slug="bfs", description="Breadth-first search")
|
||||
pattern = Pattern(
|
||||
name="Two Pointers",
|
||||
slug="two-pointers",
|
||||
description="Two pointer technique",
|
||||
common_mistakes=[
|
||||
{"title": "Off by one", "description": "Wrong bounds", "fix": "Use <="}
|
||||
],
|
||||
variations=[{"name": "Fast/slow", "description": "Different speeds"}],
|
||||
related_patterns=["bfs"],
|
||||
visualization_examples=[{"id": "ex1", "title": "Basic", "code": "x=1", "steps": []}],
|
||||
)
|
||||
db_session.add_all([related, pattern])
|
||||
await db_session.flush()
|
||||
|
||||
q1 = Question(
|
||||
title="Easy Q", slug="easy-q", difficulty=Difficulty.EASY, description="Easy."
|
||||
)
|
||||
q2 = Question(title="Med Q", slug="med-q", difficulty=Difficulty.MEDIUM, description="Med.")
|
||||
q3 = Question(
|
||||
title="Hard Q", slug="hard-q", difficulty=Difficulty.HARD, description="Hard."
|
||||
)
|
||||
q1.patterns = [pattern]
|
||||
q2.patterns = [pattern]
|
||||
q3.patterns = [pattern]
|
||||
db_session.add_all([q1, q2, q3])
|
||||
await db_session.commit()
|
||||
|
||||
service = PatternService(db_session)
|
||||
result = await service.get_pattern_tutorial("two-pointers")
|
||||
|
||||
assert result is not None
|
||||
assert result.name == "Two Pointers"
|
||||
assert len(result.common_mistakes) == 1
|
||||
assert len(result.variations) == 1
|
||||
assert len(result.related_patterns) == 1
|
||||
assert result.related_patterns[0].slug == "bfs"
|
||||
assert len(result.learning_progression.warmup) == 1
|
||||
assert len(result.learning_progression.core) == 1
|
||||
assert len(result.learning_progression.challenge) == 1
|
||||
assert len(result.visualization_examples) == 1
|
||||
|
||||
async def test_get_tutorial_not_found(self, db_session: AsyncSession) -> None:
|
||||
service = PatternService(db_session)
|
||||
result = await service.get_pattern_tutorial("nonexistent")
|
||||
|
||||
assert result is None
|
||||
|
||||
|
||||
class TestStatsService:
|
||||
async def test_get_stats(self, db_session: AsyncSession) -> None:
|
||||
|
||||
Reference in New Issue
Block a user