use std::collections::{HashMap, HashSet};
use super::super::*;
use crate::core::ir::{FieldDef, FunctionDef, PrimitiveType, TypeDef, TypeRef};
use crate::e2e::field_access::FieldResolver;
use crate::e2e::fixture::{Assertion, Fixture};
fn set(entries: &[&str]) -> HashSet<String> {
entries.iter().map(|s| (*s).to_string()).collect()
}
fn report_type_defs() -> Vec<TypeDef> {
vec![TypeDef {
name: "Report".into(),
fields: vec![FieldDef {
name: "total_count".into(),
ty: TypeRef::Primitive(PrimitiveType::U64),
..FieldDef::default()
}],
..TypeDef::default()
}]
}
fn report_functions() -> Vec<FunctionDef> {
vec![FunctionDef {
name: "generate_report".into(),
return_type: TypeRef::Named("Report".into()),
..FunctionDef::default()
}]
}
fn namespaced_fixture() -> Fixture {
Fixture {
id: "namespaced_total".into(),
description: "assert a field grouped under a virtual label".into(),
input: serde_json::json!({}),
assertions: vec![Assertion {
assertion_type: "equals".to_string(),
field: Some("interaction.total_count".to_string()),
value: Some(serde_json::json!(7)),
..Default::default()
}],
..Fixture::default()
}
}
fn namespaced_resolver() -> FieldResolver {
FieldResolver::new(
&HashMap::new(),
&HashSet::new(),
&set(&["total_count"]),
&HashSet::new(),
&HashSet::new(),
)
}
fn plain_e2e_config() -> E2eConfig {
let mut e2e = E2eConfig::default();
e2e.call.function = "generate_report".into();
e2e.result_fields = set(&["total_count"]);
e2e
}
fn sample_crate_config() -> ResolvedCrateConfig {
ResolvedCrateConfig {
name: "sample".into(),
..ResolvedCrateConfig::default()
}
}
fn render(e2e: &E2eConfig) -> String {
let fixture = namespaced_fixture();
let config = sample_crate_config();
let type_defs = report_type_defs();
let functions = report_functions();
let ir = CallIr {
functions: &functions,
type_defs: &type_defs,
};
render_test_file(
"report",
&[&fixture],
"sample_ffi.h",
"sample",
"result",
e2e,
"c",
&namespaced_resolver(),
&config,
&type_defs,
&[],
&[],
ir,
)
.expect("test file renders")
}
fn assert_addresses_the_stripped_field(rendered: &str) {
assert!(
rendered.contains("sample_report_total_count(result)"),
"the virtual `interaction.` label must strip so the accessor reads `total_count` \
directly off the result, got:\n{rendered}"
);
assert!(
!rendered.contains("sample_report_interaction("),
"`interaction` is a virtual label, not a member of `Report` -- emitting an accessor \
for it addresses a field the header never declares:\n{rendered}"
);
}
#[test]
fn plain_function_branch_strips_the_virtual_namespace() {
assert_addresses_the_stripped_field(&render(&plain_e2e_config()));
}
#[test]
fn engine_factory_branch_strips_the_virtual_namespace() {
let mut e2e = plain_e2e_config();
e2e.call.overrides.insert(
"c".into(),
crate::core::config::e2e::CallOverride {
c_engine_factory: Some("CrawlConfig".into()),
header: Some("sample_ffi.h".into()),
..Default::default()
},
);
assert_addresses_the_stripped_field(&render(&e2e));
}