From 65d51d93c1f2500b4b8484c96ffbdabb7678b909 Mon Sep 17 00:00:00 2001 From: Ivan Sapozhnik Date: Mon, 23 Feb 2026 21:06:03 +0100 Subject: [PATCH 1/7] initial fix --- .../AppKit/DiffTextLayoutMetrics.swift | 4 +- .../TextDiff/AppKit/DiffTokenLayouter.swift | 2 +- Sources/TextDiff/TextDiffView.swift | 64 +++++++++++++++---- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/Sources/TextDiff/AppKit/DiffTextLayoutMetrics.swift b/Sources/TextDiff/AppKit/DiffTextLayoutMetrics.swift index b73b532..fe2ab50 100644 --- a/Sources/TextDiff/AppKit/DiffTextLayoutMetrics.swift +++ b/Sources/TextDiff/AppKit/DiffTextLayoutMetrics.swift @@ -2,11 +2,11 @@ import AppKit enum DiffTextLayoutMetrics { static func verticalTextInset(for style: TextDiffStyle) -> CGFloat { - ceil(max(2, style.chipInsets.top + 2, style.chipInsets.bottom + 2)) + ceil(max(0, style.chipInsets.top, style.chipInsets.bottom)) } static func lineHeight(for style: TextDiffStyle) -> CGFloat { - let textHeight = ceil(style.font.ascender - style.font.descender + style.font.leading) + let textHeight = style.font.ascender - style.font.descender + style.font.leading let chipHeight = textHeight + style.chipInsets.top + style.chipInsets.bottom return ceil(chipHeight + max(0, style.lineSpacing)) } diff --git a/Sources/TextDiff/AppKit/DiffTokenLayouter.swift b/Sources/TextDiff/AppKit/DiffTokenLayouter.swift index a7f2676..101aaee 100644 --- a/Sources/TextDiff/AppKit/DiffTokenLayouter.swift +++ b/Sources/TextDiff/AppKit/DiffTokenLayouter.swift @@ -148,7 +148,7 @@ enum DiffTokenLayouter { private static func measuredTextSize(for text: String, font: NSFont) -> CGSize { let measured = (text as NSString).size(withAttributes: [.font: font]) - return CGSize(width: ceil(measured.width), height: ceil(measured.height)) + return CGSize(width: measured.width, height: measured.height) } private static func effectiveChipInsets(for style: TextDiffStyle) -> NSEdgeInsets { diff --git a/Sources/TextDiff/TextDiffView.swift b/Sources/TextDiff/TextDiffView.swift index ae188ae..d56d0d1 100644 --- a/Sources/TextDiff/TextDiffView.swift +++ b/Sources/TextDiff/TextDiffView.swift @@ -35,7 +35,7 @@ public struct TextDiffView: View { style: style, mode: mode ) - .accessibilityLabel("Text diff") + .accessibilityLabel("Text diff") } } @@ -49,6 +49,7 @@ public struct TextDiffView: View { } #Preview("TextDiffView") { + let font: NSFont = .systemFont(ofSize: 16, weight: .regular) let style = TextDiffStyle( additionsStyle: TextDiffChangeStyle( fillColor: .systemGreen.withAlphaComponent(0.28), @@ -62,7 +63,7 @@ public struct TextDiffView: View { strikethrough: true ), textColor: .labelColor, - font: .systemFont(ofSize: 16, weight: .regular), + font: font, chipCornerRadius: 3, chipInsets: NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0), interChipSpacing: 1, @@ -72,11 +73,11 @@ public struct TextDiffView: View { Text("Diff by characters") .bold() TextDiffView( - original: "Add a diff view! Looks good!", - updated: "Added a diff view. It looks good!", - style: style, - mode: .character - ) + original: "Add a diff view! Looks good!", + updated: "Added a diff view. It looks good!", + style: style, + mode: .character + ) HStack { Text("dog → fog:") TextDiffView( @@ -89,12 +90,12 @@ public struct TextDiffView: View { Divider() Text("Diff by words") .bold() - TextDiffView( - original: "Add a diff view! Looks good!", - updated: "Added a diff view. It looks good!", - style: style, - mode: .token - ) + TextDiffView( + original: "Add a diff view! Looks good!", + updated: "Added a diff view. It looks good!", + style: style, + mode: .token + ) HStack { Text("dog → fog:") TextDiffView( @@ -127,3 +128,40 @@ public struct TextDiffView: View { .padding() .frame(width: 320) } + +#Preview("Height diff") { + let font: NSFont = .systemFont(ofSize: 16, weight: .regular) + let style = TextDiffStyle( + additionsStyle: TextDiffChangeStyle( + fillColor: .systemGreen.withAlphaComponent(0.28), + strokeColor: .systemGreen.withAlphaComponent(0.75), + textColorOverride: .labelColor + ), + removalsStyle: TextDiffChangeStyle( + fillColor: .systemRed.withAlphaComponent(0.24), + strokeColor: .systemRed.withAlphaComponent(0.75), + textColorOverride: .secondaryLabelColor, + strikethrough: true + ), + textColor: .labelColor, + font: font, + chipCornerRadius: 3, + chipInsets: NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0), + interChipSpacing: 1, + lineSpacing: 0 + ) + ZStack(alignment: .topLeading) { + Text("Add ed a diff view. It looks good! Add ed a diff view. It looks good!") + .font(.system(size: 16, weight: .regular, design: nil)) + .foregroundStyle(.red.opacity(0.7)) + + TextDiffView( + original: "Add ed a diff view. It looks good! Add ed a diff view. It looks good!", + updated: "Add ed a diff view. It looks good! Add ed a diff view. It looks good!", + style: style, + mode: .character + ) + } + .padding() + .frame(width: 320) +} From 4ddfa2c3c00ae6c055b4f8206cbe4ffe636664d6 Mon Sep 17 00:00:00 2001 From: Ivan Sapozhnik Date: Mon, 23 Feb 2026 21:19:20 +0100 Subject: [PATCH 2/7] refactor: improve text measurement accuracy with line prefix Enhance `measuredTextSize` to include a `linePrefix` parameter, improving text measurement accuracy, especially for wrapping cases. Introduce `measuredIncrementalWidth` to calculate text width incrementally. These changes ensure that text layout calculations account for prefix widths, making soft-wrap decisions more precise. This update addresses inconsistencies in text dimension calculations when different font attributes are applied. --- .../TextDiff/AppKit/DiffTokenLayouter.swift | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/Sources/TextDiff/AppKit/DiffTokenLayouter.swift b/Sources/TextDiff/AppKit/DiffTokenLayouter.swift index 101aaee..d7dc436 100644 --- a/Sources/TextDiff/AppKit/DiffTokenLayouter.swift +++ b/Sources/TextDiff/AppKit/DiffTokenLayouter.swift @@ -37,12 +37,14 @@ enum DiffTokenLayouter { var maxUsedX = lineStartX var lineCount = 1 var lineHasContent = false + var lineText = "" var previousChangedLexical = false func moveToNewLine() { lineTop += lineHeight cursorX = lineStartX lineHasContent = false + lineText.removeAll(keepingCapacity: true) previousChangedLexical = false lineCount += 1 } @@ -65,7 +67,11 @@ enum DiffTokenLayouter { } let attributedText = attributedToken(for: segment, style: style) - let textSize = measuredTextSize(for: piece.text, font: style.font) + let textSize = measuredTextSize( + for: piece.text, + font: style.font, + linePrefix: lineText + ) let chipInsets = effectiveChipInsets(for: style) let runWidth = isChangedLexical ? textSize.width + chipInsets.left + chipInsets.right : textSize.width let requiredWidth = leadingGap + runWidth @@ -118,6 +124,7 @@ enum DiffTokenLayouter { cursorX += runWidth maxUsedX = max(maxUsedX, cursorX) lineHasContent = true + lineText.append(piece.text) previousChangedLexical = isChangedLexical } @@ -146,9 +153,28 @@ enum DiffTokenLayouter { return NSAttributedString(string: segment.text, attributes: attributes) } - private static func measuredTextSize(for text: String, font: NSFont) -> CGSize { + private static func measuredTextSize(for text: String, font: NSFont, linePrefix: String) -> CGSize { + let width = measuredIncrementalWidth( + for: text, + font: font, + linePrefix: linePrefix + ) let measured = (text as NSString).size(withAttributes: [.font: font]) - return CGSize(width: measured.width, height: measured.height) + return CGSize(width: width, height: measured.height) + } + + private static func measuredIncrementalWidth(for text: String, font: NSFont, linePrefix: String) -> CGFloat { + guard !text.isEmpty else { + return 0 + } + + guard !linePrefix.isEmpty else { + return (text as NSString).size(withAttributes: [.font: font]).width + } + + let prefixWidth = (linePrefix as NSString).size(withAttributes: [.font: font]).width + let combinedWidth = ((linePrefix + text) as NSString).size(withAttributes: [.font: font]).width + return max(0, combinedWidth - prefixWidth) } private static func effectiveChipInsets(for style: TextDiffStyle) -> NSEdgeInsets { From 3a1506321c47e84d9cbcf3010e752a948112f2a6 Mon Sep 17 00:00:00 2001 From: Ivan Sapozhnik Date: Mon, 23 Feb 2026 22:20:38 +0100 Subject: [PATCH 3/7] `feat: add performance test baselines for TextDiffTests` Add baseline Performance tests for `TextDiffTests` to measure the layout performance for different word counts. This helps in tracking performance regressions over time. The baselines are configured for 1000, 500, and 200 words tests and are set for a local Apple M1 environment to standardize performance metrics. --- ...BF20AB95-BD61-4DE5-BFD2-9B7DB182F4A1.plist | 42 +++++++++++++++++++ .../TextDiffTests.xcbaseline/Info.plist | 33 +++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 .swiftpm/xcode/xcshareddata/xcbaselines/TextDiffTests.xcbaseline/BF20AB95-BD61-4DE5-BFD2-9B7DB182F4A1.plist create mode 100644 .swiftpm/xcode/xcshareddata/xcbaselines/TextDiffTests.xcbaseline/Info.plist diff --git a/.swiftpm/xcode/xcshareddata/xcbaselines/TextDiffTests.xcbaseline/BF20AB95-BD61-4DE5-BFD2-9B7DB182F4A1.plist b/.swiftpm/xcode/xcshareddata/xcbaselines/TextDiffTests.xcbaseline/BF20AB95-BD61-4DE5-BFD2-9B7DB182F4A1.plist new file mode 100644 index 0000000..f9e14a8 --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcbaselines/TextDiffTests.xcbaseline/BF20AB95-BD61-4DE5-BFD2-9B7DB182F4A1.plist @@ -0,0 +1,42 @@ + + + + + classNames + + DiffLayouterPerformanceTests + + testLayoutPerformance1000Words() + + com.apple.dt.XCTMetric_Clock.time.monotonic + + baselineAverage + 0.058013 + baselineIntegrationDisplayName + Local Baseline + + + testLayoutPerformance200Words() + + com.apple.dt.XCTMetric_Clock.time.monotonic + + baselineAverage + 0.013204 + baselineIntegrationDisplayName + Local Baseline + + + testLayoutPerformance500Words() + + com.apple.dt.XCTMetric_Clock.time.monotonic + + baselineAverage + 0.027967 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/.swiftpm/xcode/xcshareddata/xcbaselines/TextDiffTests.xcbaseline/Info.plist b/.swiftpm/xcode/xcshareddata/xcbaselines/TextDiffTests.xcbaseline/Info.plist new file mode 100644 index 0000000..1a5d3e5 --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcbaselines/TextDiffTests.xcbaseline/Info.plist @@ -0,0 +1,33 @@ + + + + + runDestinationsByUUID + + BF20AB95-BD61-4DE5-BFD2-9B7DB182F4A1 + + localComputer + + busSpeedInMHz + 0 + cpuCount + 1 + cpuKind + Apple M1 + cpuSpeedInMHz + 0 + logicalCPUCoresPerPackage + 8 + modelCode + MacBookPro17,1 + physicalCPUCoresPerPackage + 8 + platformIdentifier + com.apple.platform.macosx + + targetArchitecture + arm64 + + + + From 915b24d8aed9727979bb3b984008eb867e079a63 Mon Sep 17 00:00:00 2001 From: Ivan Sapozhnik Date: Mon, 23 Feb 2026 22:21:02 +0100 Subject: [PATCH 4/7] refactor: optimize text measurement and layout Replace `measuredTextSize` with `measuredIncrementalTextWidth` to improve performance by calculating text width incrementally using an `NSMutableString`. This reduces redundant calculations and enhances efficiency in handling large text segments, particularly when soft-wrapping text. Additionally, store widths for reuse and keep track of combined line width to minimize repeated layout operations, resulting in smoother and faster text rendering. --- .../TextDiff/AppKit/DiffTokenLayouter.swift | 67 ++++++++++++------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/Sources/TextDiff/AppKit/DiffTokenLayouter.swift b/Sources/TextDiff/AppKit/DiffTokenLayouter.swift index d7dc436..a63290f 100644 --- a/Sources/TextDiff/AppKit/DiffTokenLayouter.swift +++ b/Sources/TextDiff/AppKit/DiffTokenLayouter.swift @@ -27,6 +27,7 @@ enum DiffTokenLayouter { contentInsets: NSEdgeInsets ) -> DiffLayout { let lineHeight = DiffTextLayoutMetrics.lineHeight(for: style) + let textHeight = ceil(style.font.ascender - style.font.descender + style.font.leading) let maxLineWidth = availableWidth > 0 ? availableWidth : .greatestFiniteMagnitude let lineStartX = contentInsets.left let maxLineX = lineStartX + maxLineWidth @@ -37,14 +38,16 @@ enum DiffTokenLayouter { var maxUsedX = lineStartX var lineCount = 1 var lineHasContent = false - var lineText = "" + let lineText = NSMutableString() + var lineTextWidth: CGFloat = 0 var previousChangedLexical = false func moveToNewLine() { lineTop += lineHeight cursorX = lineStartX lineHasContent = false - lineText.removeAll(keepingCapacity: true) + lineText.setString("") + lineTextWidth = 0 previousChangedLexical = false lineCount += 1 } @@ -67,13 +70,15 @@ enum DiffTokenLayouter { } let attributedText = attributedToken(for: segment, style: style) - let textSize = measuredTextSize( + var textMeasurement = measuredIncrementalTextWidth( for: piece.text, font: style.font, - linePrefix: lineText + lineText: lineText, + lineTextWidth: lineTextWidth ) + var textSize = CGSize(width: textMeasurement.textWidth, height: textHeight) let chipInsets = effectiveChipInsets(for: style) - let runWidth = isChangedLexical ? textSize.width + chipInsets.left + chipInsets.right : textSize.width + var runWidth = isChangedLexical ? textSize.width + chipInsets.left + chipInsets.right : textSize.width let requiredWidth = leadingGap + runWidth let wrapped = lineHasContent && cursorX + requiredWidth > maxLineX @@ -85,6 +90,15 @@ enum DiffTokenLayouter { if piece.tokenKind == .whitespace { continue } + + textMeasurement = measuredIncrementalTextWidth( + for: piece.text, + font: style.font, + lineText: lineText, + lineTextWidth: lineTextWidth + ) + textSize = CGSize(width: textMeasurement.textWidth, height: textHeight) + runWidth = isChangedLexical ? textSize.width + chipInsets.left + chipInsets.right : textSize.width } cursorX += leadingGap @@ -124,7 +138,7 @@ enum DiffTokenLayouter { cursorX += runWidth maxUsedX = max(maxUsedX, cursorX) lineHasContent = true - lineText.append(piece.text) + lineTextWidth = textMeasurement.combinedLineWidth previousChangedLexical = isChangedLexical } @@ -153,28 +167,26 @@ enum DiffTokenLayouter { return NSAttributedString(string: segment.text, attributes: attributes) } - private static func measuredTextSize(for text: String, font: NSFont, linePrefix: String) -> CGSize { - let width = measuredIncrementalWidth( - for: text, - font: font, - linePrefix: linePrefix - ) - let measured = (text as NSString).size(withAttributes: [.font: font]) - return CGSize(width: width, height: measured.height) - } - - private static func measuredIncrementalWidth(for text: String, font: NSFont, linePrefix: String) -> CGFloat { + private static func measuredIncrementalTextWidth( + for text: String, + font: NSFont, + lineText: NSMutableString, + lineTextWidth: CGFloat + ) -> IncrementalTextWidth { guard !text.isEmpty else { - return 0 - } - - guard !linePrefix.isEmpty else { - return (text as NSString).size(withAttributes: [.font: font]).width + return IncrementalTextWidth( + textWidth: 0, + combinedLineWidth: lineTextWidth + ) } - let prefixWidth = (linePrefix as NSString).size(withAttributes: [.font: font]).width - let combinedWidth = ((linePrefix + text) as NSString).size(withAttributes: [.font: font]).width - return max(0, combinedWidth - prefixWidth) + lineText.append(text) + let combinedWidth = lineText.size(withAttributes: [.font: font]).width + let textWidth = max(0, combinedWidth - lineTextWidth) + return IncrementalTextWidth( + textWidth: textWidth, + combinedLineWidth: combinedWidth + ) } private static func effectiveChipInsets(for style: TextDiffStyle) -> NSEdgeInsets { @@ -288,3 +300,8 @@ private struct LayoutPiece { let text: String let isLineBreak: Bool } + +private struct IncrementalTextWidth { + let textWidth: CGFloat + let combinedLineWidth: CGFloat +} From 9229e374354c45ff048effe1ae77fb2fd3d60444 Mon Sep 17 00:00:00 2001 From: Ivan Sapozhnik Date: Mon, 23 Feb 2026 22:21:21 +0100 Subject: [PATCH 5/7] refactor: update text size and punctuation in previews Increase text size from 16 to 32 in the "Height diff" preview to enhance readability. Change "!" to "." for consistent punctuation in the "Punctuation Replacement" preview. These changes improve the design aesthetics and maintain consistency in visual presentations. --- Sources/TextDiff/TextDiffView.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Sources/TextDiff/TextDiffView.swift b/Sources/TextDiff/TextDiffView.swift index d56d0d1..c1cabb7 100644 --- a/Sources/TextDiff/TextDiffView.swift +++ b/Sources/TextDiff/TextDiffView.swift @@ -130,7 +130,7 @@ public struct TextDiffView: View { } #Preview("Height diff") { - let font: NSFont = .systemFont(ofSize: 16, weight: .regular) + let font: NSFont = .systemFont(ofSize: 32, weight: .regular) let style = TextDiffStyle( additionsStyle: TextDiffChangeStyle( fillColor: .systemGreen.withAlphaComponent(0.28), @@ -152,16 +152,15 @@ public struct TextDiffView: View { ) ZStack(alignment: .topLeading) { Text("Add ed a diff view. It looks good! Add ed a diff view. It looks good!") - .font(.system(size: 16, weight: .regular, design: nil)) + .font(.system(size: 32, weight: .regular, design: nil)) .foregroundStyle(.red.opacity(0.7)) TextDiffView( - original: "Add ed a diff view. It looks good! Add ed a diff view. It looks good!", + original: "Add ed a diff view. It looks good! Add ed a diff view. It looks good.", updated: "Add ed a diff view. It looks good! Add ed a diff view. It looks good!", style: style, mode: .character ) } .padding() - .frame(width: 320) } From 6ad1c5b1976b6bb5c442aec857032fbb73eea1f4 Mon Sep 17 00:00:00 2001 From: Ivan Sapozhnik Date: Mon, 23 Feb 2026 22:21:47 +0100 Subject: [PATCH 6/7] test: add performance and improve snapshot testing Add `DiffLayouterPerformanceTests.swift` to test text layout performance with varying word counts. Convert existing snapshot tests to use XCTest, enhancing compatibility and extendability. Introduce snapshot artifacts directory configuration to manage artifacts. Update tests to specify the snapshot test name explicitly. Modify `verticalInsetIsNonNegativeAndMonotonic` test to ensure non-negativity and check monotonicity of vertical insets, improving test rigor. --- .gitignore | 1 + .../DiffLayouterPerformanceTests.swift | 62 ++++++++++++++++ .../NSTextDiffSnapshotTests.swift | 47 +++++++----- Tests/TextDiffTests/SnapshotTestSupport.swift | 70 +++++++++++------- Tests/TextDiffTests/TextDiffEngineTests.swift | 21 ++++-- .../TextDiffTests/TextDiffSnapshotTests.swift | 61 ++++++++------- .../character_suffix_refinement.1.png | Bin 3217 -> 3218 bytes .../custom_style_spacing_strikethrough.1.png | Bin 8339 -> 9222 bytes .../multiline_insertion_wrap.1.png | Bin 4414 -> 4413 bytes .../punctuation_replacement.1.png | Bin 2698 -> 2659 bytes .../token_basic_replacement.1.png | Bin 6295 -> 6130 bytes .../character_suffix_refinement.1.png | Bin 3217 -> 3218 bytes .../custom_style_spacing_strikethrough.1.png | Bin 8339 -> 9222 bytes .../multiline_insertion_wrap.1.png | Bin 4414 -> 4413 bytes .../narrow_width_wrapping.1.png | Bin 8501 -> 9142 bytes .../punctuation_replacement.1.png | Bin 2698 -> 2659 bytes .../token_basic_replacement.1.png | Bin 6295 -> 6130 bytes .../whitespace_only_layout_change.1.png | Bin 2551 -> 2543 bytes 18 files changed, 186 insertions(+), 76 deletions(-) create mode 100644 Tests/TextDiffTests/DiffLayouterPerformanceTests.swift diff --git a/.gitignore b/.gitignore index 0023a53..23038c8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ DerivedData/ .swiftpm/configuration/registries.json .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata .netrc +.snapshot-artifacts/ diff --git a/Tests/TextDiffTests/DiffLayouterPerformanceTests.swift b/Tests/TextDiffTests/DiffLayouterPerformanceTests.swift new file mode 100644 index 0000000..a8598de --- /dev/null +++ b/Tests/TextDiffTests/DiffLayouterPerformanceTests.swift @@ -0,0 +1,62 @@ +import AppKit +import XCTest +@testable import TextDiff + +// swift test --filter DiffLayouterPerformanceTests 2>&1 | xcsift + +final class DiffLayouterPerformanceTests: XCTestCase { + func testLayoutPerformance200Words() { + runLayoutPerformanceTest(wordCount: 200) + } + + func testLayoutPerformance500Words() { + runLayoutPerformanceTest(wordCount: 500) + } + + func testLayoutPerformance1000Words() { + runLayoutPerformanceTest(wordCount: 1000) + } + + private func runLayoutPerformanceTest(wordCount: Int) { + let style = TextDiffStyle.default + let verticalInset = DiffTextLayoutMetrics.verticalTextInset(for: style) + let contentInsets = NSEdgeInsets(top: verticalInset, left: 0, bottom: verticalInset, right: 0) + let availableWidth: CGFloat = 520 + + let original = Self.largeText(wordCount: wordCount) + let updated = Self.replacingLastWord(in: original) + let segments = TextDiffEngine.diff(original: original, updated: updated, mode: .character) + + measure(metrics: [XCTClockMetric()]) { + let layout = DiffTokenLayouter.layout( + segments: segments, + style: style, + availableWidth: availableWidth, + contentInsets: contentInsets + ) + XCTAssertFalse(layout.runs.isEmpty) + } + } + + private static func largeText(wordCount: Int) -> String { + let vocabulary = [ + "alpha", "beta", "gamma", "delta", "epsilon", "theta", "lambda", "sigma", + "swift", "layout", "render", "token", "word", "segment", "measure", "width" + ] + var words: [String] = [] + words.reserveCapacity(wordCount) + + for index in 0.. String { + guard let lastSpace = text.lastIndex(of: " ") else { + return "changed" + } + return String(text[..= 0) + + var largerTop = base + largerTop.chipInsets = NSEdgeInsets(top: 6, left: 2, bottom: 0, right: 2) + let largerTopInset = DiffTextLayoutMetrics.verticalTextInset(for: largerTop) + #expect(largerTopInset >= baseInset) + + var largerBottom = base + largerBottom.chipInsets = NSEdgeInsets(top: 0, left: 2, bottom: 7, right: 2) + let largerBottomInset = DiffTextLayoutMetrics.verticalTextInset(for: largerBottom) + #expect(largerBottomInset >= baseInset) } @Test diff --git a/Tests/TextDiffTests/TextDiffSnapshotTests.swift b/Tests/TextDiffTests/TextDiffSnapshotTests.swift index dbdbc54..5f5a7de 100644 --- a/Tests/TextDiffTests/TextDiffSnapshotTests.swift +++ b/Tests/TextDiffTests/TextDiffSnapshotTests.swift @@ -1,73 +1,83 @@ import AppKit import SnapshotTesting -import Testing import TextDiff +import XCTest -@Suite(.snapshots(record: .missing)) -@MainActor -struct TextDiffSnapshotTests { - @Test - func token_basic_replacement() { +final class TextDiffSnapshotTests: XCTestCase { + override func invokeTest() { + withSnapshotTesting(record: .missing) { + super.invokeTest() + } + } + + @MainActor + func testTokenBasicReplacement() { assertTextDiffSnapshot( original: "Apply old value in this sentence.", updated: "Apply new value in this sentence.", mode: .token, - size: CGSize(width: 500, height: 120) + size: CGSize(width: 500, height: 120), + testName: "token_basic_replacement()" ) } - @Test - func character_suffix_refinement() { + @MainActor + func testCharacterSuffixRefinement() { assertTextDiffSnapshot( original: "Add a diff", updated: "Added a diff", mode: .character, - size: CGSize(width: 320, height: 110) + size: CGSize(width: 320, height: 110), + testName: "character_suffix_refinement()" ) } - @Test - func punctuation_replacement() { + @MainActor + func testPunctuationReplacement() { assertTextDiffSnapshot( original: "Wait!", updated: "Wait.", mode: .token, - size: CGSize(width: 320, height: 100) + size: CGSize(width: 320, height: 100), + testName: "punctuation_replacement()" ) } - @Test - func whitespace_only_layout_change() { + @MainActor + func testWhitespaceOnlyLayoutChange() { assertTextDiffSnapshot( original: "Hello world", updated: "Hello world\n", mode: .token, - size: CGSize(width: 340, height: 110) + size: CGSize(width: 340, height: 110), + testName: "whitespace_only_layout_change()" ) } - @Test - func multiline_insertion_wrap() { + @MainActor + func testMultilineInsertionWrap() { assertTextDiffSnapshot( original: "line1\nline2", updated: "line1\nlineX\nline2", mode: .token, - size: CGSize(width: 300, height: 150) + size: CGSize(width: 300, height: 150), + testName: "multiline_insertion_wrap()" ) } - @Test - func narrow_width_wrapping() { + @MainActor + func testNarrowWidthWrapping() { assertTextDiffSnapshot( original: sampleOriginalSentence, updated: sampleUpdatedSentence, mode: .token, - size: CGSize(width: 220, height: 180) + size: CGSize(width: 220, height: 180), + testName: "narrow_width_wrapping()" ) } - @Test - func custom_style_spacing_strikethrough() { + @MainActor + func testCustomStyleSpacingStrikethrough() { var style = TextDiffStyle.default style.removalsStyle.strikethrough = true style.interChipSpacing = 1 @@ -77,7 +87,8 @@ struct TextDiffSnapshotTests { updated: sampleUpdatedSentence, mode: .character, style: style, - size: CGSize(width: 300, height: 180) + size: CGSize(width: 300, height: 180), + testName: "custom_style_spacing_strikethrough()" ) } diff --git a/Tests/TextDiffTests/__Snapshots__/NSTextDiffSnapshotTests/character_suffix_refinement.1.png b/Tests/TextDiffTests/__Snapshots__/NSTextDiffSnapshotTests/character_suffix_refinement.1.png index 2589385780cf5365f33d1a3ae57154780a7fc481..403187648a2e2732664c1e8a0b837129e183605a 100644 GIT binary patch literal 3218 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 diff --git a/Tests/TextDiffTests/__Snapshots__/NSTextDiffSnapshotTests/custom_style_spacing_strikethrough.1.png b/Tests/TextDiffTests/__Snapshots__/NSTextDiffSnapshotTests/custom_style_spacing_strikethrough.1.png index dc0b727b52fe456e215a51d4b7119003c1c2c88b..dd5178d565919ffb15d1b1a7f68ec5c575f30663 100644 GIT binary patch literal 9222 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 literal 8339 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 diff --git a/Tests/TextDiffTests/__Snapshots__/NSTextDiffSnapshotTests/multiline_insertion_wrap.1.png b/Tests/TextDiffTests/__Snapshots__/NSTextDiffSnapshotTests/multiline_insertion_wrap.1.png index 3006387a4a1aea0004dce1cd227a3f0814fa4fcf..fd100898a357ddeabeddca90898dad3ca346b7a8 100644 GIT binary patch literal 4413 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 XTFrw@=ghbKxyCTMWu{-Q>lE=n(!C#P literal 4414 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 Fe*h`mr_lfa diff --git a/Tests/TextDiffTests/__Snapshots__/NSTextDiffSnapshotTests/punctuation_replacement.1.png b/Tests/TextDiffTests/__Snapshots__/NSTextDiffSnapshotTests/punctuation_replacement.1.png index 8b47edaeff898401a7f46454195f45f56a1d412d..90d69851f55bbfccc2b02af158227451c90dd5c4 100644 GIT binary patch literal 2659 zcmeHJ{X5fpAO9L^C%LKJ!!WFjJewtr%{X&i_xUUC^TYe|e!U;A_v`w+uJ`r1J}FnPILaSVIRpTJ zyt9+NI{-+*Bsd6sKynHu7HuU?3g_;40igD)ElL8*Ti(vMU0ne^2?hgFkI;b3ev8CZ zBnAMWm!Q8hQm~iOe`6qMzes-)Py+zpjXT?)_qZpuIvJnlx~<;DXS8g<#s`s?e=90J z=f)*hF;CSw7@p=2C{&-)K9T(dj&e0!)qJddOngyOJH&*Y{_}u4ImNronRc8_IGx%@ zG#cfG^qIUpe9neb8VwQjKih^Vw~BVV8*q%DIOhZ+p-%A&9HY^~O;!HvQ5cY9px|^n zkWrfkfWRG~#=ibfT)Cn8>Y+M)_c`ohxAd@mhR6Do;l@-`@tdJ4EEf_Qiut;xOJYqw ziH@pn@*Oc7L09XPPGrQaA}5=iawb|TC+#;dcB>9FKuV^l09JCn5L9fdBVL*x%4^k& zTGo*DEBKJkX+EuPZ4iI&vTzXb3#)0V8soE>$#(pjUJo5PQB(NkcnrF(?p4ZLesaAp zM^QGA{FJaqzH4w*8LX9+3+mGacvCqEJJRS`R@rpCs)aHy*V%%)ye^FQxbnSwu<13d!lg$h+07+rToFIyd=)GOB zvdFLD4jE$LofYX9FXwXUlIhJ3u)MO#N$#nxOifn48ODU#+wl4p{*v`er=_c;Hl0va z@cT6DbO_vHZ!B9&T1w`3FRk%vAB#fUcq>RnWu+Sui7f1VelB>Jf+%j9Pv5>Z_Bs&N zn$RK?@QNdG>|it+-5I5EosA+zj=VxnyorvO+Ni^@UPbe!qZqwC zJ+*P$cc+@7TqN?z=X4GJAb~a?N#36L5scz+KLrIDD^z?4QnZOIp;r%auvLfv^ zuZ<(89N~;28?)#&-*go-z3EJGxE(E+kq}gMAVCML+7_q?0^gIFfwrZqT6ESy;-HQh zX%EiW*#&%Kw!}swJv}=eNq;^%;#K8YZAw`2US>t69Nd7hTJwIYD0d#smfs3JSyV6DV9rtAz*3vJBNMRZaqObUXPEU!A;hzs6a z8qv2!(U_l-qz{H}eD1S~oUvDXOn8%8*l#PyK13hp;`ScwNXZ<14@nBj)UcU>wn*qP z>mS=ytnd{X>ei4}RvvMW*ORNSVnf8obp$K9u3V~7SEpwMwg(Fo;7TDs?DNwUoF+s> z!Y_aPyDP(TXCdhB&O<-Omz7Pst6-06^nfM>$}uBhey!^0D+letjt{He3l7 zHiis{)x5)^`th?r&AdzH%0c-(dtxtte=2UifAQ_Zh2+m6V-5MxWN&mly0tJR!f?_O<*5QL;AiInZ<9~^k60ZBA> zr?e4ztkFX!4X^)hf35s-3QPWnGcbZ_o{GNbuLBK{TvOcV5BCOlwl}!*`d-w_*zfI7 z6%%f={e{+CM4Dtnxxa0q5uqi_0BiaBE+QPOjVcao-tD|IH#d*I)BR_H2Kyv&@!Rto z2SDJU8dwhfaQhmEHb9FNti*a~%EOKXM&XGV$|yf!rQnA7(@Pv7K}app@7kmv++uSU zR$~G@kiBXx{%0(!N5j|Z^%;l^T(t4hLSg1tCY3|FtH?M8({hm+${{Cp`oJ|^XzMio zUUKm&)YzEE6yq0#>rT9_gY`>%H;!x;2`(^%C{#3vQk$l-Psam_}=r>A#T-bc*0 zat4)90tCBAR`TxHfLsr?&G+1Fw}M*58;Pp$TUlSbDHhi$;;DkY>}is56HXK{G`X#p zQ1+wH{25uVrO82w=jVyU3iHSlwksl_#xsER^oyU~hvk=itRrPL|9@kxWD`ypc$G%n zpZ@Y@0Yfe6VsFMl@dcntCguntk6o7;;JKtq-t%>XJW}I;#TRa;+TCw+F&x+dt(SeC zeFsf!>peLTcO@y{l$pOi2rP2~1{^q>ZkhyuG^9WSrEvLwa{p-X|Fs86dm! Sz1Q|Xd(IA5?5P)S-2V#}ghrD9 literal 2698 zcmeHJ`9IX#AO6fV)il0plr76OB}+GBscr*t*jX_fPo#c7J%E^PKZO=kJZjkg^U`H&b1<@f+x~DtpH)=)>uNp9ZqkQm9@h1 zk6}jUG(E#J9=~FX^9>DJP43vlGEq&FJ^|75CLwcq3>{SPpvjd*zgq`kU??K%Cis!c z$q?uLAPC$J0!44xqJgA5IRtQ-He+%L0)KtQc4*bHQhYN;>|R0fJl$gTC|65#B-^H4 zZ{UfZoUCTqg21|%_+$Pqp<=5(?8#Q?7omS_zjkr`Mr~L`KMpB4W}AFx#ilrt5ZkA?_icP`0(`N^^*&a1DV5GOnUo1 zo4C#4ZpPz~LLASl`axRSJ()m)qS!2ySfnvO$Vw1jsQ3_)iqYmS&*xn8>N%i;e`RL@ zB#p_gGPgaisIdRa$Y*{3%4pGDThX80EH4W0bN*!|fLxq-Dg;q6+nA6xg!X%nL5d;r^zE~stPG0Bx4;hPIXHHN<>#;{l z5F~UYET}hAwaUHBx%Am)inKD7xVbihS8X-9wiYw+(7-ZV)9Lj1-^@}6ZqwxuKJ9ag zE!VKUUVj{^rY@Qr-};S*8q=;*{w0*P!BrFTRe7jcoBk@ZRVff8z8)Pcoa$_joyA0F z4h#&0;h@F`{T|G)YQsOj{u8M;`EBL?VRvc>~<|~9|$sW8gVRs3CAh_>kX$NBzyAf;M3u!C$8KpsGk*yM3|=N z(s&WSG(*|Al1e>mWJX*Sp097;Y&h3>BZ$X;UqzT1MVckZKl>W)F5#4H7(R*{t@g1u zTc&STV;U<5{8TqMdr8Rl6YLDSj6~@a=pprv&Gi+nK5yYbp2@LYU0q$LIE<_VmP@M( zpMsW*3H-A;_wVE8#+pp8E|z4fp(q*-4-WNl8?Dxx5>_JlU-u~Lqvhn}-rSn5&R7-9 z8|xxF`v74^KU)R_@zcwK6l8p+{N8lW(Ipq@OKweA37hIjQZi4BJBn$T7QVRjDMmPD zfo)4P*=3b5)
$6#(e_eI^`V+kZZ`!#F7X$KTTXnP|EZ|#)o?lXW0j4qo)lT_fZ*#tA?X%8~6fka|kMCD6~MmXB2t2+)1wy7#l~KEX#*tvqA{dIGTN(xA|^&h%ac4Yd3nn*sCR8a>mnnTd^wJCD!F$ z;84}c{+=KozbtrGQ!;4;Os3QtIELcG#xab{8YXp5N&O1fD`bx)udzemw$il38eZcp zx?S^LBV4ONBpT{gvA0dcu9&nWj-IV@+4^qmv3u2GS<_FQgx(FMx+FV0H)~hF4EPXI zYDhKZ{2)Am!C+hTXN%9efx}&lSgJ-{1Qso^ z^3P;+E?D36-OIZrS|a8=QT;vffw?NphD~MB)OJlG4#UECrdXdj()E!nI&V_#&zfVQ zlxN(^x?{_o67cJVJNvq#y?gqL%9qW5_UlsM;64@kq0agY9*g!>dh3~LpRmlJ$Sq4( z^|EijJJm3iekRn?TZTKjomyHKL3l__-Yt0S|6`-AUy{x4acwE}62l?C!&arxxsJzS z5??AJ)gHd+BKsu|j_#-dK;LNLI7Kk@l{^9nlyXObp)VxQ&Umb}v_$%BFyvgsdA=)An*{LHKY%L-$tT=UU@PR0>5|!4K&XxDWw45y6w;ocGt*V035j;il$>N tyWwaA4FD8o^dBq2`2746+FLtYQBIw^@eh7>!HWO@ diff --git a/Tests/TextDiffTests/__Snapshots__/NSTextDiffSnapshotTests/token_basic_replacement.1.png b/Tests/TextDiffTests/__Snapshots__/NSTextDiffSnapshotTests/token_basic_replacement.1.png index 86ca2b50238d891685f49e6848ea85b551ed1aed..2cdec609af6ed4f629250b4ac8ca77f7c50ad235 100644 GIT binary patch literal 6130 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 diff --git a/Tests/TextDiffTests/__Snapshots__/TextDiffSnapshotTests/custom_style_spacing_strikethrough.1.png b/Tests/TextDiffTests/__Snapshots__/TextDiffSnapshotTests/custom_style_spacing_strikethrough.1.png index dc0b727b52fe456e215a51d4b7119003c1c2c88b..dd5178d565919ffb15d1b1a7f68ec5c575f30663 100644 GIT binary patch literal 9222 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 literal 8339 zcmeHMWl$Vlvqr-L!GcSIg^&ab?kp||77`XGxVr`xXYn9`1j0*j2*F`-TY?kZZE;%` zS=?E;``)Tsb?g4VKfkFuGtbPN?&));yQk+oG1{6cBt#5ESXfvjYO0DlSXkKH7+ec@ zgxT`~DGo6QY)>5(d8~>NCM4!W%vxW~MnePZH3kE)u%qm;@c!+BX$+W#g@u!Y^FLRx zxpQ#;2V>R#dviRDxflzJg-}gV?&D|dgG_>)k3HwTWMt%WNw44Xy$)k&dHztZ=6d!Y_R;4-}N! zac?hDn>-Ogw%aYXBSTrmbyG2FkPvcm910d~8aaAhMOGF(NQjCoq%al(WQ73HReA5f z6TQaZr*hi(IK+qy>Ej>sw#*qC84mR&Eq4yn0*=d_W$#35WY9yq6`&s6io7B{8r1hy z;b5dZ`0BRkAipVleo9HuDdtx1%Qu7cy5EyiB2HsH7sj4?M&+O-3+T8oX{ez`vz`ta z4ey(lRi>Jo^Wo;pH;yxlto5;sh3`!A|B)GX>UPsZJ+djv-cl_!Zd4{g}`pxl)UXXK0$jAHU4bnY)L{zxN0tV zS#;(X8&Wm*xS7+?nG!9K6d~lT0hz?2)A_XEj5&(aSa`HdebIAOc+miKnmSYym~mE< z>TO7+0m6Db{}Fgr8uXvo$>n5$Ls4^WmI~ByUn42moJqx zff~>BBfP9FQwH2B_nJSDFp697jw}>Y#p0PVkD?bZ99qGJf8)es>Xd0e=rG}wa+{-X zS03uo7w}P3%ONZ;Ykx%Yur?7`VPlzz3IJV&hY2~`%=8PV>O*+BgBsX22l?7-IkN*M zp84;vg7?ZBV*7I$(hA(QY^Iyb4Hz%&7oYpp3c(3mVManrGbMXxCcIkGSCGInRFrwc zj%#!3RoA~mU@|vx>%gC>bJPPLwq3>!mP7QMTMp_kGFI+-MOFe%^E}!v790|V|@rhX2G((;Ho@>;JcT9RNKgEz3z;#dG|Bh z4KTLGVYcl)n zxPH;&UCaH=Uhss#osO$az?IwW(qWLTZFb;A2|-79rQlKrTlD8?@Q+W*F>ZTP6(%ju z$uc;~E?0tAeyOKhs66v4h^OQ4)D++P7Uo)I)`27WaCdqTL2Fv|h=gG-H|m)~qRh>2 z5+<>+M~~@NTYNXAo#v{XmXjt_m;nS`_ma zFLsrLGui#-y$YW>^Qd`=y|NnP<|>6IO_^(}3`yULuPY9vx|YA0SK+mTVztMW=p!`L zW!8{K@SfV`4$bYk?^>_iHFUY@I&3pMBvel`@(R|=fNDJL8}gleVWWx2U9`)ByTX^Z zE;Cz}x8O5NQOufwr{8P#8El)2K56wkd7^)cyMQ%n7Em(4dpi-oWO^FauO37EeRB{( zN~gQ4ZqpyM;-S}!3mNmFH#pu$Q8~;>t#x&^K+HoFQ`1JE?X#M3f z*fwRouduE4WPod?+ENAXIV$ZumLoTR8sW6)G01b#&z?9p`zhEt!wDLLK28j-9TtHP z*@gxcX=eW89K{r{8cOiR@g5UY{tA(nwFtOt`%;?UM!aY}rKT7woS1C|c(+FOTyW%= zX^Pt4=@!*endvzqesAo3Z`A_P*Znwz@%%x(1uY=Db~OO0BXhMHUccl6zaH>g@}9jW zx|fb0B~Z}O zkLf0JPoeV1h%B(nd4DW-`ub}B93=_$vlIIXA|0M--(Ls%yqc< z8=181d~1jAAKKn>i_2_QeK?3pUxBX`G1(u?9+=JEqaDDT6>IkaO2MCBjpba+tVgp; zX$GVBJ{`o1E+74+ZB8Q-8_kl2`;Pi9``JFMzw8wS&zktobEFwtV1|%|z8(!0S$N9# zwG!sheF&*1BT&yq0a}fp1znj}TKby+3jB79iwrTZe1AxA)T=~)6V4n-I??Lq>H1v( zw9y-X3QyXP;moo#a<2QX^ zmn4?yA^@&TGOg)cPh>macKH*7SV$1RGF&`b-;CBd&Q=XZta#(@WBke4chNnn&KWN9 zv!u5{&=1CxahyBl8DC(@dFkT|no>uo_N=cdu*FT_9}!@2MI5fSm!mGKX;@shN$}GJ#4TCJR%iB-s|9`q(T>pEE!Eg+1(Sew zlo_2j%ZsdDw9-}SxWcY&Z0E}DZx7qsH8Mno+r3#OA)=zqx$a}Drv69{Ez{fy&eK6K z_*ad3xa>gdn^=l60k_B<&cKZm_c=@INtV+p^;x^AF<#h#fUEe$PEGzn!vPlfwotU( zw%zpN=CpDl(KEOen(WWbsZK%>F_B?HMCklBqxU{sUb<9o^toK}ZNTKF<#uCIu~n?S>C!Y#b$`*v zK5}-o8Dpnw|MW2jFM2B2tw^F8^G8q5XFpwfN7Soi>2D`WU;H4U7w9IH*kR%2Nxzz% zLSzS{=qaEKf;L}{%5x8tvYiF+CiTQNYdhgAY zKYFJtJCpQ;hObj(j)rB)cYc|YI8DfPe$lY3CRHQ-TQzTQfK;!@f`z3Ph;`5z>}+c( zbIrC7y3)um+WWFvl4B|;A9tiPXJ3@rTG;sx>ynUf2~=))eHw8mr}DR+5V=-F+MIu2 z)?seVO2^#j{qj@NsLbtqpk(HE>pJCTTy8Y1NBvBI$X3@Lkj2pNT5T&;*({D^d7 zFk{VAh^6Wc-S?_@vqMdrpC$yQ*}T}r(}vRaFbR>cQ>3rco0SBlo8-p*ExbvcgQiMr zBLNn!*?FK!Sr#%qX;PQ;a^>(yiZ$@_2x(^L*T*7ETE9q;Vl?&RDszuos+RnuYow0e z0^c2s^>}gQ-p`VljGZJ;dy7GQs>`YdT{+;ywtsk$kFICi@2$Ott3I-Fn+~1P>_kwp z?Ys=EtVP{i9v%iJHM+1=EVqIAid?hsFmJSh^QT0U*krVB)>JaEap4wL_r5Xk zV!qE5d?5VLfgSC!L$l3AV$$&2eWMqa%~%oo6)AwXCWZFKB0SkGt&ALQg<*$^>g*sq zDXbJ}@woV2iG>_fcDI7n|$i-~K1G4|1Gtxf6vB zA)tdkq<3YzNWcrycbX%dCZ#KXt=8PE9*m1T^jXWyzUOPVK9KbNErhT_N0INC;>%;% zHbcY~_*(V_fIp`DhjFc3jB~>h#&pRSIUnad_ipGSm29++j1M@B^(aIqJa!l#?sFhz z4p_b_n}9y5NMJ}3U@HC*AqL72aoz>~IQkQV(}IU0rw6c$@f4+8C{G zp%6uSov4Pm=UE>nzurYBC?_x>%Y_0y)Y9K|sLc|6AiFt3 zTBdypY7&)^7w^O!lSUtPk;SKxvu9vR)%MFkj(CE{PZmW2qO=-eR4d+Dffoh{L6;qs zh-7*lvDZwZ!@?#k=~>QzSQid<6)^*Pl;)EsUG-mfwXU4j&1|iqbS!@oPcl!#pHI4xDPvb#1+;ixb~I2!Zhzq?6D!h= zTtjJ>-NLmvtSDi~$TyjI(r=FB+SU$&_pAFNpZm-h*cznqn%s>^@?v{MoCjf&J_5*; z-7B5Z0)JV$>bEV?>Nb>5`SU~{k*^x*AQqWwDd;E~v z8W8dblbDZd!^=x2TW;k_wo5z z8dcdVz(pjZ%aJs#zxfvzi$#{!Z>#aE7s&aVB4ENaoiX0MtnmGmYVD&)^J++y3!QLI zb_Nqq$h`YeBM^amZ`G~xRr*Ed zJY(fQnNkItzN;Eqv_O;McOLmdsGxrcJ~z?gvj^xyy^s@ge)8_fWcK0+s+Xa&ekm2T zC`Tt}$604nRZ^LQGWwdb_Z!O87J}B}AHjYXMm|2Jl;}<4ZMn>#8|1QvJh)%D<4LRi zSttuJ@5gKWMy0C79Sv%(P3-G&%2Eono=(-)tJ-8p#LqCti45#q zE+JhPb=K%0Qfqw27p>_v1jKWz3tr(|t0%3=32vSt(Q&%C@)4EQ1ON24nSg72o(e44 z_7j!Xv+dszcOwh+)mEp=J8mx4f6m4Y6uVC@Dr!d4uUi!2ue|4lvhjS@ODpS-0)LDu zlYgckEc`3jC0W5Cd*gXuQ!>+b?vHP&t_{%VqCC1U#8R?-yIS*?hlFUF-HKi0id}S} z0ad(JR9S%nDOz%4l;I|N0CUj=~tShtuv*w<5_q2_~5`1 z$(aflMn~-y*j}b>b6mu7g3Ic+h{=Ov<}BZ|8R&-L91ymh}Q6sLZJoGb^ZYrFiRs8G8rtOFfyMA|SXorn>ei~1w zW}YyHwDo&XeHDI=;I_Ud{8u6uXLN(JdG+T|Kov^bgAe*%?~9PI^MlwoboJ zblm(6%N{fiUaPy9o+ISiyjo^_sJV58`9^F+JbNkh1K94*sl(oGw3&8zCo3qzy8mYU z$=eq@Ro%@+PF=3S{XVG0uB({0hD6gwH~t3?P>TL9Pg3c^3sD5WE{%iJoSTPjW-2^y zpCC+)eH3*!70w9Cc+`ejwL$l|TMKndaT;uRZ=?Uj3dbUe@BY+U+6v-iP(Z`83pQUx zos0LA!qH~gH&DUIh1@oRTe4JL9eu>X5iDvh=h^K7rbvM{)ubg_pYL~R!H>br&S0nd zmQ0V;n2R+@=I4BsU!CR0m^}JfmFcK0>?3yK)@<}`6v3*&_m}NMH5Aujo~%@)v(>}= z>pyAPSfT9ZayJ(Td-+BMm3@X%Lp-qKy-yDd1a}D92eq}nHO0DBzi6Kh3moo8w^tJp2scZXLDte>fwA{JK$LDUIvsqg^ z?qG=h-eU3>H}Rt%8pe4f45C&&i3;|ccr2F3L^Q^L&Rr?IDKci9a`!Clr-0Cl7$ZD) zeDe$x=kWnCMd!Zk8%1>vDdOrPn->-th#D3=_fi&4`ROOAn(iJAb^rV&*Jo2Du9PQ$nt4cbwNFlQh2#ceaO% z%fB6L6+dMxc>N(SV^Nfi9ZX1$^k+X~fA6m)G<*%MV=2W`*O6-dj zLgYEWD>45@3cP&C=EUK8lIn;jGL6`z;BSo0LnI4k>OKAroyv# z5_pZ&rww<`HSxbunwOmM zJ;qO9*f1>exP{~41@twD8U$E+Q&woTGwY@>p!^)v9G(O+^gkcqPJ?*knpZQZ2|(N= z0+ntTan*XM*wwW>n2AfE_^k3%eVZqS-#Bg6IlMl7-z)})&3f-PyXZC{TghM2g>DhX z5jBMx8Cb!LoI-oZlg2pi9Kwu5T{XA$se{)i|X zyMEE!vBkWb2j8@CQ$EK5544YXpL;A<_2>EVU*gPY5#VR7}#cZjucPwKD=UK-cI7+DGQ*1m~{Y@C8~)CJL0-B56W^BDhKfrMxbZmT-@6dU>^~C zA9k{((SKwH+jF)#Q*nuBX-gX1GGP%|fGI#&#XT^;;l1wRK(Ds-RRE3pQ4e zUT&vXB>kj~;Uo=LFPYY(Q$C@Ufr*XZk+KGgxE=$@)8glpza++}t*(6l`4VC0k%zC5 z?Qaojj&guh8e6$R%}fcu3CmZtp|}JKRpwn%az_5uQC_{&2Z&|5*>Ar~u^7#RMiB8t`BBYnLN(#AJ`y%GwF`ni4HC{cI`eD2HHnu-@ z$l&BJSpOxG7jDpzr{MTGh5^Aviu#?$rTb&~jA1LzuQOSNjOH-0g zC!O{%u>SZ~p_sC77I!ZKS2~0#DW)aWE$Kf(7Jb94p?0KD!J5bORc`4o z%LwUzo^idq^wCkvsDFZrmA!HW7Nxbm_9#qbaS7lUqb4hBb8eI&r>h<=1k0TL?Fk&D2vT;|23 z0Blxr5*)TNyN`uoL>M)lI#0=Qz*F$FTp**nfQNKT-L=sq+8Vba4l)RGr<+Uc+6(!fa|vnu- diff --git a/Tests/TextDiffTests/__Snapshots__/TextDiffSnapshotTests/multiline_insertion_wrap.1.png b/Tests/TextDiffTests/__Snapshots__/TextDiffSnapshotTests/multiline_insertion_wrap.1.png index 3006387a4a1aea0004dce1cd227a3f0814fa4fcf..fd100898a357ddeabeddca90898dad3ca346b7a8 100644 GIT binary patch literal 4413 zcmeI0`9GB1|Ho&>HpmtkR7kg!HQ^>pg!m9zWbDgeFeXbfV+)O?5+!A6>`RucBQw^q z6p;*)b?k22FxG5YhVRw)`}q6;-{0>a&UKyZobx!>>+wG4^?p3hiMeZL$i*ST0Rn-z zjQ*p49|Qu+0`+7lEAVu+CH(|m;K%n3bwTAl=azsEHKdi1o2e;C8mL1-;O8h1^PeF= z5djJa1j&Z{w*@Sl&Gg?oDEUvPXQWFv2*g`uq<`~4Ab52m)YoDsqhpij0{aEAF?+Pc3xcaqUzv$;i*(|I_4qYeH#Zf;Ce&@MaWQjCYcZfl2H%@r7-IJB zrH+(3Gp|mzC{%wS66wmvrvn1Z=s0c0KLtT{44$?WtA}3d4`5f-jg6vFBh6ZNtTfz^US0XCLtD_{&P@Y{^H#g4_0%Ccrredhf z7Iuyz1%Zm+m4RS6=>s3l)%|I2cGssW&d9(otE%o5yb4$zFw%Q=s_$aFreFW2iX!2| z2YngK@`1*^$rAU>pn^+ootl6K9CSpkbh_Tv-5vcS`{pP)sA{clF>`v_=5U;ZPFd*5 zC@C;aD-POPsNd?**jX;A7_vE3jsih2w&JBOR!d7u!L*#`x)mh!@FW4=Utro#uV^k$ zOcaomltfY9D~{G<=okzVi42~JhOIndJtdTFUFG(%sOa(o7YMrT1z+&tYRzC{$led% zU|t|v7kS}M82XTDm3wcsg3>(%B4@w0ysNXbuh^m_F)1nkig`g1FhQ!4dk+Rj^qtZ5 zqJFw{(eU*^TMR!bVBMiR{koE}n7MZ7f&bUGwy0-)kst_^nMEQ}%OW(DX(N)2r&_Ya zvZ4uziWQV2x^;`FpnkTk*>ImzyW0@3KJ+6;4;cndOinJ?ob5pWn(M@hR#sNp5S(!G z_VuoM(h?G-M`Yw-oDK;0Ob(D5efv#%`oq@m15$teb@|2(2e+;+|Al@#ZUpyAZ<=Z^ zx6I|scY}iJDAW#7t>6&^`2w&JYEBpRwOq3`Nz!<{p*dpT7(BR(T^qMvc$l|znxB8L zA;1Si`|&w!kqgYsTV$MVz*JKF%;YlOz6p@v@$-XG^}s`WywW?bvFb9<`|W>bgtxH5 z!@`=h)I`b0-|bS6)yX#14^ax@a`N(U2ZzjzY$EZ&VoyeY48PRMn&WV}eQR#q>(}s; zV+IM)%G%K2fdzMO63%O2M=V`kKbU1|3fHr)wDM>V%y*@be5P(_oM^1owwl4;x z>O=|0S)*Vd|OES>csBNSd0X=Xi|ZKqZ!xly2Acni@x+JF^A zadi1}Wo3hZTUMpP8X`!NW*SiCQ(y($;8mIxClDMju>6x^uScVLAe<*Buhn3Ii|+rn zLQ1N?qIkf}#d11M7HO~9`E;_YSyqr-`Dapg;9;r9ew%O19Ixkb*f&TwR>Ll(?@FZV z7g_WR8po{_iAlx5$G#2Cm>6&Y5n;l zDAa~AEZAa|l$*OAFQ0xl0y-8bg+QQBl62Y@j%qCKJLHOCgmR*ab}=_fDIBC2vT0}8 z;nJ8~u&3!{Gix<8NN~lHks};pfu<*#xP1svbOBC%C2z>H;T4xDbAJinwKHW%noDJH7&z-x5s_w3v|e3s`=Ld*fS z`H;A>C!@PVn&1~3k=DE?@*9kCO&j%2-35G~%pySn?|$zn_50-Kzg=-s5-E26$9i%Z zJk0yp6n3S_C8B9>1H|=Y8<+O_M4hQOORGZaK(icKmExe9c9D%6O`C`$ZD|KYJ!1@>>t-AT&oy2uR9PYkT50km;N@`a2pK}mJF3COCnQ~O&mXf z<4+9)h|)@AQYvWq*0=q`vrlk{PDk{yNgR+X&8MHW925`!Rts&uAHLI@^Qoi#MtSqe z5|7@LY3~>J#S-@{hl6ceq489cVNF1j{l#{zoSX65Ld7x-_X~y{j$o@3`#9s<@>Kh- zkDQt2cCqLHZ=rKV6LmXU`91dKDkwT}v*zrBH83)-JbY9c%3Pcq^Iwm0~B=xo~O z^R&Y^Djm{~bv?*SLEe3*?4_GNBo;0%PlfHVnI7&uR@KVHPUt_m3Bs|;Op~Jr>+R2m z?tMNMbe;8?B1@Xsm8dn=dgB|#;LSRW_s4lVec|g>9b`%)VUp+E^I+#M9*ow+O{{45 zY$_W0ouh#?Sh`OtTp-5!6c)Ofah$qiF*O%v9JVqVdDWYG`695yH#ybV;I$$Q)=*Xd zt)^Y}Rpb{b?L}h7k-rmXDNQ#)i_rYfJ`!t%xQUp?30Ur+7K|`-s@#A{`-$twaqsI4 zVn=0eZl3Ne4ba>!IZeJTB!7o;;v>mIPcwjriGL+=YH47XilSOJ<+kb%C!71CmhMoU zIL)>?v$&Ttx>2dhbQFGqqD`*8p!V_(Gp|P!WNJhZZjtPU?$UgdYd);c*l>68LIqjZ z{rdD6W1BXnJJl_pOFg5klAmJC#5OsVcwNY+AP?|&yOeLM;1IswJrSdMJ1acdOT~|A z7>Qqx-gjTwdmAgc+aQd+&MN`yu_sL3$@s=$+q*Kv@VYO?*xd73n$SK@q1-C!T9h4} zTR)-P2>e2!mF=9Aue>YVUOCDd+kYK&VCWeh!iJCB@rR24P-BruW0pVLXtVTBpCzpE z$wV~1IrFVEl2vOrJM#`B>6jRj712t0L5VZ*ny9^%a4*4FW4pYp>}Z-@LwsX*p6&jT zgfHtxKK?dwJ0*72Jcs`@zw-M0{>xXfq?y{Vd7D>RyZrc>f>>|CvMe_FkoSyt_)$iW zyrkB)mPYy%pAG9IuZIA{G*i2Y=-(q<-uk;cr;Bx>rV>AAAY6OOMR0D;!BZ`kRoDirhSwB)sLrKkkj z38or=fHW*1PAHy3`~`syNP;0H@(dL#K_E}x2YBf1^8_HHr7)*6(KlvV)x(e5L!1Wl zlbo%A?Tg?TsfyAFSQ|*VXsC-;^BlNLLhpTzyb^Konv#;r!;z~yt7De*p)yYH^3C2~ zzx*=P9_hx!#Jr5D!}^qp_(TayJk@FBCj_9?Fw2SD=hZ*FeR~?eVQg$%k8;BN9~@QA zHh)yHZ@`wp%WU#vVG6~l{(|7`K0}g6pG3&;PoHAbg;*dP>5KdB_1=X+%U`ZdG*~|Q z)hU&OAW;EC5gj{je|1)-CsWI|GGuS@gdWgneR;v_je7%ikKMKQ=iZ6jIEsBvOioHdE&a?7K4I)( zu53iQSE2E5-{uO+*^C5bTz_nkXBa>9UeRS`@0f8omI@Hf=sLg^Iw=&i2ci5zC3$lRd;GN=Cm5yo()u12WB^bQ7R>pn4yg4YF z>ZR=jZ3CkMi^L z)dSYj8wvg6g^lRpa>Nw_L&L80oiPF;lCqXdWl`>E#jcDX91{`})Uhk?wVc9-?E^kq zRyd3Tpq&v=<<{*FtoZXm?pr_#@@0AGB8Iz<^+ZZhtiMcC+gp&L*x{=xDi)6(J;I8*2~!@)Z*h1> zEomU!{Hx4ofUPZ_w)maN69qGq*?FxdX(%BuvmFam)>3g9==^uszXADohy4G%&~gH{ XTFrw@=ghbKxyCTMWu{-Q>lE=n(!C#P literal 4414 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 Fe*h`mr_lfa diff --git a/Tests/TextDiffTests/__Snapshots__/TextDiffSnapshotTests/narrow_width_wrapping.1.png b/Tests/TextDiffTests/__Snapshots__/TextDiffSnapshotTests/narrow_width_wrapping.1.png index 9c8a3673ee9a7e80d8cbd19cc1b18b632cb33fa3..626e00daf97fd4fd2a26f5d89b03f6a46b7df96d 100644 GIT binary patch literal 9142 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 Sz1Q|Xd(IA5?5P)S-2V#}ghrD9 literal 2698 zcmeHJ`9IX#AO6fV)il0plr76OB}+GBscr*t*jX_fPo#c7J%E^PKZO=kJZjkg^U`H&b1<@f+x~DtpH)=)>uNp9ZqkQm9@h1 zk6}jUG(E#J9=~FX^9>DJP43vlGEq&FJ^|75CLwcq3>{SPpvjd*zgq`kU??K%Cis!c z$q?uLAPC$J0!44xqJgA5IRtQ-He+%L0)KtQc4*bHQhYN;>|R0fJl$gTC|65#B-^H4 zZ{UfZoUCTqg21|%_+$Pqp<=5(?8#Q?7omS_zjkr`Mr~L`KMpB4W}AFx#ilrt5ZkA?_icP`0(`N^^*&a1DV5GOnUo1 zo4C#4ZpPz~LLASl`axRSJ()m)qS!2ySfnvO$Vw1jsQ3_)iqYmS&*xn8>N%i;e`RL@ zB#p_gGPgaisIdRa$Y*{3%4pGDThX80EH4W0bN*!|fLxq-Dg;q6+nA6xg!X%nL5d;r^zE~stPG0Bx4;hPIXHHN<>#;{l z5F~UYET}hAwaUHBx%Am)inKD7xVbihS8X-9wiYw+(7-ZV)9Lj1-^@}6ZqwxuKJ9ag zE!VKUUVj{^rY@Qr-};S*8q=;*{w0*P!BrFTRe7jcoBk@ZRVff8z8)Pcoa$_joyA0F z4h#&0;h@F`{T|G)YQsOj{u8M;`EBL?VRvc>~<|~9|$sW8gVRs3CAh_>kX$NBzyAf;M3u!C$8KpsGk*yM3|=N z(s&WSG(*|Al1e>mWJX*Sp097;Y&h3>BZ$X;UqzT1MVckZKl>W)F5#4H7(R*{t@g1u zTc&STV;U<5{8TqMdr8Rl6YLDSj6~@a=pprv&Gi+nK5yYbp2@LYU0q$LIE<_VmP@M( zpMsW*3H-A;_wVE8#+pp8E|z4fp(q*-4-WNl8?Dxx5>_JlU-u~Lqvhn}-rSn5&R7-9 z8|xxF`v74^KU)R_@zcwK6l8p+{N8lW(Ipq@OKweA37hIjQZi4BJBn$T7QVRjDMmPD zfo)4P*=3b5)
$6#(e_eI^`V+kZZ`!#F7X$KTTXnP|EZ|#)o?lXW0j4qo)lT_fZ*#tA?X%8~6fka|kMCD6~MmXB2t2+)1wy7#l~KEX#*tvqA{dIGTN(xA|^&h%ac4Yd3nn*sCR8a>mnnTd^wJCD!F$ z;84}c{+=KozbtrGQ!;4;Os3QtIELcG#xab{8YXp5N&O1fD`bx)udzemw$il38eZcp zx?S^LBV4ONBpT{gvA0dcu9&nWj-IV@+4^qmv3u2GS<_FQgx(FMx+FV0H)~hF4EPXI zYDhKZ{2)Am!C+hTXN%9efx}&lSgJ-{1Qso^ z^3P;+E?D36-OIZrS|a8=QT;vffw?NphD~MB)OJlG4#UECrdXdj()E!nI&V_#&zfVQ zlxN(^x?{_o67cJVJNvq#y?gqL%9qW5_UlsM;64@kq0agY9*g!>dh3~LpRmlJ$Sq4( z^|EijJJm3iekRn?TZTKjomyHKL3l__-Yt0S|6`-AUy{x4acwE}62l?C!&arxxsJzS z5??AJ)gHd+BKsu|j_#-dK;LNLI7Kk@l{^9nlyXObp)VxQ&Umb}v_$%BFyvgsdA=)An*{LHKY%L-$tT=UU@PR0>5|!4K&XxDWw45y6w;ocGt*V035j;il$>N tyWwaA4FD8o^dBq2`2746+FLtYQBIw^@eh7>!HWO@ diff --git a/Tests/TextDiffTests/__Snapshots__/TextDiffSnapshotTests/token_basic_replacement.1.png b/Tests/TextDiffTests/__Snapshots__/TextDiffSnapshotTests/token_basic_replacement.1.png index 86ca2b50238d891685f49e6848ea85b551ed1aed..2cdec609af6ed4f629250b4ac8ca77f7c50ad235 100644 GIT binary patch literal 6130 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 J&CWmE_%DMKN6Y{K literal 2551 zcmeH}`#;nBAHY9blSQ;dPA-w^A^IZaF3jyK%1BZsR<1GQ9Gm-X%LAPpa*9>1E9b1a zjEa%VHWkSZqZlT}=|VQ_;X1eR{rKVh6W_=A;q`vM-tX7@^?1B4@AvcZ{?!xZq9CUx z2LOPA>jft-0DyRddK7#wI3~bE9B_i*y<8lCTCTnfPFYuCwuP%$lSOu4V9|iwScYf4f;bFmA?nC z!ruOXNGl;NJG6PqSKX zA@_X`BuV=uulmwfEJ8TS1APy5J-jH}5v9E9YtNfvy_@320t|hzi!E82_Nexm6F+$X zw~;RVnAL_}b($0h({5&Kolm$~AKLpWfSJU9Y#bE1xjLtkQW2wtX^!cndXz`mBrTtD zSDzhguAfvez_7;5B1iIB@xnnpb=#EJsoPtY%psNtj=t#32<4W9J7(>7wQGu=Fweg{JD>DOKhm8VCidRnstJmZJ&~z3ufK)ZG6h1)ZFHQI1{(hS|#7vI& zYlv?9=Gnzkux{mOx0MHn*jhp&r<=O0u<2;ApJcbB{(S)0VgU@NqNPpehT*4jc) zO9Jo3EyrS$@CVGK6;7UprI+X3Sm9vz>fGl?aToE02Iz(hc(Qnc-P95*qEZC)VIG-` zmbkeH26h%3|XYw?yABewoKg6{YA?qoHvEW_3x9^*h_usr` z{Pftoc$9Hka>FJ56fq1t2CJ_bY0iX{i)eNB8GHGEJv%R~y;Ee0CG&mgXhzKD<*AIA z02Ay`Pmy_al$F)sOuAUWoLgJ?s)tZ%M9b0t#CeB)%w(#WMii_I?UMhqbj%1$izD|9 z%4kzmMp^kEwT$_L5y8`^Z_JOk5;!*m5;^H5JXIG}a>0eguUyTPSN)`y^z^gW&qr-j zEHq=Au)~JEPxMEqsL~>{tG5lL_LV))?9R8i3+=>;o*wQ+CY3!?Yl=|#)*EP|f5E4Z z*ix(5$nTuOxD_Ff@FooGTVveZ=nZVkW$CtbbM?o^isiETi#%*EDKuwZxjz|wO;RCj zPBV$Fa+cJlZLao`4gHHEZgW?+)|ZCZ={u2!67BRojr?1JlWGE(EsXGi_a>?(nop;$ zTvY8UvrR3E5C%Rd3yYTzw)VR0VUxUiNowf(s)Ims%i2(shr&A!o#K_0k!Ovum+R^! z1UY7!G|BH}VCKxTd-LxG>5e&v4LCkcSF3&aFN3;b>ZW^(AC=u#Gu0nINKrlh-``H* zH*6zEUNmsY27ZzK6#F4oYO-H_s5^QG%w#4oFA86DE)0dP%ikf)ju?--6wA=2vQ-2v zZ|hE$qrtaPKk(e+`HE>*jq_eUo>@!NO|4z`8;`GU)oIY$Pz?kb!5j8PAhq+6-57j| zjMT`J&`~)sF;6Y@02EmzI7YA}=HAnC3kPercOeIRs}%Rpd(a>^Ps<0C)hATY#Q zDyePCGo8KPZx_N}r z@?I;*$_aqzLZG~TMQ7pK2n-RKYxkaT7l5Lmu&P5QAz)xEfTWiG+YAB%D*;)pdz%CD zIRyeW-TrCd7!+;+QXAD@U=NViK+JC$QypQ5pOv&dODTF80CYhHKDZWiDI2amc>+nX nvcIzT-vIxu;Q!+tY-dA!AX&Z#)VXoHA23&ElvAz4%{%`C^> Date: Mon, 23 Feb 2026 22:51:12 +0100 Subject: [PATCH 7/7] todo comment --- Sources/TextDiff/AppKit/DiffTokenLayouter.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/TextDiff/AppKit/DiffTokenLayouter.swift b/Sources/TextDiff/AppKit/DiffTokenLayouter.swift index a63290f..75ed788 100644 --- a/Sources/TextDiff/AppKit/DiffTokenLayouter.swift +++ b/Sources/TextDiff/AppKit/DiffTokenLayouter.swift @@ -181,6 +181,8 @@ enum DiffTokenLayouter { } lineText.append(text) + // TODO: Fix this later + // This now appends each token to lineText and calls size(withAttributes:) on the entire accumulated line every iteration, which makes layout cost grow quadratically with line length. On long unwrapped diffs (hundreds/thousands of tokens), this is a significant regression from the prior per-token measurement approach and can noticeably slow rendering even though the new performance tests only capture baselines and do not enforce thresholds. let combinedWidth = lineText.size(withAttributes: [.font: font]).width let textWidth = max(0, combinedWidth - lineTextWidth) return IncrementalTextWidth(