@@ -1761,3 +1761,105 @@ test diff {
17611761
17621762 // Test null inputs -- not needed because nulls can't be passed in C#.
17631763}
1764+
1765+ test diffCleanupSemantic {
1766+ // Cleanup semantically trivial equalities.
1767+ // Null case.
1768+ var diffs = std .ArrayListUnmanaged (Diff ){};
1769+ defer diffs .deinit (talloc );
1770+ // var this = default;
1771+ try diffCleanupSemantic (talloc , & diffs );
1772+ try std .testing .expectEqual (@as (usize , 0 ), diffs .items .len ); // Null case
1773+
1774+ diffs .items .len = 0 ;
1775+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "ab" ), Diff .init (.insert , "cd" ), Diff .init (.equal , "12" ), Diff .init (.delete , "e" ) });
1776+ try diffCleanupSemantic (talloc , & diffs );
1777+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // No elimination #1
1778+ Diff .init (.delete , "ab" ),
1779+ Diff .init (.insert , "cd" ),
1780+ Diff .init (.equal , "12" ),
1781+ Diff .init (.delete , "e" ),
1782+ }), diffs .items );
1783+
1784+ diffs .items .len = 0 ;
1785+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "abc" ), Diff .init (.insert , "ABC" ), Diff .init (.equal , "1234" ), Diff .init (.delete , "wxyz" ) });
1786+ try diffCleanupSemantic (talloc , & diffs );
1787+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // No elimination #2
1788+ Diff .init (.delete , "abc" ),
1789+ Diff .init (.insert , "ABC" ),
1790+ Diff .init (.equal , "1234" ),
1791+ Diff .init (.delete , "wxyz" ),
1792+ }), diffs .items );
1793+
1794+ diffs .items .len = 0 ;
1795+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "a" ), Diff .init (.equal , "b" ), Diff .init (.delete , "c" ) });
1796+ try diffCleanupSemantic (talloc , & diffs );
1797+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Simple elimination
1798+ Diff .init (.delete , "abc" ),
1799+ Diff .init (.insert , "b" ),
1800+ }), diffs .items );
1801+
1802+ diffs .items .len = 0 ;
1803+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "ab" ), Diff .init (.equal , "cd" ), Diff .init (.delete , "e" ), Diff .init (.equal , "f" ), Diff .init (.insert , "g" ) });
1804+ try diffCleanupSemantic (talloc , & diffs );
1805+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Backpass elimination
1806+ Diff .init (.delete , "abcdef" ),
1807+ Diff .init (.insert , "cdfg" ),
1808+ }), diffs .items );
1809+
1810+ diffs .items .len = 0 ;
1811+ 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" ) });
1812+ try diffCleanupSemantic (talloc , & diffs );
1813+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Multiple elimination
1814+ Diff .init (.delete , "AB_AB" ),
1815+ Diff .init (.insert , "1A2_1A2" ),
1816+ }), diffs .items );
1817+
1818+ diffs .items .len = 0 ;
1819+ try diffs .appendSlice (talloc , &.{ Diff .init (.equal , "The c" ), Diff .init (.delete , "ow and the c" ), Diff .init (.equal , "at." ) });
1820+ try diffCleanupSemantic (talloc , & diffs );
1821+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Word boundaries
1822+ Diff .init (.equal , "The " ),
1823+ Diff .init (.delete , "cow and the " ),
1824+ Diff .init (.equal , "cat." ),
1825+ }), diffs .items );
1826+
1827+ diffs .items .len = 0 ;
1828+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "abcxx" ), Diff .init (.insert , "xxdef" ) });
1829+ try diffCleanupSemantic (talloc , & diffs );
1830+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // No overlap elimination
1831+ Diff .init (.delete , "abcxx" ),
1832+ Diff .init (.insert , "xxdef" ),
1833+ }), diffs .items );
1834+
1835+ diffs .items .len = 0 ;
1836+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "abcxxx" ), Diff .init (.insert , "xxxdef" ) });
1837+ try diffCleanupSemantic (talloc , & diffs );
1838+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Overlap elimination
1839+ Diff .init (.delete , "abc" ),
1840+ Diff .init (.equal , "xxx" ),
1841+ Diff .init (.insert , "def" ),
1842+ }), diffs .items );
1843+
1844+ diffs .items .len = 0 ;
1845+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "xxxabc" ), Diff .init (.insert , "defxxx" ) });
1846+ try diffCleanupSemantic (talloc , & diffs );
1847+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Reverse overlap elimination
1848+ Diff .init (.insert , "def" ),
1849+ Diff .init (.equal , "xxx" ),
1850+ Diff .init (.delete , "abc" ),
1851+ }), diffs .items );
1852+
1853+ diffs .items .len = 0 ;
1854+ try diffs .appendSlice (talloc , &.{ Diff .init (.delete , "abcd1212" ), Diff .init (.insert , "1212efghi" ), Diff .init (.equal , "----" ), Diff .init (.delete , "A3" ), Diff .init (.insert , "3BC" ) });
1855+ try diffCleanupSemantic (talloc , & diffs );
1856+ try std .testing .expectEqualDeep (@as ([]const Diff , &[_ ]Diff { // Two overlap eliminations
1857+ Diff .init (.delete , "abcd" ),
1858+ Diff .init (.equal , "1212" ),
1859+ Diff .init (.insert , "efghi" ),
1860+ Diff .init (.equal , "----" ),
1861+ Diff .init (.delete , "A" ),
1862+ Diff .init (.equal , "3" ),
1863+ Diff .init (.insert , "BC" ),
1864+ }), diffs .items );
1865+ }
0 commit comments