1
0
mirror of git://jb55.com/damus synced 2024-09-16 02:03:45 +00:00
damus/damusTests/PostViewTests.swift
Daniel D’Aquino dcb94635ea Fix text editing issues on characters added right after mention link
Changelog-Fixed: Fix text editing issues on characters added right after mention link
Closes: https://github.com/damus-io/damus/issues/1375
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Tested-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-20 17:25:06 -07:00

144 lines
10 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// PostViewTests.swift
// damusTests
//
// Created by Daniel DAquino on 2023-08-19.
//
import Foundation
import XCTest
@testable import damus
import SwiftUI
final class PostViewTests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
/// Based on https://github.com/damus-io/damus/issues/1375
/// Tests whether the editor properly handles mention links after they have been added, to avoid manual editing of attributed links
func testMentionLinkEditorHandling() throws {
var content: NSMutableAttributedString
// Test normal insertion
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Hello"), replacementText: "@", replacementRange: NSRange(location: 0, length: 0), shouldBeAbleToChangeAutomatically: true)
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Hello "), replacementText: "@", replacementRange: NSRange(location: 6, length: 0), shouldBeAbleToChangeAutomatically: true)
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Helo "), replacementText: "l", replacementRange: NSRange(location: 3, length: 0), shouldBeAbleToChangeAutomatically: true)
// Test normal backspacing
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Hello"), replacementText: "", replacementRange: NSRange(location: 5, length: 1), shouldBeAbleToChangeAutomatically: true)
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Hello "), replacementText: "", replacementRange: NSRange(location: 6, length: 1), shouldBeAbleToChangeAutomatically: true)
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Helo "), replacementText: "", replacementRange: NSRange(location: 3, length: 1), shouldBeAbleToChangeAutomatically: true)
// Test normal insertion after mention link
content = NSMutableAttributedString(string: "Hello @user ")
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
checkMentionLinkEditorHandling(content: content, replacementText: "a", replacementRange: NSRange(location: 12, length: 0), shouldBeAbleToChangeAutomatically: true)
// Test insertion right at the end of a mention link, at the end of the text
content = NSMutableAttributedString(string: "Hello @user")
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
checkMentionLinkEditorHandling(content: content, replacementText: ",", replacementRange: NSRange(location: 11, length: 0), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 12, handleNewContent: { newManuallyEditedContent in
XCTAssertEqual(newManuallyEditedContent.string, "Hello @user,")
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 11, effectiveRange: nil))
})
// Test insertion right at the end of a mention link, in the middle of the text
content = NSMutableAttributedString(string: "Hello @user how are you?")
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
checkMentionLinkEditorHandling(content: content, replacementText: ",", replacementRange: NSRange(location: 11, length: 0), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 12, handleNewContent: { newManuallyEditedContent in
XCTAssertEqual(newManuallyEditedContent.string, "Hello @user, how are you?")
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 11, effectiveRange: nil))
})
// Test insertion in the middle of a mention link to check if the link is removed
content = NSMutableAttributedString(string: "Hello @user how are you?")
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
checkMentionLinkEditorHandling(content: content, replacementText: "a", replacementRange: NSRange(location: 8, length: 0), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 9, handleNewContent: { newManuallyEditedContent in
XCTAssertEqual(newManuallyEditedContent.string, "Hello @uaser how are you?")
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 8, effectiveRange: nil))
})
// Test insertion in the middle of a mention link to check if the link is removed, at the end of the text
content = NSMutableAttributedString(string: "Hello @user")
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
checkMentionLinkEditorHandling(content: content, replacementText: "a", replacementRange: NSRange(location: 8, length: 0), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 9, handleNewContent: { newManuallyEditedContent in
XCTAssertEqual(newManuallyEditedContent.string, "Hello @uaser")
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 8, effectiveRange: nil))
})
// Test backspacing right at the end of a mention link, at the end of the text
content = NSMutableAttributedString(string: "Hello @user")
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
checkMentionLinkEditorHandling(content: content, replacementText: "", replacementRange: NSRange(location: 10, length: 1), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 10, handleNewContent: { newManuallyEditedContent in
XCTAssertEqual(newManuallyEditedContent.string, "Hello @use")
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 6, effectiveRange: nil))
})
// Test adding text right at the start of a mention link, to check that the link is removed
content = NSMutableAttributedString(string: "Hello @user")
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
checkMentionLinkEditorHandling(content: content, replacementText: "a", replacementRange: NSRange(location: 6, length: 0), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 7, handleNewContent: { newManuallyEditedContent in
XCTAssertEqual(newManuallyEditedContent.string, "Hello a@user")
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 7, effectiveRange: nil))
})
// Test that removing one link does not affect the other
content = NSMutableAttributedString(string: "Hello @user1 @user2")
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 6))
content.addAttribute(.link, value: "damus:5678", range: NSRange(location: 13, length: 6))
checkMentionLinkEditorHandling(content: content, replacementText: "", replacementRange: NSRange(location: 18, length: 1), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 18, handleNewContent: { newManuallyEditedContent in
XCTAssertEqual(newManuallyEditedContent.string, "Hello @user1 @user")
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 13, effectiveRange: nil))
XCTAssertNotNil(newManuallyEditedContent.attribute(.link, at: 6, effectiveRange: nil))
})
// Test that replacing a whole range intersecting with two links removes both links
content = NSMutableAttributedString(string: "Hello @user1 @user2")
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 6))
content.addAttribute(.link, value: "damus:5678", range: NSRange(location: 13, length: 6))
checkMentionLinkEditorHandling(content: content, replacementText: "a", replacementRange: NSRange(location: 10, length: 4), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 11, handleNewContent: { newManuallyEditedContent in
XCTAssertEqual(newManuallyEditedContent.string, "Hello @useauser2")
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 6, effectiveRange: nil))
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 11, effectiveRange: nil))
})
// Test that replacing a whole range including two links removes both links naturally
content = NSMutableAttributedString(string: "Hello @user1 @user2, how are you?")
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 6))
content.addAttribute(.link, value: "damus:5678", range: NSRange(location: 13, length: 6))
checkMentionLinkEditorHandling(content: content, replacementText: "", replacementRange: NSRange(location: 5, length: 28), shouldBeAbleToChangeAutomatically: true)
}
}
func checkMentionLinkEditorHandling(
content: NSMutableAttributedString,
replacementText: String,
replacementRange: NSRange,
shouldBeAbleToChangeAutomatically: Bool,
expectedNewCursorIndex: Int? = nil,
handleNewContent: ((NSMutableAttributedString) -> Void)? = nil) {
let bindingContent: Binding<NSMutableAttributedString> = Binding(get: {
return content
}, set: { newValue in
handleNewContent?(newValue)
})
let coordinator: TextViewWrapper.Coordinator = TextViewWrapper.Coordinator(attributedText: bindingContent, getFocusWordForMention: nil, updateCursorPosition: { newCursorIndex in
if let expectedNewCursorIndex {
XCTAssertEqual(newCursorIndex, expectedNewCursorIndex)
}
})
let textView = UITextView()
textView.attributedText = content
XCTAssertEqual(coordinator.textView(textView, shouldChangeTextIn: replacementRange, replacementText: replacementText), shouldBeAbleToChangeAutomatically, "Expected shouldChangeTextIn to return \(shouldBeAbleToChangeAutomatically), but was \(!shouldBeAbleToChangeAutomatically)")
}