diff --git a/CHANGELOG.md b/CHANGELOG.md index 73d85d9279..2c8be36f19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,25 @@ file. ### Removed +## [0.14.2] +### Added +- Added `--all-targets` to config file + +### Changed +- Actually pass `--all-targets` to cargo +- Merge more CLI options with active config (no-run, no-default-features, +ignore-panics, forward-signals, run-ignored, release, count, all-features, +all-targets, line-coverage, branch-coverage, offline, timeout, features, +out, arguments passed to test executable, -Z) +- Update stats for all traces when they match a single address +- Correct handling of doc tests in workspaces as doctest name is relative to +package root not workspace root +- Return an error if a doctest fails to compile +- Include files with no coverable lines in Html report +- `--ignore-panics` now ignores `assert_*` and `debug_assert*` macros + +### Removed + ## [0.14.1] - 2020-07-01 ### Added - run-types for lib, bins and all-targets diff --git a/Cargo.lock b/Cargo.lock index efdbcd4d89..34a0ed86da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,7 +55,7 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "cargo-tarpaulin" -version = "0.14.1" +version = "0.14.2" dependencies = [ "cargo_metadata", "chrono", @@ -115,9 +115,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "chrono" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" +checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6" dependencies = [ "num-integer", "num-traits", @@ -236,9 +236,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" +checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" dependencies = [ "fallible-iterator", "indexmap", @@ -347,9 +347,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.71" +version = "0.2.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" +checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701" [[package]] name = "libgit2-sys" diff --git a/Cargo.toml b/Cargo.toml index 522a77295b..3c299cb83a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-tarpaulin" -version = "0.14.1" +version = "0.14.2" authors = ["Daniel McKenna "] description = "Cargo-Tarpaulin is a tool to determine code coverage achieved via tests" repository = "https://github.com/xd009642/tarpaulin" @@ -26,12 +26,12 @@ clap = "2.33.1" coveralls-api = "0.5.0" env_logger = "0.7" fallible-iterator = "0.2.0" -gimli = "0.21.0" +gimli = "0.22.0" git2 = "0.13" humantime-serde = "1" indexmap = { version = "1.4.0", features = ["serde-1"] } lazy_static = "1.0" -libc = "0.2.71" +libc = "0.2.72" log = "0.4.8" memmap = "0.7.0" nix = "0.17.0" diff --git a/README.md b/README.md index 19cada9521..deca18f3e2 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ want to run it locally, e.g. during development. See below for how to do that. Below is the help-text for a thorough explanation of the flags and features available: -```bash -cargo-tarpaulin version: 0.14.1 +``` +cargo-tarpaulin version: 0.14.2 Tool to analyse test coverage of cargo projects USAGE: diff --git a/src/cargo.rs b/src/cargo.rs index a5f1d9646c..f69bdcf880 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -4,7 +4,7 @@ use crate::path_utils::get_source_walker; use cargo_metadata::{diagnostic::DiagnosticLevel, CargoOpt, Message, Metadata, MetadataCommand}; use log::{error, trace, warn}; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::env; use std::fs::{read_dir, remove_dir_all, File}; use std::io; @@ -184,6 +184,7 @@ fn run_cargo( .map_err(|e| RunError::Cargo(e.to_string()))?; if !out.status.success() { error!("Building doctests failed"); + return Err(RunError::Cargo("Building doctest failed".to_string())); } let walker = WalkDir::new(&config.doctest_dir()).into_iter(); let dir_entries = walker @@ -217,7 +218,7 @@ fn convert_to_prefix(p: &Path) -> Option { fn is_prefix_match(prefix: &str, entry: &Path) -> bool { convert_to_prefix(entry) - .map(|s| prefix.starts_with(&s)) + .map(|s| s.ends_with(prefix)) .unwrap_or(false) } @@ -232,6 +233,7 @@ fn is_prefix_match(prefix: &str, entry: &Path) -> bool { /// that any matching file is good because we can't do any better fn get_panic_candidates(tests: &[DirEntry], config: &Config) -> HashMap> { let mut result = HashMap::new(); + let mut checked_files = HashSet::new(); let root = config.root(); for test in tests { if let Some(test_binary) = DocTestBinaryMeta::new(test.path()) { @@ -240,13 +242,18 @@ fn get_panic_candidates(tests: &[DirEntry], config: &Config) -> HashMap>, } +fn default_test_timeout() -> Duration { + Duration::from_secs(60) +} + impl Default for Config { fn default() -> Config { Config { @@ -161,6 +167,7 @@ impl Default for Config { config: None, root: Default::default(), run_ignored: false, + all_targets: false, ignore_tests: false, ignore_panics: false, force_clean: false, @@ -185,7 +192,7 @@ impl Default for Config { excluded_files: RefCell::new(vec![]), excluded_files_raw: vec![], varargs: vec![], - test_timeout: Duration::from_secs(60), + test_timeout: default_test_timeout(), release: false, all_features: false, no_run: false, @@ -231,6 +238,7 @@ impl<'a> From<&'a ArgMatches<'a>> for ConfigWrapper { ignore_panics: args.is_present("ignore-panics"), force_clean: args.is_present("force-clean"), no_fail_fast: args.is_present("no-fail-fast"), + all_targets: args.is_present("all-targets"), verbose, debug, dump_traces, @@ -431,7 +439,19 @@ impl Config { } else if other.verbose { self.verbose = other.verbose; } + self.no_run |= other.no_run; + self.no_default_features |= other.no_default_features; + self.ignore_panics |= other.ignore_panics; + self.forward_signals |= other.forward_signals; + self.run_ignored |= other.run_ignored; + self.release |= other.release; + self.count |= other.count; + self.all_features |= other.all_features; + self.all_targets |= other.all_targets; + self.line_coverage |= other.line_coverage; + self.branch_coverage |= other.branch_coverage; self.dump_traces |= other.dump_traces; + self.offline |= other.offline; self.manifest = other.manifest.clone(); self.root = Config::pick_optional_config(&self.root, &other.root); self.coveralls = Config::pick_optional_config(&self.coveralls, &other.coveralls); @@ -448,9 +468,21 @@ impl Config { self.ignore_tests |= other.ignore_tests; self.no_fail_fast |= other.no_fail_fast; + if other.test_timeout != default_test_timeout() { + self.test_timeout = other.test_timeout.clone(); + } + if self.profile.is_none() && other.profile.is_some() { self.profile = other.profile.clone(); } + if other.features.is_some() { + if self.features.is_none() { + self.features = other.features.clone(); + } else if let Some(features) = self.features.as_mut() { + features.push(' '); + features.push_str(other.features.as_ref().unwrap()); + } + } let additional_packages = other .packages @@ -460,6 +492,14 @@ impl Config { .collect::>(); self.packages.extend(additional_packages); + let additional_outs = other + .generate + .iter() + .filter(|out| !self.generate.contains(out)) + .copied() + .collect::>(); + self.generate.extend(additional_outs); + let additional_excludes = other .exclude .iter() @@ -468,6 +508,22 @@ impl Config { .collect::>(); self.exclude.extend(additional_excludes); + let additional_varargs = other + .varargs + .iter() + .filter(|package| !self.varargs.contains(package)) + .cloned() + .collect::>(); + self.varargs.extend(additional_varargs); + + let additional_z_opts = other + .unstable_features + .iter() + .filter(|package| !self.unstable_features.contains(package)) + .cloned() + .collect::>(); + self.unstable_features.extend(additional_z_opts); + let exclude = &self.exclude; self.packages.retain(|package| { let keep = !exclude.contains(package); @@ -964,6 +1020,7 @@ mod tests { no-fail-fast = true profile = "Release" dump-traces = true + all-targets = true "#; let mut configs = Config::parse_config_toml(toml.as_bytes()).unwrap(); assert_eq!(configs.len(), 1); @@ -971,6 +1028,7 @@ mod tests { assert!(config.debug); assert!(config.verbose); assert!(config.dump_traces); + assert!(config.all_targets); assert!(config.ignore_panics); assert!(config.count); assert!(config.run_ignored); diff --git a/src/config/types.rs b/src/config/types.rs index 28af54bf92..7c9a26b6ed 100644 --- a/src/config/types.rs +++ b/src/config/types.rs @@ -17,7 +17,7 @@ arg_enum! { } arg_enum! { - #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize)] + #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize)] pub enum OutputFile { Json, Toml, diff --git a/src/lib.rs b/src/lib.rs index 344dd886b0..ca021daae5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ use crate::cargo::TestBinary; use crate::config::*; use crate::errors::*; use crate::event_log::*; +use crate::path_utils::*; use crate::process_handling::*; use crate::report::report_coverage; use crate::source_analysis::LineAnalysis; @@ -81,7 +82,13 @@ pub fn trace(configs: &[Config]) -> Result { } pub fn run(configs: &[Config]) -> Result<(), RunError> { - let tracemap = trace(configs)?; + let mut tracemap = trace(configs)?; + if !configs.is_empty() { + // Assumption: all configs are for the same project + for dir in get_source_walker(&configs[0]) { + tracemap.add_file(dir.path()); + } + } if configs.len() == 1 { report_coverage(&configs[0], &tracemap)?; } else if !configs.is_empty() { diff --git a/src/report/cobertura.rs b/src/report/cobertura.rs index f4eef79ddd..1127ba76b7 100644 --- a/src/report/cobertura.rs +++ b/src/report/cobertura.rs @@ -338,7 +338,7 @@ fn render_classes(config: &Config, traces: &TraceMap, pkg: &Path) -> Vec .files() .iter() .filter(|x| x.parent() == Some(pkg)) - .map(|x| render_class(config, traces, x)) + .filter_map(|x| render_class(config, traces, x)) .collect() } @@ -350,7 +350,7 @@ fn render_classes(config: &Config, traces: &TraceMap, pkg: &Path) -> Vec // Until this is fixed, the render_method function will panic if called, as it // cannot be properly implemented. // -fn render_class(config: &Config, traces: &TraceMap, file: &Path) -> Class { +fn render_class(config: &Config, traces: &TraceMap, file: &Path) -> Option { let name = file .file_stem() .map(|x| x.to_str().unwrap()) @@ -358,23 +358,27 @@ fn render_class(config: &Config, traces: &TraceMap, file: &Path) -> Class { .to_string(); let file_name = config.strip_base_dir(file).to_str().unwrap().to_string(); - - let covered = traces.covered_in_path(file) as f64; - let line_rate = covered / traces.coverable_in_path(file) as f64; - let lines = traces - .get_child_traces(file) - .iter() - .map(|x| render_line(x)) - .collect(); - - Class { - name, - file_name, - line_rate, - branch_rate: 0.0, - complexity: 0.0, - lines, - methods: vec![], + let coverable = traces.coverable_in_path(file); + if coverable == 0 { + None + } else { + let covered = traces.covered_in_path(file) as f64; + let line_rate = covered / coverable as f64; + let lines = traces + .get_child_traces(file) + .iter() + .map(|x| render_line(x)) + .collect(); + + Some(Class { + name, + file_name, + line_rate, + branch_rate: 0.0, + complexity: 0.0, + lines, + methods: vec![], + }) } } diff --git a/src/report/coveralls.rs b/src/report/coveralls.rs index 88f4234b90..8a94365cda 100644 --- a/src/report/coveralls.rs +++ b/src/report/coveralls.rs @@ -98,8 +98,10 @@ pub fn export(coverage_data: &TraceMap, config: &Config) -> Result<(), RunError> } } } - if let Ok(source) = Source::new(&rel_path, file, &lines, &None, false) { - report.add_source(source); + if !lines.is_empty() { + if let Ok(source) = Source::new(&rel_path, file, &lines, &None, false) { + report.add_source(source); + } } } diff --git a/src/report/lcov.rs b/src/report/lcov.rs index c1d2f145e6..2c08fb5a8f 100644 --- a/src/report/lcov.rs +++ b/src/report/lcov.rs @@ -17,6 +17,9 @@ pub fn export(coverage_data: &TraceMap, config: &Config) -> Result<(), RunError> }; for (path, traces) in coverage_data.iter() { + if traces.is_empty() { + continue; + } writeln!(file, "TN:")?; writeln!(file, "SF:{}", path.to_str().unwrap())?; diff --git a/src/report/mod.rs b/src/report/mod.rs index c26425c270..6fb3373019 100644 --- a/src/report/mod.rs +++ b/src/report/mod.rs @@ -136,8 +136,11 @@ fn print_summary(config: &Config, result: &TraceMap) { }; println!("|| Tested/Total Lines:"); for file in result.files() { + if result.coverable_in_path(&file) == 0 { + continue; + } let path = config.strip_base_dir(file); - if last.contains_file(file) { + if last.contains_file(file) && last.coverable_in_path(&file) > 0 { let last_percent = coverage_percentage(&last.get_child_traces(file)); let current_percent = coverage_percentage(&result.get_child_traces(file)); let delta = 100.0f64 * (current_percent - last_percent); diff --git a/src/source_analysis/macros.rs b/src/source_analysis/macros.rs index 28c0c4baa5..839fd0244f 100644 --- a/src/source_analysis/macros.rs +++ b/src/source_analysis/macros.rs @@ -41,10 +41,14 @@ pub(crate) fn visit_macro_call( arguments: _, }) = mac.path.segments.last() { + let ident_s = ident.to_string(); let unreachable = ident == "unreachable"; let standard_ignores = ident == "unimplemented" || ident == "include" || ident == "cfg" || ident == "todo"; - let ignore_panic = ctx.config.ignore_panics && ident == "panic"; + let ignore_panic = ctx.config.ignore_panics + && (ident == "panic" + || ident_s.starts_with("assert") + || ident_s.starts_with("debug_assert")); if standard_ignores || ignore_panic || unreachable { analysis.ignore_tokens(mac); skip = true; diff --git a/src/source_analysis/tests.rs b/src/source_analysis/tests.rs index c81f32eb39..895bfa04a1 100644 --- a/src/source_analysis/tests.rs +++ b/src/source_analysis/tests.rs @@ -938,6 +938,8 @@ fn optional_panic_ignore() { let ctx = Context { config: &config, file_contents: "fn unreachable_match(x: u32) -> u32 { + assert_eq!(x, 0); + debug_assert!(x != 3419); match x { 1 => 5, 2 => 7, @@ -949,7 +951,9 @@ fn optional_panic_ignore() { }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&Lines::Line(5))); + assert!(!lines.ignore.contains(&Lines::Line(2))); + assert!(!lines.ignore.contains(&Lines::Line(3))); + assert!(!lines.ignore.contains(&Lines::Line(7))); let mut config = Config::default(); config.ignore_panics = true; @@ -957,6 +961,8 @@ fn optional_panic_ignore() { let ctx = Context { config: &config, file_contents: "fn unreachable_match(x: u32) -> u32 { + assert_eq!(x, 0); + debug_assert!(x != 3419); match x { 1 => 5, 2 => 7, @@ -969,7 +975,9 @@ fn optional_panic_ignore() { let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&Lines::Line(5))); + assert!(lines.ignore.contains(&Lines::Line(2))); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(7))); } #[test] diff --git a/src/statemachine/linux.rs b/src/statemachine/linux.rs index 3f4c488027..5a0acf566e 100644 --- a/src/statemachine/linux.rs +++ b/src/statemachine/linux.rs @@ -394,12 +394,7 @@ impl<'a> LinuxData<'a> { } }; if updated.0 { - if let Some(ref mut t) = self.traces.get_trace_mut(rip) { - if let CoverageStat::Line(ref mut x) = t.stats { - trace!("Incrementing hit count for trace"); - *x += 1; - } - } + self.traces.increment_hit(rip); } action = Some(updated.1); } diff --git a/src/test_loader.rs b/src/test_loader.rs index 0c6c182b92..6b708c6659 100644 --- a/src/test_loader.rs +++ b/src/test_loader.rs @@ -317,16 +317,7 @@ fn get_line_addresses( k.line ); } - tracemap.add_trace( - &k.path, - Trace { - line: k.line, - address, - length: 1, - stats: CoverageStat::Line(0), - fn_name, - }, - ); + tracemap.add_trace(&k.path, Trace::new(k.line, address, 1, fn_name)); } result.merge(&tracemap); } @@ -347,16 +338,7 @@ fn get_line_addresses( rpath.display(), line ); - result.add_trace( - file, - Trace { - line, - address: HashSet::new(), - length: 0, - stats: CoverageStat::Line(0), - fn_name: None, - }, - ); + result.add_trace(file, Trace::new_stub(line)); } } } diff --git a/src/traces.rs b/src/traces.rs index 86709e9c24..efd8880f68 100644 --- a/src/traces.rs +++ b/src/traces.rs @@ -1,3 +1,4 @@ +use log::trace; use serde::{Deserialize, Serialize}; use std::cmp::{Ord, Ordering}; use std::collections::btree_map::Iter; @@ -74,6 +75,28 @@ pub struct Trace { pub fn_name: Option, } +impl Trace { + pub fn new(line: u64, address: HashSet, length: usize, fn_name: Option) -> Self { + Self { + line, + address, + length, + stats: CoverageStat::Line(0), + fn_name, + } + } + + pub fn new_stub(line: u64) -> Self { + Self { + line, + address: HashSet::new(), + length: 0, + stats: CoverageStat::Line(0), + fn_name: None, + } + } +} + impl PartialOrd for Trace { fn partial_cmp(&self, other: &Trace) -> Option { // Not sure if I care about the others @@ -242,6 +265,12 @@ impl TraceMap { } } + pub fn add_file(&mut self, file: &Path) { + if !self.traces.contains_key(file) { + self.traces.insert(file.to_path_buf(), vec![]); + } + } + /// Gets an immutable reference to a trace from an address. Returns None if /// there is no trace at that address pub fn get_trace(&self, address: u64) -> Option<&Trace> { @@ -251,6 +280,19 @@ impl TraceMap { .copied() } + pub fn increment_hit(&mut self, address: u64) { + for trace in self + .all_traces_mut() + .iter_mut() + .filter(|x| x.address.contains(&address)) + { + if let CoverageStat::Line(ref mut x) = trace.stats { + trace!("Incrementing hit count for trace"); + *x += 1; + } + } + } + /// Gets a mutable reference to a trace at a given address /// Returns None if there is no trace at that address pub fn get_trace_mut(&mut self, address: u64) -> Option<&mut Trace> { diff --git a/tests/data/doctest_compile_fail_fail/Cargo.lock b/tests/data/doctest_compile_fail_fail/Cargo.lock new file mode 100644 index 0000000000..df85ae58cc --- /dev/null +++ b/tests/data/doctest_compile_fail_fail/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "doctest_compile_fail_fail" +version = "0.1.0" + diff --git a/tests/data/doctest_compile_fail_fail/Cargo.toml b/tests/data/doctest_compile_fail_fail/Cargo.toml new file mode 100644 index 0000000000..6ed8e41287 --- /dev/null +++ b/tests/data/doctest_compile_fail_fail/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "doctest_compile_fail_fail" +version = "0.1.0" +authors = ["xd009642 "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/data/doctest_compile_fail_fail/src/lib.rs b/tests/data/doctest_compile_fail_fail/src/lib.rs new file mode 100644 index 0000000000..8c78b988b4 --- /dev/null +++ b/tests/data/doctest_compile_fail_fail/src/lib.rs @@ -0,0 +1,9 @@ + +/// +///```should_panic +///use doctest_compile_fail_fail::foo; +///foo(); +///``` +pub fn foo() { + +} diff --git a/tests/data/doctest_workspace_should_panic/.gitignore b/tests/data/doctest_workspace_should_panic/.gitignore new file mode 100644 index 0000000000..96ef6c0b94 --- /dev/null +++ b/tests/data/doctest_workspace_should_panic/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/tests/data/doctest_workspace_should_panic/Cargo.toml b/tests/data/doctest_workspace_should_panic/Cargo.toml new file mode 100644 index 0000000000..edf39faa52 --- /dev/null +++ b/tests/data/doctest_workspace_should_panic/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +members = [ + "foo", + "bar" +] diff --git a/tests/data/doctest_workspace_should_panic/bar/Cargo.toml b/tests/data/doctest_workspace_should_panic/bar/Cargo.toml new file mode 100644 index 0000000000..86c1de4b5a --- /dev/null +++ b/tests/data/doctest_workspace_should_panic/bar/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "bar" +version = "0.1.0" +authors = ["xd009642 "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/data/doctest_workspace_should_panic/bar/src/lib.rs b/tests/data/doctest_workspace_should_panic/bar/src/lib.rs new file mode 100644 index 0000000000..e42766ddba --- /dev/null +++ b/tests/data/doctest_workspace_should_panic/bar/src/lib.rs @@ -0,0 +1,16 @@ + +/// ``` +/// use bar::foo2; +/// foo2(); +/// ``` +pub fn foo2() { +} + + +/// ```should_panic +/// use bar::bar2; +/// bar2(); +/// ``` +pub fn bar2() { + panic!() +} diff --git a/tests/data/doctest_workspace_should_panic/foo/Cargo.toml b/tests/data/doctest_workspace_should_panic/foo/Cargo.toml new file mode 100644 index 0000000000..587d881182 --- /dev/null +++ b/tests/data/doctest_workspace_should_panic/foo/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "foo" +version = "0.1.0" +authors = ["xd009642 "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/data/doctest_workspace_should_panic/foo/src/lib.rs b/tests/data/doctest_workspace_should_panic/foo/src/lib.rs new file mode 100644 index 0000000000..28e67cb973 --- /dev/null +++ b/tests/data/doctest_workspace_should_panic/foo/src/lib.rs @@ -0,0 +1,15 @@ +/// ``` +/// use foo::foo1; +/// foo1(); +/// ``` +pub fn foo1() { +} + + +/// ```should_panic +/// use foo::bar1; +/// bar1(); +/// ``` +pub fn bar1() { + panic!() +} diff --git a/tests/doc_coverage.rs b/tests/doc_coverage.rs index 2b7975b392..885a1f1bc8 100644 --- a/tests/doc_coverage.rs +++ b/tests/doc_coverage.rs @@ -55,3 +55,44 @@ fn doc_test_panics() { assert_eq!(ret, 0); assert_eq!(res.total_covered(), 0); } + +#[test] +fn doc_test_panics_workspace() { + let mut config = Config::default(); + config.verbose = true; + config.test_timeout = Duration::from_secs(60); + let test_dir = get_test_path("doctest_workspace_should_panic"); + env::set_current_dir(&test_dir).unwrap(); + config.manifest = test_dir; + config.manifest.push("Cargo.toml"); + + config.run_types = vec![RunType::Doctests]; + + let (res, ret) = launch_tarpaulin(&config, &None).unwrap(); + + assert_eq!(ret, 0); + assert!(res.total_covered() > 0); + assert_eq!(res.total_covered(), res.total_coverable()); + + config.run_types = vec![RunType::Tests]; + + let (res, ret) = launch_tarpaulin(&config, &None).unwrap(); + + assert_eq!(ret, 0); + assert_eq!(res.total_covered(), 0); +} + +#[test] +fn doc_test_compile_fail() { + let mut config = Config::default(); + config.verbose = true; + config.test_timeout = Duration::from_secs(60); + let test_dir = get_test_path("doctest_compile_fail_fail"); + env::set_current_dir(&test_dir).unwrap(); + config.manifest = test_dir; + config.manifest.push("Cargo.toml"); + + config.run_types = vec![RunType::Doctests]; + + assert!(launch_tarpaulin(&config, &None).is_err()); +} diff --git a/travis-install.sh b/travis-install.sh index f6d7cfc2c0..ebd15b3dfe 100755 --- a/travis-install.sh +++ b/travis-install.sh @@ -1,2 +1,2 @@ #!/bin/bash -curl -sL https://github.com/xd009642/tarpaulin/releases/download/0.14.1/cargo-tarpaulin-0.14.1-travis.tar.gz | tar xvz -C $HOME/.cargo/bin +curl -sL https://github.com/xd009642/tarpaulin/releases/download/0.14.2/cargo-tarpaulin-0.14.2-travis.tar.gz | tar xvz -C $HOME/.cargo/bin