Skip to content

Commit 4cbb7b5

Browse files
Add regression test for bearcove#53. Closes bearcove#53.
1 parent 5429783 commit 4cbb7b5

1 file changed

Lines changed: 107 additions & 0 deletions

File tree

crates/facet-styx/src/tests.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,3 +728,110 @@ fn test_map_type_ref_spacing() {
728728
output
729729
);
730730
}
731+
732+
/// Test that metadata containers with non-optional Span field work.
733+
/// This is a regression test for issue #53 where Meta<String> with
734+
/// `span: Span` (not Option<Span>) failed with "missing field `span`".
735+
#[test]
736+
fn test_metadata_container_non_optional_span() {
737+
use facet_reflect::Span;
738+
739+
#[derive(Debug, Facet)]
740+
#[facet(metadata_container)]
741+
struct Meta<T> {
742+
pub value: T,
743+
#[facet(metadata = "span")]
744+
pub span: Span,
745+
}
746+
747+
#[derive(Debug, Facet)]
748+
struct Config {
749+
name: Meta<String>,
750+
}
751+
752+
let source = r#"{name "hello"}"#;
753+
let result: Result<Config, _> = from_str(source);
754+
match result {
755+
Ok(config) => {
756+
eprintln!("Success: {:?}", config);
757+
assert_eq!(config.name.value, "hello");
758+
// Span should cover the "hello" string (offset 6, len 7 including quotes)
759+
assert_eq!(config.name.span.offset, 6);
760+
assert_eq!(config.name.span.len, 7);
761+
}
762+
Err(e) => {
763+
panic!("Failed to parse: {}", e.render("<test>", source));
764+
}
765+
}
766+
}
767+
768+
/// Test that metadata containers with non-optional Span work as map keys.
769+
/// This is a more specific test for issue #53 where Meta<String> as a
770+
/// flattened map key might fail.
771+
#[test]
772+
fn test_metadata_container_as_map_key() {
773+
use facet_reflect::Span;
774+
use indexmap::IndexMap;
775+
776+
#[derive(Debug, Facet)]
777+
#[facet(metadata_container)]
778+
struct Meta<T> {
779+
pub value: T,
780+
#[facet(metadata = "span")]
781+
pub span: Span,
782+
}
783+
784+
impl<T: PartialEq> PartialEq for Meta<T> {
785+
fn eq(&self, other: &Self) -> bool {
786+
self.value == other.value
787+
}
788+
}
789+
impl<T: Eq> Eq for Meta<T> {}
790+
impl<T: std::hash::Hash> std::hash::Hash for Meta<T> {
791+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
792+
self.value.hash(state);
793+
}
794+
}
795+
796+
#[derive(Debug, Facet)]
797+
struct QueryFile {
798+
#[facet(flatten)]
799+
queries: IndexMap<Meta<String>, Decl>,
800+
}
801+
802+
#[derive(Debug, Facet)]
803+
#[facet(rename_all = "lowercase")]
804+
#[repr(u8)]
805+
enum Decl {
806+
Select(Select),
807+
}
808+
809+
#[derive(Debug, Facet)]
810+
struct Select {
811+
from: String,
812+
}
813+
814+
let source = r#"{
815+
GetUsers @select{from users}
816+
GetPosts @select{from posts}
817+
}"#;
818+
819+
let result: Result<QueryFile, _> = from_str(source);
820+
match result {
821+
Ok(file) => {
822+
eprintln!("Success: {:?}", file);
823+
assert_eq!(file.queries.len(), 2);
824+
825+
let keys: Vec<_> = file.queries.keys().collect();
826+
assert_eq!(keys[0].value, "GetUsers");
827+
assert_eq!(keys[1].value, "GetPosts");
828+
829+
// Check that spans were captured
830+
eprintln!("GetUsers span: {:?}", keys[0].span);
831+
eprintln!("GetPosts span: {:?}", keys[1].span);
832+
}
833+
Err(e) => {
834+
panic!("Failed to parse: {}", e.render("<test>", source));
835+
}
836+
}
837+
}

0 commit comments

Comments
 (0)