From cd067503a7546eaee904a9b5c6ae30eb0175d376 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Mon, 8 Nov 2021 18:06:56 +0000 Subject: [rust] Macros --- rust/macros/tests/invalid/Cargo.toml | 55 +++++++ rust/macros/tests/invalid/comma-sep.rs | 7 + rust/macros/tests/invalid/double-commas.rs | 7 + rust/macros/tests/invalid/leading-comma.rs | 7 + rust/macros/tests/invalid/missing-argument.rs | 7 + rust/macros/tests/invalid/no-comma.rs | 7 + rust/macros/tests/invalid/only-arrow.rs | 7 + rust/macros/tests/invalid/only-comma.rs | 7 + rust/macros/tests/invalid/single-argument.rs | 7 + rust/macros/tests/invalid/triple-arguments.rs | 7 + rust/macros/tests/invalid/two-arrows.rs | 7 + rust/macros/tests/macros.rs | 200 ++++++++++++++++++++++++++ 12 files changed, 325 insertions(+) create mode 100644 rust/macros/tests/invalid/Cargo.toml create mode 100644 rust/macros/tests/invalid/comma-sep.rs create mode 100644 rust/macros/tests/invalid/double-commas.rs create mode 100644 rust/macros/tests/invalid/leading-comma.rs create mode 100644 rust/macros/tests/invalid/missing-argument.rs create mode 100644 rust/macros/tests/invalid/no-comma.rs create mode 100644 rust/macros/tests/invalid/only-arrow.rs create mode 100644 rust/macros/tests/invalid/only-comma.rs create mode 100644 rust/macros/tests/invalid/single-argument.rs create mode 100644 rust/macros/tests/invalid/triple-arguments.rs create mode 100644 rust/macros/tests/invalid/two-arrows.rs create mode 100644 rust/macros/tests/macros.rs (limited to 'rust/macros/tests') diff --git a/rust/macros/tests/invalid/Cargo.toml b/rust/macros/tests/invalid/Cargo.toml new file mode 100644 index 0000000..b096d99 --- /dev/null +++ b/rust/macros/tests/invalid/Cargo.toml @@ -0,0 +1,55 @@ +# +# This Cargo.toml file is used by the simple-trybuild module. +# When adding a new file, please name the [[bin]] name to match the file +# it is used to produce an error message +# + +[package] +name = "macros-tests" +version = "0.0.0" +edition = "2018" +publish = false + +[dependencies.macros] +path = "../../" +default-features = false + +[[bin]] +name = "comma-sep-rs" +path = "comma-sep.rs" + +[[bin]] +name = "double-commas-rs" +path = "double-commas.rs" + +[[bin]] +name = "only-arrow-rs" +path = "only-arrow.rs" + +[[bin]] +name = "only-comma-rs" +path = "only-comma.rs" + +[[bin]] +name = "single-argument-rs" +path = "single-argument.rs" + +[[bin]] +name = "triple-arguments-rs" +path = "triple-arguments.rs" + +[[bin]] +name = "two-arrows-rs" +path = "two-arrows.rs" + +[[bin]] +name = "leading-comma-rs" +path = "leading-comma.rs" + +[[bin]] +name = "no-comma-rs" +path = "no-comma.rs" + +[[bin]] +name = "missing-argument-rs" +path = "missing-argument.rs" diff --git a/rust/macros/tests/invalid/comma-sep.rs b/rust/macros/tests/invalid/comma-sep.rs new file mode 100644 index 0000000..c9b6f44 --- /dev/null +++ b/rust/macros/tests/invalid/comma-sep.rs @@ -0,0 +1,7 @@ +use macros::hashmap; +use std::collections::HashMap; + +fn main() { + // using only commas is invalid + let _hm: HashMap<_, _> = hashmap!('a', 1); +} diff --git a/rust/macros/tests/invalid/double-commas.rs b/rust/macros/tests/invalid/double-commas.rs new file mode 100644 index 0000000..d52dec6 --- /dev/null +++ b/rust/macros/tests/invalid/double-commas.rs @@ -0,0 +1,7 @@ +use macros::hashmap; +use std::collections::HashMap; + +fn main() { + // a single trailing comma is okay, but two is not + let _hm: HashMap<_, _> = hashmap!('a' => 2, ,); +} diff --git a/rust/macros/tests/invalid/leading-comma.rs b/rust/macros/tests/invalid/leading-comma.rs new file mode 100644 index 0000000..bc03666 --- /dev/null +++ b/rust/macros/tests/invalid/leading-comma.rs @@ -0,0 +1,7 @@ +use macros::hashmap; +use std::collections::HashMap; + +fn main() { + // leading commas are not valid + let _hm: HashMap<_, _> = hashmap!(, 'a' => 2); +} diff --git a/rust/macros/tests/invalid/missing-argument.rs b/rust/macros/tests/invalid/missing-argument.rs new file mode 100644 index 0000000..893d609 --- /dev/null +++ b/rust/macros/tests/invalid/missing-argument.rs @@ -0,0 +1,7 @@ +use macros::hashmap; +use std::collections::HashMap; + +fn main() { + // an argument should come between each pair of commas + let _hm: HashMap<_, _> = hashmap!('a' => 1, , 'b' => 2); +} diff --git a/rust/macros/tests/invalid/no-comma.rs b/rust/macros/tests/invalid/no-comma.rs new file mode 100644 index 0000000..c4e6a92 --- /dev/null +++ b/rust/macros/tests/invalid/no-comma.rs @@ -0,0 +1,7 @@ +use macros::hashmap; +use std::collections::HashMap; + +fn main() { + // Key value pairs must be separated by commas + let _hm: HashMap<_, _> = hashmap!('a' => 1 'b' => 2); +} diff --git a/rust/macros/tests/invalid/only-arrow.rs b/rust/macros/tests/invalid/only-arrow.rs new file mode 100644 index 0000000..7f7d730 --- /dev/null +++ b/rust/macros/tests/invalid/only-arrow.rs @@ -0,0 +1,7 @@ +use macros::hashmap; +use std::collections::HashMap; + +fn main() { + // a single random arrow is not valid + let _hm: HashMap<(), ()> = hashmap!(=>); +} diff --git a/rust/macros/tests/invalid/only-comma.rs b/rust/macros/tests/invalid/only-comma.rs new file mode 100644 index 0000000..3b863b3 --- /dev/null +++ b/rust/macros/tests/invalid/only-comma.rs @@ -0,0 +1,7 @@ +use macros::hashmap; +use std::collections::HashMap; + +fn main() { + // a single random comma is not valid + let _hm: HashMap<(), ()> = hashmap!(,); +} diff --git a/rust/macros/tests/invalid/single-argument.rs b/rust/macros/tests/invalid/single-argument.rs new file mode 100644 index 0000000..f8ac092 --- /dev/null +++ b/rust/macros/tests/invalid/single-argument.rs @@ -0,0 +1,7 @@ +use macros::hashmap; +use std::collections::HashMap; + +fn main() { + // a single argument is invalid + let _hm: HashMap<_, _> = hashmap!('a'); +} diff --git a/rust/macros/tests/invalid/triple-arguments.rs b/rust/macros/tests/invalid/triple-arguments.rs new file mode 100644 index 0000000..54351ae --- /dev/null +++ b/rust/macros/tests/invalid/triple-arguments.rs @@ -0,0 +1,7 @@ +use macros::hashmap; +use std::collections::HashMap; + +fn main() { + // three arguments are invalid + hashmap!('a' => 1, 'b'); +} diff --git a/rust/macros/tests/invalid/two-arrows.rs b/rust/macros/tests/invalid/two-arrows.rs new file mode 100644 index 0000000..254a82e --- /dev/null +++ b/rust/macros/tests/invalid/two-arrows.rs @@ -0,0 +1,7 @@ +use macros::hashmap; +use std::collections::HashMap; + +fn main() { + // a trailing => isn't valid either + hashmap!('a' => 2, =>); +} diff --git a/rust/macros/tests/macros.rs b/rust/macros/tests/macros.rs new file mode 100644 index 0000000..077a9e7 --- /dev/null +++ b/rust/macros/tests/macros.rs @@ -0,0 +1,200 @@ +use macros::hashmap; +use std::collections::HashMap; + +#[test] +fn test_empty() { + let expected: HashMap = HashMap::new(); + let computed: HashMap = hashmap!(); + assert_eq!(computed, expected); +} + +#[test] +fn test_single() { + let mut expected = HashMap::new(); + expected.insert(1, "one"); + assert_eq!(hashmap!(1 => "one"), expected); +} + +#[test] +fn test_no_trailing_comma() { + let mut expected = HashMap::new(); + expected.insert(1, "one"); + expected.insert(2, "two"); + assert_eq!(hashmap!(1 => "one", 2 => "two"), expected); +} + +#[test] +fn test_trailing_comma() { + let mut expected = HashMap::new(); + expected.insert('h', 89); + expected.insert('a', 1); + expected.insert('s', 19); + expected.insert('h', 8); + assert_eq!( + hashmap!( + 'h' => 89, + 'a' => 1, + 's' => 19, + 'h' => 8, + ), + expected + ); +} + +#[test] +fn test_nested() { + let mut expected = HashMap::new(); + expected.insert("non-empty", { + let mut subhashmap = HashMap::new(); + subhashmap.insert(23, 623); + subhashmap.insert(34, 21); + subhashmap + }); + expected.insert("empty", HashMap::new()); + assert_eq!( + hashmap!( + "non-empty" => hashmap!( + 23 => 623, + 34 => 21 + ), + "empty" => hashmap!() + ), + expected + ); +} + +mod test { + #[test] + fn type_not_in_scope() { + use macros::hashmap; + + let _empty: ::std::collections::HashMap<(), ()> = hashmap!(); + let _without_comma = hashmap!(23=> 623, 34 => 21); + let _with_trailing = hashmap!(23 => 623, 34 => 21,); + } + + #[test] + fn test_macro_out_of_scope() { + let _empty: ::std::collections::HashMap<(), ()> = macros::hashmap!(); + let _without_comma = macros::hashmap!(23=> 623, 34 => 21); + let _with_trailing = macros::hashmap!(23 => 623, 34 => 21,); + } +} + +#[test] +fn test_type_override() { + // The macro should always use std::collections::HashMap and ignore crate::std::collections::HashMap + mod std { + pub mod collections { + pub struct HashMap; + + impl HashMap { + #[allow(dead_code)] + pub fn new() -> Self { + panic!("Do not allow users to override which HashMap is used"); + } + + #[allow(dead_code)] + pub fn insert(&mut self, _key: K, _val: V) { + panic!("Do not allow users to override which HashMap is used"); + } + } + } + } + + let _empty: ::std::collections::HashMap<(), ()> = hashmap!(); + let _without_comma = hashmap!(1 => 2, 3 => 4); + let _with_trailing = hashmap!(1 => 2, 3 => 4,); +} + +#[test] +fn test_compile_fails_comma_sep() { + simple_trybuild::compile_fail("comma-sep.rs"); +} + +#[test] +fn test_compile_fails_double_commas() { + simple_trybuild::compile_fail("double-commas.rs"); +} + +#[test] +fn test_compile_fails_only_comma() { + simple_trybuild::compile_fail("only-comma.rs"); +} + +#[test] +fn test_compile_fails_single_argument() { + simple_trybuild::compile_fail("single-argument.rs"); +} + +#[test] +fn test_compile_fails_triple_arguments() { + simple_trybuild::compile_fail("triple-arguments.rs"); +} + +#[test] +fn test_compile_fails_only_arrow() { + simple_trybuild::compile_fail("only-arrow.rs"); +} + +#[test] +fn test_compile_fails_two_arrows() { + simple_trybuild::compile_fail("two-arrows.rs"); +} + +#[test] +fn test_compile_fails_leading_comma() { + simple_trybuild::compile_fail("leading-comma.rs"); +} + +#[test] +fn test_compile_fails_no_comma() { + simple_trybuild::compile_fail("no-comma.rs"); +} + +#[test] +fn test_compile_fails_missing_argument() { + simple_trybuild::compile_fail("missing-argument.rs"); +} + +mod simple_trybuild { + use std::path::PathBuf; + use std::process::Command; + + pub fn compile_fail(file_name: &str) { + let invalid_path: PathBuf = ["tests", "invalid"].iter().collect::(); + + let mut file_path = invalid_path.clone(); + file_path.push(file_name); + assert!( + file_path.exists(), + "{:?} does not exist.", + file_path.into_os_string() + ); + + let test_name = file_name.replace(".", "-"); + let macros_dir = ["..", "..", "target", "tests", "macros"] + .iter() + .collect::(); + + let result = Command::new("cargo") + .current_dir(invalid_path) + .arg("build") + .arg("--offline") + .arg("--target-dir") + .arg(macros_dir) + .arg("--bin") + .arg(test_name) + .output(); + + if let Ok(result) = result { + assert!( + !result.status.success(), + "Expected {:?} to fail to compile, but it succeeded.", + file_path + ); + } else { + panic!("Running subprocess failed."); + } + } +} -- cgit v1.2.3