|
10 | 10 |
|
11 | 11 | #[cfg(feature = "napi-support")] |
12 | 12 | use std::sync::Arc; |
| 13 | +use std::ffi::c_char; |
13 | 14 |
|
14 | 15 | #[cfg(feature = "napi-support")] |
15 | 16 | use http_handler::napi::{Request as NapiRequest, Response as NapiResponse}; |
@@ -95,7 +96,7 @@ impl FromNapiValue for PythonHandlerTarget { |
95 | 96 | check_status!(sys::napi_get_value_string_utf8( |
96 | 97 | env, |
97 | 98 | napi_val, |
98 | | - buffer.as_mut_ptr() as *mut i8, |
| 99 | + buffer.as_mut_ptr() as *mut c_char, |
99 | 100 | length + 1, |
100 | 101 | &mut length |
101 | 102 | )) |
@@ -142,7 +143,7 @@ impl ToNapiValue for PythonHandlerTarget { |
142 | 143 | unsafe { |
143 | 144 | check_status!(sys::napi_create_string_utf8( |
144 | 145 | env, |
145 | | - full_str.as_ptr() as *const i8, |
| 146 | + full_str.as_ptr() as *const c_char, |
146 | 147 | full_str.len() as isize, |
147 | 148 | &mut result |
148 | 149 | )) |
@@ -365,3 +366,106 @@ impl Task for PythonRequestTask { |
365 | 366 | Ok(Into::<NapiResponse>::into(output)) |
366 | 367 | } |
367 | 368 | } |
| 369 | + |
| 370 | +#[cfg(test)] |
| 371 | +mod tests { |
| 372 | + use super::*; |
| 373 | + |
| 374 | + #[test] |
| 375 | + fn test_python_handler_target_try_from_str_valid() { |
| 376 | + let target = PythonHandlerTarget::try_from("main:app").unwrap(); |
| 377 | + assert_eq!(target.file, "main"); |
| 378 | + assert_eq!(target.function, "app"); |
| 379 | + |
| 380 | + let target = PythonHandlerTarget::try_from("my_module:my_function").unwrap(); |
| 381 | + assert_eq!(target.file, "my_module"); |
| 382 | + assert_eq!(target.function, "my_function"); |
| 383 | + } |
| 384 | + |
| 385 | + #[test] |
| 386 | + fn test_python_handler_target_try_from_str_invalid() { |
| 387 | + // No colon |
| 388 | + let result = PythonHandlerTarget::try_from("invalid"); |
| 389 | + assert!(result.is_err()); |
| 390 | + assert_eq!(result.unwrap_err(), "Invalid format, expected \"file:function\""); |
| 391 | + |
| 392 | + // Multiple colons |
| 393 | + let result = PythonHandlerTarget::try_from("too:many:colons"); |
| 394 | + assert!(result.is_err()); |
| 395 | + assert_eq!(result.unwrap_err(), "Invalid format, expected \"file:function\""); |
| 396 | + |
| 397 | + // Empty string |
| 398 | + let result = PythonHandlerTarget::try_from(""); |
| 399 | + assert!(result.is_err()); |
| 400 | + assert_eq!(result.unwrap_err(), "Invalid format, expected \"file:function\""); |
| 401 | + |
| 402 | + // Only colon - this actually succeeds with empty file and function |
| 403 | + // The current implementation allows this: ":" -> file="", function="" |
| 404 | + let result = PythonHandlerTarget::try_from(":"); |
| 405 | + assert!(result.is_ok()); |
| 406 | + let target = result.unwrap(); |
| 407 | + assert_eq!(target.file, ""); |
| 408 | + assert_eq!(target.function, ""); |
| 409 | + |
| 410 | + // Test with empty parts in different ways |
| 411 | + let result = PythonHandlerTarget::try_from(":function"); |
| 412 | + assert!(result.is_ok()); |
| 413 | + let target = result.unwrap(); |
| 414 | + assert_eq!(target.file, ""); |
| 415 | + assert_eq!(target.function, "function"); |
| 416 | + |
| 417 | + let result = PythonHandlerTarget::try_from("file:"); |
| 418 | + assert!(result.is_ok()); |
| 419 | + let target = result.unwrap(); |
| 420 | + assert_eq!(target.file, "file"); |
| 421 | + assert_eq!(target.function, ""); |
| 422 | + } |
| 423 | + |
| 424 | + #[test] |
| 425 | + fn test_python_handler_target_from_string_conversion() { |
| 426 | + let target = PythonHandlerTarget { |
| 427 | + file: "test_module".to_string(), |
| 428 | + function: "test_function".to_string(), |
| 429 | + }; |
| 430 | + let result: String = target.into(); |
| 431 | + assert_eq!(result, "test_module:test_function"); |
| 432 | + } |
| 433 | + |
| 434 | + #[test] |
| 435 | + fn test_python_handler_target_default() { |
| 436 | + let target = PythonHandlerTarget::default(); |
| 437 | + assert_eq!(target.file, "main"); |
| 438 | + assert_eq!(target.function, "app"); |
| 439 | + } |
| 440 | + |
| 441 | + #[test] |
| 442 | + fn test_python_handler_target_debug_clone_eq_hash() { |
| 443 | + let target1 = PythonHandlerTarget { |
| 444 | + file: "test".to_string(), |
| 445 | + function: "app".to_string(), |
| 446 | + }; |
| 447 | + let target2 = target1.clone(); |
| 448 | + |
| 449 | + // Test Debug |
| 450 | + let debug_str = format!("{:?}", target1); |
| 451 | + assert!(debug_str.contains("test")); |
| 452 | + assert!(debug_str.contains("app")); |
| 453 | + |
| 454 | + // Test Clone and PartialEq |
| 455 | + assert_eq!(target1, target2); |
| 456 | + |
| 457 | + // Test inequality |
| 458 | + let target3 = PythonHandlerTarget { |
| 459 | + file: "different".to_string(), |
| 460 | + function: "app".to_string(), |
| 461 | + }; |
| 462 | + assert_ne!(target1, target3); |
| 463 | + |
| 464 | + // Test Hash by putting in a HashSet |
| 465 | + use std::collections::HashSet; |
| 466 | + let mut set = HashSet::new(); |
| 467 | + set.insert(target1); |
| 468 | + set.insert(target2); // Should not increase size due to equality |
| 469 | + assert_eq!(set.len(), 1); |
| 470 | + } |
| 471 | +} |
0 commit comments