code: // Aseprite Document Library
  // Copyright (c) 2020 Igara Studio S.A.
  //
  // This file is released under the terms of the MIT license.
  // Read LICENSE.txt for more information.
  
  #include "gtest/gtest.h"
  
  #include "doc/algorithm/fill_selection.h"
  #include "doc/grid.h"
  #include "doc/image.h"
  #include "doc/mask.h"
  
  using namespace doc;
  using namespace gfx;
  
  ::testing::AssertionResult cmp_img(const std::vector<color_t>& pixels,
                                     const Image* image)
  {
    int c = 0;
    for (int y=0; y<image->height(); ++y) {
      for (int x=0; x<image->width(); ++x) {
        if (pixels[c] != image->getPixel(x, y)) {
          return ::testing::AssertionFailure()
            << "ExpectedPixel=" << (int)pixels[c]
            << " ActualPixel=" << (int)image->getPixel(x, y)
            << " x=" << x
            << " y=" << y;
        }
        ++c;
      }
    }
    return ::testing::AssertionSuccess();
  }
  
  TEST(FillSelection, Image)
  {
    ImageRef image(Image::create(IMAGE_INDEXED, 4, 4));
    image->clear(1);
  
    // No-op (no intersection between image & mask)
    Mask mask;
    mask.replace(Rect(0, 0, 1, 5));
    algorithm::fill_selection(image.get(), Rect(1, 1, 4, 4), &mask, 2, nullptr);
    EXPECT_TRUE(cmp_img({ 1, 1, 1, 1,
                          1, 1, 1, 1,
                          1, 1, 1, 1,
                          1, 1, 1, 1 }, image.get()));
  
    mask.replace(Rect(1, 0, 2, 3));
    algorithm::fill_selection(image.get(), Rect(1, 1, 4, 4), &mask, 2, nullptr);
    EXPECT_TRUE(cmp_img({ 2, 2, 1, 1,
                          2, 2, 1, 1,
                          1, 1, 1, 1,
                          1, 1, 1, 1 }, image.get()));
  
    mask.replace(Rect(2, 2, 2, 3));
    algorithm::fill_selection(image.get(), Rect(1, 3, 4, 4), &mask, 3, nullptr);
    EXPECT_TRUE(cmp_img({ 2, 3, 3, 1,
                          2, 3, 3, 1,
                          1, 1, 1, 1,
                          1, 1, 1, 1 }, image.get()));
  }
  
  TEST(FillSelection, Tilemap)
  {
    ImageRef image(Image::create(IMAGE_TILEMAP, 4, 4));
    image->clear(1);
  
    Grid grid(Size(8, 8));
    grid.origin(Point(4, 4));
  
    // No-op (no intersection between image & mask)
    Mask mask;
    mask.replace(Rect(0, 0, 4, 4));
    algorithm::fill_selection(image.get(), Rect(4, 4, 32, 32), &mask, 2, &grid);
    EXPECT_TRUE(cmp_img({ 1, 1, 1, 1,
                          1, 1, 1, 1,
                          1, 1, 1, 1,
                          1, 1, 1, 1 }, image.get()));
  
    mask.replace(Rect(0, 0, 5, 5));
    algorithm::fill_selection(image.get(), Rect(4, 4, 32, 32), &mask, 2, &grid);
    EXPECT_TRUE(cmp_img({ 2, 1, 1, 1,
                          1, 1, 1, 1,
                          1, 1, 1, 1,
                          1, 1, 1, 1 }, image.get()));
  
    mask.replace(Rect(12, 12, 9, 8));
    algorithm::fill_selection(image.get(), Rect(4, 4, 32, 32), &mask, 3, &grid);
    EXPECT_TRUE(cmp_img({ 2, 1, 1, 1,
                          1, 3, 3, 1,
                          1, 1, 1, 1,
                          1, 1, 1, 1 }, image.get()));
  }
  
  int main(int argc, char** argv)
  {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
  }
  