import Foundation import Testing @testable import DocsKit #if os(macOS) import AppKit #else import UIKit #endif @Test func letterGeometryAndNarrowReflow() { let desktop = DocsPageGeometry(viewportWidth: 800, paged: true) #expect(desktop.paperWidth == 612) #expect(desktop.textWidth == 468) #expect(desktop.bodyHeight == 648) let phone = DocsPageGeometry(viewportWidth: 320, paged: true) #expect(phone.textWidth >= 256) let crossing = desktop.lineRect(CGRect(x: 0, y: 710, width: 800, height: 20)) #expect(crossing.minY == 888) let continuous = DocsPageGeometry(viewportWidth: 800, paged: false) #expect(continuous.lineRect(CGRect(x: 0, y: 710, width: 800, height: 20)).minY == 710) } @MainActor @Test func nativePaginationMovesGlyphsWithoutChangingTextOffsets() { let source = String(repeating: "Wrapped text العربية 日本語 🧪 preserves offsets. ", count: 100) + "\n" + String(repeating: "Native paging preserves every character and edit offset.\n", count: 100) let storage = NSTextStorage(string: source) #if os(macOS) storage.addAttribute(.font, value: NSFont.systemFont(ofSize: 12), range: NSRange(location: 0, length: storage.length)) #else storage.addAttribute(.font, value: UIFont.systemFont(ofSize: 12), range: NSRange(location: 0, length: storage.length)) #endif let manager = NSLayoutManager() let container = DocsPageTextContainer(size: CGSize(width: 800, height: 1_000_000)) container.lineFragmentPadding = 0 container.geometry = DocsPageGeometry(viewportWidth: 800, paged: true) storage.addLayoutManager(manager) manager.addTextContainer(container) manager.ensureLayout(for: container) var secondPageGlyph: Int? manager.enumerateLineFragments(forGlyphRange: NSRange(location: 0, length: manager.numberOfGlyphs)) { rect, _, _, glyphs, _ in let page = container.geometry.page(at: rect.minY) let top = CGFloat(page) * container.geometry.stride + DocsPageGeometry.verticalMargin #expect(rect.minY >= top) #expect(rect.maxY <= top + container.geometry.bodyHeight + 0.1) #expect(rect.minX >= container.geometry.textX) #expect(rect.maxX <= container.geometry.textX + container.geometry.textWidth + 0.1) if page > 0 && secondPageGlyph == nil { secondPageGlyph = glyphs.location } } #expect(secondPageGlyph != nil) #expect(storage.string == source) let location = manager.characterIndexForGlyph(at: secondPageGlyph ?? 0) #expect(location > 0 && location < source.utf16.count) storage.replaceCharacters(in: NSRange(location: location, length: 0), with: "🧪") #expect((storage.string as NSString).substring(with: NSRange(location: location, length: 2)) == "🧪") container.geometry.paged = false manager.ensureLayout(for: container) #expect(storage.length == source.utf16.count + 2) }