spikard 0.6.2 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +90 -508
  3. data/ext/spikard_rb/Cargo.lock +3287 -0
  4. data/ext/spikard_rb/Cargo.toml +1 -1
  5. data/ext/spikard_rb/extconf.rb +3 -3
  6. data/lib/spikard/app.rb +72 -49
  7. data/lib/spikard/background.rb +38 -7
  8. data/lib/spikard/testing.rb +42 -4
  9. data/lib/spikard/version.rb +1 -1
  10. data/sig/spikard.rbs +4 -0
  11. data/vendor/crates/spikard-bindings-shared/Cargo.toml +1 -1
  12. data/vendor/crates/spikard-bindings-shared/tests/config_extractor_behavior.rs +191 -0
  13. data/vendor/crates/spikard-core/Cargo.toml +1 -1
  14. data/vendor/crates/spikard-core/src/http.rs +1 -0
  15. data/vendor/crates/spikard-core/src/lifecycle.rs +63 -0
  16. data/vendor/crates/spikard-core/tests/bindings_response_tests.rs +136 -0
  17. data/vendor/crates/spikard-core/tests/di_dependency_defaults.rs +37 -0
  18. data/vendor/crates/spikard-core/tests/error_mapper.rs +761 -0
  19. data/vendor/crates/spikard-core/tests/parameters_edge_cases.rs +106 -0
  20. data/vendor/crates/spikard-core/tests/parameters_full.rs +701 -0
  21. data/vendor/crates/spikard-core/tests/parameters_schema_and_formats.rs +301 -0
  22. data/vendor/crates/spikard-core/tests/request_data_roundtrip.rs +67 -0
  23. data/vendor/crates/spikard-core/tests/validation_coverage.rs +250 -0
  24. data/vendor/crates/spikard-core/tests/validation_error_paths.rs +45 -0
  25. data/vendor/crates/spikard-http/Cargo.toml +1 -1
  26. data/vendor/crates/spikard-http/src/jsonrpc/http_handler.rs +502 -0
  27. data/vendor/crates/spikard-http/src/jsonrpc/method_registry.rs +648 -0
  28. data/vendor/crates/spikard-http/src/jsonrpc/mod.rs +58 -0
  29. data/vendor/crates/spikard-http/src/jsonrpc/protocol.rs +1207 -0
  30. data/vendor/crates/spikard-http/src/jsonrpc/router.rs +2262 -0
  31. data/vendor/crates/spikard-http/src/testing/test_client.rs +155 -2
  32. data/vendor/crates/spikard-http/src/testing.rs +171 -0
  33. data/vendor/crates/spikard-http/src/websocket.rs +79 -6
  34. data/vendor/crates/spikard-http/tests/auth_integration.rs +647 -0
  35. data/vendor/crates/spikard-http/tests/common/test_builders.rs +633 -0
  36. data/vendor/crates/spikard-http/tests/di_handler_error_responses.rs +162 -0
  37. data/vendor/crates/spikard-http/tests/middleware_stack_integration.rs +389 -0
  38. data/vendor/crates/spikard-http/tests/request_extraction_full.rs +513 -0
  39. data/vendor/crates/spikard-http/tests/server_auth_middleware_behavior.rs +244 -0
  40. data/vendor/crates/spikard-http/tests/server_configured_router_behavior.rs +200 -0
  41. data/vendor/crates/spikard-http/tests/server_cors_preflight.rs +82 -0
  42. data/vendor/crates/spikard-http/tests/server_handler_wrappers.rs +464 -0
  43. data/vendor/crates/spikard-http/tests/server_method_router_additional_behavior.rs +286 -0
  44. data/vendor/crates/spikard-http/tests/server_method_router_coverage.rs +118 -0
  45. data/vendor/crates/spikard-http/tests/server_middleware_behavior.rs +99 -0
  46. data/vendor/crates/spikard-http/tests/server_middleware_branches.rs +206 -0
  47. data/vendor/crates/spikard-http/tests/server_openapi_jsonrpc_static.rs +281 -0
  48. data/vendor/crates/spikard-http/tests/server_router_behavior.rs +121 -0
  49. data/vendor/crates/spikard-http/tests/sse_full_behavior.rs +584 -0
  50. data/vendor/crates/spikard-http/tests/sse_handler_behavior.rs +130 -0
  51. data/vendor/crates/spikard-http/tests/test_client_requests.rs +167 -0
  52. data/vendor/crates/spikard-http/tests/testing_helpers.rs +87 -0
  53. data/vendor/crates/spikard-http/tests/testing_module_coverage.rs +156 -0
  54. data/vendor/crates/spikard-http/tests/urlencoded_content_type.rs +82 -0
  55. data/vendor/crates/spikard-http/tests/websocket_full_behavior.rs +440 -0
  56. data/vendor/crates/spikard-http/tests/websocket_integration.rs +152 -0
  57. data/vendor/crates/spikard-rb/Cargo.toml +1 -1
  58. data/vendor/crates/spikard-rb/src/gvl.rs +80 -0
  59. data/vendor/crates/spikard-rb/src/handler.rs +12 -9
  60. data/vendor/crates/spikard-rb/src/lib.rs +137 -124
  61. data/vendor/crates/spikard-rb/src/request.rs +342 -0
  62. data/vendor/crates/spikard-rb/src/runtime/server_runner.rs +1 -8
  63. data/vendor/crates/spikard-rb/src/server.rs +1 -8
  64. data/vendor/crates/spikard-rb/src/testing/client.rs +168 -9
  65. data/vendor/crates/spikard-rb/src/websocket.rs +119 -30
  66. data/vendor/crates/spikard-rb-macros/Cargo.toml +14 -0
  67. data/vendor/crates/spikard-rb-macros/src/lib.rs +52 -0
  68. metadata +44 -1
