blob: 5076107e7a4e386ff1c8c6401fde2dd5a46f01f2 [file] [log] [blame]
use std::env;
use std::fs::{self, File};
use std::io::prelude::*;
use crate::support::paths;
use crate::support::{cargo_process, git_process};
fn create_empty_gitconfig() {
// This helps on Windows where libgit2 is very aggressive in attempting to
// find a git config file.
let gitconfig = paths::home().join(".gitconfig");
File::create(gitconfig).unwrap();
}
#[test]
fn simple_lib() {
cargo_process("new --lib foo --vcs none --edition 2015")
.env("USER", "foo")
.with_stderr("[CREATED] library `foo` package")
.run();
assert!(paths::root().join("foo").is_dir());
assert!(paths::root().join("foo/Cargo.toml").is_file());
assert!(paths::root().join("foo/src/lib.rs").is_file());
assert!(!paths::root().join("foo/.gitignore").is_file());
let lib = paths::root().join("foo/src/lib.rs");
let mut contents = String::new();
File::open(&lib)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert_eq!(
contents,
r#"#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
"#
);
cargo_process("build").cwd(&paths::root().join("foo")).run();
}
#[test]
fn simple_bin() {
cargo_process("new --bin foo --edition 2015")
.env("USER", "foo")
.with_stderr("[CREATED] binary (application) `foo` package")
.run();
assert!(paths::root().join("foo").is_dir());
assert!(paths::root().join("foo/Cargo.toml").is_file());
assert!(paths::root().join("foo/src/main.rs").is_file());
cargo_process("build").cwd(&paths::root().join("foo")).run();
assert!(paths::root()
.join(&format!("foo/target/debug/foo{}", env::consts::EXE_SUFFIX))
.is_file());
}
#[test]
fn both_lib_and_bin() {
cargo_process("new --lib --bin foo")
.env("USER", "foo")
.with_status(101)
.with_stderr("[ERROR] can't specify both lib and binary outputs")
.run();
}
#[test]
fn simple_git() {
cargo_process("new --lib foo --edition 2015")
.env("USER", "foo")
.run();
assert!(paths::root().is_dir());
assert!(paths::root().join("foo/Cargo.toml").is_file());
assert!(paths::root().join("foo/src/lib.rs").is_file());
assert!(paths::root().join("foo/.git").is_dir());
assert!(paths::root().join("foo/.gitignore").is_file());
let fp = paths::root().join("foo/.gitignore");
let mut contents = String::new();
File::open(&fp)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert_eq!(contents, "/target\n**/*.rs.bk\nCargo.lock\n",);
cargo_process("build").cwd(&paths::root().join("foo")).run();
}
#[test]
fn no_argument() {
cargo_process("new")
.with_status(1)
.with_stderr_contains(
"\
error: The following required arguments were not provided:
<path>
",
)
.run();
}
#[test]
fn existing() {
let dst = paths::root().join("foo");
fs::create_dir(&dst).unwrap();
cargo_process("new foo")
.with_status(101)
.with_stderr(
"[ERROR] destination `[CWD]/foo` already exists\n\n\
Use `cargo init` to initialize the directory",
)
.run();
}
#[test]
fn invalid_characters() {
cargo_process("new foo.rs")
.with_status(101)
.with_stderr(
"\
[ERROR] Invalid character `.` in crate name: `foo.rs`
use --name to override crate name",
)
.run();
}
#[test]
fn reserved_name() {
cargo_process("new test")
.with_status(101)
.with_stderr(
"\
[ERROR] The name `test` cannot be used as a crate name\n\
use --name to override crate name",
)
.run();
}
#[test]
fn reserved_binary_name() {
cargo_process("new --bin incremental")
.with_status(101)
.with_stderr(
"\
[ERROR] The name `incremental` cannot be used as a crate name\n\
use --name to override crate name",
)
.run();
}
#[test]
fn keyword_name() {
cargo_process("new pub")
.with_status(101)
.with_stderr(
"\
[ERROR] The name `pub` cannot be used as a crate name\n\
use --name to override crate name",
)
.run();
}
#[test]
fn finds_author_user() {
create_empty_gitconfig();
cargo_process("new foo").env("USER", "foo").run();
let toml = paths::root().join("foo/Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["foo"]"#));
}
#[test]
fn finds_author_user_escaped() {
create_empty_gitconfig();
cargo_process("new foo").env("USER", "foo \"bar\"").run();
let toml = paths::root().join("foo/Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["foo \"bar\""]"#));
}
#[test]
fn finds_author_username() {
create_empty_gitconfig();
cargo_process("new foo")
.env_remove("USER")
.env("USERNAME", "foo")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["foo"]"#));
}
#[test]
fn finds_author_priority() {
cargo_process("new foo")
.env("USER", "bar2")
.env("EMAIL", "baz2")
.env("CARGO_NAME", "bar")
.env("CARGO_EMAIL", "baz")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
}
#[test]
fn finds_author_email() {
create_empty_gitconfig();
cargo_process("new foo")
.env("USER", "bar")
.env("EMAIL", "baz")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
}
#[test]
fn finds_author_git() {
git_process("config --global user.name bar").exec().unwrap();
git_process("config --global user.email baz")
.exec()
.unwrap();
cargo_process("new foo").env("USER", "foo").run();
let toml = paths::root().join("foo/Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
}
#[test]
fn finds_local_author_git() {
git_process("init").exec().unwrap();
git_process("config --global user.name foo").exec().unwrap();
git_process("config --global user.email foo@bar")
.exec()
.unwrap();
// Set local git user config
git_process("config user.name bar").exec().unwrap();
git_process("config user.email baz").exec().unwrap();
cargo_process("init").env("USER", "foo").run();
let toml = paths::root().join("Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
}
#[test]
fn finds_git_email() {
cargo_process("new foo")
.env("GIT_AUTHOR_NAME", "foo")
.env("GIT_AUTHOR_EMAIL", "gitfoo")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["foo <gitfoo>"]"#), contents);
}
#[test]
fn finds_git_author() {
create_empty_gitconfig();
cargo_process("new foo")
.env_remove("USER")
.env("GIT_COMMITTER_NAME", "gitfoo")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["gitfoo"]"#));
}
#[test]
fn author_prefers_cargo() {
git_process("config --global user.name foo").exec().unwrap();
git_process("config --global user.email bar")
.exec()
.unwrap();
let root = paths::root();
fs::create_dir(&root.join(".cargo")).unwrap();
File::create(&root.join(".cargo/config"))
.unwrap()
.write_all(
br#"
[cargo-new]
name = "new-foo"
email = "new-bar"
vcs = "none"
"#,
)
.unwrap();
cargo_process("new foo").env("USER", "foo").run();
let toml = paths::root().join("foo/Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["new-foo <new-bar>"]"#));
assert!(!root.join("foo/.gitignore").exists());
}
#[test]
fn strip_angle_bracket_author_email() {
create_empty_gitconfig();
cargo_process("new foo")
.env("USER", "bar")
.env("EMAIL", "<baz>")
.run();
let toml = paths::root().join("foo/Cargo.toml");
let mut contents = String::new();
File::open(&toml)
.unwrap()
.read_to_string(&mut contents)
.unwrap();
assert!(contents.contains(r#"authors = ["bar <baz>"]"#));
}
#[test]
fn git_prefers_command_line() {
let root = paths::root();
fs::create_dir(&root.join(".cargo")).unwrap();
File::create(&root.join(".cargo/config"))
.unwrap()
.write_all(
br#"
[cargo-new]
vcs = "none"
name = "foo"
email = "bar"
"#,
)
.unwrap();
cargo_process("new foo --vcs git").env("USER", "foo").run();
assert!(paths::root().join("foo/.gitignore").exists());
}
#[test]
fn subpackage_no_git() {
cargo_process("new foo").env("USER", "foo").run();
assert!(paths::root().join("foo/.git").is_dir());
assert!(paths::root().join("foo/.gitignore").is_file());
let subpackage = paths::root().join("foo").join("components");
fs::create_dir(&subpackage).unwrap();
cargo_process("new foo/components/subcomponent")
.env("USER", "foo")
.run();
assert!(!paths::root()
.join("foo/components/subcomponent/.git")
.is_file());
assert!(!paths::root()
.join("foo/components/subcomponent/.gitignore")
.is_file());
}
#[test]
fn subpackage_git_with_gitignore() {
cargo_process("new foo").env("USER", "foo").run();
assert!(paths::root().join("foo/.git").is_dir());
assert!(paths::root().join("foo/.gitignore").is_file());
let gitignore = paths::root().join("foo/.gitignore");
fs::write(gitignore, b"components").unwrap();
let subpackage = paths::root().join("foo/components");
fs::create_dir(&subpackage).unwrap();
cargo_process("new foo/components/subcomponent")
.env("USER", "foo")
.run();
assert!(paths::root()
.join("foo/components/subcomponent/.git")
.is_dir());
assert!(paths::root()
.join("foo/components/subcomponent/.gitignore")
.is_file());
}
#[test]
fn subpackage_git_with_vcs_arg() {
cargo_process("new foo").env("USER", "foo").run();
let subpackage = paths::root().join("foo").join("components");
fs::create_dir(&subpackage).unwrap();
cargo_process("new foo/components/subcomponent --vcs git")
.env("USER", "foo")
.run();
assert!(paths::root()
.join("foo/components/subcomponent/.git")
.is_dir());
assert!(paths::root()
.join("foo/components/subcomponent/.gitignore")
.is_file());
}
#[test]
fn unknown_flags() {
cargo_process("new foo --flag")
.with_status(1)
.with_stderr_contains(
"error: Found argument '--flag' which wasn't expected, or isn't valid in this context",
)
.run();
}
#[test]
fn explicit_invalid_name_not_suggested() {
cargo_process("new --name 10-invalid a")
.with_status(101)
.with_stderr("[ERROR] Package names starting with a digit cannot be used as a crate name")
.run();
}
#[test]
fn explicit_project_name() {
cargo_process("new --lib foo --name bar")
.env("USER", "foo")
.with_stderr("[CREATED] library `bar` package")
.run();
}
#[test]
fn new_with_edition_2015() {
cargo_process("new --edition 2015 foo")
.env("USER", "foo")
.run();
let manifest = fs::read_to_string(paths::root().join("foo/Cargo.toml")).unwrap();
assert!(manifest.contains("edition = \"2015\""));
}
#[test]
fn new_with_edition_2018() {
cargo_process("new --edition 2018 foo")
.env("USER", "foo")
.run();
let manifest = fs::read_to_string(paths::root().join("foo/Cargo.toml")).unwrap();
assert!(manifest.contains("edition = \"2018\""));
}
#[test]
fn new_default_edition() {
cargo_process("new foo").env("USER", "foo").run();
let manifest = fs::read_to_string(paths::root().join("foo/Cargo.toml")).unwrap();
assert!(manifest.contains("edition = \"2018\""));
}
#[test]
fn new_with_bad_edition() {
cargo_process("new --edition something_else foo")
.env("USER", "foo")
.with_stderr_contains("error: 'something_else' isn't a valid value[..]")
.with_status(1)
.run();
}
#[test]
fn new_with_blank_email() {
cargo_process("new foo")
.env("CARGO_NAME", "Sen")
.env("CARGO_EMAIL", "")
.run();
let contents = fs::read_to_string(paths::root().join("foo/Cargo.toml")).unwrap();
assert!(contents.contains(r#"authors = ["Sen"]"#), contents);
}