diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index e8ff8930bdd7d..e70030912db0e 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -35,6 +35,7 @@ use std::fmt::{self, Write};
use std::slice;
use std::str;
use syntax::feature_gate::UnstableFeatures;
+use syntax::codemap::Span;
use html::render::derive_id;
use html::toc::TocBuilder;
@@ -429,7 +430,7 @@ pub fn render(w: &mut fmt::Formatter,
}
}
-pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line: usize) {
+pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) {
extern fn block(_ob: *mut hoedown_buffer,
text: *const hoedown_buffer,
lang: *const hoedown_buffer,
@@ -454,11 +455,12 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line:
});
let text = lines.collect::>().join("\n");
let line = tests.get_line() + line;
+ let filename = tests.get_filename();
tests.add_test(text.to_owned(),
block_info.should_panic, block_info.no_run,
block_info.ignore, block_info.test_harness,
block_info.compile_fail, block_info.error_codes,
- line);
+ line, filename);
}
}
@@ -479,7 +481,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line:
}
}
- tests.set_line(start_line);
+ tests.set_position(position);
unsafe {
let ob = hoedown_buffer_new(DEF_OUNIT);
let renderer = hoedown_html_renderer_new(0, 0);
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 49497957be980..70ef7c597e4d7 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -18,6 +18,7 @@ use getopts;
use testing;
use rustc::session::search_paths::SearchPaths;
use rustc::session::config::Externs;
+use syntax::codemap::DUMMY_SP;
use externalfiles::{ExternalHtml, LoadStringError, load_string};
@@ -154,9 +155,8 @@ pub fn test(input: &str, cfgs: Vec, libs: SearchPaths, externs: Externs,
let mut opts = TestOptions::default();
opts.no_crate_inject = true;
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
- true, opts, maybe_sysroot, "input".to_string(),
- None);
- find_testable_code(&input_str, &mut collector, 0);
+ true, opts, maybe_sysroot, None);
+ find_testable_code(&input_str, &mut collector, DUMMY_SP);
test_args.insert(0, "rustdoctest".to_string());
testing::test_main(&test_args, collector.tests);
0
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 6f38da4f24b0d..930cf401e7450 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -37,7 +37,7 @@ use rustc_trans::back::link;
use syntax::ast;
use syntax::codemap::CodeMap;
use syntax::feature_gate::UnstableFeatures;
-use syntax_pos::{BytePos, DUMMY_SP, Pos};
+use syntax_pos::{BytePos, DUMMY_SP, Pos, Span};
use errors;
use errors::emitter::ColorConfig;
@@ -97,7 +97,6 @@ pub fn run(input: &str,
link::find_crate_name(None, &hir_forest.krate().attrs, &input)
});
let opts = scrape_test_config(hir_forest.krate());
- let filename = input_path.to_str().unwrap_or("").to_owned();
let mut collector = Collector::new(crate_name,
cfgs,
libs,
@@ -105,7 +104,6 @@ pub fn run(input: &str,
false,
opts,
maybe_sysroot,
- filename,
Some(codemap));
{
@@ -391,15 +389,14 @@ pub struct Collector {
cratename: String,
opts: TestOptions,
maybe_sysroot: Option,
- filename: String,
- start_line: usize,
+ position: Span,
codemap: Option>,
}
impl Collector {
pub fn new(cratename: String, cfgs: Vec, libs: SearchPaths, externs: Externs,
use_headers: bool, opts: TestOptions, maybe_sysroot: Option,
- filename: String, codemap: Option>) -> Collector {
+ codemap: Option>) -> Collector {
Collector {
tests: Vec::new(),
names: Vec::new(),
@@ -412,8 +409,7 @@ impl Collector {
cratename: cratename,
opts: opts,
maybe_sysroot: maybe_sysroot,
- filename: filename,
- start_line: 0,
+ position: DUMMY_SP,
codemap: codemap,
}
}
@@ -421,8 +417,8 @@ impl Collector {
pub fn add_test(&mut self, test: String,
should_panic: bool, no_run: bool, should_ignore: bool,
as_test_harness: bool, compile_fail: bool, error_codes: Vec,
- line: usize) {
- let name = format!("{} - line {}", self.filename, line);
+ line: usize, filename: String) {
+ let name = format!("{} - line {}", filename, line);
self.cnt += 1;
let cfgs = self.cfgs.clone();
let libs = self.libs.clone();
@@ -467,16 +463,25 @@ impl Collector {
}
pub fn get_line(&self) -> usize {
- if let Some(ref codemap) = self.codemap{
- let line = codemap.lookup_char_pos(BytePos(self.start_line as u32)).line;
+ if let Some(ref codemap) = self.codemap {
+ let line = self.position.lo.to_usize();
+ let line = codemap.lookup_char_pos(BytePos(line as u32)).line;
if line > 0 { line - 1 } else { line }
} else {
- self.start_line
+ 0
}
}
- pub fn set_line(&mut self, start_line: usize) {
- self.start_line = start_line;
+ pub fn set_position(&mut self, position: Span) {
+ self.position = position;
+ }
+
+ pub fn get_filename(&self) -> String {
+ if let Some(ref codemap) = self.codemap {
+ codemap.span_to_filename(self.position)
+ } else {
+ "".to_owned()
+ }
}
pub fn register_header(&mut self, name: &str, level: u32) {
@@ -520,7 +525,7 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
if let Some(doc) = attrs.doc_value() {
self.collector.cnt = 0;
markdown::find_testable_code(doc, self.collector,
- attrs.span.unwrap_or(DUMMY_SP).lo.to_usize());
+ attrs.span.unwrap_or(DUMMY_SP));
}
nested(self);
diff --git a/src/test/rustdoc/test_option_check/bar.rs b/src/test/rustdoc/test_option_check/bar.rs
new file mode 100644
index 0000000000000..51daa80752622
--- /dev/null
+++ b/src/test/rustdoc/test_option_check/bar.rs
@@ -0,0 +1,19 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --test
+// check-test-line-numbers-match
+
+/// This looks like another awesome test!
+///
+/// ```
+/// println!("foo?");
+/// ```
+pub fn foooo() {}
diff --git a/src/test/rustdoc/test_option_check/test.rs b/src/test/rustdoc/test_option_check/test.rs
index b2afe43204d41..a9578c5f434a2 100644
--- a/src/test/rustdoc/test_option_check/test.rs
+++ b/src/test/rustdoc/test_option_check/test.rs
@@ -11,6 +11,8 @@
// compile-flags: --test
// check-test-line-numbers-match
+pub mod bar;
+
/// This is a Foo;
///
/// ```
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index a8c46722e163b..4e527661df72e 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -30,6 +30,7 @@ use std::io::{self, BufReader};
use std::path::{Path, PathBuf};
use std::process::{Command, Output, ExitStatus};
use std::str;
+use std::collections::HashMap;
use extract_gdb_version;
@@ -1902,17 +1903,28 @@ actual:\n\
}
}
- fn check_rustdoc_test_option(&self, res: ProcRes) {
- let mut file = fs::File::open(&self.testpaths.file)
+ fn get_lines>(&self, path: &P,
+ mut other_files: Option<&mut Vec>) -> Vec {
+ let mut file = fs::File::open(path)
.expect("markdown_test_output_check_entry File::open failed");
let mut content = String::new();
file.read_to_string(&mut content)
.expect("markdown_test_output_check_entry read_to_string failed");
let mut ignore = false;
- let mut v: Vec =
- content.lines()
- .enumerate()
- .filter_map(|(line_nb, line)| {
+ content.lines()
+ .enumerate()
+ .filter_map(|(line_nb, line)| {
+ if (line.trim_left().starts_with("pub mod ") ||
+ line.trim_left().starts_with("mod ")) &&
+ line.ends_with(";") {
+ if let Some(ref mut other_files) = other_files {
+ other_files.push(line.rsplit("mod ")
+ .next()
+ .unwrap()
+ .replace(";", ""));
+ }
+ None
+ } else {
let sline = line.split("///").last().unwrap_or("");
let line = sline.trim_left();
if line.starts_with("```") {
@@ -1926,8 +1938,21 @@ actual:\n\
} else {
None
}
- })
- .collect();
+ }
+ })
+ .collect()
+ }
+
+ fn check_rustdoc_test_option(&self, res: ProcRes) {
+ let mut other_files = Vec::new();
+ let mut files: HashMap> = HashMap::new();
+ files.insert(self.testpaths.file.to_str().unwrap().to_owned(),
+ self.get_lines(&self.testpaths.file, Some(&mut other_files)));
+ for other_file in other_files {
+ let mut path = self.testpaths.file.clone();
+ path.set_file_name(&format!("{}.rs", other_file));
+ files.insert(path.to_str().unwrap().to_owned(), self.get_lines(&path, None));
+ }
let mut tested = 0;
for _ in res.stdout.split("\n")
@@ -1935,27 +1960,35 @@ actual:\n\
.inspect(|s| {
let tmp: Vec<&str> = s.split(" - line ").collect();
if tmp.len() == 2 {
- tested += 1;
- let line = tmp[1].split(" ...")
- .next()
- .unwrap_or("0")
- .parse()
- .unwrap_or(0);
- if let Ok(pos) = v.binary_search(&line) {
- v.remove(pos);
- } else {
- self.fatal_proc_rec(
- &format!("Not found doc test: \"{}\" in {:?}", s, v),
- &res);
+ let path = tmp[0].rsplit("test ").next().unwrap();
+ if let Some(ref mut v) = files.get_mut(path) {
+ tested += 1;
+ let line = tmp[1].split(" ...")
+ .next()
+ .unwrap_or("0")
+ .parse()
+ .unwrap_or(0);
+ if let Ok(pos) = v.binary_search(&line) {
+ v.remove(pos);
+ } else {
+ self.fatal_proc_rec(
+ &format!("Not found doc test: \"{}\" in \"{}\":{:?}",
+ s, path, v),
+ &res);
+ }
}
}
}) {}
if tested == 0 {
- self.fatal_proc_rec("No test has been found", &res);
- } else if v.len() != 0 {
- self.fatal_proc_rec(&format!("Not found test at line{} {:?}",
- if v.len() > 1 { "s" } else { "" }, v),
- &res);
+ self.fatal_proc_rec(&format!("No test has been found... {:?}", files), &res);
+ } else {
+ for (entry, v) in &files {
+ if v.len() != 0 {
+ self.fatal_proc_rec(&format!("Not found test at line{} \"{}\":{:?}",
+ if v.len() > 1 { "s" } else { "" }, entry, v),
+ &res);
+ }
+ }
}
}