queryer merger test progress

This commit is contained in:
2026-03-11 05:18:01 -04:00
parent 1c08a8f2b8
commit 44be75f5d4
104 changed files with 22563 additions and 18859 deletions

View File

@ -4,7 +4,6 @@ pub mod context;
pub mod error;
pub mod result;
pub mod rules;
pub mod util;
pub use context::ValidationContext;
pub use error::ValidationError;
@ -46,11 +45,7 @@ impl Validator {
}
}
pub fn validate(
&self,
schema_id: &str,
instance: &Value,
) -> Result<ValidationResult, ValidationError> {
pub fn validate(&self, schema_id: &str, instance: &Value) -> crate::drop::Drop {
if let Some(schema) = self.db.schemas.get(schema_id) {
let ctx = ValidationContext::new(
&self.db,
@ -61,13 +56,37 @@ impl Validator {
false,
false,
);
ctx.validate_scoped()
match ctx.validate_scoped() {
Ok(result) => {
if result.is_valid() {
crate::drop::Drop::success()
} else {
let errors: Vec<crate::drop::Error> = result
.errors
.into_iter()
.map(|e| crate::drop::Error {
code: e.code,
message: e.message,
details: crate::drop::ErrorDetails { path: e.path },
})
.collect();
crate::drop::Drop::with_errors(errors)
}
}
Err(e) => crate::drop::Drop::with_errors(vec![crate::drop::Error {
code: e.code,
message: e.message,
details: crate::drop::ErrorDetails { path: e.path },
}]),
}
} else {
Err(ValidationError {
crate::drop::Drop::with_errors(vec![crate::drop::Error {
code: "SCHEMA_NOT_FOUND".to_string(),
message: format!("Schema {} not found", schema_id),
path: "".to_string(),
})
details: crate::drop::ErrorDetails {
path: "".to_string(),
},
}])
}
}
}

View File

@ -1,127 +0,0 @@
use serde::Deserialize;
use std::fs;
#[derive(Debug, Deserialize)]
struct TestSuite {
#[allow(dead_code)]
description: String,
database: serde_json::Value,
tests: Vec<TestCase>,
}
#[derive(Debug, Deserialize)]
pub struct TestCase {
pub description: String,
#[serde(default = "default_action")]
pub action: String, // "validate", "merge", or "query"
// For Validate & Query
#[serde(default)]
pub schema_id: String,
// For Query
#[serde(default)]
pub stem: Option<String>,
#[serde(default)]
pub filters: Option<serde_json::Value>,
// For Merge & Validate
#[serde(default)]
pub data: Option<serde_json::Value>,
// For Merge & Query mocks
#[serde(default)]
pub mocks: Option<serde_json::Value>,
pub expect: Option<ExpectBlock>,
// Legacy support for older tests to avoid migrating them all instantly
pub valid: Option<bool>,
pub expect_errors: Option<Vec<serde_json::Value>>,
}
fn default_action() -> String {
"validate".to_string()
}
#[derive(Debug, Deserialize)]
pub struct ExpectBlock {
pub success: bool,
pub result: Option<serde_json::Value>,
pub errors: Option<Vec<serde_json::Value>>,
pub sql_patterns: Option<Vec<String>>,
}
// use crate::validator::registry::REGISTRY; // No longer used directly for tests!
use crate::validator::Validator;
use serde_json::Value;
pub fn deserialize_some<'de, D>(deserializer: D) -> Result<Option<Value>, D::Error>
where
D: serde::Deserializer<'de>,
{
let v = Value::deserialize(deserializer)?;
Ok(Some(v))
}
pub fn run_test_file_at_index(path: &str, index: usize) -> Result<(), String> {
let content =
fs::read_to_string(path).unwrap_or_else(|_| panic!("Failed to read file: {}", path));
let suite: Vec<TestSuite> = serde_json::from_str(&content)
.unwrap_or_else(|e| panic!("Failed to parse JSON in {}: {}", path, e));
if index >= suite.len() {
panic!("Index {} out of bounds for file {}", index, path);
}
let group = &suite[index];
let mut failures = Vec::<String>::new();
let db_json = group.database.clone();
let db = crate::database::Database::new(&db_json);
let validator = Validator::new(std::sync::Arc::new(db));
// 4. Run Tests
for test in group.tests.iter() {
let schema_id = &test.schema_id;
if !validator.db.schemas.contains_key(schema_id) {
failures.push(format!(
"[{}] Missing Schema: Cannot find schema ID '{}'",
group.description, schema_id
));
continue;
}
let result = validator.validate(schema_id, &test.data);
let (got_valid, _errors) = match &result {
Ok(res) => (res.is_valid(), &res.errors),
Err(_e) => {
// If we encounter an execution error (e.g. Schema Not Found),
// we treat it as a test failure.
(false, &vec![])
}
};
if got_valid != test.valid {
let error_msg = match &result {
Ok(res) => format!("{:?}", res.errors),
Err(e) => format!("Execution Error: {:?}", e),
};
failures.push(format!(
"[{}] Test '{}' failed. Expected: {}, Got: {}. Errors: {}",
group.description, test.description, test.valid, got_valid, error_msg
));
}
}
if !failures.is_empty() {
return Err(failures.join("\n"));
}
Ok(())
}