diff options
Diffstat (limited to '')
129 files changed, 1918 insertions, 634 deletions
diff --git a/src/test/rustdoc-gui/basic.goml b/src/test/rustdoc-gui/basic.goml deleted file mode 100644 index 60292835b..000000000 --- a/src/test/rustdoc-gui/basic.goml +++ /dev/null @@ -1,4 +0,0 @@ -goto: "file://" + |DOC_PATH| + "/test_docs/index.html" -assert: ("#functions") -goto: "./struct.Foo.html" -assert: ("div.item-decl") diff --git a/src/test/rustdoc-gui/code-tags.goml b/src/test/rustdoc-gui/code-tags.goml index 837a2c1d5..94c1a6525 100644 --- a/src/test/rustdoc-gui/code-tags.goml +++ b/src/test/rustdoc-gui/code-tags.goml @@ -1,4 +1,8 @@ // This test ensures that items and documentation code blocks are wrapped in <pre><code> + +// We need to disable this check because `implementors/test_docs/trait.AnotherOne.js` +// doesn't exist. +fail-on-request-error: false goto: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" size: (1080, 600) // There should be four doc codeblocks. diff --git a/src/test/rustdoc-gui/codeblock-tooltip.goml b/src/test/rustdoc-gui/codeblock-tooltip.goml index 8e681a2a0..4d923be3e 100644 --- a/src/test/rustdoc-gui/codeblock-tooltip.goml +++ b/src/test/rustdoc-gui/codeblock-tooltip.goml @@ -4,7 +4,7 @@ show-text: true define-function: ( "check-colors", - (theme), + (theme, background, color, border), [ // Setting the theme. ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), @@ -30,6 +30,25 @@ define-function: ( ".docblock .example-wrap.compile_fail", {"border-left": "2px solid rgb(255, 0, 0)"}, )), + ("assert-css", ( + ".docblock .example-wrap.compile_fail .tooltip::after", + { + "content": '"This example deliberately fails to compile"', + "text-align": "center", + "padding": "5px 3px 3px", + "background-color": |background|, + "color": |color|, + "border": "1px solid " + |border|, + }, + )), + ("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", ( @@ -51,6 +70,25 @@ define-function: ( ".docblock .example-wrap.should_panic", {"border-left": "2px solid rgb(255, 0, 0)"}, )), + ("assert-css", ( + ".docblock .example-wrap.should_panic .tooltip::after", + { + "content": '"This example panics"', + "text-align": "center", + "padding": "5px 3px 3px", + "background-color": |background|, + "color": |color|, + "border": "1px solid " + |border|, + }, + )), + ("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", ( @@ -72,9 +110,43 @@ define-function: ( ".docblock .example-wrap.ignore", {"border-left": "2px solid rgb(255, 142, 0)"}, )), + ("assert-css", ( + ".docblock .example-wrap.ignore .tooltip::after", + { + "content": '"This example is not tested"', + "text-align": "center", + "padding": "5px 3px 3px", + "background-color": |background|, + "color": |color|, + "border": "1px solid " + |border|, + }, + )), + ("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", ("ayu")) -call-function: ("check-colors", ("dark")) -call-function: ("check-colors", ("light")) +call-function: ("check-colors", { + "theme": "ayu", + "background": "rgb(49, 69, 89)", + "color": "rgb(197, 197, 197)", + "border": "rgb(92, 103, 115)", +}) +call-function: ("check-colors", { + "theme": "dark", + "background": "rgb(0, 0, 0)", + "color": "rgb(255, 255, 255)", + "border": "rgb(224, 224, 224)", +}) +call-function: ("check-colors", { + "theme": "light", + "background": "rgb(0, 0, 0)", + "color": "rgb(255, 255, 255)", + "border": "rgb(224, 224, 224)", +}) diff --git a/src/test/rustdoc-gui/cursor.goml b/src/test/rustdoc-gui/cursor.goml new file mode 100644 index 000000000..b2e91cb81 --- /dev/null +++ b/src/test/rustdoc-gui/cursor.goml @@ -0,0 +1,24 @@ +// This test ensures that several clickable items actually have the pointer cursor. +goto: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html" + +// the `[+]/[-]` button +assert-css: ("#toggle-all-docs", {"cursor": "pointer"}) + +// the button next to the path header +assert-css: ("#copy-path", {"cursor": "pointer"}) + +// the search tabs +write: (".search-input", "Foo") +// To be SURE that the search will be run. +press-key: 'Enter' +// Waiting for the search results to appear... +wait-for: "#titles" +assert-css: ("#titles > button", {"cursor": "pointer"}) + +// mobile sidebar toggle button +size: (500, 700) +assert-css: (".sidebar-menu-toggle", {"cursor": "pointer"}) + +// the sidebar toggle button on the source code pages +goto: "file://" + |DOC_PATH| + "/src/lib2/lib.rs.html" +assert-css: ("#sidebar-toggle > button", {"cursor": "pointer"}) diff --git a/src/test/rustdoc-gui/docblock-code-block-line-number.goml b/src/test/rustdoc-gui/docblock-code-block-line-number.goml index 911ee34be..fec21ad35 100644 --- a/src/test/rustdoc-gui/docblock-code-block-line-number.goml +++ b/src/test/rustdoc-gui/docblock-code-block-line-number.goml @@ -30,10 +30,10 @@ wait-for: "#settings" assert-css: ("#settings", {"display": "block"}) // Then, click the toggle button. -click: "input#line-numbers + .slider" +click: "input#line-numbers" wait-for: 100 // wait-for-false does not exist assert-false: "pre.example-line-numbers" // Finally, turn it on again. -click: "input#line-numbers + .slider" +click: "input#line-numbers" wait-for: "pre.example-line-numbers" diff --git a/src/test/rustdoc-gui/docblock-table.goml b/src/test/rustdoc-gui/docblock-table.goml index 4e316ce0b..8645c1b19 100644 --- a/src/test/rustdoc-gui/docblock-table.goml +++ b/src/test/rustdoc-gui/docblock-table.goml @@ -2,3 +2,50 @@ goto: "file://" + |DOC_PATH| + "/test_docs/doc_block_table/struct.DocBlockTable. compare-elements-css: (".impl-items .docblock table th", ".top-doc .docblock table th", ["border"]) compare-elements-css: (".impl-items .docblock table td", ".top-doc .docblock table td", ["border"]) + +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)", { + "background-color": "rgba(0, 0, 0, 0)", + })), + ("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)", { + "background-color": "rgba(0, 0, 0, 0)", + })), + ("assert-css", (".top-doc .docblock table tbody tr:nth-child(4)", { + "background-color": |zebra_stripe_color|, + })), + ("assert-css", (".top-doc .docblock table td", { + "border-style": "solid", + "border-width": "1px", + "border-color": |border_color|, + })), + ("assert-css", (".top-doc .docblock table th", { + "border-style": "solid", + "border-width": "1px", + "border-color": |border_color|, + })), + ] +) + +call-function: ("check-colors", { + "theme": "dark", + "border_color": "rgb(224, 224, 224)", + "zebra_stripe_color": "rgb(42, 42, 42)", +}) +call-function: ("check-colors", { + "theme": "ayu", + "border_color": "rgb(92, 103, 115)", + "zebra_stripe_color": "rgb(25, 31, 38)", +}) +call-function: ("check-colors", { + "theme": "light", + "border_color": "rgb(224, 224, 224)", + "zebra_stripe_color": "rgb(245, 245, 245)", +}) diff --git a/src/test/rustdoc-gui/enum-variants.goml b/src/test/rustdoc-gui/enum-variants.goml new file mode 100644 index 000000000..8dfc49285 --- /dev/null +++ b/src/test/rustdoc-gui/enum-variants.goml @@ -0,0 +1,10 @@ +// Verifies that there is non-zero margin on variants and their docblocks. +goto: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html" + +assert-css: (".variants > .variant", {"margin": "0px 0px 12px"}) +assert-css: (".variants > .docblock", {"margin": "0px 0px 32px 24px"}) + +assert-css: ( + "details.non-exhaustive > summary", + {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'}, +) diff --git a/src/test/rustdoc-gui/help-page.goml b/src/test/rustdoc-gui/help-page.goml index 521e14748..799ba851c 100644 --- a/src/test/rustdoc-gui/help-page.goml +++ b/src/test/rustdoc-gui/help-page.goml @@ -3,6 +3,7 @@ goto: "file://" + |DOC_PATH| + "/help.html" size: (1000, 1000) // Try desktop size first. wait-for: "#help" assert-css: ("#help", {"display": "block"}) +assert-css: ("#help dd", {"font-size": "16px"}) click: "#help-button > a" assert-css: ("#help", {"display": "block"}) compare-elements-property: (".sub", "#help", ["offsetWidth"]) @@ -12,12 +13,51 @@ assert-css: ("#help", {"display": "block"}) compare-elements-property: (".sub", "#help", ["offsetWidth"]) compare-elements-position: (".sub", "#help", ("x")) +// Checking the color of the elements of the help menu. +show-text: true +define-function: ( + "check-colors", + (theme, color, background, box_shadow), + [ + // Setting the theme. + ("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", { + "color": |color|, + "background-color": |background|, + "box-shadow": |box_shadow| + " 0px -1px 0px 0px inset", + "cursor": "default", + }, ALL)), + ], +) + +call-function: ("check-colors", { + "theme": "ayu", + "color": "rgb(197, 197, 197)", + "background": "rgb(49, 69, 89)", + "box_shadow": "rgb(92, 103, 115)", +}) +call-function: ("check-colors", { + "theme": "dark", + "color": "rgb(221, 221, 221)", + "background": "rgb(250, 251, 252)", + "box_shadow": "rgb(198, 203, 209)", +}) +call-function: ("check-colors", { + "theme": "light", + "color": "rgb(0, 0, 0)", + "background": "rgb(250, 251, 252)", + "box_shadow": "rgb(198, 203, 209)", +}) + // This test ensures that opening the help popover without switching pages works. goto: "file://" + |DOC_PATH| + "/test_docs/index.html" size: (1000, 1000) // Only supported on desktop. assert-false: "#help" click: "#help-button > a" assert-css: ("#help", {"display": "block"}) +assert-css: ("#help dd", {"font-size": "16px"}) click: "#help-button > a" assert-css: ("#help", {"display": "none"}) compare-elements-property-false: (".sub", "#help", ["offsetWidth"]) diff --git a/src/test/rustdoc-gui/highlight-colors.goml b/src/test/rustdoc-gui/highlight-colors.goml index 51693314e..ff1be389d 100644 --- a/src/test/rustdoc-gui/highlight-colors.goml +++ b/src/test/rustdoc-gui/highlight-colors.goml @@ -15,7 +15,7 @@ define-function: ( string, bool_val, self, - attribute, + attr, macro, question_mark, comment, @@ -33,7 +33,7 @@ define-function: ( ("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 .attribute", {"color": |attribute|}, 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)), @@ -52,7 +52,7 @@ call-function: ("check-colors", { "string": "rgb(184, 204, 82)", "bool_val": "rgb(255, 119, 51)", "self": "rgb(54, 163, 217)", - "attribute": "rgb(230, 225, 207)", + "attr": "rgb(230, 225, 207)", "macro": "rgb(163, 122, 204)", "question_mark": "rgb(255, 144, 17)", "comment": "rgb(120, 135, 151)", @@ -69,7 +69,7 @@ call-function: ("check-colors", { "string": "rgb(131, 163, 0)", "bool_val": "rgb(238, 104, 104)", "self": "rgb(238, 104, 104)", - "attribute": "rgb(238, 104, 104)", + "attr": "rgb(238, 104, 104)", "macro": "rgb(62, 153, 159)", "question_mark": "rgb(255, 144, 17)", "comment": "rgb(141, 141, 139)", @@ -86,7 +86,7 @@ call-function: ("check-colors", { "string": "rgb(113, 140, 0)", "bool_val": "rgb(200, 40, 41)", "self": "rgb(200, 40, 41)", - "attribute": "rgb(200, 40, 41)", + "attr": "rgb(200, 40, 41)", "macro": "rgb(62, 153, 159)", "question_mark": "rgb(255, 144, 17)", "comment": "rgb(142, 144, 140)", diff --git a/src/test/rustdoc-gui/huge-logo.goml b/src/test/rustdoc-gui/huge-logo.goml new file mode 100644 index 000000000..01f06771c --- /dev/null +++ b/src/test/rustdoc-gui/huge-logo.goml @@ -0,0 +1,21 @@ +// huge_logo crate has a custom 712x860 logo +// test to ensure the maximum size in the layout works correctly +goto: "file://" + |DOC_PATH| + "/huge_logo/index.html" + +size: (1280, 1024) +// offsetWidth = width of sidebar +assert-property: (".sidebar .logo-container", {"offsetWidth": "200", "offsetHeight": 100}) +assert-property: (".sidebar .logo-container img", {"offsetWidth": "100", "offsetHeight": 100}) + +size: (400, 600) +// offset = size + margin +assert-property: (".mobile-topbar .logo-container", {"offsetWidth": "55", "offsetHeight": 45}) +assert-property: (".mobile-topbar .logo-container img", {"offsetWidth": "35", "offsetHeight": 35}) + +goto: "file://" + |DOC_PATH| + "/src/huge_logo/lib.rs.html" + +size: (1280, 1024) +assert-property: (".sub-logo-container", {"offsetWidth": "60", "offsetHeight": 60}) + +size: (400, 600) +assert-property: (".sub-logo-container", {"offsetWidth": "35", "offsetHeight": 35}) diff --git a/src/test/rustdoc-gui/item-decl-colors.goml b/src/test/rustdoc-gui/item-decl-colors.goml index ce688287a..2e07f19b1 100644 --- a/src/test/rustdoc-gui/item-decl-colors.goml +++ b/src/test/rustdoc-gui/item-decl-colors.goml @@ -1,4 +1,9 @@ // This test ensures that the color of the items in the type decl are working as expected. + +// We need to disable this check because `implementors/test_docs/trait.TraitWithoutGenerics.js` +// doesn't exist. +fail-on-request-error: false + define-function: ( "check-colors", ( @@ -25,7 +30,7 @@ define-function: ( ("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 .fnname", {"color": |fn_color|}, ALL)), + ("assert-css", (".item-decl .fn", {"color": |fn_color|}, ALL)), ("assert-css", (".item-decl .associatedtype", {"color": |assoc_type_color|}, ALL)), ], ) diff --git a/src/test/rustdoc-gui/method-margins.goml b/src/test/rustdoc-gui/method-margins.goml new file mode 100644 index 000000000..ed36bcdec --- /dev/null +++ b/src/test/rustdoc-gui/method-margins.goml @@ -0,0 +1,18 @@ +// This test ensures that the margins on methods are coherent inside an impl block. +goto: "file://" + |DOC_PATH| + "/test_docs/trait_members/struct.HasTrait.html#impl-TraitMembers-for-HasTrait" + +assert-count: ("#trait-implementations-list > .rustdoc-toggle", 1) + +compare-elements-css: ( + // compare margin on type with margin on method + "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(1) > summary", + "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(2) > summary", + ["margin"] +) + +compare-elements-css: ( + // compare margin on type with margin on method + "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(1)", + "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(2)", + ["margin"] +) diff --git a/src/test/rustdoc-gui/no-docblock.goml b/src/test/rustdoc-gui/no-docblock.goml index 2366a60f5..17a955064 100644 --- a/src/test/rustdoc-gui/no-docblock.goml +++ b/src/test/rustdoc-gui/no-docblock.goml @@ -1,4 +1,9 @@ // This test checks that there are margins applied to methods with no docblocks. + +// We need to disable this check because `implementors/test_docs/trait.TraitWithNoDocblock.js` +// doesn't exist. +fail-on-request-error: false + goto: "file://" + |DOC_PATH| + "/test_docs/trait.TraitWithNoDocblocks.html" // Check that the two methods are more than 24px apart. compare-elements-position-near-false: ("//*[@id='tymethod.first_fn']", "//*[@id='tymethod.second_fn']", {"y": 24}) diff --git a/src/test/rustdoc-gui/notable-trait.goml b/src/test/rustdoc-gui/notable-trait.goml index efe0cb15f..7d4bd27d4 100644 --- a/src/test/rustdoc-gui/notable-trait.goml +++ b/src/test/rustdoc-gui/notable-trait.goml @@ -22,25 +22,26 @@ assert-position: ( ) assert-position: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - {"x": 951}, + {"x": 955}, ) -// The tooltip should be beside the `i` +// The tooltip should be below the `i` +// Also, clicking the tooltip should bring its text into the DOM +assert-count: ("//*[@class='notable popover']", 0) click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +assert-count: ("//*[@class='notable popover']", 1) compare-elements-position-near: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']", - {"y": 2} + "//*[@class='notable popover']", + {"y": 30} ) compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']", + "//*[@class='notable popover']", ("x") ) -// The docblock should be flush with the border. -assert-css: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']/*[@class='docblock']", - {"margin-left": "0px"} -) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +move-cursor-to: "//h1" +assert-count: ("//*[@class='notable popover']", 0) // Now only the `i` should be on the next line. size: (1055, 600) @@ -71,7 +72,7 @@ assert-position: ( ) assert-position: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - {"x": 519}, + {"x": 523}, ) // Checking on mobile now. @@ -95,34 +96,181 @@ assert-position: ( ) assert-position: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - {"x": 289}, + {"x": 293}, ) -// The tooltip should be below `i` -compare-elements-position-near-false: ( +// The tooltip should STILL be below `i` +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +assert-count: ("//*[@class='notable popover']", 1) +compare-elements-position-near: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']", - {"y": 2} + "//*[@class='notable popover']", + {"y": 30} ) compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']", + "//*[@class='notable popover']", ("x") ) -compare-elements-position-near: ( - "//*[@id='method.create_an_iterator_from_read']/parent::*", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']", - {"x": 5} +assert-position: ( + "//*[@class='notable popover']", + {"x": 0} ) -// The docblock should be flush with the border. -assert-css: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']/*[@class='docblock']", - {"margin-left": "0px"} +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +move-cursor-to: "//h1" +assert-count: ("//*[@class='notable popover']", 0) + +// Now check the colors. +define-function: ( + "check-colors", + (theme, header_color, content_color, type_color, trait_color), + [ + ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html"), + // This is needed to ensure that the text color is computed. + ("show-text", true), + + // Setting the theme. + ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + // We reload the page so the local storage settings are being used. + ("reload"), + + ("move-cursor-to", "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"), + ("assert-count", (".notable.popover", 1)), + + ("assert-css", ( + ".notable.popover h3", + {"color": |header_color|}, + ALL, + )), + ("assert-css", ( + ".notable.popover pre", + {"color": |content_color|}, + ALL, + )), + ("assert-css", ( + ".notable.popover pre a.struct", + {"color": |type_color|}, + ALL, + )), + ("assert-css", ( + ".notable.popover pre a.trait", + {"color": |trait_color|}, + ALL, + )), + ] ) -// Checking on very small mobile. The `i` should be on its own line. -size: (365, 600) -compare-elements-position-false: ( - "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - ("y", "x"), +call-function: ( + "check-colors", + { + "theme": "ayu", + "content_color": "rgb(230, 225, 207)", + "header_color": "rgb(255, 255, 255)", + "type_color": "rgb(255, 160, 165)", + "trait_color": "rgb(57, 175, 215)", + }, +) + +call-function: ( + "check-colors", + { + "theme": "dark", + "content_color": "rgb(221, 221, 221)", + "header_color": "rgb(221, 221, 221)", + "type_color": "rgb(45, 191, 184)", + "trait_color": "rgb(183, 140, 242)", + }, +) + +call-function: ( + "check-colors", + { + "theme": "light", + "content_color": "rgb(0, 0, 0)", + "header_color": "rgb(0, 0, 0)", + "type_color": "rgb(173, 55, 138)", + "trait_color": "rgb(110, 79, 201)", + }, ) + +reload: + +// Check that pressing escape works +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +move-cursor-to: "//*[@class='notable popover']" +assert-count: ("//*[@class='notable popover']", 1) +press-key: "Escape" +assert-count: ("//*[@class='notable popover']", 0) +assert: "#method\.create_an_iterator_from_read .notable-traits:focus" + +// Check that clicking outside works. +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +assert-count: ("//*[@class='notable popover']", 1) +click: ".search-input" +assert-count: ("//*[@class='notable popover']", 0) +assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus" + +// Check that pressing tab over and over works. +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +move-cursor-to: "//*[@class='notable popover']" +assert-count: ("//*[@class='notable popover']", 1) +press-key: "Tab" +press-key: "Tab" +press-key: "Tab" +press-key: "Tab" +press-key: "Tab" +press-key: "Tab" +press-key: "Tab" +assert-count: ("//*[@class='notable popover']", 0) +assert: "#method\.create_an_iterator_from_read .notable-traits:focus" + +// Now we check that the focus isn't given back to the wrong item when opening +// another popover. +store-window-property: (scroll, "scrollY") +click: "#method\.create_an_iterator_from_read .fn" +// We ensure that the scroll position changed. +assert-window-property-false: {"scrollY": |scroll|} +// Store the new position. +store-window-property: (scroll, "scrollY") +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +wait-for: "//*[@class='notable popover']" +click: "#settings-menu a" +click: ".search-input" +// We ensure we didn't come back to the previous focused item. +assert-window-property-false: {"scrollY": |scroll|} + +// Same but with Escape handling. +store-window-property: (scroll, "scrollY") +click: "#method\.create_an_iterator_from_read .fn" +// We ensure that the scroll position changed. +assert-window-property-false: {"scrollY": |scroll|} +// Store the new position. +store-window-property: (scroll, "scrollY") +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +wait-for: "//*[@class='notable popover']" +click: "#settings-menu a" +press-key: "Escape" +// We ensure we didn't come back to the previous focused item. +assert-window-property-false: {"scrollY": |scroll|} + +// Opening the mobile sidebar should close the popover. +size: (650, 600) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +assert-count: ("//*[@class='notable popover']", 1) +click: ".sidebar-menu-toggle" +assert: "//*[@class='sidebar shown']" +assert-count: ("//*[@class='notable popover']", 0) +assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus" +// Clicking a notable popover should close the sidebar. +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +assert-count: ("//*[@class='notable popover']", 1) +assert-false: "//*[@class='sidebar shown']" + +// Also check the focus handling for the help button. +size: (1100, 600) +reload: +assert-count: ("//*[@class='notable popover']", 0) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +assert-count: ("//*[@class='notable popover']", 1) +click: "#help-button a" +assert-count: ("//*[@class='notable popover']", 0) +assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus" diff --git a/src/test/rustdoc-gui/pocket-menu.goml b/src/test/rustdoc-gui/pocket-menu.goml index fb63ea62a..c3649dc7b 100644 --- a/src/test/rustdoc-gui/pocket-menu.goml +++ b/src/test/rustdoc-gui/pocket-menu.goml @@ -75,3 +75,24 @@ assert-css: ( ) compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"]) compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"]) + +// Opening the mobile sidebar should close the settings popover. +size: (650, 600) +click: "#settings-menu a" +assert-css: ("#settings-menu .popover", {"display": "block"}) +click: ".sidebar-menu-toggle" +assert: "//*[@class='sidebar shown']" +assert-css: ("#settings-menu .popover", {"display": "none"}) +// Opening the settings popover should close the sidebar. +click: "#settings-menu a" +assert-css: ("#settings-menu .popover", {"display": "block"}) +assert-false: "//*[@class='sidebar shown']" + +// Opening the settings popover at start (which async loads stuff) should also close. +reload: +click: ".sidebar-menu-toggle" +assert: "//*[@class='sidebar shown']" +assert-false: "#settings-menu .popover" +click: "#settings-menu a" +assert-false: "//*[@class='sidebar shown']" +wait-for: "#settings-menu .popover" diff --git a/src/test/rustdoc-gui/run-on-hover.goml b/src/test/rustdoc-gui/run-on-hover.goml index 6c785e1c4..57d63049f 100644 --- a/src/test/rustdoc-gui/run-on-hover.goml +++ b/src/test/rustdoc-gui/run-on-hover.goml @@ -1,7 +1,54 @@ // Example code blocks sometimes have a "Run" button to run them on the // Playground. That button is hidden until the user hovers over the code block. -// This test checks that it is hidden, and that it shows on hover. +// This test checks that it is hidden, and that it shows on hover. It also +// checks for its color. goto: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" -assert-css: (".test-arrow", {"visibility": "hidden"}) -move-cursor-to: ".example-wrap" -assert-css: (".test-arrow", {"visibility": "visible"}) +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", { + "visibility": "visible", + "color": |color|, + "background-color": |background|, + "font-size": "22px", + "border-radius": "5px", + })), + ("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", { + "theme": "ayu", + "color": "rgb(120, 135, 151)", + "background": "rgba(57, 175, 215, 0.09)", + "hover_color": "rgb(197, 197, 197)", + "hover_background": "rgba(57, 175, 215, 0.37)", +}) +call-function: ("check-run-button", { + "theme": "dark", + "color": "rgb(222, 222, 222)", + "background": "rgba(78, 139, 202, 0.2)", + "hover_color": "rgb(222, 222, 222)", + "hover_background": "rgb(78, 139, 202)", +}) +call-function: ("check-run-button", { + "theme": "light", + "color": "rgb(245, 245, 245)", + "background": "rgba(78, 139, 202, 0.2)", + "hover_color": "rgb(245, 245, 245)", + "hover_background": "rgb(78, 139, 202)", +}) diff --git a/src/test/rustdoc-gui/rust-logo.goml b/src/test/rustdoc-gui/rust-logo.goml index 6c8dc8594..816cc9abd 100644 --- a/src/test/rustdoc-gui/rust-logo.goml +++ b/src/test/rustdoc-gui/rust-logo.goml @@ -17,6 +17,15 @@ define-function: ( ("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"), + // Changing theme on the new page (again...). + ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + ("reload"), + // Check there is no rust logo + ("assert-false", ".rust-logo"), + // Check there is no filter. + ("assert-css", (".sidebar .logo-container img", {"filter": "none"})), ], ) diff --git a/src/test/rustdoc-gui/scrape-examples-button-focus.goml b/src/test/rustdoc-gui/scrape-examples-button-focus.goml new file mode 100644 index 000000000..bba518db0 --- /dev/null +++ b/src/test/rustdoc-gui/scrape-examples-button-focus.goml @@ -0,0 +1,29 @@ +goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html" + +// The next/prev buttons vertically scroll the code viewport between examples +store-property: (initialScrollTop, ".scraped-example-list > .scraped-example pre", "scrollTop") +focus: ".scraped-example-list > .scraped-example .next" +press-key: "Enter" +assert-property-false: (".scraped-example-list > .scraped-example pre", { + "scrollTop": |initialScrollTop| +}) +focus: ".scraped-example-list > .scraped-example .prev" +press-key: "Enter" +assert-property: (".scraped-example-list > .scraped-example pre", { + "scrollTop": |initialScrollTop| +}) + +// The expand button increases the scrollHeight of the minimized code viewport +store-property: (smallOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight") +assert-property-false: (".scraped-example-list > .scraped-example pre", { + "scrollHeight": |smallOffsetHeight| +}) +focus: ".scraped-example-list > .scraped-example .expand" +press-key: "Enter" +assert-property-false: (".scraped-example-list > .scraped-example pre", { + "offsetHeight": |smallOffsetHeight| +}) +store-property: (fullOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight") +assert-property: (".scraped-example-list > .scraped-example pre", { + "scrollHeight": |fullOffsetHeight| +}) diff --git a/src/test/rustdoc-gui/scrape-examples-fonts.goml b/src/test/rustdoc-gui/scrape-examples-fonts.goml new file mode 100644 index 000000000..b7d7f4ccb --- /dev/null +++ b/src/test/rustdoc-gui/scrape-examples-fonts.goml @@ -0,0 +1,8 @@ +goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html" + +store-value: (font, '"Fira Sans", Arial, NanumBarunGothic, sans-serif') + +wait-for-css: (".scraped-example-title", {"font-family": |font|}) +wait-for-css: (".more-examples-toggle summary", {"font-family": |font|}) +wait-for-css: (".more-examples-toggle .hide-more", {"font-family": |font|}) +wait-for-css: (".example-links a", {"font-family": |font|}) diff --git a/src/test/rustdoc-gui/scrape-examples-toggle.goml b/src/test/rustdoc-gui/scrape-examples-toggle.goml new file mode 100644 index 000000000..ee720afb7 --- /dev/null +++ b/src/test/rustdoc-gui/scrape-examples-toggle.goml @@ -0,0 +1,14 @@ +goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html" + +// Clicking "More examples..." will open additional examples +assert-attribute-false: (".more-examples-toggle", {"open": ""}) +click: ".more-examples-toggle" +assert-attribute: (".more-examples-toggle", {"open": ""}) + +// Toggling all docs will close additional examples +click: "#toggle-all-docs" +assert-attribute-false: (".more-examples-toggle", {"open": ""}) + +// After re-opening the docs, the additional examples should stay closed +click: "#toggle-all-docs" +assert-attribute-false: (".more-examples-toggle", {"open": ""}) diff --git a/src/test/rustdoc-gui/search-filter.goml b/src/test/rustdoc-gui/search-filter.goml index 27db816e6..e0228694e 100644 --- a/src/test/rustdoc-gui/search-filter.goml +++ b/src/test/rustdoc-gui/search-filter.goml @@ -14,6 +14,7 @@ click: "#crate-search" // We select "lib2" option then press enter to change the filter. press-key: "ArrowDown" press-key: "ArrowDown" +press-key: "ArrowDown" press-key: "Enter" // Waiting for the search results to appear... wait-for: "#titles" @@ -37,6 +38,7 @@ assert-property: ("#crate-search", {"value": "lib2"}) click: "#crate-search" press-key: "ArrowUp" press-key: "ArrowUp" +press-key: "ArrowUp" press-key: "Enter" // Waiting for the search results to appear... wait-for: "#titles" diff --git a/src/test/rustdoc-gui/search-keyboard.goml b/src/test/rustdoc-gui/search-keyboard.goml new file mode 100644 index 000000000..be642fc49 --- /dev/null +++ b/src/test/rustdoc-gui/search-keyboard.goml @@ -0,0 +1,28 @@ +// Checks that the search tab results work correctly with function signature syntax +// First, try a search-by-name +goto: "file://" + |DOC_PATH| + "/test_docs/index.html" +write: (".search-input", "Foo") +// To be SURE that the search will be run. +press-key: 'Enter' +// Waiting for the search results to appear... +wait-for: "#titles" + +// Now use the keyboard commands to switch to the third result. +press-key: "ArrowDown" +press-key: "ArrowDown" +press-key: "ArrowDown" +assert: ".search-results.active > a:focus:nth-of-type(3)" + +// Now switch to the second tab, then back to the first one, then arrow back up. +press-key: "ArrowRight" +assert: ".search-results.active:nth-of-type(2) > a:focus:nth-of-type(1)" +press-key: "ArrowLeft" +assert: ".search-results.active:nth-of-type(1) > a:focus:nth-of-type(3)" +press-key: "ArrowUp" +assert: ".search-results.active > a:focus:nth-of-type(2)" +press-key: "ArrowUp" +assert: ".search-results.active > a:focus:nth-of-type(1)" +press-key: "ArrowUp" +assert: ".search-input:focus" +press-key: "ArrowDown" +assert: ".search-results.active > a:focus:nth-of-type(1)" diff --git a/src/test/rustdoc-gui/search-no-result.goml b/src/test/rustdoc-gui/search-no-result.goml new file mode 100644 index 000000000..b88be32c9 --- /dev/null +++ b/src/test/rustdoc-gui/search-no-result.goml @@ -0,0 +1,36 @@ +// The goal of this test is to check the color of the "no result" links. +goto: "file://" + |DOC_PATH| + "/lib2/index.html?search=sdkfskjfsdks" +show-text: true + +define-function: ( + "check-no-result", + (theme, link, link_hover), + [ + // 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|})), + // Moving the cursor to some other place to not create issues with next function run. + ("move-cursor-to", ".search-input"), + ] +) + +call-function: ("check-no-result", { + "theme": "ayu", + "link": "rgb(57, 175, 215)", + "link_hover": "rgb(57, 175, 215)", +}) +call-function: ("check-no-result", { + "theme": "dark", + "link": "rgb(210, 153, 29)", + "link_hover": "rgb(210, 153, 29)", +}) +call-function: ("check-no-result", { + "theme": "light", + "link": "rgb(56, 115, 173)", + "link_hover": "rgb(56, 115, 173)", +}) diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml index 69bb30df9..dde43b1c9 100644 --- a/src/test/rustdoc-gui/search-result-color.goml +++ b/src/test/rustdoc-gui/search-result-color.goml @@ -67,7 +67,7 @@ reload: // Waiting for the search results to appear... wait-for: "#titles" assert-css: ( - "//*[@class='desc']//*[text()='Just a normal struct.']", + "//*[@class='desc'][text()='Just a normal struct.']", {"color": "rgb(197, 197, 197)"}, ) assert-css: ( @@ -75,6 +75,12 @@ assert-css: ( {"color": "rgb(0, 150, 207)"}, ) +// Checking the color of the bottom border. +assert-css: ( + ".search-results > a", + {"border-bottom-color": "rgba(170, 170, 170, 0.2)"} +) + // Checking the color of "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", @@ -153,7 +159,7 @@ assert-css: ( ) // Checking color and background on hover. -move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']" +move-cursor-to: "//*[@class='desc'][text()='Just a normal struct.']" assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']", {"color": "rgb(255, 255, 255)"}, @@ -173,7 +179,7 @@ reload: // Waiting for the search results to appear... wait-for: "#titles" assert-css: ( - "//*[@class='desc']//*[text()='Just a normal struct.']", + "//*[@class='desc'][text()='Just a normal struct.']", {"color": "rgb(221, 221, 221)"}, ) assert-css: ( @@ -181,6 +187,12 @@ assert-css: ( {"color": "rgb(221, 221, 221)"}, ) +// Checking the color of the bottom border. +assert-css: ( + ".search-results > a", + {"border-bottom-color": "rgba(170, 170, 170, 0.2)"} +) + // Checking the color for "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", @@ -264,7 +276,7 @@ reload: // Waiting for the search results to appear... wait-for: "#titles" assert-css: ( - "//*[@class='desc']//*[text()='Just a normal struct.']", + "//*[@class='desc'][text()='Just a normal struct.']", {"color": "rgb(0, 0, 0)"}, ) assert-css: ( @@ -272,6 +284,12 @@ assert-css: ( {"color": "rgb(0, 0, 0)"}, ) +// Checking the color of the bottom border. +assert-css: ( + ".search-results > a", + {"border-bottom-color": "rgba(170, 170, 170, 0.2)"} +) + // Checking the color for "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", @@ -348,23 +366,42 @@ assert-css: ( {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, ) -// Check the alias more specifically in the dark theme. +// Check the alias. goto: "file://" + |DOC_PATH| + "/test_docs/index.html" -// We set the theme so we're sure that the correct values will be used, whatever the computer -// this test is running on. -local-storage: { - "rustdoc-theme": "dark", - "rustdoc-use-system-theme": "false", -} // If the text isn't displayed, the browser doesn't compute color style correctly... show-text: true -// We reload the page so the local storage settings are being used. -reload: -write: (".search-input", "thisisanalias") -// To be SURE that the search will be run. -press-key: 'Enter' -// Waiting for the search results to appear... -wait-for: "#titles" -// Checking that the colors for the alias element are the ones expected. -assert-css: (".result-name > .alias", {"color": "rgb(255, 255, 255)"}) -assert-css: (".result-name > .alias > .grey", {"color": "rgb(204, 204, 204)"}) + +define-function: ( + "check-alias", + (theme, alias, grey), + [ + ("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'), + // Waiting for the search results to appear... + ("wait-for", "#titles"), + // 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|})), + // Leave the search results to prevent reloading with an already filled search input. + ("press-key", "Escape"), + ], +) + +call-function: ("check-alias", { + "theme": "ayu", + "alias": "rgb(197, 197, 197)", + "grey": "rgb(153, 153, 153)", +}) +call-function: ("check-alias", { + "theme": "dark", + "alias": "rgb(255, 255, 255)", + "grey": "rgb(204, 204, 204)", +}) +call-function: ("check-alias", { + "theme": "light", + "alias": "rgb(0, 0, 0)", + "grey": "rgb(153, 153, 153)", +}) diff --git a/src/test/rustdoc-gui/search-result-display.goml b/src/test/rustdoc-gui/search-result-display.goml index 053bfd8c9..13a5e4c71 100644 --- a/src/test/rustdoc-gui/search-result-display.goml +++ b/src/test/rustdoc-gui/search-result-display.goml @@ -7,7 +7,7 @@ press-key: 'Enter' wait-for: "#crate-search" // The width is returned by "getComputedStyle" which returns the exact number instead of the // CSS rule which is "50%"... -assert-css: (".search-results div.desc", {"width": "318px"}) +assert-css: (".search-results div.desc", {"width": "310px"}) size: (600, 100) // As counter-intuitive as it may seem, in this width, the width is "100%", which is why // when computed it's larger. @@ -22,7 +22,8 @@ size: (900, 900) // First we check the current width, height and position. assert-css: ("#crate-search", {"width": "223px"}) -assert-css: (".search-results-title", {"height": "44px", "width": "336px"}) +assert-css: (".search-results-title", {"height": "44px", "width": "640px"}) +assert-css: ("#search", {"width": "640px"}) // Then we update the text of one of the `<option>`. text: ( @@ -35,3 +36,43 @@ assert-css: ("#crate-search", {"width": "527px"}) assert-css: (".search-results-title", {"height": "44px", "width": "640px"}) // And we check that the `<select>` isn't bigger than its container (".search-results-title"). assert-css: ("#search", {"width": "640px"}) + +// Now checking that the crate filter is working as expected too. +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"), + ], +) + +call-function: ("check-filter", { + "theme": "ayu", + "border": "rgb(92, 103, 115)", + "filter": "invert(0.41) sepia(0.12) saturate(4.87) hue-rotate(171deg) brightness(0.94) contrast(0.94)", + "hover_border": "rgb(224, 224, 224)", + "hover_filter": "invert(0.98) sepia(0.12) saturate(0.81) hue-rotate(343deg) brightness(1.13) contrast(0.76)", +}) +call-function: ("check-filter", { + "theme": "dark", + "border": "rgb(224, 224, 224)", + "filter": "invert(0.94) sepia(0) saturate(7.21) hue-rotate(255deg) brightness(0.9) contrast(0.9)", + "hover_border": "rgb(33, 150, 243)", + "hover_filter": "invert(0.69) sepia(0.6) saturate(66.13) hue-rotate(184deg) brightness(1) contrast(0.91)", +}) +call-function: ("check-filter", { + "theme": "light", + "border": "rgb(224, 224, 224)", + "filter": "invert(1) sepia(0) saturate(42.23) hue-rotate(289deg) brightness(1.14) contrast(0.76)", + "hover_border": "rgb(113, 113, 113)", + "hover_filter": "invert(0.44) sepia(0.18) saturate(0.23) hue-rotate(317deg) brightness(0.96) contrast(0.93)", +}) diff --git a/src/test/rustdoc-gui/settings.goml b/src/test/rustdoc-gui/settings.goml index f258f4d2a..fc3beaa53 100644 --- a/src/test/rustdoc-gui/settings.goml +++ b/src/test/rustdoc-gui/settings.goml @@ -37,8 +37,7 @@ click: "#settings-menu" wait-for: "#settings" // We check that the "Use system theme" is disabled. -assert-property: ("#use-system-theme", {"checked": "false"}) -assert: "//*[@class='setting-line']//span[text()='Use system theme']" +assert-property: ("#theme-system-preference", {"checked": "false"}) // Meaning that only the "theme" menu is showing up. assert: ".setting-line:not(.hidden) #theme" assert: ".setting-line.hidden #preferred-dark-theme" @@ -48,7 +47,8 @@ assert: ".setting-line.hidden #preferred-light-theme" assert-property: ("#theme .choices #theme-dark", {"checked": "true"}) // Some style checks... -// First we check the "default" display. +move-cursor-to: "#settings-menu > a" +// First we check the "default" display for radio buttons. assert-css: ( "#theme-dark", { @@ -57,7 +57,7 @@ assert-css: ( }, ) assert-css: ("#theme-light", {"border-color": "rgb(221, 221, 221)", "box-shadow": "none"}) -// Let's start with the hover. +// Let's start with the hover for radio buttons. move-cursor-to: "#theme-dark" assert-css: ( "#theme-dark", @@ -69,7 +69,7 @@ assert-css: ( move-cursor-to: "#theme-light" assert-css: ("#theme-light", {"border-color": "rgb(33, 150, 243)", "box-shadow": "none"}) move-cursor-to: "#theme-ayu" -// Let's now check with the focus. +// Let's now check with the focus for radio buttons. focus: "#theme-dark" assert-css: ( "#theme-dark", @@ -86,7 +86,7 @@ assert-css: ( "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px", }, ) -// Now we check we both focus and hover. +// Now we check we both focus and hover for radio buttons. move-cursor-to: "#theme-dark" focus: "#theme-dark" assert-css: ( @@ -106,19 +106,57 @@ assert-css: ( }, ) +// First we check the "default" display for toggles. +assert-css: ( + "#auto-hide-large-items", + { + "background-color": "rgb(33, 150, 243)", + "border-color": "rgb(221, 221, 221)", + }, +) +// Let's start with the hover for toggles. +move-cursor-to: "#auto-hide-large-items" +assert-css: ( + "#auto-hide-large-items", + { + "background-color": "rgb(33, 150, 243)", + "border-color": "rgb(33, 150, 243)", + }, +) +move-cursor-to: "#settings-menu > a" +// Let's now check with the focus for toggles. +focus: "#auto-hide-large-items" +assert-css: ( + "#auto-hide-large-items", + { + "background-color": "rgb(33, 150, 243)", + "border-color": "rgb(221, 221, 221)", + "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px", + }, +) +// Now we check we both focus and hover for toggles. +move-cursor-to: "#auto-hide-large-items" +focus: "#auto-hide-large-items" +assert-css: ( + "#auto-hide-large-items", + { + "background-color": "rgb(33, 150, 243)", + "border-color": "rgb(33, 150, 243)", + "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px", + }, +) + // We now switch the display. -click: "#use-system-theme" +click: "#theme-system-preference" // Wait for the hidden element to show up. wait-for: ".setting-line:not(.hidden) #preferred-dark-theme" assert: ".setting-line:not(.hidden) #preferred-light-theme" -// Check that the theme picking is hidden. -assert: ".setting-line.hidden #theme" // We check their text as well. assert-text: ("#preferred-dark-theme .setting-name", "Preferred dark theme") assert-text: ("#preferred-light-theme .setting-name", "Preferred light theme") -// We now check that clicking on the "sliders"' text is like clicking on the slider. +// We now check that clicking on the toggles' text is like clicking on the checkbox. // To test it, we use the "Disable keyboard shortcuts". local-storage: {"rustdoc-disable-shortcuts": "false"} click: ".setting-line:last-child .toggle .label" @@ -141,10 +179,7 @@ assert-css: ("#settings-menu .popover", {"display": "none"}) // Now we go to the settings page to check that the CSS is loaded as expected. goto: "file://" + |DOC_PATH| + "/settings.html" wait-for: "#settings" -assert-css: ( - ".setting-line .toggle .slider", - {"width": "45px", "margin-right": "20px", "border": "0px none rgb(0, 0, 0)"}, -) +assert-css: (".setting-line", {"position": "relative"}) assert-attribute-false: ("#settings", {"class": "popover"}, CONTAINS) compare-elements-position: (".sub form", "#settings", ("x")) @@ -162,4 +197,4 @@ reload: size: (300, 1000) click: "#settings-menu" wait-for: "#settings" -assert-css: ("#settings .slider", {"width": "45px"}, ALL) +assert-css: (".setting-line", {"position": "relative"}) diff --git a/src/test/rustdoc-gui/sidebar-links-color.goml b/src/test/rustdoc-gui/sidebar-links-color.goml index 18a1a3fad..7ef7ec90c 100644 --- a/src/test/rustdoc-gui/sidebar-links-color.goml +++ b/src/test/rustdoc-gui/sidebar-links-color.goml @@ -4,230 +4,168 @@ goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" // This is needed so that the text color is computed. show-text: true -// Ayu theme -local-storage: { - "rustdoc-theme": "ayu", - "rustdoc-use-system-theme": "false", -} -reload: - -// Struct -assert-css: ( - ".sidebar .block.struct a:not(.current)", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.struct a:not(.current)" -assert-css: ( - ".sidebar .block.struct a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Enum -assert-css: ( - ".sidebar .block.enum a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.enum a" -assert-css: ( - ".sidebar .block.enum a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Union -assert-css: ( - ".sidebar .block.union a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.union a" -assert-css: ( - ".sidebar .block.union a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Trait -assert-css: ( - ".sidebar .block.trait a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.trait a" -assert-css: ( - ".sidebar .block.trait a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Function -assert-css: ( - ".sidebar .block.fn a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.fn a" -assert-css: ( - ".sidebar .block.fn a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Type definition -assert-css: ( - ".sidebar .block.type a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.type a" -assert-css: ( - ".sidebar .block.type a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// Keyword -assert-css: ( - ".sidebar .block.keyword a", - {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.keyword a" -assert-css: ( - ".sidebar .block.keyword a:hover", - {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, -) - -// Dark theme -local-storage: {"rustdoc-theme": "dark"} -reload: - -// Struct -assert-css: ( - ".sidebar .block.struct a:not(.current)", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.struct a:not(.current)" -assert-css: ( - ".sidebar .block.struct a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) -// Enum -assert-css: ( - ".sidebar .block.enum a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.enum a" -assert-css: ( - ".sidebar .block.enum a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) -// Union -assert-css: ( - ".sidebar .block.union a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.union a" -assert-css: ( - ".sidebar .block.union a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, +define-function: ( + "check-colors", + ( + theme, struct, struct_hover, struct_hover_background, enum, enum_hover, + enum_hover_background, union, union_hover, union_hover_background, trait, trait_hover, + 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"), + // Struct + ("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", ( + ".sidebar .block.struct a:hover", + {"color": |struct_hover|, "background-color": |struct_hover_background|}, + )), + // Enum + ("assert-css", ( + ".sidebar .block.enum a", + {"color": |enum|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("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", ( + ".sidebar .block.union a", + {"color": |union|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("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", ( + ".sidebar .block.trait a", + {"color": |trait|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("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", ( + ".sidebar .block.fn a", + {"color": |fn|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("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", ( + ".sidebar .block.type a", + {"color": |type|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("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", ( + ".sidebar .block.keyword a", + {"color": |keyword|, "background-color": "rgba(0, 0, 0, 0)"}, + )), + ("move-cursor-to", ".sidebar .block.keyword a"), + ("assert-css", ( + ".sidebar .block.keyword a:hover", + {"color": |keyword_hover|, "background-color": |keyword_hover_background|}, + )), + ] ) -// Trait -assert-css: ( - ".sidebar .block.trait a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.trait a" -assert-css: ( - ".sidebar .block.trait a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) -// Function -assert-css: ( - ".sidebar .block.fn a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.fn a" -assert-css: ( - ".sidebar .block.fn a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) -// Type definition -assert-css: ( - ".sidebar .block.type a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.type a" -assert-css: ( - ".sidebar .block.type a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) -// Keyword -assert-css: ( - ".sidebar .block.keyword a", - {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.keyword a" -assert-css: ( - ".sidebar .block.keyword a:hover", - {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, -) - -// Light theme -local-storage: {"rustdoc-theme": "light"} -reload: -// Struct -assert-css: ( - ".sidebar .block.struct a:not(.current)", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.struct a:not(.current)" -assert-css: ( - ".sidebar .block.struct a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Enum -assert-css: ( - ".sidebar .block.enum a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.enum a" -assert-css: ( - ".sidebar .block.enum a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Union -assert-css: ( - ".sidebar .block.union a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.union a" -assert-css: ( - ".sidebar .block.union a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Trait -assert-css: ( - ".sidebar .block.trait a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.trait a" -assert-css: ( - ".sidebar .block.trait a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Function -assert-css: ( - ".sidebar .block.fn a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.fn a" -assert-css: ( - ".sidebar .block.fn a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Type definition -assert-css: ( - ".sidebar .block.type a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.type a" -assert-css: ( - ".sidebar .block.type a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, -) -// Keyword -assert-css: ( - ".sidebar .block.keyword a", - {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, -) -move-cursor-to: ".sidebar .block.keyword a" -assert-css: ( - ".sidebar .block.keyword a:hover", - {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, +call-function: ( + "check-colors", + { + "theme": "ayu", + "struct": "rgb(83, 177, 219)", + "struct_hover": "rgb(255, 180, 76)", + "struct_hover_background": "rgba(0, 0, 0, 0)", + "enum": "rgb(83, 177, 219)", + "enum_hover": "rgb(255, 180, 76)", + "enum_hover_background": "rgba(0, 0, 0, 0)", + "union": "rgb(83, 177, 219)", + "union_hover": "rgb(255, 180, 76)", + "union_hover_background": "rgba(0, 0, 0, 0)", + "trait": "rgb(83, 177, 219)", + "trait_hover": "rgb(255, 180, 76)", + "trait_hover_background": "rgba(0, 0, 0, 0)", + "fn": "rgb(83, 177, 219)", + "fn_hover": "rgb(255, 180, 76)", + "fn_hover_background": "rgba(0, 0, 0, 0)", + "type": "rgb(83, 177, 219)", + "type_hover": "rgb(255, 180, 76)", + "type_hover_background": "rgba(0, 0, 0, 0)", + "keyword": "rgb(83, 177, 219)", + "keyword_hover": "rgb(255, 180, 76)", + "keyword_hover_background": "rgba(0, 0, 0, 0)", + } +) +call-function: ( + "check-colors", + { + "theme": "dark", + "struct": "rgb(253, 191, 53)", + "struct_hover": "rgb(253, 191, 53)", + "struct_hover_background": "rgb(68, 68, 68)", + "enum": "rgb(253, 191, 53)", + "enum_hover": "rgb(253, 191, 53)", + "enum_hover_background": "rgb(68, 68, 68)", + "union": "rgb(253, 191, 53)", + "union_hover": "rgb(253, 191, 53)", + "union_hover_background": "rgb(68, 68, 68)", + "trait": "rgb(253, 191, 53)", + "trait_hover": "rgb(253, 191, 53)", + "trait_hover_background": "rgb(68, 68, 68)", + "fn": "rgb(253, 191, 53)", + "fn_hover": "rgb(253, 191, 53)", + "fn_hover_background": "rgb(68, 68, 68)", + "type": "rgb(253, 191, 53)", + "type_hover": "rgb(253, 191, 53)", + "type_hover_background": "rgb(68, 68, 68)", + "keyword": "rgb(253, 191, 53)", + "keyword_hover": "rgb(253, 191, 53)", + "keyword_hover_background": "rgb(68, 68, 68)", + } +) +call-function: ( + "check-colors", + { + "theme": "light", + "struct": "rgb(53, 109, 164)", + "struct_hover": "rgb(53, 109, 164)", + "struct_hover_background": "rgb(255, 255, 255)", + "enum": "rgb(53, 109, 164)", + "enum_hover": "rgb(53, 109, 164)", + "enum_hover_background": "rgb(255, 255, 255)", + "union": "rgb(53, 109, 164)", + "union_hover": "rgb(53, 109, 164)", + "union_hover_background": "rgb(255, 255, 255)", + "trait": "rgb(53, 109, 164)", + "trait_hover": "rgb(53, 109, 164)", + "trait_hover_background": "rgb(255, 255, 255)", + "fn": "rgb(53, 109, 164)", + "fn_hover": "rgb(53, 109, 164)", + "fn_hover_background": "rgb(255, 255, 255)", + "type": "rgb(53, 109, 164)", + "type_hover": "rgb(53, 109, 164)", + "type_hover_background": "rgb(255, 255, 255)", + "keyword": "rgb(53, 109, 164)", + "keyword_hover": "rgb(53, 109, 164)", + "keyword_hover_background": "rgb(255, 255, 255)", + } ) diff --git a/src/test/rustdoc-gui/sidebar-mobile.goml b/src/test/rustdoc-gui/sidebar-mobile.goml index 453873f1b..38d01f7f6 100644 --- a/src/test/rustdoc-gui/sidebar-mobile.goml +++ b/src/test/rustdoc-gui/sidebar-mobile.goml @@ -32,6 +32,12 @@ assert-css: ("//nav[contains(@class, 'sidebar')]//h2/a[text()='In test_docs']/pa click: "body" assert-css: (".sidebar", {"display": "block", "left": "-1000px"}) +// Open the sidebar menu, and make sure pressing Escape closes it. +click: ".sidebar-menu-toggle" +assert-css: (".sidebar", {"left": "0px"}) +press-key: "Escape" +assert-css: (".sidebar", {"display": "block", "left": "-1000px"}) + // Check that the topbar is visible assert-property: (".mobile-topbar", {"clientHeight": "45"}) @@ -48,23 +54,35 @@ compare-elements-position-near: (".block.keyword li:nth-child(1)", ".mobile-topb // Now checking the background color of the sidebar. show-text: true -local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"} -reload: - -// Open the sidebar menu. -click: ".sidebar-menu-toggle" -assert-css: (".sidebar", {"background-color": "rgb(80, 80, 80)", "color": "rgb(221, 221, 221)"}) - -local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "ayu"} -reload: -// Open the sidebar menu. -click: ".sidebar-menu-toggle" -assert-css: (".sidebar", {"background-color": "rgb(20, 25, 31)", "color": "rgb(197, 197, 197)"}) +define-function: ( + "check-colors", + (theme, color, background), + [ + ("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}), + ("reload"), -local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "light"} -reload: + // Open the sidebar menu. + ("click", ".sidebar-menu-toggle"), + ("assert-css", (".sidebar", { + "background-color": |background|, + "color": |color|, + })), + ], +) -// Open the sidebar menu. -click: ".sidebar-menu-toggle" -assert-css: (".sidebar", {"background-color": "rgb(245, 245, 245)", "color": "rgb(0, 0, 0)"}) +call-function: ("check-colors", { + "theme": "ayu", + "color": "rgb(197, 197, 197)", + "background": "rgb(20, 25, 31)", +}) +call-function: ("check-colors", { + "theme": "dark", + "color": "rgb(221, 221, 221)", + "background": "rgb(80, 80, 80)", +}) +call-function: ("check-colors", { + "theme": "light", + "color": "rgb(0, 0, 0)", + "background": "rgb(245, 245, 245)", +}) diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml index 4155dab64..40ae4af81 100644 --- a/src/test/rustdoc-gui/sidebar-source-code-display.goml +++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml @@ -29,171 +29,124 @@ assert-local-storage: {"rustdoc-source-sidebar-show": "true"} // Now we check the display of the sidebar items. show-text: true -// First we start with the light theme. -local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"} -reload: -// Waiting for the sidebar to be displayed... -wait-for-css: ("#sidebar-toggle", {"visibility": "visible"}) -assert-css: ( - "#source-sidebar details[open] > .files a.selected", - {"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"}, -) -// Without hover or focus. -assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"}) -// With focus. -focus: "#sidebar-toggle > button" -assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"}) -focus: ".search-input" -// With hover. -move-cursor-to: "#sidebar-toggle > button" -assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"}) -// Without hover. -assert-css: ( - "#source-sidebar details[open] > .files a:not(.selected)", - {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// With focus. -focus: "#source-sidebar details[open] > .files a:not(.selected)" -wait-for-css: ( - "#source-sidebar details[open] > .files a:not(.selected)", - {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"}, -) -focus: ".search-input" -// With hover. -move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)" -assert-css: ( - "#source-sidebar details[open] > .files a:not(.selected)", - {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"}, -) -// Without hover. -assert-css: ( - "#source-sidebar details[open] > .folders > details > summary", - {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// With focus. -focus: "#source-sidebar details[open] > .folders > details > summary" -wait-for-css: ( - "#source-sidebar details[open] > .folders > details > summary", - {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"}, -) -focus: ".search-input" -// With hover. -move-cursor-to: "#source-sidebar details[open] > .folders > details > summary" -assert-css: ( - "#source-sidebar details[open] > .folders > details > summary", - {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"}, -) +define-function: ( + "check-colors", + ( + 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", ("#sidebar-toggle", {"visibility": "visible"})), + ("assert-css", ( + "#source-sidebar details[open] > .files a.selected", + {"color": |color_hover|, "background-color": |background|}, + )), -// Now with the dark theme. -local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"} -reload: -// Waiting for the sidebar to be displayed... -wait-for-css: ("#sidebar-toggle", {"visibility": "visible"}) -assert-css: ( - "#source-sidebar details[open] > .files > a.selected", - {"color": "rgb(221, 221, 221)", "background-color": "rgb(51, 51, 51)"}, -) -// Without hover or focus. -assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"}) -// With focus. -focus: "#sidebar-toggle > button" -assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"}) -focus: ".search-input" -// With hover. -move-cursor-to: "#sidebar-toggle > button" -assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"}) -// Without hover. -assert-css: ( - "#source-sidebar details[open] > .files > a:not(.selected)", - {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// With focus. -focus: "#source-sidebar details[open] > .files a:not(.selected)" -wait-for-css: ( - "#source-sidebar details[open] > .files a:not(.selected)", - {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"}, -) -focus: ".search-input" -// With hover. -move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)" -assert-css: ( - "#source-sidebar details[open] > .files a:not(.selected)", - {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"}, -) -// Without hover. -assert-css: ( - "#source-sidebar details[open] > .folders > details > summary", - {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// With focus. -focus: "#source-sidebar details[open] > .folders > details > summary" -wait-for-css: ( - "#source-sidebar details[open] > .folders > details > summary", - {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"}, -) -focus: ".search-input" -// With hover. -move-cursor-to: "#source-sidebar details[open] > .folders > details > summary" -assert-css: ( - "#source-sidebar details[open] > .folders > details > summary", - {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"}, -) + // Without hover or focus. + ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle|})), + // With focus. + ("focus", "#sidebar-toggle > button"), + ("assert-css", ( + "#sidebar-toggle > button:focus", + {"background-color": |background_toggle_hover|}, + )), + ("focus", ".search-input"), + // With hover. + ("move-cursor-to", "#sidebar-toggle > button"), + ("assert-css", ( + "#sidebar-toggle > button:hover", + {"background-color": |background_toggle_hover|}, + )), -// And finally with the ayu theme. -local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"} -reload: -// Waiting for the sidebar to be displayed... -wait-for-css: ("#sidebar-toggle", {"visibility": "visible"}) -assert-css: ( - "#source-sidebar details[open] > .files a.selected", - {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"}, -) -// Without hover or focus. -assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"}) -// With focus. -focus: "#sidebar-toggle > button" -assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"}) -focus: ".search-input" -// With hover. -move-cursor-to: "#sidebar-toggle > button" -assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"}) -// Without hover. -assert-css: ( - "#source-sidebar details[open] > .files a:not(.selected)", - {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// With focus. -focus: "#source-sidebar details[open] > .files a:not(.selected)" -wait-for-css: ( - "#source-sidebar details[open] > .files a:not(.selected)", - {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"}, -) -focus: ".search-input" -// With hover. -move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)" -assert-css: ( - "#source-sidebar details[open] > .files a:not(.selected)", - {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"}, -) -// Without hover. -assert-css: ( - "#source-sidebar details[open] > .folders > details > summary", - {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"}, -) -// With focus. -focus: "#source-sidebar details[open] > .folders > details > summary" -wait-for-css: ( - "#source-sidebar details[open] > .folders > details > summary", - {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"}, -) -focus: ".search-input" -// With hover. -move-cursor-to: "#source-sidebar details[open] > .folders > details > summary" -assert-css: ( - "#source-sidebar details[open] > .folders > details > summary", - {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"}, + // Without hover or focus. + ("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", ( + "#source-sidebar details[open] > .files a:not(.selected):focus", + {"color": |color_hover|, "background-color": |background_hover|}, + )), + ("focus", ".search-input"), + // With hover. + ("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", ( + "#source-sidebar .dir-entry summary", + {"color": |color|, "background-color": |background_toggle|}, + )), + // With focus. + ("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"), + // With hover. + ("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", ( + "#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", ( + "#source-sidebar details[open] > .folders > details > summary:focus", + {"color": |color_hover|, "background-color": |background_hover|}, + )), + ("focus", ".search-input"), + // With hover. + ("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", { + "theme": "light", + "color": "rgb(0, 0, 0)", + "color_hover": "rgb(0, 0, 0)", + "background": "rgb(255, 255, 255)", + "background_hover": "rgb(224, 224, 224)", + "background_toggle": "rgba(0, 0, 0, 0)", + "background_toggle_hover": "rgb(224, 224, 224)", +}) +call-function: ("check-colors", { + "theme": "dark", + "color": "rgb(221, 221, 221)", + "color_hover": "rgb(221, 221, 221)", + "background": "rgb(51, 51, 51)", + "background_hover": "rgb(68, 68, 68)", + "background_toggle": "rgba(0, 0, 0, 0)", + "background_toggle_hover": "rgb(103, 103, 103)", +}) +call-function: ("check-colors", { + "theme": "ayu", + "color": "rgb(197, 197, 197)", + "color_hover": "rgb(255, 180, 76)", + "background": "rgb(20, 25, 31)", + "background_hover": "rgb(20, 25, 31)", + "background_toggle": "rgba(0, 0, 0, 0)", + "background_toggle_hover": "rgba(70, 70, 70, 0.33)", +}) + // Now checking on mobile devices. size: (500, 700) reload: diff --git a/src/test/rustdoc-gui/sidebar-source-code.goml b/src/test/rustdoc-gui/sidebar-source-code.goml index 9ba663687..36e4d555b 100644 --- a/src/test/rustdoc-gui/sidebar-source-code.goml +++ b/src/test/rustdoc-gui/sidebar-source-code.goml @@ -28,7 +28,7 @@ assert: "//*[@class='dir-entry' and @open]/*[text()='sub_mod']" // Only "another_folder" should be "open" in "lib2". assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']" // All other trees should be collapsed. -assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 5) +assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 7) // We now switch to mobile mode. size: (600, 600) diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index a2dac2aa6..b3b837ad3 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -2,17 +2,22 @@ goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" show-text: true // Check that we can click on the line number. -click: ".src-line-numbers > span:nth-child(4)" // This is the span for line 4. +click: ".src-line-numbers > a:nth-child(4)" // This is the anchor for line 4. // Ensure that the page URL was updated. assert-document-property: ({"URL": "lib.rs.html#4"}, ENDS_WITH) assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"}) -// We now check that the good spans are highlighted +// Ensure that the default style, with the right border, isn't used. +assert-css: ("//*[@id='4']", {"border-right-width": "0px"}) +reload: +assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"}) +assert-css: ("//*[@id='4']", {"border-right-width": "0px"}) +// We now check that the good anchors are highlighted goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4-6" -assert-attribute-false: (".src-line-numbers > span:nth-child(3)", {"class": "line-highlighted"}) -assert-attribute: (".src-line-numbers > span:nth-child(4)", {"class": "line-highlighted"}) -assert-attribute: (".src-line-numbers > span:nth-child(5)", {"class": "line-highlighted"}) -assert-attribute: (".src-line-numbers > span:nth-child(6)", {"class": "line-highlighted"}) -assert-attribute-false: (".src-line-numbers > span:nth-child(7)", {"class": "line-highlighted"}) +assert-attribute-false: (".src-line-numbers > a:nth-child(3)", {"class": "line-highlighted"}) +assert-attribute: (".src-line-numbers > a:nth-child(4)", {"class": "line-highlighted"}) +assert-attribute: (".src-line-numbers > a:nth-child(5)", {"class": "line-highlighted"}) +assert-attribute: (".src-line-numbers > a:nth-child(6)", {"class": "line-highlighted"}) +assert-attribute-false: (".src-line-numbers > a:nth-child(7)", {"class": "line-highlighted"}) define-function: ( "check-colors", @@ -21,12 +26,12 @@ define-function: ( ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), ("reload"), ("assert-css", ( - ".src-line-numbers > span:not(.line-highlighted)", + ".src-line-numbers > a:not(.line-highlighted)", {"color": |color|, "background-color": |background_color|}, ALL, )), ("assert-css", ( - ".src-line-numbers > span.line-highlighted", + ".src-line-numbers > a.line-highlighted", {"color": |highlight_color|, "background-color": |highlight_background_color|}, ALL, )), @@ -57,6 +62,25 @@ call-function: ("check-colors", { // This is to ensure that the content is correctly align with the line numbers. compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y")) +// Check the `href` property so that users can treat anchors as links. +assert-property: (".src-line-numbers > a:nth-child(1)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#1" +}) +assert-property: (".src-line-numbers > a:nth-child(2)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#2" +}) +assert-property: (".src-line-numbers > a:nth-child(3)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#3" +}) +assert-property: (".src-line-numbers > a:nth-child(4)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4" +}) +assert-property: (".src-line-numbers > a:nth-child(5)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#5" +}) +assert-property: (".src-line-numbers > a:nth-child(6)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#6" +}) // Assert that the line numbers text is aligned to the right. assert-css: (".src-line-numbers", {"text-align": "right"}) @@ -66,7 +90,7 @@ assert-css: (".src-line-numbers", {"text-align": "right"}) goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" // We use this assert-position to know where we will click. assert-position: ("//*[@id='1']", {"x": 104, "y": 112}) -// We click on the left of the "1" span but still in the "src-line-number" `<pre>`. +// We click on the left of the "1" anchor but still in the "src-line-number" `<pre>`. click: (103, 103) assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH) @@ -78,7 +102,7 @@ assert: ".source-sidebar-expanded" // We check that the first entry of the sidebar is collapsed assert-property: ("#source-sidebar details:first-of-type", {"open": "false"}) -assert-text: ("#source-sidebar details:first-of-type > summary", "implementors") +assert-text: ("#source-sidebar details:first-of-type > summary", "huge_logo") // We now click on it. click: "#source-sidebar details:first-of-type > summary" assert-property: ("#source-sidebar details:first-of-type", {"open": "true"}) diff --git a/src/test/rustdoc-gui/src-font-size.goml b/src/test/rustdoc-gui/src-font-size.goml index b17dfd94c..9233f3744 100644 --- a/src/test/rustdoc-gui/src-font-size.goml +++ b/src/test/rustdoc-gui/src-font-size.goml @@ -9,3 +9,8 @@ assert-css: (".impl.has-srclink .code-header", {"font-size": "18px", "font-weigh // Check the impl items. assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL) assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px", "font-weight": 600}, ALL) + +// Check that we can click on source link +store-document-property: (url, "URL") +click: ".impl-items .has-srclink .srclink" +assert-document-property-false: {"URL": |url|} diff --git a/src/test/rustdoc-gui/src/huge_logo/Cargo.lock b/src/test/rustdoc-gui/src/huge_logo/Cargo.lock new file mode 100644 index 000000000..142805750 --- /dev/null +++ b/src/test/rustdoc-gui/src/huge_logo/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "huge_logo" +version = "0.1.0" diff --git a/src/test/rustdoc-gui/src/huge_logo/Cargo.toml b/src/test/rustdoc-gui/src/huge_logo/Cargo.toml new file mode 100644 index 000000000..3f10d09c8 --- /dev/null +++ b/src/test/rustdoc-gui/src/huge_logo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "huge_logo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/test/rustdoc-gui/src/huge_logo/src/lib.rs b/src/test/rustdoc-gui/src/huge_logo/src/lib.rs new file mode 100644 index 000000000..ec137fb9a --- /dev/null +++ b/src/test/rustdoc-gui/src/huge_logo/src/lib.rs @@ -0,0 +1,17 @@ +// ignore-tidy-linelength +#![doc(html_logo_url = "data:image/png;base64,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")] + +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/src/test/rustdoc-gui/src/scrape_examples/Cargo.lock b/src/test/rustdoc-gui/src/scrape_examples/Cargo.lock new file mode 100644 index 000000000..7cd6d0844 --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "scrape_examples" +version = "0.1.0" diff --git a/src/test/rustdoc-gui/src/scrape_examples/Cargo.toml b/src/test/rustdoc-gui/src/scrape_examples/Cargo.toml new file mode 100644 index 000000000..aea9b657d --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "scrape_examples" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-1.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-1.rs new file mode 100644 index 000000000..1d1bc5002 --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-1.rs @@ -0,0 +1,3 @@ +fn main() { + scrape_examples::test_many(); +} diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-2.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-2.rs new file mode 100644 index 000000000..1d1bc5002 --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-2.rs @@ -0,0 +1,3 @@ +fn main() { + scrape_examples::test_many(); +} diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-3.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-3.rs new file mode 100644 index 000000000..1d1bc5002 --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-3.rs @@ -0,0 +1,3 @@ +fn main() { + scrape_examples::test_many(); +} diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-4.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-4.rs new file mode 100644 index 000000000..1d1bc5002 --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-4.rs @@ -0,0 +1,3 @@ +fn main() { + scrape_examples::test_many(); +} diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-5.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-5.rs new file mode 100644 index 000000000..1d1bc5002 --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-5.rs @@ -0,0 +1,3 @@ +fn main() { + scrape_examples::test_many(); +} diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-6.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-6.rs new file mode 100644 index 000000000..1d1bc5002 --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-6.rs @@ -0,0 +1,3 @@ +fn main() { + scrape_examples::test_many(); +} diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-7.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-7.rs new file mode 100644 index 000000000..1d1bc5002 --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-7.rs @@ -0,0 +1,3 @@ +fn main() { + scrape_examples::test_many(); +} diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check.rs new file mode 100644 index 000000000..b3f682fe4 --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check.rs @@ -0,0 +1,26 @@ +fn main() { + for i in 0..9 { + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + } + scrape_examples::test(); + for i in 0..9 { + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + println!("hello world!"); + } + scrape_examples::test(); +} diff --git a/src/test/rustdoc-gui/src/scrape_examples/src/lib.rs b/src/test/rustdoc-gui/src/scrape_examples/src/lib.rs new file mode 100644 index 000000000..88b03cf26 --- /dev/null +++ b/src/test/rustdoc-gui/src/scrape_examples/src/lib.rs @@ -0,0 +1,9 @@ +/// # Examples +/// +/// ``` +/// test(); +/// test(); +/// ``` +pub fn test() {} + +pub fn test_many() {} diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs index fdf97e492..d6eeab803 100644 --- a/src/test/rustdoc-gui/src/test_docs/lib.rs +++ b/src/test/rustdoc-gui/src/test_docs/lib.rs @@ -76,6 +76,7 @@ impl AsRef<str> for Foo { /// /// # title! #[doc(alias = "ThisIsAnAlias")] +#[non_exhaustive] pub enum WhoLetTheDogOut { /// Woof! Woof, @@ -342,6 +343,9 @@ pub mod doc_block_table { /// | 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 { @@ -408,6 +412,11 @@ pub struct WithGenerics<T: TraitWithNoDocblocks, S = String, E = WhoLetTheDogOut p: P, } +pub struct StructWithPublicUndocumentedFields { + pub first: u32, + pub second: u32, +} + pub const CONST: u8 = 0; pub trait TraitWithoutGenerics { @@ -416,3 +425,20 @@ pub trait TraitWithoutGenerics { 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() {} + } +} diff --git a/src/test/rustdoc-gui/struct-fields.goml b/src/test/rustdoc-gui/struct-fields.goml new file mode 100644 index 000000000..3ec60b58c --- /dev/null +++ b/src/test/rustdoc-gui/struct-fields.goml @@ -0,0 +1,5 @@ +goto: "file://" + |DOC_PATH| + "/test_docs/struct.StructWithPublicUndocumentedFields.html" + +// Both fields must be on their own line. In other words, they have display: block. +store-property: (first_top, "//*[@id='structfield.first']", "offsetTop") +assert-property-false: ("//*[@id='structfield.second']", { "offsetTop": |first_top| }) diff --git a/src/test/rustdoc-gui/target.goml b/src/test/rustdoc-gui/target.goml new file mode 100644 index 000000000..3e5c30dc7 --- /dev/null +++ b/src/test/rustdoc-gui/target.goml @@ -0,0 +1,35 @@ +// Check that the targetted element has the expected styles. +goto: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html#method.a_method" +show-text: true + +// Confirming that the method is the target. +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", { + "background-color": |background|, + "border-right": "3px solid " + |border|, + })), + ], +) + +call-function: ("check-style", { + "theme": "ayu", + "background": "rgba(255, 236, 164, 0.06)", + "border": "rgba(255, 180, 76, 0.85)", +}) +call-function: ("check-style", { + "theme": "dark", + "background": "rgb(73, 74, 61)", + "border": "rgb(187, 116, 16)", +}) +call-function: ("check-style", { + "theme": "light", + "background": "rgb(253, 255, 211)", + "border": "rgb(173, 124, 55)", +}) diff --git a/src/test/rustdoc-gui/theme-change.goml b/src/test/rustdoc-gui/theme-change.goml index b1de3c366..cc47f1f45 100644 --- a/src/test/rustdoc-gui/theme-change.goml +++ b/src/test/rustdoc-gui/theme-change.goml @@ -2,31 +2,66 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html" local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"} reload: + +store-value: (background_light, "rgb(255, 255, 255)") +store-value: (background_dark, "rgb(53, 53, 53)") +store-value: (background_ayu, "rgb(15, 20, 25)") + click: "#settings-menu" wait-for: "#theme-ayu" click: "#theme-ayu" // should be the ayu theme so let's check the color. -wait-for-css: ("body", { "background-color": "rgb(15, 20, 25)" }) +wait-for-css: ("body", { "background-color": |background_ayu| }) assert-local-storage: { "rustdoc-theme": "ayu" } click: "#theme-light" // should be the light theme so let's check the color. -wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" }) +wait-for-css: ("body", { "background-color": |background_light| }) assert-local-storage: { "rustdoc-theme": "light" } click: "#theme-dark" // Should be the dark theme so let's check the color. -wait-for-css: ("body", { "background-color": "rgb(53, 53, 53)" }) +wait-for-css: ("body", { "background-color": |background_dark| }) assert-local-storage: { "rustdoc-theme": "dark" } +local-storage: { + "rustdoc-preferred-light-theme": "light", + "rustdoc-preferred-dark-theme": "light", +} goto: "file://" + |DOC_PATH| + "/settings.html" + wait-for: "#settings" click: "#theme-light" -wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" }) +wait-for-css: ("body", { "background-color": |background_light| }) assert-local-storage: { "rustdoc-theme": "light" } click: "#theme-dark" -wait-for-css: ("body", { "background-color": "rgb(53, 53, 53)" }) +wait-for-css: ("body", { "background-color": |background_dark| }) assert-local-storage: { "rustdoc-theme": "dark" } click: "#theme-ayu" -wait-for-css: ("body", { "background-color": "rgb(15, 20, 25)" }) +wait-for-css: ("body", { "background-color": |background_ayu| }) assert-local-storage: { "rustdoc-theme": "ayu" } + +assert-local-storage-false: { "rustdoc-use-system-theme": "true" } +click: "#theme-system-preference" +wait-for: ".setting-line:not(.hidden) #preferred-light-theme" +assert-local-storage: { "rustdoc-use-system-theme": "true" } +// We click on both preferred light and dark themes to be sure that there is a change. +click: "#preferred-light-theme-dark" +click: "#preferred-dark-theme-dark" +wait-for-css: ("body", { "background-color": |background_dark| }) + +reload: +// Ensure that the "preferred themes" are still displayed. +wait-for: ".setting-line:not(.hidden) #preferred-light-theme" +click: "#theme-light" +wait-for-css: ("body", { "background-color": |background_light| }) +assert-local-storage: { "rustdoc-theme": "light" } +// Ensure it's now hidden again +wait-for: ".setting-line.hidden #preferred-light-theme" +// And ensure the theme was rightly set. +wait-for-css: ("body", { "background-color": |background_light| }) +assert-local-storage: { "rustdoc-theme": "light" } + +reload: +wait-for: "#settings" +assert: ".setting-line.hidden #preferred-light-theme" diff --git a/src/test/rustdoc-gui/theme-in-history.goml b/src/test/rustdoc-gui/theme-in-history.goml index c29571728..10508e86a 100644 --- a/src/test/rustdoc-gui/theme-in-history.goml +++ b/src/test/rustdoc-gui/theme-in-history.goml @@ -3,7 +3,6 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html" // Set the theme to dark. local-storage: { "rustdoc-theme": "dark", - "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false", } // We reload the page so the local storage settings are being used. diff --git a/src/test/rustdoc-gui/toggle-docs.goml b/src/test/rustdoc-gui/toggle-docs.goml index 8c9fd0a88..45bb8daf1 100644 --- a/src/test/rustdoc-gui/toggle-docs.goml +++ b/src/test/rustdoc-gui/toggle-docs.goml @@ -7,6 +7,10 @@ wait-for: 50 // This is now collapsed so there shouldn't be the "open" attribute on details. assert-attribute-false: ("#main-content > details.top-doc", {"open": ""}) assert-text: ("#toggle-all-docs", "[+]") +assert-css: ( + "#main-content > details.top-doc > summary", + {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'}, +) click: "#toggle-all-docs" // Not collapsed anymore so the "open" attribute should be back. wait-for-attribute: ("#main-content > details.top-doc", {"open": ""}) @@ -40,3 +44,32 @@ assert-attribute-false: ( click: "#toggle-all-docs" wait-for-text: ("#toggle-all-docs", "[−]") assert-attribute: ("details.rustdoc-toggle", {"open": ""}, ALL) + +// Checking the toggles style. +show-text: true +define-function: ( + "check-color", + (theme, filter), + [ + // Setting the theme. + ("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", ("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", { + "opacity": "1", + "filter": |filter|, + })), + // moving the cursor somewhere else to not mess with next function calls. + ("move-cursor-to", ".search-input"), + ] +) + +call-function: ("check-color", {"theme": "ayu", "filter": "invert(1)"}) +call-function: ("check-color", {"theme": "dark", "filter": "invert(1)"}) +call-function: ("check-color", {"theme": "light", "filter": "none"}) diff --git a/src/test/rustdoc-gui/trait-sidebar-item-order.goml b/src/test/rustdoc-gui/trait-sidebar-item-order.goml index a799444a1..e5d023544 100644 --- a/src/test/rustdoc-gui/trait-sidebar-item-order.goml +++ b/src/test/rustdoc-gui/trait-sidebar-item-order.goml @@ -1,4 +1,9 @@ // Checks that the elements in the sidebar are alphabetically sorted. + +// We need to disable this check because `implementors/test_docs/trait.AnotherOne.js` +// doesn't exist. +fail-on-request-error: false + goto: "file://" + |DOC_PATH| + "/test_docs/trait.AnotherOne.html" assert-text: (".sidebar-elems section .block li:nth-of-type(1) > a", "another") assert-text: (".sidebar-elems section .block li:nth-of-type(2) > a", "func1") diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml index fce3002e7..c014eb52e 100644 --- a/src/test/rustdoc-gui/type-declation-overflow.goml +++ b/src/test/rustdoc-gui/type-declation-overflow.goml @@ -1,4 +1,10 @@ // This test ensures that the items declaration content overflow is handled inside the <pre> directly. + +// We need to disable this check because +// `implementors/test_docs/trait.ALongNameBecauseItHelpsTestingTheCurrentProblem.js` +// doesn't exist. +fail-on-request-error: false + goto: "file://" + |DOC_PATH| + "/lib2/long_trait/trait.ALongNameBecauseItHelpsTestingTheCurrentProblem.html" // We set a fixed size so there is no chance of "random" resize. size: (1100, 800) @@ -35,3 +41,20 @@ goto: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLon store-property: (scrollWidth, ".mobile-topbar h2", "scrollWidth") assert-property: (".mobile-topbar h2", {"clientWidth": |scrollWidth|}) assert-css: (".mobile-topbar h2", {"overflow-x": "hidden"}) + +// Check wrapping for top main-heading h1 and out-of-band. +// On desktop, they wrap when too big. +size: (1100, 800) +goto: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html" +compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y")) +goto: "file://" + |DOC_PATH| + "/lib2/index.html" +compare-elements-position: (".main-heading h1", ".main-heading .out-of-band", ("y")) +// make sure there is a gap between them +compare-elements-position-near-false: (".main-heading h1", ".main-heading .out-of-band", {"x": 550}) + +// On mobile, they always wrap. +size: (600, 600) +goto: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html" +compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y")) +goto: "file://" + |DOC_PATH| + "/lib2/index.html" +compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y")) diff --git a/src/test/rustdoc-gui/where-whitespace.goml b/src/test/rustdoc-gui/where-whitespace.goml index 776c8ec72..41596a9bc 100644 --- a/src/test/rustdoc-gui/where-whitespace.goml +++ b/src/test/rustdoc-gui/where-whitespace.goml @@ -5,13 +5,13 @@ show-text: true // line than "pub trait Whitespace<Idx>"). compare-elements-position-false: (".item-decl code", ".where.fmt-newline", ("y")) // And that the code following it isn't on the same line either. -compare-elements-position-false: (".item-decl .fnname", ".where.fmt-newline", ("y")) +compare-elements-position-false: (".item-decl .fn", ".where.fmt-newline", ("y")) goto: "file://" + |DOC_PATH| + "/lib2/struct.WhereWhitespace.html" // We make the screen a bit wider to ensure that the trait impl is on one line. size: (915, 915) -compare-elements-position-false: ("#method\.new .fnname", "#method\.new .where.fmt-newline", ("y")) +compare-elements-position-false: ("#method\.new .fn", "#method\.new .where.fmt-newline", ("y")) // We ensure that both the trait name and the struct name are on the same line in // "impl<K, T> Whitespace<&K> for WhereWhitespace<T>". compare-elements-position: ( diff --git a/src/test/rustdoc-js/reexport.js b/src/test/rustdoc-js/reexport.js new file mode 100644 index 000000000..871e75d9b --- /dev/null +++ b/src/test/rustdoc-js/reexport.js @@ -0,0 +1,17 @@ +// exact-check + +const QUERY = ['Subscriber', 'AnotherOne']; + +const EXPECTED = [ + { + 'others': [ + { 'path': 'reexport::fmt', 'name': 'Subscriber' }, + { 'path': 'reexport', 'name': 'FmtSubscriber' }, + ], + }, + { + 'others': [ + { 'path': 'reexport', 'name': 'AnotherOne' }, + ], + }, +]; diff --git a/src/test/rustdoc-js/reexport.rs b/src/test/rustdoc-js/reexport.rs new file mode 100644 index 000000000..d69b2901e --- /dev/null +++ b/src/test/rustdoc-js/reexport.rs @@ -0,0 +1,11 @@ +// This test enforces that the (renamed) reexports are present in the search results. + +pub mod fmt { + pub struct Subscriber; +} +mod foo { + pub struct AnotherOne; +} + +pub use foo::AnotherOne; +pub use fmt::Subscriber as FmtSubscriber; diff --git a/src/test/rustdoc-json/enums/auxiliary/color.rs b/src/test/rustdoc-json/enums/auxiliary/color.rs new file mode 100644 index 000000000..7188f7938 --- /dev/null +++ b/src/test/rustdoc-json/enums/auxiliary/color.rs @@ -0,0 +1,5 @@ +pub enum Color { + Red, + Green, + Blue, +} diff --git a/src/test/rustdoc-json/enums/doc_link_to_foreign_variant.rs b/src/test/rustdoc-json/enums/doc_link_to_foreign_variant.rs new file mode 100644 index 000000000..470b195a2 --- /dev/null +++ b/src/test/rustdoc-json/enums/doc_link_to_foreign_variant.rs @@ -0,0 +1,11 @@ +// aux-build: color.rs + +//! The purpose of this test it to have a link to [a foreign variant](Red). + +extern crate color; +use color::Color::Red; + +// @set red = "$.index[*][?(@.inner.is_crate == true)].links.Red" + +// @!has "$.index[*][?(@.name == 'Red')]" +// @!has "$.index[*][?(@.name == 'Color')]" diff --git a/src/test/rustdoc-json/enums/use_glob.rs b/src/test/rustdoc-json/enums/use_glob.rs new file mode 100644 index 000000000..62b8b832a --- /dev/null +++ b/src/test/rustdoc-json/enums/use_glob.rs @@ -0,0 +1,18 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/104942> + +#![feature(no_core)] +#![no_core] + +// @set Color = "$.index[*][?(@.name == 'Color')].id" +pub enum Color { + Red, + Green, + Blue, +} + +// @set use_Color = "$.index[*][?(@.kind == 'import')].id" +// @is "$.index[*][?(@.kind == 'import')].inner.id" $Color +// @is "$.index[*][?(@.kind == 'import')].inner.glob" true +pub use Color::*; + +// @ismany "$.index[*][?(@.name == 'use_glob')].inner.items[*]" $Color $use_Color diff --git a/src/test/rustdoc-json/enums/use_variant.rs b/src/test/rustdoc-json/enums/use_variant.rs new file mode 100644 index 000000000..5f0d2b9b1 --- /dev/null +++ b/src/test/rustdoc-json/enums/use_variant.rs @@ -0,0 +1,15 @@ +#![feature(no_core)] +#![no_core] + +// @set AlwaysNone = "$.index[*][?(@.name == 'AlwaysNone')].id" +pub enum AlwaysNone { + // @set None = "$.index[*][?(@.name == 'None')].id" + None, +} +// @is "$.index[*][?(@.name == 'AlwaysNone')].inner.variants[*]" $None + +// @set use_None = "$.index[*][?(@.kind == 'import')].id" +// @is "$.index[*][?(@.kind == 'import')].inner.id" $None +pub use AlwaysNone::None; + +// @ismany "$.index[*][?(@.name == 'use_variant')].inner.items[*]" $AlwaysNone $use_None diff --git a/src/test/rustdoc-json/enums/use_variant_foreign.rs b/src/test/rustdoc-json/enums/use_variant_foreign.rs new file mode 100644 index 000000000..11bb6ce1f --- /dev/null +++ b/src/test/rustdoc-json/enums/use_variant_foreign.rs @@ -0,0 +1,9 @@ +// aux-build: color.rs + +extern crate color; + +// @is "$.index[*][?(@.inner.name == 'Red')].kind" '"import"' +pub use color::Color::Red; + +// @!has "$.index[*][?(@.name == 'Red')]" +// @!has "$.index[*][?(@.name == 'Color')]" diff --git a/src/test/rustdoc-json/fns/pattern_arg.rs b/src/test/rustdoc-json/fns/pattern_arg.rs new file mode 100644 index 000000000..32b7da0fa --- /dev/null +++ b/src/test/rustdoc-json/fns/pattern_arg.rs @@ -0,0 +1,7 @@ +// @is "$.index[*][?(@.name=='fst')].inner.decl.inputs[0][0]" '"(x, _)"' +pub fn fst<X, Y>((x, _): (X, Y)) -> X { + x +} + +// @is "$.index[*][?(@.name=='drop_int')].inner.decl.inputs[0][0]" '"_"' +pub fn drop_int(_: i32) {} diff --git a/src/test/rustdoc-json/fns/return_type_alias.rs b/src/test/rustdoc-json/fns/return_type_alias.rs new file mode 100644 index 000000000..2578bb49a --- /dev/null +++ b/src/test/rustdoc-json/fns/return_type_alias.rs @@ -0,0 +1,10 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/104851> + +/// @set foo = "$.index[*][?(@.name=='Foo')].id" +pub type Foo = i32; + +// @is "$.index[*][?(@.name=='demo')].inner.decl.output.kind" '"resolved_path"' +// @is "$.index[*][?(@.name=='demo')].inner.decl.output.inner.id" $foo +pub fn demo() -> Foo { + 42 +} diff --git a/src/test/rustdoc-json/impls/import_from_private.rs b/src/test/rustdoc-json/impls/import_from_private.rs index 856f7c701..fa88b6113 100644 --- a/src/test/rustdoc-json/impls/import_from_private.rs +++ b/src/test/rustdoc-json/impls/import_from_private.rs @@ -8,7 +8,7 @@ mod bar { pub struct Baz; // @set impl = "$.index[*][?(@.kind=='impl')].id" impl Baz { - // @set doit = "$.index[*][?(@.kind=='method')].id" + // @set doit = "$.index[*][?(@.kind=='function')].id" pub fn doit() {} } } diff --git a/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs b/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs new file mode 100644 index 000000000..bfe85f59e --- /dev/null +++ b/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs @@ -0,0 +1,8 @@ +pub trait Trait { + /// [`Enum::Variant`] + fn method() {} +} + +pub enum Enum { + Variant, +} diff --git a/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs b/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs new file mode 100644 index 000000000..e29682313 --- /dev/null +++ b/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs @@ -0,0 +1,13 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/105025> +// aux-build: enum_variant_in_trait_method.rs + +extern crate enum_variant_in_trait_method; + +pub struct Local; + +/// local impl +impl enum_variant_in_trait_method::Trait for Local {} + +// @!has "$.index[*][?(@.name == 'Trait')]" +// @!has "$.index[*][?(@.name == 'method')]" +// @count "$.index[*][?(@.docs == 'local impl')].inner.items[*]" 0 diff --git a/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs b/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs new file mode 100644 index 000000000..1e87966b2 --- /dev/null +++ b/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs @@ -0,0 +1,2 @@ +/// The Docs +pub trait HasDocs {} diff --git a/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs b/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs new file mode 100644 index 000000000..25a7c08d6 --- /dev/null +++ b/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs @@ -0,0 +1,10 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/105022> +// aux-build: trait_with_docs.rs + +extern crate trait_with_docs; + +pub struct Local; + +impl trait_with_docs::HasDocs for Local {} + +// @!has "$.index[*][?(@.name == 'HasDocs')]" diff --git a/src/test/rustdoc-json/traits/trait_alias.rs b/src/test/rustdoc-json/traits/trait_alias.rs new file mode 100644 index 000000000..35db9296c --- /dev/null +++ b/src/test/rustdoc-json/traits/trait_alias.rs @@ -0,0 +1,30 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/104923> +// ignore-tidy-linelength + +#![feature(trait_alias)] + +// @set Orig = "$.index[*][?(@.name == 'Orig')].id" +// @is "$.index[*][?(@.name == 'Orig')].kind" '"trait"' +pub trait Orig<T> {} + +// @set Alias = "$.index[*][?(@.name == 'Alias')].id" +// @is "$.index[*][?(@.name == 'Alias')].kind" '"trait_alias"' +// @is "$.index[*][?(@.name == 'Alias')].inner.generics" '{"params": [], "where_predicates": []}' +// @count "$.index[*][?(@.name == 'Alias')].inner.params[*]" 1 +// @is "$.index[*][?(@.name == 'Alias')].inner.params[0].trait_bound.trait.id" $Orig +// @is "$.index[*][?(@.name == 'Alias')].inner.params[0].trait_bound.trait.args.angle_bracketed.args[0].type.inner" '"i32"' +pub trait Alias = Orig<i32>; + +pub struct Struct; + +impl Orig<i32> for Struct {} + +// @is "$.index[*][?(@.name=='takes_alias')].inner.decl.inputs[0][1].kind" '"impl_trait"' +// @is "$.index[*][?(@.name=='takes_alias')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $Alias +// @is "$.index[*][?(@.name=='takes_alias')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $Alias +pub fn takes_alias(_: impl Alias) {} +// FIXME: Should the trait be mentioned in both the decl and generics? + +fn main() { + takes_alias(Struct); +} diff --git a/src/test/rustdoc-json/traits/uses_extern_trait.rs b/src/test/rustdoc-json/traits/uses_extern_trait.rs index 430dd1543..55a51f739 100644 --- a/src/test/rustdoc-json/traits/uses_extern_trait.rs +++ b/src/test/rustdoc-json/traits/uses_extern_trait.rs @@ -1,7 +1,5 @@ #![no_std] pub fn drop_default<T: core::default::Default>(_x: T) {} -// FIXME(adotinthevoid): Theses shouldn't be here -// @has "$.index[*][?(@.name=='Debug')]" -// @set Debug_fmt = "$.index[*][?(@.name=='Debug')].inner.items[*]" -// @has "$.index[*][?(@.name=='fmt')].id" $Debug_fmt +// @!has "$.index[*][?(@.name=='Debug')]" +// @!has "$.index[*][?(@.name=='Default')]" diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs index e58bba640..94ea0e93b 100644 --- a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs +++ b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs @@ -1,3 +1,4 @@ +// check-pass // This test ensures that rustdoc does not panic on inherented associated types // that are referred to without fully-qualified syntax. @@ -9,8 +10,4 @@ pub struct Struct; impl Struct { pub type AssocTy = usize; pub const AssocConst: Self::AssocTy = 42; - //~^ ERROR ambiguous associated type - //~| HELP use fully-qualified syntax - //~| ERROR ambiguous associated type - //~| HELP use fully-qualified syntax } diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr deleted file mode 100644 index b963b722f..000000000 --- a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0223]: ambiguous associated type - --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27 - | -LL | pub const AssocConst: Self::AssocTy = 42; - | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy` - -error[E0223]: ambiguous associated type - --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27 - | -LL | pub const AssocConst: Self::AssocTy = 42; - | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0223`. diff --git a/src/test/rustdoc-ui/const-evalutation-ice.rs b/src/test/rustdoc-ui/const-evalutation-ice.rs new file mode 100644 index 000000000..0dd3bcaa2 --- /dev/null +++ b/src/test/rustdoc-ui/const-evalutation-ice.rs @@ -0,0 +1,11 @@ +// Just check we don't get an ICE for `N`. + +use std::cell::Cell; +use std::mem; + +pub struct S { + s: Cell<usize> +} + +pub const N: usize = 0 - (mem::size_of::<S>() != 400) as usize; +//~^ ERROR evaluation of constant value failed diff --git a/src/test/rustdoc-ui/const-evalutation-ice.stderr b/src/test/rustdoc-ui/const-evalutation-ice.stderr new file mode 100644 index 000000000..5d9c16c07 --- /dev/null +++ b/src/test/rustdoc-ui/const-evalutation-ice.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/const-evalutation-ice.rs:10:22 + | +LL | pub const N: usize = 0 - (mem::size_of::<S>() != 400) as usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr index e7b4c43e7..19e541736 100644 --- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr @@ -4,7 +4,7 @@ error: unknown disambiguator `foo` LL | //! Linking to [foo@banana] and [`bar@banana!()`]. | ^^^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators note: the lint level is defined here --> $DIR/unknown-disambiguator.rs:2:9 | @@ -18,7 +18,7 @@ error: unknown disambiguator `bar` LL | //! Linking to [foo@banana] and [`bar@banana!()`]. | ^^^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: unknown disambiguator `foo` --> $DIR/unknown-disambiguator.rs:10:34 @@ -26,7 +26,7 @@ error: unknown disambiguator `foo` LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello]. | ^^^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: unknown disambiguator `foo` --> $DIR/unknown-disambiguator.rs:10:48 @@ -34,7 +34,7 @@ error: unknown disambiguator `foo` LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello]. | ^^^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: unknown disambiguator `` --> $DIR/unknown-disambiguator.rs:7:31 @@ -42,7 +42,7 @@ error: unknown disambiguator `` LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). | ^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: unknown disambiguator `` --> $DIR/unknown-disambiguator.rs:7:57 @@ -50,7 +50,7 @@ error: unknown disambiguator `` LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). | ^ | - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: aborting due to 6 previous errors diff --git a/src/test/rustdoc-ui/issue-103997.rs b/src/test/rustdoc-ui/issue-103997.rs new file mode 100644 index 000000000..36f42fb15 --- /dev/null +++ b/src/test/rustdoc-ui/issue-103997.rs @@ -0,0 +1,6 @@ +// check-pass + +pub fn foo() {} + +/// [`foo`](Self::foo) //~ WARNING unresolved link to `Self::foo` +pub use foo as bar; diff --git a/src/test/rustdoc-ui/issue-103997.stderr b/src/test/rustdoc-ui/issue-103997.stderr new file mode 100644 index 000000000..c06db9149 --- /dev/null +++ b/src/test/rustdoc-ui/issue-103997.stderr @@ -0,0 +1,10 @@ +warning: unresolved link to `Self::foo` + --> $DIR/issue-103997.rs:5:13 + | +LL | /// [`foo`](Self::foo) + | ^^^^^^^^^ no item named `Self` in scope + | + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: 1 warning emitted + diff --git a/src/test/rustdoc-ui/issue-91713.stdout b/src/test/rustdoc-ui/issue-91713.stdout index a19e452b4..167835243 100644 --- a/src/test/rustdoc-ui/issue-91713.stdout +++ b/src/test/rustdoc-ui/issue-91713.stdout @@ -5,11 +5,9 @@ check_doc_test_visibility - run various visibility-related lints on doctests strip-priv-imports - strips all private import statements (`use`, `extern crate`) from a crate propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items collect-intra-doc-links - resolves intra-doc links -check-code-block-syntax - validates syntax inside Rust code blocks collect-trait-impls - retrieves trait impls for items in the crate calculate-doc-coverage - counts the number of items with and without documentation -check-invalid-html-tags - detects invalid HTML tags in doc comments - check-bare-urls - detects URLs that are not hyperlinks + run-lints - runs some of rustdoc's lints Default passes for rustdoc: collect-trait-impls @@ -18,10 +16,8 @@ check_doc_test_visibility strip-private (when not --document-private-items) strip-priv-imports (when --document-private-items) collect-intra-doc-links -check-code-block-syntax -check-invalid-html-tags propagate-doc-cfg - check-bare-urls + run-lints Passes run with `--show-coverage`: strip-hidden (when not --document-hidden-items) diff --git a/src/test/rustdoc-ui/track-diagnostics.rs b/src/test/rustdoc-ui/track-diagnostics.rs new file mode 100644 index 000000000..fcc50a7ab --- /dev/null +++ b/src/test/rustdoc-ui/track-diagnostics.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" + +struct A; +struct B; +const S: A = B; diff --git a/src/test/rustdoc-ui/track-diagnostics.stderr b/src/test/rustdoc-ui/track-diagnostics.stderr new file mode 100644 index 000000000..ec3031862 --- /dev/null +++ b/src/test/rustdoc-ui/track-diagnostics.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> $DIR/track-diagnostics.rs:LL:CC + | +LL | const S: A = B; + | ^ expected struct `A`, found struct `B` +-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index 46f11d2e5..94cf7b942 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -77,6 +77,7 @@ -Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`) -Z ls=val -- list the symbols defined by a library crate (default: no) -Z macro-backtrace=val -- show macro backtraces (default: no) + -Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no) -Z merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name -Z meta-stats=val -- gather metadata statistics (default: no) -Z mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no) @@ -90,7 +91,6 @@ -Z no-analysis=val -- parse and expand the source, but run no analysis -Z no-codegen=val -- run all passes except codegen; no output -Z no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups - -Z no-interleave-lints=val -- execute lints separately; allows benchmarking individual lints -Z no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests -Z no-link=val -- compile without linking -Z no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO) @@ -171,6 +171,7 @@ -Z time-passes=val -- measure time of each rustc pass (default: no) -Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details) -Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no) + -Z track-diagnostics=val -- tracks where in rustc a diagnostic was emitted -Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation) -Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics -Z translate-lang=val -- language identifier for diagnostic output diff --git a/src/test/rustdoc/anchors.no_method_anchor.html b/src/test/rustdoc/anchors.no_method_anchor.html index 521fdcb78..b9ec8bf4c 100644 --- a/src/test/rustdoc/anchors.no_method_anchor.html +++ b/src/test/rustdoc/anchors.no_method_anchor.html @@ -1 +1 @@ -<section id="method.new" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#48">source</a><h4 class="code-header">pub fn <a href="#method.new" class="fnname">new</a>() -> Self</h4></section>
\ No newline at end of file +<section id="method.new" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#48">source</a><h4 class="code-header">pub fn <a href="#method.new" class="fn">new</a>() -> Self</h4></section>
\ No newline at end of file diff --git a/src/test/rustdoc/anchors.no_trait_method_anchor.html b/src/test/rustdoc/anchors.no_trait_method_anchor.html index d7bd525ff..4308ddad4 100644 --- a/src/test/rustdoc/anchors.no_trait_method_anchor.html +++ b/src/test/rustdoc/anchors.no_trait_method_anchor.html @@ -1 +1 @@ -<section id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fnname">bar</a>()</h4></section>
\ No newline at end of file +<section id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fn">bar</a>()</h4></section>
\ No newline at end of file diff --git a/src/test/rustdoc/anchors.no_tymethod_anchor.html b/src/test/rustdoc/anchors.no_tymethod_anchor.html index e668e5e4d..91eed8a37 100644 --- a/src/test/rustdoc/anchors.no_tymethod_anchor.html +++ b/src/test/rustdoc/anchors.no_tymethod_anchor.html @@ -1 +1 @@ -<section id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fnname">foo</a>()</h4></section>
\ No newline at end of file +<section id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fn">foo</a>()</h4></section>
\ No newline at end of file diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs index a3e10ee55..3da19a13e 100644 --- a/src/test/rustdoc/assoc-consts.rs +++ b/src/test/rustdoc/assoc-consts.rs @@ -46,6 +46,7 @@ pub fn f(_: &(ToString + 'static)) {} impl Bar { // @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \ // "const F: fn(_: &(dyn ToString + 'static))" + // FIXME(fmease): Hide default lifetime, render "const F: fn(_: &dyn ToString)" pub const F: fn(_: &(ToString + 'static)) = f; } diff --git a/src/test/rustdoc/async-trait-sig.rs b/src/test/rustdoc/async-trait-sig.rs new file mode 100644 index 000000000..2578bc8f7 --- /dev/null +++ b/src/test/rustdoc/async-trait-sig.rs @@ -0,0 +1,14 @@ +// edition:2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +pub trait Foo { + // @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn bar() -> i32" + async fn bar() -> i32; + + // @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn baz() -> i32" + async fn baz() -> i32 { + 1 + } +} diff --git a/src/test/rustdoc/auxiliary/masked.rs b/src/test/rustdoc/auxiliary/masked.rs index f289359e5..3d722d5e0 100644 --- a/src/test/rustdoc/auxiliary/masked.rs +++ b/src/test/rustdoc/auxiliary/masked.rs @@ -8,3 +8,7 @@ pub trait MaskedTrait { impl MaskedTrait for String { fn masked_method() {} } + +pub trait MaskedBlanketTrait {} + +impl<T> MaskedBlanketTrait for T {} diff --git a/src/test/rustdoc/bounds-in-multiple-parts.rs b/src/test/rustdoc/bounds-in-multiple-parts.rs new file mode 100644 index 000000000..279e3c148 --- /dev/null +++ b/src/test/rustdoc/bounds-in-multiple-parts.rs @@ -0,0 +1,20 @@ +#![crate_name = "foo"] + +pub trait Eq {} +pub trait Eq2 {} + +// Checking that "where predicates" and "generics params" are merged. +// @has 'foo/trait.T.html' +// @has - "//*[@id='tymethod.f']/h4" "fn f<'a, 'b, 'c, T>()where Self: Eq, T: Eq + 'a, 'c: 'b + 'a," +pub trait T { + fn f<'a, 'b, 'c: 'a, T: Eq + 'a>() + where Self: Eq, Self: Eq, T: Eq, 'c: 'b; +} + +// Checking that a duplicated "where predicate" is removed. +// @has 'foo/trait.T2.html' +// @has - "//*[@id='tymethod.f']/h4" "fn f<T>()where Self: Eq + Eq2, T: Eq2 + Eq," +pub trait T2 { + fn f<T: Eq>() + where Self: Eq, Self: Eq2, T: Eq2; +} diff --git a/src/test/rustdoc/check-source-code-urls-to-def.rs b/src/test/rustdoc/check-source-code-urls-to-def.rs index d00a3e355..5959f9c7c 100644 --- a/src/test/rustdoc/check-source-code-urls-to-def.rs +++ b/src/test/rustdoc/check-source-code-urls-to-def.rs @@ -10,14 +10,14 @@ extern crate source_code; // @has 'src/foo/check-source-code-urls-to-def.rs.html' -// @has - '//a[@href="auxiliary/source-code-bar.rs.html#1-17"]' 'bar' +// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#1-17"]' 'bar' #[path = "auxiliary/source-code-bar.rs"] pub mod bar; -// @count - '//a[@href="auxiliary/source-code-bar.rs.html#5"]' 4 +// @count - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#5"]' 4 use bar::Bar; -// @has - '//a[@href="auxiliary/source-code-bar.rs.html#13"]' 'self' -// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait' +// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#13"]' 'self' +// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait' use bar::sub::{self, Trait}; pub struct Foo; @@ -28,29 +28,29 @@ impl Foo { fn babar() {} -// @has - '//a/@href' '/struct.String.html' -// @has - '//a/@href' '/primitive.u32.html' -// @has - '//a/@href' '/primitive.str.html' -// @count - '//a[@href="#23"]' 5 -// @has - '//a[@href="../../source_code/struct.SourceCode.html"]' 'source_code::SourceCode' +// @has - '//pre[@class="rust"]//a/@href' '/struct.String.html' +// @has - '//pre[@class="rust"]//a/@href' '/primitive.u32.html' +// @has - '//pre[@class="rust"]//a/@href' '/primitive.str.html' +// @count - '//pre[@class="rust"]//a[@href="#23"]' 5 +// @has - '//pre[@class="rust"]//a[@href="../../source_code/struct.SourceCode.html"]' 'source_code::SourceCode' pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::SourceCode) { let x = 12; let y: Foo = Foo; let z: Bar = bar::Bar { field: Foo }; babar(); - // @has - '//a[@href="#26"]' 'hello' + // @has - '//pre[@class="rust"]//a[@href="#26"]' 'hello' y.hello(); } -// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'bar::sub::Trait' -// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait' +// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'bar::sub::Trait' +// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait' pub fn foo2<T: bar::sub::Trait, V: Trait>(t: &T, v: &V, b: bool) {} pub trait AnotherTrait {} pub trait WhyNot {} -// @has - '//a[@href="#49"]' 'AnotherTrait' -// @has - '//a[@href="#50"]' 'WhyNot' +// @has - '//pre[@class="rust"]//a[@href="#49"]' 'AnotherTrait' +// @has - '//pre[@class="rust"]//a[@href="#50"]' 'WhyNot' pub fn foo3<T, V>(t: &T, v: &V) where T: AnotherTrait, @@ -59,11 +59,11 @@ where pub trait AnotherTrait2 {} -// @has - '//a[@href="#60"]' 'AnotherTrait2' +// @has - '//pre[@class="rust"]//a[@href="#60"]' 'AnotherTrait2' pub fn foo4() { let x: Vec<AnotherTrait2> = Vec::new(); } -// @has - '//a[@href="../../foo/primitive.bool.html"]' 'bool' +// @has - '//pre[@class="rust"]//a[@href="../../foo/primitive.bool.html"]' 'bool' #[doc(primitive = "bool")] mod whatever {} diff --git a/src/test/rustdoc/const-evalutation-ice.rs b/src/test/rustdoc/const-evalutation-ice.rs deleted file mode 100644 index 68c7f9c56..000000000 --- a/src/test/rustdoc/const-evalutation-ice.rs +++ /dev/null @@ -1,10 +0,0 @@ -// Just check we don't get an ICE for `N`. - -use std::cell::Cell; -use std::mem; - -pub struct S { - s: Cell<usize> -} - -pub const N: usize = 0 - (mem::size_of::<S>() != 4) as usize; diff --git a/src/test/rustdoc/decl-trailing-whitespace.declaration.html b/src/test/rustdoc/decl-trailing-whitespace.declaration.html index e60caaeff..02b51b344 100644 --- a/src/test/rustdoc/decl-trailing-whitespace.declaration.html +++ b/src/test/rustdoc/decl-trailing-whitespace.declaration.html @@ -1,7 +1,7 @@ <code>pub trait Write { - fn <a href="#tymethod.poll_write" class="fnname">poll_write</a>(<br />        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        cx: &mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        buf: &mut [<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]<br />    ) -> <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>>>; -<span class="item-spacer" /> fn <a href="#tymethod.poll_flush" class="fnname">poll_flush</a>(<br />        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        cx: &mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>><br />    ) -> <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>>>; -<span class="item-spacer" /> fn <a href="#tymethod.poll_close" class="fnname">poll_close</a>(<br />        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        cx: &mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>><br />    ) -> <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>>>; + fn <a href="#tymethod.poll_write" class="fn">poll_write</a>(<br />        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        cx: &mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        buf: &mut [<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]<br />    ) -> <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>>>; +<span class="item-spacer" /> fn <a href="#tymethod.poll_flush" class="fn">poll_flush</a>(<br />        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        cx: &mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>><br />    ) -> <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>>>; +<span class="item-spacer" /> fn <a href="#tymethod.poll_close" class="fn">poll_close</a>(<br />        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        cx: &mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>><br />    ) -> <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>>>; - fn <a href="#method.poll_write_vectored" class="fnname">poll_write_vectored</a>(<br />        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        cx: &mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        bufs: &[<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]<br />    ) -> <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>>> { ... } -}</code> + fn <a href="#method.poll_write_vectored" class="fn">poll_write_vectored</a>(<br />        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        cx: &mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>>,<br />        bufs: &[<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]<br />    ) -> <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a><<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a><<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>>> { ... } +}</code>
\ No newline at end of file diff --git a/src/test/rustdoc/deref-to-primitive.rs b/src/test/rustdoc/deref-to-primitive.rs new file mode 100644 index 000000000..527de780d --- /dev/null +++ b/src/test/rustdoc/deref-to-primitive.rs @@ -0,0 +1,15 @@ +#![crate_name = "foo"] + +// @has 'foo/struct.Foo.html' +// @has - '//*[@id="deref-methods-i32"]' 'Methods from Deref<Target = i32>' +// @has - '//*[@id="deref-methods-i32-1"]//*[@id="associatedconstant.BITS"]/h4' \ +// 'pub const BITS: u32 = 32u32' +pub struct Foo(i32); + +impl std::ops::Deref for Foo { + type Target = i32; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html b/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html new file mode 100644 index 000000000..f2ec8320a --- /dev/null +++ b/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html @@ -0,0 +1 @@ +<script type="text/json" id="notable-traits-data">{"&'static [SomeStruct]":"<h3>Notable traits for <code>&amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\">SomeTrait</a> for &amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</span>"}</script>
\ No newline at end of file diff --git a/src/test/rustdoc/doc-notable_trait-slice.rs b/src/test/rustdoc/doc-notable_trait-slice.rs index b0d414027..2411da8cd 100644 --- a/src/test/rustdoc/doc-notable_trait-slice.rs +++ b/src/test/rustdoc/doc-notable_trait-slice.rs @@ -8,13 +8,13 @@ pub struct OtherStruct; impl SomeTrait for &[SomeStruct] {} // @has doc_notable_trait_slice/fn.bare_fn_matches.html -// @has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]' +// @snapshot bare_fn_matches - '//script[@id="notable-traits-data"]' pub fn bare_fn_matches() -> &'static [SomeStruct] { &[] } // @has doc_notable_trait_slice/fn.bare_fn_no_matches.html -// @!has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]' +// @count - '//script[@id="notable-traits-data"]' 0 pub fn bare_fn_no_matches() -> &'static [OtherStruct] { &[] } diff --git a/src/test/rustdoc/doc-notable_trait.bare-fn.html b/src/test/rustdoc/doc-notable_trait.bare-fn.html new file mode 100644 index 000000000..b426a4d7a --- /dev/null +++ b/src/test/rustdoc/doc-notable_trait.bare-fn.html @@ -0,0 +1 @@ +<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></span>"}</script>
\ No newline at end of file diff --git a/src/test/rustdoc/doc-notable_trait.rs b/src/test/rustdoc/doc-notable_trait.rs index 58a24b855..279faf554 100644 --- a/src/test/rustdoc/doc-notable_trait.rs +++ b/src/test/rustdoc/doc-notable_trait.rs @@ -9,7 +9,8 @@ impl<T: SomeTrait> SomeTrait for Wrapper<T> {} #[doc(notable_trait)] pub trait SomeTrait { // @has doc_notable_trait/trait.SomeTrait.html - // @has - '//code[@class="content"]' 'impl<T: SomeTrait> SomeTrait for Wrapper<T>' + // @has - '//a[@class="notable-traits"]/@data-ty' 'Wrapper<Self>' + // @snapshot wrap-me - '//script[@id="notable-traits-data"]' fn wrap_me(self) -> Wrapper<Self> where Self: Sized { Wrapper { inner: self, @@ -22,15 +23,16 @@ impl SomeTrait for SomeStruct {} impl SomeStruct { // @has doc_notable_trait/struct.SomeStruct.html - // @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct' - // @has - '//code[@class="content"]' 'impl<T: SomeTrait> SomeTrait for Wrapper<T>' + // @has - '//a[@class="notable-traits"]/@data-ty' 'SomeStruct' + // @snapshot some-struct-new - '//script[@id="notable-traits-data"]' pub fn new() -> SomeStruct { SomeStruct } } // @has doc_notable_trait/fn.bare_fn.html -// @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct' +// @has - '//a[@class="notable-traits"]/@data-ty' 'SomeStruct' +// @snapshot bare-fn - '//script[@id="notable-traits-data"]' pub fn bare_fn() -> SomeStruct { SomeStruct } diff --git a/src/test/rustdoc/doc-notable_trait.some-struct-new.html b/src/test/rustdoc/doc-notable_trait.some-struct-new.html new file mode 100644 index 000000000..4f8063807 --- /dev/null +++ b/src/test/rustdoc/doc-notable_trait.some-struct-new.html @@ -0,0 +1 @@ +<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></span>","Wrapper<Self>":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl&lt;T:&nbsp;<a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</span>"}</script>
\ No newline at end of file diff --git a/src/test/rustdoc/doc-notable_trait.wrap-me.html b/src/test/rustdoc/doc-notable_trait.wrap-me.html new file mode 100644 index 000000000..bed2a38b2 --- /dev/null +++ b/src/test/rustdoc/doc-notable_trait.wrap-me.html @@ -0,0 +1 @@ +<script type="text/json" id="notable-traits-data">{"Wrapper<Self>":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl&lt;T:&nbsp;<a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</span>"}</script>
\ No newline at end of file diff --git a/src/test/rustdoc/extern-default-method.no_href_on_anchor.html b/src/test/rustdoc/extern-default-method.no_href_on_anchor.html index dab0a6495..ef14836cc 100644 --- a/src/test/rustdoc/extern-default-method.no_href_on_anchor.html +++ b/src/test/rustdoc/extern-default-method.no_href_on_anchor.html @@ -1 +1 @@ -<a class="fnname">provided</a>(&self)
\ No newline at end of file +<a class="fn">provided</a>(&self)
\ No newline at end of file diff --git a/src/test/rustdoc/extern-default-method.rs b/src/test/rustdoc/extern-default-method.rs index 8139f5b26..fc28b230a 100644 --- a/src/test/rustdoc/extern-default-method.rs +++ b/src/test/rustdoc/extern-default-method.rs @@ -11,13 +11,13 @@ extern crate rustdoc_extern_default_method as ext; // However, the method in the trait impl should *not* have a link (an `href` attribute) to // its corresponding item in the trait declaration since it would otherwise be broken. // -// In older versions of rustdoc, the impl item (`a[@class="fnname"]`) used to link to +// In older versions of rustdoc, the impl item (`a[@class="fn"]`) used to link to // `#method.provided` – i.e. "to itself". Put in quotes since that was actually incorrect in // general: If the type `Struct` also had an inherent method called `provided`, the impl item // would link to that one even though those two methods are distinct items! // @count extern_default_method/struct.Struct.html '//*[@id="method.provided"]' 1 -// @count extern_default_method/struct.Struct.html '//*[@id="method.provided"]//a[@class="fnname"]' 1 -// @snapshot no_href_on_anchor - '//*[@id="method.provided"]//a[@class="fnname"]' +// @count extern_default_method/struct.Struct.html '//*[@id="method.provided"]//a[@class="fn"]' 1 +// @snapshot no_href_on_anchor - '//*[@id="method.provided"]//a[@class="fn"]' // @has extern_default_method/struct.Struct.html '//*[@id="method.provided"]//a[@class="anchor"]/@href' #method.provided pub use ext::Struct; diff --git a/src/test/rustdoc/foreigntype.rs b/src/test/rustdoc/foreigntype.rs index 891cdd5fe..29f9c2926 100644 --- a/src/test/rustdoc/foreigntype.rs +++ b/src/test/rustdoc/foreigntype.rs @@ -6,7 +6,7 @@ extern "C" { } impl ExtType { - // @has - '//a[@class="fnname"]' 'do_something' + // @has - '//a[@class="fn"]' 'do_something' pub fn do_something(&self) {} } diff --git a/src/test/rustdoc/impl-parts.rs b/src/test/rustdoc/impl-parts.rs index 7b931727e..90cbb77cb 100644 --- a/src/test/rustdoc/impl-parts.rs +++ b/src/test/rustdoc/impl-parts.rs @@ -6,7 +6,7 @@ pub auto trait AnAutoTrait {} pub struct Foo<T> { field: T } // @has impl_parts/struct.Foo.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \ -// "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync," +// "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone," // @has impl_parts/trait.AnAutoTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \ -// "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync," +// "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone," impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync {} diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs index 5f4712aab..db2491b87 100644 --- a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs +++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs @@ -33,8 +33,12 @@ extern crate assoc_item_trait_bounds as aux; // @snapshot out9 - '//*[@id="associatedtype.Out9"]/*[@class="code-header"]' // // @has - '//*[@id="tymethod.make"]' \ -// "fn make<F>(F, impl FnMut(&str) -> bool)\ +// "fn make<F>(_: F, _: impl FnMut(&str) -> bool)\ // where \ // F: FnOnce(u32) -> String, \ // Self::Out2<()>: Protocol<u8, Q0 = Self::Item, Q1 = ()>" pub use aux::Main; + +// @has main/trait.Aid.html +// @has - '//*[@id="associatedtype.Result"]' "type Result<'inter: 'src>" +pub use aux::Aid; diff --git a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs index d326e61da..6644c8e41 100644 --- a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs +++ b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs @@ -42,5 +42,5 @@ pub trait Helper { } pub trait Aid<'src> { - type Result<'inter>; + type Result<'inter: 'src>; } diff --git a/src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs b/src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs new file mode 100644 index 000000000..9ac2e3d96 --- /dev/null +++ b/src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs @@ -0,0 +1,17 @@ +pub type Ty0 = dyn for<'any> FnOnce(&'any str) -> bool; + +pub type Ty1<'obj> = dyn std::fmt::Display + 'obj; + +pub type Ty2 = dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>; + +pub type Ty3<'s> = &'s dyn ToString; + +pub fn func0(_: &(dyn Fn() + '_)) {} + +pub fn func1<'func>(_: &(dyn Fn() + 'func)) {} + +pub trait Container<'r> { + type Item<'a, 'ctx>; +} + +pub trait Shape<'a> {} diff --git a/src/test/rustdoc/inline_cross/dyn_trait.rs b/src/test/rustdoc/inline_cross/dyn_trait.rs new file mode 100644 index 000000000..fa760540e --- /dev/null +++ b/src/test/rustdoc/inline_cross/dyn_trait.rs @@ -0,0 +1,31 @@ +#![crate_name = "user"] + +// aux-crate:dyn_trait=dyn_trait.rs +// edition:2021 + +// @has user/type.Ty0.html +// @has - '//*[@class="item-decl"]//code' "dyn for<'any> FnOnce(&'any str) -> bool + 'static" +// FIXME(fmease): Hide default lifetime bound `'static` +pub use dyn_trait::Ty0; + +// @has user/type.Ty1.html +// @has - '//*[@class="item-decl"]//code' "dyn Display + 'obj" +pub use dyn_trait::Ty1; + +// @has user/type.Ty2.html +// @has - '//*[@class="item-decl"]//code' "dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>" +pub use dyn_trait::Ty2; + +// @has user/type.Ty3.html +// @has - '//*[@class="item-decl"]//code' "&'s (dyn ToString + 's)" +// FIXME(fmease): Hide default lifetime bound, render "&'s dyn ToString" +pub use dyn_trait::Ty3; + +// @has user/fn.func0.html +// @has - '//pre[@class="rust fn"]' "func0(_: &dyn Fn())" +// FIXME(fmease): Show placeholder-lifetime bound, render "func0(_: &(dyn Fn() + '_))" +pub use dyn_trait::func0; + +// @has user/fn.func1.html +// @has - '//pre[@class="rust fn"]' "func1<'func>(_: &(dyn Fn() + 'func))" +pub use dyn_trait::func1; diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs index 6c1cf8252..9c4f64659 100644 --- a/src/test/rustdoc/inline_cross/impl_trait.rs +++ b/src/test/rustdoc/inline_cross/impl_trait.rs @@ -29,7 +29,7 @@ pub use impl_trait_aux::func4; // @has impl_trait/fn.func5.html // @has - '//pre[@class="rust fn"]' "func5(" // @has - '//pre[@class="rust fn"]' "_f: impl for<'any> Fn(&'any str, &'any str) -> bool + for<'r> Other<T<'r> = ()>," -// @has - '//pre[@class="rust fn"]' "_a: impl for<'alpha, 'beta> Auxiliary<'alpha, Item<'beta> = fn(&'beta ())>" +// @has - '//pre[@class="rust fn"]' "_a: impl for<'alpha, 'beta> Auxiliary<'alpha, Item<'beta> = fn(_: &'beta ())>" // @!has - '//pre[@class="rust fn"]' 'where' pub use impl_trait_aux::func5; diff --git a/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html b/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html index 6955a9614..f3c1c0452 100644 --- a/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html +++ b/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html @@ -1 +1 @@ -<h4 class="code-header">fn <a href="#method.touch" class="fnname">touch</a>(&self)</h4>
\ No newline at end of file +<h4 class="code-header">fn <a href="#method.touch" class="fn">touch</a>(&self)</h4>
\ No newline at end of file diff --git a/src/test/rustdoc/issue-102154.rs b/src/test/rustdoc/issue-102154.rs new file mode 100644 index 000000000..b36f27080 --- /dev/null +++ b/src/test/rustdoc/issue-102154.rs @@ -0,0 +1,13 @@ +trait A<Y, N> { + type B; +} +type MaybeBox<T> = <T as A<T, Box<T>>>::B; +struct P { + t: MaybeBox<P> +} +impl<Y, N> A<Y, N> for P { + type B = N; +} +fn main() { + let t: MaybeBox<P>; +} diff --git a/src/test/rustdoc/issue-20727.rs b/src/test/rustdoc/issue-20727.rs index f7acffcb4..c1a98cd57 100644 --- a/src/test/rustdoc/issue-20727.rs +++ b/src/test/rustdoc/issue-20727.rs @@ -19,6 +19,6 @@ pub mod reexport { // @has - '//*[@class="rust trait"]' 'trait Deref {' // @has - '//*[@class="rust trait"]' 'type Target: ?Sized;' // @has - '//*[@class="rust trait"]' \ - // "fn deref(&'a self) -> &'a Self::Target;" + // "fn deref<'a>(&'a self) -> &'a Self::Target;" pub use issue_20727::Deref; } diff --git a/src/test/rustdoc/issue-41783.codeblock.html b/src/test/rustdoc/issue-41783.codeblock.html index 89987491d..3bca4536c 100644 --- a/src/test/rustdoc/issue-41783.codeblock.html +++ b/src/test/rustdoc/issue-41783.codeblock.html @@ -1,5 +1,5 @@ <code># single ## double ### triple -<span class="attribute">#[outer] +<span class="attr">#[outer] #![inner]</span></code> diff --git a/src/test/rustdoc/issue-41783.rs b/src/test/rustdoc/issue-41783.rs index 87267a750..769f984a2 100644 --- a/src/test/rustdoc/issue-41783.rs +++ b/src/test/rustdoc/issue-41783.rs @@ -1,10 +1,10 @@ // @has issue_41783/struct.Foo.html // @!hasraw - 'space' // @!hasraw - 'comment' -// @hasraw - '<span class="attribute">#[outer]' -// @!hasraw - '<span class="attribute">#[outer]</span>' +// @hasraw - '<span class="attr">#[outer]' +// @!hasraw - '<span class="attr">#[outer]</span>' // @hasraw - '#![inner]</span>' -// @!hasraw - '<span class="attribute">#![inner]</span>' +// @!hasraw - '<span class="attr">#![inner]</span>' // @snapshot 'codeblock' - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]//pre/code' /// ```no_run diff --git a/src/test/rustdoc/issue-88600.rs b/src/test/rustdoc/issue-88600.rs index fc63ed343..db0d102b7 100644 --- a/src/test/rustdoc/issue-88600.rs +++ b/src/test/rustdoc/issue-88600.rs @@ -8,22 +8,22 @@ pub struct S; // @has issue_88600/enum.FooEnum.html pub enum FooEnum { - // @has - '//*[@id="variant.HiddenTupleItem"]//code' 'HiddenTupleItem(_)' + // @has - '//*[@id="variant.HiddenTupleItem"]//h3' 'HiddenTupleItem(_)' // @count - '//*[@id="variant.HiddenTupleItem.field.0"]' 0 HiddenTupleItem(#[doc(hidden)] H), - // @has - '//*[@id="variant.MultipleHidden"]//code' 'MultipleHidden(_, _)' + // @has - '//*[@id="variant.MultipleHidden"]//h3' 'MultipleHidden(_, _)' // @count - '//*[@id="variant.MultipleHidden.field.0"]' 0 // @count - '//*[@id="variant.MultipleHidden.field.1"]' 0 MultipleHidden(#[doc(hidden)] H, #[doc(hidden)] H), - // @has - '//*[@id="variant.MixedHiddenFirst"]//code' 'MixedHiddenFirst(_, S)' + // @has - '//*[@id="variant.MixedHiddenFirst"]//h3' 'MixedHiddenFirst(_, S)' // @count - '//*[@id="variant.MixedHiddenFirst.field.0"]' 0 // @has - '//*[@id="variant.MixedHiddenFirst.field.1"]' '1: S' MixedHiddenFirst(#[doc(hidden)] H, /** dox */ S), - // @has - '//*[@id="variant.MixedHiddenLast"]//code' 'MixedHiddenLast(S, _)' + // @has - '//*[@id="variant.MixedHiddenLast"]//h3' 'MixedHiddenLast(S, _)' // @has - '//*[@id="variant.MixedHiddenLast.field.0"]' '0: S' // @count - '//*[@id="variant.MixedHiddenLast.field.1"]' 0 MixedHiddenLast(/** dox */ S, #[doc(hidden)] H), - // @has - '//*[@id="variant.HiddenStruct"]//code' 'HiddenStruct' + // @has - '//*[@id="variant.HiddenStruct"]//h3' 'HiddenStruct' // @count - '//*[@id="variant.HiddenStruct.field.h"]' 0 // @has - '//*[@id="variant.HiddenStruct.field.s"]' 's: S' HiddenStruct { diff --git a/src/test/rustdoc/local-reexport-doc.rs b/src/test/rustdoc/local-reexport-doc.rs new file mode 100644 index 000000000..1c8468008 --- /dev/null +++ b/src/test/rustdoc/local-reexport-doc.rs @@ -0,0 +1,16 @@ +// This test ensures that the reexports of local items also get the doc from +// the reexport. + +#![crate_name = "foo"] + +// @has 'foo/fn.g.html' +// @has - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]' \ +// 'outer module inner module' + +mod inner_mod { + /// inner module + pub fn g() {} +} + +/// outer module +pub use inner_mod::g; diff --git a/src/test/rustdoc/masked.rs b/src/test/rustdoc/masked.rs index 80d5b99c0..875c026fd 100644 --- a/src/test/rustdoc/masked.rs +++ b/src/test/rustdoc/masked.rs @@ -10,6 +10,7 @@ extern crate masked; // @!hasraw 'search-index.js' 'masked_method' // @!hasraw 'foo/struct.String.html' 'MaskedTrait' +// @!hasraw 'foo/struct.String.html' 'MaskedBlanketTrait' // @!hasraw 'foo/struct.String.html' 'masked_method' pub use std::string::String; diff --git a/src/test/rustdoc/multiple-import-levels.rs b/src/test/rustdoc/multiple-import-levels.rs new file mode 100644 index 000000000..1daae49cd --- /dev/null +++ b/src/test/rustdoc/multiple-import-levels.rs @@ -0,0 +1,34 @@ +// The goal of this test is to ensure that the attributes of all imports are taken into +// account. + +#![crate_name = "foo"] + +mod a { + /// 1 + pub struct Type; +} + +mod b { + /// 2 + pub use crate::a::Type; +} + +mod c { + /// 3 + pub use crate::b::Type; + /// 4 + pub use crate::b::Type as Woof; +} + +// @has 'foo/struct.Type.html' +// @has - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]' 'foo 2 1' +/// foo +pub use b::Type; +// @has 'foo/struct.Whatever.html' +// @has - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]' 'whatever 3 2 1' +/// whatever +pub use c::Type as Whatever; +// @has 'foo/struct.Woof.html' +// @has - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]' 'a dog 4 2 1' +/// a dog +pub use c::Woof; diff --git a/src/test/rustdoc/no-unit-struct-field.rs b/src/test/rustdoc/no-unit-struct-field.rs new file mode 100644 index 000000000..d301954b6 --- /dev/null +++ b/src/test/rustdoc/no-unit-struct-field.rs @@ -0,0 +1,18 @@ +// This test ensures that the tuple struct fields are not generated in the +// search index. + +// @!hasraw search-index.js '"0"' +// @!hasraw search-index.js '"1"' +// @hasraw search-index.js '"foo_a"' +// @hasraw search-index.js '"bar_a"' + +pub struct Bar(pub u32, pub u8); +pub struct Foo { + pub foo_a: u8, +} +pub enum Enum { + Foo(u8), + Bar { + bar_a: u8, + }, +} diff --git a/src/test/rustdoc/rfc-2632-const-trait-impl.rs b/src/test/rustdoc/rfc-2632-const-trait-impl.rs index 602ee1b1b..7ed9d6729 100644 --- a/src/test/rustdoc/rfc-2632-const-trait-impl.rs +++ b/src/test/rustdoc/rfc-2632-const-trait-impl.rs @@ -61,7 +61,7 @@ impl<T> S<T> { // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone' // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const' // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' - pub const fn foo<B: ~const Clone + ~const Destruct>() + pub const fn foo<B, C: ~const Clone + ~const Destruct>() where B: ~const Clone + ~const Destruct, { diff --git a/src/test/rustdoc/spotlight-from-dependency.odd.html b/src/test/rustdoc/spotlight-from-dependency.odd.html new file mode 100644 index 000000000..1d02c13eb --- /dev/null +++ b/src/test/rustdoc/spotlight-from-dependency.odd.html @@ -0,0 +1 @@ +<script type="text/json" id="notable-traits-data">{"Odd":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\">Iterator</a> for <a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></span><span class=\"where fmt-newline\"> type <a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\">Item</a> = <a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\">usize</a>;</span>"}</script>
\ No newline at end of file diff --git a/src/test/rustdoc/spotlight-from-dependency.rs b/src/test/rustdoc/spotlight-from-dependency.rs index 524578921..090ad187d 100644 --- a/src/test/rustdoc/spotlight-from-dependency.rs +++ b/src/test/rustdoc/spotlight-from-dependency.rs @@ -3,7 +3,8 @@ use std::iter::Iterator; // @has foo/struct.Odd.html -// @has - '//*[@id="method.new"]//span[@class="notable-traits"]//code/span' 'impl Iterator for Odd' +// @has - '//*[@id="method.new"]//a[@class="notable-traits"]/@data-ty' 'Odd' +// @snapshot odd - '//script[@id="notable-traits-data"]' pub struct Odd { current: usize, } diff --git a/src/test/rustdoc/static-root-path.rs b/src/test/rustdoc/static-root-path.rs index 08c055c5b..86928b0fb 100644 --- a/src/test/rustdoc/static-root-path.rs +++ b/src/test/rustdoc/static-root-path.rs @@ -1,18 +1,18 @@ // compile-flags:-Z unstable-options --static-root-path /cache/ // @has static_root_path/struct.SomeStruct.html -// @matchesraw - '"/cache/main\.js"' -// @!matchesraw - '"\.\./main\.js"' +// @matchesraw - '"/cache/main-' +// @!matchesraw - '"\.\./main' // @matchesraw - 'data-root-path="\.\./"' // @!matchesraw - '"/cache/search-index\.js"' pub struct SomeStruct; // @has src/static_root_path/static-root-path.rs.html -// @matchesraw - '"/cache/source-script\.js"' -// @!matchesraw - '"\.\./\.\./source-script\.js"' +// @matchesraw - '"/cache/source-script-' +// @!matchesraw - '"\.\./\.\./source-script' // @matchesraw - '"\.\./\.\./source-files.js"' // @!matchesraw - '"/cache/source-files\.js"' // @has settings.html -// @matchesraw - '/cache/settings\.js' -// @!matchesraw - '\./settings\.js' +// @matchesraw - '/cache/settings-' +// @!matchesraw - '\../settings' diff --git a/src/test/rustdoc/trait-impl-items-links-and-anchors.rs b/src/test/rustdoc/trait-impl-items-links-and-anchors.rs index fba594c38..a125fa036 100644 --- a/src/test/rustdoc/trait-impl-items-links-and-anchors.rs +++ b/src/test/rustdoc/trait-impl-items-links-and-anchors.rs @@ -13,10 +13,10 @@ impl MyTrait for String { // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="associatedconstant.VALUE-1"]//a[@class="constant"]/@href' #associatedconstant.VALUE // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="associatedconstant.VALUE-1"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-1 const VALUE: u32 = 5; - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function + // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function"]//a[@class="fn"]/@href' #tymethod.trait_function // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function fn trait_function(&self) {} - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-1"]//a[@class="fnname"]/@href' #method.defaulted_override + // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-1"]//a[@class="fn"]/@href' #method.defaulted_override // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-1"]//a[@class="anchor"]/@href' #method.defaulted_override-1 fn defaulted_override(&self) {} } @@ -28,10 +28,10 @@ impl MyTrait for Vec<u8> { // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="associatedconstant.VALUE-2"]//a[@class="constant"]/@href' #associatedconstant.VALUE // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="associatedconstant.VALUE-2"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-2 const VALUE: u32 = 5; - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function + // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function"]//a[@class="fn"]/@href' #tymethod.trait_function // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function-1"]//a[@class="anchor"]/@href' #method.trait_function-1 fn trait_function(&self) {} - // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-2"]//a[@class="fnname"]/@href' #method.defaulted_override + // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-2"]//a[@class="fn"]/@href' #method.defaulted_override // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-2"]//a[@class="anchor"]/@href' #method.defaulted_override-2 fn defaulted_override(&self) {} } @@ -45,13 +45,13 @@ impl MyTrait for MyStruct { // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="associatedconstant.VALUE"]//a[@class="constant"]/@href' trait.MyTrait.html#associatedconstant.VALUE // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="associatedconstant.VALUE"]//a[@class="anchor"]/@href' #associatedconstant.VALUE const VALUE: u32 = 20; - // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.trait_function"]//a[@class="fnname"]/@href' trait.MyTrait.html#tymethod.trait_function + // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.trait_function"]//a[@class="fn"]/@href' trait.MyTrait.html#tymethod.trait_function // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function fn trait_function(&self) {} - // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted_override"]//a[@class="fnname"]/@href' trait.MyTrait.html#method.defaulted_override + // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted_override"]//a[@class="fn"]/@href' trait.MyTrait.html#method.defaulted_override // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted_override"]//a[@class="anchor"]/@href' #method.defaulted_override fn defaulted_override(&self) {} - // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted"]//a[@class="fnname"]/@href' trait.MyTrait.html#method.defaulted + // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted"]//a[@class="fn"]/@href' trait.MyTrait.html#method.defaulted // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted"]//a[@class="anchor"]/@href' #method.defaulted } diff --git a/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html index 24ab77703..d5d6c556d 100644 --- a/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html +++ b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html @@ -1,8 +1,8 @@ <div class="item-decl"><pre class="rust trait"><code>pub trait TraitWhere { type <a href="#associatedtype.Item" class="associatedtype">Item</a><'a><br />    <span class="where">where<br />        Self: 'a</span>; - fn <a href="#method.func" class="fnname">func</a>(self)<br />    <span class="where">where<br />        Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>, + fn <a href="#method.func" class="fn">func</a>(self)<br />    <span class="where">where<br />        Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>, { ... } -<span class="item-spacer" /> fn <a href="#method.lines" class="fnname">lines</a>(self) -> <a class="struct" href="{{channel}}/std/io/struct.Lines.html" title="struct std::io::Lines">Lines</a><Self><br />    <span class="where">where<br />        Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>, +<span class="item-spacer" /> fn <a href="#method.lines" class="fn">lines</a>(self) -> <a class="struct" href="{{channel}}/std/io/struct.Lines.html" title="struct std::io::Lines">Lines</a><Self><br />    <span class="where">where<br />        Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>, { ... } }</code></pre></div>
\ No newline at end of file diff --git a/src/test/rustdoc/whitespace-after-where-clause.enum.html b/src/test/rustdoc/whitespace-after-where-clause.enum.html index c74866f4a..f7663e461 100644 --- a/src/test/rustdoc/whitespace-after-where-clause.enum.html +++ b/src/test/rustdoc/whitespace-after-where-clause.enum.html @@ -1,4 +1,4 @@ -<div class="item-decl"><pre class="rust enum"><code>pub enum Cow<'a, B: ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a><span class="where fmt-newline">where<br />    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>>,</span>{ +<div class="item-decl"><pre class="rust enum"><code>pub enum Cow<'a, B><span class="where fmt-newline">where<br />    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>> + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{ Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&'a </a>B), Whatever(<a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>), }</code></pre></div>
\ No newline at end of file diff --git a/src/test/rustdoc/whitespace-after-where-clause.struct.html b/src/test/rustdoc/whitespace-after-where-clause.struct.html index 1ba1367d2..fa3f224e7 100644 --- a/src/test/rustdoc/whitespace-after-where-clause.struct.html +++ b/src/test/rustdoc/whitespace-after-where-clause.struct.html @@ -1,4 +1,4 @@ -<div class="item-decl"><pre class="rust struct"><code>pub struct Struct<'a, B: ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a><span class="where fmt-newline">where<br />    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>>,</span>{ +<div class="item-decl"><pre class="rust struct"><code>pub struct Struct<'a, B><span class="where fmt-newline">where<br />    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>> + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{ pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&'a </a>B, pub b: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>, }</code></pre></div>
\ No newline at end of file diff --git a/src/test/rustdoc/whitespace-after-where-clause.trait.html b/src/test/rustdoc/whitespace-after-where-clause.trait.html index 16b558237..50cfe3623 100644 --- a/src/test/rustdoc/whitespace-after-where-clause.trait.html +++ b/src/test/rustdoc/whitespace-after-where-clause.trait.html @@ -1,6 +1,6 @@ <div class="item-decl"><pre class="rust trait"><code>pub trait ToOwned<T><span class="where fmt-newline">where<br />    T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</span>{ type <a href="#associatedtype.Owned" class="associatedtype">Owned</a>; - fn <a href="#tymethod.to_owned" class="fnname">to_owned</a>(&self) -> Self::<a class="associatedtype" href="trait.ToOwned.html#associatedtype.Owned" title="type foo::ToOwned::Owned">Owned</a>; -<span class="item-spacer" /> fn <a href="#tymethod.whatever" class="fnname">whatever</a>(&self) -> T; + fn <a href="#tymethod.to_owned" class="fn">to_owned</a>(&self) -> Self::<a class="associatedtype" href="trait.ToOwned.html#associatedtype.Owned" title="type foo::ToOwned::Owned">Owned</a>; +<span class="item-spacer" /> fn <a href="#tymethod.whatever" class="fn">whatever</a>(&self) -> T; }</code></pre></div>
\ No newline at end of file diff --git a/src/test/rustdoc/whitespace-after-where-clause.trait2.html b/src/test/rustdoc/whitespace-after-where-clause.trait2.html index eeca6e1f5..21eb89b75 100644 --- a/src/test/rustdoc/whitespace-after-where-clause.trait2.html +++ b/src/test/rustdoc/whitespace-after-where-clause.trait2.html @@ -1,6 +1,6 @@ <div class="item-decl"><pre class="rust trait"><code>pub trait ToOwned2<T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>> { type <a href="#associatedtype.Owned" class="associatedtype">Owned</a>; - fn <a href="#tymethod.to_owned" class="fnname">to_owned</a>(&self) -> Self::<a class="associatedtype" href="trait.ToOwned2.html#associatedtype.Owned" title="type foo::ToOwned2::Owned">Owned</a>; -<span class="item-spacer" /> fn <a href="#tymethod.whatever" class="fnname">whatever</a>(&self) -> T; + fn <a href="#tymethod.to_owned" class="fn">to_owned</a>(&self) -> Self::<a class="associatedtype" href="trait.ToOwned2.html#associatedtype.Owned" title="type foo::ToOwned2::Owned">Owned</a>; +<span class="item-spacer" /> fn <a href="#tymethod.whatever" class="fn">whatever</a>(&self) -> T; }</code></pre></div>
\ No newline at end of file diff --git a/src/test/rustdoc/whitespace-after-where-clause.union.html b/src/test/rustdoc/whitespace-after-where-clause.union.html index 0dfb6407d..7bb177deb 100644 --- a/src/test/rustdoc/whitespace-after-where-clause.union.html +++ b/src/test/rustdoc/whitespace-after-where-clause.union.html @@ -1,3 +1,3 @@ -<div class="item-decl"><pre class="rust union"><code>pub union Union<'a, B: ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a><span class="where fmt-newline">where<br />    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>>,</span>{ +<div class="item-decl"><pre class="rust union"><code>pub union Union<'a, B><span class="where fmt-newline">where<br />    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>> + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{ /* private fields */ }</code></pre></div>
\ No newline at end of file |