]> git.proxmox.com Git - cargo.git/blob - tests/testsuite/plugins.rs
Auto merge of #5907 - dwijnand:collapse-test-cmd-args, r=matklad
[cargo.git] / tests / testsuite / plugins.rs
1 use std::fs;
2 use std::env;
3
4 use support::{is_nightly, rustc_host};
5 use support::{basic_manifest, execs, project};
6 use support::hamcrest::assert_that;
7
8 #[test]
9 fn plugin_to_the_max() {
10 if !is_nightly() {
11 return;
12 }
13
14 let foo = project()
15 .file(
16 "Cargo.toml",
17 r#"
18 [package]
19 name = "foo"
20 version = "0.0.1"
21 authors = []
22
23 [lib]
24 name = "foo_lib"
25
26 [dependencies.bar]
27 path = "../bar"
28 "#,
29 )
30 .file(
31 "src/main.rs",
32 r#"
33 #![feature(plugin)]
34 #![plugin(bar)]
35 extern crate foo_lib;
36
37 fn main() { foo_lib::foo(); }
38 "#,
39 )
40 .file(
41 "src/foo_lib.rs",
42 r#"
43 #![feature(plugin)]
44 #![plugin(bar)]
45
46 pub fn foo() {}
47 "#,
48 )
49 .build();
50 let _bar = project().at("bar")
51 .file(
52 "Cargo.toml",
53 r#"
54 [package]
55 name = "bar"
56 version = "0.0.1"
57 authors = []
58
59 [lib]
60 name = "bar"
61 plugin = true
62
63 [dependencies.baz]
64 path = "../baz"
65 "#,
66 )
67 .file(
68 "src/lib.rs",
69 r#"
70 #![feature(plugin_registrar, rustc_private)]
71
72 extern crate rustc_plugin;
73 extern crate baz;
74
75 use rustc_plugin::Registry;
76
77 #[plugin_registrar]
78 pub fn foo(_reg: &mut Registry) {
79 println!("{}", baz::baz());
80 }
81 "#,
82 )
83 .build();
84 let _baz = project().at("baz")
85 .file(
86 "Cargo.toml",
87 r#"
88 [package]
89 name = "baz"
90 version = "0.0.1"
91 authors = []
92
93 [lib]
94 name = "baz"
95 crate_type = ["dylib"]
96 "#,
97 )
98 .file("src/lib.rs", "pub fn baz() -> i32 { 1 }")
99 .build();
100
101 assert_that(foo.cargo("build"), execs());
102 assert_that(foo.cargo("doc"), execs());
103 }
104
105 #[test]
106 fn plugin_with_dynamic_native_dependency() {
107 if !is_nightly() {
108 return;
109 }
110
111 let workspace = project().at("ws")
112 .file(
113 "Cargo.toml",
114 r#"
115 [workspace]
116 members = ["builder", "foo"]
117 "#,
118 )
119 .build();
120
121 let build = project().at("ws/builder")
122 .file(
123 "Cargo.toml",
124 r#"
125 [package]
126 name = "builder"
127 version = "0.0.1"
128 authors = []
129
130 [lib]
131 name = "builder"
132 crate-type = ["dylib"]
133 "#,
134 )
135 .file("src/lib.rs", "#[no_mangle] pub extern fn foo() {}")
136 .build();
137
138 let foo = project().at("ws/foo")
139 .file(
140 "Cargo.toml",
141 r#"
142 [package]
143 name = "foo"
144 version = "0.0.1"
145 authors = []
146
147 [dependencies.bar]
148 path = "bar"
149 "#,
150 )
151 .file(
152 "src/main.rs",
153 r#"
154 #![feature(plugin)]
155 #![plugin(bar)]
156
157 fn main() {}
158 "#,
159 )
160 .file(
161 "bar/Cargo.toml",
162 r#"
163 [package]
164 name = "bar"
165 version = "0.0.1"
166 authors = []
167 build = 'build.rs'
168
169 [lib]
170 name = "bar"
171 plugin = true
172 "#,
173 )
174 .file(
175 "bar/build.rs",
176 r#"
177 use std::path::PathBuf;
178 use std::env;
179
180 fn main() {
181 let src = PathBuf::from(env::var("SRC").unwrap());
182 println!("cargo:rustc-flags=-L {}/deps", src.parent().unwrap().display());
183 }
184 "#,
185 )
186 .file(
187 "bar/src/lib.rs",
188 r#"
189 #![feature(plugin_registrar, rustc_private)]
190 extern crate rustc_plugin;
191
192 use rustc_plugin::Registry;
193
194 #[cfg_attr(not(target_env = "msvc"), link(name = "builder"))]
195 #[cfg_attr(target_env = "msvc", link(name = "builder.dll"))]
196 extern { fn foo(); }
197
198 #[plugin_registrar]
199 pub fn bar(_reg: &mut Registry) {
200 unsafe { foo() }
201 }
202 "#,
203 )
204 .build();
205
206 assert_that(build.cargo("build"), execs());
207
208 let src = workspace.root().join("target/debug");
209 let lib = fs::read_dir(&src)
210 .unwrap()
211 .map(|s| s.unwrap().path())
212 .find(|lib| {
213 let lib = lib.file_name().unwrap().to_str().unwrap();
214 lib.starts_with(env::consts::DLL_PREFIX) && lib.ends_with(env::consts::DLL_SUFFIX)
215 })
216 .unwrap();
217
218 assert_that(
219 foo.cargo("build -v").env("SRC", &lib),
220 execs(),
221 );
222 }
223
224 #[test]
225 fn plugin_integration() {
226 let p = project()
227 .file(
228 "Cargo.toml",
229 r#"
230 [package]
231 name = "foo"
232 version = "0.0.1"
233 authors = []
234 build = "build.rs"
235
236 [lib]
237 name = "foo"
238 plugin = true
239 doctest = false
240 "#,
241 )
242 .file("build.rs", "fn main() {}")
243 .file("src/lib.rs", "")
244 .file("tests/it_works.rs", "")
245 .build();
246
247 assert_that(p.cargo("test -v"), execs());
248 }
249
250 #[test]
251 fn doctest_a_plugin() {
252 let p = project()
253 .file(
254 "Cargo.toml",
255 r#"
256 [package]
257 name = "foo"
258 version = "0.0.1"
259 authors = []
260
261 [dependencies]
262 bar = { path = "bar" }
263 "#,
264 )
265 .file("src/lib.rs", "#[macro_use] extern crate bar;")
266 .file(
267 "bar/Cargo.toml",
268 r#"
269 [package]
270 name = "bar"
271 version = "0.0.1"
272 authors = []
273
274 [lib]
275 name = "bar"
276 plugin = true
277 "#,
278 )
279 .file("bar/src/lib.rs", "pub fn bar() {}")
280 .build();
281
282 assert_that(p.cargo("test -v"), execs());
283 }
284
285 // See #1515
286 #[test]
287 fn native_plugin_dependency_with_custom_ar_linker() {
288 let target = rustc_host();
289
290 let _foo = project()
291 .file(
292 "Cargo.toml",
293 r#"
294 [package]
295 name = "foo"
296 version = "0.0.1"
297 authors = []
298
299 [lib]
300 plugin = true
301 "#,
302 )
303 .file("src/lib.rs", "")
304 .build();
305
306 let bar = project().at("bar")
307 .file(
308 "Cargo.toml",
309 r#"
310 [package]
311 name = "bar"
312 version = "0.0.1"
313 authors = []
314
315 [dependencies.foo]
316 path = "../foo"
317 "#,
318 )
319 .file("src/lib.rs", "")
320 .file(
321 ".cargo/config",
322 &format!(
323 r#"
324 [target.{}]
325 ar = "nonexistent-ar"
326 linker = "nonexistent-linker"
327 "#,
328 target
329 ),
330 )
331 .build();
332
333 assert_that(
334 bar.cargo("build --verbose"),
335 execs().with_status(101).with_stderr_contains(
336 "\
337 [COMPILING] foo v0.0.1 ([..])
338 [RUNNING] `rustc [..] -C ar=nonexistent-ar -C linker=nonexistent-linker [..]`
339 [ERROR] [..]linker[..]
340 ",
341 ),
342 );
343 }
344
345 #[test]
346 fn panic_abort_plugins() {
347 if !is_nightly() {
348 return;
349 }
350
351 let p = project()
352 .file(
353 "Cargo.toml",
354 r#"
355 [package]
356 name = "foo"
357 version = "0.0.1"
358 authors = []
359
360 [profile.dev]
361 panic = 'abort'
362
363 [dependencies]
364 bar = { path = "bar" }
365 "#,
366 )
367 .file("src/lib.rs", "")
368 .file(
369 "bar/Cargo.toml",
370 r#"
371 [package]
372 name = "bar"
373 version = "0.0.1"
374 authors = []
375
376 [lib]
377 plugin = true
378 "#,
379 )
380 .file(
381 "bar/src/lib.rs",
382 r#"
383 #![feature(rustc_private)]
384 extern crate syntax;
385 "#,
386 )
387 .build();
388
389 assert_that(p.cargo("build"), execs());
390 }
391
392 #[test]
393 fn shared_panic_abort_plugins() {
394 if !is_nightly() {
395 return;
396 }
397
398 let p = project()
399 .file(
400 "Cargo.toml",
401 r#"
402 [package]
403 name = "foo"
404 version = "0.0.1"
405 authors = []
406
407 [profile.dev]
408 panic = 'abort'
409
410 [dependencies]
411 bar = { path = "bar" }
412 baz = { path = "baz" }
413 "#,
414 )
415 .file("src/lib.rs", "extern crate baz;")
416 .file(
417 "bar/Cargo.toml",
418 r#"
419 [package]
420 name = "bar"
421 version = "0.0.1"
422 authors = []
423
424 [lib]
425 plugin = true
426
427 [dependencies]
428 baz = { path = "../baz" }
429 "#,
430 )
431 .file(
432 "bar/src/lib.rs",
433 r#"
434 #![feature(rustc_private)]
435 extern crate syntax;
436 extern crate baz;
437 "#,
438 )
439 .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1"))
440 .file("baz/src/lib.rs", "")
441 .build();
442
443 assert_that(p.cargo("build"), execs());
444 }