Skip to content

Commit 836c22d

Browse files
committed
Auto merge of #3426 - nrc:check-fix-2, r=alexcrichton
Test for #3419 Based on top of #3425. I'm not sure if this is an acceptable test because it downloads rustc-serialize. r? @alexcrichton
2 parents bf559b9 + 129ce53 commit 836c22d

File tree

3 files changed

+165
-41
lines changed

3 files changed

+165
-41
lines changed

src/cargo/ops/cargo_rustc/context.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
169169
kind: Kind)
170170
-> CargoResult<()> {
171171
let rustflags = env_args(self.config,
172-
&self.build_config,
173-
kind,
174-
"RUSTFLAGS")?;
172+
&self.build_config,
173+
kind,
174+
"RUSTFLAGS")?;
175175
let mut process = self.config.rustc()?.process();
176176
process.arg("-")
177177
.arg("--crate-name").arg("___")
@@ -613,17 +613,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
613613
match self.get_package(id) {
614614
Ok(pkg) => {
615615
pkg.targets().iter().find(|t| t.is_lib()).map(|t| {
616-
let profile = if unit.profile.check &&
617-
!t.is_custom_build()
618-
&& !t.for_host() {
619-
&self.profiles.check
620-
} else {
621-
self.lib_profile()
622-
};
623616
let unit = Unit {
624617
pkg: pkg,
625618
target: t,
626-
profile: profile,
619+
profile: self.lib_or_check_profile(unit, t),
627620
kind: unit.kind.for_target(t),
628621
};
629622
Ok(unit)
@@ -780,7 +773,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
780773
Unit {
781774
pkg: unit.pkg,
782775
target: t,
783-
profile: self.lib_profile(),
776+
profile: self.lib_or_check_profile(unit, t),
784777
kind: unit.kind.for_target(t),
785778
}
786779
})
@@ -848,6 +841,14 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
848841
}
849842
}
850843

844+
pub fn lib_or_check_profile(&self, unit: &Unit, target: &Target) -> &'a Profile {
845+
if unit.profile.check && !target.is_custom_build() && !target.for_host() {
846+
&self.profiles.check
847+
} else {
848+
self.lib_profile()
849+
}
850+
}
851+
851852
pub fn build_script_profile(&self, _pkg: &PackageId) -> &'a Profile {
852853
// TODO: should build scripts always be built with the same library
853854
// profile? How is this controlled at the CLI layer?

tests/cargotest/support/mod.rs

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ pub struct Execs {
263263
expect_exit_code: Option<i32>,
264264
expect_stdout_contains: Vec<String>,
265265
expect_stderr_contains: Vec<String>,
266+
expect_stdout_not_contains: Vec<String>,
267+
expect_stderr_not_contains: Vec<String>,
266268
expect_json: Option<Vec<Json>>,
267269
}
268270

@@ -292,6 +294,16 @@ impl Execs {
292294
self
293295
}
294296

