Sapling/Tests/SaplingEditorTests/EditorCursorRegressionTests.swift

100 lines
3.9 KiB
Swift

import XCTest
@testable import SaplingEditor
final class EditorCursorRegressionTests: XCTestCase {
func testCursorMovementUpdatesActiveLineWithoutChangingSelectionLength() {
let source = "Alpha\nBeta\nGamma"
var state = EditorState(document: document(source: source))
state.updateSelection(EditorSelection(location: location(of: "Beta", in: source), length: 0))
XCTAssertEqual(state.selection, EditorSelection(location: 6, length: 0))
XCTAssertEqual(state.activeLineIndex, 1)
XCTAssertEqual(state.activeColumnNumber, 1)
}
func testSelectionChangeWithinLinePreservesActiveLine() {
let source = "Alpha\nBeta\nGamma"
var state = EditorState(document: document(source: source))
state.updateSelection(EditorSelection(location: location(of: "eta", in: source), length: 2))
XCTAssertEqual(state.selection.length, 2)
XCTAssertEqual(state.activeLineIndex, 1)
XCTAssertEqual(state.activeColumnNumber, 2)
}
func testMultiLineSelectionUsesSelectionAnchorForActiveLine() {
let source = "Alpha\nBeta\nGamma"
var state = EditorState(document: document(source: source))
let anchor = location(of: "Beta", in: source)
let end = location(of: "Gamma", in: source) + "Gamma".utf16.count
state.updateSelection(EditorSelection(location: anchor, length: end - anchor))
XCTAssertEqual(state.selection.location, anchor)
XCTAssertEqual(state.selection.length, 10)
XCTAssertEqual(state.activeLineIndex, 1)
}
func testInsertionKeepsCursorAndActiveLineOnEditedLine() {
let source = "Alpha\nBeta\nGamma"
let updated = "Alpha\nBeta updated\nGamma"
var state = EditorState(document: document(source: source))
state.updateSelection(EditorSelection(location: location(of: "Beta", in: source) + 4, length: 0))
state.updateSource(updated)
state.updateSelection(EditorSelection(location: location(of: "updated", in: updated) + 7, length: 0))
XCTAssertEqual(state.activeLineIndex, 1)
XCTAssertEqual(state.activeColumnNumber, 13)
}
func testDeletionClampsSelectionAndActiveLine() {
let source = "Alpha\nBeta\nGamma"
var state = EditorState(document: document(source: source))
state.updateSelection(EditorSelection(location: source.utf16.count, length: 0))
state.updateSource("Alpha")
XCTAssertEqual(state.selection.location, 5)
XCTAssertEqual(state.selection.length, 0)
XCTAssertEqual(state.activeLineIndex, 0)
}
func testLineBreakMovesActiveLineAfterNativeSelectionUpdate() {
let source = "Alpha Beta"
let updated = "Alpha\n Beta"
var state = EditorState(document: document(source: source))
state.updateSelection(EditorSelection(location: 5, length: 0))
state.updateSource(updated)
state.updateSelection(EditorSelection(location: 6, length: 0))
XCTAssertEqual(state.activeLineIndex, 1)
XCTAssertEqual(state.activeColumnNumber, 1)
}
func testActiveLineTransitionsAcrossDocument() {
let source = "One\nTwo\nThree\nFour"
var state = EditorState(document: document(source: source))
state.updateSelection(EditorSelection(location: location(of: "Four", in: source), length: 0))
XCTAssertEqual(state.activeLineIndex, 3)
state.updateSelection(EditorSelection(location: location(of: "One", in: source), length: 0))
XCTAssertEqual(state.activeLineIndex, 0)
}
private func document(source: String) -> EditorDocument {
EditorDocument(
url: URL(fileURLWithPath: "/tmp/EditorCursorRegressionTests.md"),
title: "EditorCursorRegressionTests",
source: source
)
}
private func location(of needle: String, in source: String) -> Int {
(source as NSString).range(of: needle).location
}
}