@martinffx/atelier 2.0.0 → 3.0.0

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.
Files changed (81) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +94 -253
  3. package/package.json +1 -1
  4. package/skills/{spec-orchestrator → atelier-orchestrator}/SKILL.md +3 -3
  5. package/skills/atelier-setup/SKILL.md +80 -0
  6. package/skills/code-review/references/reviewers.md +3 -3
  7. package/skills/code-review/references/rq.md +6 -6
  8. package/skills/spec-brainstorm/SKILL.md +5 -5
  9. package/skills/spec-implement/SKILL.md +2 -3
  10. package/skills/spec-plan/SKILL.md +21 -29
  11. package/skills/spec-plan/references/plan_template.md +77 -0
  12. package/skills/python-architecture/SKILL.md +0 -148
  13. package/skills/python-architecture/references/data-modeling.md +0 -558
  14. package/skills/python-architecture/references/ddd.md +0 -569
  15. package/skills/python-architecture/references/functional-core.md +0 -337
  16. package/skills/python-build-tools/SKILL.md +0 -153
  17. package/skills/python-build-tools/references/basedpyright.md +0 -321
  18. package/skills/python-build-tools/references/ruff.md +0 -225
  19. package/skills/python-build-tools/references/uv.md +0 -257
  20. package/skills/python-fastapi/SKILL.md +0 -184
  21. package/skills/python-fastapi/references/api-design.md +0 -563
  22. package/skills/python-fastapi/references/dependencies.md +0 -479
  23. package/skills/python-fastapi/references/middleware.md +0 -475
  24. package/skills/python-fastapi/references/validation.md +0 -497
  25. package/skills/python-modern-python/SKILL.md +0 -201
  26. package/skills/python-modern-python/references/async.md +0 -76
  27. package/skills/python-modern-python/references/pattern-matching.md +0 -89
  28. package/skills/python-modern-python/references/typing.md +0 -96
  29. package/skills/python-monorepo/SKILL.md +0 -146
  30. package/skills/python-monorepo/references/docker.md +0 -515
  31. package/skills/python-monorepo/references/namespace-packages.md +0 -426
  32. package/skills/python-monorepo/references/workspace-config.md +0 -341
  33. package/skills/python-sqlalchemy/SKILL.md +0 -119
  34. package/skills/python-sqlalchemy/references/async.md +0 -51
  35. package/skills/python-sqlalchemy/references/models.md +0 -67
  36. package/skills/python-sqlalchemy/references/queries.md +0 -57
  37. package/skills/python-temporal/SKILL.md +0 -128
  38. package/skills/python-temporal/references/patterns.md +0 -87
  39. package/skills/python-temporal/references/testing.md +0 -54
  40. package/skills/python-testing/SKILL.md +0 -161
  41. package/skills/python-testing/references/boundaries.md +0 -449
  42. package/skills/python-testing/references/mocking.md +0 -449
  43. package/skills/python-testing/references/pytest.md +0 -524
  44. package/skills/typescript-api-design/SKILL.md +0 -396
  45. package/skills/typescript-api-design/references/error-responses.md +0 -469
  46. package/skills/typescript-build-tools/SKILL.md +0 -447
  47. package/skills/typescript-build-tools/references/biome.md +0 -436
  48. package/skills/typescript-build-tools/references/bun.md +0 -432
  49. package/skills/typescript-build-tools/references/turborepo.md +0 -426
  50. package/skills/typescript-build-tools/references/vitest.md +0 -518
  51. package/skills/typescript-drizzle-orm/SKILL.md +0 -398
  52. package/skills/typescript-drizzle-orm/references/cloudflare.md +0 -392
  53. package/skills/typescript-drizzle-orm/references/entity-pattern.md +0 -412
  54. package/skills/typescript-drizzle-orm/references/postgresql.md +0 -191
  55. package/skills/typescript-drizzle-orm/references/repository-pattern.md +0 -479
  56. package/skills/typescript-drizzle-orm/references/sqlite.md +0 -291
  57. package/skills/typescript-dynamodb-toolbox/SKILL.md +0 -370
  58. package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +0 -574
  59. package/skills/typescript-dynamodb-toolbox/references/error-handling.md +0 -495
  60. package/skills/typescript-dynamodb-toolbox/references/modeling.md +0 -332
  61. package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +0 -631
  62. package/skills/typescript-dynamodb-toolbox/references/testing.md +0 -718
  63. package/skills/typescript-dynamodb-toolbox/references/transactions.md +0 -423
  64. package/skills/typescript-effect-ts/SKILL.md +0 -341
  65. package/skills/typescript-effect-ts/references/core.md +0 -412
  66. package/skills/typescript-effect-ts/references/error-handling.md +0 -468
  67. package/skills/typescript-effect-ts/references/resources.md +0 -476
  68. package/skills/typescript-effect-ts/references/schema.md +0 -536
  69. package/skills/typescript-effect-ts/references/services.md +0 -461
  70. package/skills/typescript-fastify/SKILL.md +0 -405
  71. package/skills/typescript-fastify/references/plugins.md +0 -329
  72. package/skills/typescript-fastify/references/typeid.md +0 -315
  73. package/skills/typescript-functional-patterns/SKILL.md +0 -402
  74. package/skills/typescript-functional-patterns/references/adts.md +0 -497
  75. package/skills/typescript-functional-patterns/references/branded-types.md +0 -542
  76. package/skills/typescript-functional-patterns/references/migration-guide.md +0 -695
  77. package/skills/typescript-functional-patterns/references/option-result.md +0 -585
  78. package/skills/typescript-testing/SKILL.md +0 -353
  79. package/skills/typescript-testing/references/mocking.md +0 -675
  80. package/skills/typescript-testing/references/msw.md +0 -852
  81. package/skills/typescript-testing/references/snapshot-testing.md +0 -774
