fixed and tested subschema promotions for beat processing
This commit is contained in:
@ -508,21 +508,24 @@ impl Schema {
|
||||
to_insert: &mut Vec<(String, Arc<Schema>)>,
|
||||
errors: &mut Vec<crate::drop::Error>,
|
||||
) {
|
||||
let mut should_push = false;
|
||||
|
||||
// Push ad-hoc inline composition into the addressable registry
|
||||
if schema_arc.obj.properties.is_some()
|
||||
|| schema_arc.obj.items.is_some()
|
||||
|| schema_arc.obj.family.is_some()
|
||||
|| schema_arc.obj.one_of.is_some()
|
||||
{
|
||||
should_push = true;
|
||||
}
|
||||
|
||||
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &schema_arc.obj.type_ {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
if t == "array" {
|
||||
if let Some(items) = &schema_arc.obj.items {
|
||||
if let Some(crate::database::object::SchemaTypeOrArray::Single(it)) = &items.obj.type_ {
|
||||
if !crate::database::object::is_primitive_type(it) {
|
||||
if items.obj.properties.is_some() || items.obj.cases.is_some() {
|
||||
to_insert.push((path.clone(), Arc::clone(schema_arc)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if !crate::database::object::is_primitive_type(t) {
|
||||
Self::validate_identifier(t, "type", root_id, &path, errors);
|
||||
should_push = true;
|
||||
|
||||
// Is this an explicit inline ad-hoc composition?
|
||||
if schema_arc.obj.properties.is_some() || schema_arc.obj.cases.is_some() {
|
||||
to_insert.push((path.clone(), Arc::clone(schema_arc)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,10 +533,6 @@ impl Schema {
|
||||
Self::validate_identifier(family, "$family", root_id, &path, errors);
|
||||
}
|
||||
|
||||
if should_push {
|
||||
to_insert.push((path.clone(), Arc::clone(schema_arc)));
|
||||
}
|
||||
|
||||
Self::collect_child_schemas(schema_arc, root_id, path, to_insert, errors);
|
||||
}
|
||||
|
||||
@ -575,7 +574,9 @@ impl Schema {
|
||||
let mut map_opt = |opt: &Option<Arc<Schema>>, pass_path: bool, sub: &str| {
|
||||
if let Some(v) = opt {
|
||||
if pass_path {
|
||||
Self::collect_schemas(v, root_id, format!("{}/{}", path, sub), to_insert, errors);
|
||||
// Arrays explicitly push their wrapper natively.
|
||||
// 'items' becomes a transparent conduit, bypassing self-promotion and skipping the '/items' suffix.
|
||||
Self::collect_child_schemas(v, root_id, path.clone(), to_insert, errors);
|
||||
} else {
|
||||
Self::collect_child_schemas(v, root_id, format!("{}/{}", path, sub), to_insert, errors);
|
||||
}
|
||||
|
||||
@ -3683,6 +3683,12 @@ fn test_database_4_0() {
|
||||
crate::tests::runner::run_test_case(&path, 4, 0).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_database_5_0() {
|
||||
let path = format!("{}/fixtures/database.json", env!("CARGO_MANIFEST_DIR"));
|
||||
crate::tests::runner::run_test_case(&path, 5, 0).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cases_0_0() {
|
||||
let path = format!("{}/fixtures/cases.json", env!("CARGO_MANIFEST_DIR"));
|
||||
|
||||
@ -107,10 +107,6 @@ fn test_library_api() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"source_schema/target": {
|
||||
"type": "target_schema",
|
||||
"compiledProperties": ["value"]
|
||||
},
|
||||
"target_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@ -49,7 +49,13 @@ impl Case {
|
||||
Err(d) => d.clone(),
|
||||
};
|
||||
|
||||
expect.assert_drop(&result)
|
||||
expect.assert_drop(&result)?;
|
||||
|
||||
if let Ok(db) = db_res {
|
||||
expect.assert_schemas(db)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_validate(&self, db: Arc<Database>) -> Result<(), String> {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
pub mod pattern;
|
||||
pub mod sql;
|
||||
pub mod drop;
|
||||
pub mod schema;
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
@ -18,4 +19,6 @@ pub struct Expect {
|
||||
pub errors: Option<Vec<serde_json::Value>>,
|
||||
#[serde(default)]
|
||||
pub sql: Option<Vec<SqlExpectation>>,
|
||||
#[serde(default)]
|
||||
pub schemas: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
27
src/tests/types/expect/schema.rs
Normal file
27
src/tests/types/expect/schema.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use super::Expect;
|
||||
use std::sync::Arc;
|
||||
|
||||
impl Expect {
|
||||
pub fn assert_schemas(&self, db: &Arc<crate::database::Database>) -> Result<(), String> {
|
||||
if let Some(expected_schemas) = &self.schemas {
|
||||
// Collect actual schemas and sort
|
||||
let mut actual: Vec<String> = db.schemas.keys().cloned().collect();
|
||||
actual.sort();
|
||||
|
||||
// Collect expected schemas and sort
|
||||
let mut expected: Vec<String> = expected_schemas.clone();
|
||||
expected.sort();
|
||||
|
||||
if actual != expected {
|
||||
return Err(format!(
|
||||
"Schema Promotion Mismatch!\nExpected Schemas ({}):\n{:#?}\n\nActual Promoted Schemas ({}):\n{:#?}",
|
||||
expected.len(),
|
||||
expected,
|
||||
actual.len(),
|
||||
actual
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user