text: #include "builders/terrain/LineGridSplitter.hpp"
  
  #include <boost/test/unit_test.hpp>
  
  using namespace utymap::builders;
  using namespace utymap::math;
  
  namespace {
  typedef std::vector<Vector2> DoublePoints;
  typedef std::vector<IntPoint> IntPoints;
  const double Precision = 0.1e-9;
  }
  
  BOOST_AUTO_TEST_SUITE(Builders_Terrain_LineGridSplitter)
  
  BOOST_AUTO_TEST_CASE(GivenHorizontal_WhenSplitWithIntStep_ThenCanSplit) {
    IntPoint start(0, 0);
    IntPoint end(10, 0);
    LineGridSplitter splitter;
    DoublePoints result;
  
    splitter.split(start, end, result);
  
    for (int i = 0; i <= 10; ++i) {
      BOOST_CHECK_CLOSE(i, result[i].x, Precision);
      BOOST_CHECK_CLOSE(0, result[i].y, Precision);
    }
  }
  
  BOOST_AUTO_TEST_CASE(GivenVertical_WhenSplitWithIntStep_ThenCanSplit) {
    IntPoint start(0, 0);
    IntPoint end(0, 10);
    LineGridSplitter splitter;
    DoublePoints result;
  
    splitter.split(start, end, result);
  
    for (int i = 0; i <= 10; ++i) {
      BOOST_CHECK_CLOSE(0, result[i].x, Precision);
      BOOST_CHECK_CLOSE(i, result[i].y, Precision);
    }
  }
  
  BOOST_AUTO_TEST_CASE(Given45Angle_WhenSplitWithIntStep_ThenCanSplit) {
    IntPoint start(0, 0);
    IntPoint end(-10, 10);
    LineGridSplitter splitter;
    DoublePoints result;
  
    splitter.split(start, end, result);
  
    for (int i = 0; i <= 10; ++i) {
      BOOST_CHECK_CLOSE(-i, result[i].x, Precision);
      BOOST_CHECK_CLOSE(i, result[i].y, Precision);
    }
  }
  
  BOOST_AUTO_TEST_CASE(Given45Angle_WhenSplitWithHighLoD_ThenCanSplit) {
    LineGridSplitter splitter;
    IntPoint start(0, 0);
    IntPoint end(10, 10);
    DoublePoints result;
  
    splitter.split(start, end, result);
  
    for (int i = 0; i <= 10; ++i) {
      BOOST_CHECK_CLOSE(i, result[i].x, Precision);
      BOOST_CHECK_CLOSE(i, result[i].y, Precision);
    }
  }
  
  // These tests are for some bugs observed for real data
  BOOST_AUTO_TEST_CASE(GivenSpecificCase1_WhenSplit_ThenCanSplit) {
    LineGridSplitter splitter;
    splitter.setParams(1E8, 3);
    IntPoint start(5286462881, -916628251);
    IntPoint end(5388136261, -968852454);
    DoublePoints result;
  
    splitter.split(start, end, result);
  
    for (int i = 0; i < result.size(); ++i) {
      BOOST_CHECK_LT(std::abs(result[i].x), 54);
      BOOST_CHECK_LT(std::abs(result[i].y), 10);
    }
  }
  
  // These tests are for some bugs observed for real data
  BOOST_AUTO_TEST_CASE(GivenSpecificCase2_WhenSplit_ThenCanSplit) {
    LineGridSplitter splitter;
    splitter.setParams(1E7, 3);
    IntPoint start(-428193799, 626823300);
    IntPoint end(-411886999, 634824599);
    DoublePoints result;
  
    splitter.split(start, end, result);
  
    BOOST_CHECK_EQUAL(result.size(), 4);
  }
  
  BOOST_AUTO_TEST_CASE(GivenSpecificCase3_WhenSplit_ThenDoNotInflateDuplicates) {
    LineGridSplitter splitter;
    splitter.setParams(10000000, 0.0006103515625);
    IntPoints points = {
        {133691881, 525218163},
        {133693424, 525219786},
        {133692010, 525218310}
    };
    DoublePoints result;
  
    auto lastItemIndex = points.size() - 1;
    for (int i = 0; i <= lastItemIndex; i++)
      splitter.split(points[i], points[i==lastItemIndex ? 0 : i + 1], result);
  
    // TODO better to check duplicates directly
    BOOST_CHECK_EQUAL(result.size(), 6);
  }
  
  BOOST_AUTO_TEST_SUITE_END()
  