Skip to content

Commit 26f820d

Browse files
committed
Add integration tests to the ci pipeline to closer simulate a bevy user.
1 parent d8965cd commit 26f820d

File tree

11 files changed

+184
-2
lines changed

11 files changed

+184
-2
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ members = [
2929
# Bevy's error codes. This is a crate so we can automatically check all of the code blocks.
3030
"errors",
3131
]
32+
exclude = [
33+
# Integration tests are not part of the workspace
34+
"tests-integration",
35+
]
3236

3337
[workspace.lints.clippy]
3438
doc_markdown = "warn"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "remapped-test"
3+
edition = "2021"
4+
5+
[dependencies]
6+
bevi = { path = "../../", package = "bevy" }
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![allow(dead_code)]
2+
use bevi::prelude::*;
3+
4+
#[derive(Component)]
5+
struct _Component {
6+
_value: f32,
7+
}
8+
9+
#[derive(Resource)]
10+
struct _Resource {
11+
_value: f32,
12+
}
13+
14+
fn hello_world() {
15+
println!("hello world!");
16+
}
17+
18+
#[test]
19+
fn simple_ecs_test() {
20+
App::new().add_systems(Update, hello_world).run();
21+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "simple-ecs-test"
3+
edition = "2021"
4+
5+
[dependencies]
6+
bevy = { path = "../../" }
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![allow(dead_code)]
2+
use bevy::prelude::*;
3+
4+
#[derive(Component)]
5+
struct MyComponent {
6+
value: f32,
7+
}
8+
9+
#[derive(Resource)]
10+
struct MyResource {
11+
value: f32,
12+
}
13+
14+
fn hello_world(query: Query<&MyComponent>, resource: Res<MyResource>) {
15+
let component = query.iter().next().unwrap();
16+
let comp_value = component.value; // rust-analyzer suggestions work
17+
let res_value_deref = resource.value; // rust-analyzer suggestions don't work but ctrl+click works once it's written, also type inlay hints work correctly
18+
let res_value_direct = resource.into_inner().value; // rust-analyzer suggestions work
19+
println!(
20+
"hello world! Value: {} {} {}",
21+
comp_value, res_value_deref, res_value_direct
22+
);
23+
}
24+
25+
fn spawn_component(mut commands: Commands) {
26+
commands.spawn(MyComponent { value: 10.0 });
27+
}
28+
29+
#[test]
30+
fn simple_ecs_test() {
31+
App::new()
32+
.insert_resource(MyResource { value: 5.0 })
33+
.add_systems(Startup, spawn_component)
34+
.add_systems(Update, hello_world)
35+
.run();
36+
}

tools/ci/src/ci.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ impl CI {
7474
cmds.append(&mut commands::ClippyCommand::default().prepare(sh, flags));
7575
cmds.append(&mut commands::TestCommand::default().prepare(sh, flags));
7676
cmds.append(&mut commands::TestCheckCommand::default().prepare(sh, flags));
77+
cmds.append(&mut commands::IntegrationTestCommand::default().prepare(sh, flags));
78+
cmds.append(
79+
&mut commands::IntegrationTestCheckCommand::default().prepare(sh, flags),
80+
);
81+
cmds.append(
82+
&mut commands::IntegrationTestCleanCommand::default().prepare(sh, flags),
83+
);
7784
cmds.append(&mut commands::DocCheckCommand::default().prepare(sh, flags));
7885
cmds.append(&mut commands::DocTestCommand::default().prepare(sh, flags));
7986
cmds.append(&mut commands::CompileCheckCommand::default().prepare(sh, flags));
@@ -100,6 +107,9 @@ enum Commands {
100107
Clippy(commands::ClippyCommand),
101108
Test(commands::TestCommand),
102109
TestCheck(commands::TestCheckCommand),
110+
IntegrationTest(commands::IntegrationTestCommand),
111+
IntegrationTestCheck(commands::IntegrationTestCheckCommand),
112+
IntegrationTestClean(commands::IntegrationTestCleanCommand),
103113
DocCheck(commands::DocCheckCommand),
104114
DocTest(commands::DocTestCommand),
105115
CompileCheck(commands::CompileCheckCommand),
@@ -120,6 +130,9 @@ impl Prepare for Commands {
120130
Commands::Clippy(subcommand) => subcommand.prepare(sh, flags),
121131
Commands::Test(subcommand) => subcommand.prepare(sh, flags),
122132
Commands::TestCheck(subcommand) => subcommand.prepare(sh, flags),
133+
Commands::IntegrationTest(subcommand) => subcommand.prepare(sh, flags),
134+
Commands::IntegrationTestCheck(subcommand) => subcommand.prepare(sh, flags),
135+
Commands::IntegrationTestClean(subcommand) => subcommand.prepare(sh, flags),
123136
Commands::DocCheck(subcommand) => subcommand.prepare(sh, flags),
124137
Commands::DocTest(subcommand) => subcommand.prepare(sh, flags),
125138
Commands::CompileCheck(subcommand) => subcommand.prepare(sh, flags),

tools/ci/src/commands/compile.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use crate::{
22
commands::{
33
BenchCheckCommand, CompileCheckCommand, CompileFailCommand, ExampleCheckCommand,
4-
TestCheckCommand,
4+
IntegrationTestCheckCommand, TestCheckCommand,
55
},
66
Flag, Prepare, PreparedCommand,
77
};
88
use argh::FromArgs;
99

10-
/// Alias for running the `compile-fail`, `bench-check`, `example-check`, `compile-check`, and `test-check` subcommands.
10+
/// Alias for running the `compile-fail`, `bench-check`, `example-check`, `compile-check`, `test-check` and `test-integration-check` subcommands.
1111
#[derive(FromArgs, Default)]
1212
#[argh(subcommand, name = "compile")]
1313
pub struct CompileCommand {}
@@ -20,6 +20,7 @@ impl Prepare for CompileCommand {
2020
commands.append(&mut ExampleCheckCommand::default().prepare(sh, flags));
2121
commands.append(&mut CompileCheckCommand::default().prepare(sh, flags));
2222
commands.append(&mut TestCheckCommand::default().prepare(sh, flags));
23+
commands.append(&mut IntegrationTestCheckCommand::default().prepare(sh, flags));
2324
commands
2425
}
2526
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use crate::{commands::get_integration_tests, Flag, Prepare, PreparedCommand};
2+
use argh::FromArgs;
3+
use xshell::cmd;
4+
5+
/// Runs all integration tests (except for doc tests).
6+
#[derive(FromArgs, Default)]
7+
#[argh(subcommand, name = "integration-test")]
8+
pub struct IntegrationTestCommand {}
9+
10+
impl Prepare for IntegrationTestCommand {
11+
fn prepare<'a>(&self, sh: &'a xshell::Shell, flags: Flag) -> Vec<PreparedCommand<'a>> {
12+
let no_fail_fast = flags
13+
.contains(Flag::KEEP_GOING)
14+
.then_some("--no-fail-fast")
15+
.unwrap_or_default();
16+
17+
get_integration_tests(sh)
18+
.into_iter()
19+
.map(|path| {
20+
PreparedCommand::new::<Self>(
21+
cmd!(
22+
sh,
23+
"cargo test --manifest-path {path}/Cargo.toml --tests {no_fail_fast}"
24+
),
25+
"Please fix failing integration tests in output above.",
26+
)
27+
})
28+
.collect()
29+
}
30+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use std::path::Path;
2+
3+
use crate::{Flag, Prepare, PreparedCommand};
4+
use argh::FromArgs;
5+
use xshell::cmd;
6+
7+
pub fn get_integration_tests(sh: &xshell::Shell) -> Vec<String> {
8+
let integration_test_paths = sh.read_dir(Path::new("./tests-integration")).unwrap();
9+
10+
// Filter out non-directories
11+
integration_test_paths
12+
.into_iter()
13+
.filter(|path| path.is_dir())
14+
.map(|path| path.to_string_lossy().to_string())
15+
.collect()
16+
}
17+
18+
/// Checks that all integration tests compile.
19+
#[derive(FromArgs, Default)]
20+
#[argh(subcommand, name = "integration-test-check")]
21+
pub struct IntegrationTestCheckCommand {}
22+
23+
impl Prepare for IntegrationTestCheckCommand {
24+
fn prepare<'a>(&self, sh: &'a xshell::Shell, _flags: Flag) -> Vec<PreparedCommand<'a>> {
25+
get_integration_tests(sh)
26+
.into_iter()
27+
.map(|path| {
28+
PreparedCommand::new::<Self>(
29+
cmd!(sh, "cargo check --manifest-path {path}/Cargo.toml --tests"),
30+
"Please fix compiler errors for tests in output above.",
31+
)
32+
})
33+
.collect()
34+
}
35+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use crate::{Flag, Prepare, PreparedCommand};
2+
use argh::FromArgs;
3+
use xshell::cmd;
4+
5+
use super::get_integration_tests;
6+
7+
/// Cleans the build artifacts for all integration tests.
8+
#[derive(FromArgs, Default)]
9+
#[argh(subcommand, name = "integration-test-clean")]
10+
pub struct IntegrationTestCleanCommand {}
11+
12+
impl Prepare for IntegrationTestCleanCommand {
13+
fn prepare<'a>(&self, sh: &'a xshell::Shell, _flags: Flag) -> Vec<PreparedCommand<'a>> {
14+
get_integration_tests(sh)
15+
.into_iter()
16+
.map(|path| {
17+
PreparedCommand::new::<Self>(
18+
cmd!(sh, "cargo clean --manifest-path {path}/Cargo.toml"),
19+
"Failed to clean integration test.",
20+
)
21+
})
22+
.collect()
23+
}
24+
}

0 commit comments

Comments
 (0)