quadkit-testing 0.0.3__tar.gz → 0.0.4__tar.gz

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 (284) hide show
  1. quadkit_testing-0.0.4/.gitignore +183 -0
  2. quadkit_testing-0.0.4/PKG-INFO +270 -0
  3. quadkit_testing-0.0.3/PKG-INFO → quadkit_testing-0.0.4/README.md +60 -64
  4. quadkit_testing-0.0.4/docs/ARCHITECTURE.md +571 -0
  5. quadkit_testing-0.0.4/docs/COMPLIANCE.md +123 -0
  6. quadkit_testing-0.0.4/docs/CONFIGURATION.md +52 -0
  7. quadkit_testing-0.0.4/docs/GUIDE.md +191 -0
  8. quadkit_testing-0.0.4/docs/HOWTOS.md +220 -0
  9. quadkit_testing-0.0.4/docs/QUICKSTART.md +66 -0
  10. quadkit_testing-0.0.4/docs/TROUBLESHOOTING.md +174 -0
  11. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/pyproject.toml +49 -24
  12. quadkit_testing-0.0.4/src/quadkit/testing/README.md +233 -0
  13. quadkit_testing-0.0.4/src/quadkit/testing/__init__.py +345 -0
  14. quadkit_testing-0.0.4/src/quadkit/testing/_lazy_exports.py +72 -0
  15. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/clients/ai/client.py +21 -11
  16. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/__init__.py +64 -0
  17. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/bed.py +115 -0
  18. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/client.py +22 -0
  19. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/fixtures/__init__.py +134 -0
  20. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/fixtures/_async.py +30 -0
  21. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/fixtures/beds.py +36 -0
  22. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/fixtures/mocks.py +82 -0
  23. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/fixtures/tokens.py +196 -0
  24. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/fixtures/users.py +239 -0
  25. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/test_client.py +157 -0
  26. quadkit_testing-0.0.4/src/quadkit/testing/clients/auth/types.py +141 -0
  27. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/__init__.py +101 -0
  28. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/bed.py +114 -0
  29. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/client.py +16 -0
  30. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/client_core.py +275 -0
  31. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/data.py +60 -0
  32. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/fixtures/__init__.py +143 -0
  33. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/fixtures/_async.py +30 -0
  34. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/fixtures/beds.py +57 -0
  35. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/fixtures/data.py +173 -0
  36. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/fixtures/lifecycle.py +219 -0
  37. quadkit_testing-0.0.4/src/quadkit/testing/clients/cache/fixtures/scenarios.py +65 -0
  38. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/__init__.py +111 -0
  39. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/client.py +26 -0
  40. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/components/__init__.py +17 -0
  41. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/components/command_client.py +159 -0
  42. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/components/event_client.py +225 -0
  43. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/components/query_client.py +159 -0
  44. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/components/test_bed.py +116 -0
  45. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/components/test_data.py +195 -0
  46. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/fixtures/__init__.py +262 -0
  47. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/fixtures/_async.py +34 -0
  48. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/fixtures/beds.py +121 -0
  49. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/fixtures/data.py +219 -0
  50. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/fixtures/handlers.py +169 -0
  51. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/fixtures/models.py +139 -0
  52. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/fixtures/scenarios.py +52 -0
  53. quadkit_testing-0.0.4/src/quadkit/testing/clients/events/py.typed +0 -0
  54. quadkit_testing-0.0.4/src/quadkit/testing/clients/search/__init__.py +40 -0
  55. quadkit_testing-0.0.4/src/quadkit/testing/clients/search/client.py +431 -0
  56. quadkit_testing-0.0.4/src/quadkit/testing/clients/search/fixtures.py +63 -0
  57. quadkit_testing-0.0.4/src/quadkit/testing/clients/search/py.typed +0 -0
  58. quadkit_testing-0.0.4/src/quadkit/testing/clients/storage/__init__.py +11 -0
  59. quadkit_testing-0.0.4/src/quadkit/testing/clients/storage/fixtures.py +81 -0
  60. quadkit_testing-0.0.4/src/quadkit/testing/clients/storage/mocks.py +41 -0
  61. quadkit_testing-0.0.4/src/quadkit/testing/clients/storage/py.typed +0 -0
  62. quadkit_testing-0.0.4/src/quadkit/testing/clients/tasks/__init__.py +23 -0
  63. quadkit_testing-0.0.4/src/quadkit/testing/clients/tasks/bed.py +122 -0
  64. quadkit_testing-0.0.4/src/quadkit/testing/clients/tasks/client.py +149 -0
  65. quadkit_testing-0.0.4/src/quadkit/testing/clients/tasks/data.py +88 -0
  66. quadkit_testing-0.0.4/src/quadkit/testing/clients/tasks/mocks.py +306 -0
  67. quadkit_testing-0.0.4/src/quadkit/testing/clients/tasks/py.typed +0 -0
  68. quadkit_testing-0.0.4/src/quadkit/testing/clients/ui/__init__.py +7 -0
  69. quadkit_testing-0.0.4/src/quadkit/testing/clients/ui/core.py +106 -0
  70. quadkit_testing-0.0.4/src/quadkit/testing/clients/web/__init__.py +45 -0
  71. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/clients/web/client.py +25 -6
  72. quadkit_testing-0.0.4/src/quadkit/testing/clients/web/py.typed +0 -0
  73. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/__init__.py +41 -32
  74. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/flags.py +5 -3
  75. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/__init__.py +29 -6
  76. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/redis.py +1 -1
  77. quadkit_testing-0.0.4/src/quadkit/testing/fakes/secrets.py +14 -0
  78. quadkit_testing-0.0.4/src/quadkit/testing/fixtures/__init__.py +170 -0
  79. quadkit_testing-0.0.4/src/quadkit/testing/fixtures/ai.py +190 -0
  80. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fixtures/core.py +6 -6
  81. quadkit_testing-0.0.4/src/quadkit/testing/fixtures/db.py +279 -0
  82. quadkit_testing-0.0.4/src/quadkit/testing/fixtures/py.typed +0 -0
  83. quadkit_testing-0.0.4/src/quadkit/testing/fixtures/tasks.py +57 -0
  84. quadkit_testing-0.0.4/src/quadkit/testing/harness/environment.py +249 -0
  85. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/harness/overrides.py +1 -1
  86. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/integration/__init__.py +31 -8
  87. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/lib/__init__.py +0 -6
  88. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/lib/admin_helpers.py +2 -2
  89. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/lib/assertions.py +0 -3
  90. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/lib/factory.py +0 -3
  91. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/cqrs.py +3 -3
  92. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/lock.py +13 -14
  93. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/outbox.py +1 -1
  94. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/repository.py +3 -3
  95. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/uow.py +1 -1
  96. quadkit_testing-0.0.4/src/quadkit/testing/plugins/pytest/__init__.py +31 -0
  97. quadkit_testing-0.0.3/src/quadkit/testing/plugins/pytest/__init__.py → quadkit_testing-0.0.4/src/quadkit/testing/plugins/pytest/plugin.py +1 -1
  98. quadkit_testing-0.0.4/src/quadkit/testing/py.typed +0 -0
  99. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/testkit/environment.py +10 -2
  100. quadkit_testing-0.0.4/tests/integration/test_ai_client.py +290 -0
  101. quadkit_testing-0.0.4/tests/integration/test_bed.py +380 -0
  102. quadkit_testing-0.0.4/tests/unit/_integration_helpers.py +88 -0
  103. quadkit_testing-0.0.4/tests/unit/conftest.py +12 -0
  104. quadkit_testing-0.0.4/tests/unit/test_cache_client_fixtures.py +234 -0
  105. quadkit_testing-0.0.4/tests/unit/test_cache_clients.py +313 -0
  106. quadkit_testing-0.0.4/tests/unit/test_command_query_test_clients.py +215 -0
  107. quadkit_testing-0.0.4/tests/unit/test_compliance_suites.py +354 -0
  108. quadkit_testing-0.0.4/tests/unit/test_db_transaction_fixture.py +211 -0
  109. quadkit_testing-0.0.4/tests/unit/test_event_test_client.py +210 -0
  110. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_factory.py +7 -5
  111. quadkit_testing-0.0.4/tests/unit/test_fakes_cluster.py +369 -0
  112. quadkit_testing-0.0.4/tests/unit/test_fakes_lifecycle.py +135 -0
  113. quadkit_testing-0.0.4/tests/unit/test_fakes_observability.py +136 -0
  114. quadkit_testing-0.0.4/tests/unit/test_fixture_modules.py +418 -0
  115. quadkit_testing-0.0.4/tests/unit/test_harness_container.py +172 -0
  116. quadkit_testing-0.0.4/tests/unit/test_harness_testkit.py +191 -0
  117. quadkit_testing-0.0.4/tests/unit/test_integration_cleanup.py +155 -0
  118. quadkit_testing-0.0.4/tests/unit/test_integration_cluster.py +100 -0
  119. quadkit_testing-0.0.4/tests/unit/test_integration_environment.py +319 -0
  120. quadkit_testing-0.0.4/tests/unit/test_integration_fixtures.py +311 -0
  121. quadkit_testing-0.0.4/tests/unit/test_integration_probes.py +129 -0
  122. quadkit_testing-0.0.4/tests/unit/test_lib_admin_client.py +191 -0
  123. quadkit_testing-0.0.4/tests/unit/test_lib_async_helpers.py +168 -0
  124. quadkit_testing-0.0.4/tests/unit/test_lib_helpers.py +347 -0
  125. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_memory_lock.py +26 -0
  126. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_override_context_manager_revert.py +20 -20
  127. quadkit_testing-0.0.4/tests/unit/test_round33_hardening.py +79 -0
  128. quadkit_testing-0.0.4/tests/unit/test_tasks_clients.py +290 -0
  129. quadkit_testing-0.0.4/tests/unit/test_test_environment.py +277 -0
  130. quadkit_testing-0.0.4/tests/unit/test_test_environment_facade.py +159 -0
  131. quadkit_testing-0.0.4/tests/unit/test_test_environment_overrides.py +209 -0
  132. quadkit_testing-0.0.4/tests/unit/test_testing_stack_scenario.py +332 -0
  133. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_testing_utils.py +11 -7
  134. quadkit_testing-0.0.4/tests/unit/test_testkit_surface.py +174 -0
  135. quadkit_testing-0.0.3/.gitignore +0 -24
  136. quadkit_testing-0.0.3/README.md +0 -146
  137. quadkit_testing-0.0.3/src/quadkit/testing/README.md +0 -338
  138. quadkit_testing-0.0.3/src/quadkit/testing/__init__.py +0 -235
  139. quadkit_testing-0.0.3/src/quadkit/testing/clients/web/__init__.py +0 -14
  140. quadkit_testing-0.0.3/src/quadkit/testing/fixtures/__init__.py +0 -152
  141. quadkit_testing-0.0.3/src/quadkit/testing/fixtures/_lazy.py +0 -40
  142. quadkit_testing-0.0.3/tests/unit/test_integration_cluster.py +0 -724
  143. quadkit_testing-0.0.3/tests/unit/test_lib_helpers.py +0 -688
  144. quadkit_testing-0.0.3/tests/unit/test_test_environment.py +0 -627
  145. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/LICENSE +0 -0
  146. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/NOTICE +0 -0
  147. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/py.typed +0 -0
  148. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/clients/ai/__init__.py +0 -0
  149. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/clients/ai/bed.py +0 -0
  150. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/clients/ai/data.py +0 -0
  151. {quadkit_testing-0.0.3/src/quadkit/testing/clients/web → quadkit_testing-0.0.4/src/quadkit/testing/clients/auth}/py.typed +0 -0
  152. {quadkit_testing-0.0.3/src/quadkit/testing/fixtures → quadkit_testing-0.0.4/src/quadkit/testing/clients/cache}/py.typed +0 -0
  153. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/clients/db/__init__.py +0 -0
  154. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/clients/db/bed.py +0 -0
  155. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/clients/db/client.py +0 -0
  156. {quadkit_testing-0.0.3/src/quadkit/testing → quadkit_testing-0.0.4/src/quadkit/testing/clients/events/components}/py.typed +0 -0
  157. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/clients/web/bed.py +0 -0
  158. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/clock.py +0 -0
  159. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/audit.py +0 -0
  160. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/blob_store.py +0 -0
  161. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/cache.py +0 -0
  162. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/database.py +0 -0
  163. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/distributed_lock.py +0 -0
  164. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/event_bus.py +0 -0
  165. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/middleware.py +0 -0
  166. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/notification.py +0 -0
  167. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/queue_backend.py +0 -0
  168. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/repository.py +0 -0
  169. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/search.py +0 -0
  170. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/secrets.py +0 -0
  171. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/task_queue.py +0 -0
  172. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/vector_store.py +0 -0
  173. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/compliance/webhook.py +0 -0
  174. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/config.py +0 -0
  175. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/constants.py +0 -0
  176. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/decorators.py +0 -0
  177. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/di/__init__.py +0 -0
  178. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/events.py +0 -0
  179. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/exceptions.py +0 -0
  180. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/audit.py +0 -0
  181. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/buses.py +0 -0
  182. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/cache.py +0 -0
  183. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/clock.py +0 -0
  184. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/config.py +0 -0
  185. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/events.py +0 -0
  186. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/governance.py +0 -0
  187. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/lifecycle.py +0 -0
  188. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/logging.py +0 -0
  189. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/monitoring.py +0 -0
  190. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fakes/tracing.py +0 -0
  191. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fixtures/bed.py +0 -0
  192. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fixtures/container.py +0 -0
  193. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fixtures/containers.py +0 -0
  194. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/fixtures/web.py +0 -0
  195. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/generators.py +0 -0
  196. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/generators_contract.py +0 -0
  197. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/harness/__init__.py +0 -0
  198. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/harness/container.py +0 -0
  199. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/harness/decorators.py +0 -0
  200. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/harness/testbed.py +0 -0
  201. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/hooks.py +0 -0
  202. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/integration/cleanup.py +0 -0
  203. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/integration/config.py +0 -0
  204. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/integration/fixtures.py +0 -0
  205. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/integration/markers.py +0 -0
  206. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/integration/probes.py +0 -0
  207. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/lib/async_helper.py +0 -0
  208. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/lib/smoke.py +0 -0
  209. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/lib/snapshots.py +0 -0
  210. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/lib/stubs.py +0 -0
  211. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/__init__.py +0 -0
  212. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/audit.py +0 -0
  213. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/blob_store.py +0 -0
  214. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/cache.py +0 -0
  215. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/config/__init__.py +0 -0
  216. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/config/models.py +0 -0
  217. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/constants.py +0 -0
  218. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/di/__init__.py +0 -0
  219. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/di/provider.py +0 -0
  220. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/event_bus.py +0 -0
  221. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/exceptions.py +0 -0
  222. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/notification.py +0 -0
  223. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/queue.py +0 -0
  224. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/memory/search.py +0 -0
  225. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/mocks/__init__.py +0 -0
  226. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/mocks/base.py +0 -0
  227. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/mocks/test_provider.py +0 -0
  228. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/module.py +0 -0
  229. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/plugins/__init__.py +0 -0
  230. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/protocols.py +0 -0
  231. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/testkit/__init__.py +0 -0
  232. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/testkit/assertions.py +0 -0
  233. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/testkit/fakes.py +0 -0
  234. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/testkit/fixtures.py +0 -0
  235. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/types.py +0 -0
  236. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/websocket/__init__.py +0 -0
  237. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/websocket/client.py +0 -0
  238. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/workflow/__init__.py +0 -0
  239. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/src/quadkit/testing/workflow/harness.py +0 -0
  240. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/__snapshots__/test_snapshot_function.json +0 -0
  241. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/conftest.py +0 -0
  242. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/integration/test_web_client.py +0 -0
  243. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/test_package_structure_p1.py +0 -0
  244. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/__snapshots__/test_snapshot_function.json +0 -0
  245. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_ai_client_budget.py +0 -0
  246. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_ai_clients.py +0 -0
  247. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_app_testbed.py +0 -0
  248. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_app_testbed_from_factory_overrides.py +0 -0
  249. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_assertion_helpers.py +0 -0
  250. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_async_helper.py +0 -0
  251. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_container.py +0 -0
  252. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_container_bind.py +0 -0
  253. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_container_factory_auto_registration.py +0 -0
  254. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_container_try_resolve.py +0 -0
  255. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_db_clients.py +0 -0
  256. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_environment_lifecycle.py +0 -0
  257. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_exceptions.py +0 -0
  258. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_fake_audit.py +0 -0
  259. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_fake_event_bus_ordering.py +0 -0
  260. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_fake_tracer.py +0 -0
  261. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_fakes.py +0 -0
  262. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_generators_util.py +0 -0
  263. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_memory_backends.py +0 -0
  264. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_memory_cqrs.py +0 -0
  265. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_memory_event_bus.py +0 -0
  266. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_memory_outbox.py +0 -0
  267. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_memory_repository.py +0 -0
  268. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_mocks.py +0 -0
  269. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_mocks_cluster.py +0 -0
  270. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_plugin.py +0 -0
  271. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_public_exports.py +0 -0
  272. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_pytest_plugin_fixtures.py +0 -0
  273. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_service_probe_connectivity.py +0 -0
  274. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_small_modules.py +0 -0
  275. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_smoke.py +0 -0
  276. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_snapshot_asserter_create_compare.py +0 -0
  277. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_snapshots.py +0 -0
  278. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_stubs.py +0 -0
  279. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_subpackage_exports.py +0 -0
  280. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_testing_constants.py +0 -0
  281. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_testing_module.py +0 -0
  282. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_utilities.py +0 -0
  283. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_web_clients.py +0 -0
  284. {quadkit_testing-0.0.3 → quadkit_testing-0.0.4}/tests/unit/test_workflow_websocket_plugins.py +0 -0
