diff options
Diffstat (limited to 'tests/testsuite/plugins.rs')
-rw-r--r-- | tests/testsuite/plugins.rs | 421 |
1 files changed, 421 insertions, 0 deletions
diff --git a/tests/testsuite/plugins.rs b/tests/testsuite/plugins.rs new file mode 100644 index 0000000..331ba32 --- /dev/null +++ b/tests/testsuite/plugins.rs @@ -0,0 +1,421 @@ +//! Tests for rustc plugins. + +use cargo_test_support::rustc_host; +use cargo_test_support::{basic_manifest, project}; + +#[cargo_test(nightly, reason = "plugins are unstable")] +fn plugin_to_the_max() { + let foo = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [lib] + name = "foo_lib" + + [dependencies.bar] + path = "../bar" + "#, + ) + .file( + "src/main.rs", + r#" + #![feature(plugin)] + #![plugin(bar)] + extern crate foo_lib; + + fn main() { foo_lib::foo(); } + "#, + ) + .file( + "src/foo_lib.rs", + r#" + #![feature(plugin)] + #![plugin(bar)] + + pub fn foo() {} + "#, + ) + .build(); + let _bar = project() + .at("bar") + .file( + "Cargo.toml", + r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + + [lib] + name = "bar" + plugin = true + + [dependencies.baz] + path = "../baz" + "#, + ) + .file( + "src/lib.rs", + r#" + #![feature(rustc_private)] + + extern crate baz; + extern crate rustc_driver; + + use rustc_driver::plugin::Registry; + + #[no_mangle] + pub fn __rustc_plugin_registrar(_reg: &mut Registry) { + println!("{}", baz::baz()); + } + "#, + ) + .build(); + let _baz = project() + .at("baz") + .file( + "Cargo.toml", + r#" + [package] + name = "baz" + version = "0.0.1" + authors = [] + + [lib] + name = "baz" + crate_type = ["dylib"] + "#, + ) + .file("src/lib.rs", "pub fn baz() -> i32 { 1 }") + .build(); + + foo.cargo("build").run(); + foo.cargo("doc").run(); +} + +#[cargo_test(nightly, reason = "plugins are unstable")] +fn plugin_with_dynamic_native_dependency() { + let build = project() + .at("builder") + .file( + "Cargo.toml", + r#" + [package] + name = "builder" + version = "0.0.1" + authors = [] + + [lib] + name = "builder" + crate-type = ["dylib"] + "#, + ) + .file("src/lib.rs", "#[no_mangle] pub extern fn foo() {}") + .build(); + + let foo = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + path = "bar" + "#, + ) + .file( + "src/main.rs", + r#" + #![feature(plugin)] + #![plugin(bar)] + + fn main() {} + "#, + ) + .file( + "bar/Cargo.toml", + r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + build = 'build.rs' + + [lib] + name = "bar" + plugin = true + "#, + ) + .file( + "bar/build.rs", + r#" + use std::env; + use std::fs; + use std::path::PathBuf; + + fn main() { + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + let root = PathBuf::from(env::var("BUILDER_ROOT").unwrap()); + let file = format!("{}builder{}", + env::consts::DLL_PREFIX, + env::consts::DLL_SUFFIX); + let src = root.join(&file); + let dst = out_dir.join(&file); + fs::copy(src, dst).unwrap(); + if cfg!(target_env = "msvc") { + fs::copy(root.join("builder.dll.lib"), + out_dir.join("builder.dll.lib")).unwrap(); + } + println!("cargo:rustc-flags=-L {}", out_dir.display()); + } + "#, + ) + .file( + "bar/src/lib.rs", + r#" + #![feature(rustc_private)] + + extern crate rustc_driver; + use rustc_driver::plugin::Registry; + + #[cfg_attr(not(target_env = "msvc"), link(name = "builder"))] + #[cfg_attr(target_env = "msvc", link(name = "builder.dll"))] + extern { fn foo(); } + + #[no_mangle] + pub fn __rustc_plugin_registrar(_reg: &mut Registry) { + unsafe { foo() } + } + "#, + ) + .build(); + + build.cargo("build").run(); + + let root = build.root().join("target").join("debug"); + foo.cargo("build -v").env("BUILDER_ROOT", root).run(); +} + +#[cargo_test] +fn plugin_integration() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + build = "build.rs" + + [lib] + name = "foo" + plugin = true + doctest = false + "#, + ) + .file("build.rs", "fn main() {}") + .file("src/lib.rs", "") + .file("tests/it_works.rs", "") + .build(); + + p.cargo("test -v").run(); +} + +#[cargo_test] +fn doctest_a_plugin() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = { path = "bar" } + "#, + ) + .file("src/lib.rs", "#[macro_use] extern crate bar;") + .file( + "bar/Cargo.toml", + r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + + [lib] + name = "bar" + plugin = true + "#, + ) + .file("bar/src/lib.rs", "pub fn bar() {}") + .build(); + + p.cargo("test -v").run(); +} + +// See #1515 +#[cargo_test] +fn native_plugin_dependency_with_custom_linker() { + let target = rustc_host(); + + let _foo = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [lib] + plugin = true + "#, + ) + .file("src/lib.rs", "") + .build(); + + let bar = project() + .at("bar") + .file( + "Cargo.toml", + r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + + [dependencies.foo] + path = "../foo" + "#, + ) + .file("src/lib.rs", "") + .file( + ".cargo/config", + &format!( + r#" + [target.{}] + linker = "nonexistent-linker" + "#, + target + ), + ) + .build(); + + bar.cargo("build --verbose") + .with_status(101) + .with_stderr_contains( + "\ +[COMPILING] foo v0.0.1 ([..]) +[RUNNING] `rustc [..] -C linker=nonexistent-linker [..]` +[ERROR] [..]linker[..] +", + ) + .run(); +} + +#[cargo_test(nightly, reason = "requires rustc_private")] +fn panic_abort_plugins() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [profile.dev] + panic = 'abort' + + [dependencies] + bar = { path = "bar" } + "#, + ) + .file("src/lib.rs", "") + .file( + "bar/Cargo.toml", + r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + + [lib] + plugin = true + "#, + ) + .file( + "bar/src/lib.rs", + r#" + #![feature(rustc_private)] + extern crate rustc_ast; + extern crate rustc_driver; + "#, + ) + .build(); + + p.cargo("build").run(); +} + +#[cargo_test(nightly, reason = "requires rustc_private")] +fn shared_panic_abort_plugins() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [profile.dev] + panic = 'abort' + + [dependencies] + bar = { path = "bar" } + baz = { path = "baz" } + "#, + ) + .file("src/lib.rs", "extern crate baz;") + .file( + "bar/Cargo.toml", + r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + + [lib] + plugin = true + + [dependencies] + baz = { path = "../baz" } + "#, + ) + .file( + "bar/src/lib.rs", + r#" + #![feature(rustc_private)] + extern crate rustc_ast; + extern crate rustc_driver; + extern crate baz; + "#, + ) + .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) + .file("baz/src/lib.rs", "") + .build(); + + p.cargo("build -v").run(); +} |