diff --git a/oAI/oAI.entitlements b/oAI/oAI.entitlements deleted file mode 100644 index a86f180..0000000 --- a/oAI/oAI.entitlements +++ /dev/null @@ -1,20 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.network.client - - com.apple.security.network.server - - com.apple.security.personal-information.calendars - - com.apple.security.personal-information.reminders - - com.apple.security.personal-information.addressbook - - com.apple.security.personal-information.location - - - diff --git a/oAITests/ConversationListViewPureLogicTests.swift b/oAITests/ConversationListViewPureLogicTests.swift deleted file mode 100644 index d73cb73..0000000 --- a/oAITests/ConversationListViewPureLogicTests.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// ConversationListViewPureLogicTests.swift -// oAITests -// -// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 -// Copyright (C) 2026 Rune Olsen - -import Testing -import Foundation -@testable import Confab - -@Suite("ConversationListView.idsInRange") -struct ConversationListViewPureLogicTests { - - private let ids = (0..<6).map { _ in UUID() } - - @Test("Forward range includes anchor and target inclusive") - func forwardRange() { - let result = ConversationListView.idsInRange(orderedIds: ids, anchorId: ids[1], targetId: ids[4]) - #expect(result == Set(ids[1...4])) - } - - @Test("Backward range (target above anchor) still selects the span between them") - func backwardRange() { - let result = ConversationListView.idsInRange(orderedIds: ids, anchorId: ids[4], targetId: ids[1]) - #expect(result == Set(ids[1...4])) - } - - @Test("Anchor equal to target selects just that one id") - func sameAnchorAndTarget() { - let result = ConversationListView.idsInRange(orderedIds: ids, anchorId: ids[2], targetId: ids[2]) - #expect(result == [ids[2]]) - } - - @Test("Nil anchor (first Shift-click) falls back to just the target") - func nilAnchorFallsBackToTarget() { - let result = ConversationListView.idsInRange(orderedIds: ids, anchorId: nil, targetId: ids[3]) - #expect(result == [ids[3]]) - } - - @Test("Anchor no longer present in the ordered list falls back to just the target") - func missingAnchorFallsBackToTarget() { - let staleAnchor = UUID() - let result = ConversationListView.idsInRange(orderedIds: ids, anchorId: staleAnchor, targetId: ids[3]) - #expect(result == [ids[3]]) - } - - @Test("Single-element list selects that element") - func singleElementList() { - let solo = [ids[0]] - let result = ConversationListView.idsInRange(orderedIds: solo, anchorId: ids[0], targetId: ids[0]) - #expect(result == [ids[0]]) - } -} diff --git a/oAITests/NativeTextEditorPureLogicTests.swift b/oAITests/NativeTextEditorPureLogicTests.swift deleted file mode 100644 index 212d121..0000000 --- a/oAITests/NativeTextEditorPureLogicTests.swift +++ /dev/null @@ -1,174 +0,0 @@ -// -// 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) - } -}