Extra test for schema

This commit is contained in:
Piotr Siuszko 2025-06-07 13:04:19 +02:00
parent 42ae72256c
commit 07dd944085
2 changed files with 74 additions and 5 deletions

View File

@ -11,7 +11,7 @@ use serde_json::{json, Map, Value};
use crate::schemas::SchemaTypesMetadata; use crate::schemas::SchemaTypesMetadata;
/// Helper trait for converting TypeRegistration to JsonSchemaBevyType /// Helper trait for converting `TypeRegistration` to `JsonSchemaBevyType`
pub trait TypeRegistrySchemaReader { pub trait TypeRegistrySchemaReader {
/// Export type JSON Schema. /// Export type JSON Schema.
fn export_type_json_schema<T: GetTypeRegistration>( fn export_type_json_schema<T: GetTypeRegistration>(
@ -371,6 +371,7 @@ mod tests {
use super::*; use super::*;
use bevy_ecs::prelude::ReflectComponent; use bevy_ecs::prelude::ReflectComponent;
use bevy_ecs::prelude::ReflectResource; use bevy_ecs::prelude::ReflectResource;
use bevy_ecs::{component::Component, reflect::AppTypeRegistry, resource::Resource}; use bevy_ecs::{component::Component, reflect::AppTypeRegistry, resource::Resource};
use bevy_reflect::prelude::ReflectDefault; use bevy_reflect::prelude::ReflectDefault;
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
@ -487,6 +488,62 @@ mod tests {
assert!(schema.one_of.len() == 3, "Should have 3 possible schemas"); assert!(schema.one_of.len() == 3, "Should have 3 possible schemas");
} }
#[test]
fn reflect_struct_with_custom_type_data() {
#[derive(Reflect, Default, Deserialize, Serialize)]
#[reflect(Default)]
enum EnumComponent {
ValueOne(i32),
ValueTwo {
test: i32,
},
#[default]
NoValue,
}
#[derive(Clone)]
pub struct ReflectCustomData;
impl<T: Reflect> bevy_reflect::FromType<T> for ReflectCustomData {
fn from_type() -> Self {
ReflectCustomData
}
}
let atr = AppTypeRegistry::default();
{
let mut register = atr.write();
register.register::<EnumComponent>();
register.register_type_data::<EnumComponent, ReflectCustomData>();
}
let mut metadata = SchemaTypesMetadata::default();
metadata.register_type::<ReflectCustomData>("CustomData");
let type_registry = atr.read();
let foo_registration = type_registry
.get(TypeId::of::<EnumComponent>())
.expect("SHOULD BE REGISTERED")
.clone();
let (_, schema) = export_type(&foo_registration, &metadata);
assert!(
!metadata.has_data_type::<ReflectComponent>(&schema.reflect_types),
"Should not be a component"
);
assert!(
!metadata.has_data_type::<ReflectResource>(&schema.reflect_types),
"Should not be a resource"
);
assert!(
metadata.has_data_type::<ReflectDefault>(&schema.reflect_types),
"Should have default"
);
assert!(
metadata.has_data_type::<ReflectCustomData>(&schema.reflect_types),
"Should have CustomData"
);
assert!(schema.properties.is_empty(), "Should not have any field");
assert!(schema.one_of.len() == 3, "Should have 3 possible schemas");
}
#[test] #[test]
fn reflect_export_tuple_struct() { fn reflect_export_tuple_struct() {
#[derive(Reflect, Component, Default, Deserialize, Serialize)] #[derive(Reflect, Component, Default, Deserialize, Serialize)]
@ -569,14 +626,14 @@ mod tests {
normalize_json(&mut two); normalize_json(&mut two);
assert_eq!(one, two); assert_eq!(one, two);
/// Recursively sorts arrays in a serde_json::Value /// Recursively sorts arrays in a `serde_json::Value`
fn normalize_json(value: &mut Value) { fn normalize_json(value: &mut Value) {
match value { match value {
Value::Array(arr) => { Value::Array(arr) => {
for v in arr.iter_mut() { for v in arr.iter_mut() {
normalize_json(v); normalize_json(v);
} }
arr.sort_by(|a, b| a.to_string().cmp(&b.to_string())); // Sort by stringified version arr.sort_by_key(ToString::to_string); // Sort by stringified version
} }
Value::Object(map) => { Value::Object(map) => {
for (_k, v) in map.iter_mut() { for (_k, v) in map.iter_mut() {

View File

@ -10,7 +10,7 @@ use bevy_reflect::{
prelude::ReflectDefault, Reflect, ReflectDeserialize, ReflectSerialize, TypeData, prelude::ReflectDefault, Reflect, ReflectDeserialize, ReflectSerialize, TypeData,
TypeRegistration, TypeRegistration,
}; };
use std::any::TypeId; use core::any::TypeId;
pub mod json_schema; pub mod json_schema;
pub mod open_rpc; pub mod open_rpc;
@ -41,7 +41,7 @@ impl Default for SchemaTypesMetadata {
} }
impl SchemaTypesMetadata { impl SchemaTypesMetadata {
/// Map TypeId of TypeData to string /// Map `TypeId` of `TypeData` to string
pub fn register_type<T: TypeData>(&mut self, name: impl Into<String>) { pub fn register_type<T: TypeData>(&mut self, name: impl Into<String>) {
self.data_types.insert(TypeId::of::<T>(), name.into()); self.data_types.insert(TypeId::of::<T>(), name.into());
} }
@ -53,4 +53,16 @@ impl SchemaTypesMetadata {
.flat_map(|(id, name)| reg.data_by_id(*id).and(Some(name.clone()))) .flat_map(|(id, name)| reg.data_by_id(*id).and(Some(name.clone())))
.collect() .collect()
} }
/// checks if slice contains string value that matches checked `TypeData`
pub fn has_data_type<T: TypeData>(&self, types_string_slice: &[String]) -> bool {
self.has_data_type_by_id(TypeId::of::<T>(), types_string_slice)
}
/// checks if slice contains string value that matches checked `TypeData` by id.
pub fn has_data_type_by_id(&self, id: TypeId, types_string_slice: &[String]) -> bool {
self.data_types
.get(&id)
.is_some_and(|data_s| types_string_slice.iter().any(|e| e.eq(data_s)))
}
} }