mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 10:50:00 +00:00
C++ testing API: Intreoduce the ElementHandle
This commit is contained in:
parent
13fe59cc2e
commit
475ced0a62
15 changed files with 225 additions and 25 deletions
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
|
@ -342,7 +342,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
crate: cross
|
crate: cross
|
||||||
- name: Check
|
- name: Check
|
||||||
run: cross check --target=armv7-unknown-linux-gnueabihf -p slint-cpp --no-default-features --features=internal-testing,interpreter,std
|
run: cross check --target=armv7-unknown-linux-gnueabihf -p slint-cpp --no-default-features --features=testing,interpreter,std
|
||||||
|
|
||||||
uefi-demo:
|
uefi-demo:
|
||||||
env:
|
env:
|
||||||
|
|
|
@ -104,6 +104,7 @@ define_cargo_dependent_feature(backend-linuxkms-noseat "Enable support for the b
|
||||||
|
|
||||||
define_cargo_dependent_feature(gettext "Enable support of translations using gettext" OFF "NOT SLINT_FEATURE_FREESTANDING")
|
define_cargo_dependent_feature(gettext "Enable support of translations using gettext" OFF "NOT SLINT_FEATURE_FREESTANDING")
|
||||||
define_cargo_dependent_feature(accessibility "Enable integration with operating system provided accessibility APIs" ON "NOT SLINT_FEATURE_FREESTANDING")
|
define_cargo_dependent_feature(accessibility "Enable integration with operating system provided accessibility APIs" ON "NOT SLINT_FEATURE_FREESTANDING")
|
||||||
|
define_cargo_dependent_feature(testing "Enable support for testing API (experimental)" ON "NOT SLINT_FEATURE_FREESTANDING")
|
||||||
define_cargo_feature(experimental "Enable experimental features. (No backward compatibility guarantees)" OFF)
|
define_cargo_feature(experimental "Enable experimental features. (No backward compatibility guarantees)" OFF)
|
||||||
|
|
||||||
if (SLINT_BUILD_RUNTIME)
|
if (SLINT_BUILD_RUNTIME)
|
||||||
|
|
|
@ -27,7 +27,7 @@ name = "slint_cpp"
|
||||||
[features]
|
[features]
|
||||||
interpreter = ["slint-interpreter", "std"]
|
interpreter = ["slint-interpreter", "std"]
|
||||||
# Enable some function used by the integration tests
|
# Enable some function used by the integration tests
|
||||||
internal-testing = ["i-slint-backend-testing"]
|
testing = ["dep:i-slint-backend-testing"]
|
||||||
|
|
||||||
backend-qt = ["i-slint-backend-selector/backend-qt", "std"]
|
backend-qt = ["i-slint-backend-selector/backend-qt", "std"]
|
||||||
backend-winit = ["i-slint-backend-selector/backend-winit", "std"]
|
backend-winit = ["i-slint-backend-selector/backend-winit", "std"]
|
||||||
|
@ -51,7 +51,7 @@ default = ["std", "backend-winit", "renderer-femtovg", "backend-qt"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
i-slint-backend-selector = { workspace = true, optional = true }
|
i-slint-backend-selector = { workspace = true, optional = true }
|
||||||
i-slint-backend-testing = { workspace = true, optional = true }
|
i-slint-backend-testing = { workspace = true, optional = true, features = ["ffi"] }
|
||||||
i-slint-renderer-skia = { workspace = true, features = ["default", "x11", "wayland"], optional = true }
|
i-slint-renderer-skia = { workspace = true, features = ["default", "x11", "wayland"], optional = true }
|
||||||
i-slint-core = { workspace = true, features = ["ffi"] }
|
i-slint-core = { workspace = true, features = ["ffi"] }
|
||||||
slint-interpreter = { workspace = true, features = ["ffi", "compat-1-2"], optional = true }
|
slint-interpreter = { workspace = true, features = ["ffi", "compat-1-2"], optional = true }
|
||||||
|
|
|
@ -805,6 +805,29 @@ fn gen_backend_qt(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gen_testing(
|
||||||
|
root_dir: &Path,
|
||||||
|
include_dir: &Path,
|
||||||
|
dependencies: &mut Vec<PathBuf>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let config = default_config();
|
||||||
|
|
||||||
|
let mut crate_dir = root_dir.to_owned();
|
||||||
|
crate_dir.extend(["internal", "backends", "testing"].iter());
|
||||||
|
|
||||||
|
ensure_cargo_rerun_for_crate(&crate_dir, dependencies)?;
|
||||||
|
|
||||||
|
cbindgen::Builder::new()
|
||||||
|
.with_config(config)
|
||||||
|
.with_crate(crate_dir)
|
||||||
|
.with_include("slint_testing_internal.h")
|
||||||
|
.generate()
|
||||||
|
.context("Unable to generate bindings for slint_testing_internal.h")?
|
||||||
|
.write_to_file(include_dir.join("slint_testing_internal.h"));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn gen_platform(
|
fn gen_platform(
|
||||||
root_dir: &Path,
|
root_dir: &Path,
|
||||||
include_dir: &Path,
|
include_dir: &Path,
|
||||||
|
@ -933,7 +956,7 @@ macro_rules! declare_features {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_features! {interpreter backend_qt freestanding renderer_software renderer_skia experimental gettext}
|
declare_features! {interpreter backend_qt freestanding renderer_software renderer_skia experimental gettext testing}
|
||||||
|
|
||||||
/// Generate the headers.
|
/// Generate the headers.
|
||||||
/// `root_dir` is the root directory of the slint git repo
|
/// `root_dir` is the root directory of the slint git repo
|
||||||
|
@ -953,6 +976,9 @@ pub fn gen_all(
|
||||||
gen_corelib(root_dir, include_dir, &mut deps, enabled_features)?;
|
gen_corelib(root_dir, include_dir, &mut deps, enabled_features)?;
|
||||||
gen_backend_qt(root_dir, include_dir, &mut deps)?;
|
gen_backend_qt(root_dir, include_dir, &mut deps)?;
|
||||||
gen_platform(root_dir, include_dir, &mut deps)?;
|
gen_platform(root_dir, include_dir, &mut deps)?;
|
||||||
|
if enabled_features.testing {
|
||||||
|
gen_testing(root_dir, include_dir, &mut deps)?;
|
||||||
|
}
|
||||||
if enabled_features.interpreter {
|
if enabled_features.interpreter {
|
||||||
gen_interpreter(root_dir, include_dir, &mut deps)?;
|
gen_interpreter(root_dir, include_dir, &mut deps)?;
|
||||||
}
|
}
|
||||||
|
|
130
api/cpp/include/slint-testing.h
Normal file
130
api/cpp/include/slint-testing.h
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.2 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
|
#include "slint.h"
|
||||||
|
#include "slint_testing_internal.h"
|
||||||
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#ifdef SLINT_FEATURE_TESTING
|
||||||
|
|
||||||
|
namespace slint::testing {
|
||||||
|
/// Init the testing backend.
|
||||||
|
/// Should be called before any other Slint function that can access the platform.
|
||||||
|
/// Then future windows will not appear on the screen anymore
|
||||||
|
inline void init()
|
||||||
|
{
|
||||||
|
cbindgen_private::slint_testing_init_backend();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A Handle to an element to query accessible property for testing purposes.
|
||||||
|
///
|
||||||
|
/// Use find_by_accessible_label() to obtain all elements matching the given accessible label.
|
||||||
|
class ElementHandle
|
||||||
|
{
|
||||||
|
cbindgen_private::ItemRc inner;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Find all elements matching the given accessible label.
|
||||||
|
template<typename T>
|
||||||
|
static SharedVector<ElementHandle> find_by_accessible_label(const ComponentHandle<T> &component,
|
||||||
|
std::string_view label)
|
||||||
|
{
|
||||||
|
cbindgen_private::Slice<uint8_t> label_view {
|
||||||
|
const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(label.data())),
|
||||||
|
label.size()
|
||||||
|
};
|
||||||
|
auto vrc = component.into_dyn();
|
||||||
|
SharedVector<ElementHandle> result;
|
||||||
|
cbindgen_private::slint_testing_element_find_by_accessible_label(
|
||||||
|
&vrc, &label_view,
|
||||||
|
reinterpret_cast<SharedVector<cbindgen_private::ItemRc> *>(&result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the accessible-label of that element, if any.
|
||||||
|
std::optional<SharedString> accessible_label() const
|
||||||
|
{
|
||||||
|
SharedString result;
|
||||||
|
if (inner.item_tree.vtable()->accessible_string_property(
|
||||||
|
inner.item_tree.borrow(), inner.index,
|
||||||
|
cbindgen_private::AccessibleStringProperty::Label, &result)) {
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the accessible-value of that element, if any.
|
||||||
|
std::optional<SharedString> accessible_value() const
|
||||||
|
{
|
||||||
|
SharedString result;
|
||||||
|
if (inner.item_tree.vtable()->accessible_string_property(
|
||||||
|
inner.item_tree.borrow(), inner.index,
|
||||||
|
cbindgen_private::AccessibleStringProperty::Value, &result)) {
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the accessible-value of that element.
|
||||||
|
///
|
||||||
|
/// Setting the value will invoke the `accessible-action-set-value` callback.
|
||||||
|
void set_accessible_value(SharedString value) const
|
||||||
|
{
|
||||||
|
union SetValueHelper {
|
||||||
|
cbindgen_private::AccessibilityAction action;
|
||||||
|
SetValueHelper(SharedString value)
|
||||||
|
// : action { .set_value = { cbindgen_private::AccessibilityAction::Tag::SetValue,
|
||||||
|
// std::move(value) } }
|
||||||
|
{
|
||||||
|
new (&action.set_value) cbindgen_private::AccessibilityAction::SetValue_Body {
|
||||||
|
cbindgen_private::AccessibilityAction::Tag::SetValue, std::move(value)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
~SetValueHelper() { action.set_value.~SetValue_Body(); }
|
||||||
|
|
||||||
|
} action(std::move(value));
|
||||||
|
inner.item_tree.vtable()->accessibility_action(inner.item_tree.borrow(), inner.index,
|
||||||
|
&action.action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invokes the default accessibility action of that element (`accessible-action-default`).
|
||||||
|
void invoke_default_action() const
|
||||||
|
{
|
||||||
|
union DefaultActionHelper {
|
||||||
|
cbindgen_private::AccessibilityAction action;
|
||||||
|
DefaultActionHelper()
|
||||||
|
//: action { .tag = cbindgen_private::AccessibilityAction::Tag::Default }
|
||||||
|
{
|
||||||
|
action.tag = cbindgen_private::AccessibilityAction::Tag::Default;
|
||||||
|
}
|
||||||
|
~DefaultActionHelper() { }
|
||||||
|
|
||||||
|
} action;
|
||||||
|
inner.item_tree.vtable()->accessibility_action(inner.item_tree.borrow(), inner.index,
|
||||||
|
&action.action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the size of this element
|
||||||
|
LogicalSize size() const
|
||||||
|
{
|
||||||
|
auto rect = inner.item_tree.vtable()->item_geometry(inner.item_tree.borrow(), inner.index);
|
||||||
|
return LogicalSize({ rect.width, rect.height });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the absolute position of this element
|
||||||
|
LogicalPosition absolute_position() const
|
||||||
|
{
|
||||||
|
cbindgen_private::LogicalRect rect =
|
||||||
|
inner.item_tree.vtable()->item_geometry(inner.item_tree.borrow(), inner.index);
|
||||||
|
cbindgen_private::LogicalPoint abs = slint::cbindgen_private::slint_item_absolute_position(
|
||||||
|
&inner.item_tree, inner.index);
|
||||||
|
return LogicalPosition({ abs.x + rect.x, abs.y + rect.y });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SLINT_FEATURE_TESTING
|
|
@ -2,19 +2,13 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.2 OR LicenseRef-Slint-commercial
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.2 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "slint.h"
|
#include "slint-testing.h"
|
||||||
#include <concepts>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// this file contains function useful for internal testing
|
// this file contains function useful for internal testing
|
||||||
|
|
||||||
namespace slint::private_api::testing {
|
namespace slint::private_api::testing {
|
||||||
|
|
||||||
inline void init()
|
|
||||||
{
|
|
||||||
cbindgen_private::slint_testing_init_backend();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void mock_elapsed_time(int64_t time_in_ms)
|
inline void mock_elapsed_time(int64_t time_in_ms)
|
||||||
{
|
{
|
||||||
cbindgen_private::slint_mock_elapsed_time(time_in_ms);
|
cbindgen_private::slint_mock_elapsed_time(time_in_ms);
|
||||||
|
|
|
@ -24,8 +24,10 @@ pub fn with_platform<R>(
|
||||||
i_slint_core::with_platform(|| Err(i_slint_core::platform::PlatformError::NoPlatform), f)
|
i_slint_core::with_platform(|| Err(i_slint_core::platform::PlatformError::NoPlatform), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One need to make sure something from the crate is exported,
|
// One need to make sure something from the crate is exported,
|
||||||
/// otherwise its symbols are not going to be in the final binary
|
// otherwise its symbols are not going to be in the final binary
|
||||||
|
#[cfg(feature = "testing")]
|
||||||
|
pub use i_slint_backend_testing;
|
||||||
#[cfg(feature = "slint-interpreter")]
|
#[cfg(feature = "slint-interpreter")]
|
||||||
pub use slint_interpreter;
|
pub use slint_interpreter;
|
||||||
|
|
||||||
|
@ -138,12 +140,6 @@ pub unsafe extern "C" fn slint_register_bitmap_font(
|
||||||
window_adapter.renderer().register_bitmap_font(font_data);
|
window_adapter.renderer().register_bitmap_font(font_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "internal-testing")]
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn slint_testing_init_backend() {
|
|
||||||
i_slint_backend_testing::init_no_event_loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
mod allocator {
|
mod allocator {
|
||||||
use core::alloc::Layout;
|
use core::alloc::Layout;
|
||||||
|
|
|
@ -19,6 +19,8 @@ path = "lib.rs"
|
||||||
[features]
|
[features]
|
||||||
# Internal feature that is only enabled for Slint's own tests
|
# Internal feature that is only enabled for Slint's own tests
|
||||||
internal = []
|
internal = []
|
||||||
|
# ffi for C++ bindings
|
||||||
|
ffi = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
i-slint-core = { workspace = true }
|
i-slint-core = { workspace = true }
|
||||||
|
|
25
internal/backends/testing/ffi.rs
Normal file
25
internal/backends/testing/ffi.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.2 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
|
use i_slint_core::accessibility::AccessibleStringProperty;
|
||||||
|
use i_slint_core::item_tree::ItemTreeRc;
|
||||||
|
use i_slint_core::items::ItemRc;
|
||||||
|
use i_slint_core::slice::Slice;
|
||||||
|
use i_slint_core::SharedVector;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn slint_testing_init_backend() {
|
||||||
|
crate::init_integration_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn slint_testing_element_find_by_accessible_label(
|
||||||
|
root: &ItemTreeRc,
|
||||||
|
label: &Slice<u8>,
|
||||||
|
out: &mut SharedVector<ItemRc>,
|
||||||
|
) {
|
||||||
|
let Ok(label) = core::str::from_utf8(label.as_slice()) else { return };
|
||||||
|
*out = crate::search_api::search_item(root, |item| {
|
||||||
|
item.accessible_string_property(AccessibleStringProperty::Label).is_some_and(|x| x == label)
|
||||||
|
})
|
||||||
|
}
|
|
@ -13,6 +13,8 @@ pub use internal_tests::*;
|
||||||
mod testing_backend;
|
mod testing_backend;
|
||||||
#[cfg(feature = "internal")]
|
#[cfg(feature = "internal")]
|
||||||
pub use testing_backend::*;
|
pub use testing_backend::*;
|
||||||
|
#[cfg(feature = "ffi")]
|
||||||
|
mod ffi;
|
||||||
|
|
||||||
/// Initialize the testing backend without support for event loop.
|
/// Initialize the testing backend without support for event loop.
|
||||||
/// This means that each test thread can use its own backend, but global functions that needs
|
/// This means that each test thread can use its own backend, but global functions that needs
|
||||||
|
|
|
@ -5,10 +5,13 @@ use i_slint_core::accessibility::{AccessibilityAction, AccessibleStringProperty}
|
||||||
use i_slint_core::item_tree::{ItemTreeRc, ItemVisitorResult, TraversalOrder};
|
use i_slint_core::item_tree::{ItemTreeRc, ItemVisitorResult, TraversalOrder};
|
||||||
use i_slint_core::items::ItemRc;
|
use i_slint_core::items::ItemRc;
|
||||||
use i_slint_core::window::WindowInner;
|
use i_slint_core::window::WindowInner;
|
||||||
use i_slint_core::SharedString;
|
use i_slint_core::{SharedString, SharedVector};
|
||||||
|
|
||||||
fn search_item(item_tree: &ItemTreeRc, mut filter: impl FnMut(&ItemRc) -> bool) -> Vec<ItemRc> {
|
pub(crate) fn search_item(
|
||||||
let mut result = vec![];
|
item_tree: &ItemTreeRc,
|
||||||
|
mut filter: impl FnMut(&ItemRc) -> bool,
|
||||||
|
) -> SharedVector<ItemRc> {
|
||||||
|
let mut result = SharedVector::default();
|
||||||
i_slint_core::item_tree::visit_items(
|
i_slint_core::item_tree::visit_items(
|
||||||
item_tree,
|
item_tree,
|
||||||
TraversalOrder::BackToFront,
|
TraversalOrder::BackToFront,
|
||||||
|
|
|
@ -46,7 +46,27 @@ assert_eq!(button.absolute_position(), slint::LogicalPosition::new(123., 143.));
|
||||||
assert_eq!(button.size(), slint::LogicalSize::new(143., 76.));
|
assert_eq!(button.size(), slint::LogicalSize::new(143., 76.));
|
||||||
|
|
||||||
assert_eq!(button.accessible_value().unwrap(), "0");
|
assert_eq!(button.accessible_value().unwrap(), "0");
|
||||||
button.set_accessible_value("45".into());
|
instance.invoke_call();
|
||||||
assert_eq!(button.accessible_value().unwrap(), "45");
|
assert_eq!(button.accessible_value().unwrap(), "45");
|
||||||
|
button.set_accessible_value("78".into());
|
||||||
|
assert_eq!(button.accessible_value().unwrap(), "78");
|
||||||
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
auto handle = TestCase::create();
|
||||||
|
const TestCase &instance = *handle;
|
||||||
|
|
||||||
|
auto button_search = slint::testing::ElementHandle::find_by_accessible_label(handle, "Hello");
|
||||||
|
assert_eq(button_search.size(), 1);
|
||||||
|
auto button = button_search[0];
|
||||||
|
|
||||||
|
assert(button.absolute_position() == slint::LogicalPosition({123., 143.}));
|
||||||
|
assert(button.size() == slint::LogicalSize({143., 76.}));
|
||||||
|
|
||||||
|
assert_eq(button.accessible_value().value(), "0");
|
||||||
|
instance.invoke_call();
|
||||||
|
assert_eq(button.accessible_value().value(), "45");
|
||||||
|
button.set_accessible_value("78");
|
||||||
|
assert_eq(button.accessible_value().value(), "78");
|
||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,7 +18,7 @@ path = "main.rs"
|
||||||
name = "test-driver-cpp"
|
name = "test-driver-cpp"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
slint-cpp = { workspace = true, features = ["internal-testing", "std"] }
|
slint-cpp = { workspace = true, features = ["testing", "std"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
i-slint-compiler = { workspace = true, features = ["default", "cpp", "display-diagnostics"] }
|
i-slint-compiler = { workspace = true, features = ["default", "cpp", "display-diagnostics"] }
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub fn test(testcase: &test_driver_lib::TestCase) -> Result<(), Box<dyn Error>>
|
||||||
namespace slint_testing = slint::private_api::testing;
|
namespace slint_testing = slint::private_api::testing;
|
||||||
",
|
",
|
||||||
)?;
|
)?;
|
||||||
generated_cpp.write_all(b"int main() {\n slint::private_api::testing::init();\n")?;
|
generated_cpp.write_all(b"int main() {\n slint::testing::init();\n")?;
|
||||||
for x in test_driver_lib::extract_test_functions(&source).filter(|x| x.language_id == "cpp") {
|
for x in test_driver_lib::extract_test_functions(&source).filter(|x| x.language_id == "cpp") {
|
||||||
write!(generated_cpp, " {{\n {}\n }}\n", x.source.replace("\n", "\n "))?;
|
write!(generated_cpp, " {{\n {}\n }}\n", x.source.replace("\n", "\n "))?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ pub fn generate(show_warnings: bool) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
renderer_skia: true,
|
renderer_skia: true,
|
||||||
experimental: false,
|
experimental: false,
|
||||||
gettext: true,
|
gettext: true,
|
||||||
|
testing: true,
|
||||||
};
|
};
|
||||||
cbindgen::gen_all(&root, &generated_headers_dir, enabled_features)?;
|
cbindgen::gen_all(&root, &generated_headers_dir, enabled_features)?;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue