mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 01:13:11 +00:00
Auto merge of #106544 - matthiaskrgr:rollup-e9prjed, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #106287 (Add some docs to `bug`, `span_bug` and `delay_span_bug`) - #106341 (refactor: clean up `errors.rs` and `error_codes_check.rs`) - #106453 (Improve include macro documentation) - #106466 (Fix rustdoc source code rendering for `#[path = "../path/to/mod.rs"]` links) - #106528 (Tiny formatting fix) - #106534 (rustdoc-gui: Use new block syntax for define-function in goml scripts) - #106542 (Add default and latest stable edition to --edition in rustc (attempt 2)) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
84f22e44c5
@ -1,3 +1,5 @@
|
||||
#### Note: this error code is no longer emitted by the compiler
|
||||
|
||||
Support for Non-Lexical Lifetimes (NLL) has been included in the Rust compiler
|
||||
since 1.31, and has been enabled on the 2015 edition since 1.36. The new borrow
|
||||
checker for NLL uncovered some bugs in the old borrow checker, which in some
|
||||
|
@ -978,6 +978,7 @@ impl Handler {
|
||||
self.inner.borrow_mut().span_bug(span, msg)
|
||||
}
|
||||
|
||||
/// For documentation on this, see `Session::delay_span_bug`.
|
||||
#[track_caller]
|
||||
pub fn delay_span_bug(
|
||||
&self,
|
||||
@ -1529,6 +1530,7 @@ impl HandlerInner {
|
||||
self.emit_diagnostic(diag.set_span(sp));
|
||||
}
|
||||
|
||||
/// For documentation on this, see `Session::delay_span_bug`.
|
||||
#[track_caller]
|
||||
fn delay_span_bug(
|
||||
&mut self,
|
||||
|
@ -1,3 +1,13 @@
|
||||
/// A macro for triggering an ICE.
|
||||
/// Calling `bug` instead of panicking will result in a nicer error message and should
|
||||
/// therefore be prefered over `panic`/`unreachable` or others.
|
||||
///
|
||||
/// If you have a span available, you should use [`span_bug`] instead.
|
||||
///
|
||||
/// If the bug should only be emitted when compilation didn't fail, [`Session::delay_span_bug`] may be useful.
|
||||
///
|
||||
/// [`Session::delay_span_bug`]: rustc_session::Session::delay_span_bug
|
||||
/// [`span_bug`]: crate::span_bug
|
||||
#[macro_export]
|
||||
macro_rules! bug {
|
||||
() => ( $crate::bug!("impossible case reached") );
|
||||
@ -8,6 +18,14 @@ macro_rules! bug {
|
||||
});
|
||||
}
|
||||
|
||||
/// A macro for triggering an ICE with a span.
|
||||
/// Calling `span_bug!` instead of panicking will result in a nicer error message and point
|
||||
/// at the code the compiler was compiling when it ICEd. This is the preferred way to trigger
|
||||
/// ICEs.
|
||||
///
|
||||
/// If the bug should only be emitted when compilation didn't fail, [`Session::delay_span_bug`] may be useful.
|
||||
///
|
||||
/// [`Session::delay_span_bug`]: rustc_session::Session::delay_span_bug
|
||||
#[macro_export]
|
||||
macro_rules! span_bug {
|
||||
($span:expr, $msg:expr) => ({ $crate::util::bug::span_bug_fmt($span, ::std::format_args!($msg)) });
|
||||
|
@ -35,8 +35,7 @@ fn opt_span_bug_fmt<S: Into<MultiSpan>>(
|
||||
(Some(tcx), None) => tcx.sess.diagnostic().bug(&msg),
|
||||
(None, _) => panic_any(msg),
|
||||
}
|
||||
});
|
||||
unreachable!();
|
||||
})
|
||||
}
|
||||
|
||||
/// A query to trigger a `delay_span_bug`. Clearly, if one has a `tcx` one can already trigger a
|
||||
|
@ -1503,12 +1503,13 @@ impl<'a> Parser<'a> {
|
||||
prior_type_ascription: self.last_type_ascription,
|
||||
});
|
||||
(lo.to(self.prev_token.span), ExprKind::MacCall(mac))
|
||||
} else if self.check(&token::OpenDelim(Delimiter::Brace)) &&
|
||||
let Some(expr) = self.maybe_parse_struct_expr(&qself, &path) {
|
||||
if qself.is_some() {
|
||||
self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
|
||||
}
|
||||
return expr;
|
||||
} else if self.check(&token::OpenDelim(Delimiter::Brace))
|
||||
&& let Some(expr) = self.maybe_parse_struct_expr(&qself, &path)
|
||||
{
|
||||
if qself.is_some() {
|
||||
self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
|
||||
}
|
||||
return expr;
|
||||
} else {
|
||||
(path.span, ExprKind::Path(qself, path))
|
||||
};
|
||||
|
@ -35,6 +35,7 @@ use std::hash::Hash;
|
||||
use std::iter;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::{self, FromStr};
|
||||
use std::sync::LazyLock;
|
||||
|
||||
pub mod sigpipe;
|
||||
|
||||
@ -1322,7 +1323,12 @@ mod opt {
|
||||
unstable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
|
||||
}
|
||||
}
|
||||
|
||||
static EDITION_STRING: LazyLock<String> = LazyLock::new(|| {
|
||||
format!(
|
||||
"Specify which edition of the compiler to use when compiling code. \
|
||||
The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}."
|
||||
)
|
||||
});
|
||||
/// Returns the "short" subset of the rustc command line options,
|
||||
/// including metadata for each option, such as whether the option is
|
||||
/// part of the stable long-term interface for rustc.
|
||||
@ -1355,7 +1361,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
|
||||
opt::opt_s(
|
||||
"",
|
||||
"edition",
|
||||
"Specify which edition of the compiler to use when compiling code.",
|
||||
&*EDITION_STRING,
|
||||
EDITION_NAME_LIST,
|
||||
),
|
||||
opt::multi_s(
|
||||
|
@ -590,7 +590,19 @@ impl Session {
|
||||
pub fn warn(&self, msg: impl Into<DiagnosticMessage>) {
|
||||
self.diagnostic().warn(msg)
|
||||
}
|
||||
/// Delay a span_bug() call until abort_if_errors()
|
||||
|
||||
/// Ensures that compilation cannot succeed.
|
||||
///
|
||||
/// If this function has been called but no errors have been emitted and
|
||||
/// compilation succeeds, it will cause an internal compiler error (ICE).
|
||||
///
|
||||
/// This can be used in code paths that should never run on successful compilations.
|
||||
/// For example, it can be used to create an [`ErrorGuaranteed`]
|
||||
/// (but you should prefer threading through the [`ErrorGuaranteed`] from an error emission directly).
|
||||
///
|
||||
/// If no span is available, use [`DUMMY_SP`].
|
||||
///
|
||||
/// [`DUMMY_SP`]: rustc_span::DUMMY_SP
|
||||
#[track_caller]
|
||||
pub fn delay_span_bug<S: Into<MultiSpan>>(
|
||||
&self,
|
||||
|
@ -1315,22 +1315,41 @@ pub(crate) mod builtin {
|
||||
|
||||
/// Parses a file as an expression or an item according to the context.
|
||||
///
|
||||
/// The file is located relative to the current file (similarly to how
|
||||
/// modules are found). The provided path is interpreted in a platform-specific
|
||||
/// way at compile time. So, for instance, an invocation with a Windows path
|
||||
/// containing backslashes `\` would not compile correctly on Unix.
|
||||
/// **Warning**: For multi-file Rust projects, the `include!` macro is probably not what you
|
||||
/// are looking for. Usually, multi-file Rust projects use
|
||||
/// [modules](https://doc.rust-lang.org/reference/items/modules.html). Multi-file projects and
|
||||
/// modules are explained in the Rust-by-Example book
|
||||
/// [here](https://doc.rust-lang.org/rust-by-example/mod/split.html) and the module system is
|
||||
/// explained in the Rust Book
|
||||
/// [here](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html).
|
||||
///
|
||||
/// Using this macro is often a bad idea, because if the file is
|
||||
/// parsed as an expression, it is going to be placed in the
|
||||
/// surrounding code unhygienically. This could result in variables
|
||||
/// or functions being different from what the file expected if
|
||||
/// there are variables or functions that have the same name in
|
||||
/// the current file.
|
||||
/// The included file is placed in the surrounding code
|
||||
/// [unhygienically](https://doc.rust-lang.org/reference/macros-by-example.html#hygiene). If
|
||||
/// the included file is parsed as an expression and variables or functions share names across
|
||||
/// both files, it could result in variables or functions being different from what the
|
||||
/// included file expected.
|
||||
///
|
||||
/// The included file is located relative to the current file (similarly to how modules are
|
||||
/// found). The provided path is interpreted in a platform-specific way at compile time. So,
|
||||
/// for instance, an invocation with a Windows path containing backslashes `\` would not
|
||||
/// compile correctly on Unix.
|
||||
///
|
||||
/// # Uses
|
||||
///
|
||||
/// The `include!` macro is primarily used for two purposes. It is used to include
|
||||
/// documentation that is written in a separate file and it is used to include [build artifacts
|
||||
/// usually as a result from the `build.rs`
|
||||
/// script](https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script).
|
||||
///
|
||||
/// When using the `include` macro to include stretches of documentation, remember that the
|
||||
/// included file still needs to be a valid rust syntax. It is also possible to
|
||||
/// use the [`include_str`] macro as `#![doc = include_str!("...")]` (at the module level) or
|
||||
/// `#[doc = include_str!("...")]` (at the item level) to include documentation from a plain
|
||||
/// text or markdown file.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Assume there are two files in the same directory with the following
|
||||
/// contents:
|
||||
/// Assume there are two files in the same directory with the following contents:
|
||||
///
|
||||
/// File 'monkeys.in':
|
||||
///
|
||||
|
@ -1 +1 @@
|
||||
0.13.4
|
||||
0.14.1
|
@ -309,7 +309,7 @@ impl<'tcx> Context<'tcx> {
|
||||
|
||||
pub(crate) fn href_from_span(&self, span: clean::Span, with_lines: bool) -> Option<String> {
|
||||
let mut root = self.root_path();
|
||||
let mut path = String::new();
|
||||
let mut path: String;
|
||||
let cnum = span.cnum(self.sess());
|
||||
|
||||
// We can safely ignore synthetic `SourceFile`s.
|
||||
@ -340,10 +340,24 @@ impl<'tcx> Context<'tcx> {
|
||||
ExternalLocation::Unknown => return None,
|
||||
};
|
||||
|
||||
sources::clean_path(&src_root, file, false, |component| {
|
||||
path.push_str(&component.to_string_lossy());
|
||||
let href = RefCell::new(PathBuf::new());
|
||||
sources::clean_path(
|
||||
&src_root,
|
||||
file,
|
||||
|component| {
|
||||
href.borrow_mut().push(component);
|
||||
},
|
||||
|| {
|
||||
href.borrow_mut().pop();
|
||||
},
|
||||
);
|
||||
|
||||
path = href.into_inner().to_string_lossy().to_string();
|
||||
|
||||
if let Some(c) = path.as_bytes().last() && *c != b'/' {
|
||||
path.push('/');
|
||||
});
|
||||
}
|
||||
|
||||
let mut fname = file.file_name().expect("source has no filename").to_os_string();
|
||||
fname.push(".html");
|
||||
path.push_str(&fname.to_string_lossy());
|
||||
|
@ -1,8 +1,9 @@
|
||||
use std::cell::RefCell;
|
||||
use std::fs::{self, File};
|
||||
use std::io::prelude::*;
|
||||
use std::io::{self, BufReader};
|
||||
use std::path::{Component, Path};
|
||||
use std::rc::Rc;
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
use itertools::Itertools;
|
||||
use rustc_data_structures::flock;
|
||||
@ -184,23 +185,26 @@ pub(super) fn write_shared(
|
||||
|
||||
use std::ffi::OsString;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
struct Hierarchy {
|
||||
parent: Weak<Self>,
|
||||
elem: OsString,
|
||||
children: FxHashMap<OsString, Hierarchy>,
|
||||
elems: FxHashSet<OsString>,
|
||||
children: RefCell<FxHashMap<OsString, Rc<Self>>>,
|
||||
elems: RefCell<FxHashSet<OsString>>,
|
||||
}
|
||||
|
||||
impl Hierarchy {
|
||||
fn new(elem: OsString) -> Hierarchy {
|
||||
Hierarchy { elem, children: FxHashMap::default(), elems: FxHashSet::default() }
|
||||
fn with_parent(elem: OsString, parent: &Rc<Self>) -> Self {
|
||||
Self { elem, parent: Rc::downgrade(parent), ..Self::default() }
|
||||
}
|
||||
|
||||
fn to_json_string(&self) -> String {
|
||||
let mut subs: Vec<&Hierarchy> = self.children.values().collect();
|
||||
let borrow = self.children.borrow();
|
||||
let mut subs: Vec<_> = borrow.values().collect();
|
||||
subs.sort_unstable_by(|a, b| a.elem.cmp(&b.elem));
|
||||
let mut files = self
|
||||
.elems
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|s| format!("\"{}\"", s.to_str().expect("invalid osstring conversion")))
|
||||
.collect::<Vec<_>>();
|
||||
@ -220,36 +224,52 @@ pub(super) fn write_shared(
|
||||
files = files
|
||||
)
|
||||
}
|
||||
|
||||
fn add_path(self: &Rc<Self>, path: &Path) {
|
||||
let mut h = Rc::clone(&self);
|
||||
let mut elems = path
|
||||
.components()
|
||||
.filter_map(|s| match s {
|
||||
Component::Normal(s) => Some(s.to_owned()),
|
||||
Component::ParentDir => Some(OsString::from("..")),
|
||||
_ => None,
|
||||
})
|
||||
.peekable();
|
||||
loop {
|
||||
let cur_elem = elems.next().expect("empty file path");
|
||||
if cur_elem == ".." {
|
||||
if let Some(parent) = h.parent.upgrade() {
|
||||
h = parent;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if elems.peek().is_none() {
|
||||
h.elems.borrow_mut().insert(cur_elem);
|
||||
break;
|
||||
} else {
|
||||
let entry = Rc::clone(
|
||||
h.children
|
||||
.borrow_mut()
|
||||
.entry(cur_elem.clone())
|
||||
.or_insert_with(|| Rc::new(Self::with_parent(cur_elem, &h))),
|
||||
);
|
||||
h = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cx.include_sources {
|
||||
let mut hierarchy = Hierarchy::new(OsString::new());
|
||||
let hierarchy = Rc::new(Hierarchy::default());
|
||||
for source in cx
|
||||
.shared
|
||||
.local_sources
|
||||
.iter()
|
||||
.filter_map(|p| p.0.strip_prefix(&cx.shared.src_root).ok())
|
||||
{
|
||||
let mut h = &mut hierarchy;
|
||||
let mut elems = source
|
||||
.components()
|
||||
.filter_map(|s| match s {
|
||||
Component::Normal(s) => Some(s.to_owned()),
|
||||
_ => None,
|
||||
})
|
||||
.peekable();
|
||||
loop {
|
||||
let cur_elem = elems.next().expect("empty file path");
|
||||
if elems.peek().is_none() {
|
||||
h.elems.insert(cur_elem);
|
||||
break;
|
||||
} else {
|
||||
let e = cur_elem.clone();
|
||||
h = h.children.entry(cur_elem.clone()).or_insert_with(|| Hierarchy::new(e));
|
||||
}
|
||||
}
|
||||
hierarchy.add_path(source);
|
||||
}
|
||||
|
||||
let hierarchy = Rc::try_unwrap(hierarchy).unwrap();
|
||||
let dst = cx.dst.join(&format!("source-files{}.js", cx.shared.resource_suffix));
|
||||
let make_sources = || {
|
||||
let (mut all_sources, _krates) =
|
||||
|
@ -13,6 +13,7 @@ use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::FileName;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
@ -72,12 +73,22 @@ impl LocalSourcesCollector<'_, '_> {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut href = String::new();
|
||||
clean_path(self.src_root, &p, false, |component| {
|
||||
href.push_str(&component.to_string_lossy());
|
||||
href.push('/');
|
||||
});
|
||||
let href = RefCell::new(PathBuf::new());
|
||||
clean_path(
|
||||
&self.src_root,
|
||||
&p,
|
||||
|component| {
|
||||
href.borrow_mut().push(component);
|
||||
},
|
||||
|| {
|
||||
href.borrow_mut().pop();
|
||||
},
|
||||
);
|
||||
|
||||
let mut href = href.into_inner().to_string_lossy().to_string();
|
||||
if let Some(c) = href.as_bytes().last() && *c != b'/' {
|
||||
href.push('/');
|
||||
}
|
||||
let mut src_fname = p.file_name().expect("source has no filename").to_os_string();
|
||||
src_fname.push(".html");
|
||||
href.push_str(&src_fname.to_string_lossy());
|
||||
@ -180,13 +191,28 @@ impl SourceCollector<'_, '_> {
|
||||
|
||||
let shared = Rc::clone(&self.cx.shared);
|
||||
// Create the intermediate directories
|
||||
let mut cur = self.dst.clone();
|
||||
let mut root_path = String::from("../../");
|
||||
clean_path(&shared.src_root, &p, false, |component| {
|
||||
cur.push(component);
|
||||
root_path.push_str("../");
|
||||
});
|
||||
let cur = RefCell::new(PathBuf::new());
|
||||
let root_path = RefCell::new(PathBuf::new());
|
||||
|
||||
clean_path(
|
||||
&shared.src_root,
|
||||
&p,
|
||||
|component| {
|
||||
cur.borrow_mut().push(component);
|
||||
root_path.borrow_mut().push("..");
|
||||
},
|
||||
|| {
|
||||
cur.borrow_mut().pop();
|
||||
root_path.borrow_mut().pop();
|
||||
},
|
||||
);
|
||||
|
||||
let root_path = PathBuf::from("../../").join(root_path.into_inner());
|
||||
let mut root_path = root_path.to_string_lossy();
|
||||
if let Some(c) = root_path.as_bytes().last() && *c != b'/' {
|
||||
root_path += "/";
|
||||
}
|
||||
let mut cur = self.dst.join(cur.into_inner());
|
||||
shared.ensure_dir(&cur)?;
|
||||
|
||||
let src_fname = p.file_name().expect("source has no filename").to_os_string();
|
||||
@ -232,11 +258,13 @@ impl SourceCollector<'_, '_> {
|
||||
/// Takes a path to a source file and cleans the path to it. This canonicalizes
|
||||
/// things like ".." to components which preserve the "top down" hierarchy of a
|
||||
/// static HTML tree. Each component in the cleaned path will be passed as an
|
||||
/// argument to `f`. The very last component of the path (ie the file name) will
|
||||
/// be passed to `f` if `keep_filename` is true, and ignored otherwise.
|
||||
pub(crate) fn clean_path<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F)
|
||||
/// argument to `f`. The very last component of the path (ie the file name) is ignored.
|
||||
/// If a `..` is encountered, the `parent` closure will be called to allow the callee to
|
||||
/// handle it.
|
||||
pub(crate) fn clean_path<F, P>(src_root: &Path, p: &Path, mut f: F, mut parent: P)
|
||||
where
|
||||
F: FnMut(&OsStr),
|
||||
P: FnMut(),
|
||||
{
|
||||
// make it relative, if possible
|
||||
let p = p.strip_prefix(src_root).unwrap_or(p);
|
||||
@ -244,12 +272,12 @@ where
|
||||
let mut iter = p.components().peekable();
|
||||
|
||||
while let Some(c) = iter.next() {
|
||||
if !keep_filename && iter.peek().is_none() {
|
||||
if iter.peek().is_none() {
|
||||
break;
|
||||
}
|
||||
|
||||
match c {
|
||||
Component::ParentDir => f("up".as_ref()),
|
||||
Component::ParentDir => parent(),
|
||||
Component::Normal(c) => f(c),
|
||||
_ => continue,
|
||||
}
|
||||
|
@ -3,70 +3,72 @@
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, main_color, title_color, fqn_color, fqn_type_color, src_link_color, sidebar_link_color),
|
||||
[
|
||||
("goto", "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html"),
|
||||
block {
|
||||
goto: "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html"
|
||||
// This is needed to ensure that the text color is computed.
|
||||
("show-text", true),
|
||||
show-text: true
|
||||
|
||||
// Setting the theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
// We reload the page so the local storage settings are being used.
|
||||
("reload"),
|
||||
reload:
|
||||
|
||||
("assert-css", ("#toggle-all-docs", {"color": |main_color|})),
|
||||
("assert-css", (".fqn a:nth-of-type(1)", {"color": |fqn_color|})),
|
||||
("assert-css", (".fqn a:nth-of-type(2)", {"color": |fqn_type_color|})),
|
||||
("assert-css", (
|
||||
assert-css: ("#toggle-all-docs", {"color": |main_color|})
|
||||
assert-css: (".fqn a:nth-of-type(1)", {"color": |fqn_color|})
|
||||
assert-css: (".fqn a:nth-of-type(2)", {"color": |fqn_type_color|})
|
||||
assert-css: (
|
||||
".rightside .srclink",
|
||||
{"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|},
|
||||
ALL,
|
||||
)),
|
||||
(
|
||||
"compare-elements-css",
|
||||
(".rightside .srclink", ".rightside.srclink", ["color", "text-decoration"]),
|
||||
),
|
||||
(
|
||||
"compare-elements-css",
|
||||
(".main-heading .srclink", ".rightside.srclink", ["color", "text-decoration"]),
|
||||
),
|
||||
)
|
||||
compare-elements-css: (
|
||||
".rightside .srclink",
|
||||
".rightside.srclink",
|
||||
["color", "text-decoration"],
|
||||
)
|
||||
compare-elements-css: (
|
||||
".main-heading .srclink",
|
||||
".rightside.srclink",
|
||||
["color", "text-decoration"],
|
||||
)
|
||||
|
||||
("move-cursor-to", ".main-heading .srclink"),
|
||||
("assert-css", (
|
||||
move-cursor-to: ".main-heading .srclink"
|
||||
assert-css: (
|
||||
".main-heading .srclink",
|
||||
{"color": |src_link_color|, "text-decoration": "underline solid " + |src_link_color|},
|
||||
)),
|
||||
("move-cursor-to", ".impl-items .rightside .srclink"),
|
||||
("assert-css", (
|
||||
)
|
||||
move-cursor-to: ".impl-items .rightside .srclink"
|
||||
assert-css: (
|
||||
".impl-items .rightside .srclink",
|
||||
{"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|},
|
||||
)),
|
||||
("move-cursor-to", ".impl-items .rightside.srclink"),
|
||||
("assert-css", (
|
||||
)
|
||||
move-cursor-to: ".impl-items .rightside.srclink"
|
||||
assert-css: (
|
||||
".impl-items .rightside.srclink",
|
||||
{"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|},
|
||||
)),
|
||||
)
|
||||
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"),
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"
|
||||
// Since we changed page, we need to set the theme again.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
// We reload the page so the local storage settings are being used.
|
||||
("reload"),
|
||||
reload:
|
||||
|
||||
("assert-css", ("#top-doc-prose-title", {"color": |title_color|})),
|
||||
assert-css: ("#top-doc-prose-title", {"color": |title_color|})
|
||||
|
||||
("assert-css", (".sidebar a", {"color": |sidebar_link_color|})),
|
||||
("assert-css", ("h1.fqn a", {"color": |title_color|})),
|
||||
assert-css: (".sidebar a", {"color": |sidebar_link_color|})
|
||||
assert-css: ("h1.fqn a", {"color": |title_color|})
|
||||
|
||||
// We move the cursor over the "Implementations" title so the anchor is displayed.
|
||||
("move-cursor-to", "h2#implementations"),
|
||||
("assert-css", ("h2#implementations a.anchor", {"color": |main_color|})),
|
||||
move-cursor-to: "h2#implementations"
|
||||
assert-css: ("h2#implementations a.anchor", {"color": |main_color|})
|
||||
|
||||
// Same thing with the impl block title.
|
||||
("move-cursor-to", "#impl-HeavilyDocumentedStruct"),
|
||||
("assert-css", ("#impl-HeavilyDocumentedStruct a.anchor", {"color": |main_color|})),
|
||||
move-cursor-to: "#impl-HeavilyDocumentedStruct"
|
||||
assert-css: ("#impl-HeavilyDocumentedStruct a.anchor", {"color": |main_color|})
|
||||
|
||||
("assert-css", ("#title-for-struct-impl-item-doc", {"margin-left": "0px"})),
|
||||
],
|
||||
assert-css: ("#title-for-struct-impl-item-doc", {"margin-left": "0px"})
|
||||
},
|
||||
)
|
||||
|
||||
call-function: (
|
||||
|
@ -9,14 +9,14 @@ show-text: true
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, doc_code_color, doc_inline_code_color),
|
||||
[
|
||||
block {
|
||||
// Set the theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
// We reload the page so the local storage settings are being used.
|
||||
("reload"),
|
||||
("assert-css", (".docblock pre > code", {"color": |doc_code_color|}, ALL)),
|
||||
("assert-css", (".docblock > p > code", {"color": |doc_inline_code_color|}, ALL)),
|
||||
],
|
||||
reload:
|
||||
assert-css: (".docblock pre > code", {"color": |doc_code_color|}, ALL)
|
||||
assert-css: (".docblock > p > code", {"color": |doc_inline_code_color|}, ALL)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-colors", ("ayu", "rgb(230, 225, 207)", "rgb(255, 180, 84)"))
|
||||
|
@ -5,32 +5,32 @@ show-text: true
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, background, color, border),
|
||||
[
|
||||
block {
|
||||
// Setting the theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
|
||||
// compile_fail block
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".docblock .example-wrap.compile_fail .tooltip",
|
||||
{"color": "rgba(255, 0, 0, 0.5)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.compile_fail",
|
||||
{"border-left": "2px solid rgba(255, 0, 0, 0.5)"},
|
||||
)),
|
||||
)
|
||||
|
||||
("move-cursor-to", ".docblock .example-wrap.compile_fail .tooltip"),
|
||||
move-cursor-to: ".docblock .example-wrap.compile_fail .tooltip"
|
||||
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".docblock .example-wrap.compile_fail .tooltip",
|
||||
{"color": "rgb(255, 0, 0)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.compile_fail",
|
||||
{"border-left": "2px solid rgb(255, 0, 0)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.compile_fail .tooltip::after",
|
||||
{
|
||||
"content": '"This example deliberately fails to compile"',
|
||||
@ -39,37 +39,37 @@ define-function: (
|
||||
"color": |color|,
|
||||
"border": "1px solid " + |border|,
|
||||
},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.compile_fail .tooltip::before",
|
||||
{
|
||||
"border-width": "5px",
|
||||
"border-style": "solid",
|
||||
"border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)",
|
||||
},
|
||||
)),
|
||||
)
|
||||
|
||||
// should_panic block
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".docblock .example-wrap.should_panic .tooltip",
|
||||
{"color": "rgba(255, 0, 0, 0.5)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.should_panic",
|
||||
{"border-left": "2px solid rgba(255, 0, 0, 0.5)"},
|
||||
)),
|
||||
)
|
||||
|
||||
("move-cursor-to", ".docblock .example-wrap.should_panic .tooltip"),
|
||||
move-cursor-to: ".docblock .example-wrap.should_panic .tooltip"
|
||||
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".docblock .example-wrap.should_panic .tooltip",
|
||||
{"color": "rgb(255, 0, 0)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.should_panic",
|
||||
{"border-left": "2px solid rgb(255, 0, 0)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.should_panic .tooltip::after",
|
||||
{
|
||||
"content": '"This example panics"',
|
||||
@ -78,37 +78,37 @@ define-function: (
|
||||
"color": |color|,
|
||||
"border": "1px solid " + |border|,
|
||||
},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.should_panic .tooltip::before",
|
||||
{
|
||||
"border-width": "5px",
|
||||
"border-style": "solid",
|
||||
"border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)",
|
||||
},
|
||||
)),
|
||||
)
|
||||
|
||||
// ignore block
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".docblock .example-wrap.ignore .tooltip",
|
||||
{"color": "rgba(255, 142, 0, 0.6)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.ignore",
|
||||
{"border-left": "2px solid rgba(255, 142, 0, 0.6)"},
|
||||
)),
|
||||
)
|
||||
|
||||
("move-cursor-to", ".docblock .example-wrap.ignore .tooltip"),
|
||||
move-cursor-to: ".docblock .example-wrap.ignore .tooltip"
|
||||
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".docblock .example-wrap.ignore .tooltip",
|
||||
{"color": "rgb(255, 142, 0)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.ignore",
|
||||
{"border-left": "2px solid rgb(255, 142, 0)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.ignore .tooltip::after",
|
||||
{
|
||||
"content": '"This example is not tested"',
|
||||
@ -117,16 +117,16 @@ define-function: (
|
||||
"color": |color|,
|
||||
"border": "1px solid " + |border|,
|
||||
},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".docblock .example-wrap.ignore .tooltip::before",
|
||||
{
|
||||
"border-width": "5px",
|
||||
"border-style": "solid",
|
||||
"border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)",
|
||||
},
|
||||
)),
|
||||
],
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-colors", {
|
||||
|
@ -11,19 +11,19 @@ assert-false: "pre.example-line-numbers"
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, color),
|
||||
[
|
||||
block {
|
||||
// We now set the setting to show the line numbers on code examples.
|
||||
("local-storage", {
|
||||
local-storage: {
|
||||
"rustdoc-theme": |theme|,
|
||||
"rustdoc-use-system-theme": "false",
|
||||
"rustdoc-line-numbers": "true"
|
||||
}),
|
||||
}
|
||||
// We reload to make the line numbers appear and change theme.
|
||||
("reload"),
|
||||
reload:
|
||||
// We wait for them to be added into the DOM by the JS...
|
||||
("wait-for", "pre.example-line-numbers"),
|
||||
wait-for: "pre.example-line-numbers"
|
||||
// If the test didn't fail, it means that it was found!
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
"pre.example-line-numbers",
|
||||
{
|
||||
"color": |color|,
|
||||
@ -32,8 +32,8 @@ define-function: (
|
||||
"text-align": "right",
|
||||
},
|
||||
ALL,
|
||||
)),
|
||||
],
|
||||
)
|
||||
},
|
||||
)
|
||||
call-function: ("check-colors", {
|
||||
"theme": "ayu",
|
||||
|
@ -7,32 +7,32 @@ compare-elements-css: (".impl-items .docblock table td", ".top-doc .docblock tab
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, border_color, zebra_stripe_color),
|
||||
[
|
||||
("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}),
|
||||
("reload"),
|
||||
("assert-css", (".top-doc .docblock table tbody tr:nth-child(1)", {
|
||||
block {
|
||||
local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}
|
||||
reload:
|
||||
assert-css: (".top-doc .docblock table tbody tr:nth-child(1)", {
|
||||
"background-color": "rgba(0, 0, 0, 0)",
|
||||
})),
|
||||
("assert-css", (".top-doc .docblock table tbody tr:nth-child(2)", {
|
||||
})
|
||||
assert-css: (".top-doc .docblock table tbody tr:nth-child(2)", {
|
||||
"background-color": |zebra_stripe_color|,
|
||||
})),
|
||||
("assert-css", (".top-doc .docblock table tbody tr:nth-child(3)", {
|
||||
})
|
||||
assert-css: (".top-doc .docblock table tbody tr:nth-child(3)", {
|
||||
"background-color": "rgba(0, 0, 0, 0)",
|
||||
})),
|
||||
("assert-css", (".top-doc .docblock table tbody tr:nth-child(4)", {
|
||||
})
|
||||
assert-css: (".top-doc .docblock table tbody tr:nth-child(4)", {
|
||||
"background-color": |zebra_stripe_color|,
|
||||
})),
|
||||
("assert-css", (".top-doc .docblock table td", {
|
||||
})
|
||||
assert-css: (".top-doc .docblock table td", {
|
||||
"border-style": "solid",
|
||||
"border-width": "1px",
|
||||
"border-color": |border_color|,
|
||||
})),
|
||||
("assert-css", (".top-doc .docblock table th", {
|
||||
})
|
||||
assert-css: (".top-doc .docblock table th", {
|
||||
"border-style": "solid",
|
||||
"border-width": "1px",
|
||||
"border-color": |border_color|,
|
||||
})),
|
||||
]
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
call-function: ("check-colors", {
|
||||
|
@ -3,39 +3,39 @@
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, color, code_header_color, focus_background_color, headings_color),
|
||||
[
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"),
|
||||
block {
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
|
||||
// This is needed so that the text color is computed.
|
||||
("show-text", true),
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("assert-css", (
|
||||
show-text: true
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
assert-css: (
|
||||
".impl",
|
||||
{"color": |color|, "background-color": "rgba(0, 0, 0, 0)"},
|
||||
ALL,
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".impl .code-header",
|
||||
{"color": |code_header_color|, "background-color": "rgba(0, 0, 0, 0)"},
|
||||
ALL,
|
||||
)),
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html#impl-Foo"),
|
||||
("assert-css", (
|
||||
)
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html#impl-Foo"
|
||||
assert-css: (
|
||||
"#impl-Foo",
|
||||
{"color": |color|, "background-color": |focus_background_color|},
|
||||
)),
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html#method.must_use"),
|
||||
("assert-css", (
|
||||
)
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html#method.must_use"
|
||||
assert-css: (
|
||||
"#method\.must_use",
|
||||
{"color": |color|, "background-color": |focus_background_color|},
|
||||
ALL,
|
||||
)),
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/index.html"),
|
||||
("assert-css", (".small-section-header a", {"color": |color|}, ALL)),
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"),
|
||||
)
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
assert-css: (".small-section-header a", {"color": |color|}, ALL)
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"
|
||||
// We select headings (h2, h3, h...).
|
||||
("assert-css", (".docblock > :not(p) > a", {"color": |headings_color|}, ALL)),
|
||||
],
|
||||
assert-css: (".docblock > :not(p) > a", {"color": |headings_color|}, ALL)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: (
|
||||
|
@ -157,38 +157,38 @@ goto: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, heading_color, small_heading_color, heading_border_color),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("assert-css", (
|
||||
block {
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
assert-css: (
|
||||
".top-doc .docblock h2",
|
||||
{"color": |heading_color|, "border-bottom": "1px solid " + |heading_border_color|},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".top-doc .docblock h3",
|
||||
{"color": |heading_color|, "border-bottom": "1px solid " + |heading_border_color|},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".top-doc .docblock h4",
|
||||
{"color": |heading_color|, "border-bottom": "1px solid " + |heading_border_color|},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".top-doc .docblock h5",
|
||||
{"color": |small_heading_color|, "border-bottom-width": "0px"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
"#implementations-list .docblock h4",
|
||||
{"color": |heading_color|, "border-bottom-width": "0px"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
"#implementations-list .docblock h5",
|
||||
{"color": |small_heading_color|, "border-bottom-width": "0px"},
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
"#implementations-list .docblock h6",
|
||||
{"color": |small_heading_color|, "border-bottom-width": "0px"},
|
||||
)),
|
||||
],
|
||||
)
|
||||
},
|
||||
)
|
||||
call-function: (
|
||||
"check-colors",
|
||||
@ -221,11 +221,11 @@ call-function: (
|
||||
define-function: (
|
||||
"check-since-color",
|
||||
(theme),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|}),
|
||||
("reload"),
|
||||
("assert-css", (".since", {"color": "rgb(128, 128, 128)"}, ALL)),
|
||||
],
|
||||
block {
|
||||
local-storage: {"rustdoc-theme": |theme|}
|
||||
reload:
|
||||
assert-css: (".since", {"color": "rgb(128, 128, 128)"}, ALL)
|
||||
},
|
||||
)
|
||||
|
||||
goto: "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html"
|
||||
|
@ -18,17 +18,17 @@ show-text: true
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, color, background, box_shadow),
|
||||
[
|
||||
block {
|
||||
// Setting the theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
// We reload the page so the local storage settings are being used.
|
||||
("reload"),
|
||||
("assert-css", ("#help kbd", {
|
||||
reload:
|
||||
assert-css: ("#help kbd", {
|
||||
"color": |color|,
|
||||
"background-color": |background|,
|
||||
"box-shadow": |box_shadow| + " 0px -1px 0px 0px inset",
|
||||
}, ALL)),
|
||||
],
|
||||
}, ALL)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-colors", {
|
||||
|
@ -21,24 +21,24 @@ define-function: (
|
||||
comment,
|
||||
doc_comment,
|
||||
),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("assert-css", ("pre.rust .kw", {"color": |kw|}, ALL)),
|
||||
("assert-css", ("pre.rust .kw-2", {"color": |kw2|}, ALL)),
|
||||
("assert-css", ("pre.rust .prelude-ty", {"color": |prelude_ty|}, ALL)),
|
||||
("assert-css", ("pre.rust .prelude-val", {"color": |prelude_val|}, ALL)),
|
||||
("assert-css", ("pre.rust .lifetime", {"color": |lifetime|}, ALL)),
|
||||
("assert-css", ("pre.rust .number", {"color": |number|}, ALL)),
|
||||
("assert-css", ("pre.rust .string", {"color": |string|}, ALL)),
|
||||
("assert-css", ("pre.rust .bool-val", {"color": |bool_val|}, ALL)),
|
||||
("assert-css", ("pre.rust .self", {"color": |self|}, ALL)),
|
||||
("assert-css", ("pre.rust .attr", {"color": |attr|}, ALL)),
|
||||
("assert-css", ("pre.rust .macro", {"color": |macro|}, ALL)),
|
||||
("assert-css", ("pre.rust .question-mark", {"color": |question_mark|}, ALL)),
|
||||
("assert-css", ("pre.rust .comment", {"color": |comment|}, ALL)),
|
||||
("assert-css", ("pre.rust .doccomment", {"color": |doc_comment|}, ALL)),
|
||||
],
|
||||
block {
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
assert-css: ("pre.rust .kw", {"color": |kw|}, ALL)
|
||||
assert-css: ("pre.rust .kw-2", {"color": |kw2|}, ALL)
|
||||
assert-css: ("pre.rust .prelude-ty", {"color": |prelude_ty|}, ALL)
|
||||
assert-css: ("pre.rust .prelude-val", {"color": |prelude_val|}, ALL)
|
||||
assert-css: ("pre.rust .lifetime", {"color": |lifetime|}, ALL)
|
||||
assert-css: ("pre.rust .number", {"color": |number|}, ALL)
|
||||
assert-css: ("pre.rust .string", {"color": |string|}, ALL)
|
||||
assert-css: ("pre.rust .bool-val", {"color": |bool_val|}, ALL)
|
||||
assert-css: ("pre.rust .self", {"color": |self|}, ALL)
|
||||
assert-css: ("pre.rust .attr", {"color": |attr|}, ALL)
|
||||
assert-css: ("pre.rust .macro", {"color": |macro|}, ALL)
|
||||
assert-css: ("pre.rust .question-mark", {"color": |question_mark|}, ALL)
|
||||
assert-css: ("pre.rust .comment", {"color": |comment|}, ALL)
|
||||
assert-css: ("pre.rust .doccomment", {"color": |doc_comment|}, ALL)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-colors", {
|
||||
|
@ -17,22 +17,23 @@ define-function: (
|
||||
fn_color,
|
||||
assoc_type_color,
|
||||
),
|
||||
[
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/struct.WithGenerics.html"),
|
||||
("show-text", true),
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("assert-css", (".item-decl .code-attribute", {"color": |attr_color|}, ALL)),
|
||||
("assert-css", (".item-decl .trait", {"color": |trait_color|}, ALL)),
|
||||
block {
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/struct.WithGenerics.html"
|
||||
show-text: true
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
assert-css: (".item-decl .code-attribute", {"color": |attr_color|}, ALL)
|
||||
assert-css: (".item-decl .trait", {"color": |trait_color|}, ALL)
|
||||
// We need to add `code` here because otherwise it would select the parent too.
|
||||
("assert-css", (".item-decl code .struct", {"color": |struct_color|}, ALL)),
|
||||
("assert-css", (".item-decl .enum", {"color": |enum_color|}, ALL)),
|
||||
("assert-css", (".item-decl .primitive", {"color": |primitive_color|}, ALL)),
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/trait.TraitWithoutGenerics.html"),
|
||||
("assert-css", (".item-decl .constant", {"color": |constant_color|}, ALL)),
|
||||
("assert-css", (".item-decl .fn", {"color": |fn_color|}, ALL)),
|
||||
("assert-css", (".item-decl .associatedtype", {"color": |assoc_type_color|}, ALL)),
|
||||
],
|
||||
assert-css: (".item-decl code .struct", {"color": |struct_color|}, ALL)
|
||||
assert-css: (".item-decl .enum", {"color": |enum_color|}, ALL)
|
||||
assert-css: (".item-decl .primitive", {"color": |primitive_color|}, ALL)
|
||||
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/trait.TraitWithoutGenerics.html"
|
||||
assert-css: (".item-decl .constant", {"color": |constant_color|}, ALL)
|
||||
assert-css: (".item-decl .fn", {"color": |fn_color|}, ALL)
|
||||
assert-css: (".item-decl .associatedtype", {"color": |assoc_type_color|}, ALL)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: (
|
||||
|
@ -4,17 +4,17 @@ goto: "file://" + |DOC_PATH| + "/src/link_to_definition/lib.rs.html"
|
||||
define-function: (
|
||||
"check-background-color",
|
||||
(theme, background_color),
|
||||
[
|
||||
block {
|
||||
// Set the theme.
|
||||
("local-storage", { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }),
|
||||
local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }
|
||||
// We reload the page so the local storage settings are being used.
|
||||
("reload"),
|
||||
("assert-css", (
|
||||
reload:
|
||||
assert-css: (
|
||||
"body.source .example-wrap pre.rust a",
|
||||
{"background-color": |background_color|},
|
||||
ALL,
|
||||
)),
|
||||
],
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-background-color", ("ayu", "rgb(51, 51, 51)"))
|
||||
|
@ -8,29 +8,29 @@ define-function: (
|
||||
"check-colors",
|
||||
(theme, mod, macro, struct, enum, trait, fn, type, union, keyword,
|
||||
sidebar, sidebar_current, sidebar_current_background),
|
||||
[
|
||||
("local-storage", {
|
||||
block {
|
||||
local-storage: {
|
||||
"rustdoc-theme": |theme|,
|
||||
"rustdoc-use-system-theme": "false",
|
||||
}),
|
||||
("reload"),
|
||||
}
|
||||
reload:
|
||||
// Checking results colors.
|
||||
("assert-css", (".item-table .mod", {"color": |mod|}, ALL)),
|
||||
("assert-css", (".item-table .macro", {"color": |macro|}, ALL)),
|
||||
("assert-css", (".item-table .struct", {"color": |struct|}, ALL)),
|
||||
("assert-css", (".item-table .enum", {"color": |enum|}, ALL)),
|
||||
("assert-css", (".item-table .trait", {"color": |trait|}, ALL)),
|
||||
("assert-css", (".item-table .fn", {"color": |fn|}, ALL)),
|
||||
("assert-css", (".item-table .type", {"color": |type|}, ALL)),
|
||||
("assert-css", (".item-table .union", {"color": |union|}, ALL)),
|
||||
("assert-css", (".item-table .keyword", {"color": |keyword|}, ALL)),
|
||||
assert-css: (".item-table .mod", {"color": |mod|}, ALL)
|
||||
assert-css: (".item-table .macro", {"color": |macro|}, ALL)
|
||||
assert-css: (".item-table .struct", {"color": |struct|}, ALL)
|
||||
assert-css: (".item-table .enum", {"color": |enum|}, ALL)
|
||||
assert-css: (".item-table .trait", {"color": |trait|}, ALL)
|
||||
assert-css: (".item-table .fn", {"color": |fn|}, ALL)
|
||||
assert-css: (".item-table .type", {"color": |type|}, ALL)
|
||||
assert-css: (".item-table .union", {"color": |union|}, ALL)
|
||||
assert-css: (".item-table .keyword", {"color": |keyword|}, ALL)
|
||||
// Checking sidebar elements.
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".sidebar-elems a:not(.current)",
|
||||
{"color": |sidebar|, "background-color": "rgba(0, 0, 0, 0)", "font-weight": "400"},
|
||||
ALL,
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".sidebar-elems a.current",
|
||||
{
|
||||
"color": |sidebar_current|,
|
||||
@ -38,8 +38,8 @@ define-function: (
|
||||
"font-weight": "500",
|
||||
},
|
||||
ALL,
|
||||
)),
|
||||
],
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: (
|
||||
|
@ -123,40 +123,40 @@ assert-count: ("//*[@class='notable popover']", 0)
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, header_color, content_color, type_color, trait_color),
|
||||
[
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html"),
|
||||
block {
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html"
|
||||
// This is needed to ensure that the text color is computed.
|
||||
("show-text", true),
|
||||
show-text: true
|
||||
|
||||
// Setting the theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
// We reload the page so the local storage settings are being used.
|
||||
("reload"),
|
||||
reload:
|
||||
|
||||
("move-cursor-to", "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"),
|
||||
("assert-count", (".notable.popover", 1)),
|
||||
move-cursor-to: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
|
||||
assert-count: (".notable.popover", 1)
|
||||
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".notable.popover h3",
|
||||
{"color": |header_color|},
|
||||
ALL,
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".notable.popover pre",
|
||||
{"color": |content_color|},
|
||||
ALL,
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".notable.popover pre a.struct",
|
||||
{"color": |type_color|},
|
||||
ALL,
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".notable.popover pre a.trait",
|
||||
{"color": |trait_color|},
|
||||
ALL,
|
||||
)),
|
||||
]
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: (
|
||||
|
@ -8,27 +8,27 @@ show-text: true
|
||||
define-function: (
|
||||
"check-run-button",
|
||||
(theme, color, background, hover_color, hover_background),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("assert-css", (".test-arrow", {"visibility": "hidden"})),
|
||||
("move-cursor-to", ".example-wrap"),
|
||||
("assert-css", (".test-arrow", {
|
||||
block {
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
assert-css: (".test-arrow", {"visibility": "hidden"})
|
||||
move-cursor-to: ".example-wrap"
|
||||
assert-css: (".test-arrow", {
|
||||
"visibility": "visible",
|
||||
"color": |color|,
|
||||
"background-color": |background|,
|
||||
"font-size": "22px",
|
||||
"border-radius": "5px",
|
||||
})),
|
||||
("move-cursor-to", ".test-arrow"),
|
||||
("assert-css", (".test-arrow:hover", {
|
||||
})
|
||||
move-cursor-to: ".test-arrow"
|
||||
assert-css: (".test-arrow:hover", {
|
||||
"visibility": "visible",
|
||||
"color": |hover_color|,
|
||||
"background-color": |hover_background|,
|
||||
"font-size": "22px",
|
||||
"border-radius": "5px",
|
||||
})),
|
||||
],
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-run-button", {
|
||||
|
@ -4,29 +4,29 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
define-function: (
|
||||
"check-logo",
|
||||
(theme, filter),
|
||||
[
|
||||
block {
|
||||
// Going to the doc page.
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/index.html"),
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
// Changing theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("assert-css", (".rust-logo", {"filter": |filter|})),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
assert-css: (".rust-logo", {"filter": |filter|})
|
||||
// Going to the source code page.
|
||||
("goto", "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"),
|
||||
goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
|
||||
// Changing theme (since it's local files, the local storage works by folder).
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("assert-css", (".rust-logo", {"filter": |filter|})),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
assert-css: (".rust-logo", {"filter": |filter|})
|
||||
// Now we check that the non-rust logos don't have a CSS filter set.
|
||||
("goto", "file://" + |DOC_PATH| + "/huge_logo/index.html"),
|
||||
goto: "file://" + |DOC_PATH| + "/huge_logo/index.html"
|
||||
// Changing theme on the new page (again...).
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
// Check there is no rust logo
|
||||
("assert-false", ".rust-logo"),
|
||||
assert-false: ".rust-logo"
|
||||
// Check there is no filter.
|
||||
("assert-css", (".sidebar .logo-container img", {"filter": "none"})),
|
||||
],
|
||||
assert-css: (".sidebar .logo-container img", {"filter": "none"})
|
||||
},
|
||||
)
|
||||
|
||||
call-function: (
|
||||
|
@ -6,29 +6,29 @@ define-function: (
|
||||
"check-colors",
|
||||
(theme, highlight, highlight_focus, help_border, help_color, help_hover_border,
|
||||
help_hover_color),
|
||||
[
|
||||
("local-storage", { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", }),
|
||||
("reload"),
|
||||
("wait-for", ".more-examples-toggle"),
|
||||
("assert-css", (".scraped-example .example-wrap .rust span.highlight:not(.focus)", {
|
||||
block {
|
||||
local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", }
|
||||
reload:
|
||||
wait-for: ".more-examples-toggle"
|
||||
assert-css: (".scraped-example .example-wrap .rust span.highlight:not(.focus)", {
|
||||
"background-color": |highlight|,
|
||||
}, ALL)),
|
||||
("assert-css", (".scraped-example .example-wrap .rust span.highlight.focus", {
|
||||
}, ALL)
|
||||
assert-css: (".scraped-example .example-wrap .rust span.highlight.focus", {
|
||||
"background-color": |highlight_focus|,
|
||||
}, ALL)),
|
||||
}, ALL)
|
||||
|
||||
("assert-css", (".scraped-example-list .scrape-help", {
|
||||
assert-css: (".scraped-example-list .scrape-help", {
|
||||
"border-color": |help_border|,
|
||||
"color": |help_color|,
|
||||
})),
|
||||
("move-cursor-to", ".scraped-example-list .scrape-help"),
|
||||
("assert-css", (".scraped-example-list .scrape-help:hover", {
|
||||
})
|
||||
move-cursor-to: ".scraped-example-list .scrape-help"
|
||||
assert-css: (".scraped-example-list .scrape-help:hover", {
|
||||
"border-color": |help_hover_border|,
|
||||
"color": |help_hover_color|,
|
||||
})),
|
||||
})
|
||||
// Moving the cursor to another item to not break next runs.
|
||||
("move-cursor-to", ".search-input"),
|
||||
]
|
||||
move-cursor-to: ".search-input"
|
||||
}
|
||||
)
|
||||
|
||||
call-function: ("check-colors", {
|
||||
|
@ -6,24 +6,24 @@ show-text: true
|
||||
define-function: (
|
||||
"check-color",
|
||||
(theme, toggle_line_color, toggle_line_hover_color),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
block {
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
|
||||
// Clicking "More examples..." will open additional examples
|
||||
("assert-attribute-false", (".more-examples-toggle", {"open": ""})),
|
||||
("click", ".more-examples-toggle"),
|
||||
("assert-attribute", (".more-examples-toggle", {"open": ""})),
|
||||
assert-attribute-false: (".more-examples-toggle", {"open": ""})
|
||||
click: ".more-examples-toggle"
|
||||
assert-attribute: (".more-examples-toggle", {"open": ""})
|
||||
|
||||
("assert-css", (".toggle-line-inner", {"background-color": |toggle_line_color|}, ALL)),
|
||||
("move-cursor-to", ".toggle-line"),
|
||||
("assert-css", (
|
||||
assert-css: (".toggle-line-inner", {"background-color": |toggle_line_color|}, ALL)
|
||||
move-cursor-to: ".toggle-line"
|
||||
assert-css: (
|
||||
".toggle-line:hover .toggle-line-inner",
|
||||
{"background-color": |toggle_line_hover_color|},
|
||||
)),
|
||||
)
|
||||
// Moving cursor away from the toggle line to prevent disrupting next test.
|
||||
("move-cursor-to", ".search-input"),
|
||||
],
|
||||
move-cursor-to: ".search-input"
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-color", {
|
||||
|
@ -5,18 +5,18 @@ show-text: true
|
||||
define-function: (
|
||||
"check-no-result",
|
||||
(theme, link, link_hover),
|
||||
[
|
||||
block {
|
||||
// Changing theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("wait-for", "#results"),
|
||||
("assert", ".search-failed.active"),
|
||||
("assert-css", ("#results a", {"color": |link|}, ALL)),
|
||||
("move-cursor-to", "#results a"),
|
||||
("assert-css", ("#results a:hover", {"color": |link_hover|})),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
wait-for: "#results"
|
||||
assert: ".search-failed.active"
|
||||
assert-css: ("#results a", {"color": |link|}, ALL)
|
||||
move-cursor-to: "#results a"
|
||||
assert-css: ("#results a:hover", {"color": |link_hover|})
|
||||
// Moving the cursor to some other place to not create issues with next function run.
|
||||
("move-cursor-to", ".search-input"),
|
||||
]
|
||||
move-cursor-to: ".search-input"
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-no-result", {
|
||||
|
@ -3,53 +3,32 @@
|
||||
define-function: (
|
||||
"check-result-color",
|
||||
(result_kind, color, hover_color),
|
||||
[
|
||||
(
|
||||
"assert-css",
|
||||
(".result-" + |result_kind| + " ." + |result_kind|, {"color": |color|}, ALL),
|
||||
),
|
||||
(
|
||||
"assert-css",
|
||||
(
|
||||
".result-" + |result_kind|,
|
||||
{"color": |entry_color|, "background-color": |background_color|},
|
||||
),
|
||||
),
|
||||
(
|
||||
"move-cursor-to",
|
||||
block {
|
||||
assert-css: (".result-" + |result_kind| + " ." + |result_kind|, {"color": |color|}, ALL)
|
||||
assert-css: (
|
||||
".result-" + |result_kind|,
|
||||
),
|
||||
(
|
||||
"assert-css",
|
||||
(
|
||||
".result-" + |result_kind| + ":hover",
|
||||
{"color": |hover_entry_color|, "background-color": |hover_background_color|},
|
||||
),
|
||||
),
|
||||
(
|
||||
"assert-css",
|
||||
(".result-" + |result_kind| + ":hover ." + |result_kind|, {"color": |hover_color|}),
|
||||
),
|
||||
(
|
||||
"move-cursor-to",
|
||||
".search-input",
|
||||
),
|
||||
(
|
||||
"focus",
|
||||
".result-" + |result_kind|,
|
||||
),
|
||||
(
|
||||
"assert-css",
|
||||
(
|
||||
".result-" + |result_kind| + ":focus",
|
||||
{"color": |hover_entry_color|, "background-color": |hover_background_color|},
|
||||
),
|
||||
),
|
||||
(
|
||||
"assert-css",
|
||||
(".result-" + |result_kind| + ":focus ." + |result_kind|, {"color": |hover_color|}),
|
||||
),
|
||||
],
|
||||
{"color": |entry_color|, "background-color": |background_color|},
|
||||
)
|
||||
move-cursor-to: ".result-" + |result_kind|
|
||||
assert-css: (
|
||||
".result-" + |result_kind| + ":hover",
|
||||
{"color": |hover_entry_color|, "background-color": |hover_background_color|},
|
||||
)
|
||||
assert-css: (
|
||||
".result-" + |result_kind| + ":hover ." + |result_kind|,
|
||||
{"color": |hover_color|},
|
||||
)
|
||||
move-cursor-to: ".search-input"
|
||||
focus: ".result-" + |result_kind|
|
||||
assert-css: (
|
||||
".result-" + |result_kind| + ":focus",
|
||||
{"color": |hover_entry_color|, "background-color": |hover_background_color|},
|
||||
)
|
||||
assert-css: (
|
||||
".result-" + |result_kind| + ":focus ." + |result_kind|,
|
||||
{"color": |hover_color|},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/index.html?search=coo"
|
||||
@ -389,20 +368,20 @@ show-text: true
|
||||
define-function: (
|
||||
"check-alias",
|
||||
(theme, alias, grey),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("write", (".search-input", "thisisanalias")),
|
||||
block {
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
write: (".search-input", "thisisanalias")
|
||||
// To be SURE that the search will be run.
|
||||
("press-key", 'Enter'),
|
||||
press-key: 'Enter'
|
||||
// Waiting for the search results to appear...
|
||||
("wait-for", "#search-tabs"),
|
||||
wait-for: "#search-tabs"
|
||||
// Checking that the colors for the alias element are the ones expected.
|
||||
("assert-css", (".result-name > .alias", {"color": |alias|})),
|
||||
("assert-css", (".result-name > .alias > .grey", {"color": |grey|})),
|
||||
assert-css: (".result-name > .alias", {"color": |alias|})
|
||||
assert-css: (".result-name > .alias > .grey", {"color": |grey|})
|
||||
// Leave the search results to prevent reloading with an already filled search input.
|
||||
("press-key", "Escape"),
|
||||
],
|
||||
press-key: "Escape"
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-alias", {
|
||||
|
@ -42,17 +42,17 @@ show-text: true
|
||||
define-function: (
|
||||
"check-filter",
|
||||
(theme, border, filter, hover_border, hover_filter),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("wait-for", "#crate-search"),
|
||||
("assert-css", ("#crate-search", {"border": "1px solid " + |border|})),
|
||||
("assert-css", ("#crate-search-div::after", {"filter": |filter|})),
|
||||
("move-cursor-to", "#crate-search"),
|
||||
("assert-css", ("#crate-search", {"border": "1px solid " + |hover_border|})),
|
||||
("assert-css", ("#crate-search-div::after", {"filter": |hover_filter|})),
|
||||
("move-cursor-to", ".search-input"),
|
||||
],
|
||||
block {
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
wait-for: "#crate-search"
|
||||
assert-css: ("#crate-search", {"border": "1px solid " + |border|})
|
||||
assert-css: ("#crate-search-div::after", {"filter": |filter|})
|
||||
move-cursor-to: "#crate-search"
|
||||
assert-css: ("#crate-search", {"border": "1px solid " + |hover_border|})
|
||||
assert-css: ("#crate-search-div::after", {"filter": |hover_filter|})
|
||||
move-cursor-to: ".search-input"
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-filter", {
|
||||
|
@ -7,35 +7,35 @@ define-function: (
|
||||
(theme, background, background_selected, background_hover, border_bottom,
|
||||
border_bottom_selected, border_bottom_hover, border_top, border_top_selected,
|
||||
border_top_hover),
|
||||
[
|
||||
block {
|
||||
// Setting the theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
|
||||
// These two commands are used to be sure the search will be run.
|
||||
("focus", ".search-input"),
|
||||
("press-key", "Enter"),
|
||||
focus: ".search-input"
|
||||
press-key: "Enter"
|
||||
|
||||
("wait-for", "#search-tabs"),
|
||||
("assert-css", ("#search-tabs > button:not(.selected)", {
|
||||
wait-for: "#search-tabs"
|
||||
assert-css: ("#search-tabs > button:not(.selected)", {
|
||||
"background-color": |background|,
|
||||
"border-bottom": |border_bottom|,
|
||||
"border-top": |border_top|,
|
||||
})),
|
||||
("assert-css", ("#search-tabs > button.selected", {
|
||||
})
|
||||
assert-css: ("#search-tabs > button.selected", {
|
||||
"background-color": |background_selected|,
|
||||
"border-bottom": |border_bottom_selected|,
|
||||
"border-top": |border_top_selected|,
|
||||
})),
|
||||
("move-cursor-to", "#search-tabs > button:not(.selected)"),
|
||||
("assert-css", ("#search-tabs > button:not(.selected):hover", {
|
||||
})
|
||||
move-cursor-to: "#search-tabs > button:not(.selected)"
|
||||
assert-css: ("#search-tabs > button:not(.selected):hover", {
|
||||
"background-color": |background_hover|,
|
||||
"border-bottom": |border_bottom_hover|,
|
||||
"border-top": |border_top_hover|,
|
||||
})),
|
||||
})
|
||||
// To prevent disrupting next run of this function.
|
||||
("move-cursor-to", ".search-input"),
|
||||
],
|
||||
move-cursor-to: ".search-input"
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-colors", {
|
||||
|
@ -12,80 +12,80 @@ define-function: (
|
||||
trait_hover_background, fn, fn_hover, fn_hover_background, type, type_hover,
|
||||
type_hover_background, keyword, keyword_hover, keyword_hover_background,
|
||||
),
|
||||
[
|
||||
("local-storage", { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }),
|
||||
("reload"),
|
||||
block {
|
||||
local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }
|
||||
reload:
|
||||
// Struct
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".sidebar .block.struct a:not(.current)",
|
||||
{"color": |struct|, "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)),
|
||||
("move-cursor-to", ".sidebar .block.struct a:not(.current)"),
|
||||
("assert-css", (
|
||||
)
|
||||
move-cursor-to: ".sidebar .block.struct a:not(.current)"
|
||||
assert-css: (
|
||||
".sidebar .block.struct a:hover",
|
||||
{"color": |struct_hover|, "background-color": |struct_hover_background|},
|
||||
)),
|
||||
)
|
||||
// Enum
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".sidebar .block.enum a",
|
||||
{"color": |enum|, "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)),
|
||||
("move-cursor-to", ".sidebar .block.enum a"),
|
||||
("assert-css", (
|
||||
)
|
||||
move-cursor-to: ".sidebar .block.enum a"
|
||||
assert-css: (
|
||||
".sidebar .block.enum a:hover",
|
||||
{"color": |enum_hover|, "background-color": |enum_hover_background|},
|
||||
)),
|
||||
)
|
||||
// Union
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".sidebar .block.union a",
|
||||
{"color": |union|, "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)),
|
||||
("move-cursor-to", ".sidebar .block.union a"),
|
||||
("assert-css", (
|
||||
)
|
||||
move-cursor-to: ".sidebar .block.union a"
|
||||
assert-css: (
|
||||
".sidebar .block.union a:hover",
|
||||
{"color": |union_hover|, "background-color": |union_hover_background|},
|
||||
)),
|
||||
)
|
||||
// Trait
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".sidebar .block.trait a",
|
||||
{"color": |trait|, "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)),
|
||||
("move-cursor-to", ".sidebar .block.trait a"),
|
||||
("assert-css", (
|
||||
)
|
||||
move-cursor-to: ".sidebar .block.trait a"
|
||||
assert-css: (
|
||||
".sidebar .block.trait a:hover",
|
||||
{"color": |trait_hover|, "background-color": |trait_hover_background|},
|
||||
)),
|
||||
)
|
||||
// Function
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".sidebar .block.fn a",
|
||||
{"color": |fn|, "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)),
|
||||
("move-cursor-to", ".sidebar .block.fn a"),
|
||||
("assert-css", (
|
||||
)
|
||||
move-cursor-to: ".sidebar .block.fn a"
|
||||
assert-css: (
|
||||
".sidebar .block.fn a:hover",
|
||||
{"color": |fn_hover|, "background-color": |fn_hover_background|},
|
||||
)),
|
||||
)
|
||||
// Type definition
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".sidebar .block.type a",
|
||||
{"color": |type|, "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)),
|
||||
("move-cursor-to", ".sidebar .block.type a"),
|
||||
("assert-css", (
|
||||
)
|
||||
move-cursor-to: ".sidebar .block.type a"
|
||||
assert-css: (
|
||||
".sidebar .block.type a:hover",
|
||||
{"color": |type_hover|, "background-color": |type_hover_background|},
|
||||
)),
|
||||
)
|
||||
// Keyword
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
".sidebar .block.keyword a",
|
||||
{"color": |keyword|, "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)),
|
||||
("move-cursor-to", ".sidebar .block.keyword a"),
|
||||
("assert-css", (
|
||||
)
|
||||
move-cursor-to: ".sidebar .block.keyword a"
|
||||
assert-css: (
|
||||
".sidebar .block.keyword a:hover",
|
||||
{"color": |keyword_hover|, "background-color": |keyword_hover_background|},
|
||||
)),
|
||||
]
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
call-function: (
|
||||
|
@ -58,17 +58,17 @@ show-text: true
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, color, background),
|
||||
[
|
||||
("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}),
|
||||
("reload"),
|
||||
block {
|
||||
local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}
|
||||
reload:
|
||||
|
||||
// Open the sidebar menu.
|
||||
("click", ".sidebar-menu-toggle"),
|
||||
("assert-css", (".sidebar", {
|
||||
click: ".sidebar-menu-toggle"
|
||||
assert-css: (".sidebar", {
|
||||
"background-color": |background|,
|
||||
"color": |color|,
|
||||
})),
|
||||
],
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-colors", {
|
||||
|
@ -35,88 +35,88 @@ define-function: (
|
||||
theme, color, color_hover, background, background_hover, background_toggle,
|
||||
background_toggle_hover,
|
||||
),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("wait-for-css", ("#src-sidebar-toggle", {"visibility": "visible"})),
|
||||
("assert-css", (
|
||||
block {
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
wait-for-css: ("#src-sidebar-toggle", {"visibility": "visible"})
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files a.selected",
|
||||
{"color": |color_hover|, "background-color": |background|},
|
||||
)),
|
||||
)
|
||||
|
||||
// Without hover or focus.
|
||||
("assert-css", ("#src-sidebar-toggle > button", {"background-color": |background_toggle|})),
|
||||
assert-css: ("#src-sidebar-toggle > button", {"background-color": |background_toggle|})
|
||||
// With focus.
|
||||
("focus", "#src-sidebar-toggle > button"),
|
||||
("assert-css", (
|
||||
focus: "#src-sidebar-toggle > button"
|
||||
assert-css: (
|
||||
"#src-sidebar-toggle > button:focus",
|
||||
{"background-color": |background_toggle_hover|},
|
||||
)),
|
||||
("focus", ".search-input"),
|
||||
)
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
("move-cursor-to", "#src-sidebar-toggle > button"),
|
||||
("assert-css", (
|
||||
move-cursor-to: "#src-sidebar-toggle > button"
|
||||
assert-css: (
|
||||
"#src-sidebar-toggle > button:hover",
|
||||
{"background-color": |background_toggle_hover|},
|
||||
)),
|
||||
)
|
||||
|
||||
// Without hover or focus.
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": |color|, "background-color": |background_toggle|},
|
||||
)),
|
||||
)
|
||||
// With focus.
|
||||
("focus", "#source-sidebar details[open] > .files a:not(.selected)"),
|
||||
("wait-for-css", (
|
||||
focus: "#source-sidebar details[open] > .files a:not(.selected)"
|
||||
wait-for-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected):focus",
|
||||
{"color": |color_hover|, "background-color": |background_hover|},
|
||||
)),
|
||||
("focus", ".search-input"),
|
||||
)
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
("move-cursor-to", "#source-sidebar details[open] > .files a:not(.selected)"),
|
||||
("assert-css", (
|
||||
move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected):hover",
|
||||
{"color": |color_hover|, "background-color": |background_hover|},
|
||||
)),
|
||||
)
|
||||
|
||||
// Without hover or focus.
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
"#source-sidebar .dir-entry summary",
|
||||
{"color": |color|, "background-color": |background_toggle|},
|
||||
)),
|
||||
)
|
||||
// With focus.
|
||||
("focus", "#source-sidebar .dir-entry summary"),
|
||||
("wait-for-css", (
|
||||
focus: "#source-sidebar .dir-entry summary"
|
||||
wait-for-css: (
|
||||
"#source-sidebar .dir-entry summary:focus",
|
||||
{"color": |color_hover|, "background-color": |background_hover|},
|
||||
)),
|
||||
("focus", ".search-input"),
|
||||
)
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
("move-cursor-to", "#source-sidebar .dir-entry summary"),
|
||||
("assert-css", (
|
||||
move-cursor-to: "#source-sidebar .dir-entry summary"
|
||||
assert-css: (
|
||||
"#source-sidebar .dir-entry summary:hover",
|
||||
{"color": |color_hover|, "background-color": |background_hover|},
|
||||
)),
|
||||
)
|
||||
|
||||
// Without hover or focus.
|
||||
("assert-css", (
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": |color|, "background-color": |background_toggle|},
|
||||
)),
|
||||
)
|
||||
// With focus.
|
||||
("focus", "#source-sidebar details[open] > .folders > details > summary"),
|
||||
("wait-for-css", (
|
||||
focus: "#source-sidebar details[open] > .folders > details > summary"
|
||||
wait-for-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary:focus",
|
||||
{"color": |color_hover|, "background-color": |background_hover|},
|
||||
)),
|
||||
("focus", ".search-input"),
|
||||
)
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
("move-cursor-to", "#source-sidebar details[open] > .folders > details > summary"),
|
||||
("assert-css", (
|
||||
move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary:hover",
|
||||
{"color": |color_hover|, "background-color": |background_hover|},
|
||||
)),
|
||||
],
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-colors", {
|
||||
|
@ -7,43 +7,43 @@ show-text: true
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, color, background_color),
|
||||
[
|
||||
("local-storage", {
|
||||
block {
|
||||
local-storage: {
|
||||
"rustdoc-theme": |theme|,
|
||||
"rustdoc-use-system-theme": "false",
|
||||
}),
|
||||
("reload"),
|
||||
}
|
||||
reload:
|
||||
// Checking results colors.
|
||||
("assert-css", (".source .sidebar", {
|
||||
"color": |color|,
|
||||
"background-color": |background_color|
|
||||
}, ALL)),
|
||||
],
|
||||
assert-css: (".source .sidebar", {
|
||||
"color": |color|,
|
||||
"background-color": |background_color|
|
||||
}, ALL)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "ayu",
|
||||
"color": "rgb(197, 197, 197)",
|
||||
"background_color": "rgb(20, 25, 31)",
|
||||
}
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "ayu",
|
||||
"color": "rgb(197, 197, 197)",
|
||||
"background_color": "rgb(20, 25, 31)",
|
||||
}
|
||||
)
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "dark",
|
||||
"color": "rgb(221, 221, 221)",
|
||||
"background_color": "rgb(80, 80, 80)",
|
||||
}
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "dark",
|
||||
"color": "rgb(221, 221, 221)",
|
||||
"background_color": "rgb(80, 80, 80)",
|
||||
}
|
||||
)
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "light",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"background_color": "rgb(245, 245, 245)",
|
||||
}
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "light",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"background_color": "rgb(245, 245, 245)",
|
||||
}
|
||||
)
|
||||
|
||||
// Next, desktop mode layout.
|
||||
|
@ -7,43 +7,43 @@ show-text: true
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, color, background_color),
|
||||
[
|
||||
("local-storage", {
|
||||
block {
|
||||
local-storage: {
|
||||
"rustdoc-theme": |theme|,
|
||||
"rustdoc-use-system-theme": "false",
|
||||
}),
|
||||
("reload"),
|
||||
}
|
||||
reload:
|
||||
// Checking results colors.
|
||||
("assert-css", (".sidebar", {
|
||||
"color": |color|,
|
||||
"background-color": |background_color|
|
||||
}, ALL)),
|
||||
],
|
||||
assert-css: (".sidebar", {
|
||||
"color": |color|,
|
||||
"background-color": |background_color|
|
||||
}, ALL)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "ayu",
|
||||
"color": "rgb(197, 197, 197)",
|
||||
"background_color": "rgb(20, 25, 31)",
|
||||
}
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "ayu",
|
||||
"color": "rgb(197, 197, 197)",
|
||||
"background_color": "rgb(20, 25, 31)",
|
||||
}
|
||||
)
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "dark",
|
||||
"color": "rgb(221, 221, 221)",
|
||||
"background_color": "rgb(80, 80, 80)",
|
||||
}
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "dark",
|
||||
"color": "rgb(221, 221, 221)",
|
||||
"background_color": "rgb(80, 80, 80)",
|
||||
}
|
||||
)
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "light",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"background_color": "rgb(245, 245, 245)",
|
||||
}
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "light",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"background_color": "rgb(245, 245, 245)",
|
||||
}
|
||||
)
|
||||
|
||||
local-storage: {"rustdoc-theme": "light"}
|
||||
|
@ -22,20 +22,20 @@ assert-attribute-false: (".src-line-numbers > a:nth-child(7)", {"class": "line-h
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, color, background_color, highlight_color, highlight_background_color),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("assert-css", (
|
||||
block {
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
assert-css: (
|
||||
".src-line-numbers > a:not(.line-highlighted)",
|
||||
{"color": |color|, "background-color": |background_color|},
|
||||
ALL,
|
||||
)),
|
||||
("assert-css", (
|
||||
)
|
||||
assert-css: (
|
||||
".src-line-numbers > a.line-highlighted",
|
||||
{"color": |highlight_color|, "background-color": |highlight_background_color|},
|
||||
ALL,
|
||||
)),
|
||||
],
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-colors", {
|
||||
@ -124,28 +124,28 @@ store-property: (
|
||||
define-function: (
|
||||
"check-sidebar-dir-entry",
|
||||
(x, y),
|
||||
[
|
||||
("assert", "details:first-of-type.dir-entry[open] > summary::marker"),
|
||||
("assert-css", ("#source-sidebar > details:first-of-type.dir-entry", {"padding-left": "4px"})),
|
||||
block {
|
||||
assert: "details:first-of-type.dir-entry[open] > summary::marker"
|
||||
assert-css: ("#source-sidebar > details:first-of-type.dir-entry", {"padding-left": "4px"})
|
||||
// This check ensures that the summary is only one line.
|
||||
("assert-property", (
|
||||
assert-property: (
|
||||
"#source-sidebar > details:first-of-type.dir-entry[open] > summary",
|
||||
{"offsetHeight": |link_height|}
|
||||
)),
|
||||
("assert-position", (
|
||||
)
|
||||
assert-position: (
|
||||
"#source-sidebar > details:first-of-type.dir-entry[open] > summary",
|
||||
{"x": |x|, "y": |y|}
|
||||
)),
|
||||
("assert-property", (
|
||||
)
|
||||
assert-property: (
|
||||
"#source-sidebar > details:first-of-type.dir-entry[open] > .files > a",
|
||||
{"offsetHeight": |link_height|}
|
||||
)),
|
||||
("assert-position", (
|
||||
)
|
||||
assert-position: (
|
||||
"#source-sidebar > details:first-of-type.dir-entry[open] > .files > a",
|
||||
// left margin
|
||||
{"x": |x| + 27, "y": |y| + |link_height|}
|
||||
)),
|
||||
]
|
||||
)
|
||||
}
|
||||
)
|
||||
store-property: (
|
||||
source_sidebar_title_height,
|
||||
|
@ -2,40 +2,40 @@
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
show-text: true
|
||||
define-function: (
|
||||
"check-badge",
|
||||
(theme, background, color),
|
||||
[
|
||||
("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}),
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/index.html"),
|
||||
("assert", (".docblock .stab")),
|
||||
("assert", (".item-table .stab")),
|
||||
("assert-css", (".stab", {
|
||||
"border-radius": "3px",
|
||||
"color": |color|,
|
||||
"background-color": |background|,
|
||||
})),
|
||||
("goto", "file://" + |DOC_PATH| + "/test_docs/fn.replaced_function.html"),
|
||||
("assert", (".item-info .stab")),
|
||||
("assert-css", (".stab", {
|
||||
"border-radius": "3px",
|
||||
"color": |color|,
|
||||
"background-color": |background|,
|
||||
})),
|
||||
]
|
||||
"check-badge",
|
||||
(theme, background, color),
|
||||
block {
|
||||
local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
assert: ".docblock .stab"
|
||||
assert: ".item-table .stab"
|
||||
assert-css: (".stab", {
|
||||
"border-radius": "3px",
|
||||
"color": |color|,
|
||||
"background-color": |background|,
|
||||
})
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/fn.replaced_function.html"
|
||||
assert: (".item-info .stab")
|
||||
assert-css: (".stab", {
|
||||
"border-radius": "3px",
|
||||
"color": |color|,
|
||||
"background-color": |background|,
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-badge", {
|
||||
"theme": "ayu",
|
||||
"color": "rgb(197, 197, 197)",
|
||||
"background": "rgb(49, 69, 89)",
|
||||
"theme": "ayu",
|
||||
"color": "rgb(197, 197, 197)",
|
||||
"background": "rgb(49, 69, 89)",
|
||||
})
|
||||
call-function: ("check-badge", {
|
||||
"theme": "dark",
|
||||
"color": "rgb(221, 221, 221)",
|
||||
"background": "rgb(49, 69, 89)",
|
||||
"theme": "dark",
|
||||
"color": "rgb(221, 221, 221)",
|
||||
"background": "rgb(49, 69, 89)",
|
||||
})
|
||||
call-function: ("check-badge", {
|
||||
"theme": "light",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"background": "rgb(255, 245, 214)",
|
||||
"theme": "light",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"background": "rgb(255, 245, 214)",
|
||||
})
|
||||
|
@ -8,14 +8,14 @@ assert: "#method\.a_method:target"
|
||||
define-function: (
|
||||
"check-style",
|
||||
(theme, background, border),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("assert-css", ("#method\.a_method:target", {
|
||||
block {
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
assert-css: ("#method\.a_method:target", {
|
||||
"background-color": |background|,
|
||||
"border-right": "3px solid " + |border|,
|
||||
})),
|
||||
],
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-style", {
|
||||
|
@ -50,24 +50,24 @@ show-text: true
|
||||
define-function: (
|
||||
"check-color",
|
||||
(theme, filter),
|
||||
[
|
||||
block {
|
||||
// Setting the theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
// We reload the page so the local storage settings are being used.
|
||||
("reload"),
|
||||
reload:
|
||||
|
||||
("assert-css", ("details.rustdoc-toggle > summary::before", {
|
||||
assert-css: ("details.rustdoc-toggle > summary::before", {
|
||||
"opacity": "0.5",
|
||||
"filter": |filter|,
|
||||
}, ALL)),
|
||||
("move-cursor-to", "details.rustdoc-toggle summary"),
|
||||
("assert-css", ("details.rustdoc-toggle > summary:hover::before", {
|
||||
}, ALL)
|
||||
move-cursor-to: "details.rustdoc-toggle summary"
|
||||
assert-css: ("details.rustdoc-toggle > summary:hover::before", {
|
||||
"opacity": "1",
|
||||
"filter": |filter|,
|
||||
})),
|
||||
})
|
||||
// moving the cursor somewhere else to not mess with next function calls.
|
||||
("move-cursor-to", ".search-input"),
|
||||
]
|
||||
move-cursor-to: ".search-input"
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("check-color", {"theme": "ayu", "filter": "invert(1)"})
|
||||
|
@ -14,13 +14,13 @@ define-function: (
|
||||
// `theme` is the theme being tested.
|
||||
// `color` is the expected color of the `<sup>` element.
|
||||
(theme, color),
|
||||
[
|
||||
block {
|
||||
// Set the theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
|
||||
// We reload the page so the local storage settings are being used.
|
||||
("reload"),
|
||||
("assert-css", (".item-left sup", {"color": |color|})),
|
||||
],
|
||||
reload:
|
||||
assert-css: (".item-left sup", {"color": |color|})
|
||||
},
|
||||
)
|
||||
|
||||
call-function: ("sup-check", ("dark", "rgb(221, 221, 221)"))
|
||||
|
@ -7,6 +7,11 @@
|
||||
#[path = "src-links/mod.rs"]
|
||||
pub mod qux;
|
||||
|
||||
// @has src/foo/src-links.rs.html
|
||||
// @has foo/fizz/index.html '//a/@href' '../src/foo/src-links/fizz.rs.html'
|
||||
#[path = "src-links/../src-links/fizz.rs"]
|
||||
pub mod fizz;
|
||||
|
||||
// @has foo/bar/index.html '//a/@href' '../../src/foo/src-links.rs.html'
|
||||
pub mod bar {
|
||||
|
||||
|
1
src/test/rustdoc/src-links/fizz.rs
Normal file
1
src/test/rustdoc/src-links/fizz.rs
Normal file
@ -0,0 +1 @@
|
||||
pub struct Buzz;
|
381
src/tools/tidy/src/error_codes.rs
Normal file
381
src/tools/tidy/src/error_codes.rs
Normal file
@ -0,0 +1,381 @@
|
||||
//! Tidy check to ensure error codes are properly documented and tested.
|
||||
//!
|
||||
//! Overview of check:
|
||||
//!
|
||||
//! 1. We create a list of error codes used by the compiler. Error codes are extracted from `compiler/rustc_error_codes/src/error_codes.rs`.
|
||||
//!
|
||||
//! 2. We check that the error code has a long-form explanation in `compiler/rustc_error_codes/src/error_codes/`.
|
||||
//! - The explanation is expected to contain a `doctest` that fails with the correct error code. (`EXEMPT_FROM_DOCTEST` *currently* bypasses this check)
|
||||
//! - Note that other stylistic conventions for markdown files are checked in the `style.rs` tidy check.
|
||||
//!
|
||||
//! 3. We check that the error code has a UI test in `src/test/ui/error-codes/`.
|
||||
//! - We ensure that there is both a `Exxxx.rs` file and a corresponding `Exxxx.stderr` file.
|
||||
//! - We also ensure that the error code is used in the tests.
|
||||
//! - *Currently*, it is possible to opt-out of this check with the `EXEMPTED_FROM_TEST` constant.
|
||||
//!
|
||||
//! 4. We check that the error code is actually emitted by the compiler.
|
||||
//! - This is done by searching `compiler/` with a regex.
|
||||
//!
|
||||
//! This tidy check was merged and refactored from two others. See #PR_NUM for information about linting changes that occurred during this refactor.
|
||||
|
||||
use std::{ffi::OsStr, fs, path::Path};
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
use crate::walk::{filter_dirs, walk, walk_many};
|
||||
|
||||
const ERROR_CODES_PATH: &str = "compiler/rustc_error_codes/src/error_codes.rs";
|
||||
const ERROR_DOCS_PATH: &str = "compiler/rustc_error_codes/src/error_codes/";
|
||||
const ERROR_TESTS_PATH: &str = "src/test/ui/error-codes/";
|
||||
|
||||
// Error codes that (for some reason) can't have a doctest in their explanation. Error codes are still expected to provide a code example, even if untested.
|
||||
const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602"];
|
||||
|
||||
// Error codes that don't yet have a UI test. This list will eventually be removed.
|
||||
const IGNORE_UI_TEST_CHECK: &[&str] = &[
|
||||
"E0313", "E0461", "E0465", "E0476", "E0490", "E0514", "E0523", "E0554", "E0640", "E0717",
|
||||
"E0729", "E0789",
|
||||
];
|
||||
|
||||
macro_rules! verbose_print {
|
||||
($verbose:expr, $($fmt:tt)*) => {
|
||||
if $verbose {
|
||||
println!("{}", format_args!($($fmt)*));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut bool) {
|
||||
let mut errors = Vec::new();
|
||||
|
||||
// Stage 1: create list
|
||||
let error_codes = extract_error_codes(root_path, &mut errors, verbose);
|
||||
println!("Found {} error codes", error_codes.len());
|
||||
println!("Highest error code: `{}`", error_codes.iter().max().unwrap());
|
||||
|
||||
// Stage 2: check list has docs
|
||||
let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut errors, verbose);
|
||||
|
||||
// Stage 3: check list has UI tests
|
||||
check_error_codes_tests(root_path, &error_codes, &mut errors, verbose);
|
||||
|
||||
// Stage 4: check list is emitted by compiler
|
||||
check_error_codes_used(search_paths, &error_codes, &mut errors, &no_longer_emitted, verbose);
|
||||
|
||||
// Print any errors.
|
||||
for error in errors {
|
||||
tidy_error!(bad, "{}", error);
|
||||
}
|
||||
}
|
||||
|
||||
/// Stage 1: Parses a list of error codes from `error_codes.rs`.
|
||||
fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>, verbose: bool) -> Vec<String> {
|
||||
let path = root_path.join(Path::new(ERROR_CODES_PATH));
|
||||
let file =
|
||||
fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read `{path:?}`: {e}"));
|
||||
|
||||
let mut error_codes = Vec::new();
|
||||
let mut reached_undocumented_codes = false;
|
||||
|
||||
for line in file.lines() {
|
||||
let line = line.trim();
|
||||
|
||||
if !reached_undocumented_codes && line.starts_with('E') {
|
||||
let split_line = line.split_once(':');
|
||||
|
||||
// Extract the error code from the line, emitting a fatal error if it is not in a correct format.
|
||||
let err_code = if let Some(err_code) = split_line {
|
||||
err_code.0.to_owned()
|
||||
} else {
|
||||
errors.push(format!(
|
||||
"Expected a line with the format `Exxxx: include_str!(\"..\")`, but got \"{}\" \
|
||||
without a `:` delimiter",
|
||||
line,
|
||||
));
|
||||
continue;
|
||||
};
|
||||
|
||||
// If this is a duplicate of another error code, emit a fatal error.
|
||||
if error_codes.contains(&err_code) {
|
||||
errors.push(format!("Found duplicate error code: `{}`", err_code));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ensure that the line references the correct markdown file.
|
||||
let expected_filename = format!(" include_str!(\"./error_codes/{}.md\"),", err_code);
|
||||
if expected_filename != split_line.unwrap().1 {
|
||||
errors.push(format!(
|
||||
"Error code `{}` expected to reference docs with `{}` but instead found `{}` in \
|
||||
`compiler/rustc_error_codes/src/error_codes.rs`",
|
||||
err_code,
|
||||
expected_filename,
|
||||
split_line.unwrap().1,
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
error_codes.push(err_code);
|
||||
} else if reached_undocumented_codes && line.starts_with('E') {
|
||||
let err_code = match line.split_once(',') {
|
||||
None => line,
|
||||
Some((err_code, _)) => err_code,
|
||||
}
|
||||
.to_string();
|
||||
|
||||
verbose_print!(verbose, "warning: Error code `{}` is undocumented.", err_code);
|
||||
|
||||
if error_codes.contains(&err_code) {
|
||||
errors.push(format!("Found duplicate error code: `{}`", err_code));
|
||||
}
|
||||
|
||||
error_codes.push(err_code);
|
||||
} else if line == ";" {
|
||||
// Once we reach the undocumented error codes, adapt to different syntax.
|
||||
reached_undocumented_codes = true;
|
||||
}
|
||||
}
|
||||
|
||||
error_codes
|
||||
}
|
||||
|
||||
/// Stage 2: Checks that long-form error code explanations exist and have doctests.
|
||||
fn check_error_codes_docs(
|
||||
root_path: &Path,
|
||||
error_codes: &[String],
|
||||
errors: &mut Vec<String>,
|
||||
verbose: bool,
|
||||
) -> Vec<String> {
|
||||
let docs_path = root_path.join(Path::new(ERROR_DOCS_PATH));
|
||||
|
||||
let mut no_longer_emitted_codes = Vec::new();
|
||||
|
||||
walk(&docs_path, &mut |_| false, &mut |entry, contents| {
|
||||
let path = entry.path();
|
||||
|
||||
// Error if the file isn't markdown.
|
||||
if path.extension() != Some(OsStr::new("md")) {
|
||||
errors.push(format!(
|
||||
"Found unexpected non-markdown file in error code docs directory: {}",
|
||||
path.display()
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure that the file is referenced in `error_codes.rs`
|
||||
let filename = path.file_name().unwrap().to_str().unwrap().split_once('.');
|
||||
let err_code = filename.unwrap().0; // `unwrap` is ok because we know the filename is in the correct format.
|
||||
|
||||
if error_codes.iter().all(|e| e != err_code) {
|
||||
errors.push(format!(
|
||||
"Found valid file `{}` in error code docs directory without corresponding \
|
||||
entry in `error_code.rs`",
|
||||
path.display()
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
let (found_code_example, found_proper_doctest, emit_ignore_warning, emit_no_longer_warning) =
|
||||
check_explanation_has_doctest(&contents, &err_code);
|
||||
if emit_ignore_warning {
|
||||
verbose_print!(
|
||||
verbose,
|
||||
"warning: Error code `{err_code}` uses the ignore header. This should not be used, add the error code to the \
|
||||
`IGNORE_DOCTEST_CHECK` constant instead."
|
||||
);
|
||||
}
|
||||
if emit_no_longer_warning {
|
||||
no_longer_emitted_codes.push(err_code.to_owned());
|
||||
verbose_print!(
|
||||
verbose,
|
||||
"warning: Error code `{err_code}` is no longer emitted and should be removed entirely."
|
||||
);
|
||||
}
|
||||
if !found_code_example {
|
||||
verbose_print!(
|
||||
verbose,
|
||||
"warning: Error code `{err_code}` doesn't have a code example, all error codes are expected to have one \
|
||||
(even if untested)."
|
||||
);
|
||||
}
|
||||
|
||||
let test_ignored = IGNORE_DOCTEST_CHECK.contains(&&err_code);
|
||||
|
||||
// Check that the explanation has a doctest, and if it shouldn't, that it doesn't
|
||||
if !found_proper_doctest && !test_ignored {
|
||||
errors.push(format!(
|
||||
"`{}` doesn't use its own error code in compile_fail example",
|
||||
path.display(),
|
||||
));
|
||||
} else if found_proper_doctest && test_ignored {
|
||||
errors.push(format!(
|
||||
"`{}` has a compile_fail doctest with its own error code, it shouldn't \
|
||||
be listed in `IGNORE_DOCTEST_CHECK`",
|
||||
path.display(),
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
no_longer_emitted_codes
|
||||
}
|
||||
|
||||
/// This function returns a tuple indicating whether the provided explanation:
|
||||
/// a) has a code example, tested or not.
|
||||
/// b) has a valid doctest
|
||||
fn check_explanation_has_doctest(explanation: &str, err_code: &str) -> (bool, bool, bool, bool) {
|
||||
let mut found_code_example = false;
|
||||
let mut found_proper_doctest = false;
|
||||
|
||||
let mut emit_ignore_warning = false;
|
||||
let mut emit_no_longer_warning = false;
|
||||
|
||||
for line in explanation.lines() {
|
||||
let line = line.trim();
|
||||
|
||||
if line.starts_with("```") {
|
||||
found_code_example = true;
|
||||
|
||||
// Check for the `rustdoc` doctest headers.
|
||||
if line.contains("compile_fail") && line.contains(err_code) {
|
||||
found_proper_doctest = true;
|
||||
}
|
||||
|
||||
if line.contains("ignore") {
|
||||
emit_ignore_warning = true;
|
||||
found_proper_doctest = true;
|
||||
}
|
||||
} else if line
|
||||
.starts_with("#### Note: this error code is no longer emitted by the compiler")
|
||||
{
|
||||
emit_no_longer_warning = true;
|
||||
found_code_example = true;
|
||||
found_proper_doctest = true;
|
||||
}
|
||||
}
|
||||
|
||||
(found_code_example, found_proper_doctest, emit_ignore_warning, emit_no_longer_warning)
|
||||
}
|
||||
|
||||
// Stage 3: Checks that each error code has a UI test in the correct directory
|
||||
fn check_error_codes_tests(
|
||||
root_path: &Path,
|
||||
error_codes: &[String],
|
||||
errors: &mut Vec<String>,
|
||||
verbose: bool,
|
||||
) {
|
||||
let tests_path = root_path.join(Path::new(ERROR_TESTS_PATH));
|
||||
|
||||
for code in error_codes {
|
||||
let test_path = tests_path.join(format!("{}.stderr", code));
|
||||
|
||||
if !test_path.exists() && !IGNORE_UI_TEST_CHECK.contains(&code.as_str()) {
|
||||
verbose_print!(
|
||||
verbose,
|
||||
"warning: Error code `{code}` needs to have at least one UI test in the `src/test/ui/error-codes/` directory`!"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if IGNORE_UI_TEST_CHECK.contains(&code.as_str()) {
|
||||
if test_path.exists() {
|
||||
errors.push(format!(
|
||||
"Error code `{code}` has a UI test in `src/test/ui/error-codes/{code}.rs`, it shouldn't be listed in `EXEMPTED_FROM_TEST`!"
|
||||
));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
let file = match fs::read_to_string(&test_path) {
|
||||
Ok(file) => file,
|
||||
Err(err) => {
|
||||
verbose_print!(
|
||||
verbose,
|
||||
"warning: Failed to read UI test file (`{}`) for `{code}` but the file exists. The test is assumed to work:\n{err}",
|
||||
test_path.display()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let mut found_code = false;
|
||||
|
||||
for line in file.lines() {
|
||||
let s = line.trim();
|
||||
// Assuming the line starts with `error[E`, we can substring the error code out.
|
||||
if s.starts_with("error[E") {
|
||||
if &s[6..11] == code {
|
||||
found_code = true;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if !found_code {
|
||||
verbose_print!(
|
||||
verbose,
|
||||
"warning: Error code {code}`` has a UI test file, but doesn't contain its own error code!"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Stage 4: Search `compiler/` and ensure that every error code is actually used by the compiler and that no undocumented error codes exist.
|
||||
fn check_error_codes_used(
|
||||
search_paths: &[&Path],
|
||||
error_codes: &[String],
|
||||
errors: &mut Vec<String>,
|
||||
no_longer_emitted: &[String],
|
||||
verbose: bool,
|
||||
) {
|
||||
// We want error codes which match the following cases:
|
||||
//
|
||||
// * foo(a, E0111, a)
|
||||
// * foo(a, E0111)
|
||||
// * foo(E0111, a)
|
||||
// * #[error = "E0111"]
|
||||
let regex = Regex::new(r#"[(,"\s](E\d{4})[,)"]"#).unwrap();
|
||||
|
||||
let mut found_codes = Vec::new();
|
||||
|
||||
walk_many(search_paths, &mut filter_dirs, &mut |entry, contents| {
|
||||
let path = entry.path();
|
||||
|
||||
// Return early if we aren't looking at a source file.
|
||||
if path.extension() != Some(OsStr::new("rs")) {
|
||||
return;
|
||||
}
|
||||
|
||||
for line in contents.lines() {
|
||||
// We want to avoid parsing error codes in comments.
|
||||
if line.trim_start().starts_with("//") {
|
||||
continue;
|
||||
}
|
||||
|
||||
for cap in regex.captures_iter(line) {
|
||||
if let Some(error_code) = cap.get(1) {
|
||||
let error_code = error_code.as_str().to_owned();
|
||||
|
||||
if !error_codes.contains(&error_code) {
|
||||
// This error code isn't properly defined, we must error.
|
||||
errors.push(format!("Error code `{}` is used in the compiler but not defined and documented in `compiler/rustc_error_codes/src/error_codes.rs`.", error_code));
|
||||
continue;
|
||||
}
|
||||
|
||||
// This error code can now be marked as used.
|
||||
found_codes.push(error_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for code in error_codes {
|
||||
if !found_codes.contains(code) && !no_longer_emitted.contains(code) {
|
||||
errors.push(format!("Error code `{code}` exists, but is not emitted by the compiler!"))
|
||||
}
|
||||
|
||||
if found_codes.contains(code) && no_longer_emitted.contains(code) {
|
||||
verbose_print!(
|
||||
verbose,
|
||||
"warning: Error code `{code}` is used when it's marked as \"no longer emitted\""
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,305 +0,0 @@
|
||||
//! Checks that all error codes have at least one test to prevent having error
|
||||
//! codes that are silently not thrown by the compiler anymore.
|
||||
|
||||
use crate::walk::{filter_dirs, walk};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::ffi::OsStr;
|
||||
use std::fs::read_to_string;
|
||||
use std::path::Path;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
// A few of those error codes can't be tested but all the others can and *should* be tested!
|
||||
const EXEMPTED_FROM_TEST: &[&str] = &[
|
||||
"E0313", "E0461", "E0476", "E0490", "E0514", "E0523", "E0554", "E0640", "E0717", "E0729",
|
||||
"E0789",
|
||||
];
|
||||
|
||||
// Some error codes don't have any tests apparently...
|
||||
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E0729"];
|
||||
|
||||
// If the file path contains any of these, we don't want to try to extract error codes from it.
|
||||
//
|
||||
// We need to declare each path in the windows version (with backslash).
|
||||
const PATHS_TO_IGNORE_FOR_EXTRACTION: &[&str] =
|
||||
&["src/test/", "src\\test\\", "src/doc/", "src\\doc\\", "src/tools/", "src\\tools\\"];
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct ErrorCodeStatus {
|
||||
has_test: bool,
|
||||
has_explanation: bool,
|
||||
is_used: bool,
|
||||
}
|
||||
|
||||
fn check_error_code_explanation(
|
||||
f: &str,
|
||||
error_codes: &mut HashMap<String, ErrorCodeStatus>,
|
||||
err_code: String,
|
||||
) -> bool {
|
||||
let mut invalid_compile_fail_format = false;
|
||||
let mut found_error_code = false;
|
||||
|
||||
for line in f.lines() {
|
||||
let s = line.trim();
|
||||
if s.starts_with("```") {
|
||||
if s.contains("compile_fail") && s.contains('E') {
|
||||
if !found_error_code {
|
||||
error_codes.get_mut(&err_code).map(|x| x.has_test = true);
|
||||
found_error_code = true;
|
||||
}
|
||||
} else if s.contains("compile-fail") {
|
||||
invalid_compile_fail_format = true;
|
||||
}
|
||||
} else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
|
||||
if !found_error_code {
|
||||
error_codes.get_mut(&err_code).map(|x| x.has_test = true);
|
||||
found_error_code = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
invalid_compile_fail_format
|
||||
}
|
||||
|
||||
fn check_if_error_code_is_test_in_explanation(f: &str, err_code: &str) -> bool {
|
||||
let mut ignore_found = false;
|
||||
|
||||
for line in f.lines() {
|
||||
let s = line.trim();
|
||||
if s.starts_with("#### Note: this error code is no longer emitted by the compiler") {
|
||||
return true;
|
||||
}
|
||||
if s.starts_with("```") {
|
||||
if s.contains("compile_fail") && s.contains(err_code) {
|
||||
return true;
|
||||
} else if s.contains("ignore") {
|
||||
// It's very likely that we can't actually make it fail compilation...
|
||||
ignore_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ignore_found
|
||||
}
|
||||
|
||||
fn extract_error_codes(
|
||||
f: &str,
|
||||
error_codes: &mut HashMap<String, ErrorCodeStatus>,
|
||||
path: &Path,
|
||||
errors: &mut Vec<String>,
|
||||
) {
|
||||
let mut reached_no_explanation = false;
|
||||
|
||||
for line in f.lines() {
|
||||
let s = line.trim();
|
||||
if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") {
|
||||
let err_code = s
|
||||
.split_once(':')
|
||||
.expect(
|
||||
format!(
|
||||
"Expected a line with the format `E0xxx: include_str!(\"..\")`, but got {} \
|
||||
without a `:` delimiter",
|
||||
s,
|
||||
)
|
||||
.as_str(),
|
||||
)
|
||||
.0
|
||||
.to_owned();
|
||||
error_codes.entry(err_code.clone()).or_default().has_explanation = true;
|
||||
|
||||
// Now we extract the tests from the markdown file!
|
||||
let md_file_name = match s.split_once("include_str!(\"") {
|
||||
None => continue,
|
||||
Some((_, md)) => match md.split_once("\")") {
|
||||
None => continue,
|
||||
Some((file_name, _)) => file_name,
|
||||
},
|
||||
};
|
||||
|
||||
let Some(parent) = path.parent() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let path = parent
|
||||
.join(md_file_name)
|
||||
.canonicalize()
|
||||
.expect("failed to canonicalize error explanation file path");
|
||||
|
||||
match read_to_string(&path) {
|
||||
Ok(content) => {
|
||||
let has_test = check_if_error_code_is_test_in_explanation(&content, &err_code);
|
||||
if !has_test && !IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str()) {
|
||||
errors.push(format!(
|
||||
"`{}` doesn't use its own error code in compile_fail example",
|
||||
path.display(),
|
||||
));
|
||||
} else if has_test && IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str()) {
|
||||
errors.push(format!(
|
||||
"`{}` has a compile_fail example with its own error code, it shouldn't \
|
||||
be listed in IGNORE_EXPLANATION_CHECK!",
|
||||
path.display(),
|
||||
));
|
||||
}
|
||||
if check_error_code_explanation(&content, error_codes, err_code) {
|
||||
errors.push(format!(
|
||||
"`{}` uses invalid tag `compile-fail` instead of `compile_fail`",
|
||||
path.display(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Couldn't read `{}`: {}", path.display(), e);
|
||||
}
|
||||
}
|
||||
} else if reached_no_explanation && s.starts_with('E') {
|
||||
let err_code = match s.split_once(',') {
|
||||
None => s,
|
||||
Some((err_code, _)) => err_code,
|
||||
}
|
||||
.to_string();
|
||||
if !error_codes.contains_key(&err_code) {
|
||||
// this check should *never* fail!
|
||||
error_codes.insert(err_code, ErrorCodeStatus::default());
|
||||
}
|
||||
} else if s == ";" {
|
||||
reached_no_explanation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap<String, ErrorCodeStatus>) {
|
||||
for line in f.lines() {
|
||||
let s = line.trim();
|
||||
if s.starts_with("error[E") || s.starts_with("warning[E") {
|
||||
let err_code = match s.split_once(']') {
|
||||
None => continue,
|
||||
Some((err_code, _)) => match err_code.split_once('[') {
|
||||
None => continue,
|
||||
Some((_, err_code)) => err_code,
|
||||
},
|
||||
};
|
||||
error_codes.entry(err_code.to_owned()).or_default().has_test = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_error_codes_from_source(
|
||||
f: &str,
|
||||
error_codes: &mut HashMap<String, ErrorCodeStatus>,
|
||||
regex: &Regex,
|
||||
) {
|
||||
for line in f.lines() {
|
||||
if line.trim_start().starts_with("//") {
|
||||
continue;
|
||||
}
|
||||
for cap in regex.captures_iter(line) {
|
||||
if let Some(error_code) = cap.get(1) {
|
||||
error_codes.entry(error_code.as_str().to_owned()).or_default().is_used = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check(paths: &[&Path], bad: &mut bool) {
|
||||
let mut errors = Vec::new();
|
||||
let mut found_explanations = 0;
|
||||
let mut found_tests = 0;
|
||||
let mut error_codes: HashMap<String, ErrorCodeStatus> = HashMap::new();
|
||||
let mut explanations: HashSet<String> = HashSet::new();
|
||||
// We want error codes which match the following cases:
|
||||
//
|
||||
// * foo(a, E0111, a)
|
||||
// * foo(a, E0111)
|
||||
// * foo(E0111, a)
|
||||
// * #[error = "E0111"]
|
||||
let regex = Regex::new(r#"[(,"\s](E\d{4})[,)"]"#).unwrap();
|
||||
|
||||
for path in paths {
|
||||
walk(path, &mut filter_dirs, &mut |entry, contents| {
|
||||
let file_name = entry.file_name();
|
||||
let entry_path = entry.path();
|
||||
|
||||
if file_name == "error_codes.rs" {
|
||||
extract_error_codes(contents, &mut error_codes, entry.path(), &mut errors);
|
||||
found_explanations += 1;
|
||||
} else if entry_path.extension() == Some(OsStr::new("stderr")) {
|
||||
extract_error_codes_from_tests(contents, &mut error_codes);
|
||||
found_tests += 1;
|
||||
} else if entry_path.extension() == Some(OsStr::new("rs")) {
|
||||
let path = entry.path().to_string_lossy();
|
||||
if PATHS_TO_IGNORE_FOR_EXTRACTION.iter().all(|c| !path.contains(c)) {
|
||||
extract_error_codes_from_source(contents, &mut error_codes, ®ex);
|
||||
}
|
||||
} else if entry_path
|
||||
.parent()
|
||||
.and_then(|p| p.file_name())
|
||||
.map(|p| p == "error_codes")
|
||||
.unwrap_or(false)
|
||||
&& entry_path.extension() == Some(OsStr::new("md"))
|
||||
{
|
||||
explanations.insert(file_name.to_str().unwrap().replace(".md", ""));
|
||||
}
|
||||
});
|
||||
}
|
||||
if found_explanations == 0 {
|
||||
tidy_error!(bad, "No error code explanation was tested!");
|
||||
}
|
||||
if found_tests == 0 {
|
||||
tidy_error!(bad, "No error code was found in compilation errors!");
|
||||
}
|
||||
if explanations.is_empty() {
|
||||
tidy_error!(bad, "No error code explanation was found!");
|
||||
}
|
||||
if errors.is_empty() {
|
||||
for (err_code, error_status) in &error_codes {
|
||||
if !error_status.has_test && !EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
|
||||
errors.push(format!("Error code {err_code} needs to have at least one UI test!"));
|
||||
} else if error_status.has_test && EXEMPTED_FROM_TEST.contains(&err_code.as_str()) {
|
||||
errors.push(format!(
|
||||
"Error code {} has a UI test, it shouldn't be listed into EXEMPTED_FROM_TEST!",
|
||||
err_code
|
||||
));
|
||||
}
|
||||
if !error_status.is_used && !error_status.has_explanation {
|
||||
errors.push(format!(
|
||||
"Error code {} isn't used and doesn't have an error explanation, it should be \
|
||||
commented in error_codes.rs file",
|
||||
err_code
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
if errors.is_empty() {
|
||||
// Checking if local constants need to be cleaned.
|
||||
for err_code in EXEMPTED_FROM_TEST {
|
||||
match error_codes.get(err_code.to_owned()) {
|
||||
Some(status) => {
|
||||
if status.has_test {
|
||||
errors.push(format!(
|
||||
"{} error code has a test and therefore should be \
|
||||
removed from the `EXEMPTED_FROM_TEST` constant",
|
||||
err_code
|
||||
));
|
||||
}
|
||||
}
|
||||
None => errors.push(format!(
|
||||
"{} error code isn't used anymore and therefore should be removed \
|
||||
from `EXEMPTED_FROM_TEST` constant",
|
||||
err_code
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
if errors.is_empty() {
|
||||
for explanation in explanations {
|
||||
if !error_codes.contains_key(&explanation) {
|
||||
errors.push(format!(
|
||||
"{} error code explanation should be listed in `error_codes.rs`",
|
||||
explanation
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
errors.sort();
|
||||
for err in &errors {
|
||||
tidy_error!(bad, "{err}");
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
//! Tidy check to verify the validity of long error diagnostic codes.
|
||||
//!
|
||||
//! This ensures that error codes are used at most once and also prints out some
|
||||
//! statistics about the error codes.
|
||||
|
||||
use crate::walk::{filter_dirs, walk};
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn check(path: &Path, bad: &mut bool) {
|
||||
let mut map: HashMap<_, Vec<_>> = HashMap::new();
|
||||
walk(
|
||||
path,
|
||||
&mut |path| filter_dirs(path) || path.ends_with("src/test"),
|
||||
&mut |entry, contents| {
|
||||
let file = entry.path();
|
||||
let filename = file.file_name().unwrap().to_string_lossy();
|
||||
if filename != "error_codes.rs" {
|
||||
return;
|
||||
}
|
||||
|
||||
// In the `register_long_diagnostics!` macro, entries look like this:
|
||||
//
|
||||
// ```
|
||||
// EXXXX: r##"
|
||||
// <Long diagnostic message>
|
||||
// "##,
|
||||
// ```
|
||||
//
|
||||
// and these long messages often have error codes themselves inside
|
||||
// them, but we don't want to report duplicates in these cases. This
|
||||
// variable keeps track of whether we're currently inside one of these
|
||||
// long diagnostic messages.
|
||||
let mut inside_long_diag = false;
|
||||
for (num, line) in contents.lines().enumerate() {
|
||||
if inside_long_diag {
|
||||
inside_long_diag = !line.contains("\"##");
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut search = line;
|
||||
while let Some(i) = search.find('E') {
|
||||
search = &search[i + 1..];
|
||||
let code = if search.len() > 4 { search[..4].parse::<u32>() } else { continue };
|
||||
let code = match code {
|
||||
Ok(n) => n,
|
||||
Err(..) => continue,
|
||||
};
|
||||
map.entry(code).or_default().push((file.to_owned(), num + 1, line.to_owned()));
|
||||
break;
|
||||
}
|
||||
|
||||
inside_long_diag = line.contains("r##\"");
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
let mut max = 0;
|
||||
for (&code, entries) in map.iter() {
|
||||
if code > max {
|
||||
max = code;
|
||||
}
|
||||
if entries.len() == 1 {
|
||||
continue;
|
||||
}
|
||||
|
||||
tidy_error!(bad, "duplicate error code: {}", code);
|
||||
for &(ref file, line_num, ref line) in entries.iter() {
|
||||
tidy_error!(bad, "{}:{}: {}", file.display(), line_num, line);
|
||||
}
|
||||
}
|
||||
|
||||
if !*bad {
|
||||
println!("* {} error codes", map.len());
|
||||
println!("* highest error code: E{:04}", max);
|
||||
}
|
||||
}
|
@ -56,8 +56,7 @@ pub mod bins;
|
||||
pub mod debug_artifacts;
|
||||
pub mod deps;
|
||||
pub mod edition;
|
||||
pub mod error_codes_check;
|
||||
pub mod errors;
|
||||
pub mod error_codes;
|
||||
pub mod extdeps;
|
||||
pub mod features;
|
||||
pub mod mir_opt_tests;
|
||||
|
@ -27,6 +27,7 @@ fn main() {
|
||||
let src_path = root_path.join("src");
|
||||
let library_path = root_path.join("library");
|
||||
let compiler_path = root_path.join("compiler");
|
||||
let librustdoc_path = src_path.join("librustdoc");
|
||||
|
||||
let args: Vec<String> = env::args().skip(1).collect();
|
||||
|
||||
@ -79,8 +80,7 @@ fn main() {
|
||||
check!(mir_opt_tests, &src_path, bless);
|
||||
|
||||
// Checks that only make sense for the compiler.
|
||||
check!(errors, &compiler_path);
|
||||
check!(error_codes_check, &[&src_path, &compiler_path]);
|
||||
check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], verbose);
|
||||
|
||||
// Checks that only make sense for the std libs.
|
||||
check!(pal, &library_path);
|
||||
|
Loading…
Reference in New Issue
Block a user