krz/orgstar

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

Tests/OrgEditorAppKitTests/AccessibilityTests.swift

b98a6509c5ae75e5172dd333d1b6105fd6ceee0e
orgstar/Tests/OrgEditorAppKitTests/AccessibilityTests.swift history · blame · raw

60 lines · 2995 bytes

3 symbols in this file
 1import AppKit
 2import Testing
 3@testable import OrgEditorAppKit
 4
 5/// What VoiceOver reads: the text as shown, with ranges and lines in its terms.
 6@MainActor
 7struct AccessibilityTests {
 8    let text = "* Top\nbody\n* Links\nSee [[https://x.org][the site]] now.\n"
 9
10    @Test func readsTheTextAsShown() {
11        let h = Harness(text)
12        h.editor.showMarkup = false
13        h.caret(at: 0)
14        h.drainStyling()
15        let view = h.textView
16        #expect(view.accessibilityValue() == "* Top\nbody\n* Links\nSee the site now.\n")
17        #expect(view.accessibilityNumberOfCharacters() == 37)
18
19        // The caret after "the" in the link description.
20        let the = (text as NSString).range(of: "the site").location
21        h.caret(at: the + 3)
22        h.drainStyling()
23        h.caret(at: 0)
24        h.drainStyling()
25        view.setAccessibilitySelectedTextRange(NSRange(location: 27, length: 4))
26        #expect(view.selectedRange() == NSRange(location: the + 4, length: 4))
27        #expect(view.accessibilitySelectedText() == "site")
28        // The caret's line now shows its markup, as on screen.
29        #expect(view.accessibilityValue() == "* Top\nbody\n* Links\nSee [[https://x.org][the site]] now.\n")
30        #expect(view.accessibilityLine(for: 7) == 1 && view.accessibilityRange(forLine: 1) == NSRange(location: 6, length: 5))
31        #expect(view.accessibilityString(for: NSRange(location: 19, length: 3)) == "See")
32
33        // Folded text is still read.
34        h.caret(at: 0)
35        h.editor.cycleAtCaret()
36        h.drainStyling()
37        #expect(view.accessibilityValue() == "* Top\nbody\n* Links\nSee the site now.\n")
38        #expect(view.accessibilityInsertionPointLineNumber() == 0)
39
40        // With markup shown, the whole text.
41        h.editor.showMarkup = true
42        h.drainStyling()
43        #expect(view.accessibilityValue() == text)
44    }
45
46    @Test func mapsBetweenShownAndBufferOffsets() {
47        let storage = NSMutableAttributedString(string: "a[[x][b]]c")
48        storage.addAttribute(.font, value: NSFont.systemFont(ofSize: 0.01), range: NSRange(location: 1, length: 5))
49        storage.addAttribute(.font, value: NSFont.systemFont(ofSize: 0.01), range: NSRange(location: 7, length: 2))
50        let shown = AccessibleText(storage)
51        #expect(shown.string == "abc" && shown.model == [0, 6, 9, 10])
52        #expect(shown.visible(NSRange(location: 6, length: 1)) == NSRange(location: 1, length: 1))
53        #expect(shown.buffer(NSRange(location: 0, length: 3)) == NSRange(location: 0, length: 10))
54        #expect(shown.buffer(NSRange(location: 3, length: 0)) == NSRange(location: 10, length: 0))
55        let pretty = NSMutableAttributedString(string: "x \\alpha y")
56        pretty.addAttribute(.font, value: NSFont.systemFont(ofSize: 0.01), range: NSRange(location: 2, length: 5))
57        pretty.addAttribute(.orgEntityDisplay, value: "α", range: NSRange(location: 7, length: 1))
58        #expect(AccessibleText(pretty).string == "x α y")
59    }
60}