aboutsummaryrefslogtreecommitdiff
path: root/rust/macros/tests/macros.rs
diff options
context:
space:
mode:
authorFederico Igne <git@federicoigne.com>2021-11-08 18:06:56 +0000
committerFederico Igne <git@federicoigne.com>2021-11-08 18:06:56 +0000
commitcd067503a7546eaee904a9b5c6ae30eb0175d376 (patch)
tree2f625fc40314fa2abbe60da496b6f0993af8a779 /rust/macros/tests/macros.rs
parentb6d7705471f0a583f1d115472ddbc8c4f8a420a9 (diff)
downloadexercism-cd067503a7546eaee904a9b5c6ae30eb0175d376.tar.gz
exercism-cd067503a7546eaee904a9b5c6ae30eb0175d376.zip
[rust] Macros
Diffstat (limited to 'rust/macros/tests/macros.rs')
-rw-r--r--rust/macros/tests/macros.rs200
1 files changed, 200 insertions, 0 deletions
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 @@
1use macros::hashmap;
2use std::collections::HashMap;
3
4#[test]
5fn test_empty() {
6 let expected: HashMap<u32, u32> = HashMap::new();
7 let computed: HashMap<u32, u32> = hashmap!();
8 assert_eq!(computed, expected);
9}
10
11#[test]
12fn test_single() {
13 let mut expected = HashMap::new();
14 expected.insert(1, "one");
15 assert_eq!(hashmap!(1 => "one"), expected);
16}
17
18#[test]
19fn test_no_trailing_comma() {
20 let mut expected = HashMap::new();
21 expected.insert(1, "one");
22 expected.insert(2, "two");
23 assert_eq!(hashmap!(1 => "one", 2 => "two"), expected);
24}
25
26#[test]
27fn test_trailing_comma() {
28 let mut expected = HashMap::new();
29 expected.insert('h', 89);
30 expected.insert('a', 1);
31 expected.insert('s', 19);
32 expected.insert('h', 8);
33 assert_eq!(
34 hashmap!(
35 'h' => 89,
36 'a' => 1,
37 's' => 19,
38 'h' => 8,
39 ),
40 expected
41 );
42}
43
44#[test]
45fn test_nested() {
46 let mut expected = HashMap::new();
47 expected.insert("non-empty", {
48 let mut subhashmap = HashMap::new();
49 subhashmap.insert(23, 623);
50 subhashmap.insert(34, 21);
51 subhashmap
52 });
53 expected.insert("empty", HashMap::new());
54 assert_eq!(
55 hashmap!(
56 "non-empty" => hashmap!(
57 23 => 623,
58 34 => 21
59 ),
60 "empty" => hashmap!()
61 ),
62 expected
63 );
64}
65
66mod test {
67 #[test]
68 fn type_not_in_scope() {
69 use macros::hashmap;
70
71 let _empty: ::std::collections::HashMap<(), ()> = hashmap!();
72 let _without_comma = hashmap!(23=> 623, 34 => 21);
73 let _with_trailing = hashmap!(23 => 623, 34 => 21,);
74 }
75
76 #[test]
77 fn test_macro_out_of_scope() {
78 let _empty: ::std::collections::HashMap<(), ()> = macros::hashmap!();
79 let _without_comma = macros::hashmap!(23=> 623, 34 => 21);
80 let _with_trailing = macros::hashmap!(23 => 623, 34 => 21,);
81 }
82}
83
84#[test]
85fn test_type_override() {
86 // The macro should always use std::collections::HashMap and ignore crate::std::collections::HashMap
87 mod std {
88 pub mod collections {
89 pub struct HashMap;
90
91 impl HashMap {
92 #[allow(dead_code)]
93 pub fn new() -> Self {
94 panic!("Do not allow users to override which HashMap is used");
95 }
96
97 #[allow(dead_code)]
98 pub fn insert<K, V>(&mut self, _key: K, _val: V) {
99 panic!("Do not allow users to override which HashMap is used");
100 }
101 }
102 }
103 }
104
105 let _empty: ::std::collections::HashMap<(), ()> = hashmap!();
106 let _without_comma = hashmap!(1 => 2, 3 => 4);
107 let _with_trailing = hashmap!(1 => 2, 3 => 4,);
108}
109
110#[test]
111fn test_compile_fails_comma_sep() {
112 simple_trybuild::compile_fail("comma-sep.rs");
113}
114
115#[test]
116fn test_compile_fails_double_commas() {
117 simple_trybuild::compile_fail("double-commas.rs");
118}
119
120#[test]
121fn test_compile_fails_only_comma() {
122 simple_trybuild::compile_fail("only-comma.rs");
123}
124
125#[test]
126fn test_compile_fails_single_argument() {
127 simple_trybuild::compile_fail("single-argument.rs");
128}
129
130#[test]
131fn test_compile_fails_triple_arguments() {
132 simple_trybuild::compile_fail("triple-arguments.rs");
133}
134
135#[test]
136fn test_compile_fails_only_arrow() {
137 simple_trybuild::compile_fail("only-arrow.rs");
138}
139
140#[test]
141fn test_compile_fails_two_arrows() {
142 simple_trybuild::compile_fail("two-arrows.rs");
143}
144
145#[test]
146fn test_compile_fails_leading_comma() {
147 simple_trybuild::compile_fail("leading-comma.rs");
148}
149
150#[test]
151fn test_compile_fails_no_comma() {
152 simple_trybuild::compile_fail("no-comma.rs");
153}
154
155#[test]
156fn test_compile_fails_missing_argument() {
157 simple_trybuild::compile_fail("missing-argument.rs");
158}
159
160mod simple_trybuild {
161 use std::path::PathBuf;
162 use std::process::Command;
163
164 pub fn compile_fail(file_name: &str) {
165 let invalid_path: PathBuf = ["tests", "invalid"].iter().collect::<PathBuf>();
166
167 let mut file_path = invalid_path.clone();
168 file_path.push(file_name);
169 assert!(
170 file_path.exists(),
171 "{:?} does not exist.",
172 file_path.into_os_string()
173 );
174
175 let test_name = file_name.replace(".", "-");
176 let macros_dir = ["..", "..", "target", "tests", "macros"]
177 .iter()
178 .collect::<PathBuf>();
179
180 let result = Command::new("cargo")
181 .current_dir(invalid_path)
182 .arg("build")
183 .arg("--offline")
184 .arg("--target-dir")
185 .arg(macros_dir)
186 .arg("--bin")
187 .arg(test_name)
188 .output();
189
190 if let Ok(result) = result {
191 assert!(
192 !result.status.success(),
193 "Expected {:?} to fail to compile, but it succeeded.",
194 file_path
195 );
196 } else {
197 panic!("Running subprocess failed.");
198 }
199 }
200}