Tests/OrgEditorAppKitTests/CompletionPopupTests.swift
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}