Skip to content

Commit 86ac069

Browse files
committed
Disable printing during expected panics
1 parent 0e6a173 commit 86ac069

File tree

4 files changed

+93
-46
lines changed

4 files changed

+93
-46
lines changed

godot-core/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub mod private {
4242

4343
use crate::{log, sys};
4444

45-
sys::plugin_registry!(__GODOT_PLUGIN_REGISTRY: ClassPlugin);
45+
sys::plugin_registry!(pub __GODOT_PLUGIN_REGISTRY: ClassPlugin);
4646

4747
pub(crate) fn iterate_plugins(mut visitor: impl FnMut(&ClassPlugin)) {
4848
sys::plugin_foreach!(__GODOT_PLUGIN_REGISTRY; visitor);

godot-ffi/src/plugins.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
#[doc(hidden)]
1616
#[macro_export]
1717
macro_rules! plugin_registry {
18-
($registry:ident: $Type:ty) => {
18+
($vis:vis $registry:ident: $Type:ty) => {
1919
$crate::paste::paste! {
2020
#[used]
2121
#[allow(non_upper_case_globals)]
2222
#[doc(hidden)]
23-
pub static [< __godot_rust_plugin_ $registry >]:
23+
$vis static [< __godot_rust_plugin_ $registry >]:
2424
std::sync::Mutex<Vec<$Type>> = std::sync::Mutex::new(Vec::new());
2525
}
2626
};

godot-macros/src/itest.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ pub fn transform(input: TokenStream) -> Result<TokenStream, Error> {
5454

5555
::godot::sys::plugin_add!(__GODOT_ITEST in crate; crate::TestCase {
5656
name: #test_name_str,
57+
file: std::file!(),
58+
line: std::line!(),
5759
function: #test_name,
5860
});
5961
})

itest/rust/src/lib.rs

Lines changed: 88 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
*/
66

77
use godot::bind::{godot_api, GodotClass};
8+
use godot::builtin::ToVariant;
9+
use godot::engine::utilities::print_rich;
810
use godot::init::{gdextension, ExtensionLibrary};
911
use godot::sys;
1012
use godot::test::itest;
11-
use std::panic::UnwindSafe;
13+
use std::collections::HashSet;
14+
use std::panic;
1215

1316
mod array_test;
1417
mod base_test;
@@ -29,17 +32,8 @@ mod utilities_test;
2932
mod variant_test;
3033
mod virtual_methods_test;
3134

32-
33-
#[derive(Copy, Clone)]
34-
pub struct TestCase {
35-
name: &'static str,
36-
function: fn(),
37-
}
38-
3935
#[must_use]
4036
fn run_test(test: &TestCase) -> bool {
41-
println!(" -- {}", test.name);
42-
4337
// Explicit type to prevent tests from returning a value
4438
let success: Option<()> =
4539
godot::private::handle_panic(|| format!(" !! Test {} failed", test.name), test.function);
@@ -49,31 +43,25 @@ fn run_test(test: &TestCase) -> bool {
4943

5044
sys::plugin_registry!(__GODOT_ITEST: TestCase);
5145

52-
// fn register_classes() {
53-
// object_test::register();
54-
// gdscript_ffi_test::register();
55-
// virtual_methods_test::register();
56-
// }
57-
58-
fn run_tests() -> bool {
59-
let mut tests: Vec<TestCase> = vec![];
60-
61-
sys::plugin_foreach!(__GODOT_ITEST; |test: &TestCase| {
62-
tests.push(*test);
63-
});
64-
65-
println!("Collected {} tests.", tests.len());
66-
67-
68-
let mut stats = TestStats::default();
69-
for test in tests {
70-
stats.tests_run += 1;
71-
if run_test(&test) {
72-
stats.tests_passed += 1;
73-
}
46+
fn print_test(test: &TestCase, passed: bool, last_file: &mut Option<&'static str>) {
47+
// Check if we need to open a new category for a file
48+
let print_file = last_file.map_or(true, |last_file| last_file != test.file);
49+
if print_file {
50+
let sep_pos = test.file.rfind(&['/', '\\']).unwrap_or(0);
51+
println!("\n {}:", &test.file[sep_pos + 1..]);
7452
}
7553

76-
stats.tests_run == stats.tests_passed
54+
// Print the test itself
55+
let outcome = if passed {
56+
"[color=green]ok[/color]"
57+
} else {
58+
"[color=red]FAILED[/color]"
59+
};
60+
let output = format!(" -- {} ... {}", test.name, outcome);
61+
print_rich(output.to_variant(), &[]);
62+
63+
// State update for file-category-print
64+
*last_file = Some(test.file);
7765
}
7866

7967
// ----------------------------------------------------------------------------------------------------------------------------------------------
@@ -84,28 +72,85 @@ unsafe impl ExtensionLibrary for IntegrationTests {}
8472

8573
#[derive(GodotClass, Debug)]
8674
#[class(base=Node, init)]
87-
struct IntegrationTests {}
75+
struct IntegrationTests {
76+
tests_run: i64,
77+
tests_passed: i64,
78+
tests_skipped: i64,
79+
}
8880

8981
#[godot_api]
9082
impl IntegrationTests {
83+
// TODO could return a Stats object with properties in the future
9184
#[func]
92-
fn test_all(&mut self) -> bool {
85+
fn test_all(&mut self) {
9386
println!("Run Godot integration tests...");
94-
run_tests()
87+
self.run_tests();
88+
}
89+
90+
#[func]
91+
fn num_run(&self) -> i64 {
92+
self.tests_run
93+
}
94+
95+
#[func]
96+
fn num_passed(&self) -> i64 {
97+
self.tests_passed
98+
}
99+
100+
#[func]
101+
fn num_skipped(&self) -> i64 {
102+
self.tests_skipped
103+
}
104+
105+
fn run_tests(&mut self) {
106+
let mut tests: Vec<TestCase> = vec![];
107+
108+
let mut all_files = HashSet::new();
109+
sys::plugin_foreach!(__GODOT_ITEST; |test: &TestCase| {
110+
all_files.insert(test.file);
111+
tests.push(*test);
112+
});
113+
114+
println!(
115+
"Rust: found {} tests in {} files.",
116+
tests.len(),
117+
all_files.len()
118+
);
119+
120+
let mut last_file = None;
121+
for test in tests {
122+
let passed = run_test(&test);
123+
124+
self.tests_run += 1;
125+
if passed {
126+
self.tests_passed += 1;
127+
}
128+
129+
print_test(&test, passed, &mut last_file);
130+
}
95131
}
96132
}
97133

98-
pub(crate) fn expect_panic(context: &str, code: impl FnOnce() + UnwindSafe) {
99-
let panic = std::panic::catch_unwind(code);
134+
pub(crate) fn expect_panic(context: &str, code: impl FnOnce() + panic::UnwindSafe) {
135+
// Exchange panic hook, to disable printing during expected panics
136+
let prev_hook = panic::take_hook();
137+
panic::set_hook(Box::new(|_panic_info| {}));
138+
139+
// Run code that should panic, restore hook
140+
let panic = panic::catch_unwind(code);
141+
panic::set_hook(prev_hook);
142+
100143
assert!(
101144
panic.is_err(),
102145
"code should have panicked but did not: {context}",
103146
);
104147
}
105148

106-
#[derive(Default)]
107-
struct TestStats {
108-
tests_run: usize,
109-
tests_passed: usize,
110-
tests_skipped: usize,
149+
#[derive(Copy, Clone)]
150+
struct TestCase {
151+
name: &'static str,
152+
file: &'static str,
153+
#[allow(dead_code)]
154+
line: u32,
155+
function: fn(),
111156
}

0 commit comments

Comments
 (0)