import XCTest @testable import SaplingEditor final class EditorDirtyLineInvalidationTests: XCTestCase { func testInitialRenderTouchesEveryLine() { let source = "One\nTwo\nThree" let plan = EditorDirtyLineInvalidator.plan( previousText: nil, currentText: source, previousActiveLineIndex: nil, currentActiveLineIndex: 0 ) XCTAssertEqual(plan.reason, .initial) XCTAssertTrue(plan.isFullRender) XCTAssertEqual(plan.dirtyLineIndexes, [0, 1, 2]) } func testActiveLineChangeTouchesOnlyPreviousAndCurrentActiveLines() { let source = "One\nTwo\nThree\nFour" let plan = EditorDirtyLineInvalidator.plan( previousText: source, currentText: source, previousActiveLineIndex: 1, currentActiveLineIndex: 3 ) XCTAssertEqual(plan.reason, .activeLineChange) XCTAssertFalse(plan.isFullRender) XCTAssertEqual(plan.dirtyLineIndexes, [1, 3]) } func testSingleLineEditTouchesChangedLineAndNeighbors() { let previous = "One\nTwo\nThree\nFour\nFive" let current = "One\nTwo\nThree updated\nFour\nFive" let plan = EditorDirtyLineInvalidator.plan( previousText: previous, currentText: current, previousActiveLineIndex: 2, currentActiveLineIndex: 2 ) XCTAssertEqual(plan.reason, .sourceChange) XCTAssertFalse(plan.isFullRender) XCTAssertEqual(plan.dirtyLineIndexes, [1, 2, 3]) } func testLineBreakInsertionTouchesSplitLineAndNeighbors() { let previous = "One\nTwo three\nFour" let current = "One\nTwo\nthree\nFour" let plan = EditorDirtyLineInvalidator.plan( previousText: previous, currentText: current, previousActiveLineIndex: 1, currentActiveLineIndex: 2 ) XCTAssertEqual(plan.reason, .sourceChange) XCTAssertFalse(plan.isFullRender) XCTAssertEqual(plan.dirtyLineIndexes, [0, 1, 2]) } func testUnchangedViewUpdateDoesNotRequireStyling() { let source = "One\nTwo" let plan = EditorDirtyLineInvalidator.plan( previousText: source, currentText: source, previousActiveLineIndex: 1, currentActiveLineIndex: 1 ) XCTAssertEqual(plan.reason, .viewUpdate) XCTAssertFalse(plan.requiresStyling) XCTAssertTrue(plan.dirtyLineIndexes.isEmpty) } }