Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update accesskit #3

Merged
merged 1 commit into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,19 @@ version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef7442f1f520649b8e11ee3af6caeec24123fed4b63bc36a85b67308d8514fdf"

[[package]]
name = "accesskit"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45c97bb3cc1dacbdc6d1147040fc61309590d3e1ab5efd92a8a09c7a2e07284c"

[[package]]
name = "accesskit_consumer"
version = "0.24.1"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7072a4f17b8e7440a88ce08eb657d1ec84be061b1a94be78f9699aa18e583885"
checksum = "fa3a17950ce0d911f132387777b9b3d05eddafb59b773ccaa53fceefaeb0228e"
dependencies = [
"accesskit",
"accesskit 0.17.0",
"immutable-chunkmap",
]

Expand Down Expand Up @@ -83,7 +89,7 @@ name = "egui"
version = "0.28.1"
source = "git+https://github.com/emilk/egui?rev=dae1979dd334ace310b6e3ef02e98281ed7dfb8e#dae1979dd334ace310b6e3ef02e98281ed7dfb8e"
dependencies = [
"accesskit",
"accesskit 0.16.1",
"ahash",
"emath",
"epaint",
Expand Down Expand Up @@ -127,7 +133,7 @@ dependencies = [
name = "kittest"
version = "0.1.0"
dependencies = [
"accesskit",
"accesskit 0.17.0",
"accesskit_consumer",
"egui",
"parking_lot",
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ default = []


[dependencies]
accesskit_consumer = "0.24.0"
accesskit = "0.16.0"
accesskit_consumer = "0.25.0"
accesskit = "0.17.0"
parking_lot = "0.12"

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion examples/basic_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
ctx,
app: Box::new(app),
state: kittest::State::new(
output

Check failure on line 30 in examples/basic_integration.rs

View workflow job for this annotation

GitHub Actions / Rust

mismatched types

Check failure on line 30 in examples/basic_integration.rs

View workflow job for this annotation

GitHub Actions / Rust

mismatched types
.platform_output
.accesskit_update
.expect("AccessKit not enabled"),
Expand All @@ -41,7 +41,7 @@
.take_events()
.into_iter()
.map(|e| match e {
Event::ActionRequest(action) => egui::Event::AccessKitActionRequest(action),

Check failure on line 44 in examples/basic_integration.rs

View workflow job for this annotation

GitHub Actions / Rust

mismatched types
Event::Simulated(_) => {
panic!("Check egui_kittest for a full implementation");
}
Expand All @@ -57,7 +57,7 @@
);

self.state.update(
output

Check failure on line 60 in examples/basic_integration.rs

View workflow job for this annotation

GitHub Actions / Rust

mismatched types

Check failure on line 60 in examples/basic_integration.rs

View workflow job for this annotation

GitHub Actions / Rust

mismatched types
.platform_output
.accesskit_update
.expect("AccessKit not enabled"),
Expand All @@ -83,7 +83,7 @@
});
});

harness.get_by_name("Check me!").click();
harness.get_by_label("Check me!").click();
harness.run_frame();

drop(harness);
Expand Down
28 changes: 14 additions & 14 deletions examples/querying.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,36 @@ use kittest::{by, Queryable};
fn main() {
let harness = make_tree();

// You can query nodes by their name (query_by_* functions always return an Option<Node>)
// You can query nodes by their label (query_by_* functions always return an Option<Node>)
let _button_1 = harness
.query_by_name("Button 1")
.query_by_label("Button 1")
.expect("Button 1 not found");

// You can get nodes by their name (get_by_* functions will panic with a helpful error message
// You can get nodes by their label (get_by_* functions will panic with a helpful error message
// if the node is not found)
let _button_2 = harness.get_by_name("Button 2");
let _button_2 = harness.get_by_label("Button 2");

// You can get all nodes with a certain name
let buttons = harness.query_all_by_name("Duplicate");
// You can get all nodes with a certain label
let buttons = harness.query_all_by_label("Duplicate");
assert_eq!(
buttons.count(),
2,
"Expected 2 buttons with the name 'Duplicate'"
"Expected 2 buttons with the label 'Duplicate'"
);

// If you have multiple items with the same name, you can query by name and role
let _submit = harness.get_by_role_and_name(Role::Button, "Submit");
// If you have multiple items with the same label, you can query by label and role
let _submit = harness.get_by_role_and_label(Role::Button, "Submit");

// If you need more complex queries, you can use the by struct
let _check_me = harness.get(by().role(Role::CheckBox).name_contains("Check"));
let _check_me = harness.get(by().role(Role::CheckBox).label_contains("Check"));

// You can also query children of a node
let group = harness.get_by_role_and_name(Role::Label, "My Group");
// get_by_name won't panic here since we only find the button in the group
group.get_by_name("Duplicate");
let group = harness.get_by_role_and_label(Role::Label, "My Group");
// get_by_label won't panic here since we only find the button in the group
group.get_by_label("Duplicate");

let btn_in_parent = harness
.get_all_by_name("Duplicate")
.get_all_by_label("Duplicate")
.next_back()
.expect("No buttons found");
assert_eq!(
Expand Down
50 changes: 25 additions & 25 deletions src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ pub fn by<'a>() -> By<'a> {
/// A filter for nodes.
/// The filters are combined with a logical AND.
pub struct By<'a> {
name: Option<&'a str>,
name_contains: bool,
label: Option<&'a str>,
label_contains: bool,
include_labels: bool,
#[allow(clippy::type_complexity)]
predicate: Option<Box<dyn Fn(&Node<'_>) -> bool + 'a>>,
Expand All @@ -25,8 +25,8 @@ pub struct By<'a> {
impl<'a> Debug for By<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let By {
name,
name_contains,
label,
label_contains,
include_labels,
predicate,
had_predicate,
Expand All @@ -35,11 +35,11 @@ impl<'a> Debug for By<'a> {
recursive,
} = self;
let mut s = f.debug_struct("By");
if let Some(name) = name {
if *name_contains {
s.field("name_contains", &name);
if let Some(label) = label {
if *label_contains {
s.field("label_contains", &label);
} else {
s.field("name", &name);
s.field("label", &label);
}
}
if *include_labels {
Expand Down Expand Up @@ -71,8 +71,8 @@ impl<'a> By<'a> {
/// Create an empty filter.
pub fn new() -> Self {
Self {
name: None,
name_contains: false,
label: None,
label_contains: false,
include_labels: false,
predicate: None,
had_predicate: false,
Expand All @@ -82,16 +82,16 @@ impl<'a> By<'a> {
}
}

/// Filter by the name of the node with an exact match.
pub fn name(mut self, name: &'a str) -> Self {
self.name = Some(name);
/// Filter by the label of the node with an exact match.
pub fn label(mut self, label: &'a str) -> Self {
self.label = Some(label);
self
}

/// Filter by the name of the node with a substring match.
pub fn name_contains(mut self, name: &'a str) -> Self {
self.name = Some(name);
self.name_contains = true;
/// Filter by the label of the node with a substring match.
pub fn label_contains(mut self, label: &'a str) -> Self {
self.label = Some(label);
self.label_contains = true;
self
}

Expand Down Expand Up @@ -130,7 +130,7 @@ impl<'a> By<'a> {

/// Should the labels of labelled nodes be filtered?
pub(crate) fn should_filter_labels(&self) -> bool {
!self.include_labels && self.name.is_some()
!self.include_labels && self.label.is_some()
}

/// Since we can't clone the predicate, we can't implement Clone for By.
Expand All @@ -139,8 +139,8 @@ impl<'a> By<'a> {
/// just remember if we had one.
pub(crate) fn debug_clone_without_predicate(&self) -> Self {
Self {
name: self.name,
name_contains: self.name_contains,
label: self.label,
label_contains: self.label_contains,
include_labels: self.include_labels,
predicate: None,
had_predicate: self.had_predicate,
Expand All @@ -155,13 +155,13 @@ impl<'a> By<'a> {
/// filtered like in [`crate::Queryable::query_all`].
/// Note: Remember to check for recursive filtering
pub(crate) fn matches(&self, node: &Node<'_>) -> bool {
if let Some(name) = self.name {
if let Some(node_name) = node.name() {
if self.name_contains {
if !node_name.contains(name) {
if let Some(label) = self.label {
if let Some(node_label) = node.label() {
if self.label_contains {
if !node_label.contains(label) {
return false;
}
} else if node_name != name {
} else if node_label != label {
return false;
}
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ impl<'a> Debug for Node<'a> {
let mut s = f.debug_struct("Node");
s.field("id", &self.node.id());
s.field("role", &self.node.role());
if let Some(name) = self.node.name() {
s.field("name", &name);
if let Some(label) = self.node.label() {
s.field("label", &label);
}
if let Some(value) = self.node.value() {
s.field("value", &value);
Expand Down Expand Up @@ -80,7 +80,7 @@ impl<'tree> Node<'tree> {
pub fn click(&self) {
self.event(Event::ActionRequest(ActionRequest {
data: None,
action: accesskit::Action::Default,
action: accesskit::Action::Click,
target: self.node.id(),
}));
}
Expand Down
60 changes: 30 additions & 30 deletions src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn query_all<'tree>(

let nodes = results.collect::<Vec<_>>();

// If the widget label is provided by a different node, both will have the same name.
// If the widget label is provided by a different node, both will have the same label.
// We only want to return the node that is labelled by the other node, not the label node.
// (This matches the behavior of the testing-library getByLabelText query.)
let labels: BTreeSet<_> = if should_filter_labels {
Expand Down Expand Up @@ -109,10 +109,10 @@ fn get<'tree>(node: Node<'tree>, by: By<'tree>) -> Node<'tree> {
macro_rules! impl_helper {
(
$match_doc:literal,
$query_all_name:ident,
$get_all_name:ident,
$query_name:ident,
$get_name:ident,
$query_all_label:ident,
$get_all_label:ident,
$query_label:ident,
$get_label:ident,
($($args:ident: $arg_ty:ty),*),
$by_expr:expr,
$(#[$extra_doc:meta])*
Expand All @@ -121,7 +121,7 @@ macro_rules! impl_helper {
#[doc = $match_doc]
$(#[$extra_doc])*
#[track_caller]
fn $query_all_name(
fn $query_all_label(
&'node self, $($args: $arg_ty),*
) -> impl DoubleEndedIterator<Item = Node<'tree>> + FusedIterator<Item = Node<'tree>> + 'tree {
query_all(self.node(), $by_expr)
Expand All @@ -135,7 +135,7 @@ macro_rules! impl_helper {
/// # Panics
/// - if no nodes are found matching the query.
#[track_caller]
fn $get_all_name(
fn $get_all_label(
&'node self, $($args: $arg_ty),*
) -> impl DoubleEndedIterator<Item = Node<'tree>> + FusedIterator<Item = Node<'tree>> + 'tree {
get_all(self.node(), $by_expr)
Expand All @@ -146,7 +146,7 @@ macro_rules! impl_helper {
/// Returns `None` if no nodes are found.
$(#[$extra_doc])*
#[track_caller]
fn $query_name(&'node self, $($args: $arg_ty),*) -> Option<Node<'tree>> {
fn $query_label(&'node self, $($args: $arg_ty),*) -> Option<Node<'tree>> {
query(self.node(), $by_expr)
}

Expand All @@ -158,7 +158,7 @@ macro_rules! impl_helper {
/// - if no nodes are found matching the query.
/// - if more than one node is found matching the query.
#[track_caller]
fn $get_name(&'node self, $($args: $arg_ty),*) -> Node<'tree> {
fn $get_label(&'node self, $($args: $arg_ty),*) -> Node<'tree> {
get(self.node(), $by_expr)
}
};
Expand All @@ -179,37 +179,37 @@ pub trait Queryable<'tree, 'node> {
);

impl_helper!(
"the node name exactly matches given name.",
query_all_by_name,
get_all_by_name,
query_by_name,
get_by_name,
(name: &'tree str),
By::new().name(name),
"the node label exactly matches given label.",
query_all_by_label,
get_all_by_label,
query_by_label,
get_by_label,
(label: &'tree str),
By::new().label(label),
#[doc = ""]
#[doc = "If a node is labelled by another node, the label node will not be included in the results."]
);

impl_helper!(
"the node name contains the given substring.",
query_all_by_name_contains,
get_all_by_name_contains,
query_by_name_contains,
get_by_name_contains,
(name: &'tree str),
By::new().name_contains(name),
"the node label contains the given substring.",
query_all_by_label_contains,
get_all_by_label_contains,
query_by_label_contains,
get_by_label_contains,
(label: &'tree str),
By::new().label_contains(label),
#[doc = ""]
#[doc = "If a node is labelled by another node, the label node will not be included in the results."]
);

impl_helper!(
"the node role and name exactly match the given role and name.",
query_all_by_role_and_name,
get_all_by_role_and_name,
query_by_role_and_name,
get_by_role_and_name,
(role: accesskit::Role, name: &'tree str),
By::new().role(role).name(name),
"the node role and label exactly match the given role and label.",
query_all_by_role_and_label,
get_all_by_role_and_label,
query_by_role_and_label,
get_by_role_and_label,
(role: accesskit::Role, label: &'tree str),
By::new().role(role).label(label),
#[doc = ""]
#[doc = "If a node is labelled by another node, the label node will not be included in the results."]
);
Expand Down
Loading