| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- // Copyright (c) 2022 Google LLC.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include "source/diff/lcs.h"
- #include <string>
- #include "gtest/gtest.h"
- namespace spvtools {
- namespace diff {
- namespace {
- using Sequence = std::vector<int>;
- using LCS = LongestCommonSubsequence<Sequence>;
- void VerifyMatch(const Sequence& src, const Sequence& dst,
- size_t expected_match_count) {
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- EXPECT_EQ(match_count, expected_match_count);
- size_t src_cur = 0;
- size_t dst_cur = 0;
- size_t matches_seen = 0;
- while (src_cur < src.size() && dst_cur < dst.size()) {
- if (src_match[src_cur] && dst_match[dst_cur]) {
- EXPECT_EQ(src[src_cur], dst[dst_cur])
- << "Src: " << src_cur << " Dst: " << dst_cur;
- ++src_cur;
- ++dst_cur;
- ++matches_seen;
- continue;
- }
- if (!src_match[src_cur]) {
- ++src_cur;
- }
- if (!dst_match[dst_cur]) {
- ++dst_cur;
- }
- }
- EXPECT_EQ(matches_seen, expected_match_count);
- }
- TEST(LCSTest, EmptySequences) {
- Sequence src, dst;
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- EXPECT_EQ(match_count, 0u);
- EXPECT_TRUE(src_match.empty());
- EXPECT_TRUE(dst_match.empty());
- }
- TEST(LCSTest, EmptySrc) {
- Sequence src, dst = {1, 2, 3};
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- EXPECT_EQ(match_count, 0u);
- EXPECT_TRUE(src_match.empty());
- EXPECT_EQ(dst_match, DiffMatch(3, false));
- }
- TEST(LCSTest, EmptyDst) {
- Sequence src = {1, 2, 3}, dst;
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- EXPECT_EQ(match_count, 0u);
- EXPECT_EQ(src_match, DiffMatch(3, false));
- EXPECT_TRUE(dst_match.empty());
- }
- TEST(LCSTest, Identical) {
- Sequence src = {1, 2, 3, 4, 5, 6}, dst = {1, 2, 3, 4, 5, 6};
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- EXPECT_EQ(match_count, 6u);
- EXPECT_EQ(src_match, DiffMatch(6, true));
- EXPECT_EQ(dst_match, DiffMatch(6, true));
- }
- TEST(LCSTest, SrcPrefix) {
- Sequence src = {1, 2, 3, 4}, dst = {1, 2, 3, 4, 5, 6};
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- const DiffMatch src_expect = {true, true, true, true};
- const DiffMatch dst_expect = {true, true, true, true, false, false};
- EXPECT_EQ(match_count, 4u);
- EXPECT_EQ(src_match, src_expect);
- EXPECT_EQ(dst_match, dst_expect);
- }
- TEST(LCSTest, DstPrefix) {
- Sequence src = {1, 2, 3, 4, 5, 6}, dst = {1, 2, 3, 4, 5};
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- const DiffMatch src_expect = {true, true, true, true, true, false};
- const DiffMatch dst_expect = {true, true, true, true, true};
- EXPECT_EQ(match_count, 5u);
- EXPECT_EQ(src_match, src_expect);
- EXPECT_EQ(dst_match, dst_expect);
- }
- TEST(LCSTest, SrcSuffix) {
- Sequence src = {3, 4, 5, 6}, dst = {1, 2, 3, 4, 5, 6};
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- const DiffMatch src_expect = {true, true, true, true};
- const DiffMatch dst_expect = {false, false, true, true, true, true};
- EXPECT_EQ(match_count, 4u);
- EXPECT_EQ(src_match, src_expect);
- EXPECT_EQ(dst_match, dst_expect);
- }
- TEST(LCSTest, DstSuffix) {
- Sequence src = {1, 2, 3, 4, 5, 6}, dst = {5, 6};
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- const DiffMatch src_expect = {false, false, false, false, true, true};
- const DiffMatch dst_expect = {true, true};
- EXPECT_EQ(match_count, 2u);
- EXPECT_EQ(src_match, src_expect);
- EXPECT_EQ(dst_match, dst_expect);
- }
- TEST(LCSTest, None) {
- Sequence src = {1, 3, 5, 7, 9}, dst = {2, 4, 6, 8, 10, 12};
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- EXPECT_EQ(match_count, 0u);
- EXPECT_EQ(src_match, DiffMatch(5, false));
- EXPECT_EQ(dst_match, DiffMatch(6, false));
- }
- TEST(LCSTest, NonContiguous) {
- Sequence src = {1, 2, 3, 4, 5, 6, 10}, dst = {2, 4, 5, 8, 9, 10, 12};
- DiffMatch src_match, dst_match;
- LCS lcs(src, dst);
- size_t match_count =
- lcs.Get<int>([](int s, int d) { return s == d; }, &src_match, &dst_match);
- const DiffMatch src_expect = {false, true, false, true, true, false, true};
- const DiffMatch dst_expect = {true, true, true, false, false, true, false};
- EXPECT_EQ(match_count, 4u);
- EXPECT_EQ(src_match, src_expect);
- EXPECT_EQ(dst_match, dst_expect);
- }
- TEST(LCSTest, WithDuplicates) {
- Sequence src = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4},
- dst = {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4};
- VerifyMatch(src, dst, 6);
- }
- TEST(LCSTest, Large) {
- const std::string src_str =
- "GUJwrJSlkKJXxCVIAxlVgnUyOrdyRyFtlZwWMmFhYGfkFTNnhiBmClgHyrcXMVwfrRxNUfQk"
- "qaoGvCbPZHAzXsaZpXHPfJxOMCUtRDmIQpfiXKbHQbhTfPqhxBDWvmTQAqwsWTLajZYtMUnf"
- "hNNCfkuAXkZsaebwEbIZOxTDZsqSMUfCMoGeKJGVSNFgLTiBMbdvchHGfFRkHKcYCDjBfIcj"
- "todPnvDjzQYWBcvIfVvyBzHikrwpDORaGEZLhmyztIFCLJOqeLhOzERYmVqzlsoUzruTXTXq"
- "DLTxQRakOCMRrgRzCDTXfwwfDcKMBVnxRZemjcwcEsOVxwtwdBCWJycsDcZKlvrCvZaenKlv"
- "vyByDQeLdxAyBnPkIMQlMQwqjUfRLybeoaOanlbFkpTPPZdHelQrIvucTHzMpWWQTbuANwvN"
- "OVhCGGoIcGNDpfIsaBexlMMdHsxMGerTngmjpdPeQQJHfvKZkdYqAzrtDohqtDsaFMxQViVQ"
- "YszDVgyoSHZdOXAvXkJidojLvGZOzhRajVPhWDwKuGqdaympELxHsrXAJYufdCPwJdGJfWqq"
- "yvTWpcrFHOIuCEmNLnSCDsxQGRVDwyCykBJazhApfCnrOadnafvqfVuFqEXMSrYbHTfTnzbz"
- "MhISyOtMUITaurCXvanCbuOXBhHyCjOhVbxnMvhlPmZBMQgEHCghtAJVMXGPNRtszVZlPxVl"
- "QIPTBnPUPejlyZGPqeICyNngdQGkvKbIoWlTLBtVhMdBeUMozNlKQTIPYBeImVcMdLafuxUf"
- "TIXysmcTrUTcspOSKBxhdhLwiRnREGFWJTfUKsgGOAQeYojXdrqsGjMJfiKalyoiqrgLnlij"
- "CtOapoxDGVOOBalNYGzCtBlxbvaAzxipGnJpOEbmXcpeoIsAdxspKBzBDgoPVxnuRBUwmTSr"
- "CRpWhxikgUYQVCwalLUIeBPRyhhsECGCXJmGDZSCIUaBwROkigzdeVPOXhgCGBEprWtNdYfL"
- "tOUYJHQXxiIJgSGmWntezJFpNQoTPbRRYAGhtYvAechvBcYWocLkYFxsDAuszvQNLXdhmAHw"
- "DErcjbtCdQllnKcDADVNWVezljjLrAuyGHetINMgAvJZwOEYakihYVUbZGCsHEufluLNyNHy"
- "gqtSTSFFjBHiIqQejTPWybLdpWNwZrWvIWnlzUcGNQPEYHVPCbteWknjAnWrdTBeCbHUDBoK"
- "aHvDStmpNRGIjvlumiZTbdZNAzUeSFnFChCsSExwXeEfDJfjyOoSBofHzJqJErvHLNyUJTjX"
- "qmtgKPpMKohUPBMhtCteQFcNEpWrUVGbibMOpvBwdiWYXNissArpSasVJFgDzrqTyGkerTMX"
- "gcrzFUGFZRhNdekaJeKYPogsofJaRsUQmIRyYdkrxKeMgLPpwOfSKJOqzXDoeHljTzhOwEVy"
- "krOEnACFrWhufajsMitjOWdLOHHchQDddGPzxknEgdwmZepKDvRZGCuPqzeQkjOPqUBKpKLJ"
- "eKieSsRXkaqxSPGajfvPKmwFWdLByEcLgvrmteazgFjmMGrLYqRRxzUOfOCokenqHVYstBHf"
- "AwsWsqPTvqsRJUfGGTaYiylZMGbQqTzINhFHvdlRQvvYKBcuAHdBeKlHSxVrSsEKbcAvnIcf"
- "xzdVDdwQPHMCHeZZRpGHWvKzgTGzSTbYTeOPyKvvYWmQToTpsjAtKUJUjcEHWhmdBLDTBMHJ"
- "ivBXcLGtCsumNNVFyGbVviGmqHTdyBlkneibXBesKJGOUzOtIwXCPJggqBekSzNQYkALlItk"
- "cbEhbdXAIKVHYpInLwxXalKZrkrpxtfuagqMGmRJnJbFQaEoYMoqPsxZpocddPXXPyvxVkaF"
- "qdKISejWDhBImnEEOPDcyWTubbfVfwUztciaFJcsPLhgYVfhqlOfoNjKbmTFptFttYuyBrUI"
- "zzmZypOqrjQHTGFwlHStpIwxPtMvtsEDpsmWIgwzYgwmdpbMOnfElZMYpVIcvzSWejeJcdUB"
- "QUoBRUmGQVVWvEDseuozrDjgdXFScPwwsgaUPwSzScfBNrkpmEFDSZLKfNjMqvOmUtocUkbo"
- "VGFEKgGLbNruwLgXHTloWDrnqymPVAtzjWPutonIsMDPeeCmTjYWAFXcyTAlBeiJTIRkZxiM"
- "kLjMnAflSNJzmZkatXkYiPEMYSmzHbLKEizHbEjQOxBDzpRHiFjhedqiyMiUMvThjaRFmwll"
- "aMGgwKBIKepwyoEdnuhtzJzboiNEAFKiqiWxxmkRFRoTiFWXLPAWLuzSCrajgkQhDxAQDqyM"
- "VwZlhZicQLEDYYisEalesDWZAYzcvENuHUwRutIsGgsdoYwOZiURhcgdbTGWBNqhrFjvTQCj"
- "VlTPNlRdRLaaqzUBBwbdtyXFkCBUYYMbmRrkFxfxbCqkgZNGyHPKLkOPnezfVTRmRQgCgHbx"
- "wcZlInVOwmFePnSIbThMJosimzkhfuiqYEpwHQiemqsSDNNdbNhBLzbsPZBJZujSHJGtYKGb"
- "HaAYGJZxBumsKUrATwPuqXFLfwNyImLQbchBKiJAYRZhkcrKCHXBEGYyBhBGvSqvabcRUrfq"
- "AbPiMzjHAehGYjDEmxAnYLyoSFdeWVrfJUCuYZPluhXEBuyUpKaRXDKXeiCvGidpvATwMbcz"
- "DZpzxrhTZYyrFORFQWTbPLCBjMKMhlRMFEiarDgGPttjmkrQVlujztMSkxXffXFNqLWOLThI"
- "KBoyMHoFTEPCdUAZjLTifAdjjUehyDLEGKlRTFoLpjalziRSUjZfRYbNzhiHgTHowMMkKTwE"
- "ZgnqiirMtnNpaBJqhcIVrWXPpcPWZfRpsPstHleFJDZYAsxYhOREVbFtebXTZRAIjGgWeoiN"
- "qPLCCAVadqmUrjOcqIbdCTpcDRWuDVbHrZOQRPhqbyvOWwxAWJphjLiDgoAybcjzgfVktPlj"
- "kNBCjelpuQfnYsiTgPpCNKYtOrxGaLEEtAuLdGdDsONHNhSn";
- const std::string dst_str =
- "KzitfifORCbGhfNEbnbObUdFLLaAsLOpMkOeKupjCoatzqfHBkNJfSgqSMYouswfNMnoQngK"
- "jWwyPKmEnoZWyPBUdQRmKUNudUclueKXKQefUdXWUyyqtumzsFKznrLVLwfvPZpLChNYrrHK"
- "AtpfOuVHiUKyeRCrktJAhkyFKmPWrASEMvBLNOzuGlvinZjvZUUXazNEkyMPiOLdqXvCIroC"
- "MeWsvjHShlLhDwLZrVlpYBnDJmILcsNFDSoaLWOKNNkNGBgNBvVjPCJXAuKfsrKZhYcdEpxK"
- "UihiRkYvMiLyOUvaqBMklLDwEhvQBfCXHSRoqsLsSCzLZQhIYMhBapvHaPbDoRrHoJXZsNXc"
- "rxZYCrOMIzYcVPwDCFiHBFnPNTTeAeKEMGeVUeCaAeuWZmngyPWlQBcgWumSUIfbhjVYdnpV"
- "hRSJXrIoFZubBXfNOMhilAkVPixrhILZKgDoFTvytPFPfBLMnbhSOBmLWCbJsLQxrCrMAlOw"
- "RmfSQyGhrjhzYVqFSBHeoQBagFwyxIjcHFZngntpVHbSwqhwHeMnWSsISPljTxSNXfCxLebW"
- "GhMdlphtJbdvhEcjNpwPCFqhdquxCyOxkjsDUPNgjpDcpIMhMwMclNhfESTrroJaoyeGQclV"
- "gonnhuQRmXcBwcsWeLqjNngZOlyMyfeQBwnwMVJEvGqknDyzSApniRTPgJpFoDkJJhXQFuFB"
- "VqhuEPMRGCeTDOSEFmXeIHOnDxaJacvnmORwVpmrRhGjDpUCkuODNPdZMdupYExDEDnDLdNF"
- "iObKBaVWpGVMKdgNLgsNxcpypBPPKKoaajeSGPZQJWSOKrkLjiFexYVmUGxJnbTNsCXXLfZp"
- "jfxQAEVYvqKehBzMsVHVGWmTshWFAoCNDkNppzzjHBZWckrzSTANICioCJSpLwPwQvtXVxst"
- "nTRBAboPFREEUFazibpFesCsjzUOnECwoPCOFiwGORlIZVLpUkJyhYXCENmzTBLVigOFuCWO"
- "IiXBYmiMtsxnUdoqSTTGyEFFrQsNAjcDdOKDtHwlANWoUVwiJCMCQFILdGqzEePuSXFbOEOz"
- "dLlEnTJbKRSTfAFToOZNtDXTfFgvQiefAKbSUWUXFcpCjRYCBNXCCcLMjjuUDXErpiNsRuIx"
- "mgHsrObTEXcnmjdqxTGhTjTeYizNnkrJRhNQIqDXmZMwArBccnixpcuiGOOexjgkpcEyGAnz"
- "UbgiBfflTUyJfZeFFLrZVueFkSRosebnnwAnakIrywTGByhQKWvmNQJsWQezqLhHQzXnEpeD"
- "rFRTSQSpVxPzSeEzfWYzfpcenxsUyzOMLxhNEhfcuprDtqubsXehuqKqZlLQeSclvoGjuKJK"
- "XoWrazsgjXXnkWHdqFESZdMGDYldyYdbpSZcgBPgEKLWZHfBirNPLUadmajYkiEzmGuWGELB"
- "WLiSrMdaGSbptKmgYVqMGcQaaATStiZYteGAPxSEBHuAzzjlRHYsrdDkaGNXmzRGoalJMiCC"
- "GMtWSDMhgvRSEgKnywbRgnqWXFlwrhXbbvcgLGtWSuKQBiqIlWkfPMozOTWgVoLHavDJGRYI"
- "YerrmZnTMtuuxmZALWakfzUbksTwoetqkOiRPGqGZepcVXHoZyOaaaijjZWQLlIhYwiQNbfc"
- "KCwhhFaMQBoaCnOecJEdKzdsMPFEYQuJNPYiiNtsYxaWBRuWjlLqGokHMNtyTQfSJKbgGdol"
- "fWlOZdupouQMfUWXIYHzyJHefMDnqxxasDxtgArvDqtwjDBaVEMACPkLFpiDOoKCHqkWVizh"
- "lKqbOHpsPKkhjRQRNGYRYEfxtBjYvlCvHBNUwVuIwDJYMqHxEFtwdLqYWvjdOfQmNiviDfUq"
- "pbucbNwjNQfMYgwUuPnQWIPOlqHcbjtuDXvTzLtkdBQanJbrmLSyFqSapZCSPMDOrxWVYzyO"
- "lwDTTJFmKxoyfPunadkHcrcSQaQsAbrQtbhqwSTXGTPURYTCbNozjAVwbmcyVxIbZudBZWYm"
- "rnSDyelGCRRWYtrUxvOVWlTLHHdYuAmVMGnGbHscbjmjmAzmYLaCxNNwhmMYdExKvySxuYpE"
- "rVGwfqMngBCHnZodotNaNJZiNRFWubuPDfiywXPiyVWoQMeOlSuWmpilLTIFOvfpjmJTgrWa"
- "dgoxYeyPyOaglOvZVGdFOBSeqEcGXBwjoeUAXqkpvOxEpSXhmklKZydTvRVYVvfQdRNNDkCT"
- "dLNfcZCFQbZORdcDOhwotoyccrSbWvlqYMoiAYeEpDzZTvkamapzZMmCpEutZFCcHBWGIIkr"
- "urwDNHrobaErPpclyEegLJDtkfUWSNWZosWSbBGAHIvJsFNUlJXbnkSVycLkOVQVcNcUtiBy"
- "djLDIFsycbPBEWaMvCbntNtJlOeCttvXypGnHAQFnFSiXFWWqonWuVIKmVPpKXuJtFguXCWC"
- "rNExYYvxLGEmuZJLJDjHgjlQyOzeieCpizJxkrdqKCgomyEkvsyVYSsLeyLvOZQrrgEJgRFK"
- "CjYtoOfluNrLdRMTRkQXmAiMRFwloYECpXCReAMxOkNiwCtutsrqWoMHsrogRqPoUCueonvW"
- "MTwmkAkajfGJkhnQidwpwIMEttQkzIMOPvvyWZHpqkMHWlNTeSKibfRfwDyxveKENZhtlPwP"
- "dfAjwegjRcavtFnkkTNVYdCdCrgdUvzsIcqmUjwGmVvuuQvjVrWWIDBmAzQtiZPYvCOEWjce"
- "rWzeqVKeiYTJBOedmQCVidOgUIEjfRnbGvUbctYxfRybJkdmeAkLZQMRMGPOnsPbFswXAoCK"
- "IxWGwohoPpEJxslbqHFKSwknxTmrDCITRZWEDkGQeucPxHBdYkduwbYhKnoxCKhgjBFiFawC"
- "QtgTDldTQmlOsBiGLquMjuecAbrUJJvNtXbFNGjWxaZPimSRXUJWgRbydpsczOqSFIeEtuKA"
- "ZpRhmLtPdVNKdSDQZeeImUFmUwXApRTUNHItyvFyJtNtn";
- Sequence src;
- Sequence dst;
- src.reserve(src_str.length());
- dst.reserve(dst_str.length());
- for (char c : src_str) {
- src.push_back(c);
- }
- for (char c : dst_str) {
- dst.push_back(c);
- }
- VerifyMatch(src, dst, 723);
- }
- } // namespace
- } // namespace diff
- } // namespace spvtools
|