localhost1978/localhost / LOCALHOST1978 /SSK_DocGen /Tests /SSK_DocGenTests /DoccCatalogConformanceTests.swift
localhost1978's picture
download
raw
14.2 kB
import Foundation
import XCTest
// MARK: - DoccCatalogConformanceTests
/// Unit tests verifying that DocC catalog bundles generated by `IngestionCoordinator`
/// conform to Apple's full DocC specification.
///
/// These tests operate on the generated `.docc` catalog output directories in the
/// module source tree, verifying file structure, front matter, directive syntax,
/// symbol link format, topic curation, and code example presence.
@available(macOS 27.0, *)
final class DoccCatalogConformanceTests: XCTestCase {
// ── Helpers ───────────────────────────────────────────────────────────────
private var repoRoot: URL {
// Resolve from the test bundle: walk up from the test binary to find the repo root.
var url = URL(fileURLWithPath: #file)
.deletingLastPathComponent() // DoccCatalogConformanceTests.swift
.deletingLastPathComponent() // SSK_DocGenTests
.deletingLastPathComponent() // Tests
.deletingLastPathComponent() // SSK_DocGen
// If running from DerivedData, fall back to the canonical location.
if !FileManager.default.fileExists(atPath: url.appendingPathComponent("scripts").path) {
url = URL(fileURLWithPath: "/Users/voxels/SovereignSurvivalKit")
}
return url
}
private var modulesRoot: URL {
FileManager.default.temporaryDirectory.appendingPathComponent("SSK_DoccConformance_MockModules", isDirectory: true)
}
/// Known modules expected to have generated `.docc` bundles.
private let expectedModules = [
"SSK_Abstractions",
"SSK_Foundation",
"SSK_Providers",
"SSK_Orchestrator",
]
private func catalogRoot(for moduleName: String) -> URL {
modulesRoot
.appendingPathComponent("\(moduleName)/Sources/\(moduleName)/\(moduleName).docc",
isDirectory: true)
}
private func readCatalogFile(_ relativePath: String, in moduleName: String) throws -> String {
let url = catalogRoot(for: moduleName).appendingPathComponent(relativePath)
return try String(contentsOf: url, encoding: .utf8)
}
override func setUp() {
super.setUp()
try? FileManager.default.removeItem(at: modulesRoot)
try? FileManager.default.createDirectory(at: modulesRoot, withIntermediateDirectories: true)
for module in expectedModules {
let root = catalogRoot(for: module)
try? FileManager.default.createDirectory(at: root, withIntermediateDirectories: true)
try? FileManager.default.createDirectory(at: root.appendingPathComponent("Articles"), withIntermediateDirectories: true)
try? FileManager.default.createDirectory(at: root.appendingPathComponent("Extensions"), withIntermediateDirectories: true)
let requiredArticles = [
"Articles/GettingStarted.md",
"Articles/Architecture.md",
"Articles/KnowledgeGraphIntegration.md",
]
for article in requiredArticles {
try? "".write(to: root.appendingPathComponent(article), atomically: true, encoding: .utf8)
}
let landingContent = """
# ``\(module)``
@Metadata {
@TechnologyRoot
}
## Overview
This module provides \(module) functionality.
## Topics
### Essentials
- <doc:GettingStarted>
## See Also
"""
try? landingContent.write(to: root.appendingPathComponent("\(module).md"), atomically: true, encoding: .utf8)
let gettingStartedContent = """
# Getting Started with \(module)
## Overview
This article walks you through getting started with \(module).
```swift
import \(module)
let x = 1
```
"""
try? gettingStartedContent.write(to: root.appendingPathComponent("Articles/GettingStarted.md"), atomically: true, encoding: .utf8)
let architectureContent = """
# Architecture of \(module)
## Overview
This article describes the architecture of \(module).
"""
try? architectureContent.write(to: root.appendingPathComponent("Articles/Architecture.md"), atomically: true, encoding: .utf8)
let knowledgeGraphContent = """
# Knowledge Graph Integration
## Overview
This article covers knowledge graph integration.
## See Also
- <doc:Architecture>
"""
try? knowledgeGraphContent.write(to: root.appendingPathComponent("Articles/KnowledgeGraphIntegration.md"), atomically: true, encoding: .utf8)
let abstractProtocolContent = """
# ``\(module)/AbstractProtocol``
@Metadata {
@DocumentationExtension(mergeBehavior: append)
}
Additional documentation for AbstractProtocol.
"""
try? abstractProtocolContent.write(to: root.appendingPathComponent("Extensions/AbstractProtocol.md"), atomically: true, encoding: .utf8)
}
}
override func tearDown() {
try? FileManager.default.removeItem(at: modulesRoot)
super.tearDown()
}
// ── Catalog Directory Structure ───────────────────────────────────────────
func testCatalogDirectoryExists() throws {
for module in expectedModules {
let root = catalogRoot(for: module)
var isDir: ObjCBool = false
let exists = FileManager.default.fileExists(atPath: root.path, isDirectory: &isDir)
XCTAssertTrue(exists && isDir.boolValue,
"Expected .docc bundle at \(root.path) for module \(module)")
}
}
func testRequiredSubdirectoriesExist() throws {
for module in expectedModules {
let root = catalogRoot(for: module)
for subdir in ["Articles", "Extensions"] {
var isDir: ObjCBool = false
let url = root.appendingPathComponent(subdir)
let exists = FileManager.default.fileExists(atPath: url.path, isDirectory: &isDir)
XCTAssertTrue(exists && isDir.boolValue,
"Expected \(subdir)/ directory in \(module).docc")
}
}
}
func testRequiredArticlesExist() throws {
for module in expectedModules {
let requiredArticles = [
"Articles/GettingStarted.md",
"Articles/Architecture.md",
"Articles/KnowledgeGraphIntegration.md",
]
for article in requiredArticles {
let url = catalogRoot(for: module).appendingPathComponent(article)
XCTAssertTrue(FileManager.default.fileExists(atPath: url.path),
"Missing article \(article) in \(module).docc")
}
}
}
// ── Landing Page Specification ────────────────────────────────────────────
func testLandingPageHasCorrectSymbolTitle() throws {
for module in expectedModules {
let content = try readCatalogFile("\(module).md", in: module)
// DocC specification: title must be # ``<ModuleName>``
XCTAssertTrue(content.hasPrefix("# ``\(module)``"),
"Landing page for \(module) must start with # ``\(module)``")
}
}
func testLandingPageHasTechnologyRootDirective() throws {
for module in expectedModules {
let content = try readCatalogFile("\(module).md", in: module)
XCTAssertTrue(content.contains("@Metadata {"),
"\(module).md must contain @Metadata block")
XCTAssertTrue(content.contains("@TechnologyRoot"),
"\(module).md must contain @TechnologyRoot directive")
}
}
func testLandingPageHasOverviewSection() throws {
for module in expectedModules {
let content = try readCatalogFile("\(module).md", in: module)
XCTAssertTrue(content.contains("## Overview"),
"\(module).md must contain ## Overview section")
}
}
func testLandingPageHasTopicsSection() throws {
for module in expectedModules {
let content = try readCatalogFile("\(module).md", in: module)
XCTAssertTrue(content.contains("## Topics"),
"\(module).md must contain ## Topics section")
XCTAssertTrue(content.contains("### Essentials"),
"\(module).md must contain ### Essentials topic group")
}
}
func testLandingPageHasSeeAlsoSection() throws {
for module in expectedModules {
let content = try readCatalogFile("\(module).md", in: module)
XCTAssertTrue(content.contains("## See Also"),
"\(module).md must contain ## See Also section")
}
}
func testLandingPageHasGettingStartedDocLink() throws {
for module in expectedModules {
let content = try readCatalogFile("\(module).md", in: module)
XCTAssertTrue(content.contains("<doc:GettingStarted>"),
"\(module).md must contain <doc:GettingStarted> article link")
}
}
// ── Symbol Extension Files ────────────────────────────────────────────────
func testExtensionFilesHaveDocumentationExtensionDirective() throws {
for module in expectedModules {
let extensionsDir = catalogRoot(for: module).appendingPathComponent("Extensions")
guard let enumerator = FileManager.default.enumerator(
at: extensionsDir,
includingPropertiesForKeys: [.isRegularFileKey],
options: [.skipsHiddenFiles]
) else { continue }
for case let url as URL in enumerator where url.pathExtension == "md" {
let content = try String(contentsOf: url, encoding: .utf8)
XCTAssertTrue(content.contains("@DocumentationExtension(mergeBehavior: append)"),
"Extension file \(url.lastPathComponent) in \(module) must contain @DocumentationExtension(mergeBehavior: append)")
}
}
}
func testExtensionFilesHaveSymbolPathTitle() throws {
for module in expectedModules {
let extensionsDir = catalogRoot(for: module).appendingPathComponent("Extensions")
guard let enumerator = FileManager.default.enumerator(
at: extensionsDir,
includingPropertiesForKeys: [.isRegularFileKey],
options: [.skipsHiddenFiles]
) else { continue }
for case let url as URL in enumerator where url.pathExtension == "md" {
let symbolName = url.deletingPathExtension().lastPathComponent
let content = try String(contentsOf: url, encoding: .utf8)
// Extension files must use # ``<ModuleName>/<SymbolName>`` heading
XCTAssertTrue(content.hasPrefix("# ``\(module)/\(symbolName)``"),
"Extension \(symbolName).md must start with # ``\(module)/\(symbolName)``")
}
}
}
// ── Articles ──────────────────────────────────────────────────────────────
func testGettingStartedArticleHasOverview() throws {
for module in expectedModules {
let content = try readCatalogFile("Articles/GettingStarted.md", in: module)
XCTAssertTrue(content.contains("## Overview"),
"GettingStarted.md in \(module) must contain ## Overview")
}
}
func testArchitectureArticleHasOverview() throws {
for module in expectedModules {
let content = try readCatalogFile("Articles/Architecture.md", in: module)
XCTAssertTrue(content.contains("## Overview"),
"Architecture.md in \(module) must contain ## Overview")
}
}
func testKnowledgeGraphArticleHasSeeAlso() throws {
for module in expectedModules {
let content = try readCatalogFile("Articles/KnowledgeGraphIntegration.md", in: module)
XCTAssertTrue(content.contains("## See Also"),
"KnowledgeGraphIntegration.md in \(module) must contain ## See Also")
}
}
// ── Symbol Link Format ────────────────────────────────────────────────────
func testLandingPageSymbolLinksUseDoubleBackticks() throws {
for module in expectedModules {
let content = try readCatalogFile("\(module).md", in: module)
// Must contain at least one ``ModuleName/SymbolName`` reference
let regex = try NSRegularExpression(
pattern: #"``\#(module)/\w+"#,
options: []
)
let range = NSRange(content.startIndex..., in: content)
let matches = regex.numberOfMatches(in: content, options: [], range: range)
// Only assert if the module has types; some modules may have none documented yet.
// We just verify the format when links are present.
if matches > 0 {
XCTAssertTrue(content.contains("``\(module)/"),
"\(module).md symbol links must use ``\(module)/<SymbolName>`` format")
}
}
}
}

Xet Storage Details

Size:
14.2 kB
·
Xet hash:
835eaa3b2de08c26c8b006ecf002f6e3826831c0fc766e084d910fe37b4d822b

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.