krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Tests/OrgEditorAppKitTests/ViewToggleTests.swift

16086b4cf2caff5328774b2cd5ae3ffe1ab65ca4
orgstar/Tests/OrgEditorAppKitTests/ViewToggleTests.swift history · blame · raw

61 lines · 2925 bytes

 1import AppKit
 2import OrgCore
 3import OrgDocument
 4import Testing
 5@testable import OrgEditorAppKit
 6
 7@MainActor
 8struct ViewToggleTests {
 9    /// A plain click at the middle of the character at `offset`.
10    func click(_ h: Harness, _ offset: Int) {
11        let screen = h.textView.firstRect(forCharacterRange: NSRange(location: offset, length: 1), actualRange: nil)
12        let inWindow = h.window.convertPoint(fromScreen: NSPoint(x: screen.midX, y: screen.midY))
13        let event = NSEvent.mouseEvent(with: .leftMouseDown, location: inWindow, modifierFlags: [], timestamp: 0,
14                                       windowNumber: h.window.windowNumber, context: nil, eventNumber: 0, clickCount: 1, pressure: 1)!
15        h.textView.mouseDown(with: event)
16    }
17
18    @Test func clickingStarsCyclesAndCheckboxesToggle() {
19        let h = Harness("* Top\nbody\n- [ ] task\n* Next\n")
20        click(h, 0)
21        #expect(h.visibleLines == ["* Top\n", "* Next\n"])
22        click(h, 0)
23        #expect(h.visibleLines.count == 4)
24        click(h, h.offset(of: "[ ]") + 1)
25        #expect(h.editor.document.text == "* Top\nbody\n- [X] task\n* Next\n")
26        // Elsewhere a click is the text view's.
27        #expect(!h.editor.click(at: h.offset(of: "Top") + 1))
28        #expect(!h.editor.click(at: h.offset(of: "task") + 1))
29    }
30
31    @Test func truncatingAndSpellChecking() {
32        let h = Harness("* Hedding\n~codez~ wurds\n")
33        #expect(!h.editor.truncatesLines)
34        h.editor.run("editor.toggle-truncate-lines")
35        #expect(h.editor.truncatesLines && h.textView.enclosingScrollView?.hasHorizontalScroller == true)
36        h.editor.run("editor.toggle-truncate-lines")
37        #expect(!h.editor.truncatesLines && h.textView.textContainer?.widthTracksTextView == true)
38        h.editor.run("editor.toggle-spell-check")
39        #expect(h.textView.isContinuousSpellCheckingEnabled)
40        let code = NSRange(location: h.offset(of: "codez"), length: 5)
41        let prose = NSRange(location: h.offset(of: "wurds"), length: 5)
42        #expect(h.editor.textView(h.textView, shouldSetSpellingState: 1, range: code) == 0)
43        #expect(h.editor.textView(h.textView, shouldSetSpellingState: 1, range: prose) == 1)
44    }
45
46    @Test func gjMovesByScreenLines() {
47        let long = Array(repeating: "word", count: 60).joined(separator: " ")
48        // In Org files gj is evil-org's element motion; elsewhere it's screen lines.
49        let h = Harness(DocumentState(bytes: Array((long + "\nnext\n").utf8)), mode: .plain(language: nil))
50        h.editor.keymap = KeymapPreset.doom.keymap
51        h.editor.modal = true
52        h.caret(at: 0)
53        h.caret(at: 0)
54        ModalTests().type(h, "g j")
55        #expect(h.caret > 0 && h.caret < long.utf16.count, "\(h.caret)")
56        ModalTests().type(h, "g k")
57        #expect(h.caret == 0)
58        ModalTests().type(h, "j")
59        #expect(h.caret == long.utf16.count + 1)
60    }
61}