oficina / docs Public

Clone
git clone https://amadan.net/oficina/docs

Plain git — no account needed to clone.

Download

Download this file

1#if os(macOS)
2import AppKit
3import SwiftUI
4import XCTest
5@testable import DocsKit
6
7final class NativeClipboardInputTests: XCTestCase {
8 @MainActor func testDelegateTextReplacementAlsoRunsStructuralInputRule() {
9 var commands: [[String: JSONValue]] = []
10 let candidate = NativeDocumentTextView(content: NSAttributedString(string: "-\n"), generation: 1, didRender: { _ in }, compositionChanged: { _ in }, isEditable: true, paged: false, pendingInput: false, canRender: { _ in true }, currentSelection: { NSRange(location: 1, length: 0) }, selection: .constant(NSRange(location: 1, length: 0)), edit: { commands.append($0); return true })
11 let coordinator = candidate.makeCoordinator()
12 let text = DocsTextView(frame: CGRect(x: 0, y: 0, width: 500, height: 700))
13 text.delegate = coordinator
14 text.ruleCommand = coordinator.ruleEdit
15 coordinator.applyRender(candidate, to: text)
16 let allowed = coordinator.textView(text, shouldChangeTextIn: NSRange(location: 1, length: 0), replacementString: " ")
17 XCTAssertFalse(allowed)
18 XCTAssertEqual(text.string, "\n")
19 XCTAssertEqual(commands.last?["op"], .string("display_autoformat"))
20 XCTAssertEqual(commands.last?["generation"], .number(1))
21 }
22 @MainActor func testDelayedDuplicateRuleSelectionNotificationDoesNotCancelReversal() {
23 var commands: [[String: JSONValue]] = []
24 var selected = NSRange(location: 1, length: 0)
25 let candidate = NativeDocumentTextView(content: NSAttributedString(string: "-\n"), generation: 1, didRender: { _ in }, compositionChanged: { _ in }, isEditable: true, paged: false, pendingInput: false, canRender: { _ in true }, currentSelection: { selected }, selection: Binding(get: { selected }, set: { selected = $0 }), edit: { commands.append($0); return true })
26 let coordinator = candidate.makeCoordinator()
27 let text = DocsTextView(frame: CGRect(x: 0, y: 0, width: 500, height: 700))
28 text.delegate = coordinator; text.ruleCommand = coordinator.ruleEdit
29 coordinator.applyRender(candidate, to: text)
30 text.insertText(" ", replacementRange: NSRange(location: NSNotFound, length: 0))
31 coordinator.textViewDidChangeSelection(Notification(name: NSTextView.didChangeSelectionNotification, object: text))
32 coordinator.textViewDidChangeSelection(Notification(name: NSTextView.didChangeSelectionNotification, object: text))
33 XCTAssertNotNil(text.lastInputRule)
34 text.deleteBackward(nil)
35 XCTAssertEqual(text.string, "- \n")
36 XCTAssertEqual(commands.last?["op"], .string("display_revert_rule"))
37 }
38 @MainActor func testDirectDelegateBackspaceReversesRuleBeforeGenericDeletion() {
39 var commands: [[String: JSONValue]] = []
40 var selected = NSRange(location: 1, length: 0)
41 let candidate = NativeDocumentTextView(content: NSAttributedString(string: "-\n"), generation: 1, didRender: { _ in }, compositionChanged: { _ in }, isEditable: true, paged: false, pendingInput: false, canRender: { _ in true }, currentSelection: { selected }, selection: Binding(get: { selected }, set: { selected = $0 }), edit: { commands.append($0); return true })
42 let coordinator = candidate.makeCoordinator()
43 let text = DocsTextView(frame: CGRect(x: 0, y: 0, width: 500, height: 700))
44 text.delegate = coordinator; text.ruleCommand = coordinator.ruleEdit
45 coordinator.applyRender(candidate, to: text)
46 text.insertText(" ", replacementRange: NSRange(location: NSNotFound, length: 0))
47 XCTAssertNotNil(text.lastInputRule)
48 let allowed = coordinator.textView(text, shouldChangeTextIn: NSRange(location: 0, length: 0), replacementString: "")
49 XCTAssertFalse(allowed)
50 XCTAssertEqual(text.string, "- \n")
51 XCTAssertEqual(commands.last?["op"], .string("display_revert_rule"))
52 }
53 @MainActor func testRichPasteOptimisticMarksMatchImmediateTyping() throws {
54 let blocks: [JSONValue] = [.object(["type": .string("paragraph"), "children": .array([.object(["type": .string("text"), "runs": .array([.object(["insert": .string("bold😀"), "marks": .object(["strong": .object([:])])])])])])])]
55 let initial = NSAttributedString(string: "AB\n")
56 let insertion = try XCTUnwrap(DocumentClipboardInsertion.attributed(blocks: blocks, in: initial, range: NSRange(location: 1, length: 0)))
57 let optimistic = NSMutableAttributedString(attributedString: initial)
58 optimistic.replaceCharacters(in: NSRange(location: 1, length: 0), with: insertion)
59 XCTAssertEqual(optimistic.string, "Abold😀B\n")
60 let command = try XCTUnwrap(TextEditMapping.displayCommand(in: optimistic, range: NSRange(location: 7, length: 0), replacement: "!"))
61 XCTAssertEqual(command["at"], .number(7))
62 XCTAssertEqual(command["marks"], .object(["strong": .object([:])]))
63 }
64 @MainActor func testNativeSpaceRuleAndImmediateBackspaceRestorePrefix() {
65 let text = DocsTextView(frame: CGRect(x: 0, y: 0, width: 500, height: 700))
66 text.textStorage?.setAttributedString(NSAttributedString(string: "-\n"))
67 text.setSelectedRange(NSRange(location: 1, length: 0))
68 var commands: [[String: JSONValue]] = []
69 text.ruleCommand = { commands.append($0); return true }
70 text.insertText(" ", replacementRange: NSRange(location: NSNotFound, length: 0))
71 XCTAssertEqual(text.string, "\n")
72 XCTAssertEqual(text.selectedRange().location, 0)
73 XCTAssertEqual(commands.last?["op"], .string("display_autoformat"))
74 text.deleteBackward(nil)
75 XCTAssertEqual(text.string, "- \n")
76 XCTAssertEqual(commands.last?["op"], .string("display_revert_rule"))
77 let terminatorStyle = text.attributedString().attribute(.paragraphStyle, at: 2, effectiveRange: nil) as? NSParagraphStyle
78 XCTAssertTrue(terminatorStyle?.textLists.isEmpty == true, "The restored paragraph terminator must not continue an old native list")
79 }
80 @MainActor func testImmediateSecondReturnLeavesEmptyNativeListWithoutAddingText() {
81 let text = DocsTextView(frame: CGRect(x: 0, y: 0, width: 500, height: 700))
82 text.textStorage?.setAttributedString(NSAttributedString(string: "-\n"))
83 text.setSelectedRange(NSRange(location: 1, length: 0))
84 var commands: [[String: JSONValue]] = []
85 text.ruleCommand = { commands.append($0); return true }
86 text.insertText(" ", replacementRange: NSRange(location: NSNotFound, length: 0))
87 text.insertText("\n", replacementRange: NSRange(location: NSNotFound, length: 0))
88 XCTAssertEqual(text.string, "\n")
89 XCTAssertEqual(commands.last?["op"], .string("display_exit_list"))
90 }
91}
92#endif
93