// ./tests/catch2-tests [section] -s


/////////////////////// Qt includes
#include <QDebug>
#include <QString>
#include <QDir>


/////////////////////// Catch2 includes
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_floating_point.hpp>


/////////////////////// Local includes
#include "TestUtils.hpp"
#include "MsXpS/libXpertMassCore/IndexRangeCollection.hpp"

namespace MsXpS
{
namespace libXpertMassCore
{


SCENARIO("Construction of a IndexRangeCollection instance",
         "[IndexRangeCollection]")
{
  QString index_range_string_1("[50-150]");
  IndexRange index_range_1(50, 150);

  QString index_range_string_2("[40-160]");
  IndexRange index_range_2(40, 160);

  QString index_range_string_3("[30-170]");
  IndexRange index_range_3(30, 170);

  QString all_three_index_range_strings = QString("%1%2%3")
                                            .arg(index_range_string_1)
                                            .arg(index_range_string_2)
                                            .arg(index_range_string_3);

  GIVEN("Construction with no argument")
  {
    IndexRangeCollection index_range_collection;

    WHEN("A comment is set to it")
    {
      index_range_collection.setComment("Comment");

      THEN("The comment should be set")
      {
        REQUIRE(index_range_collection.getComment().toStdString() == "Comment");
      }
    }
  }

  GIVEN(
    "Construction of a IndexRangeCollection instance with a string "
    "representing three IndexRange instances of POSITION location type")
  {
    IndexRangeCollection index_range_collection(all_three_index_range_strings,
                                                Enums::LocationType::POSITION);

    THEN("The list must have size 3")
    {
      REQUIRE(index_range_collection.size() == 3);

      AND_THEN("All the members of the list should have proper values")
      {
        IndexRange first_index_range(index_range_collection.getRangeCstRefAt(0),
                                     Q_NULLPTR);

        REQUIRE(first_index_range.m_start == index_range_1.m_start - 1);
        REQUIRE(first_index_range.m_stop == index_range_1.m_stop - 1);

        IndexRange second_index_range(
          index_range_collection.getRangeCstRefAt(1), Q_NULLPTR);

        REQUIRE(second_index_range.m_start == index_range_2.m_start - 1);
        REQUIRE(second_index_range.m_stop == index_range_2.m_stop - 1);

        IndexRange third_index_range(index_range_collection.getRangeCstRefAt(2),
                                     Q_NULLPTR);

        REQUIRE(third_index_range.m_start == index_range_3.m_start - 1);
        REQUIRE(third_index_range.m_stop == index_range_3.m_stop - 1);
      }
    }
  }

  GIVEN(
    "An incorrect string incorrectly representing three IndexRange (missing "
    "1 "
    "'[')")
  {
    QString all_three_index_range_strings("50-150][40-160][30-170]");

    WHEN("Constructing a IndexRangeCollection instance")
    {
      IndexRangeCollection index_range_collection(
        all_three_index_range_strings);

      THEN("The list is created empty")
      {
        REQUIRE(index_range_collection.size() == 0);
      }
    }
  }

  GIVEN(
    "An incorrect string incorrectly representing three IndexRange (missing "
    "1 "
    "']'")
  {
    QString all_three_index_range_strings("[50-150][40-160[30-170]");

    WHEN("Constructing a IndexRangeCollection instance")
    {
      IndexRangeCollection index_range_collection(
        all_three_index_range_strings);

      THEN("The list is created empty")
      {
        REQUIRE(index_range_collection.size() == 0);
      }
    }
  }

  GIVEN(
    "An incorrect string incorrectly representing three IndexRange (missing "
    "1 "
    "']' and 1 '['")
  {
    QString all_three_index_range_strings("50-150][40-160[30-170]");

    WHEN("Constructing a IndexRangeCollection instance")
    {
      IndexRangeCollection index_range_collection(
        all_three_index_range_strings);

      THEN("The list is created empty")
      {
        REQUIRE(index_range_collection.size() == 0);
      }
    }
  }

  GIVEN(
    "An incorrect string incorrectly representing three IndexRange (missing "
    "1 "
    "'-'")
  {
    QString all_three_index_range_strings("[50-150][40-160][30 170]");

    WHEN("Constructing a IndexRangeCollection instance")
    {
      IndexRangeCollection index_range_collection(
        all_three_index_range_strings);

      THEN("The list is created empty")
      {
        REQUIRE(index_range_collection.size() == 0);
      }
    }
  }

  GIVEN("Construction with a comment and no list; and IndexRange objects")
  {
    IndexRangeCollection index_range_collection;
    index_range_collection.setComment("Comment");
    REQUIRE(index_range_collection.getComment().toStdString() == "Comment");
    REQUIRE(index_range_collection.size() == 0);

    WHEN("One IndexRange object is appended to the list")
    {
      index_range_collection.appendIndexRange(index_range_1);

      THEN(
        "The list must have size 1, and that object has to be the one appended")
      {
        REQUIRE(index_range_collection.size() == 1);
        REQUIRE(index_range_collection.getRangeCstRefAt(0) == index_range_1);
      }

      AND_WHEN("Another IndexRange object is appended to the list")
      {
        index_range_collection.appendIndexRange(index_range_2);

        THEN(
          "The list must have size 2, and that object has to be the last of "
          "the list")
        {
          REQUIRE(index_range_collection.size() == 2);
          REQUIRE(index_range_collection.getRangeCstRefAt(
                    index_range_collection.size() - 1) == index_range_2);
        }

        AND_WHEN(
          "That 2-sized IndexRangeCollection instance is copied "
          "(copy-constructor "
          "with reference)")
        {
          IndexRangeCollection new_index_range_collection(
            index_range_collection);

          THEN("The two IndexRangeCollection instances must have the same data")
          {
            REQUIRE(new_index_range_collection.getComment().toStdString() ==
                    index_range_collection.getComment().toStdString());
            REQUIRE(new_index_range_collection.size() ==
                    index_range_collection.size());
            REQUIRE(new_index_range_collection.getRangeCstRefAt(0) ==
                    index_range_collection.getRangeCstRefAt(0));
            REQUIRE(new_index_range_collection.getRangeCstRefAt(
                      new_index_range_collection.size() - 1) ==
                    index_range_collection.getRangeCstRefAt(
                      new_index_range_collection.size() - 1));
          }
        }

        AND_WHEN(
          "That 2-sized IndexRangeCollection instance is initialized to "
          "itself,  a reference to itself is returned")
        {
          REQUIRE((index_range_collection.initialize(index_range_collection)) ==
                  index_range_collection);
        }

        AND_WHEN(
          "A new IndexRangeCollection instance is copy-constructed from the "
          "previous one")
        {
          IndexRangeCollection new_index_range_collection(
            index_range_collection, Q_NULLPTR);

          THEN("The two IndexRangeCollection instances must have the same data")
          {
            REQUIRE(new_index_range_collection.getComment().toStdString() ==
                    index_range_collection.getComment().toStdString());
            REQUIRE(new_index_range_collection.size() ==
                    index_range_collection.size());
            REQUIRE(new_index_range_collection.getRangeCstRefAt(0) ==
                    index_range_collection.getRangeCstRefAt(0));
            REQUIRE(new_index_range_collection.getRangeCstRefAt(
                      new_index_range_collection.size() - 1) ==
                    index_range_collection.getRangeCstRefAt(
                      index_range_collection.size() - 1));
          }
        }
      }
    }
  }
}

SCENARIO(
  "Empty IndexRangeCollection instances can be filled-in after construction "
  "with "
  "other IndexRangeCollection",
  "[IndexRangeCollection]")
{

  GIVEN(
    "Construction of a IndexRangeCollection instance with two IndexRange "
    "instances")
  {
    IndexRange index_range_1(50, 150);
    IndexRange index_range_2(40, 160);
    IndexRange index_range_3(30, 170);

    IndexRangeCollection index_range_collection_0;
    index_range_collection_0.setComment("Giver");
    index_range_collection_0.appendIndexRange(index_range_1);
    index_range_collection_0.appendIndexRange(index_range_2);

    REQUIRE(index_range_collection_0.size() == 2);
    REQUIRE(index_range_collection_0.getRangeCstRefAt(0) == index_range_1);
    REQUIRE(index_range_collection_0.getRangeCstRefAt(
              index_range_collection_0.size() - 1) == index_range_2);

    AND_GIVEN("Construction of an empty IndexRangeCollection instance")
    {
      IndexRangeCollection index_range_collection;
      index_range_collection.setComment("Receiver");
      REQUIRE(index_range_collection.getComment().toStdString() == "Receiver");
      REQUIRE(index_range_collection.size() == 0);

      WHEN(
        "The first IndexRangeCollection instance with two items is appended to "
        "the "
        "the empty one")
      {
        index_range_collection.appendIndexRanges(index_range_collection_0);

        THEN("Its size must become the same at the one that was appended")
        {
          REQUIRE(index_range_collection.size() ==
                  index_range_collection_0.size());
          REQUIRE(index_range_collection.getRangeCstRefAt(0) ==
                  index_range_collection_0.getRangeCstRefAt(0));
          REQUIRE(index_range_collection.getRangeCstRefAt(
                    index_range_collection.size() - 1) ==
                  index_range_collection_0.getRangeCstRefAt(
                    index_range_collection_0.size() - 1));
        }

        AND_WHEN("A new IndexRange instance is set (not appended)")
        {
          index_range_collection.setIndexRange(index_range_3);

          THEN("The single instance has to be this last")
          {
            REQUIRE(index_range_collection.size() == 1);
            REQUIRE(index_range_collection.getRangeCstRefAt(0) ==
                    index_range_3);
          }

          AND_WHEN("A IndexRangeCollection instance is set (not appended)")
          {
            index_range_collection.setIndexRanges(index_range_collection_0);

            THEN(
              "The previous single instance has to be lost and be replaced by "
              "the new ones")
            {
              REQUIRE(index_range_collection.size() == 2);
              REQUIRE(index_range_collection.getRangeCstRefAt(0) ==
                      index_range_collection_0.getRangeCstRefAt(0));
              REQUIRE(index_range_collection.getRangeCstRefAt(
                        index_range_collection.size() - 1) ==
                      index_range_collection_0.getRangeCstRefAt(
                        index_range_collection_0.size() - 1));
            }
          }
        }
      }
    }
  }
}

SCENARIO(
  "Empty IndexRangeCollection instances can be filled in after construction "
  "with "
  "strings representative of IndexRange instances (single or multiple)",
  "[IndexRangeCollection]")
{
  QString index_range_string_1("[50-150]");
  IndexRange index_range_1(50, 150);

  QString index_range_string_2("[40-160]");
  IndexRange index_range_2(40, 160);

  QString index_range_string_3("[30-170]");
  IndexRange index_range_3(30, 170);

  QString all_three_index_range_strings = QString("%1%2%3")
                                            .arg(index_range_string_1)
                                            .arg(index_range_string_2)
                                            .arg(index_range_string_3);

  GIVEN("Construction with a comment and no list; and IndexRange objects")
  {
    IndexRangeCollection index_range_collection;
    index_range_collection.setComment("Comment");
    REQUIRE(index_range_collection.getComment().toStdString() == "Comment");
    REQUIRE(index_range_collection.size() == 0);

    WHEN(
      "That IndexRangeCollection is set with one string representative of a "
      "single IndexRange instance of location type INDEX")
    {
      index_range_collection.setIndexRanges(index_range_string_1,
                                            Enums::LocationType::INDEX);

      THEN(
        "The list must have size 1, and that object has to be the one set,  "
        "with each first/second value decremented by one to convert positions "
        "to "
        "indices")
      {
        REQUIRE(index_range_collection.size() == 1);
        REQUIRE(index_range_collection.getRangeCstRefAt(0).m_start ==
                index_range_1.m_start);
        REQUIRE(index_range_collection.getRangeCstRefAt(0).m_stop ==
                index_range_1.m_stop);
      }
    }

    WHEN(
      "That IndexRangeCollection is set with one string representative of a "
      "single IndexRange instance of location type POSITION")
    {
      index_range_collection.setIndexRanges(index_range_string_1,
                                            Enums::LocationType::POSITION);

      THEN(
        "The list must have size 1, and that object has to be the one set,  "
        "with each first/second value decremented by one to convert positions "
        "to "
        "indices")
      {
        REQUIRE(index_range_collection.size() == 1);
        REQUIRE(index_range_collection.getRangeCstRefAt(0).m_start ==
                index_range_1.m_start - 1);
        REQUIRE(index_range_collection.getRangeCstRefAt(0).m_stop ==
                index_range_1.m_stop - 1);
      }
    }

    WHEN(
      "That IndexRangeCollection is set with one string representative of "
      "three "
      "IndexRange instances")
    {
      index_range_collection.setIndexRanges(all_three_index_range_strings,
                                            Enums::LocationType::INDEX);

      THEN("The list must have size 3")
      {
        REQUIRE(index_range_collection.size() == 3);
      }

      AND_THEN("All the members of the list should have proper values")
      {
        REQUIRE(index_range_collection.getRangeCstRefAt(0).m_start ==
                index_range_1.m_start);
        REQUIRE(index_range_collection.getRangeCstRefAt(0).m_stop ==
                index_range_1.m_stop);

        REQUIRE(index_range_collection.getRangeCstRefAt(1).m_start ==
                index_range_2.m_start);
        REQUIRE(index_range_collection.getRangeCstRefAt(1).m_stop ==
                index_range_2.m_stop);

        REQUIRE(index_range_collection
                  .getRangeCstRefAt(index_range_collection.size() - 1)
                  .m_start == index_range_3.m_start);
        REQUIRE(index_range_collection
                  .getRangeCstRefAt(index_range_collection.size() - 1)
                  .m_stop == index_range_3.m_stop);
      }
    }
  }
}

SCENARIO("IndexRangeCollection instances can provide topological data",
         "[IndexRangeCollection]")
{
  GIVEN("A IndexRangeCollection instance with a single IndexRange instance")
  {
    IndexRangeCollection index_range_collection;

    QString all_index_range_strings("[1-20]");

    index_range_collection.setIndexRanges(all_index_range_strings,
                                          Enums::LocationType::POSITION);

    REQUIRE(index_range_collection.size() == 1);

    QList<qsizetype> left_most_indices;
    QList<qsizetype> right_most_indices;

    WHEN("Asking for the leftmost and the rightmost IndexRange instances")
    {
      left_most_indices = index_range_collection.indicesOfLeftMostIndexRanges();
      right_most_indices =
        index_range_collection.indicesOfRightMostIndexRanges();
      REQUIRE(left_most_indices.size() == 1);
      REQUIRE(right_most_indices.size() == 1);

      THEN("The indices should actually match the correct IndexRange instance")
      {
        REQUIRE(index_range_collection.getRangeCstRefAt(left_most_indices.at(0))
                  .m_start == 0);
        REQUIRE(
          index_range_collection.getRangeCstRefAt(right_most_indices.at(0))
            .m_stop == 19);
      }
    }

    WHEN(
      "Checking if there are overlaps,  there cannot be because only one "
      "instance")
    {
      REQUIRE_FALSE(index_range_collection.overlap());
    }

    WHEN("Checking for indices that are encompassed or not")
    {
      THEN("The results should be consistent")
      {
        REQUIRE(index_range_collection.encompassIndex(0));
        REQUIRE(index_range_collection.encompassIndex(19));
        REQUIRE(index_range_collection.encompassIndex(10));
        REQUIRE_FALSE(index_range_collection.encompassIndex(20));
      }
    }

    WHEN("Checking for indices left most IndexRange")
    {
      THEN("The results should be consistent")
      {
        REQUIRE(index_range_collection.isLeftMostIndexRange(
          index_range_collection.getRangeCstRefAt(0)));
        REQUIRE(index_range_collection.isRightMostIndexRange(
          index_range_collection.getRangeCstRefAt(0)));
      }
    }
  }

  GIVEN(
    "A IndexRangeCollection instance with a number of non-overlapping "
    "IndexRange")
  {
    IndexRangeCollection index_range_collection;

    QString all_index_range_strings("[1-20][25-45][55-100]");

    index_range_collection.setIndexRanges(all_index_range_strings,
                                          Enums::LocationType::POSITION);

    REQUIRE(index_range_collection.size() == 3);

    QList<qsizetype> left_most_indices;
    QList<qsizetype> right_most_indices;

    WHEN("Asking for the leftmost and the rightmost IndexRangeCollection")
    {
      left_most_indices = index_range_collection.indicesOfLeftMostIndexRanges();
      right_most_indices =
        index_range_collection.indicesOfRightMostIndexRanges();
      REQUIRE(left_most_indices.size() == 1);
      REQUIRE(right_most_indices.size() == 1);

      THEN("The indices should actually match the right IndexRange instances")
      {
        REQUIRE(index_range_collection.getRangeCstRefAt(left_most_indices.at(0))
                  .m_start == 0);
        REQUIRE(
          index_range_collection.getRangeCstRefAt(right_most_indices.at(0))
            .m_stop == 99);
      }
    }

    WHEN("Checking if there are overlaps, there should not be")
    {
      REQUIRE_FALSE(index_range_collection.overlap());
    }

    WHEN("Checking for indices that are encompassed or not")
    {
      THEN("The results should be consistent")
      {
        REQUIRE(index_range_collection.encompassIndex(0));
        REQUIRE_FALSE(index_range_collection.encompassIndex(50));
        REQUIRE(index_range_collection.encompassIndex(50, /*globally*/ true));
        REQUIRE(index_range_collection.encompassIndex(99));
        REQUIRE_FALSE(index_range_collection.encompassIndex(100));
      }
    }

    WHEN("Checking for indices left most IndexRange")
    {
      THEN("The results should be consistent")
      {
        // "[1-20][25-45][55-100]"

        REQUIRE(index_range_collection.isLeftMostIndexRange(
          index_range_collection.getRangeCstRefAt(0)));
        REQUIRE_FALSE(index_range_collection.isRightMostIndexRange(
          index_range_collection.getRangeCstRefAt(0)));

        REQUIRE_FALSE(index_range_collection.isLeftMostIndexRange(
          index_range_collection.getRangeCstRefAt(1)));
        REQUIRE_FALSE(index_range_collection.isRightMostIndexRange(
          index_range_collection.getRangeCstRefAt(1)));

        REQUIRE_FALSE(index_range_collection.isLeftMostIndexRange(
          index_range_collection.getRangeCstRefAt(2)));
        REQUIRE(index_range_collection.isRightMostIndexRange(
          index_range_collection.getRangeCstRefAt(2)));
      }
    }
  }

  GIVEN(
    "A IndexRangeCollection instance with a number of IndexRange with overlaps")
  {
    IndexRangeCollection index_range_collection;

    QString all_index_range_strings(
      "[1-20][1-30][10-50][15-80][25-100][30-100]");

    index_range_collection.setIndexRanges(all_index_range_strings,
                                          Enums::LocationType::POSITION);

    REQUIRE(index_range_collection.size() == 6);

    QList<qsizetype> left_most_indices;
    QList<qsizetype> right_most_indices;

    WHEN("Asking for the leftmost and the rightmost IndexRangeCollection")
    {
      left_most_indices = index_range_collection.indicesOfLeftMostIndexRanges();
      right_most_indices =
        index_range_collection.indicesOfRightMostIndexRanges();
      REQUIRE(left_most_indices.size() == 2);
      REQUIRE(right_most_indices.size() == 2);

      THEN("The indices should actually match the right IndexRange instances")
      {
        REQUIRE(index_range_collection.getRangeCstRefAt(left_most_indices.at(0))
                  .m_start == 0);
        REQUIRE(
          index_range_collection.getRangeCstRefAt(left_most_indices.back())
            .m_start == 0);
        REQUIRE(
          index_range_collection.getRangeCstRefAt(right_most_indices.at(0))
            .m_stop == 99);
        REQUIRE(
          index_range_collection.getRangeCstRefAt(right_most_indices.back())
            .m_stop == 99);
      }
    }

    WHEN("Checking if there are overlaps, there should  be")
    {
      REQUIRE(index_range_collection.overlap());
    }

    WHEN("Checking for indices that are encompassed or not")
    {
      THEN("The results should be consistent")
      {
        REQUIRE(index_range_collection.encompassIndex(0));
        REQUIRE(index_range_collection.encompassIndex(49));
        REQUIRE(index_range_collection.encompassIndex(50));
        REQUIRE(index_range_collection.encompassIndex(99));
        REQUIRE_FALSE(index_range_collection.encompassIndex(100));
      }
    }

    WHEN("Checking for indices left most IndexRange")
    {
      THEN("The results should be consistent")
      {
        // "[1-20][1-30][10-50][15-80][25-100][30-100]"

        REQUIRE(index_range_collection.isLeftMostIndexRange(
          index_range_collection.getRangeCstRefAt(0)));
        REQUIRE_FALSE(index_range_collection.isRightMostIndexRange(
          index_range_collection.getRangeCstRefAt(0)));

        REQUIRE(index_range_collection.isLeftMostIndexRange(
          index_range_collection.getRangeCstRefAt(1)));
        REQUIRE_FALSE(index_range_collection.isRightMostIndexRange(
          index_range_collection.getRangeCstRefAt(1)));

        REQUIRE_FALSE(index_range_collection.isLeftMostIndexRange(
          index_range_collection.getRangeCstRefAt(2)));
        REQUIRE_FALSE(index_range_collection.isRightMostIndexRange(
          index_range_collection.getRangeCstRefAt(2)));

        REQUIRE_FALSE(index_range_collection.isLeftMostIndexRange(
          index_range_collection.getRangeCstRefAt(3)));
        REQUIRE_FALSE(index_range_collection.isRightMostIndexRange(
          index_range_collection.getRangeCstRefAt(3)));

        REQUIRE_FALSE(index_range_collection.isLeftMostIndexRange(
          index_range_collection.getRangeCstRefAt(4)));
        REQUIRE(index_range_collection.isRightMostIndexRange(
          index_range_collection.getRangeCstRefAt(4)));

        REQUIRE_FALSE(index_range_collection.isLeftMostIndexRange(
          index_range_collection.getRangeCstRefAt(5)));
        REQUIRE(index_range_collection.isRightMostIndexRange(
          index_range_collection.getRangeCstRefAt(5)));
      }
    }
  }
}

SCENARIO("IndexRangeCollection instances can self-describe with text strings",
         "[IndexRangeCollection]")
{
  QString all_three_index_range_strings("[50-150][40-160][30-170]");

  GIVEN("Construction with a string describing three IndexRange instances")
  {
    IndexRangeCollection index_range_collection(all_three_index_range_strings,
                                                Enums::LocationType::POSITION);

    WHEN("When asked to self-describe as indices")
    {
      QString text = index_range_collection.indicesAsText();

      THEN("The string should be list indices and not positions")
      {
        REQUIRE(text.toStdString() == "[49-149][39-159][29-169]");
      }
    }

    WHEN("When asked to self-describe as positions")
    {
      QString text = index_range_collection.positionsAsText();

      THEN("The string should be list positions and not indices")
      {
        REQUIRE(text.toStdString() ==
                all_three_index_range_strings.toStdString());
      }
    }
  }
}

SCENARIO("IndexRangeCollection and IndexRange instances can be compared",
         "[IndexRangeCollection]")
{
  QString index_range_string_1("[50-150]");
  IndexRange index_range_1(50, 150);

  QString index_range_string_2("[40-160]");
  IndexRange index_range_2(40, 160);

  QString index_range_string_3("[30-170]");
  IndexRange index_range_3(30, 170);

  QString all_three_index_range_strings = QString("%1%2%3")
                                            .arg(index_range_string_1)
                                            .arg(index_range_string_2)
                                            .arg(index_range_string_3);

  GIVEN("A IndexRangeCollection instance with 3 IndexRange instances")
  {
    // By default location type INDEX.
    IndexRangeCollection index_range_collection(all_three_index_range_strings);

    THEN("The list must have size 3")
    {
      REQUIRE(index_range_collection.size() == 3);
    }

    AND_THEN("All the members of the list should have proper values")
    {
      REQUIRE(index_range_collection.getRangeCstRefAt(0).m_start ==
              index_range_1.m_start);
      REQUIRE(index_range_collection.getRangeCstRefAt(0).m_stop ==
              index_range_1.m_stop);

      REQUIRE(index_range_collection.getRangeCstRefAt(1).m_start ==
              index_range_2.m_start);
      REQUIRE(index_range_collection.getRangeCstRefAt(1).m_stop ==
              index_range_2.m_stop);

      REQUIRE(index_range_collection
                .getRangeCstRefAt(index_range_collection.size() - 1)
                .m_start == index_range_3.m_start);
      REQUIRE(index_range_collection
                .getRangeCstRefAt(index_range_collection.size() - 1)
                .m_stop == index_range_3.m_stop);
    }

    WHEN(
      "A new IndexRangeCollection instance is created as a copy of the first "
      "one")
    {
      IndexRangeCollection new_index_range_collection(index_range_collection);

      THEN("The new instance should be identical to the initial one")
      {
        REQUIRE(new_index_range_collection.size() == 3);
        REQUIRE(new_index_range_collection.getRangeCstRefAt(0).m_start ==
                index_range_1.m_start);
        REQUIRE(new_index_range_collection.getRangeCstRefAt(0).m_stop ==
                index_range_1.m_stop);

        REQUIRE(new_index_range_collection.getRangeCstRefAt(1).m_start ==
                index_range_2.m_start);
        REQUIRE(new_index_range_collection.getRangeCstRefAt(1).m_stop ==
                index_range_2.m_stop);

        REQUIRE(new_index_range_collection
                  .getRangeCstRefAt(new_index_range_collection.size() - 1)
                  .m_start == index_range_3.m_start);
        REQUIRE(new_index_range_collection
                  .getRangeCstRefAt(new_index_range_collection.size() - 1)
                  .m_stop == index_range_3.m_stop);
      }

      AND_THEN("The comparison operators should return identity")
      {
        REQUIRE(new_index_range_collection == index_range_collection);
        REQUIRE_FALSE(new_index_range_collection != index_range_collection);
      }

      AND_WHEN("A one IndexRange instance is modified")
      {
        // IndexRange index_range_1(50, 150);
        // IndexRange index_range_2(40, 160);
        // IndexRange index_range_3(30, 170);

        IndexRangeCollection new_index_range_collection(index_range_collection);

        IndexRange &index_range = new_index_range_collection.getRangeRefAt(1);
        index_range.m_start     = 50;
        index_range.m_stop      = 150;

        THEN("The new instance should not be identical anymore")
        {
          REQUIRE(new_index_range_collection.size() == 3);
          REQUIRE(new_index_range_collection.getRangeCstRefAt(0).m_start ==
                  index_range_1.m_start);
          REQUIRE(new_index_range_collection.getRangeCstRefAt(0).m_stop ==
                  index_range_1.m_stop);

          REQUIRE(new_index_range_collection.getRangeCstRefAt(1).m_start == 50);
          REQUIRE(new_index_range_collection.getRangeCstRefAt(1).m_stop == 150);

          REQUIRE(new_index_range_collection
                    .getRangeCstRefAt(new_index_range_collection.size() - 1)
                    .m_start == index_range_3.m_start);
          REQUIRE(new_index_range_collection
                    .getRangeCstRefAt(new_index_range_collection.size() - 1)
                    .m_stop == index_range_3.m_stop);
        }

        AND_THEN("The comparison operators should return identity")
        {
          REQUIRE(new_index_range_collection != index_range_collection);
          REQUIRE_FALSE(new_index_range_collection == index_range_collection);
        }
      }
    }
  }
}


} // namespace libXpertMassCore
} // namespace MsXpS
