Add line number and filename in error message
This commit is contained in:
parent
230234f3a8
commit
902460d218
2 changed files with 55 additions and 6 deletions
|
@ -154,7 +154,7 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
||||||
let mut opts = TestOptions::default();
|
let mut opts = TestOptions::default();
|
||||||
opts.no_crate_inject = true;
|
opts.no_crate_inject = true;
|
||||||
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
|
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
|
||||||
true, opts, maybe_sysroot);
|
true, opts, maybe_sysroot, &input_str, "input".to_string());
|
||||||
find_testable_code(&input_str, &mut collector);
|
find_testable_code(&input_str, &mut collector);
|
||||||
test_args.insert(0, "rustdoctest".to_string());
|
test_args.insert(0, "rustdoctest".to_string());
|
||||||
testing::test_main(&test_args, collector.tests);
|
testing::test_main(&test_args, collector.tests);
|
||||||
|
|
|
@ -8,8 +8,10 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -96,13 +98,24 @@ pub fn run(input: &str,
|
||||||
link::find_crate_name(None, &hir_forest.krate().attrs, &input)
|
link::find_crate_name(None, &hir_forest.krate().attrs, &input)
|
||||||
});
|
});
|
||||||
let opts = scrape_test_config(hir_forest.krate());
|
let opts = scrape_test_config(hir_forest.krate());
|
||||||
|
let filename = input_path.to_str().unwrap_or("").to_owned();
|
||||||
|
let mut f = match File::open(input_path) {
|
||||||
|
Ok(f) => f,
|
||||||
|
_ => return 1,
|
||||||
|
};
|
||||||
|
let mut file_content = String::new();
|
||||||
|
if let Err(_) = f.read_to_string(&mut file_content) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
let mut collector = Collector::new(crate_name,
|
let mut collector = Collector::new(crate_name,
|
||||||
cfgs,
|
cfgs,
|
||||||
libs,
|
libs,
|
||||||
externs,
|
externs,
|
||||||
false,
|
false,
|
||||||
opts,
|
opts,
|
||||||
maybe_sysroot);
|
maybe_sysroot,
|
||||||
|
&file_content,
|
||||||
|
filename);
|
||||||
|
|
||||||
{
|
{
|
||||||
let dep_graph = DepGraph::new(false);
|
let dep_graph = DepGraph::new(false);
|
||||||
|
@ -162,11 +175,12 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
|
||||||
should_panic: bool, no_run: bool, as_test_harness: bool,
|
should_panic: bool, no_run: bool, as_test_harness: bool,
|
||||||
compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
|
compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
|
||||||
maybe_sysroot: Option<PathBuf>,
|
maybe_sysroot: Option<PathBuf>,
|
||||||
original: &str) {
|
original: &str, line_number: u32, filename: &str) {
|
||||||
// the test harness wants its own `main` & top level functions, so
|
// the test harness wants its own `main` & top level functions, so
|
||||||
// never wrap the test in `fn main() { ... }`
|
// never wrap the test in `fn main() { ... }`
|
||||||
let new_test = maketest(test, Some(cratename), as_test_harness, opts);
|
let new_test = maketest(test, Some(cratename), as_test_harness, opts);
|
||||||
let test = format!("```{}\n{}\n```\n", original, test);
|
let test = format!("Error on {}:{}\n\n```{}\n{}\n```\n",
|
||||||
|
filename, line_number, original, test);
|
||||||
let input = config::Input::Str {
|
let input = config::Input::Str {
|
||||||
name: driver::anon_src(),
|
name: driver::anon_src(),
|
||||||
input: new_test.to_owned(),
|
input: new_test.to_owned(),
|
||||||
|
@ -389,11 +403,27 @@ pub struct Collector {
|
||||||
cratename: String,
|
cratename: String,
|
||||||
opts: TestOptions,
|
opts: TestOptions,
|
||||||
maybe_sysroot: Option<PathBuf>,
|
maybe_sysroot: Option<PathBuf>,
|
||||||
|
code_blocks: HashMap<String, Vec<u32>>,
|
||||||
|
filename: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Collector {
|
impl Collector {
|
||||||
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
||||||
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>) -> Collector {
|
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
|
||||||
|
file_content: &str, filename: String) -> Collector {
|
||||||
|
let mut line_number = 1;
|
||||||
|
let mut block_lines = HashMap::new();
|
||||||
|
for (pos, block) in file_content.split("```").enumerate() {
|
||||||
|
if (pos & 1) != 0 {
|
||||||
|
let key = format!("{}", block.replace("/// ", "").replace("//!", ""));
|
||||||
|
if !block_lines.contains_key(&key) {
|
||||||
|
block_lines.insert(key.clone(), Vec::new());
|
||||||
|
}
|
||||||
|
block_lines.get_mut(&key).unwrap().push(line_number);
|
||||||
|
}
|
||||||
|
line_number += block.lines().count() as u32 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
Collector {
|
Collector {
|
||||||
tests: Vec::new(),
|
tests: Vec::new(),
|
||||||
names: Vec::new(),
|
names: Vec::new(),
|
||||||
|
@ -406,9 +436,24 @@ impl Collector {
|
||||||
cratename: cratename,
|
cratename: cratename,
|
||||||
opts: opts,
|
opts: opts,
|
||||||
maybe_sysroot: maybe_sysroot,
|
maybe_sysroot: maybe_sysroot,
|
||||||
|
code_blocks: block_lines,
|
||||||
|
filename: filename,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_line_from_key(&mut self, key: &String) -> u32 {
|
||||||
|
let (line, need_removal) = if let Some(l) = self.code_blocks.get_mut(key) {
|
||||||
|
let need_removal = l.len() > 1;
|
||||||
|
(l.pop().unwrap_or(1), need_removal)
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
if need_removal {
|
||||||
|
self.code_blocks.remove(key);
|
||||||
|
}
|
||||||
|
line
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_test(&mut self, test: String,
|
pub fn add_test(&mut self, test: String,
|
||||||
should_panic: bool, no_run: bool, should_ignore: bool,
|
should_panic: bool, no_run: bool, should_ignore: bool,
|
||||||
as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
|
as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
|
||||||
|
@ -427,6 +472,8 @@ impl Collector {
|
||||||
let opts = self.opts.clone();
|
let opts = self.opts.clone();
|
||||||
let maybe_sysroot = self.maybe_sysroot.clone();
|
let maybe_sysroot = self.maybe_sysroot.clone();
|
||||||
debug!("Creating test {}: {}", name, test);
|
debug!("Creating test {}: {}", name, test);
|
||||||
|
let line_number = self.get_line_from_key(&format!("{}\n{}\n", original, test));
|
||||||
|
let filename = self.filename.clone();
|
||||||
self.tests.push(testing::TestDescAndFn {
|
self.tests.push(testing::TestDescAndFn {
|
||||||
desc: testing::TestDesc {
|
desc: testing::TestDesc {
|
||||||
name: testing::DynTestName(name),
|
name: testing::DynTestName(name),
|
||||||
|
@ -453,7 +500,9 @@ impl Collector {
|
||||||
error_codes,
|
error_codes,
|
||||||
&opts,
|
&opts,
|
||||||
maybe_sysroot,
|
maybe_sysroot,
|
||||||
&original)
|
&original,
|
||||||
|
line_number,
|
||||||
|
&filename)
|
||||||
})
|
})
|
||||||
} {
|
} {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue