-
Notifications
You must be signed in to change notification settings - Fork 499
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
Add element type information and ids to the testing API #5254
base: master
Are you sure you want to change the base?
Conversation
243f773
to
1069811
Compare
Oops, too early to review. There are some issues. |
pub struct ElementDebugInfo { | ||
// The id qualified with the enclosing component name. Given `foo := Bar {}` this is `EnclosingComponent::foo` | ||
pub qualified_id: Option<String>, | ||
pub type_name: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you have no access to the AST anymore? Otherwise that info is not too hard to find ;-)
What happens when you import Button as MyButton? What's going to be stored in there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly because of that this patch does not use the AST. It should be Button, not MyBytton. That’s why the code uses the ElementType’s type_name():
slint/internal/compiler/object_tree.rs
Line 942 in 1069811
let type_name = base_type.type_name().unwrap_or_default().to_string(); |
20d9131
to
c918cda
Compare
4ed68de
to
6058260
Compare
7977853
to
330ba4f
Compare
/// Enables the emission of additional debug information in the generated code, | ||
/// needed for use with Slint's testing APIs. Disabled by default. | ||
#[must_use] | ||
pub fn with_debug_info(self, enable: bool) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds this public API right now, however the "Slint's testing APIs" are not yet stable. Should this be behind an experimental flag? Or maybe just left out at this point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we leave it out, the experimental APIs cannot be used - so it's a bit of a chicken and egg problem. So I'd keep this in and in the unlikely event that we totally decide against having a testing API, then we deprecate this function and make it a no-op.
@@ -345,6 +345,11 @@ fn extract_compiler_config( | |||
_ => break, | |||
} | |||
} | |||
Some(TokenTree::Ident(debug_info_ident)) | |||
if debug_info_ident.to_string() == "debug_info" => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the problem with that is that the developer can't make this conditional to a feature in this crate or something like that.
I'm a bit unsure on how best to do that.
Perhaps an env variable set from the build.rs would be better?
Or is there a way to detect if it is building a test? Maybe CARGO_CFG_TEST
but i don't know if it's set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is sub-optimal and not quite correct. I did that just so that our own tests pass, but this is not really suitable. I'd keep this like the other options we have there, but they are undocumented.
Since we're not in build.rs but in the crate build itself, maybe CARG_CFG_TEST
works - that would be nice. I can try that.
There's one other scenario and that's system tests for a Rust app that uses this macro. I ran into this in the example app, but I guess I need to change that to just not use the macro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah no, I think I got it wrong - we still need a solution for build.rs, and inside build.rs we don't know if later tests will be run or not.
Ok, alternate proposal:
Objective:
- Support unit testing via search_api.rs for Rust applications, using build.rs and the slint! macro.
- Support unit testing via slint-testing.h for C++ apps
- Support system testing via Rust and a
slint/system-testing
feature - Support system testing via C++ and a
SLINT_FEATURE_SYSTEM_TESTING
feature
(In theory we have the same for JS and Python, but those use the interpreter and we always have the info available, or can access it if needed)
- We remove any
debug_info(bool)
/--generate-debug-info=true
options from the compiler. - We always emit the code to retrieve the element information, but we guard it with
#[cfg(test)]
and#ifdef SLINT_ENABLE_DEBUG_INFO
(or so). This covers both (1) and (2). - For (4), we could add a define to the interface definitions, and it'll be visible during application compilation.
- For (3) .... I don't know yet.... :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We always emit the code to retrieve the element information, but we guard it with #[cfg(test)] and #ifdef SLINT_ENABLE_DEBUG_INFO (or so). This covers both (1) and (2).
Good idea. Although #[cfg(test)]
won't work with rust system-testing i think.
For the macro, we could forward the slint/system-testing feature to the macro.
For the build, we could either have a feature, or an api function, or the build.rs from slint crate (that doesn't exist) could print something based on the enabled feature so that the slint-build can access env variables.
I think for now we could simply use an env variable since it is internal only.
/// ("".into(), "ButtonBase::root".into()) | ||
/// ]); | ||
/// ``` | ||
pub fn element_type_names_and_ids( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it was me, I'd only give the "App::mybutton" and not the root for everything.
I'd have element_id(&self) -> Option<SharedString>
and element_type(&self) -> Option<SharedString>
as single function.
This means you cannot match based on the root.
Maybe we could do element_bases(&self) -> Option<impl Iterator<Item = SharedString>>
so we could still match on the root.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, that makes the API easier to use for the common case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is implemented now (also for C++).
I need to rebase this as the CI merges this with master and then it doesn't compile anymore due to compiler API changes. |
501eab5
to
f9c2e2d
Compare
also compile the LSP
Simplify a bit the llr generation so that there is less code duplication between Rust and C++
By default with C++ it's enabled if debug info is on CONFIG. For Rust it's in the CompilerConfiguration API. For the interpreter it's always enabled, since ... we have it.
Replace dummy accessible-label use with the new element id lookup mechanism for testing.
Keep merging elements, but remember the boundaries in the debug info, separated by a slash. Also fixed tests that rely on accessible-label being set only once. For example ``` Button { text: "foo"; } ``` will certainly have "foo" as accessible-label on `Button`, but its internal `Text` element has an implicit "accessible-label" set to the same value. So don't rely on that for now but search by id instead.
Describe what an id is and provide an example.
De-duplicate the example and the same code in the test.
…, type_name() and bases() functions This API may be easier to use.
f9c2e2d
to
b0364ec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is almost good to go. My only slight concern at this point is that the API in slint-build and slint-macro is being available even though this is still an experimental feature.
but since this cannot be used anyway i think it's probably fine to add it and to change later.
@@ -345,6 +345,11 @@ fn extract_compiler_config( | |||
_ => break, | |||
} | |||
} | |||
Some(TokenTree::Ident(debug_info_ident)) | |||
if debug_info_ident.to_string() == "debug_info" => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We always emit the code to retrieve the element information, but we guard it with #[cfg(test)] and #ifdef SLINT_ENABLE_DEBUG_INFO (or so). This covers both (1) and (2).
Good idea. Although #[cfg(test)]
won't work with rust system-testing i think.
For the macro, we could forward the slint/system-testing feature to the macro.
For the build, we could either have a feature, or an api function, or the build.rs from slint crate (that doesn't exist) could print something based on the enabled feature so that the slint-build can access env variables.
I think for now we could simply use an env variable since it is internal only.
@@ -72,5 +75,5 @@ fn can_optimize(elem: &ElementRc) -> bool { | |||
!e.bindings.keys().chain(analysis.iter().filter(|(_, v)| v.is_set).map(|(k, _)| k)).any(|k| { | |||
!e.property_declarations.contains_key(k.as_str()) | |||
&& base_type.properties.contains_key(k.as_str()) | |||
}) | |||
}) && e.accessibility_props.0.is_empty() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm thinking we should still be able to optimize that but make sure to keep the accessibility prop. Anyway, this is simpler for this PR so let's go with that.
This requires additional debug information to be generated, which is disabled by default in Rust and in C++ for release builds.