use faucet_conformance::{
assert_batch_size_zero_single_page, assert_bounded_memory, assert_config_schema_valid_value,
assert_connector_name_nonempty, assert_errors_not_panics, assert_preflight_check_wellformed,
};
use faucet_source_xml::{XmlStream, XmlStreamConfig};
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
const TOTAL: usize = 6_000;
const BATCH: usize = 250;
#[test]
fn conformance_config_schema_valid() {
let schema = serde_json::to_value(schemars::schema_for!(XmlStreamConfig)).unwrap();
assert_config_schema_valid_value(&schema, "faucet-source-xml");
}
fn build_doc(n: usize) -> String {
let mut s = String::with_capacity(n * 64 + 32);
s.push_str("<root>");
for i in 0..n {
s.push_str(&format!(
"<item id=\"{i}\"><name>item-{i}</name><qty>{}</qty></item>",
i * 2
));
}
s.push_str("</root>");
s
}
#[tokio::test(flavor = "multi_thread")]
async fn conformance_bounded_memory() {
let server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/feed.xml"))
.respond_with(
ResponseTemplate::new(200)
.insert_header("Content-Type", "application/xml")
.set_body_string(build_doc(TOTAL)),
)
.mount(&server)
.await;
let config = XmlStreamConfig::new(server.uri(), "/feed.xml")
.records_element_path("root.item")
.with_batch_size(BATCH);
let source = XmlStream::new(config);
assert_bounded_memory(&source, BATCH, TOTAL).await;
}
#[tokio::test(flavor = "multi_thread")]
async fn conformance_batch_size_zero_single_page() {
let server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/feed.xml"))
.respond_with(
ResponseTemplate::new(200)
.insert_header("Content-Type", "application/xml")
.set_body_string(build_doc(200)),
)
.mount(&server)
.await;
let config = XmlStreamConfig::new(server.uri(), "/feed.xml")
.records_element_path("root.item")
.with_batch_size(0);
let source = XmlStream::new(config);
assert_batch_size_zero_single_page(&source).await;
}
fn unreachable_source() -> XmlStream {
XmlStream::new(XmlStreamConfig::new("http://127.0.0.1:1", "/feed.xml"))
}
#[tokio::test]
async fn conformance_errors_not_panics() {
assert_errors_not_panics(&unreachable_source()).await;
}
#[test]
fn conformance_connector_name_nonempty() {
assert_connector_name_nonempty(&unreachable_source());
}
#[tokio::test]
async fn conformance_preflight_check_wellformed() {
assert_preflight_check_wellformed(
&unreachable_source(),
&faucet_core::check::CheckContext::default(),
)
.await;
}