@@ -2972,6 +2972,143 @@ let expected = """
2972
2972
XCTAssertEqual ( linkResolutionProblems. first? . diagnostic. identifier, " org.swift.docc.unresolvedTopicReference " )
2973
2973
}
2974
2974
2975
+ func testLinkDiagnosticsInSynthesizedTechnologyRoots( ) throws {
2976
+ // Verify that when synthesizing a technology root, links are resolved in the roots content.
2977
+ // Also, if an article is promoted to a root, verify that any existing metadata is preserved.
2978
+
2979
+ func makeMetadata( root: Bool , color: Bool ) -> String {
2980
+ guard root || color else {
2981
+ return " "
2982
+ }
2983
+ return """
2984
+ @Metadata {
2985
+ \( root ? " @TechnologyRoot " : " " )
2986
+ \( color ? " @PageColor(orange) " : " " )
2987
+ }
2988
+ """
2989
+ }
2990
+
2991
+ // Only a single article
2992
+ for withExplicitTechnologyRoot in [ true , false ] {
2993
+ for withPageColor in [ true , false ] {
2994
+ let catalogURL = try createTempFolder ( content: [
2995
+ Folder ( name: " unit-test.docc " , content: [
2996
+ TextFile ( name: " Root.md " , utf8Content: """
2997
+ # My root page
2998
+
2999
+ \( makeMetadata ( root: withExplicitTechnologyRoot, color: withPageColor) )
3000
+
3001
+ This implicit technology root links to pages and on-page elements that don't exist.
3002
+
3003
+ - ``NotFoundSymbol``
3004
+ - <doc:NotFoundArticle>
3005
+ - <doc:#NotFoundHeading>
3006
+ """ ) ,
3007
+ ] )
3008
+ ] )
3009
+ let ( _, _, context) = try loadBundle ( from: catalogURL)
3010
+
3011
+ XCTAssertEqual ( context. problems. map ( \. diagnostic. summary) , [
3012
+ " 'NotFoundSymbol' doesn't exist at '/Root' " ,
3013
+ " 'NotFoundArticle' doesn't exist at '/Root' " ,
3014
+ " 'NotFoundHeading' doesn't exist at '/Root' " ,
3015
+ ] , withExplicitTechnologyRoot ? " with @TechnologyRoot " : " with synthesized root " )
3016
+
3017
+ let rootReference = try XCTUnwrap ( context. soleRootModuleReference)
3018
+ let rootPage = try context. entity ( with: rootReference)
3019
+ XCTAssertNotNil ( rootPage. metadata? . technologyRoot)
3020
+ if withPageColor {
3021
+ XCTAssertEqual ( rootPage. metadata? . pageColor? . rawValue, " orange " )
3022
+ } else {
3023
+ XCTAssertNil ( rootPage. metadata? . pageColor)
3024
+ }
3025
+ }
3026
+ }
3027
+
3028
+ // Article that match the bundle's name
3029
+ for withExplicitTechnologyRoot in [ true , false ] {
3030
+ for withPageColor in [ true , false ] {
3031
+ let catalogURL = try createTempFolder ( content: [
3032
+ Folder ( name: " CatalogName.docc " , content: [
3033
+ TextFile ( name: " CatalogName.md " , utf8Content: """
3034
+ # My root page
3035
+
3036
+ \( makeMetadata ( root: withExplicitTechnologyRoot, color: withPageColor) )
3037
+
3038
+ This implicit technology root links to pages and on-page elements that don't exist.
3039
+
3040
+ - ``NotFoundSymbol``
3041
+ - <doc:NotFoundArticle>
3042
+ - <doc:#NotFoundHeading>
3043
+ """ ) ,
3044
+
3045
+ TextFile ( name: " OtherArticle.md " , utf8Content: """
3046
+ # Another article
3047
+
3048
+ This article links to the technology root.
3049
+
3050
+ - <doc:CatalogName>
3051
+ """ ) ,
3052
+ ] )
3053
+ ] )
3054
+ let ( _, _, context) = try loadBundle ( from: catalogURL)
3055
+
3056
+ XCTAssertEqual ( context. problems. map ( \. diagnostic. summary) , [
3057
+ " 'NotFoundSymbol' doesn't exist at '/CatalogName' " ,
3058
+ " 'NotFoundArticle' doesn't exist at '/CatalogName' " ,
3059
+ " 'NotFoundHeading' doesn't exist at '/CatalogName' " ,
3060
+ ] , withExplicitTechnologyRoot ? " with @TechnologyRoot " : " with synthesized root " )
3061
+
3062
+ let rootReference = try XCTUnwrap ( context. soleRootModuleReference)
3063
+ let rootPage = try context. entity ( with: rootReference)
3064
+ XCTAssertNotNil ( rootPage. metadata? . technologyRoot)
3065
+ if withPageColor {
3066
+ XCTAssertEqual ( rootPage. metadata? . pageColor? . rawValue, " orange " )
3067
+ } else {
3068
+ XCTAssertNil ( rootPage. metadata? . pageColor)
3069
+ }
3070
+ }
3071
+ }
3072
+
3073
+ // Completely synthesized root
3074
+ let catalogURL = try createTempFolder ( content: [
3075
+ Folder ( name: " CatalogName.docc " , content: [
3076
+ TextFile ( name: " First.md " , utf8Content: """
3077
+ # One article
3078
+
3079
+ This article links to pages and on-page elements that don't exist.
3080
+
3081
+ - ``NotFoundSymbol``
3082
+ - <doc:#NotFoundHeading>
3083
+
3084
+ It also links to the technology root.
3085
+
3086
+ - <doc:CatalogName>
3087
+ """ ) ,
3088
+
3089
+ TextFile ( name: " Second.md " , utf8Content: """
3090
+ # Another article
3091
+
3092
+ This article links to a page that doesn't exist to the synthesized technology root.
3093
+
3094
+ - <doc:NotFoundArticle>
3095
+ - <doc:CatalogName>
3096
+ """ ) ,
3097
+ ] )
3098
+ ] )
3099
+ let ( _, _, context) = try loadBundle ( from: catalogURL)
3100
+
3101
+ XCTAssertEqual ( context. problems. map ( \. diagnostic. summary) . sorted ( ) , [
3102
+ " 'NotFoundArticle' doesn't exist at '/CatalogName/Second' " ,
3103
+ " 'NotFoundHeading' doesn't exist at '/CatalogName/First' " ,
3104
+ " 'NotFoundSymbol' doesn't exist at '/CatalogName/First' " ,
3105
+ ] )
3106
+
3107
+ let rootReference = try XCTUnwrap ( context. soleRootModuleReference)
3108
+ let rootPage = try context. entity ( with: rootReference)
3109
+ XCTAssertNotNil ( rootPage. metadata? . technologyRoot)
3110
+ }
3111
+
2975
3112
func testResolvingLinksToHeaders( ) throws {
2976
3113
let tempURL = try createTemporaryDirectory ( )
2977
3114
0 commit comments