@@ -0,0 +1,106 @@
1
+ use serde_json::json;
2
+ use spikard_core::parameters::ParameterValidator;
3
+ use std::collections::HashMap;
4
+
5
+ #[test]
6
+ fn test_header_underscores_are_normalized_to_hyphens() {
7
+ let schema = json!({
8
+ "type": "object",
9
+ "properties": {
10
+ "X_Request_ID": {
11
+ "type": "integer",
12
+ "source": "header"
13
+ }
14
+ },
15
+ "required": ["X_Request_ID"]
16
+ });
17
+ let validator = ParameterValidator::new(schema).expect("validator");
18
+
19
+ let mut headers = HashMap::new();
20
+ headers.insert("x-request-id".to_string(), "not-an-int".to_string());
21
+
22
+ let result =
23
+ validator.validate_and_extract(&json!({}), &HashMap::new(), &HashMap::new(), &headers, &HashMap::new());
24
+ let err = result.expect_err("expected type error");
25
+ assert_eq!(err.errors.len(), 1);
26
+ assert_eq!(err.errors[0].error_type, "int_parsing");
27
+ assert_eq!(err.errors[0].loc, vec!["headers", "x-request-id"]);
28
+ }
29
+
30
+ #[test]
31
+ fn test_query_boolean_empty_string_coerces_to_false() {
32
+ let schema = json!({
33
+ "type": "object",
34
+ "properties": {
35
+ "flag": { "type": "boolean", "source": "query" }
36
+ },
37
+ "required": ["flag"]
38
+ });
39
+ let validator = ParameterValidator::new(schema).expect("validator");
40
+
41
+ let mut raw_query_params = HashMap::new();
42
+ raw_query_params.insert("flag".to_string(), vec!["".to_string()]);
43
+
44
+ let extracted = validator.validate_and_extract(
45
+ &json!({}),
46
+ &raw_query_params,
47
+ &HashMap::new(),
48
+ &HashMap::new(),
49
+ &HashMap::new(),
50
+ );
51
+ let extracted = extracted.expect("expected success");
52
+ assert_eq!(extracted["flag"], false);
53
+ }
54
+
55
+ #[test]
56
+ fn test_query_time_format_accepts_rfc3339_full_time() {
57
+ let schema = json!({
58
+ "type": "object",
59
+ "properties": {
60
+ "meeting_time": { "type": "string", "format": "time", "source": "query" }
61
+ },
62
+ "required": ["meeting_time"]
63
+ });
64
+ let validator = ParameterValidator::new(schema).expect("validator");
65
+
66
+ let mut raw_query_params = HashMap::new();
67
+ raw_query_params.insert("meeting_time".to_string(), vec!["10:30:00Z".to_string()]);
68
+
69
+ let extracted = validator.validate_and_extract(
70
+ &json!({}),
71
+ &raw_query_params,
72
+ &HashMap::new(),
73
+ &HashMap::new(),
74
+ &HashMap::new(),
75
+ );
76
+ let extracted = extracted.expect("expected success");
77
+ assert_eq!(extracted["meeting_time"], "10:30:00Z");
78
+ }
79
+
80
+ #[test]
81
+ fn test_query_uuid_format_surfaces_uuid_parsing_error() {
82
+ let schema = json!({
83
+ "type": "object",
84
+ "properties": {
85
+ "id": { "type": "string", "format": "uuid", "source": "query" }
86
+ },
87
+ "required": ["id"]
88
+ });
89
+ let validator = ParameterValidator::new(schema).expect("validator");
90
+
91
+ let mut raw_query_params = HashMap::new();
92
+ raw_query_params.insert("id".to_string(), vec!["not-a-uuid".to_string()]);
93
+
94
+ let result = validator.validate_and_extract(
95
+ &json!({}),
96
+ &raw_query_params,
97
+ &HashMap::new(),
98
+ &HashMap::new(),
99
+ &HashMap::new(),
100
+ );
101
+ let err = result.expect_err("expected error");
102
+ assert_eq!(err.errors.len(), 1);
103
+ assert_eq!(err.errors[0].error_type, "uuid_parsing");
104
+ assert_eq!(err.errors[0].loc, vec!["query", "id"]);
105
+ assert!(err.errors[0].msg.contains("Input should be a valid UUID"));
106
+ }