1 use paste::paste;
2
3 #[test]
test_shared_hygiene()4 fn test_shared_hygiene() {
5 paste! {
6 let [<a a>] = 1;
7 assert_eq!([<a a>], 1);
8 }
9 }
10
11 #[test]
test_repeat()12 fn test_repeat() {
13 const ROCKET_A: &str = "/a";
14 const ROCKET_B: &str = "/b";
15
16 macro_rules! routes {
17 ($($route:ident),*) => {{
18 paste! {
19 vec![$( [<ROCKET_ $route>] ),*]
20 }
21 }}
22 }
23
24 let routes = routes!(A, B);
25 assert_eq!(routes, vec!["/a", "/b"]);
26 }
27
28 #[test]
test_literal_to_identifier()29 fn test_literal_to_identifier() {
30 const CONST0: &str = "const0";
31
32 let pasted = paste!([<CONST 0>]);
33 assert_eq!(pasted, CONST0);
34
35 let pasted = paste!([<CONST '0'>]);
36 assert_eq!(pasted, CONST0);
37
38 let pasted = paste!([<CONST "0">]);
39 assert_eq!(pasted, CONST0);
40
41 let pasted = paste!([<CONST r"0">]);
42 assert_eq!(pasted, CONST0);
43
44 let pasted = paste!([<CONST '\u{30}'>]);
45 assert_eq!(pasted, CONST0);
46 }
47
48 #[test]
test_literal_suffix()49 fn test_literal_suffix() {
50 macro_rules! literal {
51 ($bit:tt) => {
52 paste!([<1_u $bit>])
53 };
54 }
55
56 assert_eq!(literal!(32), 1);
57 }
58
59 #[test]
test_underscore()60 fn test_underscore() {
61 paste! {
62 const A_B: usize = 0;
63 assert_eq!([<A _ B>], 0);
64 }
65 }
66
67 #[test]
test_lifetime()68 fn test_lifetime() {
69 paste! {
70 #[allow(dead_code)]
71 struct S<[<'d e>]> {
72 q: &[<'d e>] str,
73 }
74 }
75 }
76
77 #[test]
test_keyword()78 fn test_keyword() {
79 paste! {
80 struct [<F move>];
81
82 let _ = Fmove;
83 }
84 }
85
86 #[test]
test_literal_str()87 fn test_literal_str() {
88 paste! {
89 #[allow(non_camel_case_types)]
90 struct [<Foo "Bar-Baz">];
91
92 let _ = FooBar_Baz;
93 }
94 }
95
96 #[test]
test_env_literal()97 fn test_env_literal() {
98 paste! {
99 struct [<Lib env bar>];
100
101 let _ = Libenvbar;
102 }
103 }
104
105 #[test]
test_env_present()106 fn test_env_present() {
107 paste! {
108 struct [<Lib "paste">];
109
110 let _ = Libpaste;
111 }
112 }
113
114 #[test]
test_raw_identifier()115 fn test_raw_identifier() {
116 paste! {
117 struct [<F r#move>];
118
119 let _ = Fmove;
120 }
121 }
122
123 #[test]
test_false_start()124 fn test_false_start() {
125 trait Trait {
126 fn f() -> usize;
127 }
128
129 struct S;
130
131 impl Trait for S {
132 fn f() -> usize {
133 0
134 }
135 }
136
137 paste! {
138 let x = [<S as Trait>::f()];
139 assert_eq!(x[0], 0);
140 }
141 }
142
143 #[test]
test_local_variable()144 fn test_local_variable() {
145 let yy = 0;
146
147 paste! {
148 assert_eq!([<y y>], 0);
149 }
150 }
151
152 #[test]
test_empty()153 fn test_empty() {
154 paste! {
155 assert_eq!(stringify!([<y y>]), "yy");
156 assert_eq!(stringify!([<>]).replace(' ', ""), "[<>]");
157 }
158 }
159
160 #[test]
test_env_to_lower()161 fn test_env_to_lower() {
162 paste! {
163 struct [<Lib "paste":lower>];
164
165 let _ = Libpaste;
166 }
167 }
168
169 #[test]
test_env_to_upper()170 fn test_env_to_upper() {
171 paste! {
172 const [<LIB "paste":upper>]: &str = "libpaste";
173
174 let _ = LIBPASTE;
175 }
176 }
177
178 #[test]
test_env_to_snake()179 fn test_env_to_snake() {
180 paste! {
181 const [<LIB "paste":snake:upper>]: &str = "libpaste";
182
183 let _ = LIBPASTE;
184 }
185 }
186
187 #[test]
test_env_to_camel()188 fn test_env_to_camel() {
189 paste! {
190 #[allow(non_upper_case_globals)]
191 const [<LIB "paste":camel>]: &str = "libpaste";
192
193 let _ = LIBPaste;
194 }
195 }
196
197 mod test_x86_feature_literal {
198 // work around https://github.com/rust-lang/rust/issues/72726
199
200 use paste::paste;
201
202 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
203 macro_rules! my_is_x86_feature_detected {
204 ($feat:literal) => {
205 paste! {
206 #[test]
207 fn test() {
208 let _ = is_x86_feature_detected!($feat);
209 }
210 }
211 };
212 }
213
214 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
215 macro_rules! my_is_x86_feature_detected {
216 ($feat:literal) => {
217 #[ignore]
218 #[test]
219 fn test() {}
220 };
221 }
222
223 my_is_x86_feature_detected!("mmx");
224 }
225
226 #[rustversion::since(1.46)]
227 mod test_local_setter {
228 // https://github.com/dtolnay/paste/issues/7
229
230 use paste::paste;
231
232 #[derive(Default)]
233 struct Test {
234 val: i32,
235 }
236
237 impl Test {
set_val(&mut self, arg: i32)238 fn set_val(&mut self, arg: i32) {
239 self.val = arg;
240 }
241 }
242
243 macro_rules! setter {
244 ($obj:expr, $field:ident, $value:expr) => {
245 paste! { $obj.[<set_ $field>]($value); }
246 };
247
248 ($field:ident, $value:expr) => {{
249 let mut new = Test::default();
250 setter!(new, val, $value);
251 new
252 }};
253 }
254
255 #[test]
test_local_setter()256 fn test_local_setter() {
257 let a = setter!(val, 42);
258 assert_eq!(a.val, 42);
259 }
260 }
261
262 // https://github.com/dtolnay/paste/issues/85
263 #[test]
test_top_level_none_delimiter()264 fn test_top_level_none_delimiter() {
265 macro_rules! clone {
266 ($val:expr) => {
267 paste! {
268 $val.clone()
269 }
270 };
271 }
272
273 #[derive(Clone)]
274 struct A;
275
276 impl A {
277 fn consume_self(self) {
278 let _ = self;
279 }
280 }
281
282 clone!(&A).consume_self();
283 }
284