Skip to content

Commit

Permalink
Extract a function for testing re-exports with matching names. (#71) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
obi1kenobi authored Feb 5, 2023
1 parent 3581e6b commit 29aee53
Showing 1 changed file with 53 additions and 48 deletions.
101 changes: 53 additions & 48 deletions src/indexed_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,54 @@ mod tests {
}
}

/// Allows testing for items with overlapping names, such as a function and a type
/// with the same name (which Rust considers in separate namespaces).
fn assert_duplicated_exported_items_match(
test_crate: &str,
expected_items_and_counts: &BTreeMap<&str, (usize, BTreeSet<&str>)>,
) {
let rustdoc = load_pregenerated_rustdoc(test_crate);
let indexed_crate = IndexedCrate::new(&rustdoc);

for (&expected_item_name, (expected_count, expected_importable_paths)) in
expected_items_and_counts
{
assert!(
!expected_item_name.contains(':'),
"only direct item names can be checked at the moment: {expected_item_name}"
);

let item_id_candidates = rustdoc
.index
.iter()
.filter_map(|(id, item)| {
(item.name.as_deref() == Some(expected_item_name)).then_some(id)
})
.collect_vec();
if item_id_candidates.len() != *expected_count {
panic!(
"Expected to find exactly one item with name {expected_item_name}, \
but found these matching IDs: {item_id_candidates:?}"
);
}
for item_id in item_id_candidates {
let actual_items: Vec<_> = indexed_crate
.publicly_importable_names(item_id)
.into_iter()
.map(|components| components.into_iter().join("::"))
.collect();
let deduplicated_actual_items: BTreeSet<_> =
actual_items.iter().map(|x| x.as_str()).collect();
assert_eq!(
actual_items.len(),
deduplicated_actual_items.len(),
"duplicates found: {actual_items:?}"
);
assert_eq!(expected_importable_paths, &deduplicated_actual_items);
}
}
}

#[test]
fn pub_inside_pub_crate_mod() {
let test_crate = "pub_inside_pub_crate_mod";
Expand Down Expand Up @@ -1237,60 +1285,17 @@ mod tests {
fn type_and_value_with_matching_names() {
let test_crate = "type_and_value_with_matching_names";
let expected_items = btreemap! {
"Foo" => btreeset![
"Foo" => (2, btreeset![
"type_and_value_with_matching_names::Foo",
"type_and_value_with_matching_names::nested::Foo",
],
"Bar" => btreeset![
]),
"Bar" => (2, btreeset![
"type_and_value_with_matching_names::Bar",
"type_and_value_with_matching_names::nested::Bar",
],
]),
};

let rustdoc = load_pregenerated_rustdoc(test_crate);
let indexed_crate = IndexedCrate::new(&rustdoc);

// We can't use the `assert_exported_items_match()` helper function,
// since it assumes that names are unique.
// This test case *specifically* tests the situation where a type and a value
// happen to have the same name.
//
// Instead, we implement the needed test logic directly.
for (&expected_item_name, expected_importable_paths) in &expected_items {
assert!(
!expected_item_name.contains(':'),
"only direct item names can be checked at the moment: {expected_item_name}"
);

let item_id_candidates = rustdoc
.index
.iter()
.filter_map(|(id, item)| {
(item.name.as_deref() == Some(expected_item_name)).then_some(id)
})
.collect_vec();
if item_id_candidates.len() != 2 {
panic!(
"Expected to find exactly two items with name {expected_item_name}, \
but found these matching IDs: {item_id_candidates:?}"
);
}
for item_id in item_id_candidates {
let actual_items: Vec<_> = indexed_crate
.publicly_importable_names(item_id)
.into_iter()
.map(|components| components.into_iter().join("::"))
.collect();
let deduplicated_actual_items: BTreeSet<_> =
actual_items.iter().map(|x| x.as_str()).collect();
assert_eq!(
actual_items.len(),
deduplicated_actual_items.len(),
"duplicates found: {actual_items:?}"
);
assert_eq!(expected_importable_paths, &deduplicated_actual_items);
}
}
assert_duplicated_exported_items_match(test_crate, &expected_items);
}
}
}

0 comments on commit 29aee53

Please sign in to comment.