Buckets:
localhost1978/localhost / LOCALHOST1978 /SSK_DocGen /Tests /SSK_DocGenTests /DoccCatalogConformanceTests.swift
| 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.