Add support for multiple formats to test cases

This patch adds support for multiple rustdoc output formats to the test
suite.  This is a preparation for adding support for rustdoc’s JSON
output.
This commit is contained in:
Robin Krahl 2020-09-12 18:38:49 +02:00
parent b0485d515c
commit 601ec251f8
No known key found for this signature in database
GPG Key ID: 8E9B0870524F69D8
299 changed files with 98 additions and 56 deletions

View File

@ -5,6 +5,10 @@ SPDX-License-Identifier: MIT
# Changelog for rusty-man
# Unreleased
- Prepare supporting multiple parser backends.
## v0.4.2 (2021-06-06)
This patch releases adds support for the new search index format (Rust 1.52.0

View File

@ -255,7 +255,7 @@ impl Index {
mod tests {
use super::{CrateData, Data, Index, IndexItem, ItemData};
use crate::doc::ItemType;
use crate::test_utils::with_rustdoc;
use crate::test_utils::{with_rustdoc, Format};
#[test]
fn test_empty() {
@ -296,7 +296,7 @@ mod tests {
#[test]
fn test_index() {
with_rustdoc(">=1.44.0, <1.50.0", |_, path| {
with_rustdoc(">=1.44.0, <1.50.0", Format::all(), |_, _, path| {
let index = Index::load(path.join("search-index.js")).unwrap().unwrap();
let empty: Vec<IndexItem> = Vec::new();
@ -315,7 +315,7 @@ mod tests {
assert_eq!(empty, index.find(&"NodeDataReff".to_owned().into()));
});
with_rustdoc(">=1.50.0", |_, path| {
with_rustdoc(">=1.50.0", Format::all(), |_, _, path| {
let index = Index::load(path.join("search-index.js")).unwrap().unwrap();
let empty: Vec<IndexItem> = Vec::new();
@ -334,7 +334,7 @@ mod tests {
assert_eq!(empty, index.find(&"NodeDataReff".to_owned().into()));
});
with_rustdoc(">=1.44.0", |_, path| {
with_rustdoc(">=1.44.0", Format::all(), |_, _, path| {
let index = Index::load(path.join("search-index.js")).unwrap().unwrap();
let empty: Vec<IndexItem> = Vec::new();

View File

@ -208,11 +208,11 @@ fn select_item(
#[cfg(test)]
mod tests {
use crate::source;
use crate::test_utils::with_rustdoc;
use crate::test_utils::{with_rustdoc, Format};
#[test]
fn test_find_doc() {
with_rustdoc("*", |_, path| {
with_rustdoc("*", Format::all(), |_, _, path| {
let sources = source::Sources::new(vec![source::get_source(path).unwrap()]);
assert!(sources

View File

@ -759,11 +759,11 @@ fn get_item_group_id(ty: doc::ItemType) -> &'static str {
#[cfg(test)]
mod tests {
use crate::doc;
use crate::test_utils::with_rustdoc;
use crate::test_utils::{with_rustdoc, Format};
#[test]
fn test_find_item() {
with_rustdoc("*", |_, path| {
with_rustdoc("*", Format::all(), |_, _, path| {
let path = path.join("kuchiki").join("all.html");
let parser = super::Parser::from_file(path).unwrap();
@ -777,7 +777,7 @@ mod tests {
#[test]
fn test_parse_item_doc() {
with_rustdoc("*", |_, path| {
with_rustdoc("*", Format::all(), |_, _, path| {
let path = path.join("kuchiki").join("struct.NodeRef.html");
let name: doc::Fqn = "kuchiki::NodeRef".to_owned().into();
let doc = super::Parser::from_file(path)
@ -794,7 +794,7 @@ mod tests {
#[test]
fn test_find_member() {
with_rustdoc("*", |_, path| {
with_rustdoc("*", Format::all(), |_, _, path| {
let path = path.join("kuchiki").join("struct.NodeDataRef.html");
let name: doc::Fqn = "kuchiki::NodeDataRef::as_node".to_owned().into();
let ty = super::Parser::from_file(path)
@ -807,7 +807,7 @@ mod tests {
#[test]
fn test_parse_member_doc() {
with_rustdoc("*", |_, path| {
with_rustdoc("*", Format::all(), |_, _, path| {
let path = path.join("kuchiki").join("struct.NodeDataRef.html");
let name: doc::Fqn = "kuchiki::NodeDataRef::as_node".to_owned().into();
let doc = super::Parser::from_file(path)

View File

@ -4,19 +4,46 @@
//! Utility functions for executing tests with the output of different rustdoc versions.
use std::env;
use std::fmt;
use std::fs;
use std::path;
use std::process;
use std::sync;
static mut VERSIONS: Option<Vec<(semver::Version, path::PathBuf)>> = None;
static mut VERSIONS: Option<Vec<(semver::Version, Format, path::PathBuf)>> = None;
static INIT: sync::Once = sync::Once::new();
fn get_versions() -> &'static [(semver::Version, path::PathBuf)] {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Format {
Html,
}
impl Format {
pub fn all() -> &'static [Format] {
FORMATS
}
}
static FORMATS: &[Format] = &[Format::Html];
impl fmt::Display for Format {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Format::Html => "html",
})
}
}
fn get_versions() -> &'static [(semver::Version, Format, path::PathBuf)] {
INIT.call_once(|| {
let mut versions = find_rust_versions("tests/html");
let mut versions = Vec::new();
for format in Format::all() {
versions.append(&mut find_rust_versions(*format));
if env::var("RUSTY_MAN_GENERATE").is_ok() {
versions.push(generate_docs());
if let Some(docs) = generate_docs(*format) {
versions.push(docs);
}
}
}
unsafe {
VERSIONS = Some(versions);
@ -26,21 +53,31 @@ fn get_versions() -> &'static [(semver::Version, path::PathBuf)] {
unsafe { VERSIONS.as_ref().unwrap() }
}
fn find_rust_versions(path: impl AsRef<path::Path>) -> Vec<(semver::Version, path::PathBuf)> {
fs::read_dir(path)
fn find_rust_versions(format: Format) -> Vec<(semver::Version, Format, path::PathBuf)> {
let mut path = path::PathBuf::from("tests");
path.push(format.to_string());
if !path.is_dir() {
return Vec::new();
}
fs::read_dir(&path)
.unwrap()
.map(Result::unwrap)
.filter(|e| e.file_type().unwrap().is_dir())
.map(|e| {
(
semver::Version::parse(&e.file_name().into_string().unwrap()).unwrap(),
format,
e.path(),
)
})
.collect()
}
fn generate_docs() -> (semver::Version, path::PathBuf) {
fn generate_docs(format: Format) -> Option<(semver::Version, Format, path::PathBuf)> {
if format != Format::Html {
return None;
}
// TODO: check which rustc/rustdoc $CARGO is using
let version = rustc_version::version().unwrap();
let mut path = tempfile::tempdir().unwrap().into_path();
@ -56,25 +93,26 @@ fn generate_docs() -> (semver::Version, path::PathBuf) {
.output()
.unwrap();
path.push("doc");
(version, path)
Some((version, format, path))
}
/// Calls the given function with all paths to rustdoc documentation generated by rustdoc versions
/// that match the given requirement string.
pub fn with_rustdoc<F>(version: &str, f: F)
pub fn with_rustdoc<F>(version: &str, formats: &[Format], f: F)
where
F: Fn(&semver::Version, &path::Path),
F: Fn(&semver::Version, Format, &path::Path),
{
let version_req = semver::VersionReq::parse(version).unwrap();
let versions = get_versions();
for (version, path) in versions {
if version_req.matches(&version) {
for (version, format, path) in versions {
if version_req.matches(&version) && formats.contains(format) {
log::warn!(
"Executing test case for version {} at {}",
"Executing test case for version {} at {} (format {})",
version,
path.display()
path.display(),
format
);
f(version, &path);
f(version, *format, &path);
}
}
}

View File

@ -10,7 +10,7 @@ use std::process;
use assert_cmd::prelude::*;
use test_utils::with_rustdoc;
use test_utils::{with_rustdoc, Format};
fn run(path: impl AsRef<path::Path>, args: &[&str]) -> assert_cmd::assert::Assert {
process::Command::cargo_bin(env!("CARGO_PKG_NAME"))
@ -29,12 +29,12 @@ fn get_stdout(path: impl AsRef<path::Path>, args: &[&str]) -> String {
}
macro_rules! generate_run {
($name:ident $version:literal $args:expr) => {
($name:ident $version:literal $formats:expr; $args:expr) => {
#[test]
fn $name() {
with_rustdoc($version, |version, path| {
with_rustdoc($version, $formats, |version, format, path| {
insta::assert_snapshot!(
format!("{}_{}", version, std::stringify!($name)),
format!("{}_{}_{}", version, format, std::stringify!($name)),
get_stdout(path, $args)
);
});
@ -43,50 +43,50 @@ macro_rules! generate_run {
}
macro_rules! assert_doc {
($( $name:ident($version:literal): $item:literal ),* $(,)? ) => {
($( $name:ident($version:literal, $formats:expr): $item:literal ),* $(,)? ) => {
$(
generate_run!($name $version &[$item]);
generate_run!($name $version $formats; &[$item]);
)*
};
}
macro_rules! assert_examples {
($( $name:ident($version:literal): $item:literal ),* $(,)? ) => {
($( $name:ident($version:literal, $formats:expr): $item:literal ),* $(,)? ) => {
$(
generate_run!($name $version &["-e", $item]);
generate_run!($name $version $formats; &["-e", $item]);
)*
};
}
assert_doc![
mod_anyhow("*"): "anyhow",
macro_anyhow_anyhow("*"): "anyhow::anyhow",
macro_anyhow_ensure("*"): "anyhow::ensure",
struct_anyhow_error("<1.51.0"): "anyhow::Error",
trait_anyhow_context("*"): "anyhow::Context",
type_anyhow_result("*"): "anyhow::Result",
mod_anyhow("*", Format::all()): "anyhow",
macro_anyhow_anyhow("*", Format::all()): "anyhow::anyhow",
macro_anyhow_ensure("*", Format::all()): "anyhow::ensure",
struct_anyhow_error("<1.51.0", Format::all()): "anyhow::Error",
trait_anyhow_context("*", Format::all()): "anyhow::Context",
type_anyhow_result("*", Format::all()): "anyhow::Result",
];
assert_doc![
mod_log("*"): "log",
macro_log_debug("*"): "log::debug",
struct_log_metadata("*"): "log::Metadata",
enum_log_level("*"): "log::Level",
constant_log_static_max_level("*"): "log::STATIC_MAX_LEVEL",
trait_log_log("*"): "log::Log",
fn_log_logger("*"): "log::logger",
fn_log_set_logger_racy("*"): "log::set_logger_racy",
mod_log("*", Format::all()): "log",
macro_log_debug("*", Format::all()): "log::debug",
struct_log_metadata("*", Format::all()): "log::Metadata",
enum_log_level("*", Format::all()): "log::Level",
constant_log_static_max_level("*", Format::all()): "log::STATIC_MAX_LEVEL",
trait_log_log("*", Format::all()): "log::Log",
fn_log_logger("*", Format::all()): "log::logger",
fn_log_set_logger_racy("*", Format::all()): "log::set_logger_racy",
];
assert_doc![
mod_rand_core("*"): "rand_core",
trait_rand_core_rngcore("*"): "rand_core::RngCore",
trait_rand_core_seedablerng("*"): "rand_core::SeedableRng",
struct_rand_core_block_blockrng("*"): "rand_core::block::BlockRng",
mod_rand_core("*", Format::all()): "rand_core",
trait_rand_core_rngcore("*", Format::all()): "rand_core::RngCore",
trait_rand_core_seedablerng("*", Format::all()): "rand_core::SeedableRng",
struct_rand_core_block_blockrng("*", Format::all()): "rand_core::block::BlockRng",
];
assert_examples![
examples_mod_anyhow("*"): "anyhow",
examples_mod_log(">1.40.0"): "log",
examples_struct_rand_core_rngcore("*"): "rand_core::RngCore",
examples_mod_anyhow("*", Format::all()): "anyhow",
examples_mod_log(">1.40.0", Format::all()): "log",
examples_struct_rand_core_rngcore("*", Format::all()): "rand_core::RngCore",
];

Some files were not shown because too many files have changed in this diff Show More