@@ -1873,3 +1873,105 @@ test diff {
18731873
18741874 // Test null inputs -- not needed because nulls can't be passed in C#.
18751875}
1876+
1877+ test diffCleanupSemantic {
1878+ // Cleanup semantically trivial equalities.
1879+ // Null case.
1880+ var diffs = std .ArrayListUnmanaged (Diff ){};
1881+ defer diffs .deinit (talloc );
1882+ // var this = default;
1883+ try diffCleanupSemantic (talloc , & diffs );
1884+ try std .testing .expectEqual (@as (usize , 0 ), diffs .items .len ); // Null case
1885+
1886+ diffs .items .len = 0 ;
1887+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "ab" ), Diff .init (.insert , "cd" ), Diff .init (.equal , "12" ), Diff .init (.delete , "e" ) });
1888+ try diffCleanupSemantic (talloc , & diffs );
1889+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // No elimination #1
1890+ Diff .init (.delete , "ab" ),
1891+ Diff .init (.insert , "cd" ),
1892+ Diff .init (.equal , "12" ),
1893+ Diff .init (.delete , "e" ),
1894+ }), diffs .items );
1895+
1896+ diffs .items .len = 0 ;
1897+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "abc" ), Diff .init (.insert , "ABC" ), Diff .init (.equal , "1234" ), Diff .init (.delete , "wxyz" ) });
1898+ try diffCleanupSemantic (talloc , & diffs );
1899+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // No elimination #2
1900+ Diff .init (.delete , "abc" ),
1901+ Diff .init (.insert , "ABC" ),
1902+ Diff .init (.equal , "1234" ),
1903+ Diff .init (.delete , "wxyz" ),
1904+ }), diffs .items );
1905+
1906+ diffs .items .len = 0 ;
1907+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "a" ), Diff .init (.equal , "b" ), Diff .init (.delete , "c" ) });
1908+ try diffCleanupSemantic (talloc , & diffs );
1909+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Simple elimination
1910+ Diff .init (.delete , "abc" ),
1911+ Diff .init (.insert , "b" ),
1912+ }), diffs .items );
1913+
1914+ diffs .items .len = 0 ;
1915+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "ab" ), Diff .init (.equal , "cd" ), Diff .init (.delete , "e" ), Diff .init (.equal , "f" ), Diff .init (.insert , "g" ) });
1916+ try diffCleanupSemantic (talloc , & diffs );
1917+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Backpass elimination
1918+ Diff .init (.delete , "abcdef" ),
1919+ Diff .init (.insert , "cdfg" ),
1920+ }), diffs .items );
1921+
1922+ diffs .items .len = 0 ;
1923+ try diffs .appendSlice (talloc , &.{ Diff .init (.insert , "1" ), Diff .init (.equal , "A" ), Diff .init (.delete , "B" ), Diff .init (.insert , "2" ), Diff .init (.equal , "_" ), Diff .init (.insert , "1" ), Diff .init (.equal , "A" ), Diff .init (.delete , "B" ), Diff .init (.insert , "2" ) });
1924+ try diffCleanupSemantic (talloc , & diffs );
1925+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Multiple elimination
1926+ Diff .init (.delete , "AB_AB" ),
1927+ Diff .init (.insert , "1A2_1A2" ),
1928+ }), diffs .items );
1929+
1930+ diffs .items .len = 0 ;
1931+ try diffs .appendSlice (talloc , &.{ Diff .init (.equal , "The c" ), Diff .init (.delete , "ow and the c" ), Diff .init (.equal , "at." ) });
1932+ try diffCleanupSemantic (talloc , & diffs );
1933+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Word boundaries
1934+ Diff .init (.equal , "The " ),
1935+ Diff .init (.delete , "cow and the " ),
1936+ Diff .init (.equal , "cat." ),
1937+ }), diffs .items );
1938+
1939+ diffs .items .len = 0 ;
1940+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "abcxx" ), Diff .init (.insert , "xxdef" ) });
1941+ try diffCleanupSemantic (talloc , & diffs );
1942+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // No overlap elimination
1943+ Diff .init (.delete , "abcxx" ),
1944+ Diff .init (.insert , "xxdef" ),
1945+ }), diffs .items );
1946+
1947+ diffs .items .len = 0 ;
1948+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "abcxxx" ), Diff .init (.insert , "xxxdef" ) });
1949+ try diffCleanupSemantic (talloc , & diffs );
1950+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Overlap elimination
1951+ Diff .init (.delete , "abc" ),
1952+ Diff .init (.equal , "xxx" ),
1953+ Diff .init (.insert , "def" ),
1954+ }), diffs .items );
1955+
1956+ diffs .items .len = 0 ;
1957+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "xxxabc" ), Diff .init (.insert , "defxxx" ) });
1958+ try diffCleanupSemantic (talloc , & diffs );
1959+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Reverse overlap elimination
1960+ Diff .init (.insert , "def" ),
1961+ Diff .init (.equal , "xxx" ),
1962+ Diff .init (.delete , "abc" ),
1963+ }), diffs .items );
1964+
1965+ diffs .items .len = 0 ;
1966+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "abcd1212" ), Diff .init (.insert , "1212efghi" ), Diff .init (.equal , "----" ), Diff .init (.delete , "A3" ), Diff .init (.insert , "3BC" ) });
1967+ try diffCleanupSemantic (talloc , & diffs );
1968+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Two overlap eliminations
1969+ Diff .init (.delete , "abcd" ),
1970+ Diff .init (.equal , "1212" ),
1971+ Diff .init (.insert , "efghi" ),
1972+ Diff .init (.equal , "----" ),
1973+ Diff .init (.delete , "A" ),
1974+ Diff .init (.equal , "3" ),
1975+ Diff .init (.insert , "BC" ),
1976+ }), diffs .items );
1977+ }
0 commit comments