Skip to content

Commit e80935a

Browse files
committed
Start adding tests
1 parent e71e575 commit e80935a

1 file changed

Lines changed: 126 additions & 18 deletions

File tree

DiffMatchPatch.zig

Lines changed: 126 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ fn diffCompute(
207207
return dmp.diffBisect(allocator, before, after, deadline);
208208
}
209209

210-
const HalfMatchResult = ?struct {
210+
const HalfMatchResult = struct {
211211
prefix_before: []const u8,
212212
suffix_before: []const u8,
213213
prefix_after: []const u8,
@@ -220,7 +220,7 @@ fn diffHalfMatch(
220220
allocator: std.mem.Allocator,
221221
before: []const u8,
222222
after: []const u8,
223-
) DiffError!HalfMatchResult {
223+
) DiffError!?HalfMatchResult {
224224
if (dmp.diff_timeout <= 0) {
225225
// Don't risk returning a non-optimal diff if we have unlimited time.
226226
return null;
@@ -237,7 +237,7 @@ fn diffHalfMatch(
237237
// Check again based on the third quarter.
238238
var half_match_2 = try dmp.diffHalfMatchInternal(allocator, long_text, short_text, (long_text.len + 1) / 2);
239239

240-
var half_match: HalfMatchResult = undefined;
240+
var half_match: ?HalfMatchResult = null;
241241
if (half_match_1 == null and half_match_2 == null) {
242242
return null;
243243
} else if (half_match_2 == null) {
@@ -270,7 +270,7 @@ fn diffHalfMatchInternal(
270270
long_text: []const u8,
271271
short_text: []const u8,
272272
i: usize,
273-
) DiffError!HalfMatchResult {
273+
) DiffError!?HalfMatchResult {
274274
// Start with a 1/4 length Substring at position i as a seed.
275275
const seed = long_text[i .. i + long_text.len / 4];
276276
var j: isize = -1;
@@ -1198,21 +1198,129 @@ fn diffCommonOverlap(text1_in: []const u8, text2_in: []const u8) usize {
11981198
// std.log.err("{any}", .{bruh});
11991199
// }
12001200

1201-
test {
1201+
// test {
1202+
// var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
1203+
// defer arena.deinit();
1204+
1205+
// var bruh = try default.diff(arena.allocator(), "Hello World.", "Goodbye World.", true);
1206+
// try diffCleanupSemantic(arena.allocator(), &bruh);
1207+
// for (bruh.items) |b| {
1208+
// std.log.err("{any}", .{b});
1209+
// }
1210+
1211+
// // for (bruh.items) |b| {
1212+
// // std.log.err("{s} {s}", .{ switch (b.operation) {
1213+
// // .equal => "",
1214+
// // .insert => "+",
1215+
// // .delete => "-",
1216+
// // }, b.text });
1217+
// // }
1218+
// }
1219+
1220+
test diffCommonPrefix {
1221+
// Detect any common suffix.
1222+
try std.testing.expectEqual(@as(usize, 0), diffCommonPrefix("abc", "xyz")); // Null case
1223+
try std.testing.expectEqual(@as(usize, 4), diffCommonPrefix("1234abcdef", "1234xyz")); // Non-null case
1224+
try std.testing.expectEqual(@as(usize, 4), diffCommonPrefix("1234", "1234xyz")); // Whole case
1225+
}
1226+
1227+
test diffCommonSuffix {
1228+
// Detect any common suffix.
1229+
try std.testing.expectEqual(@as(usize, 0), diffCommonSuffix("abc", "xyz")); // Null case
1230+
try std.testing.expectEqual(@as(usize, 4), diffCommonSuffix("abcdef1234", "xyz1234")); // Non-null case
1231+
try std.testing.expectEqual(@as(usize, 4), diffCommonSuffix("1234", "xyz1234")); // Whole case
1232+
}
1233+
1234+
test diffCommonOverlap {
1235+
// Detect any suffix/prefix overlap.
1236+
try std.testing.expectEqual(@as(usize, 0), diffCommonOverlap("", "abcd")); // Null case
1237+
try std.testing.expectEqual(@as(usize, 3), diffCommonOverlap("abc", "abcd")); // Whole case
1238+
try std.testing.expectEqual(@as(usize, 0), diffCommonOverlap("123456", "abcd")); // No overlap
1239+
try std.testing.expectEqual(@as(usize, 3), diffCommonOverlap("123456xxx", "xxxabcd")); // Overlap
1240+
1241+
// Some overly clever languages (C#) may treat ligatures as equal to their
1242+
// component letters. E.g. U+FB01 == 'fi'
1243+
try std.testing.expectEqual(@as(usize, 0), diffCommonOverlap("fi", "\u{fb01}")); // Unicode
1244+
}
1245+
1246+
test diffHalfMatch {
12021247
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
12031248
defer arena.deinit();
12041249

1205-
var bruh = try default.diff(arena.allocator(), "Hello World.", "Goodbye World.", true);
1206-
try diffCleanupSemantic(arena.allocator(), &bruh);
1207-
for (bruh.items) |b| {
1208-
std.log.err("{any}", .{b});
1209-
}
1210-
1211-
// for (bruh.items) |b| {
1212-
// std.log.err("{s} {s}", .{ switch (b.operation) {
1213-
// .equal => "",
1214-
// .insert => "+",
1215-
// .delete => "-",
1216-
// }, b.text });
1217-
// }
1250+
var one_timeout = DiffMatchPatch{};
1251+
one_timeout.diff_timeout = 1;
1252+
1253+
try std.testing.expectEqual(@as(?HalfMatchResult, null), try one_timeout.diffHalfMatch(arena.allocator(), "1234567890", "abcdef")); // No match #1
1254+
try std.testing.expectEqual(@as(?HalfMatchResult, null), try one_timeout.diffHalfMatch(arena.allocator(), "12345", "23")); // No match #2
1255+
1256+
// Single matches
1257+
try std.testing.expectEqualDeep(@as(?HalfMatchResult, HalfMatchResult{
1258+
.prefix_before = "12",
1259+
.suffix_before = "90",
1260+
.prefix_after = "a",
1261+
.suffix_after = "z",
1262+
.common_middle = "345678",
1263+
}), try one_timeout.diffHalfMatch(arena.allocator(), "1234567890", "a345678z")); // Single Match #1
1264+
1265+
try std.testing.expectEqualDeep(@as(?HalfMatchResult, HalfMatchResult{
1266+
.prefix_before = "a",
1267+
.suffix_before = "z",
1268+
.prefix_after = "12",
1269+
.suffix_after = "90",
1270+
.common_middle = "345678",
1271+
}), try one_timeout.diffHalfMatch(arena.allocator(), "a345678z", "1234567890")); // Single Match #2
1272+
1273+
try std.testing.expectEqualDeep(@as(?HalfMatchResult, HalfMatchResult{
1274+
.prefix_before = "abc",
1275+
.suffix_before = "z",
1276+
.prefix_after = "1234",
1277+
.suffix_after = "0",
1278+
.common_middle = "56789",
1279+
}), try one_timeout.diffHalfMatch(arena.allocator(), "abc56789z", "1234567890")); // Single Match #3
1280+
1281+
try std.testing.expectEqualDeep(@as(?HalfMatchResult, HalfMatchResult{
1282+
.prefix_before = "a",
1283+
.suffix_before = "xyz",
1284+
.prefix_after = "1",
1285+
.suffix_after = "7890",
1286+
.common_middle = "23456",
1287+
}), try one_timeout.diffHalfMatch(arena.allocator(), "a23456xyz", "1234567890")); // Single Match #4
1288+
1289+
// Multiple matches
1290+
try std.testing.expectEqualDeep(@as(?HalfMatchResult, HalfMatchResult{
1291+
.prefix_before = "12123",
1292+
.suffix_before = "123121",
1293+
.prefix_after = "a",
1294+
.suffix_after = "z",
1295+
.common_middle = "1234123451234",
1296+
}), try one_timeout.diffHalfMatch(arena.allocator(), "121231234123451234123121", "a1234123451234z")); // Multiple Matches #1
1297+
1298+
try std.testing.expectEqualDeep(@as(?HalfMatchResult, HalfMatchResult{
1299+
.prefix_before = "",
1300+
.suffix_before = "-=-=-=-=-=",
1301+
.prefix_after = "x",
1302+
.suffix_after = "",
1303+
.common_middle = "x-=-=-=-=-=-=-=",
1304+
}), try one_timeout.diffHalfMatch(arena.allocator(), "x-=-=-=-=-=-=-=-=-=-=-=-=", "xx-=-=-=-=-=-=-=")); // Multiple Matches #2
1305+
1306+
try std.testing.expectEqualDeep(@as(?HalfMatchResult, HalfMatchResult{
1307+
.prefix_before = "-=-=-=-=-=",
1308+
.suffix_before = "",
1309+
.prefix_after = "",
1310+
.suffix_after = "y",
1311+
.common_middle = "-=-=-=-=-=-=-=y",
1312+
}), try one_timeout.diffHalfMatch(arena.allocator(), "-=-=-=-=-=-=-=-=-=-=-=-=y", "-=-=-=-=-=-=-=yy")); // Multiple Matches #3
1313+
1314+
// Other cases
1315+
// Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy
1316+
try std.testing.expectEqualDeep(@as(?HalfMatchResult, HalfMatchResult{
1317+
.prefix_before = "qHillo",
1318+
.suffix_before = "w",
1319+
.prefix_after = "x",
1320+
.suffix_after = "Hulloy",
1321+
.common_middle = "HelloHe",
1322+
}), try one_timeout.diffHalfMatch(arena.allocator(), "qHilloHelloHew", "xHelloHeHulloy")); // Non-optimal halfmatch
1323+
1324+
one_timeout.diff_timeout = 0;
1325+
try std.testing.expectEqualDeep(@as(?HalfMatchResult, null), try one_timeout.diffHalfMatch(arena.allocator(), "qHilloHelloHew", "xHelloHeHulloy")); // Non-optimal halfmatch
12181326
}

0 commit comments

Comments
 (0)