75 lines
3.1 KiB
Swift
75 lines
3.1 KiB
Swift
|
|
import XCTest
|
||
|
|
@testable import SaplingEditor
|
||
|
|
|
||
|
|
final class DocumentPresentationStateTests: XCTestCase {
|
||
|
|
func testEveryLineHasExactlyOnePresentationState() {
|
||
|
|
let source = "# Heading\n* [x] Done\nParagraph"
|
||
|
|
let lineIndex = DocumentLineIndex(source: source)
|
||
|
|
|
||
|
|
let presentation = DocumentPresentationState(lineIndex: lineIndex, activeLineIndex: 1)
|
||
|
|
|
||
|
|
XCTAssertEqual(presentation.lines.count, 3)
|
||
|
|
XCTAssertEqual(presentation.lineState(at: 0), .rendered)
|
||
|
|
XCTAssertEqual(presentation.lineState(at: 1), .source)
|
||
|
|
XCTAssertEqual(presentation.lineState(at: 2), .rendered)
|
||
|
|
XCTAssertEqual(presentation.lines.filter { $0.state == .source }.map(\.line.index), [1])
|
||
|
|
XCTAssertEqual(presentation.lines.filter { $0.state == .rendered }.map(\.line.index), [0, 2])
|
||
|
|
}
|
||
|
|
|
||
|
|
func testPresentationStateIsDeterministicForSameDocumentAndActiveLine() {
|
||
|
|
let source = "# Heading\nThis has **bold** and `code`.\n* [ ] Todo"
|
||
|
|
let lineIndex = DocumentLineIndex(source: source)
|
||
|
|
|
||
|
|
let first = DocumentPresentationState(lineIndex: lineIndex, activeLineIndex: 2)
|
||
|
|
let second = DocumentPresentationState(lineIndex: lineIndex, activeLineIndex: 2)
|
||
|
|
|
||
|
|
XCTAssertEqual(first, second)
|
||
|
|
}
|
||
|
|
|
||
|
|
func testRenderedElementsAreSemantic() {
|
||
|
|
let source = "# Heading\n* [x] Done\nSee [Docs](https://example.com)"
|
||
|
|
let lineIndex = DocumentLineIndex(source: source)
|
||
|
|
|
||
|
|
let presentation = DocumentPresentationState(lineIndex: lineIndex, activeLineIndex: 99)
|
||
|
|
|
||
|
|
XCTAssertTrue(presentation.elements.contains {
|
||
|
|
guard case .heading(let heading) = $0 else { return false }
|
||
|
|
return heading.lineIndex == 0 && heading.level == 1
|
||
|
|
})
|
||
|
|
XCTAssertEqual(presentation.renderedTasks.map(\.checked), [true])
|
||
|
|
XCTAssertTrue(presentation.elements.contains {
|
||
|
|
guard case .link(let link) = $0 else { return false }
|
||
|
|
return (source as NSString).substring(with: link.titleRange) == "Docs"
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func testCodeBlockIsRepresentedAsSemanticBlock() {
|
||
|
|
let source = "Intro\n```swift\nlet value = 42\n```"
|
||
|
|
let lineIndex = DocumentLineIndex(source: source)
|
||
|
|
|
||
|
|
let presentation = DocumentPresentationState(lineIndex: lineIndex, activeLineIndex: 0)
|
||
|
|
|
||
|
|
XCTAssertEqual(presentation.renderedCodeBlocks.count, 1)
|
||
|
|
XCTAssertEqual(presentation.renderedCodeBlocks[0].lineIndexes, [1, 2, 3])
|
||
|
|
XCTAssertEqual(
|
||
|
|
(source as NSString).substring(with: presentation.renderedCodeBlocks[0].languageRange!),
|
||
|
|
"swift"
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
func testDirtyPresentationResolvesNearbyCodeBlockContext() {
|
||
|
|
let source = "Intro\n```swift\nlet value = 42\n```"
|
||
|
|
let lineIndex = DocumentLineIndex(source: source)
|
||
|
|
|
||
|
|
let presentation = DocumentPresentationState(
|
||
|
|
lineIndex: lineIndex,
|
||
|
|
activeLineIndex: 0,
|
||
|
|
lineIndexes: [2]
|
||
|
|
)
|
||
|
|
|
||
|
|
XCTAssertEqual(presentation.lines.count, 1)
|
||
|
|
XCTAssertEqual(presentation.lines[0].state, .rendered)
|
||
|
|
XCTAssertEqual(presentation.lines[0].renderPlan.kind, .codeBlockContent)
|
||
|
|
}
|
||
|
|
}
|