@@ -13,7 +13,7 @@ import XCTest
1313
1414class SymbolBreadcrumbTests : XCTestCase {
1515 func testLanguageSpecificBreadcrumbs( ) throws {
16- let ( _ , context) = try testBundleAndContext ( named: " GeometricalShapes " )
16+ let ( bundle , context) = try testBundleAndContext ( named: " GeometricalShapes " )
1717 let resolver = try XCTUnwrap ( context. linkResolver. localResolver)
1818 let moduleReference = try XCTUnwrap ( context. soleRootModuleReference)
1919
@@ -22,7 +22,8 @@ class SymbolBreadcrumbTests: XCTestCase {
2222 // CGFloat radius;
2323 // } TLACircle NS_SWIFT_NAME(Circle);
2424 do {
25- let reference = moduleReference. appendingPath ( " Circle/center " )
25+ let reference = try XCTUnwrap ( context. knownPages. first ( where: { $0. path == " \( moduleReference. path) /Circle/center " } ) )
26+ XCTAssertEqual ( reference. sourceLanguages. count, 2 , " Symbol has 2 language representations " )
2627
2728 XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . swift) ? . map ( \. path) , [
2829 " /documentation/GeometricalShapes " ,
@@ -32,11 +33,14 @@ class SymbolBreadcrumbTests: XCTestCase {
3233 " /documentation/GeometricalShapes " ,
3334 " /documentation/GeometricalShapes/Circle " , // named TLACircle in Objective-C
3435 ] )
36+
37+ assertNoVariantsForRenderHierarchy ( reference, context, bundle) // Same breadcrumbs in both languages
3538 }
3639
3740 // extern const TLACircle TLACircleZero NS_SWIFT_NAME(Circle.zero);
3841 do {
39- let reference = moduleReference. appendingPath ( " Circle/zero " )
42+ let reference = try XCTUnwrap ( context. knownPages. first ( where: { $0. path == " \( moduleReference. path) /Circle/zero " } ) )
43+ XCTAssertEqual ( reference. sourceLanguages. count, 2 , " Symbol has 2 language representations " )
4044
4145 XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . swift) ? . map ( \. path) , [
4246 " /documentation/GeometricalShapes " ,
@@ -45,11 +49,14 @@ class SymbolBreadcrumbTests: XCTestCase {
4549 XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . objectiveC) ? . map ( \. path) , [
4650 " /documentation/GeometricalShapes " , // The Objective-C representation is a top-level function
4751 ] )
52+
53+ assertHasSomeVariantsForRenderHierarchy ( reference, context, bundle) // Different breadcrumbs in different languages
4854 }
4955
5056 // BOOL TLACircleIntersects(TLACircle circle, TLACircle otherCircle) NS_SWIFT_NAME(Circle.intersects(self:_:));
5157 do {
52- let reference = moduleReference. appendingPath ( " Circle/intersects(_:) " )
58+ let reference = try XCTUnwrap ( context. knownPages. first ( where: { $0. path == " \( moduleReference. path) /Circle/intersects(_:) " } ) )
59+ XCTAssertEqual ( reference. sourceLanguages. count, 2 , " Symbol has 2 language representations " )
5360
5461 XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . swift) ? . map ( \. path) , [
5562 " /documentation/GeometricalShapes " ,
@@ -58,26 +65,99 @@ class SymbolBreadcrumbTests: XCTestCase {
5865 XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . objectiveC) ? . map ( \. path) , [
5966 " /documentation/GeometricalShapes " , // The Objective-C representation is a top-level function
6067 ] )
68+
69+ assertHasSomeVariantsForRenderHierarchy ( reference, context, bundle) // Different breadcrumbs in different languages
6170 }
6271
6372 // TLACircle TLACircleMake(CGPoint center, CGFloat radius) NS_SWIFT_UNAVAILABLE("Use 'Circle.init(center:radius:)' instead.");
6473 do {
65- let reference = moduleReference. appendingPath ( " TLACircleMake " )
74+ let reference = try XCTUnwrap ( context. knownPages. first ( where: { $0. path == " \( moduleReference. path) /TLACircleMake " } ) )
75+ XCTAssertEqual ( reference. sourceLanguages. count, 1 , " Symbol only has one language representation " )
6676
6777 XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . swift) ? . map ( \. path) , nil ) // There is no Swift representation
6878 XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . objectiveC) ? . map ( \. path) , [
6979 " /documentation/GeometricalShapes " , // The Objective-C representation is a top-level function
7080 ] )
81+
82+ assertNoVariantsForRenderHierarchy ( reference, context, bundle) // Only has one language representation
7183 }
7284
7385 do {
74- let reference = moduleReference. appendingPath ( " Circle/init(center:radius:) " )
86+ let reference = try XCTUnwrap ( context. knownPages. first ( where: { $0. path == " \( moduleReference. path) /Circle/init(center:radius:) " } ) )
87+ XCTAssertEqual ( reference. sourceLanguages. count, 1 , " Symbol only has one language representation " )
7588
7689 XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . swift) ? . map ( \. path) , [
7790 " /documentation/GeometricalShapes " ,
7891 " /documentation/GeometricalShapes/Circle " , // The Swift representation is a member
7992 ] )
8093 XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . objectiveC) ? . map ( \. path) , nil ) // There is no Objective-C representation
94+
95+ assertNoVariantsForRenderHierarchy ( reference, context, bundle) // Only has one language representation
8196 }
8297 }
98+
99+ func testMixedLanguageSpecificBreadcrumbs( ) throws {
100+ let ( bundle, context) = try testBundleAndContext ( named: " MixedLanguageFramework " )
101+ let resolver = try XCTUnwrap ( context. linkResolver. localResolver)
102+ let moduleReference = try XCTUnwrap ( context. soleRootModuleReference)
103+
104+ do {
105+ let reference = try XCTUnwrap ( context. knownPages. first ( where: { $0. path == " \( moduleReference. path) /MixedLanguageProtocol/mixedLanguageMethod() " } ) )
106+ XCTAssertEqual ( reference. sourceLanguages. count, 2 , " Symbol has 2 language representations " )
107+
108+ XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . swift) ? . map ( \. path) , [
109+ " /documentation/MixedLanguageFramework " ,
110+ " /documentation/MixedLanguageFramework/MixedLanguageProtocol " ,
111+ ] )
112+ XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . objectiveC) ? . map ( \. path) , [
113+ " /documentation/MixedLanguageFramework " ,
114+ " /documentation/MixedLanguageFramework/MixedLanguageProtocol " ,
115+ ] )
116+
117+ assertNoVariantsForRenderHierarchy ( reference, context, bundle) // Same breadcrumbs in both languages
118+ }
119+ do {
120+ let reference = try XCTUnwrap ( context. knownPages. first ( where: { $0. path == " \( moduleReference. path) /MixedLanguageProtocol " } ) )
121+ XCTAssertEqual ( reference. sourceLanguages. count, 2 , " Symbol has 2 language representations " )
122+
123+ XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . swift) ? . map ( \. path) , [
124+ " /documentation/MixedLanguageFramework " ,
125+ ] )
126+ XCTAssertEqual ( resolver. breadcrumbs ( of: reference, in: . objectiveC) ? . map ( \. path) , [
127+ " /documentation/MixedLanguageFramework " ,
128+ ] )
129+
130+ assertNoVariantsForRenderHierarchy ( reference, context, bundle) // Same breadcrumbs in both languages
131+ }
132+ }
133+
134+ // MARK: Test helpers
135+
136+ private func assertNoVariantsForRenderHierarchy(
137+ _ reference: ResolvedTopicReference ,
138+ _ context: DocumentationContext ,
139+ _ bundle: DocumentationBundle ,
140+ file: StaticString = #file,
141+ line: UInt = #line
142+ ) {
143+ var hierarchyTranslator = RenderHierarchyTranslator ( context: context, bundle: bundle)
144+ let hierarchyVariants = hierarchyTranslator. visitSymbol ( reference)
145+
146+ XCTAssertNotNil ( hierarchyVariants. defaultValue, " Should always have default breadcrumbs " , file: file, line: line)
147+ XCTAssert ( hierarchyVariants. variants. isEmpty, " No need for variants when value is same in Swift and Objective-C " , file: file, line: line)
148+ }
149+
150+ private func assertHasSomeVariantsForRenderHierarchy(
151+ _ reference: ResolvedTopicReference ,
152+ _ context: DocumentationContext ,
153+ _ bundle: DocumentationBundle ,
154+ file: StaticString = #file,
155+ line: UInt = #line
156+ ) {
157+ var hierarchyTranslator = RenderHierarchyTranslator ( context: context, bundle: bundle)
158+ let hierarchyVariants = hierarchyTranslator. visitSymbol ( reference)
159+
160+ XCTAssertNotNil ( hierarchyVariants. defaultValue, " Should always have default breadcrumbs " , file: file, line: line)
161+ XCTAssertFalse ( hierarchyVariants. variants. isEmpty, " Either language needs a variant when value is different in Swift and Objective-C " , file: file, line: line)
162+ }
83163}
0 commit comments