From db3a5e829fdd9e66e6c0940068bd9705cc774551 Mon Sep 17 00:00:00 2001 From: Adrien Burgun Date: Tue, 12 Jul 2022 18:30:41 +0200 Subject: [PATCH] :bug: Fix Diode accepting counter-flowing signals, fix build script rerun --- stackline/Cargo.toml | 1 + stackline/build.rs | 1 + stackline/tests/common/mod.rs | 52 ++++++++++++++++++++++++++++ stackline/tests/wire.rs | 27 +++++++++++++++ stackline/tests/wire/diode-loop.json | 1 + stackline/tests/wire/loop.json | 1 + stackline/tiles/wire.rs | 4 +++ 7 files changed, 87 insertions(+) create mode 100644 stackline/tests/common/mod.rs create mode 100644 stackline/tests/wire.rs create mode 100644 stackline/tests/wire/diode-loop.json create mode 100644 stackline/tests/wire/loop.json diff --git a/stackline/Cargo.toml b/stackline/Cargo.toml index c4c0d8a..6eaf3b3 100755 --- a/stackline/Cargo.toml +++ b/stackline/Cargo.toml @@ -16,6 +16,7 @@ serde = { version = "1", features = ["derive"] } [dev-dependencies] criterion = { version = "0.3.5", features = ["html_reports"] } +serde_json = "1.0" [build-dependencies] syn = {version = "1.0", features = ["full", "parsing"] } diff --git a/stackline/build.rs b/stackline/build.rs index b85c3f4..d960a15 100644 --- a/stackline/build.rs +++ b/stackline/build.rs @@ -97,6 +97,7 @@ fn generate_code(files: Vec<(PathBuf, Vec)>, names: Vec) -> Stri // TODO: use a HashMap to prevent duplicate module names for (file, names) in files { + println!("cargo:rerun-if-changed={}", file.display()); let module_name = file .as_path() .file_stem() diff --git a/stackline/tests/common/mod.rs b/stackline/tests/common/mod.rs new file mode 100644 index 0000000..b131751 --- /dev/null +++ b/stackline/tests/common/mod.rs @@ -0,0 +1,52 @@ +#[macro_export] +macro_rules! load_test { + ( $path:expr ) => {{ + let path = format!("{}/{}", env!("CARGO_MANIFEST_DIR"), $path); + let raw = std::fs::read_to_string(&path).unwrap_or_else(|err| { + panic!("Couldn't load {}: {}", &path, err); + }); + let world: stackline::prelude::World = serde_json::from_str(&raw).expect("Couldn't parse World"); + world + }} +} + +#[macro_export] +macro_rules! run { + ( $world:expr ) => { + $world.step(); + }; + + ( $world:expr, $steps:expr ) => { + for _step in 0..$steps { + $world.step(); + } + } +} + +#[macro_export] +macro_rules! assert_signal { + ( $world:expr, $x:expr, $y:expr ) => {{ + let guard = $world + .get(($x, $y)) + .expect(&format!("Couldn't get tile at {}:{}", $x, $y)); + let signal = guard.signal(); + assert!(signal.is_some(), "Expected signal at {}:{}!\n{}", $x, $y, $world); + signal + }}; + + ( $world:expr, $x:expr, $y:expr, [ $( $data:expr ),* ] ) => {{ + let signal = assert_signal!($pane, $x, $y); + // TODO: check that signal.data == data + }}; +} + +#[macro_export] +macro_rules! assert_no_signal { + ( $world:expr, $x:expr, $y:expr ) => {{ + let guard = $world + .get(($x, $y)) + .expect(&format!("Couldn't get tile at {}:{}", $x, $y)); + let signal = guard.signal(); + assert!(signal.is_none(), "Expected no signal at {}:{}!\n{}", $x, $y, $world); + }}; +} diff --git a/stackline/tests/wire.rs b/stackline/tests/wire.rs new file mode 100644 index 0000000..50ef1f2 --- /dev/null +++ b/stackline/tests/wire.rs @@ -0,0 +1,27 @@ +use stackline::prelude::*; +mod common; + +#[test] +fn test_wire_loop() { + let mut world = load_test!("tests/wire/loop.json"); + + run!(world, 6); + assert_no_signal!(world, 0, 0); + assert_signal!(world, 3, 3); + + run!(world, 6); + assert_signal!(world, 0, 0); + assert_no_signal!(world, 3, 3); +} + +#[test] +fn test_diode_loop() { + let mut world = load_test!("tests/wire/diode-loop.json"); + + run!(world, 2); + assert_no_signal!(world, 0, 0); + assert_signal!(world, 1, 1); + + run!(world, 4); + assert_signal!(world, 1, 1); +} diff --git a/stackline/tests/wire/diode-loop.json b/stackline/tests/wire/diode-loop.json new file mode 100644 index 0000000..90b716e --- /dev/null +++ b/stackline/tests/wire/diode-loop.json @@ -0,0 +1 @@ +{"panes":{"main":{"tiles":[{"cell":{"Diode":"Right"},"signal":null,"state":"Idle","updated":false},{"cell":{"Wire":"Any"},"signal":null,"state":"Idle","updated":false},{"cell":{"Diode":"Left"},"signal":{"direction":"Left","position":[2,0],"stack":[]},"state":"Active","updated":false},{"cell":{"Diode":"Up"},"signal":null,"state":"Idle","updated":false},{"cell":{"Diode":"Left"},"signal":null,"state":"Idle","updated":false},{"cell":null,"signal":null,"state":"Idle","updated":false}],"width":3,"height":2,"position":[0,0],"signals":[]}}} \ No newline at end of file diff --git a/stackline/tests/wire/loop.json b/stackline/tests/wire/loop.json new file mode 100644 index 0000000..644a996 --- /dev/null +++ b/stackline/tests/wire/loop.json @@ -0,0 +1 @@ +{"panes":{"main":{"tiles":[{"cell":{"Diode":"Right"},"signal":{"direction":"Right","position":[0,0],"stack":[]},"state":"Active","updated":false},{"cell":{"Wire":"Horizontal"},"signal":null,"state":"Idle","updated":false},{"cell":{"Wire":"Horizontal"},"signal":null,"state":"Idle","updated":false},{"cell":{"Diode":"Down"},"signal":null,"state":"Idle","updated":false},{"cell":{"Wire":"Vertical"},"signal":null,"state":"Idle","updated":false},{"cell":null,"signal":null,"state":"Idle","updated":false},{"cell":null,"signal":null,"state":"Idle","updated":false},{"cell":{"Wire":"Vertical"},"signal":null,"state":"Idle","updated":false},{"cell":{"Wire":"Vertical"},"signal":null,"state":"Idle","updated":false},{"cell":null,"signal":null,"state":"Idle","updated":false},{"cell":null,"signal":null,"state":"Idle","updated":false},{"cell":{"Wire":"Vertical"},"signal":null,"state":"Idle","updated":false},{"cell":{"Diode":"Up"},"signal":null,"state":"Idle","updated":false},{"cell":{"Wire":"Horizontal"},"signal":null,"state":"Idle","updated":false},{"cell":{"Wire":"Horizontal"},"signal":null,"state":"Idle","updated":false},{"cell":{"Diode":"Left"},"signal":null,"state":"Idle","updated":false}],"width":4,"height":4,"position":[0,0],"signals":[]}}} \ No newline at end of file diff --git a/stackline/tiles/wire.rs b/stackline/tiles/wire.rs index bc993c9..a838137 100644 --- a/stackline/tiles/wire.rs +++ b/stackline/tiles/wire.rs @@ -72,6 +72,10 @@ impl Tile for Diode { } } + fn accepts_signal(&self, direction: Direction) -> bool { + direction.opposite() != self.0 + } + fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) { let ch = match self.0 { Direction::Up => '^',