-
Notifications
You must be signed in to change notification settings - Fork 151
Add warnings for multiple root pages #1276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
d260243
665321f
ded8478
aa33e18
4ec94c0
121c159
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -169,4 +169,125 @@ class DocumentationContext_RootPageTests: XCTestCase { | |
|
||
XCTAssertEqual(context.problems.count, 0) | ||
} | ||
|
||
func testWarnsAboutMultipleTechnologyRootDirectives() async throws { | ||
let (_, context) = try await loadBundle(catalog: | ||
Folder(name: "multiple-roots.docc", content: [ | ||
TextFile(name: "FirstRoot.md", utf8Content: """ | ||
# First Root | ||
@Metadata { | ||
@TechnologyRoot | ||
} | ||
This is the first root page. | ||
"""), | ||
|
||
TextFile(name: "SecondRoot.md", utf8Content: """ | ||
# Second Root | ||
@Metadata { | ||
@TechnologyRoot | ||
} | ||
This is the second root page. | ||
"""), | ||
|
||
TextFile(name: "ThirdRoot.md", utf8Content: """ | ||
# Third Root | ||
@Metadata { | ||
@TechnologyRoot | ||
} | ||
This is the third root page. | ||
"""), | ||
]) | ||
) | ||
|
||
// Verify that we emit warnings for multiple TechnologyRoot directives | ||
let multipleRootsProblems = context.problems.filter { $0.diagnostic.identifier == "org.swift.docc.MultipleTechnologyRoots" } | ||
XCTAssertEqual(multipleRootsProblems.count, 3, "Should emit warnings for all three TechnologyRoot directives") | ||
|
||
// Verify the warnings are associated with the correct files | ||
let problemSources = multipleRootsProblems.compactMap { $0.diagnostic.source?.lastPathComponent }.sorted() | ||
XCTAssertEqual(problemSources, ["FirstRoot.md", "SecondRoot.md", "ThirdRoot.md"]) | ||
|
||
// Verify each warning has a solution to remove the TechnologyRoot directive | ||
for problem in multipleRootsProblems { | ||
XCTAssertEqual(problem.possibleSolutions.count, 1) | ||
let solution = try XCTUnwrap(problem.possibleSolutions.first) | ||
XCTAssertEqual(solution.summary, "Remove the 'TechnologyRoot' directive") | ||
XCTAssertEqual(solution.replacements.count, 1) | ||
} | ||
} | ||
|
||
func testWarnsAboutSymbolsWithTechnologyRootPages() async throws { | ||
// Test the third case: documentation contains symbols (has a module) and also has @TechnologyRoot pages | ||
let (_, context) = try await loadBundle(catalog: | ||
Folder(name: "symbols-with-root.docc", content: [ | ||
// Symbol graph with a module | ||
JSONFile(name: "MyModule.symbols.json", content: makeSymbolGraph(moduleName: "MyModule")), | ||
|
||
// Article with @TechnologyRoot directive | ||
TextFile(name: "GettingStarted.md", utf8Content: """ | ||
# Getting Started | ||
@Metadata { | ||
@TechnologyRoot | ||
} | ||
Learn how to use MyModule. | ||
"""), | ||
|
||
// Another article with @TechnologyRoot directive | ||
TextFile(name: "Overview.md", utf8Content: """ | ||
# Overview | ||
@Metadata { | ||
@TechnologyRoot | ||
} | ||
Overview of the technology. | ||
"""), | ||
]) | ||
) | ||
|
||
// Verify that we emit warnings for @TechnologyRoot directives when symbols are present | ||
let symbolsWithRootProblems = context.problems.filter { $0.diagnostic.identifier == "org.swift.docc.TechnologyRootWithSymbols" } | ||
XCTAssertEqual(symbolsWithRootProblems.count, 2, "Should emit warnings for both @TechnologyRoot directives when symbols are present") | ||
Comment on lines
+247
to
+248
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that this code is checking for all 3 scenarios of multiple root pages, this test assertion becomes a good example of why it's important to not ignore unexpected diagnostics in tests. The way the code is written right now, this setup would result in both "MultipleTechnologyRoots" warnings and "TechnologyRootWithSymbols" warnings for the same |
||
|
||
// Verify the warnings are associated with the correct files | ||
let problemSources = symbolsWithRootProblems.compactMap { $0.diagnostic.source?.lastPathComponent }.sorted() | ||
XCTAssertEqual(problemSources, ["GettingStarted.md", "Overview.md"]) | ||
|
||
// Verify each warning has a solution to remove the TechnologyRoot directive | ||
for problem in symbolsWithRootProblems { | ||
XCTAssertEqual(problem.possibleSolutions.count, 1) | ||
let solution = try XCTUnwrap(problem.possibleSolutions.first) | ||
XCTAssertEqual(solution.summary, "Remove the 'TechnologyRoot' directive") | ||
XCTAssertEqual(solution.replacements.count, 1) | ||
|
||
// Verify that diagnostic notes point to the symbol graph file | ||
XCTAssertEqual(problem.diagnostic.notes.count, 1, "Should have a note pointing to the symbol graph file") | ||
let note = try XCTUnwrap(problem.diagnostic.notes.first) | ||
XCTAssertTrue(note.source.lastPathComponent.hasSuffix(".symbols.json"), "Note should point to a symbol graph file") | ||
XCTAssertTrue(note.message.contains("Symbol graph file"), "Note should mention symbol graph file") | ||
} | ||
} | ||
|
||
func testWarnsAboutMultipleMainModules() async throws { | ||
// Create a bundle with multiple symbol graphs for different modules | ||
let (_, context) = try await loadBundle(catalog: | ||
Folder(name: "multiple-modules.docc", content: [ | ||
// First module symbol graph | ||
JSONFile(name: "ModuleA.symbols.json", content: makeSymbolGraph(moduleName: "ModuleA")), | ||
|
||
// Second module symbol graph | ||
JSONFile(name: "ModuleB.symbols.json", content: makeSymbolGraph(moduleName: "ModuleB")), | ||
|
||
InfoPlist(displayName: "TestBundle", identifier: "com.test.example"), | ||
]) | ||
) | ||
|
||
// Verify that we emit a warning for multiple main modules | ||
let multipleModulesProblem = try XCTUnwrap(context.problems.first(where: { $0.diagnostic.identifier == "org.swift.docc.MultipleMainModules" })) | ||
XCTAssertEqual(multipleModulesProblem.diagnostic.severity, .warning) | ||
XCTAssertTrue(multipleModulesProblem.diagnostic.summary.contains("more than one main module")) | ||
XCTAssertTrue(multipleModulesProblem.diagnostic.explanation?.contains("ModuleA, ModuleB") == true) | ||
|
||
// Verify the warning doesn't have a source location since it's about the overall input structure | ||
XCTAssertNil(multipleModulesProblem.diagnostic.source) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor (non-blocking): We could refer to one of the symbol graph files here and use See for example There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed here: 121c159 |
||
XCTAssertNil(multipleModulesProblem.diagnostic.range) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that this code is checking for all 3 scenarios, there are 2 things that I notice:
It would be good to address both of these by extracting all 3 into a common place (for example
private func emitWarningsForMultipleRootPages() {...}
) and reduce some of that duplication.