Split doctests into two categories: mergeable ones and standalone ones
This commit is contained in:
parent
96051f20e2
commit
6ae3524835
@ -206,7 +206,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, options: RustdocOptions) -> Result<()
|
|||||||
test_args,
|
test_args,
|
||||||
nocapture,
|
nocapture,
|
||||||
opts,
|
opts,
|
||||||
rustdoc_options,
|
&rustdoc_options,
|
||||||
&unused_extern_reports,
|
&unused_extern_reports,
|
||||||
standalone_tests,
|
standalone_tests,
|
||||||
mergeable_tests,
|
mergeable_tests,
|
||||||
@ -259,10 +259,10 @@ pub(crate) fn run_tests(
|
|||||||
mut test_args: Vec<String>,
|
mut test_args: Vec<String>,
|
||||||
nocapture: bool,
|
nocapture: bool,
|
||||||
opts: GlobalTestOptions,
|
opts: GlobalTestOptions,
|
||||||
rustdoc_options: RustdocOptions,
|
rustdoc_options: &Arc<RustdocOptions>,
|
||||||
unused_extern_reports: &Arc<Mutex<Vec<UnusedExterns>>>,
|
unused_extern_reports: &Arc<Mutex<Vec<UnusedExterns>>>,
|
||||||
mut standalone_tests: Vec<test::TestDescAndFn>,
|
mut standalone_tests: Vec<test::TestDescAndFn>,
|
||||||
mut mergeable_tests: FxHashMap<Edition, Vec<(DocTest, ScrapedDoctest)>>,
|
mergeable_tests: FxHashMap<Edition, Vec<(DocTest, ScrapedDoctest)>>,
|
||||||
) {
|
) {
|
||||||
test_args.insert(0, "rustdoctest".to_string());
|
test_args.insert(0, "rustdoctest".to_string());
|
||||||
if nocapture {
|
if nocapture {
|
||||||
@ -270,28 +270,32 @@ pub(crate) fn run_tests(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut nb_errors = 0;
|
let mut nb_errors = 0;
|
||||||
|
let target_str = rustdoc_options.target.to_string();
|
||||||
|
|
||||||
for (edition, mut doctests) in mergeable_tests {
|
for (edition, mut doctests) in mergeable_tests {
|
||||||
if doctests.is_empty() {
|
if doctests.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
doctests.sort_by(|(_, a), (_, b)| a.name.cmp(&b.name));
|
doctests.sort_by(|(_, a), (_, b)| a.name.cmp(&b.name));
|
||||||
let outdir = Arc::clone(&doctests[0].outdir);
|
|
||||||
|
|
||||||
let mut tests_runner = runner::DocTestRunner::new();
|
let mut tests_runner = runner::DocTestRunner::new();
|
||||||
|
|
||||||
let rustdoc_test_options = IndividualTestOptions::new(
|
let rustdoc_test_options = IndividualTestOptions::new(
|
||||||
&rustdoc_options,
|
&rustdoc_options,
|
||||||
format!("merged_doctest"),
|
&format!("merged_doctest_{edition}"),
|
||||||
PathBuf::from(r"doctest.rs"),
|
PathBuf::from(format!("doctest_{edition}.rs")),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (doctest, scraped_test) in &doctests {
|
for (doctest, scraped_test) in &doctests {
|
||||||
tests_runner.add_test(doctest, scraped_test);
|
tests_runner.add_test(doctest, scraped_test, &target_str);
|
||||||
}
|
}
|
||||||
if let Ok(success) =
|
if let Ok(success) = tests_runner.run_tests(
|
||||||
tests_runner.run_tests(rustdoc_test_options, edition, &opts, &test_args, &outdir)
|
rustdoc_test_options,
|
||||||
{
|
edition,
|
||||||
|
&opts,
|
||||||
|
&test_args,
|
||||||
|
rustdoc_options,
|
||||||
|
) {
|
||||||
if !success {
|
if !success {
|
||||||
nb_errors += 1;
|
nb_errors += 1;
|
||||||
}
|
}
|
||||||
@ -311,7 +315,7 @@ pub(crate) fn run_tests(
|
|||||||
doctest,
|
doctest,
|
||||||
scraped_test,
|
scraped_test,
|
||||||
opts.clone(),
|
opts.clone(),
|
||||||
rustdoc_test_options.clone(),
|
Arc::clone(&rustdoc_options),
|
||||||
unused_extern_reports.clone(),
|
unused_extern_reports.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -406,7 +410,7 @@ fn path(&self) -> &std::path::Path {
|
|||||||
// We could unify this struct the one in rustc but they have different
|
// We could unify this struct the one in rustc but they have different
|
||||||
// ownership semantics, so doing so would create wasteful allocations.
|
// ownership semantics, so doing so would create wasteful allocations.
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
struct UnusedExterns {
|
pub(crate) struct UnusedExterns {
|
||||||
/// Lint level of the unused_crate_dependencies lint
|
/// Lint level of the unused_crate_dependencies lint
|
||||||
lint_level: String,
|
lint_level: String,
|
||||||
/// List of unused externs by their names.
|
/// List of unused externs by their names.
|
||||||
@ -642,12 +646,11 @@ fn make_maybe_absolute_path(path: PathBuf) -> PathBuf {
|
|||||||
}
|
}
|
||||||
struct IndividualTestOptions {
|
struct IndividualTestOptions {
|
||||||
outdir: DirState,
|
outdir: DirState,
|
||||||
test_id: String,
|
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndividualTestOptions {
|
impl IndividualTestOptions {
|
||||||
fn new(options: &RustdocOptions, test_id: String, test_path: PathBuf) -> Self {
|
fn new(options: &RustdocOptions, test_id: &str, test_path: PathBuf) -> Self {
|
||||||
let outdir = if let Some(ref path) = options.persist_doctests {
|
let outdir = if let Some(ref path) = options.persist_doctests {
|
||||||
let mut path = path.clone();
|
let mut path = path.clone();
|
||||||
path.push(&test_id);
|
path.push(&test_id);
|
||||||
@ -662,15 +665,14 @@ fn new(options: &RustdocOptions, test_id: String, test_path: PathBuf) -> Self {
|
|||||||
DirState::Temp(get_doctest_dir().expect("rustdoc needs a tempdir"))
|
DirState::Temp(get_doctest_dir().expect("rustdoc needs a tempdir"))
|
||||||
};
|
};
|
||||||
|
|
||||||
Self { outdir, test_id, path: test_path }
|
Self { outdir, path: test_path }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A doctest scraped from the code, ready to be turned into a runnable test.
|
/// A doctest scraped from the code, ready to be turned into a runnable test.
|
||||||
struct ScrapedDoctest {
|
pub(crate) struct ScrapedDoctest {
|
||||||
filename: FileName,
|
filename: FileName,
|
||||||
line: usize,
|
line: usize,
|
||||||
logical_path: Vec<String>,
|
|
||||||
langstr: LangString,
|
langstr: LangString,
|
||||||
text: String,
|
text: String,
|
||||||
name: String,
|
name: String,
|
||||||
@ -692,7 +694,7 @@ fn new(
|
|||||||
let name =
|
let name =
|
||||||
format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionaly());
|
format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionaly());
|
||||||
|
|
||||||
Self { filename, line, logical_path, langstr, text, name }
|
Self { filename, line, langstr, text, name }
|
||||||
}
|
}
|
||||||
fn edition(&self, opts: &RustdocOptions) -> Edition {
|
fn edition(&self, opts: &RustdocOptions) -> Edition {
|
||||||
self.langstr.edition.unwrap_or(opts.edition)
|
self.langstr.edition.unwrap_or(opts.edition)
|
||||||
@ -701,6 +703,19 @@ fn edition(&self, opts: &RustdocOptions) -> Edition {
|
|||||||
fn no_run(&self, opts: &RustdocOptions) -> bool {
|
fn no_run(&self, opts: &RustdocOptions) -> bool {
|
||||||
self.langstr.no_run || opts.no_run
|
self.langstr.no_run || opts.no_run
|
||||||
}
|
}
|
||||||
|
fn path(&self) -> PathBuf {
|
||||||
|
match &self.filename {
|
||||||
|
FileName::Real(path) => {
|
||||||
|
if let Some(local_path) = path.local_path() {
|
||||||
|
local_path.to_path_buf()
|
||||||
|
} else {
|
||||||
|
// Somehow we got the filename from the metadata of another crate, should never happen
|
||||||
|
unreachable!("doctest from a different crate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => PathBuf::from(r"doctest.rs"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait DoctestVisitor {
|
pub(crate) trait DoctestVisitor {
|
||||||
@ -757,7 +772,7 @@ fn add_test(&mut self, scraped_test: ScrapedDoctest) {
|
|||||||
|
|
||||||
let edition = scraped_test.edition(&self.rustdoc_options);
|
let edition = scraped_test.edition(&self.rustdoc_options);
|
||||||
let doctest =
|
let doctest =
|
||||||
DocTest::new(&scraped_test.text, Some(&self.opts.crate_name), edition, test_id);
|
DocTest::new(&scraped_test.text, Some(&self.opts.crate_name), edition, Some(test_id));
|
||||||
let is_standalone = scraped_test.langstr.compile_fail
|
let is_standalone = scraped_test.langstr.compile_fail
|
||||||
|| scraped_test.langstr.test_harness
|
|| scraped_test.langstr.test_harness
|
||||||
|| self.rustdoc_options.nocapture
|
|| self.rustdoc_options.nocapture
|
||||||
@ -784,7 +799,7 @@ fn generate_test_desc_and_fn(
|
|||||||
test,
|
test,
|
||||||
scraped_test,
|
scraped_test,
|
||||||
self.opts.clone(),
|
self.opts.clone(),
|
||||||
self.rustdoc_options.clone(),
|
Arc::clone(&self.rustdoc_options),
|
||||||
self.unused_extern_reports.clone(),
|
self.unused_extern_reports.clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -794,32 +809,20 @@ fn generate_test_desc_and_fn(
|
|||||||
test: DocTest,
|
test: DocTest,
|
||||||
scraped_test: ScrapedDoctest,
|
scraped_test: ScrapedDoctest,
|
||||||
opts: GlobalTestOptions,
|
opts: GlobalTestOptions,
|
||||||
rustdoc_options: IndividualTestOptions,
|
rustdoc_options: Arc<RustdocOptions>,
|
||||||
unused_externs: Arc<Mutex<Vec<UnusedExterns>>>,
|
unused_externs: Arc<Mutex<Vec<UnusedExterns>>>,
|
||||||
) -> test::TestDescAndFn {
|
) -> test::TestDescAndFn {
|
||||||
let target_str = rustdoc_options.target.to_string();
|
let target_str = rustdoc_options.target.to_string();
|
||||||
|
let rustdoc_test_options = IndividualTestOptions::new(
|
||||||
|
&rustdoc_options,
|
||||||
|
test.test_id.as_deref().unwrap_or_else(|| "<doctest>"),
|
||||||
|
scraped_test.path(),
|
||||||
|
);
|
||||||
|
|
||||||
let path = match &scraped_test.filename {
|
debug!("creating test {}: {}", scraped_test.name, scraped_test.text);
|
||||||
FileName::Real(path) => {
|
|
||||||
if let Some(local_path) = path.local_path() {
|
|
||||||
local_path.to_path_buf()
|
|
||||||
} else {
|
|
||||||
// Somehow we got the filename from the metadata of another crate, should never happen
|
|
||||||
unreachable!("doctest from a different crate");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => PathBuf::from(r"doctest.rs"),
|
|
||||||
};
|
|
||||||
|
|
||||||
let name = &test.name;
|
|
||||||
let rustdoc_test_options =
|
|
||||||
IndividualTestOptions::new(&rustdoc_options, test.test_id.clone(), path);
|
|
||||||
// let rustdoc_options_clone = rustdoc_options.clone();
|
|
||||||
|
|
||||||
debug!("creating test {name}: {}", scraped_test.text);
|
|
||||||
test::TestDescAndFn {
|
test::TestDescAndFn {
|
||||||
desc: test::TestDesc {
|
desc: test::TestDesc {
|
||||||
name: test::DynTestName(name),
|
name: test::DynTestName(scraped_test.name.clone()),
|
||||||
ignore: match scraped_test.langstr.ignore {
|
ignore: match scraped_test.langstr.ignore {
|
||||||
Ignore::All => true,
|
Ignore::All => true,
|
||||||
Ignore::None => false,
|
Ignore::None => false,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Doctest functionality used only for doctests in `.md` Markdown files.
|
//! Doctest functionality used only for doctests in `.md` Markdown files.
|
||||||
|
|
||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use rustc_span::FileName;
|
use rustc_span::FileName;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
@ -114,6 +115,16 @@ pub(crate) fn test(options: Options) -> Result<(), String> {
|
|||||||
|
|
||||||
let mut collector = CreateRunnableDoctests::new(options.clone(), opts);
|
let mut collector = CreateRunnableDoctests::new(options.clone(), opts);
|
||||||
md_collector.tests.into_iter().for_each(|t| collector.add_test(t));
|
md_collector.tests.into_iter().for_each(|t| collector.add_test(t));
|
||||||
crate::doctest::run_tests(options.test_args, options.nocapture, collector.standalone_tests);
|
let CreateRunnableDoctests { opts, rustdoc_options, standalone_tests, mergeable_tests, .. } =
|
||||||
|
collector;
|
||||||
|
crate::doctest::run_tests(
|
||||||
|
options.test_args,
|
||||||
|
options.nocapture,
|
||||||
|
opts,
|
||||||
|
&rustdoc_options,
|
||||||
|
&Arc::new(Mutex::new(Vec::new())),
|
||||||
|
standalone_tests,
|
||||||
|
mergeable_tests,
|
||||||
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
use crate::doctest::{
|
use crate::doctest::{
|
||||||
run_test, DirState, DocTest, GlobalTestOptions, IndividualTestOptions, RunnableDoctest,
|
run_test, DocTest, GlobalTestOptions, IndividualTestOptions, RunnableDoctest, RustdocOptions,
|
||||||
RustdocOptions, ScrapedDoctest, TestFailure, UnusedExterns,
|
ScrapedDoctest, TestFailure, UnusedExterns,
|
||||||
};
|
};
|
||||||
use crate::html::markdown::LangString;
|
use crate::html::markdown::{Ignore, LangString};
|
||||||
|
|
||||||
/// Convenient type to merge compatible doctests into one.
|
/// Convenient type to merge compatible doctests into one.
|
||||||
pub(crate) struct DocTestRunner {
|
pub(crate) struct DocTestRunner {
|
||||||
@ -17,7 +16,6 @@ pub(crate) struct DocTestRunner {
|
|||||||
output: String,
|
output: String,
|
||||||
supports_color: bool,
|
supports_color: bool,
|
||||||
nb_tests: usize,
|
nb_tests: usize,
|
||||||
doctests: Vec<DocTest>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DocTestRunner {
|
impl DocTestRunner {
|
||||||
@ -28,12 +26,21 @@ pub(crate) fn new() -> Self {
|
|||||||
output: String::new(),
|
output: String::new(),
|
||||||
supports_color: true,
|
supports_color: true,
|
||||||
nb_tests: 0,
|
nb_tests: 0,
|
||||||
doctests: Vec::with_capacity(10),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_test(&mut self, doctest: &DocTest, scraped_test: &ScrapedDoctest) {
|
pub(crate) fn add_test(
|
||||||
if !doctest.ignore {
|
&mut self,
|
||||||
|
doctest: &DocTest,
|
||||||
|
scraped_test: &ScrapedDoctest,
|
||||||
|
target_str: &str,
|
||||||
|
) {
|
||||||
|
let ignore = match scraped_test.langstr.ignore {
|
||||||
|
Ignore::All => true,
|
||||||
|
Ignore::None => false,
|
||||||
|
Ignore::Some(ref ignores) => ignores.iter().any(|s| target_str.contains(s)),
|
||||||
|
};
|
||||||
|
if !ignore {
|
||||||
for line in doctest.crate_attrs.split('\n') {
|
for line in doctest.crate_attrs.split('\n') {
|
||||||
self.crate_attrs.insert(line.to_string());
|
self.crate_attrs.insert(line.to_string());
|
||||||
}
|
}
|
||||||
@ -43,11 +50,16 @@ pub(crate) fn add_test(&mut self, doctest: &DocTest, scraped_test: &ScrapedDocte
|
|||||||
}
|
}
|
||||||
self.ids.push_str(&format!(
|
self.ids.push_str(&format!(
|
||||||
"{}::TEST",
|
"{}::TEST",
|
||||||
generate_mergeable_doctest(doctest, scraped_test, self.nb_tests, &mut self.output),
|
generate_mergeable_doctest(
|
||||||
|
doctest,
|
||||||
|
scraped_test,
|
||||||
|
ignore,
|
||||||
|
self.nb_tests,
|
||||||
|
&mut self.output
|
||||||
|
),
|
||||||
));
|
));
|
||||||
self.supports_color &= doctest.supports_color;
|
self.supports_color &= doctest.supports_color;
|
||||||
self.nb_tests += 1;
|
self.nb_tests += 1;
|
||||||
self.doctests.push(doctest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn run_tests(
|
pub(crate) fn run_tests(
|
||||||
@ -56,9 +68,7 @@ pub(crate) fn run_tests(
|
|||||||
edition: Edition,
|
edition: Edition,
|
||||||
opts: &GlobalTestOptions,
|
opts: &GlobalTestOptions,
|
||||||
test_args: &[String],
|
test_args: &[String],
|
||||||
outdir: &Arc<DirState>,
|
|
||||||
rustdoc_options: &RustdocOptions,
|
rustdoc_options: &RustdocOptions,
|
||||||
unused_externs: Arc<Mutex<Vec<UnusedExterns>>>,
|
|
||||||
) -> Result<bool, ()> {
|
) -> Result<bool, ()> {
|
||||||
let mut code = "\
|
let mut code = "\
|
||||||
#![allow(unused_extern_crates)]
|
#![allow(unused_extern_crates)]
|
||||||
@ -73,7 +83,19 @@ pub(crate) fn run_tests(
|
|||||||
code.push('\n');
|
code.push('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
DocTest::push_attrs(&mut code, opts, &mut 0);
|
if opts.attrs.is_empty() {
|
||||||
|
// If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some
|
||||||
|
// lints that are commonly triggered in doctests. The crate-level test attributes are
|
||||||
|
// commonly used to make tests fail in case they trigger warnings, so having this there in
|
||||||
|
// that case may cause some tests to pass when they shouldn't have.
|
||||||
|
code.push_str("#![allow(unused)]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, any attributes that came from the crate root via #![doc(test(attr(...)))].
|
||||||
|
for attr in &opts.attrs {
|
||||||
|
code.push_str(&format!("#![{attr}]\n"));
|
||||||
|
}
|
||||||
|
|
||||||
code.push_str("extern crate test;\n");
|
code.push_str("extern crate test;\n");
|
||||||
|
|
||||||
let test_args =
|
let test_args =
|
||||||
@ -91,7 +113,6 @@ fn main() {{
|
|||||||
ids = self.ids,
|
ids = self.ids,
|
||||||
)
|
)
|
||||||
.expect("failed to generate test code");
|
.expect("failed to generate test code");
|
||||||
// let out_dir = build_test_dir(outdir, true, "");
|
|
||||||
let runnable_test = RunnableDoctest {
|
let runnable_test = RunnableDoctest {
|
||||||
full_test_code: code,
|
full_test_code: code,
|
||||||
full_test_line_offset: 0,
|
full_test_line_offset: 0,
|
||||||
@ -102,7 +123,8 @@ fn main() {{
|
|||||||
edition,
|
edition,
|
||||||
no_run: false,
|
no_run: false,
|
||||||
};
|
};
|
||||||
let ret = run_test(runnable_test, rustdoc_options, self.supports_color, unused_externs);
|
let ret =
|
||||||
|
run_test(runnable_test, rustdoc_options, self.supports_color, |_: UnusedExterns| {});
|
||||||
if let Err(TestFailure::CompileError) = ret { Err(()) } else { Ok(ret.is_ok()) }
|
if let Err(TestFailure::CompileError) = ret { Err(()) } else { Ok(ret.is_ok()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,12 +133,13 @@ fn main() {{
|
|||||||
fn generate_mergeable_doctest(
|
fn generate_mergeable_doctest(
|
||||||
doctest: &DocTest,
|
doctest: &DocTest,
|
||||||
scraped_test: &ScrapedDoctest,
|
scraped_test: &ScrapedDoctest,
|
||||||
|
ignore: bool,
|
||||||
id: usize,
|
id: usize,
|
||||||
output: &mut String,
|
output: &mut String,
|
||||||
) -> String {
|
) -> String {
|
||||||
let test_id = format!("__doctest_{id}");
|
let test_id = format!("__doctest_{id}");
|
||||||
|
|
||||||
if doctest.ignore {
|
if ignore {
|
||||||
// We generate nothing else.
|
// We generate nothing else.
|
||||||
writeln!(output, "mod {test_id} {{\n").unwrap();
|
writeln!(output, "mod {test_id} {{\n").unwrap();
|
||||||
} else {
|
} else {
|
||||||
@ -166,8 +189,7 @@ fn main() {returns_result} {{
|
|||||||
}};
|
}};
|
||||||
}}",
|
}}",
|
||||||
test_name = scraped_test.name,
|
test_name = scraped_test.name,
|
||||||
ignore = scraped_test.langstr.ignore,
|
file = scraped_test.path(),
|
||||||
file = scraped_test.file,
|
|
||||||
line = scraped_test.line,
|
line = scraped_test.line,
|
||||||
no_run = scraped_test.langstr.no_run,
|
no_run = scraped_test.langstr.no_run,
|
||||||
should_panic = if !scraped_test.langstr.no_run && scraped_test.langstr.should_panic {
|
should_panic = if !scraped_test.langstr.no_run && scraped_test.langstr.should_panic {
|
||||||
@ -177,7 +199,7 @@ fn main() {returns_result} {{
|
|||||||
},
|
},
|
||||||
// Setting `no_run` to `true` in `TestDesc` still makes the test run, so we simply
|
// Setting `no_run` to `true` in `TestDesc` still makes the test run, so we simply
|
||||||
// don't give it the function to run.
|
// don't give it the function to run.
|
||||||
runner = if scraped_test.langstr.no_run || scraped_test.langstr.ignore {
|
runner = if ignore || scraped_test.langstr.no_run {
|
||||||
"Ok::<(), String>(())"
|
"Ok::<(), String>(())"
|
||||||
} else {
|
} else {
|
||||||
"self::main()"
|
"self::main()"
|
||||||
|
@ -10,9 +10,10 @@ fn make_test(
|
|||||||
opts: &GlobalTestOptions,
|
opts: &GlobalTestOptions,
|
||||||
test_id: Option<&str>,
|
test_id: Option<&str>,
|
||||||
) -> (String, usize) {
|
) -> (String, usize) {
|
||||||
let doctest = DocTest::new(test_code, crate_name, DEFAULT_EDITION);
|
let doctest =
|
||||||
|
DocTest::new(test_code, crate_name, DEFAULT_EDITION, test_id.map(|s| s.to_string()));
|
||||||
let (code, line_offset) =
|
let (code, line_offset) =
|
||||||
doctest.generate_unique_doctest(test_code, dont_insert_main, opts, test_id, crate_name);
|
doctest.generate_unique_doctest(test_code, dont_insert_main, opts, crate_name);
|
||||||
(code, line_offset)
|
(code, line_offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user