Skip to content

Commit 530d3ad

Browse files
committed
Add rustdoc test support and change logger output
We add the missing component for tests here which is doctests! We now have rustdoc integrated with it's own module like rustc. This commit does a few things in particular: - Add support to run rustdoc tests - Add a doctest to Rustc for testing purposes - Changes the logging output to be more consistent with cargo's minus coloring - Removes some logging from building test binaries so as not to be confusing as to what's going on which is building test binaries, not the freight library per se
1 parent edb6326 commit 530d3ad

5 files changed

Lines changed: 129 additions & 33 deletions

File tree

‎.gitignore‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
11
/target
22
.direnv
3+
4+
5+
# Added by cargo
6+
#
7+
# already existing elements were commented out
8+
9+
#/target

‎src/lib.rs‎

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
mod config;
22
mod logger;
33
pub mod rustc;
4+
pub mod rustdoc;
45

56
use crate::rustc::CrateType;
67
use crate::rustc::Edition;
78
use crate::rustc::Rustc;
9+
use crate::rustdoc::RustDoc;
810
use config::Manifest;
911
use logger::Logger;
1012
use std::env;
@@ -23,7 +25,7 @@ fn lib_compile(
2325
lib_path: &Path,
2426
out_dir: &Path,
2527
) -> Result<()> {
26-
logger.compiling_crate(&manifest.crate_name);
28+
logger.compiling_crate(&manifest.crate_name)?;
2729
Rustc::builder()
2830
.edition(manifest.edition)
2931
.crate_type(CrateType::Lib)
@@ -32,7 +34,6 @@ fn lib_compile(
3234
.lib_dir(out_dir.clone())
3335
.done()
3436
.run(lib_path.to_str().unwrap())?;
35-
logger.done_compiling();
3637
Ok(())
3738
}
3839

@@ -43,7 +44,7 @@ fn bin_compile(
4344
out_dir: &Path,
4445
externs: &[&str],
4546
) -> Result<()> {
46-
logger.compiling_bin(&manifest.crate_name);
47+
logger.compiling_bin(&manifest.crate_name)?;
4748
let mut builder = Rustc::builder()
4849
.edition(manifest.edition)
4950
.crate_type(CrateType::Bin)
@@ -56,18 +57,15 @@ fn bin_compile(
5657
}
5758

5859
builder.done().run(bin_path.to_str().unwrap())?;
59-
logger.done_compiling();
6060
Ok(())
6161
}
6262

6363
fn test_compile(
64-
logger: &mut Logger,
6564
manifest: &Manifest,
6665
bin_path: &Path,
6766
out_dir: &Path,
6867
externs: &[&str],
6968
) -> Result<()> {
70-
logger.compiling_bin(&manifest.crate_name);
7169
let mut builder = Rustc::builder()
7270
.edition(manifest.edition)
7371
.crate_type(CrateType::Bin)
@@ -85,7 +83,6 @@ fn test_compile(
8583
}
8684

8785
builder.done().run(bin_path.to_str().unwrap())?;
88-
logger.done_compiling();
8986
Ok(())
9087
}
9188

@@ -136,42 +133,51 @@ pub fn build_tests() -> Result<()> {
136133

137134
match (lib_rs.exists(), main_rs.exists()) {
138135
(true, true) => {
139-
test_compile(&mut logger, &manifest, &lib_rs, &target_tests, &[])?;
136+
test_compile(&manifest, &lib_rs, &target_tests, &[])?;
140137
lib_compile(&mut logger, &manifest, &lib_rs, &target_tests)?;
141-
test_compile(
142-
&mut logger,
143-
&manifest,
144-
&main_rs,
145-
&target_tests,
146-
&[&manifest.crate_name],
147-
)?;
138+
test_compile(&manifest, &main_rs, &target_tests, &[&manifest.crate_name])?;
148139
}
149140
(true, false) => {
150-
test_compile(&mut logger, &manifest, &lib_rs, &target_tests, &[])?;
141+
test_compile(&manifest, &lib_rs, &target_tests, &[])?;
151142
}
152143
(false, true) => {
153-
test_compile(&mut logger, &manifest, &main_rs, &target_tests, &[])?;
144+
test_compile(&manifest, &main_rs, &target_tests, &[])?;
154145
}
155146
(false, false) => return Err("There is nothing to compile".into()),
156147
}
157148

149+
logger.done_compiling()?;
158150
Ok(())
159151
}
160152

161153
pub fn run_tests(test_args: Vec<String>) -> Result<()> {
162-
for item in root_dir()?
163-
.join("target")
164-
.join("debug")
165-
.join("tests")
166-
.read_dir()?
167-
{
154+
let mut logger = Logger::new();
155+
let root = root_dir()?;
156+
let manifest = Manifest::parse_from_file(root.join("Freight.toml"))?;
157+
for item in root.join("target").join("debug").join("tests").read_dir()? {
168158
let item = item?;
169159
let path = item.path();
170160
let is_test = path.extension().is_none();
171161
if is_test {
162+
let file_name = path.file_name().unwrap().to_str().unwrap();
163+
if file_name == "test_freight_main" {
164+
logger.main_unit_test()?;
165+
} else if file_name == "test_freight_lib" {
166+
logger.lib_unit_test()?;
167+
}
172168
Command::new(path).args(&test_args).spawn()?.wait()?;
173169
}
174170
}
171+
let lib = root.join("src").join("lib.rs");
172+
if lib.exists() {
173+
logger.doc_test(&manifest.crate_name)?;
174+
RustDoc::new(
175+
manifest.edition,
176+
manifest.crate_name,
177+
root.join("target").join("debug"),
178+
)
179+
.test(lib)?;
180+
}
175181
Ok(())
176182
}
177183

‎src/logger.rs‎

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::Result;
12
use std::io;
23
use std::io::Write;
34

@@ -11,17 +12,43 @@ impl Logger {
1112
out: io::stdout().lock(),
1213
}
1314
}
14-
pub fn compiling_crate(&mut self, crate_name: &str) {
15-
let _ = self
16-
.out
17-
.write_all(format!("Compiling crate {crate_name}...").as_bytes());
15+
pub fn compiling_crate(&mut self, crate_name: &str) -> Result<()> {
16+
self.out
17+
.write_all(format!(" Compiling lib {crate_name}\n").as_bytes())?;
18+
self.out.flush()?;
19+
Ok(())
1820
}
19-
pub fn compiling_bin(&mut self, crate_name: &str) {
20-
let _ = self
21-
.out
22-
.write_all(format!("Compiling bin {crate_name}...").as_bytes());
21+
pub fn compiling_bin(&mut self, crate_name: &str) -> Result<()> {
22+
self.out
23+
.write_all(format!(" Compiling bin {crate_name}\n").as_bytes())?;
24+
self.out.flush()?;
25+
Ok(())
2326
}
24-
pub fn done_compiling(&mut self) {
25-
let _ = self.out.write_all(b"Done\n");
27+
pub fn done_compiling(&mut self) -> Result<()> {
28+
self.out.write_all(b" Finished dev\n")?;
29+
self.out.flush()?;
30+
Ok(())
31+
}
32+
pub fn main_unit_test(&mut self) -> Result<()> {
33+
self.unit_test("src/main.rs")?;
34+
Ok(())
35+
}
36+
pub fn lib_unit_test(&mut self) -> Result<()> {
37+
self.unit_test("src/lib.rs")?;
38+
Ok(())
39+
}
40+
fn unit_test(&mut self, file: &str) -> Result<()> {
41+
self.out.write_all(b" Running unittests ")?;
42+
self.out.write_all(file.as_bytes())?;
43+
self.out.write_all(b"\n")?;
44+
self.out.flush()?;
45+
Ok(())
46+
}
47+
pub fn doc_test(&mut self, crate_name: &str) -> Result<()> {
48+
self.out.write_all(b" Doc-tests ")?;
49+
self.out.write_all(crate_name.as_bytes())?;
50+
self.out.write_all(b"\n")?;
51+
self.out.flush()?;
52+
Ok(())
2653
}
2754
}

‎src/rustc.rs‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,22 @@ pub struct Rustc {
1818
}
1919

2020
impl Rustc {
21+
/// Create a builder type to build up commands to then invoke rustc with.
22+
/// ```
23+
/// # use std::error::Error;
24+
/// # use freight::rustc::Rustc;
25+
/// # use freight::rustc::Edition;
26+
/// # use freight::rustc::CrateType;
27+
/// # fn main() -> Result<(), Box<dyn Error>> {
28+
/// let builder = Rustc::builder()
29+
/// .edition(Edition::E2021)
30+
/// .crate_type(CrateType::Bin)
31+
/// .crate_name("freight")
32+
/// .out_dir(".")
33+
/// .lib_dir(".");
34+
/// # Ok(())
35+
/// # }
36+
/// ```
2137
pub fn builder() -> RustcBuilder {
2238
RustcBuilder {
2339
..Default::default()

‎src/rustdoc.rs‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use super::Result;
2+
use crate::rustc::Edition;
3+
use std::path::Path;
4+
use std::path::PathBuf;
5+
use std::process::Command;
6+
7+
pub struct RustDoc {
8+
edition: Edition,
9+
crate_name: String,
10+
lib_path: PathBuf,
11+
}
12+
13+
impl RustDoc {
14+
pub fn new(
15+
edition: Edition,
16+
crate_name: impl Into<String>,
17+
lib_path: impl Into<PathBuf>,
18+
) -> Self {
19+
Self {
20+
edition,
21+
crate_name: crate_name.into(),
22+
lib_path: lib_path.into(),
23+
}
24+
}
25+
pub fn test(&self, path: impl AsRef<Path>) -> Result<()> {
26+
let path = path.as_ref();
27+
Command::new("rustdoc")
28+
.arg("--test")
29+
.arg(path)
30+
.arg("--crate-name")
31+
.arg(&self.crate_name)
32+
.arg("--edition")
33+
.arg(self.edition.to_string())
34+
.arg("-L")
35+
.arg(&self.lib_path)
36+
.spawn()?
37+
.wait()?;
38+
Ok(())
39+
}
40+
}

0 commit comments

Comments
 (0)