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