devscout-rs 0.10.0

Fast code index for C# and TypeScript codebases -- map, find, refs, impact from the CLI.
use std::collections::BTreeSet;

use super::*;

const NAMESPACE_ROOTS: [&str; 3] = ["MassTransit", "Microsoft.Extensions", "System"];

fn qualified(name: &str) -> bool {
    name.contains('.')
        && NAMESPACE_ROOTS
            .iter()
            .any(|root| name == *root || name.starts_with(&format!("{root}.")))
}

fn is_type(name: &str) -> bool {
    type_entry(name).is_some()
}

#[test]
fn transport_facts_ac_1_no_entry_is_listed_twice() {
    let mut types = BTreeSet::new();
    for entry in TYPES {
        assert!(types.insert(entry.name), "{} twice", entry.name);
    }
    let mut simple_names = BTreeSet::new();
    for entry in TYPES {
        assert!(
            simple_names.insert((simple(entry.name), arity(entry.name))),
            "{} shares its simple name and arity",
            entry.name
        );
    }
    let mut overloads = BTreeSet::new();
    for member in members() {
        for overload in member.overloads {
            let signature = format!(
                "{}.{}{:?}{:?}{:?}",
                overload.decl, member.name, overload.on, overload.types, overload.params
            );
            assert!(overloads.insert(signature.clone()), "{signature} twice");
        }
    }
    let mut keys = std::collections::BTreeMap::new();
    for member in members() {
        for overload in member.overloads {
            let key = format!("{}.{}", overload.decl, member.name);
            let previous = keys.insert(key.clone(), member as *const Member);
            assert!(
                previous.is_none_or(|p| std::ptr::eq(p, member)),
                "{key} names two members"
            );
            let (found, _) = member_by_key(&key).expect("every key resolves");
            assert!(std::ptr::eq(found, member), "{key}");
        }
    }
}

#[test]
fn transport_facts_ac_1_every_name_is_fully_qualified() {
    for entry in TYPES {
        assert!(qualified(entry.name), "{}", entry.name);
        for base in entry.bases {
            assert!(is_type(base), "{}: base {base}", entry.name);
        }
        if let Some(endpoint) = entry.endpoint {
            assert!(is_type(endpoint), "{}: {endpoint}", entry.name);
        }
    }
    for member in members() {
        if let Some(returns) = member.returns {
            assert!(is_type(returns), "{}: {returns}", member.name);
        }
        for overload in member.overloads {
            assert!(
                qualified(overload.decl),
                "{}: {}",
                member.name,
                overload.decl
            );
            assert!(is_type(overload.on), "{}: on {}", member.name, overload.on);
            for param in overload.params {
                if let P::Lambda(types) = param.kind {
                    for ty in types {
                        assert!(
                            ty.is_empty() || *ty == "$endpoint" || is_type(ty),
                            "{}: lambda type {ty}",
                            member.name
                        );
                    }
                }
            }
        }
    }
    let tables = FORMATTERS
        .iter()
        .map(|(n, _)| *n)
        .chain(DEFINITIONS.iter().map(|(n, _)| *n))
        .chain(ATTRIBUTES.iter().map(|(n, _, _)| *n))
        .chain(OPTIONS.iter().map(|(n, _)| *n))
        .chain(TRANSPORTS.iter().map(|(n, _)| *n))
        .chain([URI_TYPE, DEFAULT_ENDPOINT]);
    for name in tables {
        assert!(is_type(name), "{name}");
    }
    for (sdk, namespaces) in IMPLICIT_USINGS {
        assert!(sdk.starts_with("Microsoft.NET.Sdk"), "{sdk}");
        for namespace in *namespaces {
            assert!(
                *namespace == "System"
                    || namespace.starts_with("System.")
                    || namespace.starts_with("Microsoft."),
                "{sdk}: {namespace}"
            );
        }
    }
}

#[test]
fn transport_facts_ac_1_every_role_is_known() {
    let roles: BTreeSet<&str> = ROLE_WORDS.iter().copied().collect();
    assert_eq!(roles.len(), ROLE_WORDS.len(), "the role words are distinct");
    for entry in TYPES {
        assert!(roles.contains(entry.role.word()), "{}", entry.name);
    }
    for member in members() {
        assert!(roles.contains(member.role.word()), "{}", member.name);
        for overload in member.overloads {
            for ty in overload.types {
                assert!(
                    *ty == Ty::Unused || TYPE_ROLE_WORDS.contains(&ty.word()),
                    "{}: {ty:?}",
                    member.name
                );
            }
        }
    }
    for (_, role) in DEFINITIONS {
        assert!(TYPE_ROLE_WORDS.contains(&role.word()));
    }
}

#[test]
fn transport_facts_ac_1_receivers_derive_through_the_catalogue_bases() {
    assert!(derives(
        "MassTransit.IRabbitMqBusFactoryConfigurator",
        "MassTransit.IReceiveConfigurator"
    ));
    assert!(derives(
        "MassTransit.ConsumeContext`1",
        "MassTransit.ISendEndpointProvider"
    ));
    assert!(!derives(
        "MassTransit.IReceiveEndpointConfigurator",
        "MassTransit.IRabbitMqBusFactoryConfigurator"
    ));
    assert_eq!(
        endpoint_of("MassTransit.IAmazonSqsBusFactoryConfigurator"),
        "MassTransit.IAmazonSqsReceiveEndpointConfigurator"
    );
    assert_eq!(
        endpoint_of("MassTransit.IReceiveConfigurator"),
        DEFAULT_ENDPOINT
    );
}