LCOV - code coverage report
Current view: top level - tests - catch_remove_duplicates.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 189 189
Test Date: 2025-07-03 19:05:49 Functions: 100.0 % 3 3
Legend: Lines: hit not hit

            Line data    Source code
       1              : // Copyright (c) 2018-2025  Made to Order Software Corp.  All Rights Reserved
       2              : //
       3              : // https://snapwebsites.org/project/snapdev
       4              : // contact@m2osw.com
       5              : //
       6              : // This program is free software: you can redistribute it and/or modify
       7              : // it under the terms of the GNU General Public License as published by
       8              : // the Free Software Foundation, either version 3 of the License, or
       9              : // (at your option) any later version.
      10              : //
      11              : // This program is distributed in the hope that it will be useful,
      12              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : // GNU General Public License for more details.
      15              : //
      16              : // You should have received a copy of the GNU General Public License
      17              : // along with this program.  If not, see <https://www.gnu.org/licenses/>.
      18              : 
      19              : /** \file
      20              :  * \brief Verify that the different remove duplicate algorithms work.
      21              :  *
      22              :  * This file implements tests for the different remove duplicate functions.
      23              :  */
      24              : 
      25              : // self
      26              : //
      27              : #include    <snapdev/remove_duplicates.h>
      28              : 
      29              : #include    "catch_main.h"
      30              : 
      31              : 
      32              : // C++
      33              : //
      34              : #include    <deque>
      35              : #include    <list>
      36              : 
      37              : 
      38              : // last include
      39              : //
      40              : #include    <snapdev/poison.h>
      41              : 
      42              : 
      43              : namespace
      44              : {
      45              : 
      46              : 
      47              : 
      48              : 
      49              : 
      50              : }
      51              : // no name namespace
      52              : 
      53              : 
      54              : 
      55            3 : CATCH_TEST_CASE("sort_and_remove_duplicates", "[remove_duplicates][container]")
      56              : {
      57            3 :     CATCH_START_SECTION("sort_and_remove_duplicates: empty container")
      58              :     {
      59            1 :         std::vector<std::string> empty;
      60            1 :         std::vector<std::string> *output = &snapdev::sort_and_remove_duplicates(empty);
      61            1 :         CATCH_REQUIRE(&empty == output);
      62            1 :         CATCH_REQUIRE(empty.empty());
      63            1 :     }
      64            3 :     CATCH_END_SECTION()
      65              : 
      66            3 :     CATCH_START_SECTION("sort_and_remove_duplicates: container without duplicates")
      67              :     {
      68           11 :         for(int count(0); count < 10; ++count)
      69              :         {
      70           10 :             std::vector<std::string> container;
      71           10 :             std::size_t size(rand() % 100 + 50);
      72         1159 :             while(container.size() < size)
      73              :             {
      74         1149 :                 std::string const s(SNAP_CATCH2_NAMESPACE::random_string(0, rand() % 25));
      75         1149 :                 if(std::find(container.begin(), container.end(), s) == container.end())
      76              :                 {
      77          970 :                     container.push_back(s);
      78              :                 }
      79         1149 :             }
      80           10 :             std::vector<std::string> copy(container);
      81           10 :             std::vector<std::string> *output = &snapdev::sort_and_remove_duplicates(container);
      82           10 :             CATCH_REQUIRE(&container == output);
      83           10 :             CATCH_REQUIRE(container.size() == copy.size());
      84              : 
      85           10 :             std::sort(copy.begin(), copy.end());
      86           10 :             CATCH_REQUIRE(container == copy);
      87           10 :         }
      88              :     }
      89            3 :     CATCH_END_SECTION()
      90              : 
      91            3 :     CATCH_START_SECTION("sort_and_remove_duplicates: container with duplicates")
      92              :     {
      93           11 :         for(int count(0); count < 10; ++count)
      94              :         {
      95           10 :             std::vector<std::string> container;
      96              : 
      97              :             // we want to be in control of the duplication and know exactly what
      98              :             // we are going to get back out so we need to create a container
      99              :             // without duplicates first then add duplicates in a second loop
     100              :             //
     101           10 :             std::size_t size(rand() % 100 + 50);
     102         1221 :             while(container.size() < size)
     103              :             {
     104         1211 :                 std::string const s(SNAP_CATCH2_NAMESPACE::random_string(0, rand() % 25));
     105         1211 :                 if(std::find(container.begin(), container.end(), s) == container.end())
     106              :                 {
     107         1013 :                     container.push_back(s);
     108              :                 }
     109         1211 :             }
     110           10 :             std::vector<std::string> copy(container);
     111           10 :             std::size_t dups(rand() % 50 + 25);
     112          491 :             for(std::size_t i(0); i < dups; ++i)
     113              :             {
     114          481 :                 int const d(rand() % container.size());
     115          481 :                 int const p(rand() % (container.size() + 1));
     116          481 :                 container.insert(container.begin() + p, container[d]);
     117              :             }
     118           10 :             std::vector<std::string> *output = &snapdev::sort_and_remove_duplicates(container);
     119           10 :             CATCH_REQUIRE(&container == output);
     120           10 :             CATCH_REQUIRE(container.size() == copy.size());
     121              : 
     122           10 :             std::sort(copy.begin(), copy.end());
     123           10 :             CATCH_REQUIRE(container == copy);
     124           10 :         }
     125              :     }
     126            3 :     CATCH_END_SECTION()
     127            3 : }
     128              : 
     129              : 
     130            4 : CATCH_TEST_CASE("sorted_remove_duplicates", "[remove_duplicates][container]")
     131              : {
     132            4 :     CATCH_START_SECTION("sorted_remove_duplicates: empty container")
     133              :     {
     134            1 :         std::vector<std::string> empty;
     135            1 :         std::vector<std::string> *output = &snapdev::sorted_remove_duplicates(empty);
     136            1 :         CATCH_REQUIRE(&empty == output);
     137            1 :         CATCH_REQUIRE(empty.empty());
     138            1 :     }
     139            4 :     CATCH_END_SECTION()
     140              : 
     141            4 :     CATCH_START_SECTION("sorted_remove_duplicates: container without duplicates")
     142              :     {
     143           11 :         for(int count(0); count < 10; ++count)
     144              :         {
     145           10 :             std::vector<std::string> container;
     146           10 :             std::size_t size(rand() % 100 + 50);
     147         1477 :             while(container.size() < size)
     148              :             {
     149         1467 :                 std::string const s(SNAP_CATCH2_NAMESPACE::random_string(0, rand() % 25));
     150         1467 :                 if(std::find(container.begin(), container.end(), s) == container.end())
     151              :                 {
     152         1245 :                     container.push_back(s);
     153              :                 }
     154         1467 :             }
     155           10 :             std::sort(container.begin(), container.end());
     156           10 :             std::vector<std::string> copy(container);
     157           10 :             std::vector<std::string> *output = &snapdev::sorted_remove_duplicates(container);
     158           10 :             CATCH_REQUIRE(&container == output);
     159           10 :             CATCH_REQUIRE(container.size() == copy.size());
     160           10 :             CATCH_REQUIRE(container == copy);
     161           10 :         }
     162              :     }
     163            4 :     CATCH_END_SECTION()
     164              : 
     165            4 :     CATCH_START_SECTION("sorted_remove_duplicates: container with duplicates")
     166              :     {
     167           11 :         for(int count(0); count < 10; ++count)
     168              :         {
     169           10 :             std::vector<std::string> container;
     170              : 
     171              :             // we want to be in control of the duplication and know exactly what
     172              :             // we are going to get back out so we need to create a container
     173              :             // without duplicates first then add duplicates in a second loop
     174              :             //
     175           10 :             std::size_t size(rand() % 100 + 50);
     176         1073 :             while(container.size() < size)
     177              :             {
     178         1063 :                 std::string const s(SNAP_CATCH2_NAMESPACE::random_string(0, rand() % 25));
     179         1063 :                 if(std::find(container.begin(), container.end(), s) == container.end())
     180              :                 {
     181          877 :                     container.push_back(s);
     182              :                 }
     183         1063 :             }
     184           10 :             std::vector<std::string> copy(container);
     185           10 :             std::size_t dups(rand() % 50 + 25);
     186          571 :             for(std::size_t i(0); i < dups; ++i)
     187              :             {
     188          561 :                 int const d(rand() % container.size());
     189          561 :                 int const p(rand() % (container.size() + 1));
     190          561 :                 container.insert(container.begin() + p, container[d]);
     191              :             }
     192           10 :             std::sort(container.begin(), container.end());
     193           10 :             std::vector<std::string> *output = &snapdev::sorted_remove_duplicates(container);
     194           10 :             CATCH_REQUIRE(&container == output);
     195           10 :             CATCH_REQUIRE(container.size() == copy.size());
     196              : 
     197           10 :             std::sort(copy.begin(), copy.end());
     198           10 :             CATCH_REQUIRE(container == copy);
     199           10 :         }
     200              :     }
     201            4 :     CATCH_END_SECTION()
     202              : 
     203            4 :     CATCH_START_SECTION("sorted_remove_duplicates: container with one item duplicated")
     204              :     {
     205           11 :         for(int count(0); count < 10; ++count)
     206              :         {
     207           10 :             std::list<std::string> container;
     208              : 
     209              :             // we want to be in control of the duplication and know exactly what
     210              :             // we are going to get back out so we need to create a container
     211              :             // without duplicates first then add duplicates in a second loop
     212              :             //
     213           10 :             std::string const s(SNAP_CATCH2_NAMESPACE::random_string(0, rand() % 25));
     214           10 :             std::size_t size(rand() % 100 + 50);
     215         1080 :             while(container.size() < size)
     216              :             {
     217         1070 :                 container.push_back(s);
     218              :             }
     219           10 :             std::list<std::string> *output = &snapdev::sorted_remove_duplicates(container);
     220           10 :             CATCH_REQUIRE(&container == output);
     221           10 :             CATCH_REQUIRE(container.size() == 1);
     222           10 :             CATCH_REQUIRE(container.front() == s);
     223           10 :         }
     224              :     }
     225            4 :     CATCH_END_SECTION()
     226            4 : }
     227              : 
     228              : 
     229            5 : CATCH_TEST_CASE("unsorted_remove_duplicates", "[remove_duplicates][container]")
     230              : {
     231            5 :     CATCH_START_SECTION("unsorted_remove_duplicates: empty container")
     232              :     {
     233            1 :         std::vector<std::string> empty;
     234            1 :         std::vector<std::string> *output = &snapdev::unsorted_remove_duplicates(empty);
     235            1 :         CATCH_REQUIRE(&empty == output);
     236            1 :         CATCH_REQUIRE(empty.empty());
     237            1 :     }
     238            5 :     CATCH_END_SECTION()
     239              : 
     240            5 :     CATCH_START_SECTION("unsorted_remove_duplicates: container without duplicates")
     241              :     {
     242            1 :         std::vector<std::string> container;
     243            1 :         std::size_t size(rand() % 100 + 50);
     244           82 :         while(container.size() < size)
     245              :         {
     246           81 :             std::string const s(SNAP_CATCH2_NAMESPACE::random_string(0, rand() % 25));
     247           81 :             if(std::find(container.begin(), container.end(), s) == container.end())
     248              :             {
     249           73 :                 container.push_back(s);
     250              :             }
     251           81 :         }
     252            1 :         std::vector<std::string> copy(container);
     253            1 :         std::vector<std::string> *output = &snapdev::unsorted_remove_duplicates(container);
     254            1 :         CATCH_REQUIRE(&container == output);
     255            1 :         CATCH_REQUIRE(container.size() == copy.size());
     256            1 :         CATCH_REQUIRE(container == copy);
     257            1 :     }
     258            5 :     CATCH_END_SECTION()
     259              : 
     260            5 :     CATCH_START_SECTION("unsorted_remove_duplicates: container with duplicates (vector)")
     261              :     {
     262            1 :         std::vector<std::string> container;
     263              : 
     264              :         // we want to be in control of the duplication and know exactly what
     265              :         // we are going to get back out so we need to create a container
     266              :         // without duplicates first then add duplicates in a second loop
     267              :         //
     268            1 :         std::size_t size(rand() % 100 + 50);
     269          144 :         while(container.size() < size)
     270              :         {
     271          143 :             std::string const s(SNAP_CATCH2_NAMESPACE::random_string(0, rand() % 25));
     272          143 :             if(std::find(container.begin(), container.end(), s) == container.end())
     273              :             {
     274          125 :                 container.push_back(s);
     275              :             }
     276          143 :         }
     277            1 :         std::vector<std::string> copy(container);
     278            1 :         std::size_t dups(rand() % 50 + 25);
     279           33 :         for(std::size_t i(0); i < dups; ++i)
     280              :         {
     281           32 :             int const d(rand() % container.size());
     282              : 
     283              :             // since items do not get sorted, we need p > d for this test
     284              :             // to work properly
     285              :             //
     286           32 :             int const p(d + rand() % (container.size() - d) + 1);
     287              : 
     288           32 :             container.insert(container.begin() + p, container[d]);
     289              :         }
     290            1 :         std::vector<std::string> *output = &snapdev::unsorted_remove_duplicates(container);
     291            1 :         CATCH_REQUIRE(&container == output);
     292            1 :         CATCH_REQUIRE(container.size() == copy.size());
     293            1 :         CATCH_REQUIRE(container == copy);
     294            1 :     }
     295            5 :     CATCH_END_SECTION()
     296              : 
     297            5 :     CATCH_START_SECTION("unsorted_remove_duplicates: container with duplicates (list)")
     298              :     {
     299            1 :         std::list<std::string> container;
     300              : 
     301              :         // we want to be in control of the duplication and know exactly what
     302              :         // we are going to get back out so we need to create a container
     303              :         // without duplicates first then add duplicates in a second loop
     304              :         //
     305            1 :         std::size_t size(rand() % 100 + 50);
     306          114 :         while(container.size() < size)
     307              :         {
     308          113 :             std::string const s(SNAP_CATCH2_NAMESPACE::random_string(0, rand() % 25));
     309          113 :             if(std::find(container.begin(), container.end(), s) == container.end())
     310              :             {
     311           95 :                 container.push_back(s);
     312              :             }
     313          113 :         }
     314            1 :         std::list<std::string> copy(container);
     315            1 :         std::size_t dups(rand() % 50 + 25);
     316           34 :         for(std::size_t i(0); i < dups; ++i)
     317              :         {
     318           33 :             int const d(rand() % container.size());
     319              : 
     320              :             // since items do not get sorted, we need p > d for this test
     321              :             // to work properly
     322              :             //
     323           33 :             int const p(d + rand() % (container.size() - d) + 1);
     324              : 
     325           33 :             auto d_it(container.begin());
     326              :             std::advance(d_it, d);
     327           33 :             auto p_it(container.begin());
     328              :             std::advance(p_it, p);
     329           33 :             container.insert(p_it, *d_it);
     330              :         }
     331            1 :         std::list<std::string> *output = &snapdev::unsorted_remove_duplicates(container);
     332            1 :         CATCH_REQUIRE(&container == output);
     333            1 :         CATCH_REQUIRE(container.size() == copy.size());
     334            1 :         CATCH_REQUIRE(container == copy);
     335            1 :     }
     336            5 :     CATCH_END_SECTION()
     337              : 
     338            5 :     CATCH_START_SECTION("unsorted_remove_duplicates: container with one item duplicated")
     339              :     {
     340           11 :         for(int count(0); count < 10; ++count)
     341              :         {
     342           10 :             std::deque<std::string> container;
     343              : 
     344              :             // we want to be in control of the duplication and know exactly what
     345              :             // we are going to get back out so we need to create a container
     346              :             // without duplicates first then add duplicates in a second loop
     347              :             //
     348           10 :             std::string const s(SNAP_CATCH2_NAMESPACE::random_string(0, rand() % 25));
     349           10 :             std::size_t size(rand() % 100 + 50);
     350          990 :             while(container.size() < size)
     351              :             {
     352          980 :                 container.push_back(s);
     353              :             }
     354           10 :             std::deque<std::string> *output = &snapdev::sorted_remove_duplicates(container);
     355           10 :             CATCH_REQUIRE(&container == output);
     356           10 :             CATCH_REQUIRE(container.size() == 1);
     357           10 :             CATCH_REQUIRE(container.front() == s);
     358           10 :         }
     359              :     }
     360            5 :     CATCH_END_SECTION()
     361            5 : }
     362              : 
     363              : 
     364              : 
     365              : // vim: ts=4 sw=4 et
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions