-
Notifications
You must be signed in to change notification settings - Fork 697
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
example test for item discovery callback (new_item_found)
- Loading branch information
Showing
5 changed files
with
267 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
bindgen-tests/tests/parse_callbacks/item_discovery_callback/header_item_discovery.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Unions | ||
void function_using_anonymous_struct(struct {} arg0); | ||
|
||
struct NamedStruct { | ||
}; | ||
|
||
typedef struct NamedStruct AliasOfNamedStruct; | ||
|
||
|
||
// Unions | ||
void function_using_anonymous_union(union {} arg0); | ||
|
||
union NamedUnion { | ||
}; | ||
|
||
typedef union NamedUnion AliasOfNamedUnion; |
246 changes: 246 additions & 0 deletions
246
bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
use std::cell::RefCell; | ||
use std::collections::HashMap; | ||
use std::rc::Rc; | ||
|
||
use regex::Regex; | ||
|
||
use bindgen::callbacks::{DiscoveredItem, DiscoveredItemId, ParseCallbacks}; | ||
use bindgen::Builder; | ||
|
||
#[derive(Debug, Default)] | ||
struct ItemDiscovery(Rc<RefCell<ItemCache>>); | ||
|
||
pub type ItemCache = HashMap<DiscoveredItemId, DiscoveredItem>; | ||
|
||
impl ParseCallbacks for ItemDiscovery { | ||
fn new_item_found(&self, _id: DiscoveredItemId, _item: DiscoveredItem) { | ||
self.0.borrow_mut().insert(_id, _item); | ||
} | ||
} | ||
#[test] | ||
pub fn test_item_discovery_callback() { | ||
let discovery = ItemDiscovery::default(); | ||
let info = Rc::clone(&discovery.0); | ||
|
||
Builder::default() | ||
.header(concat!( | ||
env!("CARGO_MANIFEST_DIR"), | ||
"/tests/parse_callbacks/item_discovery_callback/header_item_discovery.h" | ||
)) | ||
.parse_callbacks(Box::new(discovery)) | ||
.generate() | ||
.expect("TODO: panic message"); | ||
|
||
let expected = ItemCache::from([ | ||
( | ||
DiscoveredItemId::new(10), | ||
DiscoveredItem::Struct { | ||
original_name: Some("NamedStruct".to_string()), | ||
final_name: "NamedStruct".to_string(), | ||
}, | ||
), | ||
( | ||
DiscoveredItemId::new(11), | ||
DiscoveredItem::Alias { | ||
alias_name: "AliasOfNamedStruct".to_string(), | ||
alias_for: DiscoveredItemId::new(10), | ||
}, | ||
), | ||
( | ||
DiscoveredItemId::new(20), | ||
DiscoveredItem::Union { | ||
original_name: Some("NamedUnion".to_string()), | ||
final_name: "NamedUnion".to_string(), | ||
}, | ||
), | ||
( | ||
DiscoveredItemId::new(21), | ||
DiscoveredItem::Alias { | ||
alias_name: "AliasOfNamedUnion".to_string(), | ||
alias_for: DiscoveredItemId::new(20), | ||
}, | ||
), | ||
( | ||
DiscoveredItemId::new(30), | ||
DiscoveredItem::Struct { | ||
original_name: None, | ||
final_name: "_bindgen_ty_*".to_string(), | ||
}, | ||
), | ||
( | ||
DiscoveredItemId::new(40), | ||
DiscoveredItem::Union { | ||
original_name: None, | ||
final_name: "_bindgen_ty_*".to_string(), | ||
}, | ||
), | ||
]); | ||
|
||
compare_item_caches(info.borrow().clone(), expected); | ||
} | ||
|
||
pub fn compare_item_caches(generated: ItemCache, expected: ItemCache) { | ||
// We can't use a simple Eq::eq comparison because of two reasons: | ||
// - anonymous structs/unions will have a final name generated by bindgen which may change | ||
// if the header file or the bindgen logic is altered | ||
// - aliases have a DiscoveredItemId that we can't directly compare for the same instability reasons | ||
for expected_item in expected.values() { | ||
let found = generated.iter().find(|(_generated_id, generated_item)| { | ||
compare_item_info( | ||
expected_item, | ||
generated_item, | ||
&expected, | ||
&generated, | ||
) | ||
}); | ||
|
||
if found.is_none() { | ||
panic!( | ||
"Missing Expected Item: {:#?}\n in {:#?}", | ||
expected_item, generated | ||
); | ||
} | ||
} | ||
} | ||
|
||
fn compare_item_info( | ||
expected_item: &DiscoveredItem, | ||
generated_item: &DiscoveredItem, | ||
expected: &ItemCache, | ||
generated: &ItemCache, | ||
) -> bool { | ||
if std::mem::discriminant(expected_item) != | ||
std::mem::discriminant(generated_item) | ||
{ | ||
return false; | ||
} | ||
|
||
match generated_item { | ||
DiscoveredItem::Struct { .. } => { | ||
compare_struct_info(expected_item, generated_item) | ||
} | ||
DiscoveredItem::Union { .. } => { | ||
compare_union_info(expected_item, generated_item) | ||
} | ||
DiscoveredItem::Alias { .. } => compare_alias_info( | ||
expected_item, | ||
generated_item, | ||
expected, | ||
generated, | ||
), | ||
} | ||
} | ||
|
||
pub fn compare_names(expected_name: &str, generated_name: &str) -> bool { | ||
if let Ok(regex) = Regex::new(expected_name) { | ||
regex.is_match(generated_name) | ||
} else { | ||
false | ||
} | ||
} | ||
|
||
pub fn compare_struct_info( | ||
expected_item: &DiscoveredItem, | ||
generated_item: &DiscoveredItem, | ||
) -> bool { | ||
let DiscoveredItem::Struct { | ||
original_name: expected_original_name, | ||
final_name: expected_final_name, | ||
} = expected_item | ||
else { | ||
unreachable!() | ||
}; | ||
|
||
let DiscoveredItem::Struct { | ||
original_name: generated_original_name, | ||
final_name: generated_final_name, | ||
} = generated_item | ||
else { | ||
unreachable!() | ||
}; | ||
|
||
if !compare_names(expected_final_name, generated_final_name) { | ||
return false; | ||
} | ||
|
||
match (expected_original_name, generated_original_name) { | ||
(None, None) => true, | ||
(Some(expected_original_name), Some(generated_original_name)) => { | ||
compare_names(expected_original_name, generated_original_name) | ||
} | ||
_ => false, | ||
} | ||
} | ||
|
||
pub fn compare_union_info( | ||
expected_item: &DiscoveredItem, | ||
generated_item: &DiscoveredItem, | ||
) -> bool { | ||
let DiscoveredItem::Union { | ||
original_name: expected_original_name, | ||
final_name: expected_final_name, | ||
} = expected_item | ||
else { | ||
unreachable!() | ||
}; | ||
|
||
let DiscoveredItem::Union { | ||
original_name: generated_original_name, | ||
final_name: generated_final_name, | ||
} = generated_item | ||
else { | ||
unreachable!() | ||
}; | ||
|
||
if !compare_names(expected_final_name, generated_final_name) { | ||
return false; | ||
} | ||
|
||
match (expected_original_name, generated_original_name) { | ||
(None, None) => true, | ||
(Some(expected_original_name), Some(generated_original_name)) => { | ||
compare_names(expected_original_name, generated_original_name) | ||
} | ||
_ => false, | ||
} | ||
} | ||
|
||
pub fn compare_alias_info( | ||
expected_item: &DiscoveredItem, | ||
generated_item: &DiscoveredItem, | ||
expected: &ItemCache, | ||
generated: &ItemCache, | ||
) -> bool { | ||
let DiscoveredItem::Alias { | ||
alias_name: expected_alias_name, | ||
alias_for: expected_alias_for, | ||
} = expected_item | ||
else { | ||
unreachable!() | ||
}; | ||
|
||
let DiscoveredItem::Alias { | ||
alias_name: generated_alias_name, | ||
alias_for: generated_alias_for, | ||
} = generated_item | ||
else { | ||
unreachable!() | ||
}; | ||
|
||
if !compare_names(expected_alias_name, generated_alias_name) { | ||
return false; | ||
} | ||
|
||
// Assumes correct test definition | ||
let expected_aliased = expected.get(expected_alias_for).unwrap(); | ||
|
||
// We must have the aliased type in the cache | ||
let generated_aliased = | ||
if let Some(generated_aliased) = generated.get(generated_alias_for) { | ||
generated_aliased | ||
} else { | ||
return false; | ||
}; | ||
|
||
compare_item_info(expected_aliased, generated_aliased, expected, generated) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
mod item_discovery_callback; | ||
|
||
use bindgen::callbacks::*; | ||
use bindgen::FieldVisibilityKind; | ||
|
||
|