297+
pub fn with_stdout_does_not_contain<S: ToString>(mut self, expected: S) -> Execs {
298+
self.expect_stdout_not_contains.push(expected.to_string());
299+
self
300+
}
301+
302+
pub fn with_stderr_does_not_contain<S: ToString>(mut self, expected: S) -> Execs {
303+
self.expect_stderr_not_contains.push(expected.to_string());
304+
self
305+
}
306+
295307
pub fn with_json(mut self, expected: &str) -> Execs {
296308
self.expect_json = Some(expected.split("\n\n").map(|obj| {
297309
Json::from_str(obj).unwrap()
@@ -321,14 +333,22 @@ impl Execs {
321333

322334
fn match_stdout(&self, actual: &Output) -> ham::MatchResult {
323335
self.match_std(self.expect_stdout.as_ref(), &actual.stdout,
324-
"stdout", &actual.stderr, false)?;
336+
"stdout", &actual.stderr, MatchKind::Exact)?;
325337
for expect in self.expect_stdout_contains.iter() {
326338
self.match_std(Some(expect), &actual.stdout, "stdout",
327-
&actual.stderr, true)?;
339+
&actual.stderr, MatchKind::Partial)?;
328340
}
329341
for expect in self.expect_stderr_contains.iter() {
330342
self.match_std(Some(expect), &actual.stderr, "stderr",
331-
&actual.stdout, true)?;
343+
&actual.stdout, MatchKind::Partial)?;
344+
}
345+
for expect in self.expect_stdout_not_contains.iter() {
346+
self.match_std(Some(expect), &actual.stdout, "stdout",
347+
&actual.stderr, MatchKind::NotPresent)?;
348+
}
349+
for expect in self.expect_stderr_not_contains.iter() {
350+
self.match_std(Some(expect), &actual.stderr, "stderr",
351+
&actual.stdout, MatchKind::NotPresent)?;
332352
}
333353

334354
if let Some(ref objects) = self.expect_json {
@@ -349,12 +369,12 @@ impl Execs {
349369

350370
fn match_stderr(&self, actual: &Output) -> ham::MatchResult {
351371
self.match_std(self.expect_stderr.as_ref(), &actual.stderr,
352-
"stderr", &actual.stdout, false)
372+
"stderr", &actual.stdout, MatchKind::Exact)
353373
}
354374

355375
fn match_std(&self, expected: Option<&String>, actual: &[u8],
356376
description: &str, extra: &[u8],
357-
partial: bool) -> ham::MatchResult {
377+
kind: MatchKind) -> ham::MatchResult {
358378
let out = match expected {
359379
Some(out) => out,
360380
None => return ham::success(),
@@ -368,33 +388,46 @@ impl Execs {
368388
let actual = actual.replace("\r", "");
369389
let actual = actual.replace("\t", "<tab>");
370390

371-
let mut a = actual.lines();
372-
let e = out.lines();
373-
374-
if partial {
375-
let mut diffs = self.diff_lines(a.clone(), e.clone(), partial);
376-
while let Some(..) = a.next() {
377-
let a = self.diff_lines(a.clone(), e.clone(), partial);
378-
if a.len() < diffs.len() {
379-
diffs = a;
391+
match kind {
392+
MatchKind::Exact => {
393+
let a = actual.lines();
394+
let e = out.lines();
395+
396+
let diffs = self.diff_lines(a, e, false);
397+
ham::expect(diffs.is_empty(),
398+
format!("differences:\n\
399+
{}\n\n\
400+
other output:\n\
401+
`{}`", diffs.join("\n"),
402+
String::from_utf8_lossy(extra)))
403+
}
404+
MatchKind::Partial => {
405+
let mut a = actual.lines();
406+
let e = out.lines();
407+
408+
let mut diffs = self.diff_lines(a.clone(), e.clone(), true);
409+
while let Some(..) = a.next() {
410+
let a = self.diff_lines(a.clone(), e.clone(), true);
411+
if a.len() < diffs.len() {
412+
diffs = a;
413+
}
380414
}
415+
ham::expect(diffs.is_empty(),
416+
format!("expected to find:\n\
417+
{}\n\n\
418+
did not find in output:\n\
419+
{}", out,
420+
actual))
421+
}
422+
MatchKind::NotPresent => {
423+
ham::expect(!actual.contains(out),
424+
format!("expected not to find:\n\
425+
{}\n\n\
426+
but found in output:\n\
427+
{}", out,
428+
actual))
381429
}
382-
ham::expect(diffs.is_empty(),
383-
format!("expected to find:\n\
384-
{}\n\n\
385-
did not find in output:\n\
386-
{}", out,
387-
actual))
388-
} else {
389-
let diffs = self.diff_lines(a, e, partial);
390-
ham::expect(diffs.is_empty(),
391-
format!("differences:\n\
392-
{}\n\n\
393-
other output:\n\
394-
`{}`", diffs.join("\n"),
395-
String::from_utf8_lossy(extra)))
396430
}
397-
398431
}
399432

400433
fn match_json(&self, expected: &Json, line: &str) -> ham::MatchResult {
@@ -441,6 +474,13 @@ impl Execs {
441474
}
442475
}
443476

477+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
478+
enum MatchKind {
479+
Exact,
480+
Partial,
481+
NotPresent,
482+
}
483+
444484
pub fn lines_match(expected: &str, mut actual: &str) -> bool {
445485
let expected = substitute_macros(expected);
446486
for (i, part) in expected.split("[..]").enumerate() {
@@ -589,6 +629,8 @@ pub fn execs() -> Execs {
589629
expect_exit_code: None,
590630
expect_stdout_contains: Vec::new(),
591631
expect_stderr_contains: Vec::new(),
632+
expect_stdout_not_contains: Vec::new(),
633+
expect_stderr_not_contains: Vec::new(),
592634
expect_json: None,
593635
}
594636
}

tests/check.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ extern crate hamcrest;
33

44
use cargotest::is_nightly;
55
use cargotest::support::{execs, project};
6+
use cargotest::support::registry::Package;
67
use hamcrest::assert_that;
78

89
#[test]
@@ -219,3 +220,83 @@ fn build_check() {
219220
assert_that(foo.cargo_process("check"),
220221
execs().with_status(0));
221222
}
223+
224+
// Checks that where a project has both a lib and a bin, the lib is only checked
225+
// not built.
226+
#[test]
227+
fn issue_3418() {
228+
if !is_nightly() {
229+
return;
230+
}
231+
232+
let foo = project("foo")
233+
.file("Cargo.toml", r#"
234+
[package]
235+
name = "foo"
236+
version = "0.1.0"
237+
authors = []
238+
239+
[dependencies]
240+
"#)
241+
.file("src/lib.rs", "")
242+
.file("src/main.rs", "fn main() {}");
243+
foo.build();
244+
245+
assert_that(foo.cargo_process("check").arg("-v"),
246+
execs().with_status(0)
247+
.with_stderr_does_not_contain("--crate-type lib"));
248+
}
249+
250+
// Some weirdness that seems to be caused by a crate being built as well as
251+
// checked, but in this case with a proc macro too.
252+
#[test]
253+
fn issue_3419() {
254+
if !is_nightly() {
255+
return;
256+
}
257+
258+
let foo = project("foo")
259+
.file("Cargo.toml", r#"
260+
[package]
261+
name = "foo"
262+
version = "0.0.1"
263+
authors = []
264+
265+
[dependencies]
266+
rustc-serialize = "*"
267+
"#)
268+
.file("src/lib.rs", r#"
269+
extern crate rustc_serialize;
270+
271+
use rustc_serialize::Decodable;
272+
273+
pub fn take<T: Decodable>() {}
274+
"#)
275+
.file("src/main.rs", r#"
276+
extern crate rustc_serialize;
277+
278+
extern crate foo;
279+
280+
#[derive(RustcDecodable)]
281+
pub struct Foo;
282+
283+
fn main() {
284+
foo::take::<Foo>();
285+
}
286+
"#);
287+
288+
Package::new("rustc-serialize", "1.0.0")
289+
.file("src/lib.rs",
290+
r#"pub trait Decodable: Sized {
291+
fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error>;
292+
}
293+
pub trait Decoder {
294+
type Error;
295+
fn read_struct<T, F>(&mut self, s_name: &str, len: usize, f: F)
296+
-> Result<T, Self::Error>
297+
where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
298+
} "#).publish();
299+
300+
assert_that(foo.cargo_process("check"),
301+
execs().with_status(0));
302+
}

0 commit comments

Comments
 (0)