Skip to content

Commit

Permalink
tests: seperate test backends into individual tests
Browse files Browse the repository at this point in the history
  • Loading branch information
StackDoubleFlow committed Sep 20, 2024
1 parent dcae6f9 commit 76b9b8c
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 83 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ mchprs_world ={ path = "./crates/world" }
mchprs_blocks ={ path = "./crates/blocks" }
mchprs_redpiler ={ path = "./crates/redpiler" }
mchprs_redstone = { path = "./crates/redstone" }
paste = "1.0"

[patch.crates-io]
hematite-nbt = { git = "https://github.com/StackDoubleFlow/hematite_nbt" }
135 changes: 71 additions & 64 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,98 +124,93 @@ impl World for TestWorld {

struct RedpilerInstance {
options: CompilerOptions,
world: TestWorld,
compiler: Compiler,
}

pub struct AllBackendRunner {
redstone_world: TestWorld,
redpilers: Vec<RedpilerInstance>,
impl RedpilerInstance {
fn new(world: &TestWorld, variant: BackendVariant) -> RedpilerInstance {
let options = CompilerOptions {
backend_variant: variant,
..Default::default()
};
let mut compiler = Compiler::default();
let max = world.size * 16 - 1;
let bounds = (BlockPos::new(0, 0, 0), BlockPos::new(max, max, max));
let monitor = Default::default();
let ticks = world.to_be_ticked.clone();
compiler.compile(world, bounds, options.clone(), ticks, monitor);
RedpilerInstance { options, compiler }
}
}

#[derive(Copy, Clone)]
pub enum TestBackend {
Redstone,
Redpiler(BackendVariant),
}

pub struct BackendRunner {
world: TestWorld,
redpiler: Option<RedpilerInstance>,
}

impl AllBackendRunner {
pub fn new(world: TestWorld) -> AllBackendRunner {
let variants = [BackendVariant::Direct];
let redpilers = variants
.iter()
.map(|&variant| {
let options = CompilerOptions {
backend_variant: variant,
..Default::default()
};
let mut compiler = Compiler::default();
let max = world.size * 16 - 1;
let bounds = (BlockPos::new(0, 0, 0), BlockPos::new(max, max, max));
let monitor = Default::default();
let ticks = world.to_be_ticked.clone();
compiler.compile(&world, bounds, options.clone(), ticks, monitor);
RedpilerInstance {
options,
world: world.clone(),
compiler,
}
})
.collect();
AllBackendRunner {
redstone_world: world,
redpilers,
impl BackendRunner {
pub fn new(world: TestWorld, backend: TestBackend) -> BackendRunner {
match backend {
TestBackend::Redstone => BackendRunner {
world,
redpiler: None,
},
TestBackend::Redpiler(variant) => BackendRunner {
redpiler: Some(RedpilerInstance::new(&world, variant)),
world,
},
}
}

pub fn tick(&mut self) {
self.redstone_world
if let Some(redpiler) = &mut self.redpiler {
redpiler.compiler.tick();
redpiler.compiler.flush(&mut self.world);
return;
}

self.world
.to_be_ticked
.sort_by_key(|e| (e.ticks_left, e.tick_priority));
for pending in &mut self.redstone_world.to_be_ticked {
for pending in &mut self.world.to_be_ticked {
pending.ticks_left = pending.ticks_left.saturating_sub(1);
}
while self
.redstone_world
.to_be_ticked
.first()
.map_or(1, |e| e.ticks_left)
== 0
{
let entry = self.redstone_world.to_be_ticked.remove(0);
mchprs_redstone::tick(
self.redstone_world.get_block(entry.pos),
&mut self.redstone_world,
entry.pos,
);
}

for redpiler in &mut self.redpilers {
redpiler.compiler.tick();
redpiler.compiler.flush(&mut redpiler.world);
while self.world.to_be_ticked.first().map_or(1, |e| e.ticks_left) == 0 {
let entry = self.world.to_be_ticked.remove(0);
mchprs_redstone::tick(self.world.get_block(entry.pos), &mut self.world, entry.pos);
}
}

pub fn use_block(&mut self, pos: BlockPos) {
mchprs_redstone::on_use(
self.redstone_world.get_block(pos),
&mut self.redstone_world,
pos,
);
for redpiler in &mut self.redpilers {
if let Some(redpiler) = &mut self.redpiler {
redpiler.compiler.on_use_block(pos);
redpiler.compiler.flush(&mut redpiler.world);
redpiler.compiler.flush(&mut self.world);
return;
}
mchprs_redstone::on_use(self.world.get_block(pos), &mut self.world, pos);
}

pub fn check_block_powered(&self, pos: BlockPos, powered: bool) {
assert_eq!(
is_block_powered(self.redstone_world.get_block(pos)),
Some(powered),
"when testing with the base redstone implementation"
);
for redpiler in &self.redpilers {
if let Some(redpiler) = &self.redpiler {
assert_eq!(
is_block_powered(redpiler.world.get_block(pos)),
is_block_powered(self.world.get_block(pos)),
Some(powered),
"when testing on redpiler options: {:#?}",
redpiler.options
);
return;
}
assert_eq!(
is_block_powered(self.world.get_block(pos)),
Some(powered),
"when testing with the base redstone implementation"
);
}

pub fn check_powered_for(&mut self, pos: BlockPos, powered: bool, ticks: usize) {
Expand All @@ -241,3 +236,15 @@ fn is_block_powered(block: Block) -> Option<bool> {
_ => return None,
})
}

macro_rules! test_all_backends {
($name:ident) => {
paste::paste! {
#[test]
fn [< $name _redstone >]() { $name(TestBackend::Redstone) }
#[test]
fn [< $name _rp_direct >]() { $name(TestBackend::Redpiler(BackendVariant::Direct)) }
}
};
}
pub(crate) use test_all_backends;
39 changes: 20 additions & 19 deletions tests/components.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
mod common;

use common::{AllBackendRunner, TestWorld};
use common::{test_all_backends, BackendRunner, TestBackend, TestWorld};
use mchprs_blocks::blocks::{Block, Lever, LeverFace, RedstoneRepeater};
use mchprs_blocks::{BlockDirection, BlockPos};
use mchprs_redpiler::BackendVariant;
use mchprs_redstone::wire::make_cross;
use mchprs_world::World;

Expand Down Expand Up @@ -37,14 +38,14 @@ fn make_lever(world: &mut TestWorld, lever_pos: BlockPos) {
);
}

#[test]
fn lever_on_off() {
test_all_backends!(lever_on_off);
fn lever_on_off(backend: TestBackend) {
let lever_pos = pos(0, 1, 0);

let mut world = TestWorld::new(1);
make_lever(&mut world, lever_pos);

let mut runner = AllBackendRunner::new(world);
let mut runner = BackendRunner::new(world, backend);
runner.check_block_powered(lever_pos, false);

runner.use_block(lever_pos);
Expand All @@ -54,16 +55,16 @@ fn lever_on_off() {
runner.check_block_powered(lever_pos, false);
}

#[test]
fn trapdoor_on_off() {
test_all_backends!(trapdoor_on_off);
fn trapdoor_on_off(backend: TestBackend) {
let lever_pos = pos(0, 1, 0);
let trapdoor_pos = pos(1, 0, 0);

let mut world = TestWorld::new(1);
make_lever(&mut world, lever_pos);
world.set_block(trapdoor_pos, trapdoor());

let mut runner = AllBackendRunner::new(world);
let mut runner = BackendRunner::new(world, backend);
runner.check_block_powered(trapdoor_pos, false);

runner.use_block(lever_pos);
Expand All @@ -73,16 +74,16 @@ fn trapdoor_on_off() {
runner.check_block_powered(trapdoor_pos, false);
}

#[test]
fn lamp_on_off() {
test_all_backends!(lamp_on_off);
fn lamp_on_off(backend: TestBackend) {
let lever_pos = pos(0, 1, 0);
let lamp_pos = pos(1, 0, 0);

let mut world = TestWorld::new(1);
make_lever(&mut world, lever_pos);
world.set_block(lamp_pos, Block::RedstoneLamp { lit: false });

let mut runner = AllBackendRunner::new(world);
let mut runner = BackendRunner::new(world, backend);
runner.check_block_powered(lamp_pos, false);

runner.use_block(lever_pos);
Expand All @@ -93,8 +94,8 @@ fn lamp_on_off() {
runner.check_block_powered(lamp_pos, false);
}

#[test]
fn wall_torch_on_off() {
test_all_backends!(wall_torch_on_off);
fn wall_torch_on_off(backend: TestBackend) {
let lever_pos = pos(0, 1, 0);
let torch_pos = pos(1, 0, 0);

Expand All @@ -108,7 +109,7 @@ fn wall_torch_on_off() {
},
);

let mut runner = AllBackendRunner::new(world);
let mut runner = BackendRunner::new(world, backend);
runner.check_block_powered(torch_pos, true);

runner.use_block(lever_pos);
Expand All @@ -120,8 +121,8 @@ fn wall_torch_on_off() {
runner.check_block_powered(torch_pos, true);
}

#[test]
fn torch_on_off() {
test_all_backends!(torch_on_off);
fn torch_on_off(backend: TestBackend) {
let lever_pos = pos(0, 2, 0);
let torch_pos = pos(2, 2, 0);

Expand All @@ -136,7 +137,7 @@ fn torch_on_off() {
);
place_on_block(&mut world, torch_pos, Block::RedstoneTorch { lit: true });

let mut runner = AllBackendRunner::new(world);
let mut runner = BackendRunner::new(world, backend);
runner.check_block_powered(torch_pos, true);

runner.use_block(lever_pos);
Expand All @@ -148,8 +149,8 @@ fn torch_on_off() {
runner.check_block_powered(torch_pos, true);
}

#[test]
fn repeater_on_off() {
test_all_backends!(repeater_on_off);
fn repeater_on_off(backend: TestBackend) {
let lever_pos = pos(0, 2, 0);
let trapdoor_pos = pos(2, 1, 0);

Expand All @@ -169,7 +170,7 @@ fn repeater_on_off() {
);
world.set_block(trapdoor_pos, trapdoor());

let mut runner = AllBackendRunner::new(world);
let mut runner = BackendRunner::new(world, backend);
runner.check_block_powered(trapdoor_pos, false);

// Check with a 1 tick pulse
Expand Down

0 comments on commit 76b9b8c

Please sign in to comment.