use std::sync::Arc;
use std::time::{Duration, Instant};
use arrow::array::{Int32Array, RecordBatch, StringArray, StructArray};
use arrow::datatypes::{DataType, Field, Fields, Schema};
use datafusion::prelude::SessionContext;
use egui_kittest::Harness;
use parking_lot::Mutex;
use re_dataframe_ui::{DataFusionTableWidget, TableStatus};
use re_test_context::TestContext;
use re_viewer_context::AsyncRuntimeHandle;
#[tokio::test]
async fn test_text_truncation() {
let (session_context, table_ref) = prepare_session_context();
let test_context = TestContext::new();
let runtime_handle = AsyncRuntimeHandle::from_current_tokio_runtime_or_wasmbindgen().unwrap();
let table_status = Arc::new(Mutex::new(None::<TableStatus>));
let mut harness = test_context
.setup_kittest_for_rendering_ui([2500.0, 200.0])
.build_ui(|ui| {
test_context.run_recording(&ui.ctx().clone(), |ctx| {
let status = DataFusionTableWidget::new(Arc::clone(&session_context), table_ref)
.title("Text truncation")
.show(ctx, &runtime_handle, ui);
table_status.lock().replace(status);
});
});
run_async_harness(&mut harness, &table_status).await;
harness.snapshot("test_text_truncation");
}
fn prepare_session_context() -> (Arc<SessionContext>, &'static str) {
let lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.";
let struct_fields = Fields::from(vec![Field::new("description", DataType::Utf8, false)]);
let schema = Arc::new(Schema::new_with_metadata(
vec![
Field::new("text", DataType::Utf8, false),
Field::new("number", DataType::Int32, false),
Field::new("structured", DataType::Struct(struct_fields.clone()), false),
],
Default::default(),
));
let struct_array = StructArray::new(
struct_fields,
vec![Arc::new(StringArray::from(vec![lorem]))],
None,
);
let batch = RecordBatch::try_new_with_options(
schema.clone(),
vec![
Arc::new(StringArray::from(vec![lorem])),
Arc::new(Int32Array::from(vec![42])),
Arc::new(struct_array),
],
&Default::default(),
)
.expect("Failed to create a record batch");
let session_context = Arc::new(SessionContext::new());
let table_ref = "test_table";
session_context
.register_batch(table_ref, batch)
.expect("Failed to register the table");
(session_context, table_ref)
}
async fn run_async_harness(
harness: &mut Harness<'_>,
table_status: &Arc<Mutex<Option<TableStatus>>>,
) {
let timeout = Duration::from_secs(20);
let start = Instant::now();
loop {
assert!(
start.elapsed() <= timeout,
"Test timed out waiting for table to load"
);
harness.run_steps(2);
tokio::task::yield_now().await;
let status = table_status.lock();
match status.as_ref() {
Some(TableStatus::InitialLoading | TableStatus::Updating) => {}
Some(TableStatus::Loaded) => break,
Some(TableStatus::Error(err)) => panic!("Failed to load the table: {err}"),
None => panic!("No table status (should not happen)"),
}
}
}