Skip to content

Commit 44ad6f0

Browse files
committed
Add test case
1 parent 0129a72 commit 44ad6f0

1 file changed

Lines changed: 13 additions & 69 deletions

File tree

crates/vespera_macro/src/parser/operation.rs

Lines changed: 13 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
use std::collections::BTreeMap;
22

33
use syn::{FnArg, PatType, Type};
4-
use vespera_core::{
5-
route::{MediaType, Operation, Parameter, ParameterLocation, RequestBody, Response},
6-
schema::{Schema, SchemaRef},
7-
};
4+
use vespera_core::route::{MediaType, Operation, Parameter, ParameterLocation, Response};
85

96
use super::{
107
parameters::parse_function_parameter, path::extract_path_parameters,
@@ -160,49 +157,6 @@ pub fn build_operation_from_function(
160157
}
161158
}
162159

163-
// Fallback: if last arg is String/&str and no body yet, treat as text/plain body
164-
if request_body.is_none()
165-
&& let Some(FnArg::Typed(PatType { ty, .. })) = sig.inputs.last()
166-
{
167-
let is_string = match ty.as_ref() {
168-
Type::Path(type_path) => type_path
169-
.path
170-
.segments
171-
.last()
172-
.map(|s| s.ident == "String" || s.ident == "str")
173-
.unwrap_or(false),
174-
Type::Reference(type_ref) => {
175-
if let Type::Path(p) = type_ref.elem.as_ref() {
176-
p.path
177-
.segments
178-
.last()
179-
.map(|s| s.ident == "String" || s.ident == "str")
180-
.unwrap_or(false)
181-
} else {
182-
false
183-
}
184-
}
185-
_ => false,
186-
};
187-
188-
if is_string {
189-
let mut content = BTreeMap::new();
190-
content.insert(
191-
"text/plain".to_string(),
192-
MediaType {
193-
schema: Some(SchemaRef::Inline(Box::new(Schema::string()))),
194-
example: None,
195-
examples: None,
196-
},
197-
);
198-
request_body = Some(RequestBody {
199-
description: None,
200-
content,
201-
required: Some(true),
202-
});
203-
}
204-
}
205-
206160
// Parse return type - may return multiple responses (for Result types)
207161
let mut responses = parse_return_type(&sig.output, known_schemas, struct_definitions);
208162

@@ -588,8 +542,8 @@ mod tests {
588542
}
589543

590544
#[test]
591-
fn test_string_body_fallback() {
592-
// Test lines 100-107: String as last arg becomes text/plain body
545+
fn test_string_body() {
546+
// String arg is handled by parse_request_body via is_string_like()
593547
let op = build("fn upload(content: String) -> String", "/upload", None);
594548

595549
let body = op.request_body.as_ref().expect("request body expected");
@@ -604,32 +558,27 @@ mod tests {
604558
}
605559

606560
#[test]
607-
fn test_str_ref_body_fallback() {
608-
// Test lines 100-106: &str as last arg becomes text/plain body
561+
fn test_str_ref_body() {
562+
// &str arg is handled by parse_request_body via is_string_like()
609563
let op = build("fn upload(content: &str) -> String", "/upload", None);
610564

611565
let body = op.request_body.as_ref().expect("request body expected");
612566
assert!(body.content.contains_key("text/plain"));
613567
}
614568

615569
#[test]
616-
fn test_type_reference_with_string() {
617-
// Test lines 100-102, 104: Type::Reference branch - &String
570+
fn test_string_ref_body() {
571+
// &String arg is handled by parse_request_body via is_string_like()
618572
let op = build("fn upload(content: &String) -> String", "/upload", None);
619573

620-
// &String reference should be detected as string type
621-
// Line 101-102 checks if Type::Reference elem is a Path with String/str
622574
let body = op.request_body.as_ref().expect("request body expected");
623575
assert!(body.content.contains_key("text/plain"));
624576
}
625577

626578
#[test]
627-
fn test_non_string_last_arg_not_body() {
628-
// Test line 107: last arg that's NOT String/&str should NOT become body
579+
fn test_non_string_arg_not_body() {
580+
// Non-string args don't become request body
629581
let op = build("fn process(count: i32) -> String", "/process", None);
630-
631-
// i32 is not String/&str, so line 107 returns false, no body created
632-
// However, bare i32 without extractor is also ignored
633582
assert!(op.request_body.is_none());
634583
}
635584

@@ -651,38 +600,33 @@ mod tests {
651600

652601
#[test]
653602
fn test_reference_to_non_path_type_not_body() {
654-
// Test line 104: &(tuple) reference where elem is NOT a Path type
655-
// This hits the else branch at line 104 returning false
603+
// &(tuple) is not string-like, no body created
656604
let op = build("fn process(data: &(i32, i32)) -> String", "/process", None);
657-
// Reference to tuple is not String/&str, so no body created
658605
assert!(op.request_body.is_none());
659606
}
660607

661608
#[test]
662609
fn test_reference_to_slice_not_body() {
663-
// Test line 104: &[T] reference where elem is NOT a simple Path type
610+
// &[T] is not string-like, no body created
664611
let op = build("fn process(data: &[u8]) -> String", "/process", None);
665-
// Reference to slice is not String/&str
666612
assert!(op.request_body.is_none());
667613
}
668614

669615
#[test]
670616
fn test_tuple_type_not_body() {
671-
// Test line 107: tuple type (not Path, not Reference) returns false
617+
// Tuple type is not string-like, no body created
672618
let op = build(
673619
"fn process(data: (i32, String)) -> String",
674620
"/process",
675621
None,
676622
);
677-
// Tuple is neither Path nor Reference, hits line 107
678623
assert!(op.request_body.is_none());
679624
}
680625

681626
#[test]
682627
fn test_array_type_not_body() {
683-
// Test line 107: array type (not Path, not Reference) returns false
628+
// Array type is not string-like, no body created
684629
let op = build("fn process(data: [u8; 4]) -> String", "/process", None);
685-
// Array is neither Path nor Reference
686630
assert!(op.request_body.is_none());
687631
}
688632

0 commit comments

Comments
 (0)