Skip to content

Commit

Permalink
Test harness and "demo test" for the selection panel
Browse files Browse the repository at this point in the history
  • Loading branch information
abey79 committed May 25, 2024
1 parent 65ca659 commit 63d213b
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 3 deletions.
30 changes: 30 additions & 0 deletions crates/re_selection_panel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,33 @@ mod space_view_entity_picker;
mod space_view_space_origin_ui;

pub use selection_panel::SelectionPanel;

#[cfg(test)]
mod test {
use super::*;
use re_data_store::LatestAtQuery;
use re_viewer_context::{blueprint_timeline, Item, SpaceViewId};
use re_viewport_blueprint::ViewportBlueprint;

#[test]
fn test_selection_panel() {
re_log::setup_logging();

let mut test_ctx = re_viewer_context::test_context::TestContext::default();
test_ctx.edit_selection(|selection_state| {
selection_state.set_selection(Item::SpaceView(SpaceViewId::random()));
});

test_ctx.run(|ctx, ui| {
let (sender, _) = std::sync::mpsc::channel();
let blueprint = ViewportBlueprint::try_from_db(
ctx.store_context.blueprint,
&LatestAtQuery::latest(blueprint_timeline()),
sender,
);

let mut selection_panel = SelectionPanel::default();
selection_panel.show_panel(ctx, &blueprint, &mut Default::default(), ui, true);
});
}
}
4 changes: 3 additions & 1 deletion crates/re_viewer/src/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@ impl AppState {

viewport.is_item_valid(store_context, item)
},
re_viewer_context::Item::StoreId(store_context.recording.store_id().clone()),
Some(re_viewer_context::Item::StoreId(
store_context.recording.store_id().clone(),
)),
);

if ui.input(|i| i.key_pressed(egui::Key::Escape)) {
Expand Down
1 change: 1 addition & 0 deletions crates/re_viewer_context/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mod space_view;
mod store_context;
pub mod store_hub;
mod tensor;
pub mod test_context;
mod time_control;
mod typed_entity_collections;
mod utils;
Expand Down
6 changes: 4 additions & 2 deletions crates/re_viewer_context/src/selection_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ impl ApplicationSelectionState {
pub fn on_frame_start(
&mut self,
item_retain_condition: impl Fn(&Item) -> bool,
fallback_selection: Item,
fallback_selection: Option<Item>,
) {
// Use a different name so we don't get a collision in puffin.
re_tracing::profile_scope!("SelectionState::on_frame_start");
Expand All @@ -243,7 +243,9 @@ impl ApplicationSelectionState {
let selection_this_frame = self.selection_this_frame.get_mut();
selection_this_frame.retain(|item, _| item_retain_condition(item));
if selection_this_frame.is_empty() {
*selection_this_frame = ItemCollection::from(fallback_selection);
if let Some(fallback_selection) = fallback_selection {
*selection_this_frame = ItemCollection::from(fallback_selection);
}
}

// Hovering needs to be refreshed every frame: If it wasn't hovered last frame, it's no longer hovered!
Expand Down
115 changes: 115 additions & 0 deletions crates/re_viewer_context/src/test_context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
use crate::{
command_channel, ApplicationSelectionState, ComponentUiRegistry, StoreContext, ViewerContext,
};

use re_data_store::LatestAtQuery;
use re_entity_db::EntityDb;
use re_log_types::{StoreId, StoreKind};

/// Harness to execute code that rely on [`crate::ViewerContext`].
///
/// Example:
/// ```rust
/// use re_viewer_context::test_context::TestContext;
/// use re_viewer_context::ViewerContext;
///
/// let mut test_context = TestContext::default();
/// test_context.run(|ctx: &ViewerContext, _| {
/// /* do something with ctx */
/// });
/// ```
pub struct TestContext {
recording_store: EntityDb,
blueprint_store: EntityDb,
selection_state: ApplicationSelectionState,
}

impl Default for TestContext {
fn default() -> Self {
let recording_store = EntityDb::new(StoreId::random(StoreKind::Recording));
let blueprint_store = EntityDb::new(StoreId::random(StoreKind::Blueprint));
Self {
recording_store,
blueprint_store,
selection_state: Default::default(),
}
}
}

impl TestContext {
pub fn edit_selection(&mut self, edit_fn: impl FnOnce(&mut ApplicationSelectionState)) {
edit_fn(&mut self.selection_state);

// the selection state is double-buffered, so let's ensure it's updated
self.selection_state.on_frame_start(|_| true, None);
}

pub fn run(&self, mut func: impl FnMut(&ViewerContext<'_>, &mut egui::Ui)) {
egui::__run_test_ui(|ui| {
let re_ui = re_ui::ReUi::load_and_apply(ui.ctx());
let blueprint_query = LatestAtQuery::latest(re_log_types::Timeline::new(
"timeline",
re_log_types::TimeType::Time,
));
let (command_sender, _) = command_channel();
let component_ui_registry = ComponentUiRegistry::new(Box::new(
|_ctx, _ui, _ui_layout, _query, _db, _entity_path, _component, _instance| {},
));

let store_context = StoreContext {
app_id: "rerun_test".into(),
blueprint: &self.blueprint_store,
default_blueprint: None,
recording: &self.recording_store,
bundle: &Default::default(),
hub: &Default::default(),
};

let ctx = ViewerContext {
app_options: &Default::default(),
cache: &Default::default(),
component_ui_registry: &component_ui_registry,
space_view_class_registry: &Default::default(),
store_context: &store_context,
applicable_entities_per_visualizer: &Default::default(),
indicated_entities_per_visualizer: &Default::default(),
query_results: &Default::default(),
rec_cfg: &Default::default(),
blueprint_cfg: &Default::default(),
selection_state: &self.selection_state,
blueprint_query: &blueprint_query,
re_ui: &re_ui,
render_ctx: None,
command_sender: &command_sender,
focused_item: &None,
};

func(&ctx, ui);
});
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::Item;
use re_entity_db::InstancePath;

#[test]
fn test_edit_selection() {
let mut test_context = TestContext::default();

let item = Item::InstancePath(InstancePath::entity_all("/entity/path".into()));

test_context.edit_selection(|selection_state| {
selection_state.set_selection(item.clone());
});

test_context.run(|ctx, _| {
assert_eq!(
ctx.selection_state.selected_items().single_item(),
Some(&item)
);
});
}
}

0 comments on commit 63d213b

Please sign in to comment.