Sapling/Tests/SaplingEditorTests/DocumentLineIndexTests.swift

117 lines
4.7 KiB
Swift

import XCTest
@testable import SaplingEditor
final class DocumentLineIndexTests: XCTestCase {
func testLFLineBoundaries() {
assertLineIndex(
source: "One\nTwo\nThree",
expectedSources: ["One", "Two", "Three"],
expectedRanges: [
NSRange(location: 0, length: 3),
NSRange(location: 4, length: 3),
NSRange(location: 8, length: 5)
],
expectedEndings: [.lf, .lf, .none]
)
}
func testCRLFLineBoundaries() {
assertLineIndex(
source: "One\r\nTwo\r\nThree",
expectedSources: ["One", "Two", "Three"],
expectedRanges: [
NSRange(location: 0, length: 3),
NSRange(location: 5, length: 3),
NSRange(location: 10, length: 5)
],
expectedEndings: [.crlf, .crlf, .none]
)
}
func testCRLineBoundaries() {
assertLineIndex(
source: "One\rTwo\rThree",
expectedSources: ["One", "Two", "Three"],
expectedRanges: [
NSRange(location: 0, length: 3),
NSRange(location: 4, length: 3),
NSRange(location: 8, length: 5)
],
expectedEndings: [.cr, .cr, .none]
)
}
func testMixedLineBoundaries() {
assertLineIndex(
source: "One\nTwo\r\nThree\rFour",
expectedSources: ["One", "Two", "Three", "Four"],
expectedRanges: [
NSRange(location: 0, length: 3),
NSRange(location: 4, length: 3),
NSRange(location: 9, length: 5),
NSRange(location: 15, length: 4)
],
expectedEndings: [.lf, .crlf, .cr, .none]
)
}
func testTrailingBlankLineForEveryLineEnding() {
XCTAssertEqual(DocumentLineIndex(source: "One\n").boundaries.map(\.contentRange.location), [0, 4])
XCTAssertEqual(DocumentLineIndex(source: "One\r\n").boundaries.map(\.contentRange.location), [0, 5])
XCTAssertEqual(DocumentLineIndex(source: "One\r").boundaries.map(\.contentRange.location), [0, 4])
}
func testActiveLineDetectionAcrossCRLFBoundaries() {
let source = "One\r\nTwo\r\nThree"
XCTAssertEqual(EditorActiveLineTracker.lineIndex(containing: 0, in: source), 0)
XCTAssertEqual(EditorActiveLineTracker.lineIndex(containing: 3, in: source), 0)
XCTAssertEqual(EditorActiveLineTracker.lineIndex(containing: 4, in: source), 0)
XCTAssertEqual(EditorActiveLineTracker.lineIndex(containing: 5, in: source), 1)
XCTAssertEqual(EditorActiveLineTracker.lineIndex(containing: 8, in: source), 1)
XCTAssertEqual(EditorActiveLineTracker.lineIndex(containing: 9, in: source), 1)
XCTAssertEqual(EditorActiveLineTracker.lineIndex(containing: 10, in: source), 2)
}
func testEditorLinesPreserveCRLFSourceRangesAndModes() {
let lines = EditorActiveLineTracker.lines(from: "One\r\nTwo\r\nThree", activeLineIndex: 1)
XCTAssertEqual(lines.count, 3)
XCTAssertEqual(lines.map(\.source), ["One", "Two", "Three"])
XCTAssertEqual(lines.map(\.range), [
NSRange(location: 0, length: 3),
NSRange(location: 5, length: 3),
NSRange(location: 10, length: 5)
])
XCTAssertEqual(lines.map(\.mode), [.rendered, .source, .rendered])
}
func testBenchmarkDocumentSegmentsIntoPhysicalLines() throws {
let url = URL(fileURLWithPath: "/Users/feror/Sapling/Docs/Benchmarks/5mb.md")
let source = try String(contentsOf: url, encoding: .utf8)
let lines = EditorActiveLineTracker.lines(from: source, activeLineIndex: 0)
XCTAssertEqual(lines.count, 51_482)
XCTAssertEqual(lines[0].source, "# ExampleFile.com - Example Files")
XCTAssertEqual(lines[1].source, "")
XCTAssertEqual(lines[2].source, "- ✨ExampleFile ✨")
XCTAssertEqual(lines.filter { $0.mode == .source }.count, 1)
XCTAssertEqual(lines.filter { $0.mode == .rendered }.count, 51_481)
}
private func assertLineIndex(
source: String,
expectedSources: [String],
expectedRanges: [NSRange],
expectedEndings: [LineEndingStrategy],
file: StaticString = #filePath,
line: UInt = #line
) {
let index = DocumentLineIndex(source: source)
let lines = index.editorLines(activeLineIndex: 0)
XCTAssertEqual(lines.map(\.source), expectedSources, file: file, line: line)
XCTAssertEqual(index.boundaries.map(\.contentRange), expectedRanges, file: file, line: line)
XCTAssertEqual(index.boundaries.map(\.lineEnding), expectedEndings, file: file, line: line)
}
}