mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-03 21:24:17 +00:00
material: Add doc tests
Taken from the slint repo, these verify that the code snippets included in the docs compile.
Imported from d247c2b72c
This commit is contained in:
parent
256dfa7aaa
commit
cf08b23b56
5 changed files with 195 additions and 2 deletions
14
ui-libraries/material/.github/workflows/ci.yaml
vendored
14
ui-libraries/material/.github/workflows/ci.yaml
vendored
|
|
@ -27,6 +27,20 @@ jobs:
|
|||
secrets:
|
||||
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
||||
tests:
|
||||
env:
|
||||
CARGO_PROFILE_RELEASE_OPT_LEVEL: s
|
||||
CARGO_INCREMENTAL: false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
key: tests
|
||||
- name: Build & run tests
|
||||
run: cargo test
|
||||
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
|
||||
[workspace]
|
||||
members = ["crate", "examples/gallery"]
|
||||
default-members = ["crate", "examples/gallery"]
|
||||
members = ["crate", "examples/gallery", "tests/doctests"]
|
||||
default-members = ["crate", "examples/gallery", "tests/doctests"]
|
||||
resolver = "3"
|
||||
|
||||
[workspace.package]
|
||||
|
|
|
|||
25
ui-libraries/material/tests/doctests/Cargo.toml
Normal file
25
ui-libraries/material/tests/doctests/Cargo.toml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
[package]
|
||||
name = "doctests"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
homepage.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
version.workspace = true
|
||||
publish = false
|
||||
build = "build.rs"
|
||||
|
||||
[[bin]]
|
||||
path = "main.rs"
|
||||
name = "doctests"
|
||||
|
||||
[build-dependencies]
|
||||
walkdir = "2"
|
||||
|
||||
[dev-dependencies]
|
||||
slint-interpreter = { version = "1.12.0", features = ["display-diagnostics"] }
|
||||
spin_on = { version = "0.1" }
|
||||
101
ui-libraries/material/tests/doctests/build.rs
Normal file
101
ui-libraries/material/tests/doctests/build.rs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::path::Path;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let tests_file_path =
|
||||
std::path::Path::new(&std::env::var_os("OUT_DIR").unwrap()).join("test_functions.rs");
|
||||
let mut tests_file = BufWriter::new(std::fs::File::create(&tests_file_path)?);
|
||||
|
||||
let prefix = Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../..")
|
||||
.canonicalize()?;
|
||||
for entry in walkdir::WalkDir::new(&prefix)
|
||||
.follow_links(false)
|
||||
.into_iter()
|
||||
.filter_entry(|entry| entry.file_name() != "target")
|
||||
{
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
if path.extension().is_none_or(|e| e != "md" && e != "mdx") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let file = std::fs::read_to_string(path)?;
|
||||
let file = file.replace('\r', ""); // Remove \r, because Windows.
|
||||
|
||||
const BEGIN_MARKER: &str = "\n```slint";
|
||||
if !file.contains(BEGIN_MARKER) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let stem = path
|
||||
.strip_prefix(&prefix)?
|
||||
.to_string_lossy()
|
||||
.replace('-', "ˍ")
|
||||
.replace(['/', '\\'], "Ⳇ")
|
||||
.replace(['.'], "ᐧ")
|
||||
.to_lowercase();
|
||||
|
||||
writeln!(tests_file, "\nmod {stem} {{")?;
|
||||
|
||||
let mut rest = file.as_str();
|
||||
let mut line = 1;
|
||||
|
||||
while let Some(begin) = rest.find(BEGIN_MARKER) {
|
||||
line += rest[..begin].bytes().filter(|&c| c == b'\n').count() + 1;
|
||||
rest = rest[begin..].strip_prefix(BEGIN_MARKER).unwrap();
|
||||
|
||||
// Permit `slint,no-preview` and `slint,no-auto-preview` but skip `slint,ignore` and others.
|
||||
rest = match rest.split_once('\n') {
|
||||
Some((",ignore", _)) => continue,
|
||||
Some((x, _)) if x.contains("no-test") => continue,
|
||||
Some((_, rest)) => rest,
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
let end = rest.find("\n```\n").ok_or_else(|| {
|
||||
format!(
|
||||
"Could not find the end of a code snippet in {}",
|
||||
path.display()
|
||||
)
|
||||
})?;
|
||||
let snippet = &rest[..end];
|
||||
|
||||
if snippet.starts_with("{{#include") {
|
||||
// Skip non literal slint text
|
||||
continue;
|
||||
}
|
||||
|
||||
rest = &rest[end..];
|
||||
|
||||
write!(
|
||||
tests_file,
|
||||
r##"
|
||||
#[test]
|
||||
fn line_{}() {{
|
||||
crate::do_test("{}", "{}").unwrap();
|
||||
}}
|
||||
|
||||
"##,
|
||||
line,
|
||||
snippet.escape_default(),
|
||||
path.to_string_lossy().escape_default()
|
||||
)?;
|
||||
|
||||
line += snippet.bytes().filter(|&c| c == b'\n').count() + 1;
|
||||
}
|
||||
writeln!(tests_file, "}}")?;
|
||||
println!("cargo:rerun-if-changed={}", path.display());
|
||||
}
|
||||
|
||||
println!(
|
||||
"cargo:rustc-env=TEST_FUNCTIONS={}",
|
||||
tests_file_path.to_string_lossy()
|
||||
);
|
||||
println!("cargo:rustc-env=SLINT_ENABLE_EXPERIMENTAL_FEATURES=1");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
53
ui-libraries/material/tests/doctests/main.rs
Normal file
53
ui-libraries/material/tests/doctests/main.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#![allow(uncommon_codepoints)]
|
||||
|
||||
#[cfg(test)]
|
||||
fn do_test(snippet: &str, path: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let must_wrap = !snippet.contains("component ") && !snippet.contains("global ");
|
||||
|
||||
let code = if must_wrap {
|
||||
format!(
|
||||
"import {{
|
||||
CheckBox, CheckState, Switch, TimePicker, NavigationBar}} from\"material.slint\";
|
||||
component Example {{\n{snippet}\n}}"
|
||||
)
|
||||
} else {
|
||||
snippet.into()
|
||||
};
|
||||
|
||||
let mut compiler = slint_interpreter::Compiler::default();
|
||||
|
||||
compiler.set_include_paths(vec![std::path::PathBuf::from(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/../../"
|
||||
))]);
|
||||
|
||||
let result = spin_on::spin_on(compiler.build_from_source(code, path.into()));
|
||||
|
||||
let diagnostics = result
|
||||
.diagnostics()
|
||||
.filter(|d| {
|
||||
let msg = d.message();
|
||||
// It is ok if there is no components
|
||||
msg != "No component found"
|
||||
// Ignore warning about examples that don't inherit from Window or not exported
|
||||
&& !msg.contains(" doesn't inherit Window.")
|
||||
&& msg != "Component is implicitly marked for export. This is deprecated and it should be explicitly exported"
|
||||
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
slint_interpreter::print_diagnostics(&diagnostics);
|
||||
|
||||
if result.has_errors() && !diagnostics.is_empty() {
|
||||
return Err(format!("Error when loading {snippet:?} in {path:?}: {diagnostics:?}").into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
include!(env!("TEST_FUNCTIONS"));
|
||||
|
||||
fn main() {
|
||||
println!("Nothing to see here, please run me through cargo test :)");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue