#![cfg(feature = "query")]
#![allow(dead_code)]
use libtmux::Filterable;
use libtmux::query::{FilterEnum, Filterable as _, QueryIteratorExt};
#[derive(Clone, Copy)]
enum WorkflowState {
Ready,
Blocked,
}
impl FilterEnum for WorkflowState {
const FILTER_VARIANTS: &'static [&'static str] = &["ready", "blocked"];
fn filter_name(&self) -> &'static str {
match self {
Self::Ready => "ready",
Self::Blocked => "blocked",
}
}
}
#[derive(Filterable)]
#[filterable(target = "child", crate = "libtmux")]
struct Child {
label: String,
active: bool,
}
#[derive(Filterable)]
#[filterable(target = "collision_target", crate = "libtmux")]
struct InherentTargetCollision {
label: String,
}
impl InherentTargetCollision {
const FILTER_TARGET: &'static str = "inherent_target";
}
#[derive(Filterable)]
#[filterable(target = "work_item", fields = "TaskHandles", crate = "libtmux")]
struct Task {
#[filterable(rename = "name")]
summary: String,
done: bool,
score: Option<i16>,
#[filterable(enum)]
state: WorkflowState,
#[filterable(skip)]
private_note: String,
#[filterable(many)]
children: Vec<Child>,
#[filterable(one)]
owner: Option<Child>,
}
fn assert_value_traits<T: Clone + Copy + core::fmt::Debug + Eq + Send + Sync>() {}
fn fixture() -> Vec<Task> {
vec![
Task {
summary: String::from("build"),
done: false,
score: Some(7),
state: WorkflowState::Ready,
private_note: String::from("first-secret"),
children: vec![Child {
label: String::from("compile"),
active: true,
}],
owner: None,
},
Task {
summary: String::from("test"),
done: true,
score: None,
state: WorkflowState::Blocked,
private_note: String::from("second-secret"),
children: Vec::new(),
owner: Some(Child {
label: String::from("review"),
active: true,
}),
},
Task {
summary: String::from("deploy"),
done: false,
score: None,
state: WorkflowState::Ready,
private_note: String::from("third-secret"),
children: vec![Child {
label: String::from("ship"),
active: false,
}],
owner: Some(Child {
label: String::from("release"),
active: false,
}),
},
]
}
#[test]
fn root_derive_filters_downstream_vectors_in_order() {
let values = fixture();
let fields = Task::filter_fields();
let child_fields = Child::filter_fields();
let expression = fields
.summary
.contains("u")
.or(fields.owner.is(child_fields.active.eq(true)));
let selected = values
.iter()
.matching(&expression)
.map(|task| task.summary.as_str())
.collect::<Vec<_>>();
assert_eq!(selected, ["build", "test"]);
}
#[test]
fn generated_dispatch_handles_optional_scalars_enums_and_relations() {
let values = fixture();
let fields = Task::filter_fields();
let child_fields = Child::filter_fields();
assert!(fields.score.eq(7).matches(&values[0]));
assert!(!fields.score.eq(7).matches(&values[1]));
assert!(fields.score.not_in([]).matches(&values[0]));
assert!(!fields.score.not_in([]).matches(&values[1]));
assert!(fields.score.not_in([]).not().matches(&values[1]));
assert!(fields.state.eq(WorkflowState::Ready).matches(&values[0]));
assert!(!fields.state.eq(WorkflowState::Ready).matches(&values[1]));
assert!(
!fields
.children
.any(child_fields.active.eq(true))
.matches(&values[1])
);
assert!(
fields
.children
.all(child_fields.active.eq(true))
.matches(&values[1])
);
assert!(
fields
.children
.none(child_fields.active.eq(true))
.matches(&values[1])
);
assert!(
!fields
.owner
.is(child_fields.active.eq(true))
.matches(&values[0])
);
assert!(
fields
.owner
.is(child_fields.active.eq(true))
.matches(&values[1])
);
}
#[test]
fn generated_companion_has_stable_names_and_value_traits() {
assert_value_traits::<TaskHandles>();
assert_eq!(
<Task as libtmux::query::Filterable>::FILTER_TARGET,
"work_item"
);
let fields = Task::filter_fields();
let copied = fields;
assert_eq!(fields, copied);
let debug = format!("{fields:?}");
assert!(debug.contains("TaskHandles"));
assert!(debug.contains("work_item"));
assert!(debug.contains("name"));
assert!(!debug.contains("private_note"));
assert!(!debug.contains("first-secret"));
}
#[test]
fn generated_handles_use_trait_target_when_inherent_constant_collides() {
let fields = InherentTargetCollision::filter_fields();
let expected = libtmux::query::__private::text_field::<InherentTargetCollision>(
<InherentTargetCollision as libtmux::query::Filterable>::FILTER_TARGET,
"label",
);
assert_eq!(fields.label, expected);
}
#[test]
fn an_empty_relation_is_vacuously_true_for_all_and_false_for_any() {
let childless = Task {
summary: "alone".into(),
done: false,
score: None,
state: WorkflowState::Blocked,
private_note: String::new(),
children: Vec::new(),
owner: None,
};
let fields = Task::filter_fields();
let impossible = Child::filter_fields().label.eq("nothing matches this");
assert!(
fields.children.all(impossible.clone()).matches(&childless),
"all holds over no children",
);
assert!(
!fields.children.any(impossible.clone()).matches(&childless),
"any holds over none of them",
);
assert!(
fields.children.none(impossible).matches(&childless),
"and none holds too",
);
}