tigrbl_tests 0.3.7.dev1__tar.gz → 0.3.7.dev3__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 (252) hide show
  1. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/PKG-INFO +1 -1
  2. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/pyproject.toml +1 -1
  3. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/request/test_request_dot_notation.py +2 -1
  4. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/request/test_request_response_conveniences.py +2 -2
  5. tigrbl_tests-0.3.7.dev3/tests/request/test_request_transport_convenience_dot_notation.py +61 -0
  6. tigrbl_tests-0.3.7.dev3/tests/requests/test_request_json_modes.py +37 -0
  7. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/response/test_response_dot_notation.py +2 -1
  8. tigrbl_tests-0.3.7.dev3/tests/response/test_response_transport_convenience_dot_notation.py +27 -0
  9. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/security/test_dot_notation_schemes.py +1 -1
  10. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/decorators/test_response_ctx_bindings.py +1 -1
  11. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/response_utils.py +3 -3
  12. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_file_response.py +1 -1
  13. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_response_alias_table_rpc.py +1 -1
  14. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_response_ctx_precedence.py +1 -1
  15. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_response_diagnostics_kernelz.py +1 -1
  16. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_response_html_jinja_behavior.py +1 -1
  17. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_response_template.py +1 -1
  18. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_response_uuid.py +2 -2
  19. tigrbl_tests-0.3.7.dev3/tests/unit/test_stdapi_transport_asgi_wsgi.py +269 -0
  20. tigrbl_tests-0.3.7.dev1/tests/unit/test_stdapi_transport_asgi_wsgi.py +0 -121
  21. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/LICENSE +0 -0
  22. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/README.md +0 -0
  23. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/__init__.py +0 -0
  24. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/conftest.py +0 -0
  25. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/hooks/test_hook_ctx_phase_validation.py +0 -0
  26. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/__init__.py +0 -0
  27. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_acronym_route_name.py +0 -0
  28. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_allow_anon.py +0 -0
  29. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_apikey_generation.py +0 -0
  30. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_authn_provider_integration.py +0 -0
  31. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_bindings_integration.py +0 -0
  32. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_bindings_modules.py +0 -0
  33. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_bulk_docs_client.py +0 -0
  34. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_core_access.py +0 -0
  35. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_engine_install_uvicorn.py +0 -0
  36. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_engine_resolver_uvicorn.py +0 -0
  37. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_error_mappings.py +0 -0
  38. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_field_spec_effects.py +0 -0
  39. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_header_io_uvicorn.py +0 -0
  40. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_healthz_methodz_hookz.py +0 -0
  41. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_hook_ctx_v3_i9n.py +0 -0
  42. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_hook_lifecycle.py +0 -0
  43. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_iospec_attributes.py +0 -0
  44. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_iospec_integration.py +0 -0
  45. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_jsonrpc_batch_behavior.py +0 -0
  46. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_key_digest_uvicorn.py +0 -0
  47. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_list_filters_optional.py +0 -0
  48. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_mixins.py +0 -0
  49. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_mountable_favicon_uvicorn.py +0 -0
  50. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_mountable_lens_uvicorn.py +0 -0
  51. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_mountable_openapi_uvicorn.py +0 -0
  52. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_mountable_openrpc_uvicorn.py +0 -0
  53. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_mountable_swagger_uvicorn.py +0 -0
  54. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_nested_path_schema_and_rpc.py +0 -0
  55. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_nested_routing_depth.py +0 -0
  56. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_op_ctx_alias_examples.py +0 -0
  57. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_op_ctx_behavior.py +0 -0
  58. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_op_ctx_core_crud_order.py +0 -0
  59. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_openapi_clear_response_schema.py +0 -0
  60. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_openapi_schema_examples_presence.py +0 -0
  61. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_opspec_effects_i9n_test.py +0 -0
  62. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_owner_tenant_policy.py +0 -0
  63. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_request_extras.py +0 -0
  64. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_request_extras_provider.py +0 -0
  65. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_response_extras_provider.py +0 -0
  66. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_rest_fallback_serialization.py +0 -0
  67. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_rest_row_serialization.py +0 -0
  68. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_rest_rpc_parity_v3.py +0 -0
  69. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_row_result_serialization.py +0 -0
  70. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_schema.py +0 -0
  71. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_schema_ctx_attributes_integration.py +0 -0
  72. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_schema_ctx_op_ctx_integration.py +0 -0
  73. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_schema_ctx_spec_integration.py +0 -0
  74. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_sqlite_attachments.py +0 -0
  75. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_storage_spec_integration.py +0 -0
  76. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_symmetry_parity.py +0 -0
  77. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_tigrbl_api_app_usage_uvicorn.py +0 -0
  78. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_tigrbl_api_usage_uvicorn.py +0 -0
  79. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_tigrbl_api_uvicorn.py +0 -0
  80. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_tigrbl_app_include_api_uvicorn.py +0 -0
  81. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_tigrbl_app_multi_api_uvicorn.py +0 -0
  82. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_tigrbl_app_usage_uvicorn.py +0 -0
  83. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_tigrbl_app_uvicorn.py +0 -0
  84. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_v3_bulk_rest_endpoints.py +0 -0
  85. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_v3_default_rest_ops.py +0 -0
  86. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_v3_default_rpc_ops.py +0 -0
  87. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_v3_opspec_attributes.py +0 -0
  88. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/test_verb_alias_policy.py +0 -0
  89. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/i9n/uvicorn_utils.py +0 -0
  90. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/mount/__init__.py +0 -0
  91. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/mount/test_mount_favico.py +0 -0
  92. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/parity/__init__.py +0 -0
  93. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/parity/test_stdapi_openapi_docs.py +0 -0
  94. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/parity/test_stdapi_primitives.py +0 -0
  95. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/parity/test_stdapi_routing.py +0 -0
  96. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/perf/__init__.py +0 -0
  97. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/perf/test_collect_caching.py +0 -0
  98. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/perf/test_hookz_performance.py +0 -0
  99. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/perf/test_methodz_performance.py +0 -0
  100. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/security/test_schemes.py +0 -0
  101. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/__init__.py +0 -0
  102. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/decorators/test_alias_ctx_bindings.py +0 -0
  103. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/decorators/test_engine_ctx_bindings.py +0 -0
  104. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/decorators/test_hook_ctx_bindings.py +0 -0
  105. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/decorators/test_op_alias_bindings.py +0 -0
  106. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/decorators/test_op_ctx_bindings.py +0 -0
  107. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/decorators/test_schema_ctx_bindings.py +0 -0
  108. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_emit_paired_post.py +0 -0
  109. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_emit_paired_pre.py +0 -0
  110. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_emit_readtime_alias.py +0 -0
  111. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_out_masking.py +0 -0
  112. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_refresh_demand.py +0 -0
  113. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_resolve_assemble.py +0 -0
  114. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_resolve_paired_gen.py +0 -0
  115. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_schema_collect_in.py +0 -0
  116. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_schema_collect_out.py +0 -0
  117. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_storage_to_stored.py +0 -0
  118. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_wire_build_in.py +0 -0
  119. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_wire_build_out.py +0 -0
  120. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_wire_dump.py +0 -0
  121. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/atoms/test_wire_validate_in.py +0 -0
  122. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/runtime/test_events_phases.py +0 -0
  123. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_acol_vcol_knobs.py +0 -0
  124. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_alias_ctx_op_alias_attributes.py +0 -0
  125. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_alias_ctx_op_attributes.py +0 -0
  126. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_api_level_set_auth.py +0 -0
  127. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_app_model_defaults.py +0 -0
  128. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_app_reexport.py +0 -0
  129. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_base_columnspec_inheritance.py +0 -0
  130. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_base_facade_initialize.py +0 -0
  131. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_build_list_params_spec_model.py +0 -0
  132. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_bulk_body_annotation.py +0 -0
  133. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_bulk_response_schema.py +0 -0
  134. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_colspec_map_isolation.py +0 -0
  135. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_column_collect_mixins.py +0 -0
  136. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_column_rest_rpc_results.py +0 -0
  137. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_column_table_orm_binding.py +0 -0
  138. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_config_dataclass_none.py +0 -0
  139. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_core_crud_bulk_ops.py +0 -0
  140. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_core_crud_default_ops.py +0 -0
  141. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_core_crud_methods.py +0 -0
  142. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_core_wrap_memoization.py +0 -0
  143. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_db_dependency.py +0 -0
  144. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_decorator_and_collect.py +0 -0
  145. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_default_tags.py +0 -0
  146. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_engine_install_api.py +0 -0
  147. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_engine_install_app.py +0 -0
  148. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_engine_install_op.py +0 -0
  149. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_engine_install_table.py +0 -0
  150. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_engine_spec_and_shortcuts.py +0 -0
  151. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_engine_usage_levels.py +0 -0
  152. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_field_spec_attrs.py +0 -0
  153. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_get_schema.py +0 -0
  154. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_handler_step_qualname.py +0 -0
  155. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_hook_ctx_attributes.py +0 -0
  156. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_hook_ctx_binding.py +0 -0
  157. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_hookz_empty_phase.py +0 -0
  158. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_hybrid_session_run_sync.py +0 -0
  159. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_in_tx.py +0 -0
  160. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_include_model_columns_namespace.py +0 -0
  161. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_include_models_base_prefix.py +0 -0
  162. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_initialize_async_task.py +0 -0
  163. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_initialize_cross_ddl.py +0 -0
  164. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_initialize_mixed_engines.py +0 -0
  165. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_initialize_task_schedule.py +0 -0
  166. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_io_spec_attributes.py +0 -0
  167. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_iospec_attributes.py +0 -0
  168. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_iospec_effects.py +0 -0
  169. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_jsonrpc_id_example.py +0 -0
  170. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_jsonrpc_openrpc.py +0 -0
  171. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_jsonrpc_router_default_tag.py +0 -0
  172. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_kernel_invoke_ctx.py +0 -0
  173. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_kernel_opview_on_demand.py +0 -0
  174. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_kernel_plan_labels.py +0 -0
  175. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_kernelz_endpoint.py +0 -0
  176. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_make_column_shortcuts.py +0 -0
  177. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_mixins_sqlalchemy.py +0 -0
  178. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_op_alias.py +0 -0
  179. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_op_class_engine_binding.py +0 -0
  180. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_op_ctx_arity_paths.py +0 -0
  181. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_op_ctx_attributes.py +0 -0
  182. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_op_ctx_core_crud_integration.py +0 -0
  183. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_op_ctx_dynamic_attach.py +0 -0
  184. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_op_ctx_persist_options.py +0 -0
  185. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_opspec_effects.py +0 -0
  186. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_postgres_engine_errors.py +0 -0
  187. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_postgres_env_vars.py +0 -0
  188. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_relationship_alias_cols.py +0 -0
  189. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_request_body_schema.py +0 -0
  190. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_request_response_examples.py +0 -0
  191. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_resolver_interning_warmup.py +0 -0
  192. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_resolver_precedence.py +0 -0
  193. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_response_parity.py +0 -0
  194. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_response_rest.py +0 -0
  195. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_response_rpc.py +0 -0
  196. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_rest_all_default_op_verbs.py +0 -0
  197. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_rest_bulk_delete_suppresses_clear.py +0 -0
  198. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_rest_no_schema_jsonable.py +0 -0
  199. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_rest_operation_id_uniqueness.py +0 -0
  200. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_rest_rpc_parity_default_ops.py +0 -0
  201. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_rest_rpc_prefixes.py +0 -0
  202. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_rest_rpc_symmetry.py +0 -0
  203. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_router_compatibility_shims.py +0 -0
  204. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_rpc_all_default_op_verbs.py +0 -0
  205. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_rpc_default_ops.py +0 -0
  206. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_schema_ctx_attributes.py +0 -0
  207. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_schema_ctx_plain_class.py +0 -0
  208. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_schema_spec_presence.py +0 -0
  209. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_schemas_binding.py +0 -0
  210. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_security_per_route.py +0 -0
  211. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_should_wire_canonical.py +0 -0
  212. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_spec_api.py +0 -0
  213. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_spec_app.py +0 -0
  214. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_spec_column.py +0 -0
  215. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_spec_engine.py +0 -0
  216. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_spec_field.py +0 -0
  217. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_spec_hook.py +0 -0
  218. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_spec_io.py +0 -0
  219. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_spec_op.py +0 -0
  220. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_spec_storage.py +0 -0
  221. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_spec_table.py +0 -0
  222. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_sqlite_attachments.py +0 -0
  223. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_sqlite_uuid_type.py +0 -0
  224. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_stdapi_request_injection.py +0 -0
  225. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_storage_spec_attributes.py +0 -0
  226. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_sys_handler_crud.py +0 -0
  227. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_sys_run_rollback.py +0 -0
  228. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_sys_tx_async_begin.py +0 -0
  229. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_sys_tx_begin.py +0 -0
  230. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_sys_tx_commit.py +0 -0
  231. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_table_base_exports.py +0 -0
  232. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_table_collect_spec.py +0 -0
  233. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_table_columns_namespace.py +0 -0
  234. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_table_namespace_init.py +0 -0
  235. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_table_namespace_isolation.py +0 -0
  236. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_tigrbl_api_app_configuration.py +0 -0
  237. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_tigrbl_api_app_instantiation.py +0 -0
  238. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_tigrbl_api_app_subclass_definition.py +0 -0
  239. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_tigrbl_api_configuration.py +0 -0
  240. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_tigrbl_api_instantiation.py +0 -0
  241. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_tigrbl_api_subclass_definition.py +0 -0
  242. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_tigrbl_app_configuration.py +0 -0
  243. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_tigrbl_app_event_handlers.py +0 -0
  244. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_tigrbl_app_instantiation.py +0 -0
  245. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_tigrbl_app_subclass_definition.py +0 -0
  246. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_v3_favicon_endpoint.py +0 -0
  247. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_v3_healthz_endpoint.py +0 -0
  248. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_v3_op_alias.py +0 -0
  249. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_v3_op_ctx_attributes.py +0 -0
  250. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_v3_schemas_and_decorators.py +0 -0
  251. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_v3_storage_spec_attributes.py +0 -0
  252. {tigrbl_tests-0.3.7.dev1 → tigrbl_tests-0.3.7.dev3}/tests/unit/test_verbosity.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tigrbl_tests
