Skip to content

Commit

Permalink
Auto merge of #36320 - GuillaumeGomez:rustdoc_test_info, r=alexcrichton
Browse files Browse the repository at this point in the history
Add information in case of markdown block code test failure

r? @steveklabnik

cc @jonathandturner
  • Loading branch information
bors committed Feb 4, 2017
2 parents 0648517 + b7f1d7a commit c781fc4
Show file tree
Hide file tree
Showing 15 changed files with 207 additions and 57 deletions.
1 change: 1 addition & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
[submodule "src/rt/hoedown"]
path = src/rt/hoedown
url = https://github.com/rust-lang/hoedown.git
branch = rust-2015-09-21-do-not-delete
[submodule "src/jemalloc"]
path = src/jemalloc
url = https://github.com/rust-lang/jemalloc.git
Expand Down
10 changes: 8 additions & 2 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,17 +521,22 @@ impl<'a, I: IntoIterator<Item=&'a ast::NestedMetaItem>> NestedAttributesExt for
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug, Default)]
pub struct Attributes {
pub doc_strings: Vec<String>,
pub other_attrs: Vec<ast::Attribute>
pub other_attrs: Vec<ast::Attribute>,
pub span: Option<syntax_pos::Span>,
}

impl Attributes {
pub fn from_ast(attrs: &[ast::Attribute]) -> Attributes {
let mut doc_strings = vec![];
let mut sp = None;
let other_attrs = attrs.iter().filter_map(|attr| {
attr.with_desugared_doc(|attr| {
if let Some(value) = attr.value_str() {
if attr.check_name("doc") {
doc_strings.push(value.to_string());
if sp.is_none() {
sp = Some(attr.span);
}
return None;
}
}
Expand All @@ -541,7 +546,8 @@ impl Attributes {
}).collect();
Attributes {
doc_strings: doc_strings,
other_attrs: other_attrs
other_attrs: other_attrs,
span: sp,
}
}

Expand Down
56 changes: 37 additions & 19 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,29 +71,31 @@ const HOEDOWN_EXTENSIONS: libc::c_uint =
enum hoedown_document {}

type blockcodefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
*const hoedown_buffer, *const hoedown_renderer_data);
*const hoedown_buffer, *const hoedown_renderer_data,
libc::size_t);

type blockquotefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
*const hoedown_renderer_data);
*const hoedown_renderer_data, libc::size_t);

type headerfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
libc::c_int, *const hoedown_renderer_data);
libc::c_int, *const hoedown_renderer_data,
libc::size_t);

type blockhtmlfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
*const hoedown_renderer_data);
*const hoedown_renderer_data, libc::size_t);

type codespanfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
*const hoedown_renderer_data) -> libc::c_int;
*const hoedown_renderer_data, libc::size_t) -> libc::c_int;

type linkfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
*const hoedown_buffer, *const hoedown_buffer,
*const hoedown_renderer_data) -> libc::c_int;
*const hoedown_renderer_data, libc::size_t) -> libc::c_int;

type entityfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
*const hoedown_renderer_data);
*const hoedown_renderer_data, libc::size_t);

type normaltextfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
*const hoedown_renderer_data);
*const hoedown_renderer_data, libc::size_t);

#[repr(C)]
struct hoedown_renderer_data {
Expand Down Expand Up @@ -147,7 +149,8 @@ struct html_toc_data {

struct MyOpaque {
dfltblk: extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
*const hoedown_buffer, *const hoedown_renderer_data),
*const hoedown_buffer, *const hoedown_renderer_data,
libc::size_t),
toc_builder: Option<TocBuilder>,
}

