@@ -831,3 +831,119 @@ async fn diff_comprehensive() {
831831
832832 insta:: assert_json_snapshot!( "diff_comprehensive_diff_only" , pages) ;
833833}
834+
835+ /// Verify that README headings in the module doc TOC:
836+ /// 1. Appear before @example entries (matching the rendered page order)
837+ /// 2. Are not inflated to deeper nesting levels by the offset state
838+ #[ tokio:: test]
839+ async fn readme_toc_order_with_examples ( ) {
840+ let source = r#"
841+ /**
842+ * ## Installation
843+ *
844+ * Install the library.
845+ *
846+ * ## Usage
847+ *
848+ * Use the library.
849+ *
850+ * ## API Reference
851+ *
852+ * The API reference.
853+ *
854+ * @example My Example
855+ * ```ts
856+ * hello();
857+ * ```
858+ *
859+ * @module
860+ */
861+
862+ /** A simple function. */
863+ export function hello(): string {
864+ return "hello";
865+ }
866+ "# ;
867+
868+ let doc_nodes_by_url = parse_source ( source) . await ;
869+
870+ let specifier = ModuleSpecifier :: parse ( "file:///mod.ts" ) . unwrap ( ) ;
871+
872+ let ctx = GenerateCtx :: create_basic (
873+ GenerateOptions {
874+ package_name : None ,
875+ main_entrypoint : Some ( specifier) ,
876+ href_resolver : Arc :: new ( EmptyResolver ) ,
877+ usage_composer : Some ( Arc :: new ( EmptyResolver ) ) ,
878+ rewrite_map : None ,
879+ category_docs : None ,
880+ disable_search : false ,
881+ symbol_redirect_map : None ,
882+ default_symbol_map : None ,
883+ markdown_renderer : comrak:: create_renderer ( None , None , None ) ,
884+ markdown_stripper : Arc :: new ( comrak:: strip) ,
885+ head_inject : None ,
886+ id_prefix : None ,
887+ diff_only : false ,
888+ } ,
889+ doc_nodes_by_url,
890+ None ,
891+ )
892+ . unwrap ( ) ;
893+
894+ let files = generate ( ctx) . unwrap ( ) ;
895+ let index_html = files. get ( "./index.html" ) . unwrap ( ) ;
896+
897+ // README headings should appear before the Examples section in the TOC,
898+ // matching the page layout where the markdown body comes before @example sections.
899+ let readme_heading_pos = index_html
900+ . find ( "title=\" Installation\" " )
901+ . expect ( "Installation heading not found in TOC" ) ;
902+ let examples_pos = index_html
903+ . find ( "title=\" Examples\" " )
904+ . expect ( "Examples heading not found in TOC" ) ;
905+
906+ assert ! (
907+ readme_heading_pos < examples_pos,
908+ "README headings should appear before Examples in the TOC"
909+ ) ;
910+
911+ // Verify README headings are in document order
912+ let headings = [ "Installation" , "Usage" , "API Reference" ] ;
913+ let positions: Vec < usize > = headings
914+ . iter ( )
915+ . map ( |h| {
916+ index_html
917+ . find ( & format ! ( "title=\" {}\" " , h) )
918+ . unwrap_or_else ( || panic ! ( "heading '{}' not found in TOC" , h) )
919+ } )
920+ . collect ( ) ;
921+
922+ for window in positions. windows ( 2 ) {
923+ assert ! (
924+ window[ 0 ] < window[ 1 ] ,
925+ "TOC headings are not in document order"
926+ ) ;
927+ }
928+
929+ // Verify heading levels aren't inflated: README h2 headings should NOT be
930+ // nested deeper than the Examples section (level 1). If the offset leaked,
931+ // they'd be at level 4 and appear as deeply nested sub-items.
932+ // In the correct output, README headings at level 2 nest directly under the
933+ // top-level list, not under a third-level nested list.
934+ let nav_start = index_html. find ( "documentNavigation" ) . unwrap ( ) ;
935+ let nav_section = & index_html[ nav_start..] ;
936+ let nav_end = nav_section. find ( "</nav>" ) . unwrap ( ) ;
937+ let nav_html = & nav_section[ ..nav_end] ;
938+
939+ // Count nesting depth of the first README heading (Installation).
940+ // It should be in at most one <ul> nesting (the root <ul> + one sub-<ul>
941+ // for level 2), not two or more sub-<ul>s which would indicate inflated levels.
942+ let before_installation = & nav_html[ ..nav_html. find ( "Installation" ) . unwrap ( ) ] ;
943+ let ul_depth = before_installation. matches ( "<ul>" ) . count ( ) ;
944+ assert ! (
945+ ul_depth <= 2 ,
946+ "README headings are nested too deeply (depth {}), offset likely leaked from Examples" ,
947+ ul_depth
948+ ) ;
949+ }
0 commit comments