lcs_test.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. // Copyright (c) 2022 Google LLC.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "source/diff/lcs.h"
  15. #include <string>
  16. #include "gtest/gtest.h"
  17. namespace spvtools {
  18. namespace diff {
  19. namespace {
  20. using Sequence = std::vector<int>;
  21. using LCS = LongestCommonSubsequence<Sequence>;
  22. void VerifyMatch(const Sequence& src, const Sequence& dst,
  23. size_t expected_match_count) {
  24. DiffMatch src_match, dst_match;
  25. LCS lcs(src, dst);
  26. size_t match_count =
  27. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  28. EXPECT_EQ(match_count, expected_match_count);
  29. size_t src_cur = 0;
  30. size_t dst_cur = 0;
  31. size_t matches_seen = 0;
  32. while (src_cur < src.size() && dst_cur < dst.size()) {
  33. if (src_match[src_cur] && dst_match[dst_cur]) {
  34. EXPECT_EQ(src[src_cur], dst[dst_cur])
  35. << "Src: " << src_cur << " Dst: " << dst_cur;
  36. ++src_cur;
  37. ++dst_cur;
  38. ++matches_seen;
  39. continue;
  40. }
  41. if (!src_match[src_cur]) {
  42. ++src_cur;
  43. }
  44. if (!dst_match[dst_cur]) {
  45. ++dst_cur;
  46. }
  47. }
  48. EXPECT_EQ(matches_seen, expected_match_count);
  49. }
  50. TEST(LCSTest, EmptySequences) {
  51. Sequence src, dst;
  52. DiffMatch src_match, dst_match;
  53. LCS lcs(src, dst);
  54. size_t match_count =
  55. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  56. EXPECT_EQ(match_count, 0u);
  57. EXPECT_TRUE(src_match.empty());
  58. EXPECT_TRUE(dst_match.empty());
  59. }
  60. TEST(LCSTest, EmptySrc) {
  61. Sequence src, dst = {1, 2, 3};
  62. DiffMatch src_match, dst_match;
  63. LCS lcs(src, dst);
  64. size_t match_count =
  65. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  66. EXPECT_EQ(match_count, 0u);
  67. EXPECT_TRUE(src_match.empty());
  68. EXPECT_EQ(dst_match, DiffMatch(3, false));
  69. }
  70. TEST(LCSTest, EmptyDst) {
  71. Sequence src = {1, 2, 3}, dst;
  72. DiffMatch src_match, dst_match;
  73. LCS lcs(src, dst);
  74. size_t match_count =
  75. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  76. EXPECT_EQ(match_count, 0u);
  77. EXPECT_EQ(src_match, DiffMatch(3, false));
  78. EXPECT_TRUE(dst_match.empty());
  79. }
  80. TEST(LCSTest, Identical) {
  81. Sequence src = {1, 2, 3, 4, 5, 6}, dst = {1, 2, 3, 4, 5, 6};
  82. DiffMatch src_match, dst_match;
  83. LCS lcs(src, dst);
  84. size_t match_count =
  85. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  86. EXPECT_EQ(match_count, 6u);
  87. EXPECT_EQ(src_match, DiffMatch(6, true));
  88. EXPECT_EQ(dst_match, DiffMatch(6, true));
  89. }
  90. TEST(LCSTest, SrcPrefix) {
  91. Sequence src = {1, 2, 3, 4}, dst = {1, 2, 3, 4, 5, 6};
  92. DiffMatch src_match, dst_match;
  93. LCS lcs(src, dst);
  94. size_t match_count =
  95. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  96. const DiffMatch src_expect = {true, true, true, true};
  97. const DiffMatch dst_expect = {true, true, true, true, false, false};
  98. EXPECT_EQ(match_count, 4u);
  99. EXPECT_EQ(src_match, src_expect);
  100. EXPECT_EQ(dst_match, dst_expect);
  101. }
  102. TEST(LCSTest, DstPrefix) {
  103. Sequence src = {1, 2, 3, 4, 5, 6}, dst = {1, 2, 3, 4, 5};
  104. DiffMatch src_match, dst_match;
  105. LCS lcs(src, dst);
  106. size_t match_count =
  107. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  108. const DiffMatch src_expect = {true, true, true, true, true, false};
  109. const DiffMatch dst_expect = {true, true, true, true, true};
  110. EXPECT_EQ(match_count, 5u);
  111. EXPECT_EQ(src_match, src_expect);
  112. EXPECT_EQ(dst_match, dst_expect);
  113. }
  114. TEST(LCSTest, SrcSuffix) {
  115. Sequence src = {3, 4, 5, 6}, dst = {1, 2, 3, 4, 5, 6};
  116. DiffMatch src_match, dst_match;
  117. LCS lcs(src, dst);
  118. size_t match_count =
  119. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  120. const DiffMatch src_expect = {true, true, true, true};
  121. const DiffMatch dst_expect = {false, false, true, true, true, true};
  122. EXPECT_EQ(match_count, 4u);
  123. EXPECT_EQ(src_match, src_expect);
  124. EXPECT_EQ(dst_match, dst_expect);
  125. }
  126. TEST(LCSTest, DstSuffix) {
  127. Sequence src = {1, 2, 3, 4, 5, 6}, dst = {5, 6};
  128. DiffMatch src_match, dst_match;
  129. LCS lcs(src, dst);
  130. size_t match_count =
  131. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  132. const DiffMatch src_expect = {false, false, false, false, true, true};
  133. const DiffMatch dst_expect = {true, true};
  134. EXPECT_EQ(match_count, 2u);
  135. EXPECT_EQ(src_match, src_expect);
  136. EXPECT_EQ(dst_match, dst_expect);
  137. }
  138. TEST(LCSTest, None) {
  139. Sequence src = {1, 3, 5, 7, 9}, dst = {2, 4, 6, 8, 10, 12};
  140. DiffMatch src_match, dst_match;
  141. LCS lcs(src, dst);
  142. size_t match_count =
  143. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  144. EXPECT_EQ(match_count, 0u);
  145. EXPECT_EQ(src_match, DiffMatch(5, false));
  146. EXPECT_EQ(dst_match, DiffMatch(6, false));
  147. }
  148. TEST(LCSTest, NonContiguous) {
  149. Sequence src = {1, 2, 3, 4, 5, 6, 10}, dst = {2, 4, 5, 8, 9, 10, 12};
  150. DiffMatch src_match, dst_match;
  151. LCS lcs(src, dst);
  152. size_t match_count =
  153. lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
  154. const DiffMatch src_expect = {false, true, false, true, true, false, true};
  155. const DiffMatch dst_expect = {true, true, true, false, false, true, false};
  156. EXPECT_EQ(match_count, 4u);
  157. EXPECT_EQ(src_match, src_expect);
  158. EXPECT_EQ(dst_match, dst_expect);
  159. }
  160. TEST(LCSTest, WithDuplicates) {
  161. Sequence src = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4},
  162. dst = {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4};
  163. VerifyMatch(src, dst, 6);
  164. }
  165. TEST(LCSTest, Large) {
  166. const std::string src_str =
  167. "GUJwrJSlkKJXxCVIAxlVgnUyOrdyRyFtlZwWMmFhYGfkFTNnhiBmClgHyrcXMVwfrRxNUfQk"
  168. "qaoGvCbPZHAzXsaZpXHPfJxOMCUtRDmIQpfiXKbHQbhTfPqhxBDWvmTQAqwsWTLajZYtMUnf"
  169. "hNNCfkuAXkZsaebwEbIZOxTDZsqSMUfCMoGeKJGVSNFgLTiBMbdvchHGfFRkHKcYCDjBfIcj"
  170. "todPnvDjzQYWBcvIfVvyBzHikrwpDORaGEZLhmyztIFCLJOqeLhOzERYmVqzlsoUzruTXTXq"
  171. "DLTxQRakOCMRrgRzCDTXfwwfDcKMBVnxRZemjcwcEsOVxwtwdBCWJycsDcZKlvrCvZaenKlv"
  172. "vyByDQeLdxAyBnPkIMQlMQwqjUfRLybeoaOanlbFkpTPPZdHelQrIvucTHzMpWWQTbuANwvN"
  173. "OVhCGGoIcGNDpfIsaBexlMMdHsxMGerTngmjpdPeQQJHfvKZkdYqAzrtDohqtDsaFMxQViVQ"
  174. "YszDVgyoSHZdOXAvXkJidojLvGZOzhRajVPhWDwKuGqdaympELxHsrXAJYufdCPwJdGJfWqq"
  175. "yvTWpcrFHOIuCEmNLnSCDsxQGRVDwyCykBJazhApfCnrOadnafvqfVuFqEXMSrYbHTfTnzbz"
  176. "MhISyOtMUITaurCXvanCbuOXBhHyCjOhVbxnMvhlPmZBMQgEHCghtAJVMXGPNRtszVZlPxVl"
  177. "QIPTBnPUPejlyZGPqeICyNngdQGkvKbIoWlTLBtVhMdBeUMozNlKQTIPYBeImVcMdLafuxUf"
  178. "TIXysmcTrUTcspOSKBxhdhLwiRnREGFWJTfUKsgGOAQeYojXdrqsGjMJfiKalyoiqrgLnlij"
  179. "CtOapoxDGVOOBalNYGzCtBlxbvaAzxipGnJpOEbmXcpeoIsAdxspKBzBDgoPVxnuRBUwmTSr"
  180. "CRpWhxikgUYQVCwalLUIeBPRyhhsECGCXJmGDZSCIUaBwROkigzdeVPOXhgCGBEprWtNdYfL"
  181. "tOUYJHQXxiIJgSGmWntezJFpNQoTPbRRYAGhtYvAechvBcYWocLkYFxsDAuszvQNLXdhmAHw"
  182. "DErcjbtCdQllnKcDADVNWVezljjLrAuyGHetINMgAvJZwOEYakihYVUbZGCsHEufluLNyNHy"
  183. "gqtSTSFFjBHiIqQejTPWybLdpWNwZrWvIWnlzUcGNQPEYHVPCbteWknjAnWrdTBeCbHUDBoK"
  184. "aHvDStmpNRGIjvlumiZTbdZNAzUeSFnFChCsSExwXeEfDJfjyOoSBofHzJqJErvHLNyUJTjX"
  185. "qmtgKPpMKohUPBMhtCteQFcNEpWrUVGbibMOpvBwdiWYXNissArpSasVJFgDzrqTyGkerTMX"
  186. "gcrzFUGFZRhNdekaJeKYPogsofJaRsUQmIRyYdkrxKeMgLPpwOfSKJOqzXDoeHljTzhOwEVy"
  187. "krOEnACFrWhufajsMitjOWdLOHHchQDddGPzxknEgdwmZepKDvRZGCuPqzeQkjOPqUBKpKLJ"
  188. "eKieSsRXkaqxSPGajfvPKmwFWdLByEcLgvrmteazgFjmMGrLYqRRxzUOfOCokenqHVYstBHf"
  189. "AwsWsqPTvqsRJUfGGTaYiylZMGbQqTzINhFHvdlRQvvYKBcuAHdBeKlHSxVrSsEKbcAvnIcf"
  190. "xzdVDdwQPHMCHeZZRpGHWvKzgTGzSTbYTeOPyKvvYWmQToTpsjAtKUJUjcEHWhmdBLDTBMHJ"
  191. "ivBXcLGtCsumNNVFyGbVviGmqHTdyBlkneibXBesKJGOUzOtIwXCPJggqBekSzNQYkALlItk"
  192. "cbEhbdXAIKVHYpInLwxXalKZrkrpxtfuagqMGmRJnJbFQaEoYMoqPsxZpocddPXXPyvxVkaF"
  193. "qdKISejWDhBImnEEOPDcyWTubbfVfwUztciaFJcsPLhgYVfhqlOfoNjKbmTFptFttYuyBrUI"
  194. "zzmZypOqrjQHTGFwlHStpIwxPtMvtsEDpsmWIgwzYgwmdpbMOnfElZMYpVIcvzSWejeJcdUB"
  195. "QUoBRUmGQVVWvEDseuozrDjgdXFScPwwsgaUPwSzScfBNrkpmEFDSZLKfNjMqvOmUtocUkbo"
  196. "VGFEKgGLbNruwLgXHTloWDrnqymPVAtzjWPutonIsMDPeeCmTjYWAFXcyTAlBeiJTIRkZxiM"
  197. "kLjMnAflSNJzmZkatXkYiPEMYSmzHbLKEizHbEjQOxBDzpRHiFjhedqiyMiUMvThjaRFmwll"
  198. "aMGgwKBIKepwyoEdnuhtzJzboiNEAFKiqiWxxmkRFRoTiFWXLPAWLuzSCrajgkQhDxAQDqyM"
  199. "VwZlhZicQLEDYYisEalesDWZAYzcvENuHUwRutIsGgsdoYwOZiURhcgdbTGWBNqhrFjvTQCj"
  200. "VlTPNlRdRLaaqzUBBwbdtyXFkCBUYYMbmRrkFxfxbCqkgZNGyHPKLkOPnezfVTRmRQgCgHbx"
  201. "wcZlInVOwmFePnSIbThMJosimzkhfuiqYEpwHQiemqsSDNNdbNhBLzbsPZBJZujSHJGtYKGb"
  202. "HaAYGJZxBumsKUrATwPuqXFLfwNyImLQbchBKiJAYRZhkcrKCHXBEGYyBhBGvSqvabcRUrfq"
  203. "AbPiMzjHAehGYjDEmxAnYLyoSFdeWVrfJUCuYZPluhXEBuyUpKaRXDKXeiCvGidpvATwMbcz"
  204. "DZpzxrhTZYyrFORFQWTbPLCBjMKMhlRMFEiarDgGPttjmkrQVlujztMSkxXffXFNqLWOLThI"
  205. "KBoyMHoFTEPCdUAZjLTifAdjjUehyDLEGKlRTFoLpjalziRSUjZfRYbNzhiHgTHowMMkKTwE"
  206. "ZgnqiirMtnNpaBJqhcIVrWXPpcPWZfRpsPstHleFJDZYAsxYhOREVbFtebXTZRAIjGgWeoiN"
  207. "qPLCCAVadqmUrjOcqIbdCTpcDRWuDVbHrZOQRPhqbyvOWwxAWJphjLiDgoAybcjzgfVktPlj"
  208. "kNBCjelpuQfnYsiTgPpCNKYtOrxGaLEEtAuLdGdDsONHNhSn";
  209. const std::string dst_str =
  210. "KzitfifORCbGhfNEbnbObUdFLLaAsLOpMkOeKupjCoatzqfHBkNJfSgqSMYouswfNMnoQngK"
  211. "jWwyPKmEnoZWyPBUdQRmKUNudUclueKXKQefUdXWUyyqtumzsFKznrLVLwfvPZpLChNYrrHK"
  212. "AtpfOuVHiUKyeRCrktJAhkyFKmPWrASEMvBLNOzuGlvinZjvZUUXazNEkyMPiOLdqXvCIroC"
  213. "MeWsvjHShlLhDwLZrVlpYBnDJmILcsNFDSoaLWOKNNkNGBgNBvVjPCJXAuKfsrKZhYcdEpxK"
  214. "UihiRkYvMiLyOUvaqBMklLDwEhvQBfCXHSRoqsLsSCzLZQhIYMhBapvHaPbDoRrHoJXZsNXc"
  215. "rxZYCrOMIzYcVPwDCFiHBFnPNTTeAeKEMGeVUeCaAeuWZmngyPWlQBcgWumSUIfbhjVYdnpV"
  216. "hRSJXrIoFZubBXfNOMhilAkVPixrhILZKgDoFTvytPFPfBLMnbhSOBmLWCbJsLQxrCrMAlOw"
  217. "RmfSQyGhrjhzYVqFSBHeoQBagFwyxIjcHFZngntpVHbSwqhwHeMnWSsISPljTxSNXfCxLebW"
  218. "GhMdlphtJbdvhEcjNpwPCFqhdquxCyOxkjsDUPNgjpDcpIMhMwMclNhfESTrroJaoyeGQclV"
  219. "gonnhuQRmXcBwcsWeLqjNngZOlyMyfeQBwnwMVJEvGqknDyzSApniRTPgJpFoDkJJhXQFuFB"
  220. "VqhuEPMRGCeTDOSEFmXeIHOnDxaJacvnmORwVpmrRhGjDpUCkuODNPdZMdupYExDEDnDLdNF"
  221. "iObKBaVWpGVMKdgNLgsNxcpypBPPKKoaajeSGPZQJWSOKrkLjiFexYVmUGxJnbTNsCXXLfZp"
  222. "jfxQAEVYvqKehBzMsVHVGWmTshWFAoCNDkNppzzjHBZWckrzSTANICioCJSpLwPwQvtXVxst"
  223. "nTRBAboPFREEUFazibpFesCsjzUOnECwoPCOFiwGORlIZVLpUkJyhYXCENmzTBLVigOFuCWO"
  224. "IiXBYmiMtsxnUdoqSTTGyEFFrQsNAjcDdOKDtHwlANWoUVwiJCMCQFILdGqzEePuSXFbOEOz"
  225. "dLlEnTJbKRSTfAFToOZNtDXTfFgvQiefAKbSUWUXFcpCjRYCBNXCCcLMjjuUDXErpiNsRuIx"
  226. "mgHsrObTEXcnmjdqxTGhTjTeYizNnkrJRhNQIqDXmZMwArBccnixpcuiGOOexjgkpcEyGAnz"
  227. "UbgiBfflTUyJfZeFFLrZVueFkSRosebnnwAnakIrywTGByhQKWvmNQJsWQezqLhHQzXnEpeD"
  228. "rFRTSQSpVxPzSeEzfWYzfpcenxsUyzOMLxhNEhfcuprDtqubsXehuqKqZlLQeSclvoGjuKJK"
  229. "XoWrazsgjXXnkWHdqFESZdMGDYldyYdbpSZcgBPgEKLWZHfBirNPLUadmajYkiEzmGuWGELB"
  230. "WLiSrMdaGSbptKmgYVqMGcQaaATStiZYteGAPxSEBHuAzzjlRHYsrdDkaGNXmzRGoalJMiCC"
  231. "GMtWSDMhgvRSEgKnywbRgnqWXFlwrhXbbvcgLGtWSuKQBiqIlWkfPMozOTWgVoLHavDJGRYI"
  232. "YerrmZnTMtuuxmZALWakfzUbksTwoetqkOiRPGqGZepcVXHoZyOaaaijjZWQLlIhYwiQNbfc"
  233. "KCwhhFaMQBoaCnOecJEdKzdsMPFEYQuJNPYiiNtsYxaWBRuWjlLqGokHMNtyTQfSJKbgGdol"
  234. "fWlOZdupouQMfUWXIYHzyJHefMDnqxxasDxtgArvDqtwjDBaVEMACPkLFpiDOoKCHqkWVizh"
  235. "lKqbOHpsPKkhjRQRNGYRYEfxtBjYvlCvHBNUwVuIwDJYMqHxEFtwdLqYWvjdOfQmNiviDfUq"
  236. "pbucbNwjNQfMYgwUuPnQWIPOlqHcbjtuDXvTzLtkdBQanJbrmLSyFqSapZCSPMDOrxWVYzyO"
  237. "lwDTTJFmKxoyfPunadkHcrcSQaQsAbrQtbhqwSTXGTPURYTCbNozjAVwbmcyVxIbZudBZWYm"
  238. "rnSDyelGCRRWYtrUxvOVWlTLHHdYuAmVMGnGbHscbjmjmAzmYLaCxNNwhmMYdExKvySxuYpE"
  239. "rVGwfqMngBCHnZodotNaNJZiNRFWubuPDfiywXPiyVWoQMeOlSuWmpilLTIFOvfpjmJTgrWa"
  240. "dgoxYeyPyOaglOvZVGdFOBSeqEcGXBwjoeUAXqkpvOxEpSXhmklKZydTvRVYVvfQdRNNDkCT"
  241. "dLNfcZCFQbZORdcDOhwotoyccrSbWvlqYMoiAYeEpDzZTvkamapzZMmCpEutZFCcHBWGIIkr"
  242. "urwDNHrobaErPpclyEegLJDtkfUWSNWZosWSbBGAHIvJsFNUlJXbnkSVycLkOVQVcNcUtiBy"
  243. "djLDIFsycbPBEWaMvCbntNtJlOeCttvXypGnHAQFnFSiXFWWqonWuVIKmVPpKXuJtFguXCWC"
  244. "rNExYYvxLGEmuZJLJDjHgjlQyOzeieCpizJxkrdqKCgomyEkvsyVYSsLeyLvOZQrrgEJgRFK"
  245. "CjYtoOfluNrLdRMTRkQXmAiMRFwloYECpXCReAMxOkNiwCtutsrqWoMHsrogRqPoUCueonvW"
  246. "MTwmkAkajfGJkhnQidwpwIMEttQkzIMOPvvyWZHpqkMHWlNTeSKibfRfwDyxveKENZhtlPwP"
  247. "dfAjwegjRcavtFnkkTNVYdCdCrgdUvzsIcqmUjwGmVvuuQvjVrWWIDBmAzQtiZPYvCOEWjce"
  248. "rWzeqVKeiYTJBOedmQCVidOgUIEjfRnbGvUbctYxfRybJkdmeAkLZQMRMGPOnsPbFswXAoCK"
  249. "IxWGwohoPpEJxslbqHFKSwknxTmrDCITRZWEDkGQeucPxHBdYkduwbYhKnoxCKhgjBFiFawC"
  250. "QtgTDldTQmlOsBiGLquMjuecAbrUJJvNtXbFNGjWxaZPimSRXUJWgRbydpsczOqSFIeEtuKA"
  251. "ZpRhmLtPdVNKdSDQZeeImUFmUwXApRTUNHItyvFyJtNtn";
  252. Sequence src;
  253. Sequence dst;
  254. src.reserve(src_str.length());
  255. dst.reserve(dst_str.length());
  256. for (char c : src_str) {
  257. src.push_back(c);
  258. }
  259. for (char c : dst_str) {
  260. dst.push_back(c);
  261. }
  262. VerifyMatch(src, dst, 723);
  263. }
  264. } // namespace
  265. } // namespace diff
  266. } // namespace spvtools