BigQuery: Convert `json` atoms to a JSON column type if configured in `mozPipelineMetadata`

This allows the `object` metric type to become a JSON column in
BigQuery.

This is the _only_ place where jsonschema-transpiler uses
schema metadata specific to Mozilla for generating BigQuery schemas.

It's added to the context after parsing the schema into an AST.
This _could_ be a CLI parameter instead, but due to how
jsonschema-transpiler is used it is easier for us to pass that
information as configuration within the schema itself.
It's still generic enough that we could extend it to other fields in the
future if needed.
This commit is contained in:
Jan-Erik Rediger 2023-09-08 14:55:08 +02:00 коммит произвёл Jan-Erik Rediger
Родитель ea6b747204
Коммит 7702542911
8 изменённых файлов: 408 добавлений и 81 удалений

Просмотреть файл

@ -88,7 +88,12 @@ fn avro_{name}() {{
}};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {{
// No expected data = no avro support
return;
}}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -130,7 +135,7 @@ fn bigquery_{name}() {{
}};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);

Просмотреть файл

@ -20,6 +20,7 @@ pub enum Atom {
Geography,
Time,
Timestamp,
Json,
}
#[derive(Serialize, Deserialize, Debug)]
@ -88,10 +89,16 @@ impl TranslateFrom<ast::Tag> for Tag {
ast::Atom::String => Atom::String,
ast::Atom::Datetime => Atom::Timestamp,
ast::Atom::Bytes => Atom::Bytes,
ast::Atom::Json => match handle_error("json atom") {
Ok(_) => Atom::String,
Err(reason) => return Err(reason),
},
ast::Atom::Json => {
if context.is_json_object_path(&tag.fully_qualified_name()) {
Atom::Json
} else {
match handle_error("json atom") {
Ok(_) => Atom::String,
Err(reason) => return Err(reason),
}
}
}
}),
ast::Type::Object(object) => {
let fields: HashMap<String, Box<Tag>> = if object.fields.is_empty() {
@ -687,6 +694,7 @@ mod tests {
force_nullable: false,
tuple_struct: false,
allow_maps_without_value: true,
..Default::default()
};
assert_eq!(expect, transform_tag_with_context(data, &context));
}

Просмотреть файл

@ -83,6 +83,7 @@ enum Format {
DateTime,
// Custom format value for casting strings into byte-strings
Bytes,
Json,
#[serde(other)]
Other,
}
@ -108,7 +109,7 @@ pub struct Tag {
#[serde(skip_serializing_if = "Option::is_none")]
all_of: Option<AllOf>,
#[serde(flatten)]
extra: HashMap<String, Value>,
pub(crate) extra: HashMap<String, Value>,
}
impl Tag {

Просмотреть файл

@ -13,6 +13,7 @@ pub mod casing;
mod jsonschema;
mod traits;
use regex::Regex;
use serde_json::{json, Value};
use traits::TranslateFrom;
@ -51,31 +52,62 @@ pub enum ResolveMethod {
/// particular, the context is useful for resolving edge-cases in ambiguous
/// situations. This can includes situations like casting or dropping an empty
/// object.
#[derive(Copy, Clone, Default, Deserialize)]
#[derive(Clone, Default, Deserialize)]
#[serde(default)]
pub struct Context {
pub resolve_method: ResolveMethod,
pub normalize_case: bool,
pub force_nullable: bool,
pub tuple_struct: bool,
pub allow_maps_without_value: bool,
pub json_object_path: Option<String>,
}
fn into_ast(input: &Value, context: &Context) -> ast::Tag {
impl Context {
/// Determine whether the given fully qualified name matches the configured json object path.
fn is_json_object_path(&self, fqn: &str) -> bool {
// would need to be passed in _somehow_.
self.json_object_path
.as_ref()
.map(|json_object_path| {
let re = format!(r"\A{}", json_object_path);
let json_object_path_re = Regex::new(&re).unwrap();
json_object_path_re.is_match(fqn)
})
.unwrap_or(false)
}
}
fn into_ast(input: &Value, context: &mut Context) -> ast::Tag {
let jsonschema: jsonschema::Tag = match serde_json::from_value(json!(input)) {
Ok(tag) => tag,
Err(e) => panic!("{:#?}", e),
};
// The only special thing this crates knows about the schema:
// Every sub-tree id matching the regex in `mozPipelineMetadata.json_object_path` is dumped as a JSON
// column without peeking further into that subtree.
let metadata = jsonschema
.extra
.get("mozPipelineMetadata")
.and_then(|obj| obj["json_object_path"].as_str());
if let Some(json_object_path) = metadata {
context.json_object_path = Some(json_object_path.to_string());
}
ast::Tag::translate_from(jsonschema, context).unwrap()
}
/// Convert JSON Schema into an Avro compatible schema
pub fn convert_avro(input: &Value, context: Context) -> Value {
let avro = avro::Type::translate_from(into_ast(input, &context), &context).unwrap();
pub fn convert_avro(input: &Value, mut context: Context) -> Value {
let ast = into_ast(input, &mut context);
let avro = avro::Type::translate_from(ast, &context).unwrap();
json!(avro)
}
/// Convert JSON Schema into a BigQuery compatible schema
pub fn convert_bigquery(input: &Value, context: Context) -> Value {
let bq = bigquery::Schema::translate_from(into_ast(input, &context), &context).unwrap();
pub fn convert_bigquery(input: &Value, mut context: Context) -> Value {
let ast = into_ast(input, &mut context);
let bq = bigquery::Schema::translate_from(ast, &context).unwrap();
json!(bq)
}

Просмотреть файл

@ -81,6 +81,7 @@ fn main() {
force_nullable: args.force_nullable,
tuple_struct: args.tuple_struct,
allow_maps_without_value: args.allow_maps_without_value,
json_object_path: None,
};
let output = match args.typ {

Просмотреть файл

@ -0,0 +1,33 @@
{
"name": "json",
"tests": [
{
"name": "test_json_object",
"compatible": true,
"test": {
"avro": null,
"bigquery": [
{
"mode": "NULLABLE",
"name": "an_object_name",
"type": "JSON"
}
],
"json": {
"properties": {
"an_object_name": {
"items": {},
"type": [
"object",
"array"
]
}
}
},
"context": {
"json_object_path": "an_object_name"
}
}
}
]
}

Просмотреть файл

@ -26,7 +26,12 @@ fn avro_test_array_with_atomics() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -91,7 +96,12 @@ fn avro_test_array_with_complex() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -169,7 +179,12 @@ fn avro_test_array_of_array() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -192,7 +207,12 @@ fn avro_test_atomic() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -223,7 +243,12 @@ fn avro_test_atomic_with_null() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -250,7 +275,12 @@ fn avro_test_incompatible_atomic_multitype() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -283,7 +313,12 @@ fn avro_test_incompatible_atomic_multitype_with_null() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -307,7 +342,12 @@ fn avro_test_datetime() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -331,7 +371,12 @@ fn avro_test_bytes_format() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -355,7 +400,12 @@ fn avro_test_atomic_with_description() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -380,7 +430,12 @@ fn avro_test_atomic_with_description_and_title() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -404,7 +459,46 @@ fn avro_test_atomic_with_title() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
}
#[test]
fn avro_test_json_object() {
let input_data = r#"
{
"properties": {
"an_object_name": {
"items": {},
"type": [
"object",
"array"
]
}
}
}
"#;
let expected_data = r#"
null
"#;
let mut context = Context {
..Default::default()
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -433,7 +527,12 @@ fn avro_test_map_with_atomics() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -501,7 +600,12 @@ fn avro_test_map_with_complex() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -533,7 +637,12 @@ fn avro_test_map_with_pattern_properties() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -567,7 +676,12 @@ fn avro_test_map_with_pattern_and_additional_properties() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -603,7 +717,12 @@ fn avro_test_incompatible_map_with_pattern_properties() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -638,7 +757,12 @@ fn avro_test_incompatible_map_with_pattern_and_additional_properties() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -726,7 +850,12 @@ fn avro_test_object_with_atomics_is_sorted() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -791,7 +920,12 @@ fn avro_test_object_with_atomics_required() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -865,7 +999,12 @@ fn avro_test_object_with_atomics_required_with_null() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -945,7 +1084,12 @@ fn avro_test_object_with_complex() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -970,7 +1114,12 @@ fn avro_test_object_empty_record() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1000,7 +1149,12 @@ fn avro_test_oneof_atomic() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1035,7 +1189,12 @@ fn avro_test_oneof_atomic_with_null() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1066,7 +1225,12 @@ fn avro_test_incompatible_oneof_atomic() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1105,7 +1269,12 @@ fn avro_test_incompatible_oneof_atomic_with_null() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1178,7 +1347,12 @@ fn avro_test_oneof_object_with_atomics() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1263,7 +1437,12 @@ fn avro_test_oneof_object_merge() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1409,7 +1588,12 @@ fn avro_test_oneof_object_merge_with_complex() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1445,7 +1629,12 @@ fn avro_test_incompatible_oneof_atomic_and_object() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1486,7 +1675,12 @@ fn avro_test_incompatible_oneof_object() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1543,7 +1737,12 @@ fn avro_test_incompatible_oneof_object_with_complex() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);
@ -1628,7 +1827,12 @@ fn avro_test_oneof_object_merge_nullability() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_avro(&input, context));
if expected.is_null() {
// No expected data = no avro support
return;
}
assert_eq!(expected, convert_avro(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_avro(&input, context);

Просмотреть файл

@ -33,7 +33,7 @@ fn bigquery_test_array_with_atomics() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -89,7 +89,7 @@ fn bigquery_test_array_with_complex() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -153,7 +153,7 @@ fn bigquery_test_array_of_array() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -186,7 +186,7 @@ fn bigquery_test_atomic() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -222,7 +222,7 @@ fn bigquery_test_atomic_with_null() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -259,7 +259,7 @@ fn bigquery_test_incompatible_atomic_multitype() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -297,7 +297,7 @@ fn bigquery_test_incompatible_atomic_multitype_with_null() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -331,7 +331,7 @@ fn bigquery_test_datetime() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -365,7 +365,7 @@ fn bigquery_test_bytes_format() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -400,7 +400,7 @@ fn bigquery_test_atomic_with_description() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -436,7 +436,7 @@ fn bigquery_test_atomic_with_description_and_title() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -471,7 +471,50 @@ fn bigquery_test_atomic_with_title() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
}
#[test]
fn bigquery_test_json_object() {
let input_data = r#"
{
"properties": {
"an_object_name": {
"items": {},
"type": [
"object",
"array"
]
}
}
}
"#;
let expected_data = r#"
[
{
"mode": "NULLABLE",
"name": "an_object_name",
"type": "JSON"
}
]
"#;
let context_data = r#"
{
"json_object_path": "an_object_name"
}
"#;
let context: Value = serde_json::from_str(context_data).unwrap();
let mut context: Context = if context.is_null() {
Default::default()
} else {
serde_json::from_value(context).unwrap()
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -519,7 +562,7 @@ fn bigquery_test_map_with_atomics() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -593,7 +636,7 @@ fn bigquery_test_map_with_complex() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -644,7 +687,7 @@ fn bigquery_test_map_with_pattern_properties() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -697,7 +740,7 @@ fn bigquery_test_map_with_pattern_and_additional_properties() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -752,7 +795,7 @@ fn bigquery_test_incompatible_map_with_pattern_properties() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -806,7 +849,7 @@ fn bigquery_test_incompatible_map_with_pattern_and_additional_properties() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -868,7 +911,7 @@ fn bigquery_test_object_with_atomics_is_sorted() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -926,7 +969,7 @@ fn bigquery_test_object_with_atomics_required() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -987,7 +1030,7 @@ fn bigquery_test_object_with_atomics_required_with_null() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1047,7 +1090,7 @@ fn bigquery_test_object_with_complex() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1082,7 +1125,7 @@ fn bigquery_test_object_empty_record() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1122,7 +1165,7 @@ fn bigquery_test_oneof_atomic() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1162,7 +1205,7 @@ fn bigquery_test_oneof_atomic_with_null() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1203,7 +1246,7 @@ fn bigquery_test_incompatible_oneof_atomic() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1247,7 +1290,7 @@ fn bigquery_test_incompatible_oneof_atomic_with_null() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1308,7 +1351,7 @@ fn bigquery_test_oneof_object_with_atomics() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1374,7 +1417,7 @@ fn bigquery_test_oneof_object_merge() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1478,7 +1521,7 @@ fn bigquery_test_oneof_object_merge_with_complex() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1524,7 +1567,7 @@ fn bigquery_test_incompatible_oneof_atomic_and_object() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1575,7 +1618,7 @@ fn bigquery_test_incompatible_oneof_object() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1642,7 +1685,7 @@ fn bigquery_test_incompatible_oneof_object_with_complex() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);
@ -1714,7 +1757,7 @@ fn bigquery_test_oneof_object_merge_nullability() {
};
let input: Value = serde_json::from_str(input_data).unwrap();
let expected: Value = serde_json::from_str(expected_data).unwrap();
assert_eq!(expected, convert_bigquery(&input, context));
assert_eq!(expected, convert_bigquery(&input, context.clone()));
context.resolve_method = ResolveMethod::Panic;
convert_bigquery(&input, context);