Files
alexandrev-tibco f85c746af0 Rename to Kotej and add the app icon
"Cotejo" means nothing outside Spanish and is hard to pronounce elsewhere, so the
project is now Kotej: same root, but it reads and sounds the same in English and
Spanish. Renamed throughout — engine, targets, bundle ids and the URL scheme,
which is now kotej://compare.

Icon generated with Codex: two facing panels split by a seam, content lines on
each side and one amber line marking a difference — the tool's job at a glance,
still legible at 16pt.

34 tests still green; kotej:// verified end to end against the demo JARs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UfhDYRLTpGJSKGP1m3LVJN
2026-07-27 17:24:05 +02:00

82 lines
3.3 KiB
Swift

import XCTest
@testable import KotejEngine
final class TextDiffTests: XCTestCase {
func testIdenticalTextIsAllEqual() {
let rows = TextDiff.rows(left: "uno\ndos\ntres", right: "uno\ndos\ntres")
XCTAssertEqual(rows.count, 3)
XCTAssertTrue(rows.allSatisfy { $0.kind == .equal })
XCTAssertEqual(rows[1].leftNumber, 2)
XCTAssertEqual(rows[1].rightNumber, 2)
}
func testChangedLinePairsUpInsteadOfDeletePlusInsert() {
let rows = TextDiff.rows(left: "uno\ndos\ntres", right: "uno\nDOS\ntres")
XCTAssertEqual(rows.count, 3)
XCTAssertEqual(rows[1].kind, .changed)
XCTAssertEqual(rows[1].left, "dos")
XCTAssertEqual(rows[1].right, "DOS")
// The unchanged lines keep their numbering on both sides.
XCTAssertEqual(rows[2].leftNumber, 3)
XCTAssertEqual(rows[2].rightNumber, 3)
}
func testInsertionShiftsRightNumbering() {
let rows = TextDiff.rows(left: "a\nc", right: "a\nb\nc")
XCTAssertEqual(rows.map(\.kind), [.equal, .added, .equal])
let added = rows[1]
XCTAssertNil(added.leftNumber)
XCTAssertEqual(added.rightNumber, 2)
XCTAssertEqual(added.right, "b")
XCTAssertEqual(rows[2].leftNumber, 2)
XCTAssertEqual(rows[2].rightNumber, 3)
}
func testDeletionIsReported() {
let rows = TextDiff.rows(left: "a\nb\nc", right: "a\nc")
XCTAssertEqual(rows.map(\.kind), [.equal, .removed, .equal])
XCTAssertEqual(rows[1].left, "b")
XCTAssertNil(rows[1].rightNumber)
}
func testUnrelatedTextsAreFullyChanged() {
let rows = TextDiff.rows(left: "uno\ndos", right: "tres\ncuatro")
XCTAssertTrue(rows.allSatisfy { $0.kind == .changed })
XCTAssertEqual(rows.count, 2)
}
func testHugeFileWithOneChangeStaysCheap() {
// The common prefix/suffix trim means only the changed middle is aligned,
// so this must not fall back to the block path despite the size.
let common = (0..<20_000).map { "line \($0)" }
var modified = common
modified[10_000] = "line 10000 CHANGED"
let rows = TextDiff.rows(left: common.joined(separator: "\n"),
right: modified.joined(separator: "\n"))
XCTAssertEqual(rows.count, 20_000)
let changed = rows.filter { $0.kind != .equal }
XCTAssertEqual(changed.count, 1)
XCTAssertEqual(changed.first?.leftNumber, 10_001)
}
func testVeryLargeDifferingSectionFallsBackWithoutHanging() {
let left = (0..<5_000).map { "izquierda \($0)" }.joined(separator: "\n")
let right = (0..<5_000).map { "derecha \($0)" }.joined(separator: "\n")
let rows = TextDiff.rows(left: left, right: right, limit: 1_000)
XCTAssertEqual(rows.count, 5_000)
XCTAssertTrue(rows.allSatisfy { $0.kind == .changed })
}
func testHandlesEmptySides() {
XCTAssertTrue(TextDiff.rows(left: "", right: "").allSatisfy { $0.kind == .equal })
let added = TextDiff.rows(left: "", right: "a\nb")
XCTAssertTrue(added.contains { $0.kind == .added && $0.right == "b" })
}
func testNormalisesWindowsLineEndings() {
let rows = TextDiff.rows(left: "a\r\nb", right: "a\nb")
XCTAssertTrue(rows.allSatisfy { $0.kind == .equal }, "CRLF alone isn't a change")
}
}