@@ -2008,6 +2008,157 @@ Root
2008
2008
2009
2009
return navigatorIndex
2010
2010
}
2011
+
2012
+ func testCrossLanguageCurationBehavior( ) async throws {
2013
+ let catalog = Folder ( name: " CrossLanguageTest.docc " , content: [
2014
+ InfoPlist ( identifier: " org.swift.docc.crosslanguagetest " ) ,
2015
+ // Symbol graph with both Swift and Objective-C symbols
2016
+ JSONFile ( name: " CrossLanguageFramework.symbols.json " , content: makeSymbolGraph (
2017
+ moduleName: " CrossLanguageFramework " ,
2018
+ symbols: [
2019
+ . init(
2020
+ identifier: . init( precise: " swift-class-id " , interfaceLanguage: SourceLanguage . swift. id) ,
2021
+ names: . init( title: " SwiftClass " , navigator: [ . init( kind: . identifier, spelling: " SwiftClass " , preciseIdentifier: nil ) ] , subHeading: nil , prose: nil ) ,
2022
+ pathComponents: [ " SwiftClass " ] ,
2023
+ docComment: nil ,
2024
+ accessLevel: . public,
2025
+ kind: . init( parsedIdentifier: . class, displayName: " Class " ) ,
2026
+ mixins: [ : ]
2027
+ ) ,
2028
+ . init(
2029
+ identifier: . init( precise: " objc-class-id " , interfaceLanguage: SourceLanguage . objectiveC. id) ,
2030
+ names: . init( title: " ObjCClass " , navigator: [ . init( kind: . identifier, spelling: " ObjCClass " , preciseIdentifier: nil ) ] , subHeading: nil , prose: nil ) ,
2031
+ pathComponents: [ " ObjCClass " ] ,
2032
+ docComment: nil ,
2033
+ accessLevel: . public,
2034
+ kind: . init( parsedIdentifier: . class, displayName: " Class " ) ,
2035
+ mixins: [ : ]
2036
+ )
2037
+ ] ,
2038
+ relationships: [ ]
2039
+ ) ) ,
2040
+ TextFile ( name: " CrossLanguageArticle.md " , utf8Content: """
2041
+ # Cross Language Article
2042
+
2043
+ This is a general article.
2044
+ """ ) ,
2045
+ TextFile ( name: " SwiftOnlyArticle.md " , utf8Content: """
2046
+ # Swift Only Article
2047
+
2048
+ @Metadata {
2049
+ @SupportedLanguage(swift)
2050
+ }
2051
+
2052
+ This is a Swift-only article.
2053
+ """ ) ,
2054
+ TextFile ( name: " ObjCOnlyArticle.md " , utf8Content: """
2055
+ # Objective-C Only Article
2056
+
2057
+ @Metadata {
2058
+ @SupportedLanguage(objc)
2059
+ }
2060
+
2061
+ This article is only available in Objective-C.
2062
+ """ ) ,
2063
+ // Swift page that curates ObjC articles and symbols
2064
+ TextFile ( name: " SwiftContainer.md " , utf8Content: """
2065
+ # Swift Container
2066
+
2067
+ @Metadata {
2068
+ @SupportedLanguage(swift)
2069
+ }
2070
+
2071
+ This page curates articles and attempts to curate Objective-C symbols (which should be dropped).
2072
+
2073
+ ## Topics
2074
+
2075
+ ### Articles
2076
+ - <doc:CrossLanguageArticle>
2077
+ - <doc:ObjCOnlyArticle>
2078
+
2079
+ ### Swift Symbols
2080
+ - ``SwiftClass``
2081
+
2082
+ ### Objective-C Symbols
2083
+ - ``ObjCClass``
2084
+ """ ) ,
2085
+ // ObjC page that curates Swift articles and symbols
2086
+ TextFile ( name: " ObjCContainer.md " , utf8Content: """
2087
+ # Objective-C Container
2088
+
2089
+ @Metadata {
2090
+ @SupportedLanguage(objc)
2091
+ }
2092
+
2093
+ This page curates articles and attempts to curate Swift symbols (which should be dropped).
2094
+
2095
+ ## Topics
2096
+
2097
+ ### Articles
2098
+ - <doc:CrossLanguageArticle>
2099
+ - <doc:SwiftOnlyArticle>
2100
+
2101
+ ### Objective-C Symbols
2102
+ - ``ObjCClass``
2103
+
2104
+ ### Swift Symbols
2105
+ - ``SwiftClass``
2106
+ """ )
2107
+ ] )
2108
+
2109
+ let ( _, context) = try await loadBundle ( catalog: catalog)
2110
+ let bundle = try XCTUnwrap ( context. bundle)
2111
+
2112
+ XCTAssert ( context. problems. isEmpty, " Failed to unwrap bundle: \( context. problems. map ( \. diagnostic. summary) ) " )
2113
+
2114
+ // Generate navigator index
2115
+ let targetURL = try createTemporaryDirectory ( )
2116
+ let builder = NavigatorIndex . Builder ( outputURL: targetURL, bundleIdentifier: " org.swift.docc.crosslanguagetest " , groupByLanguage: true )
2117
+ builder. setup ( )
2118
+
2119
+ let renderContext = RenderContext ( documentationContext: context, bundle: bundle)
2120
+ let converter = DocumentationContextConverter ( bundle: bundle, context: context, renderContext: renderContext)
2121
+
2122
+ for identifier in context. knownPages {
2123
+ let entity = try context. entity ( with: identifier)
2124
+ let renderNode = try XCTUnwrap ( converter. renderNode ( for: entity) )
2125
+ try builder. index ( renderNode: renderNode)
2126
+ }
2127
+
2128
+ builder. finalize ( )
2129
+ let navigatorIndex = try XCTUnwrap ( builder. navigatorIndex)
2130
+
2131
+ let swiftNode = try XCTUnwrap ( navigatorIndex. navigatorTree. root. children. first { $0. item. title == " Swift " } )
2132
+ let swiftContainer = try XCTUnwrap ( search ( node: swiftNode) { $0. item. title == " Swift Container " } )
2133
+ let swiftContainerChildren = Set ( swiftContainer. children. map { $0. item. title } )
2134
+ // Articles should be curated across languages
2135
+ XCTAssertTrue ( swiftContainerChildren. contains ( " Cross Language Article " ) ,
2136
+ " Cross-language article should be curated in Swift container " )
2137
+ XCTAssertTrue ( swiftContainerChildren. contains ( " Objective-C Only Article " ) ,
2138
+ " Objective-C-only article should be curated in Swift container " )
2139
+
2140
+ // Swift symbols should be curated under Swift
2141
+ XCTAssertTrue ( swiftContainerChildren. contains ( " SwiftClass " ) ,
2142
+ " Swift symbol should be curated in Swift container " )
2143
+ // Objective-C symbols should NOT be curated under Swift
2144
+ XCTAssertFalse ( swiftContainerChildren. contains ( " ObjCClass " ) ,
2145
+ " Objective-C symbol should NOT be curated in Swift container " )
2146
+
2147
+ // Same checks as above for Objective-C
2148
+ let objcNode = try XCTUnwrap ( navigatorIndex. navigatorTree. root. children. first { $0. item. title == " Objective-C " } )
2149
+ let objcContainer = try XCTUnwrap ( search ( node: objcNode) { $0. item. title == " Objective-C Container " } )
2150
+ let objcContainerChildren = Set ( objcContainer. children. map { $0. item. title } )
2151
+
2152
+ XCTAssertTrue ( objcContainerChildren. contains ( " Cross Language Article " ) ,
2153
+ " Cross-language article should be curated in Objective-C container " )
2154
+ XCTAssertTrue ( objcContainerChildren. contains ( " Swift Only Article " ) ,
2155
+ " Swift-only article should be curated in Objective-C container " )
2156
+
2157
+ XCTAssertTrue ( objcContainerChildren. contains ( " ObjCClass " ) ,
2158
+ " Objective-C symbol should be curated in Objective-C container " )
2159
+ XCTAssertFalse ( objcContainerChildren. contains ( " SwiftClass " ) ,
2160
+ " Swift symbol should NOT be curated in Objective-C container " )
2161
+ }
2011
2162
}
2012
2163
2013
2164
/// This function compares two nodes to ensure their data is equal.
0 commit comments