import XCTest @testable import SaplingEditor final class EditorMarkdownRenderingSampleTests: XCTestCase { func testMilestoneThreeSamplesExerciseMarkdownRenderingFeatures() throws { let sampleNames = [ "markdown-technical-documentation.md", "markdown-meeting-notes.md", "markdown-research-notes.md", "markdown-project-plan.md", "markdown-long-form-writing.md" ] let samplesDirectory = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) .appendingPathComponent("Docs/EditorPrototypes", isDirectory: true) let renderer = HybridMarkdownLineRenderer() var counts = FeatureCounts() for sampleName in sampleNames { let source = try String(contentsOf: samplesDirectory.appendingPathComponent(sampleName), encoding: .utf8) let lines = EditorActiveLineTracker.lines(from: source, activeLineIndex: 0) let plans = renderer.renderPlans(for: lines) XCTAssertGreaterThan(lines.count, 10, "\(sampleName) should represent a realistic document shape.") counts.collect(plans) } XCTAssertGreaterThan(counts.headings, 0) XCTAssertGreaterThan(counts.blockquotes, 0) XCTAssertGreaterThan(counts.horizontalRules, 0) XCTAssertGreaterThan(counts.unorderedLists, 0) XCTAssertGreaterThan(counts.orderedLists, 0) XCTAssertGreaterThan(counts.taskLists, 0) XCTAssertGreaterThan(counts.codeFences, 0) XCTAssertGreaterThan(counts.codeContentLines, 0) XCTAssertGreaterThan(counts.tableRows, 0) XCTAssertGreaterThan(counts.boldSpans, 0) XCTAssertGreaterThan(counts.italicSpans, 0) XCTAssertGreaterThan(counts.inlineCodeSpans, 0) XCTAssertGreaterThan(counts.markdownLinks, 0) XCTAssertGreaterThan(counts.automaticLinks, 0) } } private struct FeatureCounts { var headings = 0 var blockquotes = 0 var horizontalRules = 0 var unorderedLists = 0 var orderedLists = 0 var taskLists = 0 var codeFences = 0 var codeContentLines = 0 var tableRows = 0 var boldSpans = 0 var italicSpans = 0 var inlineCodeSpans = 0 var markdownLinks = 0 var automaticLinks = 0 mutating func collect(_ plans: [HybridMarkdownLineRenderPlan]) { for plan in plans { switch plan.kind { case .heading: headings += 1 case .blockquote: blockquotes += 1 case .horizontalRule: horizontalRules += 1 case .unorderedList: unorderedLists += 1 case .orderedList: orderedLists += 1 case .taskList: taskLists += 1 case .fencedCodeFence: codeFences += 1 case .codeBlockContent: codeContentLines += 1 case .tableRow: tableRows += 1 case .paragraph: break } for span in plan.spans { switch span.kind { case .bold: boldSpans += 1 case .italic: italicSpans += 1 case .inlineCode: inlineCodeSpans += 1 case .link: markdownLinks += 1 case .automaticLink: automaticLinks += 1 case .markdownDelimiter: break } } } } }