oficina / docs Public

Clone
git clone https://amadan.net/oficina/docs

Plain git — no account needed to clone.

Download

Download this file

1#if os(macOS)
2import AppKit
3import XCTest
4@testable import DocsKit
5
6final class DocumentTypographyTests: XCTestCase {
7 // Synthetic fixture also measured in WebKit at 96 CSS px/in with the same
8 // bundled Liberation fonts and the production [docs-text] CSS rules.
9 @MainActor func testBrowserFixtureLineBreaks() throws {
10 let heading = "A shared document with consistent typography on every screen"
11 let bold = "This is a synthetic layout fixture for the native and browser editors. The same bundled font, page width and paragraph styles must produce the same line breaks, including a long sentence that wraps across several lines."
12 let body = "The quick brown fox jumps over the lazy dog. A small change in font metrics can move the final word onto another line, so this paragraph deliberately includes enough words to exercise wrapping at a fixed document width."
13 func block(_ id: String, _ text: String, heading: Bool = false, strong: Bool = false) -> CRDTNode {
14 CRDTNode(id: id, type: heading ? "heading" : "paragraph", attrs: heading ? ["level": "1"] : nil, children: [CRDTNode(id: id + "t", type: "text", runs: [CRDTRun(insert: text, marks: strong ? ["strong": .object([:])] : nil)])])
15 }
16 let projection = CRDTProjection(children: [block("h", heading, heading: true), block("b", bold, strong: true), block("gap", ""), block("p", body)], canUndo: false, canRedo: false)
17 let storage = NSTextStorage(attributedString: NativeTextProjection.render(projection))
18 let manager = NSLayoutManager()
19 manager.usesFontLeading = false
20 let container = DocsPageTextContainer(size: CGSize(width: 636, height: 100000))
21 container.geometry = DocsPageGeometry(viewportWidth: 636, paged: false)
22 container.lineFragmentPadding = 0
23 storage.addLayoutManager(manager); manager.addTextContainer(container)
24 manager.ensureLayout(for: container)
25 var lines: [String] = []
26 var heights: [CGFloat] = []
27 manager.enumerateLineFragments(forGlyphRange: NSRange(location: 0, length: manager.numberOfGlyphs)) { rect, _, _, range, _ in
28 let chars = manager.characterRange(forGlyphRange: range, actualGlyphRange: nil)
29 let line = (storage.string as NSString).substring(with: chars).trimmingCharacters(in: .whitespacesAndNewlines)
30 if !line.isEmpty { lines.append(line); heights.append(rect.height) }
31 }
32 XCTAssertEqual(heights[2], 16.8, accuracy: 0.01)
33 XCTAssertEqual(heights[3], 16.8, accuracy: 0.01)
34 XCTAssertEqual(lines, Self.browserLines)
35 }
36 private static let browserLines: [String] = [
37 "A shared document with consistent typography on",
38 "every screen",
39 "This is a synthetic layout fixture for the native and browser editors. The same",
40 "bundled font, page width and paragraph styles must produce the same line",
41 "breaks, including a long sentence that wraps across several lines.",
42 "The quick brown fox jumps over the lazy dog. A small change in font metrics can move",
43 "the final word onto another line, so this paragraph deliberately includes enough words to",
44 "exercise wrapping at a fixed document width."
45]
46}
47#endif
48