Skip to content

Commit

Permalink
Merge #4320
Browse files Browse the repository at this point in the history
4320: add doctest support r=matklad a=bnjjj

close #4317

preview:

<img width="253" alt="Capture d’écran 2020-05-05 à 17 39 58" src="https://user-images.githubusercontent.com/5719034/81086040-45110b80-8ef8-11ea-9c05-79c6fe400fc3.png">


Co-authored-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
  • Loading branch information
bors[bot] and bnjjj authored May 5, 2020
2 parents 58f6431 + fe52f8f commit f0411ff
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 6 deletions.
43 changes: 43 additions & 0 deletions crates/ra_ide/src/runnables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use ra_syntax::{
};

use crate::FileId;
use ast::DocCommentsOwner;
use std::fmt::Display;

#[derive(Debug)]
Expand Down Expand Up @@ -37,6 +38,7 @@ pub enum RunnableKind {
Test { test_id: TestId, attr: TestAttr },
TestMod { path: String },
Bench { test_id: TestId },
DocTest { test_id: TestId },
Bin,
}

Expand Down Expand Up @@ -81,6 +83,8 @@ fn runnable_fn(sema: &Semantics<RootDatabase>, fn_def: ast::FnDef) -> Option<Run
RunnableKind::Test { test_id, attr }
} else if fn_def.has_atom_attr("bench") {
RunnableKind::Bench { test_id }
} else if has_doc_test(&fn_def) {
RunnableKind::DocTest { test_id }
} else {
return None;
}
Expand Down Expand Up @@ -117,6 +121,10 @@ fn has_test_related_attribute(fn_def: &ast::FnDef) -> bool {
.any(|attribute_text| attribute_text.contains("test"))
}

fn has_doc_test(fn_def: &ast::FnDef) -> bool {
fn_def.doc_comment_text().map_or(false, |comment| comment.contains("```"))
}

fn runnable_mod(sema: &Semantics<RootDatabase>, module: ast::Module) -> Option<Runnable> {
let has_test_function = module
.item_list()?
Expand Down Expand Up @@ -194,6 +202,41 @@ mod tests {
);
}

#[test]
fn test_runnables_doc_test() {
let (analysis, pos) = analysis_and_position(
r#"
//- /lib.rs
<|> //empty
fn main() {}
/// ```
/// let x = 5;
/// ```
fn foo() {}
"#,
);
let runnables = analysis.runnables(pos.file_id).unwrap();
assert_debug_snapshot!(&runnables,
@r###"
[
Runnable {
range: 1..21,
kind: Bin,
},
Runnable {
range: 22..64,
kind: DocTest {
test_id: Path(
"foo",
),
},
},
]
"###
);
}

#[test]
fn test_runnables_module() {
let (analysis, pos) = analysis_and_position(
Expand Down
26 changes: 20 additions & 6 deletions crates/rust-analyzer/src/cargo_target_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,40 +27,49 @@ impl CargoTargetSpec {
RunnableKind::Test { test_id, attr } => {
args.push("test".to_string());
if let Some(spec) = spec {
spec.push_to(&mut args);
spec.push_to(&mut args, kind);
}
extra_args.push(test_id.to_string());
if let TestId::Path(_) = test_id {
extra_args.push("--exact".to_string());
}
extra_args.push("--nocapture".to_string());
if attr.ignore {
extra_args.push("--ignored".to_string())
extra_args.push("--ignored".to_string());
}
}
RunnableKind::TestMod { path } => {
args.push("test".to_string());
if let Some(spec) = spec {
spec.push_to(&mut args);
spec.push_to(&mut args, kind);
}
extra_args.push(path.to_string());
extra_args.push("--nocapture".to_string());
}
RunnableKind::Bench { test_id } => {
args.push("bench".to_string());
if let Some(spec) = spec {
spec.push_to(&mut args);
spec.push_to(&mut args, kind);
}
extra_args.push(test_id.to_string());
if let TestId::Path(_) = test_id {
extra_args.push("--exact".to_string());
}
extra_args.push("--nocapture".to_string());
}
RunnableKind::DocTest { test_id } => {
args.push("test".to_string());
args.push("--doc".to_string());
if let Some(spec) = spec {
spec.push_to(&mut args, kind);
}
extra_args.push(test_id.to_string());
extra_args.push("--nocapture".to_string());
}
RunnableKind::Bin => {
args.push("run".to_string());
if let Some(spec) = spec {
spec.push_to(&mut args);
spec.push_to(&mut args, kind);
}
}
}
Expand Down Expand Up @@ -91,9 +100,14 @@ impl CargoTargetSpec {
Ok(res)
}

pub(crate) fn push_to(self, buf: &mut Vec<String>) {
pub(crate) fn push_to(self, buf: &mut Vec<String>, kind: &RunnableKind) {
buf.push("--package".to_string());
buf.push(self.package);

// Can't mix --doc with other target flags
if let RunnableKind::DocTest { .. } = kind {
return;
}
match self.target_kind {
TargetKind::Bin => {
buf.push("--bin".to_string());
Expand Down
2 changes: 2 additions & 0 deletions crates/rust-analyzer/src/main_loop/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,7 @@ pub fn handle_code_lens(
for runnable in world.analysis().runnables(file_id)? {
let title = match &runnable.kind {
RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => "▶️\u{fe0e}Run Test",
RunnableKind::DocTest { .. } => "▶️\u{fe0e}Run Doctest",
RunnableKind::Bench { .. } => "Run Bench",
RunnableKind::Bin => "Run",
}
Expand Down Expand Up @@ -1018,6 +1019,7 @@ fn to_lsp_runnable(
RunnableKind::Test { test_id, .. } => format!("test {}", test_id),
RunnableKind::TestMod { path } => format!("test-mod {}", path),
RunnableKind::Bench { test_id } => format!("bench {}", test_id),
RunnableKind::DocTest { test_id, .. } => format!("doctest {}", test_id),
RunnableKind::Bin => "run binary".to_string(),
};
Ok(req::Runnable {
Expand Down

0 comments on commit f0411ff

Please sign in to comment.