create-caspian-app 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,76 @@
1
- """Unit tests for the pure helper functions in `main.py`.
1
+ """Unit tests for focused helper and lifecycle functions in `main.py`.
2
2
 
3
3
  These cover the app-owned logic that has no external dependencies: env
4
4
  parsing, query-param coercion, and the component-deferral HTML transform.
5
5
  """
6
6
 
7
7
  import inspect
8
+ import io
9
+ from dataclasses import replace
10
+ from types import SimpleNamespace
8
11
  from typing import Optional
12
+ from unittest.mock import AsyncMock
9
13
 
10
14
  import main
15
+ from conftest import run_async
16
+
17
+
18
+ class TestPrismaLifespan:
19
+ def test_disconnects_on_shutdown(self, monkeypatch):
20
+ disconnect = AsyncMock()
21
+ monkeypatch.setattr(main.prisma, "disconnect", disconnect)
22
+
23
+ async def exercise_lifespan():
24
+ async with main.prisma_lifespan(main.app):
25
+ disconnect.assert_not_awaited()
26
+
27
+ run_async(exercise_lifespan())
28
+ disconnect.assert_awaited_once_with()
29
+
30
+ def test_disabled_prisma_is_not_registered(self, monkeypatch):
31
+ monkeypatch.setattr(main, "cfg", replace(main.cfg, prisma=False))
32
+
33
+ assert main.prisma_lifespan not in main.get_app_lifespans()
34
+
35
+ def test_disconnects_when_another_lifespan_raises(self, monkeypatch):
36
+ disconnect = AsyncMock()
37
+ monkeypatch.setattr(main.prisma, "disconnect", disconnect)
38
+
39
+ async def exercise_lifespan():
40
+ try:
41
+ async with main.prisma_lifespan(main.app):
42
+ raise RuntimeError("shutdown path")
43
+ except RuntimeError:
44
+ pass
45
+
46
+ run_async(exercise_lifespan())
47
+ disconnect.assert_awaited_once_with()
48
+
49
+
50
+ class TestDevControlPipe:
51
+ def test_valid_shutdown_command_stops_server(self):
52
+ server = SimpleNamespace(should_exit=False)
53
+
54
+ main._consume_dev_control_stream(
55
+ server,
56
+ "expected-token",
57
+ io.StringIO("shutdown:expected-token\n"),
58
+ )
59
+
60
+ assert server.should_exit is True
61
+
62
+ def test_ignores_invalid_commands_until_pipe_closes(self):
63
+ server = SimpleNamespace(should_exit=False)
64
+
65
+ main._consume_dev_control_stream(
66
+ server,
67
+ "expected-token",
68
+ io.StringIO("shutdown:wrong-token\nnoop:expected-token\n"),
69
+ )
70
+
71
+ # EOF means the owning development orchestrator exited, so an otherwise
72
+ # orphaned child still shuts down cleanly.
73
+ assert server.should_exit is True
11
74
 
12
75
 
13
76
  class TestEnvParsing:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-caspian-app",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "Scaffold a new Caspian project (FastAPI-powered reactive Python framework).",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",