3
- Version: 0.3.7.dev1
3
+ Version: 0.3.7.dev3
4
4
  Summary: Test suite and fixtures for the Tigrbl framework.
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tigrbl_tests"
3
- version = "0.3.7.dev1"
3
+ version = "0.3.7.dev3"
4
4
  description = "Test suite and fixtures for the Tigrbl framework."
5
5
  license = "Apache-2.0"
6
6
  readme = "README.md"
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- from tigrbl.transport.request import Headers, Request
3
+ from tigrbl.headers import Headers
4
+ from tigrbl.requests import Request
4
5
 
5
6
 
6
7
  def test_request_headers_support_dot_notation_access_and_assignment() -> None:
@@ -4,8 +4,8 @@ import json
4
4
 
5
5
  import pytest
6
6
 
7
- from tigrbl.response.stdapi import Response
8
- from tigrbl.transport.request import Request
7
+ from tigrbl.responses import Response
8
+ from tigrbl.requests import Request
9
9
 
10
10
 
11
11
  def _make_request(
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+
5
+ import pytest
6
+
7
+ from tigrbl.requests import Request
8
+
9
+
10
+ def _make_request(*, headers: dict[str, str], body: bytes = b"") -> Request:
11
+ return Request(
12
+ method="POST",
13
+ path="/session",
14
+ headers=headers,
15
+ query={},
16
+ path_params={},
17
+ body=body,
18
+ scope={"client": ("203.0.113.10", 443)},
19
+ )
20
+
21
+
22
+ def test_request_headers_and_cookies_support_nested_dot_notation_access() -> None:
23
+ request = _make_request(
24
+ headers={
25
+ "Authorization": "Bearer access-token",
26
+ "Cookie": "sid=session-token; tenant=acme",
27
+ }
28
+ )
29
+
30
+ assert request.headers.authorization == "Bearer access-token"
31
+ assert request.headers.cookie.sid == "session-token"
32
+ assert request.headers.cookie.tenant == "acme"
33
+
34
+
35
+ @pytest.mark.asyncio()
36
+ async def test_request_exposes_json_and_dot_notation_bearer_conveniences() -> None:
37
+ request = _make_request(
38
+ headers={"Authorization": "Bearer access-token"},
39
+ body=json.dumps({"ok": True}).encode("utf-8"),
40
+ )
41
+
42
+ assert request.json() == {"ok": True}
43
+ assert await request.json() == {"ok": True}
44
+ assert request.bearer_token == "access-token"
45
+ assert request.session_token == "access-token"
46
+
47
+
48
+ def test_request_session_token_falls_back_to_cookie_and_client_ip_attribute() -> None:
49
+ request = _make_request(headers={"Cookie": "sid=session-token"})
50
+
51
+ assert request.session_token == "session-token"
52
+ assert request.client.ip == "203.0.113.10"
53
+
54
+
55
+ def test_request_exposes_b64url_helpers_via_dot_notation() -> None:
56
+ request = _make_request(headers={})
57
+
58
+ token = request.b64url_encode(b'{"alg":"HS256"}')
59
+
60
+ assert token == "eyJhbGciOiJIUzI1NiJ9"
61
+ assert request.b64url_decode(token) == b'{"alg":"HS256"}'
@@ -0,0 +1,37 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+
5
+ import pytest
6
+
7
+ from tigrbl.requests import Request
8
+
9
+
10
+ def _make_request(path: str, body: bytes | None = None) -> Request:
11
+ return Request(
12
+ method="POST",
13
+ path=path,
14
+ headers={"content-type": "application/json"},
15
+ query={},
16
+ path_params={},
17
+ body=body or b"",
18
+ )
19
+
20
+
21
+ @pytest.mark.asyncio()
22
+ async def test_request_supports_request_url_path_and_body_and_async_json() -> None:
23
+ req = _make_request("/users/42", json.dumps({"id": 42}).encode("utf-8"))
24
+
25
+ assert req.url.path == "/users/42"
26
+ assert req.body == b'{"id": 42}'
27
+ assert await req.json() == {"id": 42}
28
+
29
+
30
+ def test_request_json_is_usable_without_await_for_blocking_style() -> None:
31
+ req = _make_request("/users", json.dumps({"ok": True, "id": 1}).encode("utf-8"))
32
+
33
+ payload = req.json()
34
+
35
+ assert payload["ok"] is True
36
+ assert payload.get("id") == 1
37
+ assert dict(payload) == {"ok": True, "id": 1}
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- from tigrbl.response.stdapi import Headers, Response
3
+ from tigrbl.headers import Headers
4
+ from tigrbl.responses import Response
4
5
 
5
6
 
6
7
  def test_response_headers_support_dot_notation_access_and_assignment() -> None:
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+
3
+ from tigrbl.responses import Response
4
+
5
+
6
+ def test_response_supports_instance_json_method_for_body_payload() -> None:
7
+ response = Response(
8
+ status_code=200,
9
+ headers=[("content-type", "application/json; charset=utf-8")],
10
+ body=b'{"ok":true,"count":1}',
11
+ )
12
+
13
+ assert response.json() == {"ok": True, "count": 1}
14
+
15
+
16
+ def test_response_headers_and_cookies_support_dot_notation() -> None:
17
+ response = Response(
18
+ status_code=200,
19
+ headers=[
20
+ ("x-request-id", "req-123"),
21
+ ("set-cookie", "sid=session-token; Path=/"),
22
+ ],
23
+ body=b"",
24
+ )
25
+
26
+ assert response.headers_map.x_request_id == "req-123"
27
+ assert response.cookies.sid == "session-token"
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from tigrbl.security import APIKey, HTTPBearer
4
- from tigrbl.transport.request import Request
4
+ from tigrbl.requests import Request
5
5
 
6
6
 
7
7
  def test_http_bearer_reads_authorization_from_request_headers_attribute() -> None:
@@ -1,5 +1,5 @@
1
1
  from tigrbl import response_ctx
2
- from tigrbl.response.types import ResponseSpec
2
+ from tigrbl.responses.types import ResponseSpec
3
3
 
4
4
 
5
5
  def test_response_ctx_internal_binding_on_function():
@@ -8,8 +8,8 @@ from tigrbl.bindings import (
8
8
  register_rpc,
9
9
  )
10
10
  from tigrbl.op.mro_collect import mro_collect_decorated_ops
11
- from tigrbl.response import response_ctx, render_template
12
- from tigrbl.response.shortcuts import (
11
+ from tigrbl.responses import response_ctx, render_template
12
+ from tigrbl.responses.shortcuts import (
13
13
  as_file,
14
14
  as_html,
15
15
  as_json,
@@ -19,7 +19,7 @@ from tigrbl.response.shortcuts import (
19
19
  )
20
20
  from pydantic import BaseModel
21
21
  from typing import get_args
22
- from tigrbl.response.types import ResponseKind
22
+ from tigrbl.responses.types import ResponseKind
23
23
 
24
24
 
25
25
  RESPONSE_KINDS = get_args(ResponseKind)
@@ -5,7 +5,7 @@ from httpx import ASGITransport, Client
5
5
 
6
6
  from tigrbl.op.mro_collect import mro_collect_decorated_ops
7
7
  from tigrbl.op import op_ctx
8
- from tigrbl.response.shortcuts import as_file
8
+ from tigrbl.responses.shortcuts import as_file
9
9
  from tigrbl.bindings import (
10
10
  build_hooks,
11
11
  build_handlers,
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
  import pytest
3
3
  from tigrbl import alias_ctx
4
- from tigrbl.response import response_ctx
4
+ from tigrbl.responses import response_ctx
5
5
  from tigrbl.engine.shortcuts import engine as build_engine, mem
6
6
  from tigrbl.orm.mixins import GUIDPk
7
7
  from tigrbl.orm.tables import Base
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
  from types import SimpleNamespace
3
3
 
4
- from tigrbl.response import (
4
+ from tigrbl.responses import (
5
5
  ResponseSpec,
6
6
  get_attached_response_spec,
7
7
  infer_hints,
@@ -3,7 +3,7 @@ from types import SimpleNamespace
3
3
  import pytest
4
4
 
5
5
  from tigrbl.op.types import OpSpec
6
- from tigrbl.response.types import ResponseSpec, TemplateSpec
6
+ from tigrbl.responses.types import ResponseSpec, TemplateSpec
7
7
  from tigrbl.system.diagnostics import _build_kernelz_endpoint
8
8
 
9
9
  from .response_utils import RESPONSE_KINDS
@@ -9,7 +9,7 @@ from tigrbl import TigrblApp
9
9
  from tigrbl.bindings import rpc_call
10
10
  from tigrbl.system.diagnostics import _build_kernelz_endpoint
11
11
  from tigrbl.runtime.kernel import _default_kernel as K
12
- from tigrbl.response import render_template
12
+ from tigrbl.responses import render_template
13
13
 
14
14
  from .response_utils import build_model_for_response, build_model_for_jinja_response
15
15
 
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
  import pytest
3
3
 
4
- from tigrbl.response import render_template
4
+ from tigrbl.responses import render_template
5
5
 
6
6
  pytest.importorskip("jinja2")
7
7
 
@@ -8,7 +8,7 @@ import types
8
8
  from uuid import uuid4
9
9
 
10
10
 
11
- from tigrbl.response.shortcuts import as_json
11
+ from tigrbl.responses.shortcuts import as_json
12
12
 
13
13
 
14
14
  def test_as_json_serializes_uuid() -> None:
@@ -27,7 +27,7 @@ def test_as_json_serializes_bytes() -> None:
27
27
 
28
28
 
29
29
  def test_as_json_fallbacks_when_orjson_unsupported(monkeypatch) -> None:
30
- import tigrbl.response.shortcuts as shortcuts
30
+ import tigrbl.responses.shortcuts as shortcuts
31
31
 
32
32
  original_orjson = sys.modules.get("orjson")
33
33
  fake_orjson = types.SimpleNamespace(
@@ -0,0 +1,269 @@
1
+ from __future__ import annotations
2
+
3
+ import io
4
+
5
+ import pytest
6
+
7
+ from tigrbl.types import APIRouter, Request, Response
8
+
9
+
10
+ @pytest.mark.asyncio()
11
+ async def test_asgi_http_scope_dispatches_with_query_and_body() -> None:
12
+ app = APIRouter()
13
+
14
+ @app.post("/echo")
15
+ async def echo(request: Request) -> dict[str, object]:
16
+ return {
17
+ "method": request.method,
18
+ "query": request.query,
19
+ "body": request.body.decode("utf-8"),
20
+ }
21
+
22
+ messages: list[dict[str, object]] = []
23
+
24
+ request_messages = iter(
25
+ [
26
+ {
27
+ "type": "http.request",
28
+ "body": b'{"hello":"world"}',
29
+ "more_body": False,
30
+ }
31
+ ]
32
+ )
33
+
34
+ async def receive() -> dict[str, object]:
35
+ return next(request_messages)
36
+
37
+ async def send(message: dict[str, object]) -> None:
38
+ messages.append(message)
39
+
40
+ await app._asgi_app(
41
+ {
42
+ "type": "http",
43
+ "method": "POST",
44
+ "path": "/echo",
45
+ "query_string": b"x=1&x=2",
46
+ "headers": [(b"content-type", b"application/json")],
47
+ },
48
+ receive,
49
+ send,
50
+ )
51
+
52
+ assert messages[0]["type"] == "http.response.start"
53
+ assert messages[0]["status"] == 200
54
+ assert messages[1]["type"] == "http.response.body"
55
+ assert (
56
+ messages[1]["body"]
57
+ == b'{"method":"POST","query":{"x":["1","2"]},"body":"{\\"hello\\":\\"world\\"}"}'
58
+ )
59
+
60
+
61
+ @pytest.mark.asyncio()
62
+ async def test_asgi_non_http_scope_returns_500() -> None:
63
+ app = APIRouter()
64
+ messages: list[dict[str, object]] = []
65
+
66
+ async def receive() -> dict[str, object]:
67
+ return {"type": "websocket.receive", "text": "ignored"}
68
+
69
+ async def send(message: dict[str, object]) -> None:
70
+ messages.append(message)
71
+
72
+ await app._asgi_app({"type": "websocket"}, receive, send)
73
+
74
+ assert messages == [
75
+ {"type": "http.response.start", "status": 500, "headers": []},
76
+ {"type": "http.response.body", "body": b""},
77
+ ]
78
+
79
+
80
+ @pytest.mark.asyncio()
81
+ async def test_asgi_204_response_omits_body_and_content_length() -> None:
82
+ app = APIRouter()
83
+
84
+ @app.delete("/items/{item_id}", status_code=204)
85
+ def delete_item(item_id: str) -> None:
86
+ assert item_id == "1"
87
+ return None
88
+
89
+ messages: list[dict[str, object]] = []
90
+
91
+ request_messages = iter([{"type": "http.request", "body": b"", "more_body": False}])
92
+
93
+ async def receive() -> dict[str, object]:
94
+ return next(request_messages)
95
+
96
+ async def send(message: dict[str, object]) -> None:
97
+ messages.append(message)
98
+
99
+ await app._asgi_app(
100
+ {
101
+ "type": "http",
102
+ "method": "DELETE",
103
+ "path": "/items/1",
104
+ "query_string": b"",
105
+ "headers": [],
106
+ },
107
+ receive,
108
+ send,
109
+ )
110
+
111
+ assert messages[0]["type"] == "http.response.start"
112
+ assert messages[0]["status"] == 204
113
+ assert (b"content-length", b"0") not in messages[0]["headers"]
114
+ assert messages[1] == {
115
+ "type": "http.response.body",
116
+ "body": b"",
117
+ "more_body": False,
118
+ }
119
+
120
+
121
+ @pytest.mark.asyncio()
122
+ async def test_asgi_head_response_strips_body_and_entity_headers() -> None:
123
+ app = APIRouter()
124
+
125
+ @app.get("/items")
126
+ def list_items() -> dict[str, str]:
127
+ return {"ok": "yes"}
128
+
129
+ messages: list[dict[str, object]] = []
130
+
131
+ request_messages = iter([{"type": "http.request", "body": b"", "more_body": False}])
132
+
133
+ async def receive() -> dict[str, object]:
134
+ return next(request_messages)
135
+
136
+ async def send(message: dict[str, object]) -> None:
137
+ messages.append(message)
138
+
139
+ await app._asgi_app(
140
+ {
141
+ "type": "http",
142
+ "method": "HEAD",
143
+ "path": "/items",
144
+ "query_string": b"",
145
+ "headers": [],
146
+ },
147
+ receive,
148
+ send,
149
+ )
150
+
151
+ assert messages[0]["type"] == "http.response.start"
152
+ start_headers = dict(messages[0]["headers"])
153
+ assert b"content-length" not in start_headers
154
+ assert b"content-type" not in start_headers
155
+ assert b"transfer-encoding" not in start_headers
156
+ assert messages[1] == {
157
+ "type": "http.response.body",
158
+ "body": b"",
159
+ "more_body": False,
160
+ }
161
+
162
+
163
+ def test_wsgi_205_response_strips_body_and_entity_headers() -> None:
164
+ app = APIRouter()
165
+
166
+ @app.get("/reset", status_code=205)
167
+ def reset() -> dict[str, str]:
168
+ return {"reset": "ok"}
169
+
170
+ called: dict[str, object] = {}
171
+
172
+ def start_response(status: str, headers: list[tuple[str, str]]) -> None:
173
+ called["status"] = status
174
+ called["headers"] = headers
175
+
176
+ response_chunks = app._wsgi_app(
177
+ {
178
+ "REQUEST_METHOD": "GET",
179
+ "PATH_INFO": "/reset",
180
+ "QUERY_STRING": "",
181
+ "CONTENT_LENGTH": "0",
182
+ "wsgi.input": io.BytesIO(b""),
183
+ },
184
+ start_response,
185
+ )
186
+
187
+ headers = dict(called["headers"])
188
+ assert called["status"] == "205 Reset Content"
189
+ assert "content-length" not in headers
190
+ assert "content-type" not in headers
191
+ assert "transfer-encoding" not in headers
192
+ assert response_chunks == [b""]
193
+
194
+
195
+ def test_wsgi_recomputes_stale_content_length() -> None:
196
+ app = APIRouter()
197
+
198
+ @app.get("/raw")
199
+ def raw() -> object:
200
+ return Response(
201
+ body=b"hello",
202
+ headers=[("content-type", "text/plain"), ("content-length", "999")],
203
+ )
204
+
205
+ called: dict[str, object] = {}
206
+
207
+ def start_response(status: str, headers: list[tuple[str, str]]) -> None:
208
+ called["status"] = status
209
+ called["headers"] = headers
210
+
211
+ response_chunks = app._wsgi_app(
212
+ {
213
+ "REQUEST_METHOD": "GET",
214
+ "PATH_INFO": "/raw",
215
+ "QUERY_STRING": "",
216
+ "CONTENT_LENGTH": "0",
217
+ "wsgi.input": io.BytesIO(b""),
218
+ },
219
+ start_response,
220
+ )
221
+
222
+ headers = dict(called["headers"])
223
+ assert called["status"] == "200 OK"
224
+ assert headers["content-length"] == "5"
225
+ assert response_chunks == [b"hello"]
226
+
227
+
228
+ def test_wsgi_dispatch_reads_body_and_query() -> None:
229
+ app = APIRouter()
230
+
231
+ @app.post("/echo")
232
+ def echo(request: Request) -> dict[str, object]:
233
+ return {
234
+ "path": request.path,
235
+ "query": request.query,
236
+ "body": request.body.decode("utf-8"),
237
+ "script_name": request.script_name,
238
+ }
239
+
240
+ called: dict[str, object] = {}
241
+
242
+ def start_response(status: str, headers: list[tuple[str, str]]) -> None:
243
+ called["status"] = status
244
+ called["headers"] = headers
245
+
246
+ response_chunks = app._wsgi_app(
247
+ {
248
+ "REQUEST_METHOD": "POST",
249
+ "PATH_INFO": "/echo",
250
+ "SCRIPT_NAME": "/v1",
251
+ "QUERY_STRING": "a=1&a=2",
252
+ "CONTENT_TYPE": "application/json",
253
+ "CONTENT_LENGTH": "7",
254
+ "wsgi.input": io.BytesIO(b'{"a":1}'),
255
+ },
256
+ start_response,
257
+ )
258
+
259
+ assert called["status"] == "200 OK"
260
+ assert response_chunks == [
261
+ b'{"path":"/echo","query":{"a":["1","2"]},"body":"{\\"a\\":1}","script_name":"/v1"}'
262
+ ]
263
+
264
+
265
+ def test_invalid_asgi_wsgi_invocation_raises_type_error() -> None:
266
+ app = APIRouter()
267
+
268
+ with pytest.raises(TypeError, match="Invalid ASGI/WSGI invocation"):
269
+ app("not-a-scope")
@@ -1,121 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import io
4
-
5
- import pytest
6
-
7
- from tigrbl.types import APIRouter, Request
8
-
9
-
10
- @pytest.mark.asyncio()
11
- async def test_asgi_http_scope_dispatches_with_query_and_body() -> None:
12
- app = APIRouter()
13
-
14
- @app.post("/echo")
15
- async def echo(request: Request) -> dict[str, object]:
16
- return {
17
- "method": request.method,
18
- "query": request.query,
19
- "body": request.body.decode("utf-8"),
20
- }
21
-
22
- messages: list[dict[str, object]] = []
23
-
24
- request_messages = iter(
25
- [
26
- {
27
- "type": "http.request",
28
- "body": b'{"hello":"world"}',
29
- "more_body": False,
30
- }
31
- ]
32
- )
33
-
34
- async def receive() -> dict[str, object]:
35
- return next(request_messages)
36
-
37
- async def send(message: dict[str, object]) -> None:
38
- messages.append(message)
39
-
40
- await app._asgi_app(
41
- {
42
- "type": "http",
43
- "method": "POST",
44
- "path": "/echo",
45
- "query_string": b"x=1&x=2",
46
- "headers": [(b"content-type", b"application/json")],
47
- },
48
- receive,
49
- send,
50
- )
51
-
52
- assert messages[0]["type"] == "http.response.start"
53
- assert messages[0]["status"] == 200
54
- assert messages[1]["type"] == "http.response.body"
55
- assert (
56
- messages[1]["body"]
57
- == b'{"method":"POST","query":{"x":["1","2"]},"body":"{\\"hello\\":\\"world\\"}"}'
58
- )
59
-
60
-
61
- @pytest.mark.asyncio()
62
- async def test_asgi_non_http_scope_returns_500() -> None:
63
- app = APIRouter()
64
- messages: list[dict[str, object]] = []
65
-
66
- async def receive() -> dict[str, object]:
67
- return {"type": "websocket.receive", "text": "ignored"}
68
-
69
- async def send(message: dict[str, object]) -> None:
70
- messages.append(message)
71
-
72
- await app._asgi_app({"type": "websocket"}, receive, send)
73
-
74
- assert messages == [
75
- {"type": "http.response.start", "status": 500, "headers": []},
76
- {"type": "http.response.body", "body": b""},
77
- ]
78
-
79
-
80
- def test_wsgi_dispatch_reads_body_and_query() -> None:
81
- app = APIRouter()
82
-
83
- @app.post("/echo")
84
- def echo(request: Request) -> dict[str, object]:
85
- return {
86
- "path": request.path,
87
- "query": request.query,
88
- "body": request.body.decode("utf-8"),
89
- "script_name": request.script_name,
90
- }
91
-
92
- called: dict[str, object] = {}
93
-
94
- def start_response(status: str, headers: list[tuple[str, str]]) -> None:
95
- called["status"] = status
96
- called["headers"] = headers
97
-
98
- response_chunks = app._wsgi_app(
99
- {
100
- "REQUEST_METHOD": "POST",
101
- "PATH_INFO": "/echo",
102
- "SCRIPT_NAME": "/v1",
103
- "QUERY_STRING": "a=1&a=2",
104
- "CONTENT_TYPE": "application/json",
105
- "CONTENT_LENGTH": "7",
106
- "wsgi.input": io.BytesIO(b'{"a":1}'),
107
- },
108
- start_response,
109
- )
110
-
111
- assert called["status"] == "200 OK"
112
- assert response_chunks == [
113
- b'{"path":"/echo","query":{"a":["1","2"]},"body":"{\\"a\\":1}","script_name":"/v1"}'
114
- ]
115
-
116
-
117
- def test_invalid_asgi_wsgi_invocation_raises_type_error() -> None:
118
- app = APIRouter()
119
-
120
- with pytest.raises(TypeError, match="Invalid ASGI/WSGI invocation"):
121
- app("not-a-scope")