krz/orgstar

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

Tests/OrgEditorAppKitTests/CompletionPopupTests.swift

3a3dedba062790e1580c66d38606eda4b02cb501
orgstar/Tests/OrgEditorAppKitTests/CompletionPopupTests.swift history · blame · raw

76 lines · 3509 bytes

 1import AppKit
 2import OrgCore
 3import Testing
 4@testable import OrgEditorAppKit
 5
 6@MainActor
 7struct CompletionPopupTests {
 8    func at(_ text: String) -> Harness {
 9        let h = Harness(text)
10        h.caret(at: text.utf16.count)
11        return h
12    }
13
14    @Test func oneCandidateIsInserted() {
15        let h = at("#+TI")
16        h.editor.run("editor.complete")
17        #expect(h.editor.document.text == "#+TITLE: " && h.caret == 9)
18        let tags = at("* H :work:\n* I :")
19        tags.editor.run("editor.complete")
20        #expect(tags.editor.document.text == "* H :work:\n* I :work:")
21        let template = at("  <s")
22        template.editor.run("editor.complete")
23        #expect(template.editor.document.text == "#+begin_src \n#+end_src" && template.caret == 12)
24        let none = at("plain")
25        none.editor.run("editor.complete")
26        #expect(none.editor.completionPopup == nil && none.editor.document.text == "plain")
27    }
28
29    @Test func listPicksWithKeys() {
30        let h = at("#+STARTUP: in")
31        h.editor.run("editor.complete")
32        #expect(h.editor.completionPopup?.completion.candidates == ["indent", "inlineimages"])
33        #expect(h.editor.completionPopup?.window.isVisible == true)
34        ModalTests().type(h, "C-n C-n")
35        #expect(h.editor.completionPopup?.selected == "inlineimages")
36        ModalTests().type(h, "C-p RET")
37        #expect(h.editor.document.text == "#+STARTUP: indent" && h.editor.completionPopup == nil)
38
39        // TAB completes the common start, then the list follows the text.
40        let common = at("#+STARTUP: entities")
41        common.editor.run("editor.complete")
42        ModalTests().type(common, "TAB")
43        #expect(common.editor.document.text == "#+STARTUP: entitiesp")
44        #expect(common.editor.completionPopup?.completion.candidates == ["entitiesplain", "entitiespretty"])
45        common.textView.insertText("r", replacementRange: common.textView.selectedRange())
46        #expect(common.editor.completionPopup?.completion.candidates == ["entitiespretty"])
47        common.textView.insertText(" ", replacementRange: common.textView.selectedRange())
48        #expect(common.editor.completionPopup?.completion.candidates == nil || common.editor.completionPopup?.completion.range.lowerBound != 11)
49
50        // RET with nothing chosen closes the list and is a newline.
51        let plain = at("#+STARTUP: in")
52        plain.editor.run("editor.complete")
53        ModalTests().type(plain, "C-g")
54        #expect(plain.editor.completionPopup == nil && plain.editor.document.text == "#+STARTUP: in")
55    }
56
57    @Test func doomOpensTheListAsYouType() {
58        let h = Harness("* H :work:home:\n* I \n")
59        h.editor.keymap = KeymapPreset.doom.keymap
60        h.editor.modal = true
61        h.caret(at: 20)
62        ModalTests().type(h, "a")
63        h.textView.insertText(":w", replacementRange: h.textView.selectedRange())
64        h.editor.autoComplete()
65        #expect(h.editor.completionPopup == nil)
66        h.textView.insertText("o", replacementRange: h.textView.selectedRange())
67        h.editor.autoComplete()
68        #expect(h.editor.completionPopup?.completion.candidates == ["work:"])
69        ModalTests().type(h, "ESC")
70        #expect(h.editor.completionPopup == nil && h.editor.vim.mode == .normal)
71        ModalTests().type(h, "a")
72        h.textView.insertText("\\alp", replacementRange: h.textView.selectedRange())
73        ModalTests().type(h, "C-SPC")
74        #expect(h.editor.document.text.contains("\\alpha"))
75    }
76}