// // NativeTextEditorPureLogicTests.swift // oAITests // // SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 // Copyright (C) 2026 Rune Olsen import Testing import Foundation import AppKit import SwiftUI @testable import Confab @Suite("NativeTextEditor.inlineCodeRanges") struct NativeTextEditorPureLogicTests { @Test("No backticks yields no ranges") func noBackticks() { #expect(NativeTextEditor.inlineCodeRanges(in: "hello world").isEmpty) } @Test("A single closed backtick pair is matched, backticks included") func singleClosedPair() { let text = "Hello `code` world" let ranges = NativeTextEditor.inlineCodeRanges(in: text) #expect(ranges.count == 1) let matched = (text as NSString).substring(with: ranges[0]) #expect(matched == "`code`") } @Test("An unterminated single backtick is not matched") func unterminatedBacktick() { let text = "Hello `code world" #expect(NativeTextEditor.inlineCodeRanges(in: text).isEmpty) } @Test("Multiple closed pairs are all matched") func multiplePairs() { let text = "`one` and `two` and `three`" let ranges = NativeTextEditor.inlineCodeRanges(in: text) #expect(ranges.count == 3) let nsText = text as NSString #expect(ranges.map { nsText.substring(with: $0) } == ["`one`", "`two`", "`three`"]) } @Test("Backtick pair cannot span a newline") func doesNotSpanNewline() { let text = "`code\nblock`" #expect(NativeTextEditor.inlineCodeRanges(in: text).isEmpty) } @Test("Empty string yields no ranges") func emptyString() { #expect(NativeTextEditor.inlineCodeRanges(in: "").isEmpty) } @Test("Adjacent backtick pairs on the same line are each matched separately") func adjacentPairs() { let text = "`a``b`" let ranges = NativeTextEditor.inlineCodeRanges(in: text) let nsText = text as NSString #expect(ranges.map { nsText.substring(with: $0) } == ["`a`", "`b`"]) } } @Suite("NativeTextEditor.fencedCodeBlockRanges") struct NativeTextEditorFencedBlockTests { @Test("No fences yields no ranges") func noFences() { #expect(NativeTextEditor.fencedCodeBlockRanges(in: "hello world").isEmpty) } @Test("A closed multi-line fence is matched in full, including the language tag") func closedMultilineFence() { let text = "```python\nprint(\"hi\")\n```" let ranges = NativeTextEditor.fencedCodeBlockRanges(in: text) #expect(ranges.count == 1) #expect((text as NSString).substring(with: ranges[0]) == text) } @Test("An unterminated fence (no closing triple) is not matched") func unterminatedFence() { let text = "```python\nprint(\"hi\")" #expect(NativeTextEditor.fencedCodeBlockRanges(in: text).isEmpty) } @Test("Text before and after a fence is excluded from the match") func surroundingTextExcluded() { let text = "before\n```\ncode\n```\nafter" let ranges = NativeTextEditor.fencedCodeBlockRanges(in: text) #expect(ranges.count == 1) #expect((text as NSString).substring(with: ranges[0]) == "```\ncode\n```") } } @Suite("NativeTextEditor.codeStyledRanges") struct NativeTextEditorCodeStyledRangesTests { @Test("Combines a fenced block and a separate inline span") func combinesFencedAndInline() { let text = "See `foo` then:\n```\nbar\n```" let ranges = NativeTextEditor.codeStyledRanges(in: text) let nsText = text as NSString #expect(ranges.map { nsText.substring(with: $0) } == ["`foo`", "```\nbar\n```"]) } @Test("A backtick inside a fenced block's own content is not separately re-matched as inline") func backtickInsideFenceNotDoubleMatched() { let text = "```\nuse `code` here\n```" let ranges = NativeTextEditor.codeStyledRanges(in: text) #expect(ranges.count == 1) #expect((text as NSString).substring(with: ranges[0]) == text) } } @Suite("NativeTextEditor.fencedCodeBlocks (language + code-content extraction)") struct NativeTextEditorFencedCodeBlocksTests { @Test("Extracts the language tag and the code content, excluding fences and the tag line") func extractsLanguageAndCodeContent() { let text = "```python\nprint(\"hi\")\n```" let blocks = NativeTextEditor.fencedCodeBlocks(in: text) #expect(blocks.count == 1) #expect(blocks[0].language == "python") let nsText = text as NSString #expect(nsText.substring(with: blocks[0].codeRange) == "print(\"hi\")\n") } @Test("No language tag yields a nil language") func noLanguageTagYieldsNil() { let text = "```\ncode\n```" let blocks = NativeTextEditor.fencedCodeBlocks(in: text) #expect(blocks.count == 1) #expect(blocks[0].language == nil) } @Test("Language alias is passed through as typed, unresolved (SyntaxHighlighter resolves aliases itself)") func languageAliasPassthrough() { let text = "```py\nprint(1)\n```" let blocks = NativeTextEditor.fencedCodeBlocks(in: text) #expect(blocks[0].language == "py") } @Test("Unterminated fence yields no blocks") func unterminatedFenceYieldsNoBlocks() { #expect(NativeTextEditor.fencedCodeBlocks(in: "```python\nprint(1)").isEmpty) } } @Suite("SyntaxHighlighter runs → NSColor") struct SyntaxHighlighterBridgingTests { // NB: bridging via `NSAttributedString(highlighted)` does NOT work — that path stores // SwiftUI's `.foregroundColor` under a private `SwiftUI.ForegroundColor` key, not the // standard Cocoa `.foregroundColor` key (confirmed empirically before landing on this // `.runs`-based approach, which is what `NativeTextEditor` actually uses in production). @Test("A Python keyword's foreground color is readable via AttributedString.runs and converts to NSColor") func keywordColorReadableViaRuns() { let highlighted = SyntaxHighlighter.highlight(code: "def foo():", language: "python") #expect(!highlighted.runs.isEmpty) var foundKeywordColor = false let expected = NSColor(SyntaxHighlighter.keywordColor) for run in highlighted.runs { guard let color = run.foregroundColor else { continue } if NSColor(color).usingColorSpace(.deviceRGB) == expected.usingColorSpace(.deviceRGB) { foundKeywordColor = true } } #expect(foundKeywordColor) } }