@@ -1,524 +0,0 @@
1
- # pytest Configuration and Patterns
2
-
3
- ## Configuration (pyproject.toml)
4
-
5
- ### Basic Setup
6
-
7
- ```toml
8
- [tool.pytest.ini_options]
9
- testpaths = ["tests"]
10
- python_files = ["test_*.py", "*_test.py"]
11
- python_classes = ["Test*"]
12
- python_functions = ["test_*"]
13
- addopts = [
14
- "-ra", # Show summary of all test outcomes
15
- "--strict-markers", # Fail on unknown markers
16
- "--strict-config", # Fail on invalid config
17
- "-v", # Verbose output
18
- ]
19
- ```
20
-
21
- ### With Coverage
22
-
23
- ```toml
24
- [tool.pytest.ini_options]
25
- testpaths = ["tests"]
26
- addopts = [
27
- "-ra",
28
- "--strict-markers",
29
- "--cov=src",
30
- "--cov-report=term-missing",
31
- "--cov-report=html",
32
- "--cov-fail-under=80",
33
- ]
34
- ```
35
-
36
- ### Markers
37
-
38
- ```toml
39
- [tool.pytest.ini_options]
40
- markers = [
41
- "unit: unit tests (no I/O)",
42
- "integration: integration tests (with I/O)",
43
- "slow: slow tests (takes >1s)",
44
- "db: database tests",
45
- ]
46
- ```
47
-
48
- ## Fixtures
49
-
50
- ### Database Session
51
-
52
- ```python
53
- import pytest
54
- from sqlalchemy import create_engine
55
- from sqlalchemy.orm import sessionmaker
56
-
57
- @pytest.fixture
58
- def test_db():
59
- """In-memory test database"""
60
- engine = create_engine("sqlite:///:memory:")
61
- Base.metadata.create_all(engine)
62
-
63
- SessionLocal = sessionmaker(bind=engine)
64
- db = SessionLocal()
65
-
66
- try:
67
- yield db
68
- finally:
69
- db.close()
70
- ```
71
-
72
- ### Application Client
73
-
74
- ```python
75
- import pytest
76
- from fastapi.testclient import TestClient
77
-
78
- @pytest.fixture
79
- def test_client():
80
- """FastAPI test client"""
81
- return TestClient(app)
82
- ```
83
-
84
- ### Auto-Use Fixtures for Setup/Teardown
85
-
86
- ```python
87
- @pytest.fixture(autouse=True)
88
- def reset_db(test_db):
89
- """Reset database before each test"""
90
- Base.metadata.drop_all(bind=test_db.bind)
91
- Base.metadata.create_all(bind=test_db.bind)
92
- ```
93
-
94
- ### Fixture Scope
95
-
96
- ```python
97
- @pytest.fixture(scope="function") # Default: per test
98
- def data():
99
- ...
100
-
101
- @pytest.fixture(scope="module") # Per test file
102
- def client():
103
- ...
104
-
105
- @pytest.fixture(scope="session") # For entire test run
106
- def config():
107
- ...
108
- ```
109
-
110
- ### Parametrized Fixtures
111
-
112
- ```python
113
- @pytest.fixture(params=[
114
- {"name": "Alice", "age": 25},
115
- {"name": "Bob", "age": 30},
116
- {"name": "Charlie", "age": 35},
117
- ])
118
- def user_data(request):
119
- """Fixture provides multiple inputs"""
120
- return request.param
121
-
122
- def test_user_creation(user_data):
123
- """Runs 3 times with different data"""
124
- user = User(**user_data)
125
- assert user.name is not None
126
- ```
127
-
128
- ### Fixture Dependencies
129
-
130
- ```python
131
- @pytest.fixture
132
- def test_db():
133
- """Database fixture"""
134
- engine = create_engine("sqlite:///:memory:")
135
- Base.metadata.create_all(engine)
136
- SessionLocal = sessionmaker(bind=engine)
137
- return SessionLocal()
138
-
139
- @pytest.fixture
140
- def user_repository(test_db):
141
- """Repository depends on database"""
142
- return UserRepository(test_db)
143
-
144
- def test_repository_save(user_repository):
145
- """Test uses repository (which uses database)"""
146
- user = User(id=1, name="Alice")
147
- user_repository.save(user)
148
- assert user_repository.get(1) is not None
149
- ```
150
-
151
- ## Running Tests
152
-
153
- ### Basic Commands
154
-
155
- ```bash
156
- # Run all tests
157
- pytest
158
-
159
- # Run specific file
160
- pytest tests/test_entities.py
161
-
162
- # Run specific test
163
- pytest tests/test_entities.py::test_user_creation
164
-
165
- # Run with pattern
166
- pytest tests/test_*.py
167
-
168
- # Verbose output
169
- pytest -v
170
-
171
- # Very verbose (shows parameters)
172
- pytest -vv
173
- ```
174
-
175
- ### Filtering Tests
176
-
177
- ```bash
178
- # Stop on first failure
179
- pytest -x
180
-
181
- # Stop after N failures
182
- pytest --maxfail=3
183
-
184
- # Show print statements
185
- pytest -s
186
-
187
- # Show local variables on failure
188
- pytest -l
189
-
190
- # Show durations of slowest tests
191
- pytest --durations=10
192
- ```
193
-
194
- ### Markers
195
-
196
- ```bash
197
- # Run only unit tests
198
- pytest -m unit
199
-
200
- # Skip slow tests
201
- pytest -m "not slow"
202
-
203
- # Run integration tests
204
- pytest -m integration
205
-
206
- # Run tests matching pattern
207
- pytest -m "unit or integration"
208
- ```
209
-
210
- ### Coverage
211
-
212
- ```bash
213
- # Generate coverage report
214
- pytest --cov=src
215
-
216
- # Show missing lines
217
- pytest --cov=src --cov-report=term-missing
218
-
219
- # Generate HTML report
220
- pytest --cov=src --cov-report=html
221
- # Open htmlcov/index.html in browser
222
-
223
- # Fail if below threshold
224
- pytest --cov=src --cov-fail-under=80
225
- ```
226
-
227
- ## Parametrize
228
-
229
- ### Multiple Inputs
230
-
231
- ```python
232
- @pytest.mark.parametrize("input,expected", [
233
- (1, 2),
234
- (2, 4),
235
- (3, 6),
236
- (4, 8),
237
- ])
238
- def test_double(input, expected):
239
- assert double(input) == expected
240
- ```
241
-
242
- ### Multiple Parameters
243
-
244
- ```python
245
- @pytest.mark.parametrize("x,y,expected", [
246
- (1, 2, 3),
247
- (2, 3, 5),
248
- (5, 5, 10),
249
- ])
250
- def test_add(x, y, expected):
251
- assert add(x, y) == expected
252
- ```
253
-
254
- ### Parametrize Multiple Test Values
255
-
256
- ```python
257
- @pytest.mark.parametrize("value", [
258
- "alice@example.com",
259
- "bob@example.com",
260
- "charlie@example.com",
261
- ])
262
- def test_valid_email(value):
263
- assert is_valid_email(value)
264
- ```
265
-
266
- ### Combining Parametrize
267
-
268
- ```python
269
- @pytest.mark.parametrize("user_type", ["admin", "user", "guest"])
270
- @pytest.mark.parametrize("resource", ["posts", "comments", "users"])
271
- def test_permissions(user_type, resource):
272
- """Tests all combinations (3×3 = 9 tests)"""
273
- has_access = check_access(user_type, resource)
274
- assert has_access is not None
275
- ```
276
-
277
- ## Markers
278
-
279
- ### Built-in Markers
280
-
281
- ```python
282
- @pytest.mark.skip
283
- def test_not_ready():
284
- """Skip this test"""
285
- ...
286
-
287
- @pytest.mark.skip(reason="Not implemented yet")
288
- def test_future():
289
- """Skip with reason"""
290
- ...
291
-
292
- @pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires 3.10+")
293
- def test_new_syntax():
294
- """Skip conditionally"""
295
- ...
296
-
297
- @pytest.mark.xfail
298
- def test_known_bug():
299
- """Mark as expected to fail"""
300
- ...
301
- ```
302
-
303
- ### Custom Markers
304
-
305
- ```python
306
- @pytest.mark.unit
307
- def test_entity():
308
- ...
309
-
310
- @pytest.mark.integration
311
- def test_with_database():
312
- ...
313
-
314
- @pytest.mark.slow
315
- def test_expensive_computation():
316
- ...
317
-
318
- @pytest.mark.db
319
- def test_with_db():
320
- ...
321
- ```
322
-
323
- ## Test Organization
324
-
325
- ### Structure by Layer
326
-
327
- ```
328
- tests/
329
- ├── unit/
330
- │ ├── test_entities.py # Entity tests
331
- │ ├── test_services.py # Service tests (mocked)
332
- │ └── test_value_objects.py # Value object tests
333
- ├── integration/
334
- │ ├── test_repositories.py # Repository tests (with DB)
335
- │ └── test_endpoints.py # Router tests (with client)
336
- └── fixtures.py # Shared fixtures
337
- ```
338
-
339
- ### conftest.py for Shared Fixtures
340
-
341
- ```python
342
- # tests/conftest.py
343
- import pytest
344
- from sqlalchemy import create_engine
345
- from sqlalchemy.orm import sessionmaker
346
- from fastapi.testclient import TestClient
347
-
348
- @pytest.fixture
349
- def test_db():
350
- """Shared database fixture"""
351
- engine = create_engine("sqlite:///:memory:")
352
- Base.metadata.create_all(engine)
353
- SessionLocal = sessionmaker(bind=engine)
354
- db = SessionLocal()
355
- try:
356
- yield db
357
- finally:
358
- db.close()
359
-
360
- @pytest.fixture
361
- def test_client():
362
- """Shared test client"""
363
- return TestClient(app)
364
-
365
- # tests/test_entities.py
366
- def test_product_creation(test_db):
367
- """Uses fixture from conftest.py"""
368
- ...
369
- ```
370
-
371
- ### Naming Conventions
372
-
373
- ```python
374
- # File names
375
- test_entities.py # Tests for entities module
376
- test_create_product.py # Tests for specific feature
377
-
378
- # Test class (optional grouping)
379
- class TestProduct:
380
- def test_creation(self):
381
- ...
382
-
383
- def test_validation(self):
384
- ...
385
-
386
- # Test function names
387
- def test_product_creation(): # What is tested
388
- def test_product_with_discount(): # Behavior variant
389
- def test_product_raises_on_invalid_price(): # Error case
390
- ```
391
-
392
- ## Assertions and Context
393
-
394
- ### assert with Message
395
-
396
- ```python
397
- def test_with_message():
398
- result = calculate()
399
- assert result == 42, f"Expected 42 but got {result}"
400
- ```
401
-
402
- ### pytest.raises
403
-
404
- ```python
405
- def test_raises_error():
406
- with pytest.raises(ValueError):
407
- invalid_operation()
408
-
409
- def test_raises_with_match():
410
- with pytest.raises(ValueError, match="Invalid price"):
411
- Product(price=-10)
412
-
413
- def test_raises_with_check():
414
- with pytest.raises(ValueError) as exc_info:
415
- invalid_operation()
416
- assert "specific message" in str(exc_info.value)
417
- ```
418
-
419
- ### pytest.approx for Floats
420
-
421
- ```python
422
- def test_float_calculation():
423
- result = expensive_calculation()
424
- # Avoid exact equality with floats
425
- assert result == pytest.approx(3.14159, abs=0.0001)
426
- ```
427
-
428
- ### Comparing Collections
429
-
430
- ```python
431
- def test_lists():
432
- result = get_items()
433
- assert result == [1, 2, 3]
434
- assert 2 in result
435
- assert len(result) == 3
436
-
437
- def test_dicts():
438
- result = get_data()
439
- assert result == {"name": "Alice", "age": 25}
440
- assert result["name"] == "Alice"
441
- assert "email" not in result
442
- ```
443
-
444
- ## Debugging Failed Tests
445
-
446
- ### Print Debugging
447
-
448
- ```bash
449
- # Show print statements
450
- pytest -s
451
-
452
- # Show print + traceback
453
- pytest -s -vv
454
-
455
- # Show local variables
456
- pytest -l
457
-
458
- # Full diff for collections
459
- pytest -vv --tb=short
460
- ```
461
-
462
- ### Using pdb
463
-
464
- ```python
465
- def test_with_debugger():
466
- result = complex_operation()
467
- # Drop into debugger on failure
468
- import pdb; pdb.set_trace()
469
- assert result == expected
470
- ```
471
-
472
- ### Test Reports
473
-
474
- ```bash
475
- # Generate JUnit XML (for CI)
476
- pytest --junit-xml=report.xml
477
-
478
- # Generate JSON report
479
- pytest --json-report --json-report-file=report.json
480
-
481
- # Generate HTML report
482
- pytest --html=report.html
483
- ```
484
-
485
- ## Performance Optimization
486
-
487
- ### Profile Test Execution
488
-
489
- ```bash
490
- # Show slowest tests
491
- pytest --durations=10
492
-
493
- # Show all tests sorted by duration
494
- pytest --durations=0
495
- ```
496
-
497
- ### Parallelize Tests
498
-
499
- ```bash
500
- # Install pytest-xdist
501
- pip install pytest-xdist
502
-
503
- # Run tests in parallel (use N workers)
504
- pytest -n auto
505
- pytest -n 4
506
- ```
507
-
508
- ### Fixture Optimization
509
-
510
- ```python
511
- # SLOW: Creates database for every test
512
- @pytest.fixture(scope="function")
513
- def test_db():
514
- engine = create_engine("sqlite:///:memory:")
515
- Base.metadata.create_all(engine)
516
- ...
517
-
518
- # FAST: Creates once per session (if tests don't modify schema)
519
- @pytest.fixture(scope="session")
520
- def test_db():
521
- engine = create_engine("sqlite:///:memory:")
522
- Base.metadata.create_all(engine)
523
- ...
524
- ```