Files
conjure/Tests/ConjureKitTests/NotesHeadingTests.swift
T
2026-10-20 16:28:42 +02:00

77 lines
3.4 KiB
Swift

import AppKit
import ConjureKit
import Testing
@testable import Conjure
@Test @MainActor
func headingsFollowVisibleParagraphEditingAndRoundTrip() throws {
_ = NSApplication.shared
let suite = "NotesHeadings.\(UUID().uuidString)"
let defaults = try #require(UserDefaults(suiteName: suite))
let directory = FileManager.default.temporaryDirectory.appendingPathComponent(suite)
defer {
defaults.removePersistentDomain(forName: suite)
try? FileManager.default.removeItem(at: directory)
}
let controller = NotesController(defaults: defaults, directory: directory)
let window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 600, height: 500),
styleMask: .borderless, backing: .buffered, defer: false)
window.contentViewController = controller
defer { _ = controller.close(); window.orderOut(nil) }
func descendants(_ view: NSView) -> [NSView] { [view] + view.subviews.flatMap(descendants) }
let editor = try #require(descendants(controller.view).compactMap { $0 as? NotesTextView }.first)
window.makeFirstResponder(editor)
func reset(_ source: String) {
editor.setMarkdownContents(NSAttributedString(string: source))
MarkdownHighlighting.apply(to: editor)
editor.refreshTasks()
editor.breakUndoCoalescing()
editor.undoManager?.removeAllActions()
let title = (editor.string as NSString).range(of: "Title")
editor.setSelectedRange(NSRange(location: title.location, length: 0))
}
for (before, after) in [
("## Title", "## Title"),
("\n## Title", "## Title"),
("Text\n## Title", "TextTitle"),
("# Text\n## Title", "# TextTitle"),
("Text\n\n## Title", "Text\n## Title")
] {
reset(before)
editor.undoManager?.beginUndoGrouping()
editor.deleteBackward(nil)
editor.undoManager?.endUndoGrouping()
#expect(editor.markdownString == after)
if before != after {
editor.undoManager?.undo()
#expect(editor.markdownString == before)
editor.undoManager?.redo()
#expect(editor.markdownString == after)
}
}
for level in 1...6 {
reset("### Title")
editor.undoManager?.beginUndoGrouping()
for character in String(repeating: "#", count: level) + " " {
editor.insertText(String(character), replacementRange: editor.selectedRange())
}
editor.undoManager?.endUndoGrouping()
let expected = String(repeating: "#", count: level) + " Title"
#expect(editor.markdownString == expected)
let title = (editor.string as NSString).range(of: "Title")
#expect(editor.selectedRange().location == title.location)
let sizes: [CGFloat] = [26, 23, 21, 19, 17, 15]
#expect((editor.textStorage?.attribute(.font, at: title.location, effectiveRange: nil) as? NSFont)?.pointSize == sizes[level - 1])
editor.undoManager?.undo()
#expect(editor.markdownString == "### Title")
editor.undoManager?.redo()
#expect(editor.markdownString == expected)
#expect(controller.save())
let reloaded = try #require(NotesStore(directory: directory).notes.first)
#expect(reloaded.contents.string == expected)
}
reset("```text\n## Title\n```")
editor.insertText("# ", replacementRange: editor.selectedRange())
#expect(editor.markdownString == "```text\n## # Title\n```")
}