use bevy_grimoire_core::reload::{self, KINDS};
use bevy_grimoire_core::reload_check::{self, Check};
struct Frozen {
kind: &'static str,
file: &'static str,
since: &'static str,
text: &'static str,
}
macro_rules! frozen {
($kind:literal, $file:literal, $since:literal, $path:literal) => {
Frozen { kind: $kind, file: $file, since: $since, text: include_str!($path) }
};
}
const FROZEN: &[Frozen] = &[
frozen!("kits", "kits.ron", "bevy_emerge_core 0.1.0", "old_data/core-0.1.0/kits.ron"),
frozen!("vocab", "vocab.ron", "bevy_emerge_core 0.1.0", "old_data/core-0.1.0/vocab.ron"),
frozen!("library", "scp/library.ron", "bevy_emerge_core 0.1.0", "old_data/core-0.1.0/library.ron"),
frozen!("library", "site/library.ron", "bevy_emerge_core 0.1.0", "old_data/core-0.1.0/library_site.ron"),
frozen!("policy", "site/project.ron", "bevy_emerge_core 0.1.0", "old_data/core-0.1.0/policy.ron"),
frozen!("policy", "furniture/project.ron", "bevy_emerge_core 0.1.0", "old_data/core-0.1.0/policy_furniture.ron"),
frozen!("compositions", "compositions.ron", "bevy_emerge_core 0.1.0", "old_data/core-0.1.0/compositions.ron"),
frozen!("rigs", "rigs.ron", "bevy_emerge_core 0.1.0", "old_data/core-0.1.0/rigs.ron"),
frozen!("rules", "rules.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/rules.ron"),
frozen!("standards", "standards.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/standards.ron"),
frozen!("repetition", "repetition.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/repetition.ron"),
frozen!("map", "maps/yard.map.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/map.ron"),
frozen!("notes", "maps/yard.notes.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/notes.ron"),
frozen!("plan", "maps/yard.plan.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/plan.ron"),
frozen!("references", "maps/yard.references.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/references.ron"),
frozen!("relations", "maps/yard.relations.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/relations.ron"),
frozen!("terrain", "site/terrain/yard.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/terrain.ron"),
frozen!("water_plan", "site/water/yard.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/water_plan.ron"),
frozen!("water_field", "site/water/yard.field.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/water_field.ron"),
frozen!("volume", "site/volume/yard.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/volume.ron"),
frozen!("data_registry", "site/data.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/data_registry.ron"),
frozen!("family_list", "family.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/family_list.ron"),
frozen!("agent", "agent.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/agent.ron"),
frozen!("play", "play.ron", "bevy_grimoire_core 0.3.0", "old_data/core-0.3.0/play.ron"),
frozen!("destructible_marks", "destructible.ron", "the editor at 3f4084c", "old_data/editor-3f4084c/destructible.ron"),
frozen!("destructible_bake", "destructible/site__cart.bake.ron", "the editor at 3f4084c", "old_data/editor-3f4084c/site__cart.bake.ron"),
];
const FROZEN_MIN: usize = 26;
#[test]
fn data_an_earlier_release_wrote_still_reads() {
let mut broken = Vec::new();
for f in FROZEN {
let kind = reload::kind_by_id(f.kind).unwrap_or_else(|| panic!("`{}` is not a kind of the registry", f.kind));
if let Check::Refused(r) = reload_check::check(kind, f.file, f.text) {
broken.push(format!(
"`{}` ({}) written by {} no longer reads{}: {}",
r.kind,
r.file,
f.since,
r.field.as_deref().map(|p| format!(", at field `{p}`")).unwrap_or_default(),
r.reason
));
}
}
assert!(
broken.is_empty(),
"an edit to a settings type refuses data already on disk. A field added with no default, or (for a type that denies unknown fields) a field removed that old files still carry, is refused here; give the field `#[serde(default)]`, keep reading the old one, or bump the version and migrate it (the frozen file stays):\n{}",
broken.join("\n")
);
}
#[test]
fn every_kind_the_check_reads_has_frozen_data_and_each_file_is_its_kinds() {
let mut frozen: Vec<&str> = FROZEN.iter().map(|f| f.kind).collect();
frozen.sort_unstable();
frozen.dedup();
let mut checked: Vec<&str> = KINDS.iter().filter(|k| !reload_check::unchecked().any(|u| u.id == k.id)).map(|k| k.id).collect();
checked.sort_unstable();
assert_eq!(frozen, checked, "a kind `check` reads needs a file frozen in `tests/old_data/`, and a frozen file needs a kind that is read");
for f in FROZEN {
let kind = reload::kind_by_id(f.kind).unwrap();
assert!(kind.matches(f.file), "`{}` is not a path of kind `{}`", f.file, f.kind);
assert!(!f.text.trim().is_empty(), "`{}` is empty", f.file);
}
}
#[test]
fn a_frozen_file_is_never_dropped() {
assert!(FROZEN.len() >= FROZEN_MIN, "the list has {} files and the floor is {FROZEN_MIN}: a frozen file is never removed", FROZEN.len());
}