use super::{
PlanesOwner, RenderContext,
materials::{resolve_material, resolve_material_with_override},
};
use indicatrix::{geometry::cuts::StandardGemCuts, optics::materials::GemMaterial};
use std::sync::Arc;
#[test]
fn builtin_is_the_default_owner_and_anything_may_claim_over_it() {
let ctx = RenderContext::default();
assert_eq!(ctx.planes_owner, PlanesOwner::Builtin);
assert!(ctx.may_claim_active_planes(PlanesOwner::Catalogue { entry_id: 1 }));
assert!(ctx.may_claim_active_planes(PlanesOwner::Editor { generation: 0 }));
}
#[test]
fn a_catalogue_claim_may_overwrite_an_editor_owner() {
let mut ctx = RenderContext::default();
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 3 },
));
assert!(
ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Catalogue { entry_id: 42 },
),
"an explicit Library selection must always be able to show its row"
);
assert_eq!(ctx.planes_owner, PlanesOwner::Catalogue { entry_id: 42 });
}
#[test]
fn a_stale_editor_generation_never_overwrites_a_newer_one() {
let mut ctx = RenderContext::default();
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 5 },
));
assert!(!ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 2 },
));
assert_eq!(ctx.planes_owner, PlanesOwner::Editor { generation: 5 });
}
#[test]
fn a_newer_or_equal_editor_generation_may_overwrite_the_current_one() {
let mut ctx = RenderContext::default();
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 5 },
));
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 5 },
));
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 6 },
));
assert_eq!(ctx.planes_owner, PlanesOwner::Editor { generation: 6 });
}
#[test]
fn two_catalogue_claims_freely_replace_each_other() {
let mut ctx = RenderContext::default();
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Catalogue { entry_id: 1 },
));
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Catalogue { entry_id: 2 },
));
assert_eq!(ctx.planes_owner, PlanesOwner::Catalogue { entry_id: 2 });
}
#[test]
fn a_zero_stone_width_claim_is_unaffected_by_an_owner_change() {
let mut ctx = RenderContext::default();
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Catalogue { entry_id: 1 },
));
assert_eq!(ctx.stone_width_mm, 0.0);
}
#[test]
fn a_nonzero_stone_width_survives_an_owner_change_the_claim_still_accepts() {
let mut ctx = RenderContext {
stone_width_mm: 6.5,
..RenderContext::default()
};
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Catalogue { entry_id: 9 },
));
assert_eq!(ctx.stone_width_mm, 6.5);
}
#[test]
fn a_nonzero_stone_width_claim_for_the_same_owner_is_not_an_owner_change() {
let mut ctx = RenderContext {
stone_width_mm: 6.5,
..RenderContext::default()
};
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 1 },
));
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 2 },
));
assert_eq!(ctx.stone_width_mm, 6.5);
}
#[test]
fn traced_planes_match_the_generation_they_were_claimed_at() {
let mut ctx = RenderContext::default();
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 7 },
));
assert!(!ctx.traced_planes_are_stale(7));
}
#[test]
fn traced_planes_are_stale_once_a_newer_edit_has_landed() {
let mut ctx = RenderContext::default();
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 7 },
));
assert!(ctx.traced_planes_are_stale(8));
}
#[test]
fn a_slot_the_editor_has_never_owned_is_never_stale() {
let ctx = RenderContext::default();
assert_eq!(ctx.planes_owner, PlanesOwner::Builtin);
assert!(!ctx.traced_planes_are_stale(1));
let mut ctx = RenderContext::default();
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Catalogue { entry_id: 3 },
));
assert!(!ctx.traced_planes_are_stale(1));
}
#[test]
fn a_refused_claim_leaves_every_field_untouched() {
let mut ctx = RenderContext::default();
let original_planes = Arc::new(StandardGemCuts::emerald_cut());
ctx.active_planes = Arc::clone(&original_planes);
ctx.design_gear = Some((96, 0.5));
ctx.planes_owner = PlanesOwner::Editor { generation: 10 };
let accepted = ctx.claim_active_planes(
Arc::new(StandardGemCuts::standard_round_brilliant()),
Some((64, 0.0)),
PlanesOwner::Catalogue { entry_id: 7 },
);
assert!(!accepted);
assert!(Arc::ptr_eq(&ctx.active_planes, &original_planes));
assert_eq!(ctx.design_gear, Some((96, 0.5)));
assert_eq!(ctx.planes_owner, PlanesOwner::Editor { generation: 10 });
}
#[test]
fn default_context_has_no_custom_specific_gravity_entries() {
let ctx = RenderContext::default();
assert!(ctx.custom_material_specific_gravity.is_empty());
assert_eq!(ctx.custom_specific_gravity("My Garnet"), None);
}
#[test]
fn custom_specific_gravity_finds_a_recorded_entry_case_insensitively() {
let ctx = RenderContext {
custom_material_specific_gravity: Arc::new(vec![("My Garnet".to_string(), 3.9)]),
..RenderContext::default()
};
assert_eq!(ctx.custom_specific_gravity("my garnet"), Some(3.9));
assert_eq!(ctx.custom_specific_gravity("MY GARNET"), Some(3.9));
}
#[test]
fn custom_specific_gravity_is_none_for_an_unrecorded_name() {
let ctx = RenderContext {
custom_material_specific_gravity: Arc::new(vec![("My Garnet".to_string(), 3.9)]),
..RenderContext::default()
};
assert_eq!(ctx.custom_specific_gravity("Custom Diamond"), None);
}
#[test]
fn no_override_falls_through_to_the_plain_by_name_lookup() {
let materials = GemMaterial::all_materials();
let by_name = resolve_material(&materials, &[], "Diamond").expect("Diamond resolves");
let via_override_fn =
resolve_material_with_override(&materials, &[], None, "Diamond").expect("Diamond resolves");
assert_eq!(by_name.name, via_override_fn.name);
assert_eq!(by_name.dispersion, via_override_fn.dispersion);
}
#[test]
fn an_override_wins_regardless_of_what_material_name_says() {
let materials = GemMaterial::all_materials();
let quartz = GemMaterial::new_custom("Quartz-ish", 1.5442, 0.013, 0.0, [0.0, 0.0, 0.0]);
let resolved = resolve_material_with_override(
&materials,
&[],
Some(&quartz),
"Diamond", )
.expect("an explicit override always resolves");
assert_eq!(resolved.name, quartz.name);
assert_eq!(resolved.dispersion, quartz.dispersion);
}
#[test]
fn an_unrecognized_name_refuses_rather_than_substituting_diamond() {
let materials = GemMaterial::all_materials();
assert_eq!(
resolve_material(&materials, &[], "no such stone"),
None,
"an unrecognized name must refuse, not silently resolve to Diamond"
);
assert_eq!(
resolve_material_with_override(&materials, &[], None, "no such stone"),
None,
"with no override, the by-name refusal must still propagate"
);
}
#[test]
fn a_display_only_epoch_acts_as_remote_only_until_released() {
use super::effective_live_target;
use crate::settings::LiveComputeTarget::{Both, LocalOnly, RemoteOnly};
assert_eq!(effective_live_target(Both, true), RemoteOnly);
assert_eq!(effective_live_target(Both, false), Both);
assert_eq!(effective_live_target(RemoteOnly, true), RemoteOnly);
assert_eq!(effective_live_target(LocalOnly, true), LocalOnly);
let mut ctx = RenderContext {
live_display_only: true,
remote_active: true,
..RenderContext::default()
};
assert_eq!(ctx.effective_live_target(), RemoteOnly);
ctx.release_remote();
assert!(!ctx.live_display_only);
assert_eq!(ctx.effective_live_target(), Both);
}
#[test]
fn the_editors_material_survives_a_library_selection_and_comes_back() {
let mut ctx = RenderContext::default();
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 1 },
));
"Sapphire".clone_into(&mut ctx.material_name);
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Catalogue { entry_id: 7 },
));
ctx.material_name.clear();
ctx.material_unresolved = Some("no material".to_string());
assert!(ctx.claim_active_planes(
Arc::new(Vec::new()),
None,
PlanesOwner::Editor { generation: 2 },
));
assert_eq!(ctx.material_name, "Sapphire");
assert!(ctx.material_unresolved.is_none());
assert!(ctx.editor_material_stash.is_none());
}