@@ -0,0 +1,183 @@
1
+ *
2
+ !tests/
3
+ !tests/**
4
+ !README.md
5
+ !AGENTS.md
6
+ !DEVELOPMENT.md
7
+ !QUICKGUIDE.md
8
+ !MILESTONE*.md
9
+ !TESTS*.md
10
+ !CHANGELOG.md
11
+ !AUDIT*.md
12
+ !REF*.md
13
+ !AUDIT*.json
14
+ !LICENSE
15
+ !LICENSE-MIT.txt
16
+ !NOTICE
17
+ !TRADEMARK.md
18
+ !conftest.py
19
+ !CONTRIBUTING.md
20
+ !CODE_OF_CONDUCT.md
21
+ !SECURITY.md
22
+ !GOVERNANCE.md
23
+ !pyproject.toml
24
+ !uv.lock
25
+ !docker-compose.yml
26
+ !.env.example
27
+ !.env.full.example
28
+ !.importlinter
29
+ !.superpowers/
30
+ !.superpowers/**
31
+ !.gitattributes
32
+ !.editorconfig
33
+ !Makefile
34
+ !docker-compose.test.yml
35
+ !quadkit.yaml.example
36
+ !.github/
37
+ !.github/workflows/
38
+ !.github/workflows/**
39
+ !.github/dependabot.yml
40
+ !.devcontainer/
41
+ !.devcontainer/**
42
+ !tools/
43
+ !tools/**
44
+ !*example.yaml
45
+
46
+ # Quadkit Packages
47
+ !quadkit*/
48
+ !quadkit*/pyproject.toml
49
+ !quadkit*/CHANGELOG.md
50
+ !quadkit*/README.md
51
+ !quadkit*/alembic.ini
52
+ !quadkit*/mypy.ini
53
+ !quadkit*/*.yaml.example
54
+ !quadkit*/src/
55
+ !quadkit*/src/**
56
+ !quadkit*/docs/
57
+ !quadkit*/docs/**
58
+ !quadkit*/tests/
59
+ !quadkit*/tests/**
60
+
61
+ # Keep quadkit docs
62
+ !/docs/
63
+ !docs/**
64
+
65
+ # Session / cutover plans at the repo root
66
+ !plans/
67
+ !plans/**
68
+
69
+ # Keep example files for README examples
70
+ !/examples/
71
+ !/examples/**
72
+
73
+ # Re-ignore these AFTER negations (last match wins)
74
+ *.tape
75
+ examples/*/runs/
76
+ __pycache__/
77
+ *.pyc
78
+ *.pyo
79
+ *.egg-info/
80
+ dist/
81
+ build/
82
+ .eggs/
83
+ *.egg
84
+ .pytest_cache/
85
+ .mypy_cache/
86
+ .ruff_cache/
87
+ htmlcov/
88
+ .coverage
89
+ coverage.xml
90
+ test.db
91
+ !quadkit*/tests/fixtures/test.db
92
+ *.log
93
+ *.tmp
94
+
95
+ # Company-specific files (keep private, do not commit)
96
+ .company/
97
+ COMPANY_*.md
98
+ company-config/
99
+ internal-docs/
100
+ # Editor swap files
101
+ *.swp
102
+
103
+ !core/
104
+ !packages/
105
+ !core/quadkit*/
106
+ !packages/quadkit*/
107
+ !core/quadkit*/pyproject.toml
108
+ !packages/quadkit*/pyproject.toml
109
+ !core/quadkit*/CHANGELOG.md
110
+ !packages/quadkit*/CHANGELOG.md
111
+ !core/quadkit*/README.md
112
+ !packages/quadkit*/README.md
113
+ !core/quadkit*/alembic.ini
114
+ !packages/quadkit*/alembic.ini
115
+ !core/quadkit*/mypy.ini
116
+ !packages/quadkit*/mypy.ini
117
+ !core/quadkit*/*.yaml.example
118
+ !packages/quadkit*/*.yaml.example
119
+ !core/quadkit*/src/
120
+ !core/quadkit*/src/**
121
+ !packages/quadkit*/src/
122
+ !packages/quadkit*/src/**
123
+ !core/quadkit*/tests/
124
+ !core/quadkit*/tests/**
125
+ !packages/quadkit*/tests/
126
+ !packages/quadkit*/tests/**
127
+ !core/quadkit*/docs/
128
+ !core/quadkit*/docs/**
129
+ !packages/quadkit*/docs/
130
+ !packages/quadkit*/docs/**
131
+
132
+ # dev/
133
+ !dev/
134
+ !dev/**
135
+
136
+ # Admin dev playground (committed dev asset; local SQLite files stay ignored)
137
+ !packages/quadkit-admin/playground/
138
+ !packages/quadkit-admin/playground/serve.py
139
+
140
+ # gatewai apps
141
+ !apps/
142
+ !apps/**
143
+ !apps/gatewai/
144
+ !apps/gatewai/**
145
+ apps/**/node_modules/
146
+ apps/**/dist/
147
+ apps/**/__pycache__/
148
+ apps/**/*.pyc
149
+ apps/**/*.db
150
+ apps/**/*.db-wal
151
+ apps/**/*.db-shm
152
+
153
+ # Re-exclude private content under the tiered paths.
154
+ # MUST come after the !...docs/** negations above — last match wins.
155
+ core/quadkit*/docs/plans/
156
+ packages/quadkit*/docs/plans/
157
+ core/quadkit*/docs/**/
158
+ packages/quadkit*/docs/**/
159
+
160
+ # Re-exclude tooling artifacts under the tiered paths
161
+ __pycache__/
162
+ *.pyc
163
+ *.pyo
164
+ *.egg-info/
165
+ .pytest_cache/
166
+ .mypy_cache/
167
+ .ruff_cache/
168
+ htmlcov/
169
+ .coverage
170
+ coverage.xml
171
+ test.db
172
+ *.tmp
173
+ *.log
174
+ !core/quadkit*/tests/fixtures/test.db
175
+ !packages/quadkit*/tests/fixtures/test.db
176
+
177
+ # Allow the generated example gifs to be tracked (README hero images).
178
+ !core/quadkit*/docs/gifs/
179
+ !core/quadkit*/docs/gifs/**
180
+ !packages/*/quadkit*/docs/gifs/
181
+ !packages/*/quadkit*/docs/gifs/**
182
+ examples/*/screenshot.png
183
+ !banner*
@@ -0,0 +1,270 @@
1
+ Metadata-Version: 2.5
2
+ Name: quadkit-testing
3
+ Version: 0.0.4
4
+ Summary: Centralized testing infrastructure for Quadkit Framework - Fixtures, factories, and utilities
5
+ Project-URL: Homepage, https://dbtinoy-.github.io/quadkit/
6
+ Project-URL: Repository, https://github.com/dbtinoy-/quadkit
7
+ Project-URL: Documentation, https://dbtinoy-.github.io/quadkit/
8
+ Project-URL: Issues, https://github.com/dbtinoy-/quadkit/issues
9
+ Project-URL: Changelog, https://github.com/dbtinoy-/quadkit/blob/main/CHANGELOG.md
10
+ Author-email: Quadkit Framework Team <team@quadkit.dev>
11
+ Maintainer-email: Quadkit Framework Team <team@quadkit.dev>
12
+ License: Apache-2.0
13
+ License-File: LICENSE
14
+ License-File: NOTICE
15
+ Keywords: async,factories,fixtures,framework,mocking,pytest,testing
16
+ Classifier: Development Status :: 3 - Alpha
17
+ Classifier: Framework :: AsyncIO
18
+ Classifier: Framework :: Pytest
19
+ Classifier: Intended Audience :: Developers
20
+ Classifier: License :: OSI Approved :: Apache Software License
21
+ Classifier: Operating System :: OS Independent
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: Software Development :: Testing
27
+ Classifier: Typing :: Typed
28
+ Requires-Python: >=3.11
29
+ Requires-Dist: pytest-asyncio<2,>=0.21.0
30
+ Requires-Dist: pytest-cov<8,>=4.0.0
31
+ Requires-Dist: pytest-mock<4,>=3.10.0
32
+ Requires-Dist: pytest<10,>=8.0.0
33
+ Requires-Dist: quadkit-contracts>=0.0.2
34
+ Requires-Dist: quadkit>=0.0.2
35
+ Provides-Extra: all
36
+ Requires-Dist: aiosqlite<1,>=0.19.0; extra == 'all'
37
+ Requires-Dist: asyncpg<1,>=0.29.0; extra == 'all'
38
+ Requires-Dist: httpx2<3,>=2.0.0; extra == 'all'
39
+ Requires-Dist: httpx<1,>=0.26.0; extra == 'all'
40
+ Requires-Dist: quadkit-auth>=0.0.2; extra == 'all'
41
+ Requires-Dist: quadkit-cache>=0.0.2; extra == 'all'
42
+ Requires-Dist: quadkit-storage>=0.0.2; extra == 'all'
43
+ Requires-Dist: starlette<2,>=0.28.0; extra == 'all'
44
+ Provides-Extra: auth
45
+ Requires-Dist: quadkit-auth>=0.0.2; extra == 'auth'
46
+ Provides-Extra: cache
47
+ Requires-Dist: quadkit-cache>=0.0.2; extra == 'cache'
48
+ Provides-Extra: db
49
+ Requires-Dist: aiosqlite<1,>=0.19.0; extra == 'db'
50
+ Requires-Dist: asyncpg<1,>=0.29.0; extra == 'db'
51
+ Requires-Dist: quadkit-sql>=0.0.2; extra == 'db'
52
+ Provides-Extra: dev
53
+ Requires-Dist: black<27,>=23.0.0; extra == 'dev'
54
+ Requires-Dist: mypy<3,>=1.0.0; extra == 'dev'
55
+ Requires-Dist: ruff<1,>=0.16.4; extra == 'dev'
56
+ Provides-Extra: integration
57
+ Requires-Dist: aiokafka<1,>=0.12.0; extra == 'integration'
58
+ Requires-Dist: aiosqlite<1,>=0.19.0; extra == 'integration'
59
+ Requires-Dist: asyncpg<1,>=0.29.0; extra == 'integration'
60
+ Requires-Dist: elasticsearch[async]<10,>=8.12.0; extra == 'integration'
61
+ Requires-Dist: motor<4,>=3.3.0; extra == 'integration'
62
+ Requires-Dist: neo4j<7,>=5.18.0; extra == 'integration'
63
+ Requires-Dist: qdrant-client<2,>=1.9.0; extra == 'integration'
64
+ Requires-Dist: redis<9,>=5.0.0; extra == 'integration'
65
+ Provides-Extra: storage
66
+ Requires-Dist: quadkit-storage>=0.0.2; extra == 'storage'
67
+ Provides-Extra: web
68
+ Requires-Dist: httpx2<3,>=2.0.0; extra == 'web'
69
+ Requires-Dist: httpx<1,>=0.26.0; extra == 'web'
70
+ Requires-Dist: starlette<2,>=0.28.0; extra == 'web'
71
+ Description-Content-Type: text/markdown
72
+
73
+ # quadkit-testing
74
+
75
+ ![Quadkit](https://raw.githubusercontent.com/dbtinoy-/quadkit/main/banner.jpg)
76
+
77
+ [![PyPI](https://img.shields.io/pypi/v/quadkit-testing?color=%2322c55e&label=pypi)](https://pypi.org/project/quadkit-testing/)
78
+ [![Python](https://img.shields.io/pypi/pyversions/quadkit-testing?color=%2322c55e)](https://pypi.org/project/quadkit-testing/)
79
+ [![License](https://img.shields.io/pypi/l/quadkit-testing?color=%2322c55e)](https://github.com/dbtinoy-/quadkit/blob/main/LICENSE)
80
+
81
+ Test harnesses, fakes, and fixtures for Quadkit applications: boot the
82
+ real application in-process, substitute bindings instead of mocking
83
+ import sites, and assert on responses with helpers that say what
84
+ failed.
85
+
86
+ For anyone writing tests against Quadkit applications — and for tooling
87
+ that needs drop-in implementations of the framework's protocols.
88
+
89
+ ## The quadkit family
90
+
91
+ | Package | Role |
92
+ | --- | --- |
93
+ | [`quadkit-contracts`](https://pypi.org/project/quadkit-contracts/) | zero-dependency protocols, types, exception hierarchy |
94
+ | [`quadkit`](https://pypi.org/project/quadkit/) | the framework core — DI container, modules, config, logging, `Result` |
95
+ | [`quadkit-web`](https://pypi.org/project/quadkit-web/) | ASGI layer — controllers, routing, middleware, OpenAPI docs |
96
+ | [`quadkit-cli`](https://pypi.org/project/quadkit-cli/) | project scaffolding and code generators |
97
+ | [`quadkit-testing`](https://pypi.org/project/quadkit-testing/) | in-process test beds, fakes, fixtures |
98
+
99
+ ## Installation
100
+
101
+ ```bash
102
+ uv add --dev quadkit-testing
103
+ ```
104
+
105
+ Requires **Python >= 3.11**.
106
+
107
+ ## Minimal working example
108
+
109
+ Test an HTTP route with the real application, in-process:
110
+
111
+ ```python
112
+ import pytest
113
+
114
+ from quadkit.testing import WebTestBed
115
+
116
+ from my_app import create_app
117
+
118
+
119
+ @pytest.mark.asyncio
120
+ async def test_hello() -> None:
121
+ async with WebTestBed(create_app()) as bed:
122
+ response = bed.get("/hello", params={"name": "quadkit"})
123
+ response.assert_status(200)
124
+ assert response.json == {"message": "hello, quadkit"}
125
+ ```
126
+
127
+ Or test services directly, with binding overrides:
128
+
129
+ ```python
130
+ async def test_service() -> None:
131
+ from quadkit.testing import AppTestBed
132
+
133
+ async with AppTestBed.from_factory(
134
+ create_app, overrides={Cache: FakeCache()}
135
+ ) as bed:
136
+ service = await bed.app.container.resolve(UserService)
137
+ ```
138
+
139
+ A pytest plugin registers automatically via entry points — no
140
+ `conftest.py` wiring — and provides auto-registered fixtures including
141
+ `fake_cache`, `fake_event_bus`, `fake_logger`, `fake_clock`,
142
+ `fake_command_bus`, `fake_query_bus`, `fake_unit_of_work`,
143
+ `fake_metrics`, `fake_config`, `fake_state_store`, `test_bed`,
144
+ `test_container`, and `test_data`:
145
+
146
+ ```python
147
+ import pytest
148
+
149
+ from quadkit.contracts.domain.events import DomainEvent
150
+
151
+
152
+ class UserCreated(DomainEvent):
153
+ user_id: str
154
+ email: str
155
+
156
+
157
+ @pytest.mark.asyncio
158
+ async def test_signup_publishes(fake_event_bus) -> None:
159
+ await fake_event_bus.publish(UserCreated(user_id="1", email="a@b.c"))
160
+ fake_event_bus.assert_published(UserCreated, user_id="1")
161
+
162
+
163
+ def test_trial_expiry_is_deterministic(fake_clock) -> None:
164
+ t0 = fake_clock.now()
165
+ fake_clock.advance(30 * 24 * 3600)
166
+ assert (fake_clock.now() - t0).days == 30
167
+ ```
168
+
169
+ ## Optional extras
170
+
171
+ | Extra | Contents |
172
+ | --- | --- |
173
+ | `[web]` | `httpx` + Starlette — the `WebTestBed` client transport |
174
+ | `[db]` | `aiosqlite`, `asyncpg` — drivers for your async DB test suites |
175
+ | `[integration]` | service clients for integration suites (Redis, MongoDB, Kafka, Elasticsearch, Neo4j, Qdrant, PostgreSQL, SQLite) |
176
+ | `[dev]` | `ruff`, `mypy`, `black` |
177
+
178
+ ## Public API entry points
179
+
180
+ ### Test beds
181
+
182
+ ```python
183
+ from quadkit.testing import AppTestBed, WebTestBed
184
+ ```
185
+
186
+ - `AppTestBed.from_factory(factory, overrides=None)` /
187
+ `AppTestBed.from_app(app)` — application-level beds.
188
+ - `WebTestBed(app_or_provider, raise_server_exceptions=True)` with
189
+ `get/post/put/patch/delete`, `override(Contract, impl)` (before
190
+ boot), and `TestResponse` — `status_code`, `headers`, `text`,
191
+ `json` (property), `assert_status`, `assert_json`,
192
+ `assert_json_path`, `assert_header`.
193
+ - `quadkit.testing.fixtures.container.ContainerTestFixture` — DI-level
194
+ fixture with `mock()`, `override()`, `get()`, `get_optional()`.
195
+ - `quadkit.testing.fixtures.bed.TestEnvironment` — programmatic
196
+ environment builder (`use_provider`, `override`, `fake`, `resolve`).
197
+ - `quadkit.testing.lib.factory.TestDataFactory` — deterministic
198
+ `create_user()`, `create_task()`, `create_message()`,
199
+ `create_request()`.
200
+
201
+ ### Fakes (`quadkit.testing.fakes`)
202
+
203
+ All in-process, async-native, implementing the same contracts as the
204
+ real services:
205
+
206
+ | Class | Covers |
207
+ | --- | --- |
208
+ | `FakeCache` / `FakeStateStore` | cache and state storage |
209
+ | `FakeEventBus` | in-process events with `assert_published()`, `published_of_type()`, `assert_events_in_order()` and friends |
210
+ | `FakeCommandBus` / `FakeQueryBus` | command / query dispatch |
211
+ | `FakeUnitOfWork` | unit-of-work context |
212
+ | `FakeClock` (+ `Clock`, `SystemClock`) | deterministic time |
213
+ | `FakeConfig` | config overrides |
214
+ | `FakeLogger` (+ `LogEntry`) | structlog-compatible sink |
215
+ | `FakeMetricsCollector` / `FakeResourceUnitTracker` | metrics / resource tracking |
216
+ | `FakeRedisClient` | Redis-protocol client |
217
+ | `FakeAuditLogger` | audit records |
218
+ | `FakeTracer` / `FakeSpan` | tracing |
219
+
220
+ The published wheel carries the `ai`, `db` and `web` test clients and beds
221
+ plus the fakes and fixtures that need no private package. The `auth`,
222
+ `cache`, `events`, `search`, `storage`, `tasks`, `ui` test clients, the
223
+ AI/DB/task fixture modules, the secrets fake and `IntegrationEnvironment`
224
+ stay in this repository until their packages publish; asking the published
225
+ wheel for one raises `AttributeError` naming the module.
226
+
227
+ ## Configuration
228
+
229
+ None required — the pytest plugin self-registers. Mark suites for
230
+ external services and gate them yourself (e.g.
231
+ `uv run pytest -m "not integration"`).
232
+
233
+ ## Error handling
234
+
235
+ Test beds surface failures, they don't hide them: with
236
+ `raise_server_exceptions=True` (the default) unexpected exceptions
237
+ re-raise into your test with their original traceback; HTTP-expected
238
+ failures assert on the response instead.
239
+
240
+ ## Testing
241
+
242
+ Ironically self-hosted: this package's public tests are among the
243
+ suite the release executes from the exported tree against the built
244
+ wheels.
245
+
246
+ ## Security
247
+
248
+ Fakes are in-process and safe to wire into unit suites. Report
249
+ vulnerabilities privately per [SECURITY.md](https://github.com/dbtinoy-/quadkit/blob/main/SECURITY.md).
250
+
251
+ ## Stability
252
+
253
+ Version `0.0.3` in the `0.x` series, released in lockstep with the
254
+ other four distributions; APIs may change between minor versions until
255
+ 1.0 — pin an exact version (`quadkit-testing==0.0.3`) or a tight range
256
+ (`>=0.0.3,<0.1.0`). Full policy:
257
+ [stability and compatibility](https://dbtinoy-.github.io/quadkit/reference/stability/).
258
+
259
+ ## Links
260
+
261
+ - **Documentation** — <https://dbtinoy-.github.io/quadkit/>
262
+ - **Getting started** — <https://dbtinoy-.github.io/quadkit/getting-started/installation/>
263
+ - **Changelog** — <https://github.com/dbtinoy-/quadkit/blob/main/CHANGELOG.md>
264
+ - **Issues** — <https://github.com/dbtinoy-/quadkit/issues>
265
+ - **Security** — report privately per [SECURITY.md](https://github.com/dbtinoy-/quadkit/blob/main/SECURITY.md)
266
+ - **Contributing** — [CONTRIBUTING.md](https://github.com/dbtinoy-/quadkit/blob/main/CONTRIBUTING.md)
267
+
268
+ Apache-2.0 — see [LICENSE](https://github.com/dbtinoy-/quadkit/blob/main/LICENSE). "Quadkit" and the
269
+ Quadkit logo are trademarks of the project — see
270
+ [TRADEMARK.md](https://github.com/dbtinoy-/quadkit/blob/main/TRADEMARK.md).
@@ -1,61 +1,11 @@
1
- Metadata-Version: 2.5
2
- Name: quadkit-testing
3
- Version: 0.0.3
4
- Summary: Centralized testing infrastructure for Quadkit Framework - Fixtures, factories, and utilities
5
- Project-URL: Homepage, https://quadkit.dev
6
- Project-URL: Repository, https://github.com/dbtinoy-/quadkit
7
- Project-URL: Documentation, https://quadkit.dev
8
- Project-URL: Issues, https://github.com/dbtinoy-/quadkit/issues
9
- Project-URL: Changelog, https://github.com/dbtinoy-/quadkit/blob/main/CHANGELOG.md
10
- Author-email: Quadkit Framework Team <team@quadkit.dev>
11
- Maintainer-email: Quadkit Framework Team <team@quadkit.dev>
12
- License: Apache-2.0
13
- License-File: LICENSE
14
- License-File: NOTICE
15
- Keywords: async,factories,fixtures,framework,mocking,pytest,testing
16
- Classifier: Development Status :: 3 - Alpha
17
- Classifier: Framework :: AsyncIO
18
- Classifier: Framework :: Pytest
19
- Classifier: Intended Audience :: Developers
20
- Classifier: License :: OSI Approved :: Apache Software License
21
- Classifier: Operating System :: OS Independent
22
- Classifier: Programming Language :: Python :: 3
23
- Classifier: Programming Language :: Python :: 3.11
24
- Classifier: Programming Language :: Python :: 3.12
25
- Classifier: Programming Language :: Python :: 3.13
26
- Classifier: Topic :: Software Development :: Testing
27
- Classifier: Typing :: Typed
28
- Requires-Python: >=3.11
29
- Requires-Dist: pytest-asyncio>=0.21.0
30
- Requires-Dist: pytest-cov>=4.0.0
31
- Requires-Dist: pytest-mock>=3.10.0
32
- Requires-Dist: pytest>=8.0.0
33
- Requires-Dist: quadkit-contracts>=0.0.2
34
- Requires-Dist: quadkit>=0.0.2
35
- Provides-Extra: db
36
- Requires-Dist: aiosqlite>=0.19.0; extra == 'db'
37
- Requires-Dist: asyncpg>=0.29.0; extra == 'db'
38
- Provides-Extra: dev
39
- Requires-Dist: black>=23.0.0; extra == 'dev'
40
- Requires-Dist: mypy>=1.0.0; extra == 'dev'
41
- Requires-Dist: ruff>=0.16.4; extra == 'dev'
42
- Provides-Extra: integration
43
- Requires-Dist: aiokafka>=0.12.0; extra == 'integration'
44
- Requires-Dist: aiosqlite>=0.19.0; extra == 'integration'
45
- Requires-Dist: asyncpg>=0.29.0; extra == 'integration'
46
- Requires-Dist: elasticsearch[async]>=8.12.0; extra == 'integration'
47
- Requires-Dist: motor>=3.3.0; extra == 'integration'
48
- Requires-Dist: neo4j>=5.18.0; extra == 'integration'
49
- Requires-Dist: qdrant-client>=1.9.0; extra == 'integration'
50
- Requires-Dist: redis>=5.0.0; extra == 'integration'
51
- Provides-Extra: web
52
- Requires-Dist: httpx2>=2.0.0; extra == 'web'
53
- Requires-Dist: httpx>=0.26.0; extra == 'web'
54
- Requires-Dist: starlette>=0.28.0; extra == 'web'
55
- Description-Content-Type: text/markdown
56
-
57
1
  # quadkit-testing
58
2
 
3
+ ![Quadkit](https://raw.githubusercontent.com/dbtinoy-/quadkit/main/banner.jpg)
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/quadkit-testing?color=%2322c55e&label=pypi)](https://pypi.org/project/quadkit-testing/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/quadkit-testing?color=%2322c55e)](https://pypi.org/project/quadkit-testing/)
7
+ [![License](https://img.shields.io/pypi/l/quadkit-testing?color=%2322c55e)](https://github.com/dbtinoy-/quadkit/blob/main/LICENSE)
8
+
59
9
  Test harnesses, fakes, and fixtures for Quadkit applications: boot the
60
10
  real application in-process, substitute bindings instead of mocking
61
11
  import sites, and assert on responses with helpers that say what
@@ -64,6 +14,16 @@ failed.
64
14
  For anyone writing tests against Quadkit applications — and for tooling
65
15
  that needs drop-in implementations of the framework's protocols.
66
16
 
17
+ ## The quadkit family
18
+
19
+ | Package | Role |
20
+ | --- | --- |
21
+ | [`quadkit-contracts`](https://pypi.org/project/quadkit-contracts/) | zero-dependency protocols, types, exception hierarchy |
22
+ | [`quadkit`](https://pypi.org/project/quadkit/) | the framework core — DI container, modules, config, logging, `Result` |
23
+ | [`quadkit-web`](https://pypi.org/project/quadkit-web/) | ASGI layer — controllers, routing, middleware, OpenAPI docs |
24
+ | [`quadkit-cli`](https://pypi.org/project/quadkit-cli/) | project scaffolding and code generators |
25
+ | [`quadkit-testing`](https://pypi.org/project/quadkit-testing/) | in-process test beds, fakes, fixtures |
26
+
67
27
  ## Installation
68
28
 
69
29
  ```bash
@@ -109,11 +69,32 @@ A pytest plugin registers automatically via entry points — no
109
69
  `fake_cache`, `fake_event_bus`, `fake_logger`, `fake_clock`,
110
70
  `fake_command_bus`, `fake_query_bus`, `fake_unit_of_work`,
111
71
  `fake_metrics`, `fake_config`, `fake_state_store`, `test_bed`,
112
- `test_container`, and `test_data`.
72
+ `test_container`, and `test_data`:
73
+
74
+ ```python
75
+ import pytest
76
+
77
+ from quadkit.contracts.domain.events import DomainEvent
113
78
 
114
- ## Optional extras
115
79
 
116
- Verified against the package's `pyproject.toml`:
80
+ class UserCreated(DomainEvent):
81
+ user_id: str
82
+ email: str
83
+
84
+
85
+ @pytest.mark.asyncio
86
+ async def test_signup_publishes(fake_event_bus) -> None:
87
+ await fake_event_bus.publish(UserCreated(user_id="1", email="a@b.c"))
88
+ fake_event_bus.assert_published(UserCreated, user_id="1")
89
+
90
+
91
+ def test_trial_expiry_is_deterministic(fake_clock) -> None:
92
+ t0 = fake_clock.now()
93
+ fake_clock.advance(30 * 24 * 3600)
94
+ assert (fake_clock.now() - t0).days == 30
95
+ ```
96
+
97
+ ## Optional extras
117
98
 
118
99
  | Extra | Contents |
119
100
  | --- | --- |
@@ -164,8 +145,12 @@ real services:
164
145
  | `FakeAuditLogger` | audit records |
165
146
  | `FakeTracer` / `FakeSpan` | tracing |
166
147
 
167
- Fakes that depend on packages outside the published set are not
168
- included in this distribution.
148
+ The published wheel carries the `ai`, `db` and `web` test clients and beds
149
+ plus the fakes and fixtures that need no private package. The `auth`,
150
+ `cache`, `events`, `search`, `storage`, `tasks`, `ui` test clients, the
151
+ AI/DB/task fixture modules, the secrets fake and `IntegrationEnvironment`
152
+ stay in this repository until their packages publish; asking the published
153
+ wheel for one raises `AttributeError` naming the module.
169
154
 
170
155
  ## Configuration
171
156
 
@@ -189,7 +174,7 @@ wheels.
189
174
  ## Security
190
175
 
191
176
  Fakes are in-process and safe to wire into unit suites. Report
192
- vulnerabilities privately per [SECURITY.md](../../SECURITY.md).
177
+ vulnerabilities privately per [SECURITY.md](https://github.com/dbtinoy-/quadkit/blob/main/SECURITY.md).
193
178
 
194
179
  ## Stability
195
180
 
@@ -197,6 +182,17 @@ Version `0.0.3` in the `0.x` series, released in lockstep with the
197
182
  other four distributions; APIs may change between minor versions until
198
183
  1.0 — pin an exact version (`quadkit-testing==0.0.3`) or a tight range
199
184
  (`>=0.0.3,<0.1.0`). Full policy:
200
- [stability and compatibility](../../docs/reference/stability.md).
185
+ [stability and compatibility](https://dbtinoy-.github.io/quadkit/reference/stability/).
186
+
187
+ ## Links
188
+
189
+ - **Documentation** — <https://dbtinoy-.github.io/quadkit/>
190
+ - **Getting started** — <https://dbtinoy-.github.io/quadkit/getting-started/installation/>
191
+ - **Changelog** — <https://github.com/dbtinoy-/quadkit/blob/main/CHANGELOG.md>
192
+ - **Issues** — <https://github.com/dbtinoy-/quadkit/issues>
193
+ - **Security** — report privately per [SECURITY.md](https://github.com/dbtinoy-/quadkit/blob/main/SECURITY.md)
194
+ - **Contributing** — [CONTRIBUTING.md](https://github.com/dbtinoy-/quadkit/blob/main/CONTRIBUTING.md)
201
195
 
202
- Issues: <https://github.com/dbtinoy-/quadkit/issues>
196
+ Apache-2.0 — see [LICENSE](https://github.com/dbtinoy-/quadkit/blob/main/LICENSE). "Quadkit" and the
197
+ Quadkit logo are trademarks of the project — see
198
+ [TRADEMARK.md](https://github.com/dbtinoy-/quadkit/blob/main/TRADEMARK.md).