From: Carl Lerche + Yehuda Katz Date: Thu, 12 Jun 2014 22:51:16 +0000 (-0700) Subject: Smoke test for git support X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~1015 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=35e21c7600ed473885accae8fdb08b96e107a6c4;p=cargo.git Smoke test for git support --- diff --git a/Makefile b/Makefile index 0a44bd9f1..edb5b6909 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ $(BIN_TARGETS): target/%: src/bin/%.rs $(HAMMER) $(TOML) $(LIBCARGO) # === Tests -TEST_SRC = $(wildcard tests/*.rs) +TEST_SRC = $(shell find tests -name '*.rs') TEST_DEPS = $(DEPS) -L libs/hamcrest-rust/target target/tests/test-integration: $(HAMCREST) $(TEST_SRC) $(BIN_TARGETS) diff --git a/src/bin/cargo-compile.rs b/src/bin/cargo-compile.rs index b4eae3c0f..fd741c691 100644 --- a/src/bin/cargo-compile.rs +++ b/src/bin/cargo-compile.rs @@ -13,7 +13,7 @@ use hammer::FlagConfig; use cargo::{execute_main_without_stdin,CLIResult,CLIError,ToResult}; use cargo::ops; use cargo::util::important_paths::find_project; -use cargo::util::ToCLI; +use cargo::util::{ToCLI,simple_human}; #[deriving(PartialEq,Clone,Decodable,Encodable)] pub struct Options { diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 072b2bc95..5591b27a5 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -35,6 +35,7 @@ pub fn compile(manifest_path: &Path) -> CargoResult<()> { let sources = try!(sources_for(&package)); + try!(sources.update().wrap("unable to update sources")); let summaries = try!(sources.list().wrap("unable to list packages from source")); let resolved = try!(resolve(package.get_dependencies(), &summaries).wrap("unable to resolve dependencies")); diff --git a/src/cargo/sources/git/source.rs b/src/cargo/sources/git/source.rs index 2e2de1b58..a3872be8e 100644 --- a/src/cargo/sources/git/source.rs +++ b/src/cargo/sources/git/source.rs @@ -37,6 +37,7 @@ impl Show for GitSource { impl Source for GitSource { fn update(&self) -> CargoResult<()> { + log!(5, "updating git source `{}`", self.remote); let repo = try!(self.remote.checkout(&self.db_path)); try!(repo.copy_to(self.reference.as_slice(), &self.checkout_path)); @@ -44,6 +45,7 @@ impl Source for GitSource { } fn list(&self) -> CargoResult> { + log!(5, "listing summaries in git source `{}`", self.remote); let pkg = try!(read_manifest(&self.checkout_path, self.get_namespace())); Ok(vec!(pkg.get_summary().clone())) } @@ -53,6 +55,7 @@ impl Source for GitSource { } fn get(&self, package_ids: &[PackageId]) -> CargoResult> { + log!(5, "getting packages for package ids `{}` from `{}`", package_ids, self.remote); // TODO: Support multiple manifests per repo let pkg = try!(read_manifest(&self.checkout_path, self.remote.get_url())); diff --git a/src/cargo/sources/git/utils.rs b/src/cargo/sources/git/utils.rs index 7218ee41f..4118364cd 100644 --- a/src/cargo/sources/git/utils.rs +++ b/src/cargo/sources/git/utils.rs @@ -67,7 +67,7 @@ macro_rules! errln( * GitRemote represents a remote repository. It gets cloned into a local GitDatabase. */ -#[deriving(PartialEq,Clone)] +#[deriving(PartialEq,Clone,Show)] pub struct GitRemote { url: Url, verbose: bool @@ -170,7 +170,7 @@ impl GitRemote { } fn fetch_into(&self, path: &Path) -> CargoResult<()> { - Ok(git!(*path, self.verbose, "fetch --force --quiet --tags {} refs/heads/*:refs/heads/*", self.url)) + Ok(git!(*path, self.verbose, "fetch --force --quiet --tags {} refs/heads/*:refs/heads/*", self.fetch_location())) } fn clone_into(&self, path: &Path) -> CargoResult<()> { @@ -179,7 +179,14 @@ impl GitRemote { try!(mkdir_recursive(path, UserDir).map_err(|err| human_error(format!("Couldn't recursively create `{}`", dirname.display()), format!("path={}", dirname.display()), io_error(err)))); - Ok(git!(dirname, self.verbose, "clone {} {} --bare --no-hardlinks --quiet", self.url, path.display())) + Ok(git!(dirname, self.verbose, "clone {} {} --bare --no-hardlinks --quiet", self.fetch_location(), path.display())) + } + + fn fetch_location(&self) -> String { + match self.url.scheme.as_slice() { + "file" => self.url.path.clone(), + _ => self.url.to_str() + } } } @@ -254,9 +261,7 @@ impl GitCheckout { } fn git(path: &Path, verbose: bool, str: &str) -> ProcessBuilder { - if verbose { - errln!("Executing git {} @ {}", str, path.display()); - } + debug!("Executing git {} @ {}", str, path.display()); process("git").args(str.split(' ').collect::>().as_slice()).cwd(path.clone()) } diff --git a/src/cargo/util/result.rs b/src/cargo/util/result.rs index e0419e162..8d26fc1a5 100644 --- a/src/cargo/util/result.rs +++ b/src/cargo/util/result.rs @@ -116,14 +116,14 @@ impl CargoError { CargoError { kind: HumanReadableError, desc: BoxedDescription(desc), detail: detail, .. } => { CLIError::new(desc, detail, exit_code) }, - CargoError { kind: InternalError, desc: StaticDescription(desc), detail: None, .. } => { - CLIError::new("An unexpected error occurred", Some(desc), exit_code) + ref err @ CargoError { kind: InternalError, desc: StaticDescription(desc), detail: None, .. } => { + CLIError::new(format!("An unexpected error occurred: {}", err), Some(desc), exit_code) }, - CargoError { kind: InternalError, desc: StaticDescription(desc), detail: Some(detail), .. } => { - CLIError::new("An unexpected error occurred", Some(format!("{}\n{}", desc, detail)), exit_code) + ref err @ CargoError { kind: InternalError, desc: StaticDescription(desc), detail: Some(ref detail), .. } => { + CLIError::new(format!("An unexpected error occurred: {}", err), Some(format!("{}\n{}", desc, detail)), exit_code) }, - _ => { - CLIError::new("An unexpected error occurred", None::<&str>, exit_code) + ref err @ _ => { + CLIError::new(format!("An unexpected error occurred: {}", err), None::<&str>, exit_code) } } } diff --git a/tests/support.rs b/tests/support.rs deleted file mode 100644 index ec4f6172d..000000000 --- a/tests/support.rs +++ /dev/null @@ -1,308 +0,0 @@ -// use std::io::fs::{mkdir_recursive,rmdir_recursive}; -use std; -use std::io; -use std::io::fs; -use std::io::process::{ProcessOutput,ProcessExit}; -use std::os; -use std::path::{Path,BytesContainer}; -use std::str; -use std::vec::Vec; -use std::fmt::Show; -use ham = hamcrest; -use cargo::core::shell; -use cargo::util::{process,ProcessBuilder,CargoError}; -use cargo::util::result::ProcessError; - -static CARGO_INTEGRATION_TEST_DIR : &'static str = "cargo-integration-tests"; - -/* - * - * ===== Builders ===== - * - */ - -#[deriving(PartialEq,Clone)] -struct FileBuilder { - path: Path, - body: String -} - -impl FileBuilder { - pub fn new(path: Path, body: &str) -> FileBuilder { - FileBuilder { path: path, body: body.to_str() } - } - - fn mk(&self) -> Result<(), String> { - try!(mkdir_recursive(&self.dirname())); - - let mut file = try!( - fs::File::create(&self.path) - .with_err_msg(format!("Could not create file; path={}", self.path.display()))); - - file.write_str(self.body.as_slice()) - .with_err_msg(format!("Could not write to file; path={}", self.path.display())) - } - - fn dirname(&self) -> Path { - Path::new(self.path.dirname()) - } -} - -#[deriving(PartialEq,Clone)] -struct ProjectBuilder { - name: String, - root: Path, - files: Vec -} - -impl ProjectBuilder { - pub fn new(name: &str, root: Path) -> ProjectBuilder { - ProjectBuilder { - name: name.to_str(), - root: root, - files: vec!() - } - } - - pub fn root(&self) -> Path { - self.root.clone() - } - - pub fn cargo_process(&self, program: &str) -> ProcessBuilder { - self.build(); - - process(program) - .cwd(self.root()) - .extra_path(cargo_dir()) - } - - pub fn file(mut self, path: B, body: &str) -> ProjectBuilder { - self.files.push(FileBuilder::new(self.root.join(path), body)); - self - } - - // TODO: return something different than a ProjectBuilder - pub fn build<'a>(&'a self) -> &'a ProjectBuilder { - match self.build_with_result() { - Err(e) => fail!(e), - _ => return self - } - } - - pub fn build_with_result(&self) -> Result<(), String> { - // First, clean the directory if it already exists - try!(self.rm_root()); - - // Create the empty directory - try!(mkdir_recursive(&self.root)); - - for file in self.files.iter() { - try!(file.mk()); - } - - Ok(()) - } - - fn rm_root(&self) -> Result<(), String> { - if self.root.exists() { - rmdir_recursive(&self.root) - } - else { - Ok(()) - } - } -} - -// Generates a project layout -pub fn project(name: &str) -> ProjectBuilder { - ProjectBuilder::new(name, os::tmpdir().join(CARGO_INTEGRATION_TEST_DIR)) -} - -// === Helpers === - -pub fn mkdir_recursive(path: &Path) -> Result<(), String> { - fs::mkdir_recursive(path, io::UserDir) - .with_err_msg(format!("could not create directory; path={}", path.display())) -} - -pub fn rmdir_recursive(path: &Path) -> Result<(), String> { - fs::rmdir_recursive(path) - .with_err_msg(format!("could not rm directory; path={}", path.display())) -} - -trait ErrMsg { - fn with_err_msg(self, val: String) -> Result; -} - -impl ErrMsg for Result { - fn with_err_msg(self, val: String) -> Result { - match self { - Ok(val) => Ok(val), - Err(err) => Err(format!("{}; original={}", val, err)) - } - } -} - -// Path to cargo executables -pub fn cargo_dir() -> Path { - os::getenv("CARGO_BIN_PATH") - .map(|s| Path::new(s)) - .unwrap_or_else(|| fail!("CARGO_BIN_PATH wasn't set. Cannot continue running test")) -} - -/// Returns an absolute path in the filesystem that `path` points to. The -/// returned path does not contain any symlinks in its hierarchy. -/* - * - * ===== Matchers ===== - * - */ - -#[deriving(Clone)] -struct Execs { - expect_stdout: Option, - expect_stdin: Option, - expect_stderr: Option, - expect_exit_code: Option -} - -impl Execs { - - pub fn with_stdout(mut ~self, expected: S) -> Box { - self.expect_stdout = Some(expected.to_str()); - self - } - - pub fn with_stderr(mut ~self, expected: S) -> Box { - self.expect_stderr = Some(expected.to_str()); - self - } - - pub fn with_status(mut ~self, expected: int) -> Box { - self.expect_exit_code = Some(expected); - self - } - - fn match_output(&self, actual: &ProcessOutput) -> ham::MatchResult { - self.match_status(actual.status) - .and(self.match_stdout(actual)) - .and(self.match_stderr(actual)) - } - - fn match_status(&self, actual: ProcessExit) -> ham::MatchResult { - match self.expect_exit_code { - None => ham::success(), - Some(code) => { - ham::expect( - actual.matches_exit_status(code), - format!("exited with {}", actual)) - } - } - } - - fn match_stdout(&self, actual: &ProcessOutput) -> ham::MatchResult { - self.match_std(self.expect_stdout.as_ref(), actual.output.as_slice(), "stdout", actual.error.as_slice()) - } - - fn match_stderr(&self, actual: &ProcessOutput) -> ham::MatchResult { - self.match_std(self.expect_stderr.as_ref(), actual.error.as_slice(), "stderr", actual.output.as_slice()) - } - - fn match_std(&self, expected: Option<&String>, actual: &[u8], description: &str, extra: &[u8]) -> ham::MatchResult { - match expected.as_ref().map(|s| s.as_slice()) { - None => ham::success(), - Some(out) => { - match str::from_utf8(actual) { - None => Err(format!("{} was not utf8 encoded", description)), - Some(actual) => { - ham::expect(actual == out, format!("{} was:\n`{}`\n\nexpected:\n`{}`\n\nother output:\n`{}`", description, actual, out, str::from_utf8_lossy(extra))) - } - } - } - } - } -} - -impl ham::SelfDescribing for Execs { - fn describe(&self) -> String { - "execs".to_str() - } -} - -impl ham::Matcher for Execs { - fn matches(&self, process: ProcessBuilder) -> ham::MatchResult { - let res = process.exec_with_output(); - - match res { - Ok(out) => self.match_output(&out), - Err(CargoError { kind: ProcessError(_, ref out), .. }) => self.match_output(out.get_ref()), - Err(e) => Err(format!("could not exec process {}: {}", process, e)) - } - } -} - -pub fn execs() -> Box { - box Execs { - expect_stdout: None, - expect_stderr: None, - expect_stdin: None, - expect_exit_code: None - } -} - -#[deriving(Clone)] -struct ShellWrites { - expected: String -} - -impl ham::SelfDescribing for ShellWrites { - fn describe(&self) -> String { - format!("`{}` written to the shell", self.expected) - } -} - -impl<'a> ham::Matcher<&'a mut shell::Shell> for ShellWrites { - fn matches(&self, actual: &mut shell::Shell) -> ham::MatchResult { - use term::Terminal; - - let actual = std::str::from_utf8_lossy(actual.get_ref().get_ref()).to_str(); - ham::expect(actual == self.expected, actual) - } -} - -pub fn shell_writes(string: T) -> Box { - box ShellWrites { expected: string.to_str() } -} - -pub trait ResultTest { - fn assert(self) -> T; -} - -impl ResultTest for Result { - fn assert(self) -> T { - match self { - Ok(val) => val, - Err(err) => fail!("Result was error: {}", err) - } - } -} - -impl ResultTest for Option { - fn assert(self) -> T { - match self { - Some(val) => val, - None => fail!("Option was None") - } - } -} - -pub trait Tap { - fn tap(mut self, callback: |&mut Self|) -> Self; -} - -impl Tap for T { - fn tap(mut self, callback: |&mut T|) -> T { - callback(&mut self); - self - } -} diff --git a/tests/support/mod.rs b/tests/support/mod.rs new file mode 100644 index 000000000..ac2326ae1 --- /dev/null +++ b/tests/support/mod.rs @@ -0,0 +1,334 @@ +// use std::io::fs::{mkdir_recursive,rmdir_recursive}; +use std; +use std::io; +use std::io::fs; +use std::io::process::{ProcessOutput,ProcessExit}; +use std::os; +use std::path::{Path,BytesContainer}; +use std::str; +use std::vec::Vec; +use std::fmt::Show; +use ham = hamcrest; +use cargo::core::shell; +use cargo::util::{process,ProcessBuilder,CargoError}; +use cargo::util::result::ProcessError; + +pub mod paths; + +/* + * + * ===== Builders ===== + * + */ + +#[deriving(PartialEq,Clone)] +struct FileBuilder { + path: Path, + body: String +} + +impl FileBuilder { + pub fn new(path: Path, body: &str) -> FileBuilder { + FileBuilder { path: path, body: body.to_str() } + } + + fn mk(&self) -> Result<(), String> { + try!(mkdir_recursive(&self.dirname())); + + let mut file = try!( + fs::File::create(&self.path) + .with_err_msg(format!("Could not create file; path={}", self.path.display()))); + + file.write_str(self.body.as_slice()) + .with_err_msg(format!("Could not write to file; path={}", self.path.display())) + } + + fn dirname(&self) -> Path { + Path::new(self.path.dirname()) + } +} + +#[deriving(PartialEq,Clone)] +pub struct ProjectBuilder { + name: String, + root: Path, + files: Vec +} + +impl ProjectBuilder { + pub fn new(name: &str, root: Path) -> ProjectBuilder { + ProjectBuilder { + name: name.to_str(), + root: root, + files: vec!() + } + } + + pub fn join(&self, name: &str, path: T) -> ProjectBuilder { + ProjectBuilder { + name: name.as_slice().to_str(), + root: self.root.join(path.as_slice()).clone(), + files: vec!() + } + } + + pub fn root(&self) -> Path { + self.root.clone() + } + + pub fn process(&self, program: &str) -> ProcessBuilder { + process(program) + .cwd(self.root()) + .env("HOME", Some(paths::home().display().to_str().as_slice())) + } + + pub fn cargo_process(&self, program: &str) -> ProcessBuilder { + self.build(); + self.process(program) + .extra_path(cargo_dir()) + } + + pub fn file(mut self, path: B, body: S) -> ProjectBuilder { + self.files.push(FileBuilder::new(self.root.join(path), body.as_slice())); + self + } + + // TODO: return something different than a ProjectBuilder + pub fn build<'a>(&'a self) -> &'a ProjectBuilder { + match self.build_with_result() { + Err(e) => fail!(e), + _ => return self + } + } + + pub fn build_with_result(&self) -> Result<(), String> { + // First, clean the directory if it already exists + try!(self.rm_root()); + + // Create the empty directory + try!(mkdir_recursive(&self.root)); + + for file in self.files.iter() { + try!(file.mk()); + } + + Ok(()) + } + + fn rm_root(&self) -> Result<(), String> { + if self.root.exists() { + rmdir_recursive(&self.root) + } + else { + Ok(()) + } + } +} + +// Generates a project layout +pub fn project(name: &str) -> ProjectBuilder { + ProjectBuilder::new(name, paths::root().join(name)) +} + +// === Helpers === + +pub fn mkdir_recursive(path: &Path) -> Result<(), String> { + fs::mkdir_recursive(path, io::UserDir) + .with_err_msg(format!("could not create directory; path={}", path.display())) +} + +pub fn rmdir_recursive(path: &Path) -> Result<(), String> { + fs::rmdir_recursive(path) + .with_err_msg(format!("could not rm directory; path={}", path.display())) +} + +pub fn main_file(println: T, deps: &[&str]) -> String { + let mut buf = String::new(); + + for dep in deps.iter() { + buf.push_str(format!("extern crate {};\n", dep).as_slice()); + } + + buf.push_str("fn main() { println!("); + buf.push_str(println.as_slice()); + buf.push_str("); }\n"); + + buf.to_str() +} + +trait ErrMsg { + fn with_err_msg(self, val: String) -> Result; +} + +impl ErrMsg for Result { + fn with_err_msg(self, val: String) -> Result { + match self { + Ok(val) => Ok(val), + Err(err) => Err(format!("{}; original={}", val, err)) + } + } +} + +// Path to cargo executables +pub fn cargo_dir() -> Path { + os::getenv("CARGO_BIN_PATH") + .map(|s| Path::new(s)) + .unwrap_or_else(|| fail!("CARGO_BIN_PATH wasn't set. Cannot continue running test")) +} + +/// Returns an absolute path in the filesystem that `path` points to. The +/// returned path does not contain any symlinks in its hierarchy. +/* + * + * ===== Matchers ===== + * + */ + +#[deriving(Clone)] +struct Execs { + expect_stdout: Option, + expect_stdin: Option, + expect_stderr: Option, + expect_exit_code: Option +} + +impl Execs { + + pub fn with_stdout(mut ~self, expected: S) -> Box { + self.expect_stdout = Some(expected.to_str()); + self + } + + pub fn with_stderr(mut ~self, expected: S) -> Box { + self.expect_stderr = Some(expected.to_str()); + self + } + + pub fn with_status(mut ~self, expected: int) -> Box { + self.expect_exit_code = Some(expected); + self + } + + fn match_output(&self, actual: &ProcessOutput) -> ham::MatchResult { + self.match_status(actual.status) + .and(self.match_stdout(actual)) + .and(self.match_stderr(actual)) + } + + fn match_status(&self, actual: ProcessExit) -> ham::MatchResult { + match self.expect_exit_code { + None => ham::success(), + Some(code) => { + ham::expect( + actual.matches_exit_status(code), + format!("exited with {}", actual)) + } + } + } + + fn match_stdout(&self, actual: &ProcessOutput) -> ham::MatchResult { + self.match_std(self.expect_stdout.as_ref(), actual.output.as_slice(), "stdout", actual.error.as_slice()) + } + + fn match_stderr(&self, actual: &ProcessOutput) -> ham::MatchResult { + self.match_std(self.expect_stderr.as_ref(), actual.error.as_slice(), "stderr", actual.output.as_slice()) + } + + fn match_std(&self, expected: Option<&String>, actual: &[u8], description: &str, extra: &[u8]) -> ham::MatchResult { + match expected.as_ref().map(|s| s.as_slice()) { + None => ham::success(), + Some(out) => { + match str::from_utf8(actual) { + None => Err(format!("{} was not utf8 encoded", description)), + Some(actual) => { + ham::expect(actual == out, format!("{} was:\n`{}`\n\nexpected:\n`{}`\n\nother output:\n`{}`", description, actual, out, str::from_utf8_lossy(extra))) + } + } + } + } + } +} + +impl ham::SelfDescribing for Execs { + fn describe(&self) -> String { + "execs".to_str() + } +} + +impl ham::Matcher for Execs { + fn matches(&self, process: ProcessBuilder) -> ham::MatchResult { + let res = process.exec_with_output(); + + match res { + Ok(out) => self.match_output(&out), + Err(CargoError { kind: ProcessError(_, ref out), .. }) => self.match_output(out.get_ref()), + Err(e) => Err(format!("could not exec process {}: {}", process, e)) + } + } +} + +pub fn execs() -> Box { + box Execs { + expect_stdout: None, + expect_stderr: None, + expect_stdin: None, + expect_exit_code: None + } +} + +#[deriving(Clone)] +struct ShellWrites { + expected: String +} + +impl ham::SelfDescribing for ShellWrites { + fn describe(&self) -> String { + format!("`{}` written to the shell", self.expected) + } +} + +impl<'a> ham::Matcher<&'a mut shell::Shell> for ShellWrites { + fn matches(&self, actual: &mut shell::Shell) -> ham::MatchResult { + use term::Terminal; + + let actual = std::str::from_utf8_lossy(actual.get_ref().get_ref()).to_str(); + ham::expect(actual == self.expected, actual) + } +} + +pub fn shell_writes(string: T) -> Box { + box ShellWrites { expected: string.to_str() } +} + +pub trait ResultTest { + fn assert(self) -> T; +} + +impl ResultTest for Result { + fn assert(self) -> T { + match self { + Ok(val) => val, + Err(err) => fail!("Result was error: {}", err) + } + } +} + +impl ResultTest for Option { + fn assert(self) -> T { + match self { + Some(val) => val, + None => fail!("Option was None") + } + } +} + +pub trait Tap { + fn tap(mut self, callback: |&mut Self|) -> Self; +} + +impl Tap for T { + fn tap(mut self, callback: |&mut T|) -> T { + callback(&mut self); + self + } +} diff --git a/tests/support/paths.rs b/tests/support/paths.rs new file mode 100644 index 000000000..84013ac6b --- /dev/null +++ b/tests/support/paths.rs @@ -0,0 +1,46 @@ +use std::{io,os}; +use std::io::IoResult; +use std::io::fs; +use cargo::util::realpath; + +static CARGO_INTEGRATION_TEST_DIR : &'static str = "cargo-integration-tests"; + +pub fn root() -> Path { + realpath(&os::tmpdir().join(CARGO_INTEGRATION_TEST_DIR)).unwrap() +} + +pub fn home() -> Path { + root().join("home") +} + +pub trait PathExt { + fn rm_rf(&self) -> IoResult<()>; + fn mkdir_p(&self) -> IoResult<()>; +} + +impl PathExt for Path { + /* Technically there is a potential race condition, but we don't + * care all that much for our tests + */ + fn rm_rf(&self) -> IoResult<()> { + if self.exists() { + fs::rmdir_recursive(self) + } + else { + Ok(()) + } + } + + fn mkdir_p(&self) -> IoResult<()> { + fs::mkdir_recursive(self, io::UserDir) + } +} + +/** + * Ensure required test directories exist and are empty + */ +pub fn setup() { + debug!("path setup; root={}; home={}", root().display(), home().display()); + root().rm_rf().unwrap(); + home().mkdir_p().unwrap(); +} diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 1fad32a04..39cc57026 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -1,4 +1,4 @@ -use support::{ResultTest,project,execs}; +use support::{ResultTest,project,execs,main_file}; use hamcrest::{assert_that,existing_file}; use cargo; use cargo::util::{process,realpath}; @@ -284,18 +284,4 @@ test!(cargo_compile_with_nested_deps_longhand { execs().with_stdout("test passed\n")); }) -fn main_file(println: &str, deps: &[&str]) -> String { - let mut buf = String::new(); - - for dep in deps.iter() { - buf.push_str(format!("extern crate {};\n", dep).as_slice()); - } - - buf.push_str("fn main() { println!("); - buf.push_str(println); - buf.push_str("); }\n"); - - buf.to_str() -} - // test!(compiling_project_with_invalid_manifest) diff --git a/tests/test_cargo_compile_git_deps.rs b/tests/test_cargo_compile_git_deps.rs new file mode 100644 index 000000000..2574a3631 --- /dev/null +++ b/tests/test_cargo_compile_git_deps.rs @@ -0,0 +1,79 @@ +use support::{ProjectBuilder,ResultTest,project,execs,main_file}; +use hamcrest::{assert_that,existing_file}; +use cargo; +use cargo::util::{CargoResult,process}; + +fn setup() { +} + +fn git_repo(name: &str, callback: |ProjectBuilder| -> ProjectBuilder) -> CargoResult { + let mut git_project = project(name); + git_project = callback(git_project); + git_project.build(); + + log!(5, "git init"); + try!(git_project.process("git").args(["init"]).exec_with_output()); + log!(5, "building git project"); + log!(5, "git add ."); + try!(git_project.process("git").args(["add", "."]).exec_with_output()); + log!(5, "git commit"); + try!(git_project.process("git").args(["commit", "-m", "Initial commit"]).exec_with_output()); + Ok(git_project) +} + +test!(cargo_compile_simple_git_dep { + let project = project("foo"); + let git_project = git_repo("dep1", |project| { + project + .file("Cargo.toml", r#" + [project] + + name = "dep1" + version = "0.5.0" + authors = ["carlhuda@example.com"] + + [[lib]] + + name = "dep1" + "#) + .file("src/dep1.rs", r#" + pub fn hello() -> &'static str { + "hello world" + } + "#) + }).assert(); + + let project = project + .file("Cargo.toml", format!(r#" + [project] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.dep1] + + version = "0.5.0" + git = "file://{}" + + [[bin]] + + name = "foo" + "#, git_project.root().display())) + .file("src/foo.rs", main_file(r#""{}", dep1::hello()"#, ["dep1"])); + + let root = project.root(); + let git_root = git_project.root(); + + assert_that(project.cargo_process("cargo-compile"), + execs() + .with_stdout(format!("Compiling dep1 v0.5.0 (file:{})\nCompiling foo v0.5.0 (file:{})\n", + git_root.display(), root.display())) + .with_stderr("")); + + assert_that(&project.root().join("target/foo"), existing_file()); + + assert_that( + cargo::util::process("foo").extra_path(project.root().join("target")), + execs().with_stdout("hello world\n")); +}) diff --git a/tests/tests.rs b/tests/tests.rs index c9dfb93e2..3357e0a62 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -8,16 +8,18 @@ extern crate hamcrest; #[phase(plugin, link)] extern crate log; +mod support; macro_rules! test( ($name:ident $expr:expr) => ( #[test] fn $name() { + ::support::paths::setup(); setup(); $expr; } ) ) -mod support; mod test_cargo_compile; +mod test_cargo_compile_git_deps; mod test_shell;