diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 4fc4932..6e7a6da 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1952,7 +1952,7 @@ instead, we check that it's not a "finger" cursor. } } -:target:not([data-nosnippet]):not(:empty) { +:target:not([data-nosnippet]) { background-color: var(--target-background-color); border-right: 3px solid var(--target-border-color); } diff --git a/tests/rustdoc-gui/src/test_docs/lib.rs b/tests/rustdoc-gui/src/test_docs/lib.rs new file mode 100644 index 0000000..54db340 --- /dev/null +++ b/tests/rustdoc-gui/src/test_docs/lib.rs @@ -0,0 +1,829 @@ +// ignore-tidy-file-linelength +// +//@ compile-flags: --enable-index-page -Z unstable-options +//! The point of this crate is to be able to have enough different "kinds" of +//! documentation generated so we can test each different features. +#![doc(html_playground_url="https://play.rust-lang.org/")] + +#![crate_name = "test_docs"] +#![allow(internal_features)] +#![feature(rustdoc_internals)] +#![feature(doc_cfg)] +#![feature(associated_type_defaults)] +#![feature(macro_attr)] +#![feature(macro_derive)] +#![feature(negative_impls)] +#![feature(doc_notable_trait)] +#![feature(decl_macro)] + +/*! +Enable the feature some-feature to enjoy +this crate even more! +Enable the feature some-feature to enjoy +this crate even more! +Enable the feature some-feature to enjoy +this crate even more! + +Also, stop using `bar` as it's deprecated. +Also, stop using `bar` as it's deprecated. +Also, stop using `bar` as it's deprecated. + +Finally, you can use `quz` only on Unix or x86-64 +. +Finally, you can use `quz` only on Unix or x86-64 +. +*/ + +use std::convert::AsRef; +use std::fmt; + +/// Basic function with some code examples: +/// +/// ``` +/// println!("nothing fancy"); +/// println!("but with two lines!"); +/// ``` +/// +/// A failing to compile one: +/// +/// ```compile_fail +/// println!("where did my argument {} go? :'("); +/// ``` +/// +/// An ignored one: +/// +/// ```ignore (it's a test) +/// Let's say I'm just some text will ya? +/// ``` +/// +/// A failing to run one: +/// +/// ```should_panic +/// panic!("tadam"); +/// ``` +/// +/// An inlined `code`! +pub fn foo() {} + +/// Just a normal struct. +pub struct Foo; + +impl Foo { + #[must_use] + pub fn must_use(&self) -> bool { + true + } + + /// hello + /// + ///
this is a warning
+ /// + /// done + pub fn warning1() {} + + /// Checking there is no bottom margin if "warning" is the last element. + /// + ///
this is a warning
+ pub fn warning2() {} +} + +/// A collapsible trait impl with a link +impl AsRef for Foo { + fn as_ref(&self) -> &str { + "hello" + } +} + +unsafe impl Send for Foo {} +impl !Sync for Foo {} + +impl From for Foo { + fn from(value: u8) -> Self { todo!(); } +} +impl From for Foo { + fn from(value: u16) -> Self { todo!(); } +} +impl From for Foo { + fn from(value: u32) -> Self { todo!(); } +} + +///
I have warnings!
+pub struct WarningStruct; + +/// Just a normal enum. +/// +/// # title! +#[doc(alias = "ThisIsAnAlias")] +#[non_exhaustive] +pub enum WhoLetTheDogOut { + /// Woof! + Woof, + /// Meoooooooow... + Meow, +} + +/// Who doesn't love to wrap a `format!` call? +pub fn some_more_function(t: &T) -> String { + format!("{:?}", t) +} + +/// Woohoo! A trait! +pub trait AnotherOne { + /// Some func 3. + fn func3(); + + /// Some func 1. + fn func1(); + + fn another(); + fn why_not(); + + /// Some func 2. + fn func2(); + + fn hello(); +} + +/// ```compile_fail +/// whatever +/// ``` +/// +/// Check for "i" signs in lists! +/// +/// 1. elem 1 +/// 2. test 1 +/// ```compile_fail +/// fn foo() {} +/// ``` +/// 3. elem 3 +/// 4. ```ignore (it's a test) +/// fn foo() {} +/// ``` +/// 5. elem 5 +/// +/// Final one: +/// +/// ```ignore (still a test) +/// let x = 12; +/// ``` +pub fn check_list_code_block() {} + +/// a thing with a label +#[deprecated(since = "1.0.0", note = "text why this deprecated")] +#[doc(cfg(unix))] +pub fn replaced_function() {} + +/// Some doc with `code`! +pub enum AnEnum { + WithVariants { and: usize, sub: usize, variants: usize }, +} + +#[doc(keyword = "for")] +/// Some keyword. +const _: () = (); + +#[doc(attribute = "forbid")] +/// Some attribute. +const _: () = (); + +/// Just some type alias. +pub type SomeType = u32; + +/// Another type alias, this time with methods. +pub type SomeOtherTypeWithMethodsAndInlining = Foo; + +impl SomeOtherTypeWithMethodsAndInlining { + pub fn some_other_method_directly(&self) {} +} + +/// Another type alias, this time with methods. +pub struct UnderlyingFooBarBaz; +pub type SomeOtherTypeWithMethodsAndInliningAndTraits = UnderlyingFooBarBaz; + +impl AsRef for UnderlyingFooBarBaz { + fn as_ref(&self) -> &str { + "hello" + } +} + +impl UnderlyingFooBarBaz { + pub fn inherent_fn(&self) {} +} + +impl AsRef for SomeOtherTypeWithMethodsAndInliningAndTraits { + fn as_ref(&self) -> &u8 { + b"hello" + } +} + +pub mod huge_amount_of_consts { + include!(concat!(env!("OUT_DIR"), "/huge_amount_of_consts.rs")); +} + +/// Very long code text `hereIgoWithLongTextBecauseWhyNotAndWhyWouldntI`. +pub mod long_code_block {} + +/// Very long code text [`hereIgoWithLongTextBecauseWhyNotAndWhyWouldntI`][lnk]. +/// +/// [lnk]: crate::long_code_block_link +pub mod long_code_block_link {} + +#[macro_export] +macro_rules! repro { + () => {}; +} + +pub use crate::repro as repro2; + +/// # Top-doc Prose title +/// +/// Text below title. +/// +/// ## Top-doc Prose sub-heading +/// +/// Text below sub-heading. +/// +/// ### Top-doc Prose sub-sub-heading +/// +/// Text below sub-sub-heading +/// +/// #### You know the drill. +/// +/// More text. +pub struct HeavilyDocumentedStruct { + /// # Title for field + /// ## Sub-heading for field + pub nothing: (), +} + +/// # Title for struct impl doc +/// +/// Text below heading. +/// +/// ## Sub-heading for struct impl doc +/// +/// Text below sub-heading. +/// +/// ### Sub-sub-heading for struct impl doc +/// +/// Text below sub-sub-heading. +/// +impl HeavilyDocumentedStruct { + /// # Title for struct impl-item doc + /// Text below title. + /// ## Sub-heading for struct impl-item doc + /// Text below sub-heading. + /// ### Sub-sub-heading for struct impl-item doc + /// Text below sub-sub-heading. + pub fn do_nothing() {} +} + +/// # Top-doc Prose title +/// +/// Text below title. +/// +/// ## Top-doc Prose sub-heading +/// +/// Text below sub-heading. +/// +/// ### Top-doc Prose sub-sub-heading +/// +/// Text below sub-sub-heading +pub enum HeavilyDocumentedEnum { + /// # None prose title + /// ## None prose sub-heading + None, + /// # Wrapped prose title + /// ## Wrapped prose sub-heading + Wrapped( + /// # Wrapped.0 prose title + /// ## Wrapped.0 prose sub-heading + String, + String, + ), + Structy { + /// # Structy prose title + /// ## Structy prose sub-heading + alpha: String, + beta: String, + }, +} + +/// # Title for enum impl doc +/// +/// Text below heading. +/// +/// ## Sub-heading for enum impl doc +/// +/// Text below sub-heading. +/// +/// ### Sub-sub-heading for enum impl doc +/// +/// Text below sub-sub-heading. +/// +impl HeavilyDocumentedEnum { + /// # Title for enum impl-item doc + /// Text below title. + /// ## Sub-heading for enum impl-item doc + /// Text below sub-heading. + /// ### Sub-sub-heading for enum impl-item doc + /// Text below sub-sub-heading. + pub fn do_nothing() {} +} + +/// # Top-doc prose title +/// +/// Text below heading. +/// +/// ## Top-doc prose sub-heading +/// +/// Text below heading. +pub union HeavilyDocumentedUnion { + /// # Title for union variant + /// ## Sub-heading for union variant + pub nothing: (), + pub something: f32, +} + +/// # Title for union impl doc +/// ## Sub-heading for union impl doc +impl HeavilyDocumentedUnion { + /// # Title for union impl-item doc + /// ## Sub-heading for union impl-item doc + pub fn do_nothing() {} +} + +/// # Top-doc prose title +/// +/// Text below heading. +/// +/// ## Top-doc prose sub-heading +/// +/// Text below heading. +#[macro_export] +macro_rules! heavily_documented_macro { + () => {}; +} + +pub trait EmptyTrait1 {} +pub trait EmptyTrait2 {} +pub trait EmptyTrait3 {} + +pub struct HasEmptyTraits{} + +impl EmptyTrait1 for HasEmptyTraits {} +impl EmptyTrait2 for HasEmptyTraits {} +#[doc(cfg(feature = "some-feature"))] +impl EmptyTrait3 for HasEmptyTraits {} + +mod macros; +pub use macros::*; + +#[doc(alias = "AliasForTheStdReexport")] +pub use ::std as TheStdReexport; + +pub mod details { + /// We check the appearance of the `
`/`` in here. + /// + /// ## Hello + /// + ///
+ ///

I'm a summary

+ ///
I'm the content of the details!
+ ///
+ pub struct Details; + + impl Details { + /// We check the appearance of the `
`/`` in here. + /// + /// ## Hello + /// + ///
+ ///

I'm a summary

+ ///
I'm the content of the details!
+ ///
+ pub fn method() {} + } +} + +pub mod doc_block_table { + + pub trait DocBlockTableTrait { + fn foo(); + } + + /// Struct doc. + /// + /// | header1 | header2 | + /// |--------------------------|--------------------------| + /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum | + /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum | + /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum | + /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum | + pub struct DocBlockTable {} + + impl DocBlockTableTrait for DocBlockTable { + /// Trait impl func doc for struct. + /// + /// | header1 | header2 | + /// |--------------------------|--------------------------| + /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum | + fn foo() { + println!(); + } + } + +} + +pub struct NotableStructWithLongName(R); + +impl NotableStructWithLongName { + pub fn create_an_iterator_from_read(r: R) -> NotableStructWithLongName { Self(r) } +} + +impl std::iter::Iterator for NotableStructWithLongName { + type Item = (); + + fn next(&mut self) -> Option { () } +} + +pub trait TraitWithNoDocblocks { + fn first_fn(&self); + fn second_fn(&self); +} + +pub struct TypeWithNoDocblocks; + +impl TypeWithNoDocblocks { + fn x() -> Option { + Some(Self) + } + fn y() -> Option { + // code comment + let t = Self::x()?; + Some(0) + } +} + +impl TypeWithNoDocblocks { + pub fn first_fn(&self) {} + pub fn second_fn<'a>(&'a self) { + let x = 12; + let y = "a"; + let z = false; + } +} + +pub unsafe fn unsafe_fn() {} + +pub fn safe_fn() {} + +#[repr(C)] +pub struct WithGenerics { + pub s: S, + pub t: T, + pub e: E, + pub p: P, +} + +pub struct StructWithPublicUndocumentedFields { + pub first: u32, + pub second: u32, +} + +pub const CONST: u8 = 0; + +pub trait TraitWithoutGenerics { + const C: u8 = CONST; + type T = SomeType; + + fn foo(); +} + +pub mod trait_members { + pub trait TraitMembers { + /// Some type + type Type; + /// Some function + fn function(); + /// Some other function + fn function2(); + } + pub struct HasTrait; + impl TraitMembers for HasTrait { + type Type = u8; + fn function() {} + fn function2() {} + } +} + +pub struct TypeWithImplDoc; + +/// impl doc +impl TypeWithImplDoc { + /// fn doc + pub fn test_fn() {} +} + +/// +/// +/// ``` +/// one +/// ``` +/// +/// +/// +/// +/// +/// ``` +/// one +/// two +/// three +/// ``` +/// +/// +pub mod codeblock_sub {} +pub mod search_results { + + pub struct SearchResults { + pub foo: i32, + } + + #[macro_export] + macro_rules! foo { + () => {}; + } + +} + +pub mod fields { + pub struct Struct { + pub a: u8, + pub b: u32, + } + pub union Union { + pub a: u8, + pub b: u32, + } + pub enum Enum { + A { + a: u8, + b: u32, + }, + B { + a: u8, + b: u32, + }, + } +} + +pub mod cfgs { + #[doc(cfg(all( + any(not(feature = "appservice-api-c"), not(feature = "appservice-api-s")), + any(not(feature = "client"), not(feature = "server")), + )))] + /// Some docs. + pub mod cfgs {} +} + +pub struct ZyxwvutMethodDisambiguation; + +impl ZyxwvutMethodDisambiguation { + pub fn method_impl_disambiguation(&self) -> bool { + true + } +} + +pub trait ZyxwvutTrait { + fn method_impl_disambiguation(&self, x: usize) -> usize; +} + +impl ZyxwvutTrait for ZyxwvutMethodDisambiguation { + fn method_impl_disambiguation(&self, x: usize) -> usize { + x + } +} + +pub mod foreign_impl_order { + pub trait Foo { + fn f(&mut self, with: [u8; W]); + } + + impl Foo<4> for [u8; 4] { + fn f(&mut self, fg: [u8; 4]) {} + } + impl Foo<2> for [u8; 2] { + fn f(&mut self, fg: [u8; 2]) {} + } + impl Foo<1> for [u8; 1] { + fn f(&mut self, fg: [u8; 1]) {} + } + impl Foo<3> for [u8; 3] { + fn f(&mut self, fg: [u8; 3]) {} + } +} + +pub mod private { + pub struct Tuple(u32, u8); + pub struct Struct { + a: u8, + } + + pub union Union { + a: u8, + b: u16, + } + + pub enum Enum { + A, + #[doc(hidden)] + B, + } +} + +/// ``` +/// fn super_long_function_name_because_i_need_to_hit_the_limit_and_break_beyond_it() { +/// } +/// ``` +/// +/// ```text +/// fn super_long_function_name_because_i_need_to_hit_the_limit_and_break_beyond_it_v2() { +/// } +/// ``` +pub mod trait_bounds { + pub trait OneBound: Sized {} + pub trait TwoBounds: Sized + Copy {} + pub trait ThreeBounds: Sized + Copy + Eq {} +} + +pub mod short_docs { + /// mult_vec_num(x: &[f64], y: f64) + pub fn mult_vec_num() {} + + /// subt_vec_num(x: &[f64], y: f64) + pub fn subt_vec_num() {} +} + +pub mod long_list { + //! bla + //! + //! * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque et libero ut leo + //! interdum laoreet vitae a mi. Aliquam erat volutpat. Suspendisse volutpat non quam non + //! commodo. + //! + //! Praesent enim neque, imperdiet sed nisl at, lobortis egestas augue. Sed vitae tristique + //! augue. Phasellus vel pretium lectus. + //! * Praesent enim neque, imperdiet sed nisl at, lobortis egestas augue. Sed vitae tristique + //! augue. Phasellus vel pretium lectus. + //! * Praesent enim neque, imperdiet sed nisl at, lobortis egestas augue. Sed vitae tristique + //! augue. Phasellus vel pretium lectus. + //! + //! Another list: + //! + //! 100. [`TryFromBytes`](#a) indicates that a type may safely be converted from certain byte + //! sequence (conditional on runtime checks) + //! 101. [`FromZeros`](#a) indicates that a sequence of zero bytes represents a valid instance of + //! a type + //! 102. [`FromBytes`](#a) indicates that a type may safely be converted from an arbitrary byte + //! sequence +} + +pub struct ImplDoc; + +/// bla sondfosdnf sdfasd fadsd fdsa f ads fad sf sad f sad fasdfsafsa df dsafasdasd fsa dfadsfasd +/// fads fadfadd +/// +/// bla +impl ImplDoc { + pub fn bar() {} +} + +/// bla +/// +/// bla +impl ImplDoc { + pub fn bar2() {} +} + +/// | this::is::a::kinda::very::long::header::number::one | this::is::a::kinda::very::long::header::number::two | this::is::a::kinda::very::long::header::number::three | +/// |-|-|-| +/// | bla | bli | blob | +impl ImplDoc { + pub fn bar3() {} +} + +/// # h1 +/// +/// bla +impl ImplDoc { + pub fn bar4() {} +} + +/// * list +/// * list +/// * list +impl ImplDoc { + pub fn bar5() {} +} + +pub trait ItemsTrait { + /// You want doc, here is doc! + /// + /// blablala + type F; + + /// You want doc, here is doc! + /// + /// blablala + const X: u32; + + /// You want doc, here is doc! + /// + /// blablala + fn foo() {} + + /// You want doc, here is doc! + /// + /// blablala + fn bar(); +} + +pub mod SidebarSort { + use std::cell::Cell; + use std::sync::atomic::*; + pub trait Sort {} + + impl Sort for u32 {} + impl Sort for u8 {} + impl Sort for u16 {} + impl Sort for usize {} + impl Sort for AtomicU32 {} + impl Sort for AtomicU16 {} + impl Sort for AtomicU8 {} + impl Sort for AtomicBool {} + impl Sort for Cell {} + impl Sort for Cell {} + impl<'a> Sort for &'a str {} +} + +pub mod impls_indent { + pub struct Context; + + /// Working with objects. + /// + /// # Safety + /// + /// Functions that take indices of locals do not check bounds on these indices; + /// the caller must ensure that the indices are less than the number of locals + /// in the current stack frame. + impl Context { + } + + /// Working with objects. + /// + /// # Safety + /// + /// Functions that take indices of locals do not check bounds on these indices; + /// the caller must ensure that the indices are less than the number of locals + /// in the current stack frame. + impl Context { + /// bla + pub fn bar() {} + } +} + +pub mod tooltips { + pub struct X; + + impl X { + pub fn bar() -> Vec { + Vec::new() + } + } + + pub fn bar() -> Vec { + Vec::new() + } +} + +pub mod tyalias { + pub struct X(pub T); + + impl X { + pub fn blob(&self) {} + } + + pub type Y = X; +} + +pub mod notable { + #[doc(notable_trait)] + pub trait Labeled {} + + pub struct Wrapper; + impl Labeled for Wrapper {} +} + +pub macro decl_macro { + () => { "bar" } +} diff --git a/tests/rustdoc-gui/warning-block.goml b/tests/rustdoc-gui/warning-block.goml new file mode 100644 index 0000000..34207ed --- /dev/null +++ b/tests/rustdoc-gui/warning-block.goml @@ -0,0 +1,55 @@ +// Test to check that the "warning blocks" are displayed as expected. +include: "utils.goml" +go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" +show-text: true + +store-value: (default_y_pos, 5) +define-function: ( + "check-warning", + [theme, color, border_color], + block { + call-function: ("switch-theme", {"theme": |theme|}) + + // The IDs are added directly into the DOM to make writing this test easier. + assert-css: ("#doc-warning-1", { + "margin-bottom": "12px", + "color": |color|, + "border-left": "2px solid " + |border_color|, + "background-color": "transparent", + }) + store-position: ("#doc-warning-1", {"y": warn_div_y}) + store-position: ("#doc-warning-1::before", {"y": warn_y}) + assert: |warn_y| == |warn_div_y| + |default_y_pos| + assert-css: ("#doc-warning-2", { + "margin-bottom": "0px", + "color": |color|, + "border-left": "2px solid " + |border_color|, + "background-color": "transparent", + }) + store-position: ("#doc-warning-2", {"y": warn_div_y}) + store-position: ("#doc-warning-2::before", {"y": warn_y}) + assert: |warn_y| == |warn_div_y| + |default_y_pos| + }, +) + +call-function: ("check-warning", { + "theme": "ayu", + "color": "#c5c5c5", + "border_color": "#ff8e00", +}) +call-function: ("check-warning", { + "theme": "dark", + "color": "#ddd", + "border_color": "#ff8e00", +}) +call-function: ("check-warning", { + "theme": "light", + "color": "black", + "border_color": "#ff8e00", +}) + +// We ensure that the warning element in the top doc is not overlaying the "[-]" button. +go-to: "file://" + |DOC_PATH| + "/test_docs/struct.WarningStruct.html" +store-position: ("#doc-warning-0", {"y": warn_div_y}) +store-position: ("#doc-warning-0::before", {"y": warn_y}) +assert: |warn_y| == |warn_div_y| + |default_y_pos| + 15