Expand Down Expand Up @@ -229,7 +232,8 @@ pub fn render(w: &mut fmt::Formatter,
print_toc: bool,
html_flags: libc::c_uint) -> fmt::Result {
extern fn block(ob: *mut hoedown_buffer, orig_text: *const hoedown_buffer,
lang: *const hoedown_buffer, data: *const hoedown_renderer_data) {
lang: *const hoedown_buffer, data: *const hoedown_renderer_data,
line: libc::size_t) {
unsafe {
if orig_text.is_null() { return }

Expand All @@ -246,7 +250,8 @@ pub fn render(w: &mut fmt::Formatter,
let rlang = str::from_utf8(rlang).unwrap();
if !LangString::parse(rlang).rust {
(my_opaque.dfltblk)(ob, orig_text, lang,
opaque as *const hoedown_renderer_data);
opaque as *const hoedown_renderer_data,
line);
true
} else {
false
Expand Down Expand Up @@ -312,7 +317,8 @@ pub fn render(w: &mut fmt::Formatter,
}

extern fn header(ob: *mut hoedown_buffer, text: *const hoedown_buffer,
level: libc::c_int, data: *const hoedown_renderer_data) {
level: libc::c_int, data: *const hoedown_renderer_data,
_: libc::size_t) {
// hoedown does this, we may as well too
unsafe { hoedown_buffer_puts(ob, "\n\0".as_ptr() as *const _); }

Expand Down Expand Up @@ -373,6 +379,7 @@ pub fn render(w: &mut fmt::Formatter,
ob: *mut hoedown_buffer,
text: *const hoedown_buffer,
_: *const hoedown_renderer_data,
_: libc::size_t
) -> libc::c_int {
let content = if text.is_null() {
"".to_owned()
Expand Down Expand Up @@ -422,11 +429,12 @@ pub fn render(w: &mut fmt::Formatter,
}
}

pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line: usize) {
extern fn block(_ob: *mut hoedown_buffer,
text: *const hoedown_buffer,
lang: *const hoedown_buffer,
data: *const hoedown_renderer_data) {
data: *const hoedown_renderer_data,
line: libc::size_t) {
unsafe {
if text.is_null() { return }
let block_info = if lang.is_null() {
Expand All @@ -445,16 +453,19 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
stripped_filtered_line(l).unwrap_or(l)
});
let text = lines.collect::<Vec<&str>>().join("\n");
let line = tests.get_line() + line;
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);
block_info.compile_fail, block_info.error_codes,
line);
}
}

extern fn header(_ob: *mut hoedown_buffer,
text: *const hoedown_buffer,
level: libc::c_int, data: *const hoedown_renderer_data) {
level: libc::c_int, data: *const hoedown_renderer_data,
_: libc::size_t) {
unsafe {
let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
Expand All @@ -468,6 +479,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
}
}

tests.set_line(start_line);
unsafe {
let ob = hoedown_buffer_new(DEF_OUNIT);
let renderer = hoedown_html_renderer_new(0, 0);
Expand All @@ -488,6 +500,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {

#[derive(Eq, PartialEq, Clone, Debug)]
struct LangString {
original: String,
should_panic: bool,
no_run: bool,
ignore: bool,
Expand All @@ -500,6 +513,7 @@ struct LangString {
impl LangString {
fn all_false() -> LangString {
LangString {
original: String::new(),
should_panic: false,
no_run: false,
ignore: false,
Expand All @@ -521,6 +535,7 @@ impl LangString {
allow_error_code_check = true;
}

data.original = string.to_owned();
let tokens = string.split(|c: char|
!(c == '_' || c == '-' || c.is_alphanumeric())
);
Expand Down Expand Up @@ -586,7 +601,8 @@ pub fn plain_summary_line(md: &str) -> String {
_link: *const hoedown_buffer,
_title: *const hoedown_buffer,
content: *const hoedown_buffer,
data: *const hoedown_renderer_data) -> libc::c_int
data: *const hoedown_renderer_data,
_: libc::size_t) -> libc::c_int
{
unsafe {
if !content.is_null() && (*content).size > 0 {
Expand All @@ -599,8 +615,9 @@ pub fn plain_summary_line(md: &str) -> String {
}

extern fn normal_text(_ob: *mut hoedown_buffer,
text: *const hoedown_buffer,
data: *const hoedown_renderer_data)
text: *const hoedown_buffer,
data: *const hoedown_renderer_data,
_: libc::size_t)
{
unsafe {
let ob = (*data).opaque as *mut hoedown_buffer;
Expand Down Expand Up @@ -647,6 +664,7 @@ mod tests {
test_harness: test_harness,
compile_fail: compile_fail,
error_codes: error_codes,
original: s.to_owned(),
})
}

Expand Down
5 changes: 3 additions & 2 deletions src/librustdoc/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,9 @@ pub fn test(input: &str, cfgs: Vec<String>, 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);
find_testable_code(&input_str, &mut collector);
true, opts, maybe_sysroot, "input".to_string(),
None);
find_testable_code(&input_str, &mut collector, 0);
test_args.insert(0, "rustdoctest".to_string());
testing::test_main(&test_args, collector.tests);
0
Expand Down
49 changes: 36 additions & 13 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +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 errors;
use errors::emitter::ColorConfig;

Expand Down Expand Up @@ -79,7 +80,7 @@ pub fn run(input: &str,
let _ignore = dep_graph.in_ignore();
let cstore = Rc::new(CStore::new(&dep_graph));
let mut sess = session::build_session_(
sessopts, &dep_graph, Some(input_path.clone()), handler, codemap, cstore.clone(),
sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone(), cstore.clone(),
);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
sess.parse_sess.config =
Expand All @@ -96,13 +97,16 @@ 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,
externs,
false,
opts,
maybe_sysroot);
maybe_sysroot,
filename,
Some(codemap));

{
let dep_graph = DepGraph::new(false);
Expand Down Expand Up @@ -256,7 +260,9 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
error_codes.retain(|err| !out.contains(err));
}
}
Ok(()) if compile_fail => panic!("test compiled while it wasn't supposed to"),
Ok(()) if compile_fail => {
panic!("test compiled while it wasn't supposed to")
}
_ => {}
}
}
Expand Down Expand Up @@ -302,7 +308,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
if should_panic && out.status.success() {
panic!("test executable succeeded when it should have failed");
} else if !should_panic && !out.status.success() {
panic!("test executable failed:\n{}\n{}",
panic!("test executable failed:\n{}\n{}\n",
str::from_utf8(&out.stdout).unwrap_or(""),
str::from_utf8(&out.stderr).unwrap_or(""));
}
Expand Down Expand Up @@ -384,11 +390,15 @@ pub struct Collector {
cratename: String,
opts: TestOptions,
maybe_sysroot: Option<PathBuf>,
filename: String,
start_line: usize,
codemap: Option<Rc<CodeMap>>,
}

impl Collector {
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>,
filename: String, codemap: Option<Rc<CodeMap>>) -> Collector {
Collector {
tests: Vec::new(),
names: Vec::new(),
Expand All @@ -401,18 +411,17 @@ impl Collector {
cratename: cratename,
opts: opts,
maybe_sysroot: maybe_sysroot,
filename: filename,
start_line: 0,
codemap: codemap,
}
}

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<String>) {
let name = if self.use_headers {
let s = self.current_header.as_ref().map(|s| &**s).unwrap_or("");
format!("{}_{}", s, self.cnt)
} else {
format!("{}_{}", self.names.join("::"), self.cnt)
};
as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
line: usize) {
let name = format!("{} - line {}", self.filename, line);
self.cnt += 1;
let cfgs = self.cfgs.clone();
let libs = self.libs.clone();
Expand Down Expand Up @@ -456,6 +465,19 @@ 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 line > 0 { line - 1 } else { line }
} else {
self.start_line
}
}

pub fn set_line(&mut self, start_line: usize) {
self.start_line = start_line;
}

pub fn register_header(&mut self, name: &str, level: u32) {
if self.use_headers && level == 1 {
// we use these headings as test names, so it's good if
Expand Down Expand Up @@ -496,7 +518,8 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
attrs.unindent_doc_comments();
if let Some(doc) = attrs.doc_value() {
self.collector.cnt = 0;
markdown::find_testable_code(doc, self.collector);
markdown::find_testable_code(doc, self.collector,
attrs.span.unwrap_or(DUMMY_SP).lo.to_usize());
}

nested(self);
Expand Down
Loading

0 comments on commit c781fc4

Please sign in to comment.