use super::*;
use crate::core::config::e2e::CallConfig;
use crate::core::ir::{FieldDef, FunctionDef, TypeDef, TypeRef};
fn docs_fixture(presentation_operations: serde_json::Value, assertions: serde_json::Value) -> Fixture {
serde_json::from_value(serde_json::json!({
"id": "sample_fixture",
"description": "Sample fixture",
"input": {"html": "<p>Hello World</p>"},
"assertions": assertions,
"docs": {
"topic": "smoke",
"stem": "sample_fixture",
"presentation": {"operations": presentation_operations},
}
}))
.expect("fixture must parse")
}
fn config() -> E2eConfig {
E2eConfig {
call: CallConfig {
function: "convert".into(),
result_var: "result".into(),
..CallConfig::default()
},
..E2eConfig::default()
}
}
fn field(name: &str, ty: TypeRef) -> FieldDef {
FieldDef {
name: name.to_string(),
ty,
..FieldDef::default()
}
}
fn convert_returning(type_name: &str) -> Vec<FunctionDef> {
vec![FunctionDef {
name: "convert".to_string(),
return_type: TypeRef::Named(type_name.to_string()),
..FunctionDef::default()
}]
}
fn type_defs() -> Vec<TypeDef> {
vec![
TypeDef {
name: "Envelope".to_string(),
fields: vec![field("document", TypeRef::Named("Document".to_string()))],
..TypeDef::default()
},
TypeDef {
name: "Document".to_string(),
fields: vec![
field("label", TypeRef::String),
field("format", TypeRef::Named("FormatInfo".to_string())),
field("items", TypeRef::Vec(Box::new(TypeRef::Named("Row".to_string())))),
],
..TypeDef::default()
},
TypeDef {
name: "Row".to_string(),
fields: vec![field("value", TypeRef::String)],
..TypeDef::default()
},
]
}
fn resolved(fixture: &Fixture, language: &str) -> Vec<PresentationOperation> {
resolve(
fixture,
&config(),
language,
&type_defs(),
&[],
&convert_returning("Envelope"),
)
}
#[test]
fn a_misspelled_authored_show_is_dropped() {
let fixture = docs_fixture(
serde_json::json!([{"op": "show", "path": "document.wrong_label"}]),
serde_json::json!([]),
);
assert_eq!(resolved(&fixture, "python"), Vec::new());
}
#[test]
fn an_authored_show_through_an_unwalkable_field_is_dropped() {
let fixture = docs_fixture(
serde_json::json!([{"op": "show", "path": "document.format.variant.detail"}]),
serde_json::json!([]),
);
assert_eq!(resolved(&fixture, "python"), Vec::new());
}
#[test]
fn a_correct_authored_show_survives_in_every_language() {
let fixture = docs_fixture(
serde_json::json!([{"op": "show", "path": "document.label"}]),
serde_json::json!([]),
);
assert_eq!(
resolved(&fixture, "python")
.into_iter()
.map(|op| op.expression)
.collect::<Vec<_>>(),
vec!["result.document.label"]
);
assert_eq!(
resolved(&fixture, "rust")
.into_iter()
.map(|op| op.expression)
.collect::<Vec<_>>(),
vec!["result.document.label"]
);
}
#[test]
fn an_authored_iterate_drops_only_the_unknown_per_item_field() {
let fixture = docs_fixture(
serde_json::json!([{
"op": "iterate",
"path": "document.items",
"item": "row",
"fields": ["wrong_value"],
}]),
serde_json::json!([]),
);
let operations = resolved(&fixture, "python");
assert_eq!(operations.len(), 1, "the iterate operation itself must survive");
assert_eq!(operations[0].kind, "iterate");
assert_eq!(operations[0].fields, Vec::<String>::new());
}
#[test]
fn an_authored_iterate_keeps_a_real_per_item_field_in_every_language() {
let fixture = docs_fixture(
serde_json::json!([{
"op": "iterate",
"path": "document.items",
"item": "row",
"fields": ["value"],
}]),
serde_json::json!([]),
);
for language in ["python", "rust"] {
let operations = resolved(&fixture, language);
assert_eq!(operations.len(), 1);
assert_eq!(operations[0].fields, vec!["row.value".to_string()]);
}
}
#[test]
fn dropping_every_authored_operation_falls_back_to_deriving_from_assertions() {
let fixture = docs_fixture(
serde_json::json!([{"op": "show", "path": "document.wrong_label"}]),
serde_json::json!([{"type": "equals", "field": "document.label", "value": "Hello"}]),
);
assert_eq!(
resolved(&fixture, "python")
.into_iter()
.map(|op| op.expression)
.collect::<Vec<_>>(),
vec!["result.document.label"]
);
}