11const DiffMatchPatch = @This ();
22
33const std = @import ("std" );
4+ const testing = std .testing ;
45const ArrayListUnmanaged = std .ArrayListUnmanaged ;
56
67/// DMP with default configuration options
@@ -577,11 +578,11 @@ fn diffLinesToCharsMunge(
577578 // Walk the text, pulling out a Substring for each line.
578579 // text.split('\n') would would temporarily double our memory footprint.
579580 // Modifying text would create many large strings to garbage collect.
580- while (line_end < text .len - 1 ) {
581+ while (line_end < @intCast ( isize , text .len ) - 1 ) {
581582 line_end = b : {
582583 break :b @intCast (isize , std .mem .indexOf (u8 , text [@intCast (usize , line_start ).. ], "\n " ) orelse break :b @intCast (isize , text .len - 1 )) + line_start ;
583584 };
584- line = text [@intCast (usize , line_start ).. @intCast (usize , line_end + 1 - line_start )];
585+ line = text [@intCast (usize , line_start ) .. @intCast ( usize , line_start ) + @intCast (usize , line_end + 1 - line_start )];
585586
586587 if (line_hash .get (line )) | value | {
587588 try chars .append (allocator , @intCast (u8 , value ));
@@ -1199,7 +1200,7 @@ fn diffCommonOverlap(text1_in: []const u8, text2_in: []const u8) usize {
11991200// }
12001201
12011202// test {
1202- // var arena = std.heap.ArenaAllocator.init(std. testing.allocator);
1203+ // var arena = std.heap.ArenaAllocator.init(testing.allocator);
12031204// defer arena.deinit();
12041205
12051206// var bruh = try default.diff(arena.allocator(), "Hello World.", "Goodbye World.", true);
@@ -1219,66 +1220,66 @@ fn diffCommonOverlap(text1_in: []const u8, text2_in: []const u8) usize {
12191220
12201221test diffCommonPrefix {
12211222 // 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
1223+ try testing .expectEqual (@as (usize , 0 ), diffCommonPrefix ("abc" , "xyz" )); // Null case
1224+ try testing .expectEqual (@as (usize , 4 ), diffCommonPrefix ("1234abcdef" , "1234xyz" )); // Non-null case
1225+ try testing .expectEqual (@as (usize , 4 ), diffCommonPrefix ("1234" , "1234xyz" )); // Whole case
12251226}
12261227
12271228test diffCommonSuffix {
12281229 // 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
1230+ try testing .expectEqual (@as (usize , 0 ), diffCommonSuffix ("abc" , "xyz" )); // Null case
1231+ try testing .expectEqual (@as (usize , 4 ), diffCommonSuffix ("abcdef1234" , "xyz1234" )); // Non-null case
1232+ try testing .expectEqual (@as (usize , 4 ), diffCommonSuffix ("1234" , "xyz1234" )); // Whole case
12321233}
12331234
12341235test diffCommonOverlap {
12351236 // 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
1237+ try testing .expectEqual (@as (usize , 0 ), diffCommonOverlap ("" , "abcd" )); // Null case
1238+ try testing .expectEqual (@as (usize , 3 ), diffCommonOverlap ("abc" , "abcd" )); // Whole case
1239+ try testing .expectEqual (@as (usize , 0 ), diffCommonOverlap ("123456" , "abcd" )); // No overlap
1240+ try testing .expectEqual (@as (usize , 3 ), diffCommonOverlap ("123456xxx" , "xxxabcd" )); // Overlap
12401241
12411242 // Some overly clever languages (C#) may treat ligatures as equal to their
12421243 // component letters. E.g. U+FB01 == 'fi'
1243- try std . testing .expectEqual (@as (usize , 0 ), diffCommonOverlap ("fi" , "\u{fb01} " )); // Unicode
1244+ try testing .expectEqual (@as (usize , 0 ), diffCommonOverlap ("fi" , "\u{fb01} " )); // Unicode
12441245}
12451246
12461247test diffHalfMatch {
1247- var arena = std .heap .ArenaAllocator .init (std . testing .allocator );
1248+ var arena = std .heap .ArenaAllocator .init (testing .allocator );
12481249 defer arena .deinit ();
12491250
12501251 var one_timeout = DiffMatchPatch {};
12511252 one_timeout .diff_timeout = 1 ;
12521253
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
1254+ try testing .expectEqual (@as (? HalfMatchResult , null ), try one_timeout .diffHalfMatch (arena .allocator (), "1234567890" , "abcdef" )); // No match #1
1255+ try testing .expectEqual (@as (? HalfMatchResult , null ), try one_timeout .diffHalfMatch (arena .allocator (), "12345" , "23" )); // No match #2
12551256
12561257 // Single matches
1257- try std . testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1258+ try testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
12581259 .prefix_before = "12" ,
12591260 .suffix_before = "90" ,
12601261 .prefix_after = "a" ,
12611262 .suffix_after = "z" ,
12621263 .common_middle = "345678" ,
12631264 }), try one_timeout .diffHalfMatch (arena .allocator (), "1234567890" , "a345678z" )); // Single Match #1
12641265
1265- try std . testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1266+ try testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
12661267 .prefix_before = "a" ,
12671268 .suffix_before = "z" ,
12681269 .prefix_after = "12" ,
12691270 .suffix_after = "90" ,
12701271 .common_middle = "345678" ,
12711272 }), try one_timeout .diffHalfMatch (arena .allocator (), "a345678z" , "1234567890" )); // Single Match #2
12721273
1273- try std . testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1274+ try testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
12741275 .prefix_before = "abc" ,
12751276 .suffix_before = "z" ,
12761277 .prefix_after = "1234" ,
12771278 .suffix_after = "0" ,
12781279 .common_middle = "56789" ,
12791280 }), try one_timeout .diffHalfMatch (arena .allocator (), "abc56789z" , "1234567890" )); // Single Match #3
12801281
1281- try std . testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1282+ try testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
12821283 .prefix_before = "a" ,
12831284 .suffix_before = "xyz" ,
12841285 .prefix_after = "1" ,
@@ -1287,23 +1288,23 @@ test diffHalfMatch {
12871288 }), try one_timeout .diffHalfMatch (arena .allocator (), "a23456xyz" , "1234567890" )); // Single Match #4
12881289
12891290 // Multiple matches
1290- try std . testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1291+ try testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
12911292 .prefix_before = "12123" ,
12921293 .suffix_before = "123121" ,
12931294 .prefix_after = "a" ,
12941295 .suffix_after = "z" ,
12951296 .common_middle = "1234123451234" ,
12961297 }), try one_timeout .diffHalfMatch (arena .allocator (), "121231234123451234123121" , "a1234123451234z" )); // Multiple Matches #1
12971298
1298- try std . testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1299+ try testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
12991300 .prefix_before = "" ,
13001301 .suffix_before = "-=-=-=-=-=" ,
13011302 .prefix_after = "x" ,
13021303 .suffix_after = "" ,
13031304 .common_middle = "x-=-=-=-=-=-=-=" ,
13041305 }), try one_timeout .diffHalfMatch (arena .allocator (), "x-=-=-=-=-=-=-=-=-=-=-=-=" , "xx-=-=-=-=-=-=-=" )); // Multiple Matches #2
13051306
1306- try std . testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
1307+ try testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
13071308 .prefix_before = "-=-=-=-=-=" ,
13081309 .suffix_before = "" ,
13091310 .prefix_after = "" ,
@@ -1313,7 +1314,7 @@ test diffHalfMatch {
13131314
13141315 // Other cases
13151316 // 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+ try testing .expectEqualDeep (@as (? HalfMatchResult , HalfMatchResult {
13171318 .prefix_before = "qHillo" ,
13181319 .suffix_before = "w" ,
13191320 .prefix_after = "x" ,
@@ -1322,5 +1323,67 @@ test diffHalfMatch {
13221323 }), try one_timeout .diffHalfMatch (arena .allocator (), "qHilloHelloHew" , "xHelloHeHulloy" )); // Non-optimal halfmatch
13231324
13241325 one_timeout .diff_timeout = 0 ;
1325- try std .testing .expectEqualDeep (@as (? HalfMatchResult , null ), try one_timeout .diffHalfMatch (arena .allocator (), "qHilloHelloHew" , "xHelloHeHulloy" )); // Non-optimal halfmatch
1326+ try testing .expectEqualDeep (@as (? HalfMatchResult , null ), try one_timeout .diffHalfMatch (arena .allocator (), "qHilloHelloHew" , "xHelloHeHulloy" )); // Non-optimal halfmatch
1327+ }
1328+
1329+ test diffLinesToChars {
1330+ var arena = std .heap .ArenaAllocator .init (testing .allocator );
1331+ defer arena .deinit ();
1332+
1333+ // Convert lines down to characters.
1334+ var tmp_array_list = std .ArrayList ([]const u8 ).init (arena .allocator ());
1335+ try tmp_array_list .append ("" );
1336+ try tmp_array_list .append ("alpha\n " );
1337+ try tmp_array_list .append ("beta\n " );
1338+
1339+ var result = try diffLinesToChars (arena .allocator (), "alpha\n beta\n alpha\n " , "beta\n alpha\n beta\n " );
1340+ try testing .expectEqualStrings ("\u{0001}\u{0002}\u{0001} " , result .chars_1 ); // Shared lines #1
1341+ try testing .expectEqualStrings ("\u{0002}\u{0001}\u{0002} " , result .chars_2 ); // Shared lines #2
1342+ try testing .expectEqualDeep (tmp_array_list .items , result .line_array .items ); // Shared lines #3
1343+
1344+ tmp_array_list .items .len = 0 ;
1345+ try tmp_array_list .append ("" );
1346+ try tmp_array_list .append ("alpha\r \n " );
1347+ try tmp_array_list .append ("beta\r \n " );
1348+ try tmp_array_list .append ("\r \n " );
1349+
1350+ result = try diffLinesToChars (arena .allocator (), "" , "alpha\r \n beta\r \n \r \n \r \n " );
1351+ try testing .expectEqualStrings ("" , result .chars_1 ); // Empty string and blank lines #1
1352+ try testing .expectEqualStrings ("\u{0001}\u{0002}\u{0003}\u{0003} " , result .chars_2 ); // Empty string and blank lines #2
1353+ try testing .expectEqualDeep (tmp_array_list .items , result .line_array .items ); // Empty string and blank lines #3
1354+
1355+ tmp_array_list .items .len = 0 ;
1356+ try tmp_array_list .append ("" );
1357+ try tmp_array_list .append ("a" );
1358+ try tmp_array_list .append ("b" );
1359+
1360+ result = try diffLinesToChars (arena .allocator (), "a" , "b" );
1361+ try testing .expectEqualStrings ("\u{0001} " , result .chars_1 ); // No linebreaks #1.
1362+ try testing .expectEqualStrings ("\u{0002} " , result .chars_2 ); // No linebreaks #2.
1363+ try testing .expectEqualDeep (tmp_array_list .items , result .line_array .items ); // No linebreaks #3.
1364+
1365+ // TODO: More than 256 to reveal any 8-bit limitations but this requires
1366+ // some unicode logic that I don't want to deal with
1367+
1368+ // TODO: Fix this
1369+
1370+ // const n: u8 = 255;
1371+ // tmp_array_list.items.len = 0;
1372+
1373+ // var line_list = std.ArrayList(u8).init(arena.allocator());
1374+ // var char_list = std.ArrayList(u8).init(arena.allocator());
1375+
1376+ // var i: u8 = 0;
1377+ // while (i < n) : (i += 1) {
1378+ // try tmp_array_list.append(&.{ i, '\n' });
1379+ // try line_list.appendSlice(&.{ i, '\n' });
1380+ // try char_list.append(i);
1381+ // }
1382+ // try testing.expectEqual(@as(usize, n), tmp_array_list.items.len); // Test initialization fail #1
1383+ // try testing.expectEqual(@as(usize, n), char_list.items.len); // Test initialization fail #2
1384+ // try tmp_array_list.insert(0, "");
1385+ // result = try diffLinesToChars(arena.allocator(), line_list.items, "");
1386+ // try testing.expectEqualStrings(char_list.items, result.chars_1);
1387+ // try testing.expectEqualStrings("", result.chars_2);
1388+ // try testing.expectEqualDeep(tmp_array_list.items, result.line_array.items);
13261389}
0 commit comments