<commit_before>#include "gtest/gtest.h"

#include <tuple>

#include "../include/spica.h"
using namespace spica;

// -----------------------------------------------------------------------------
// Color class test
// -----------------------------------------------------------------------------

class ColorTest : public ::testing::Test {
protected:
    ColorTest() {}
    virtual ~ColorTest() {}
}; 

class ColorTestWithParam : public ColorTest, public ::testing::WithParamInterface<std::tuple<double, double, double> > {
protected:
    double d0, d1, d2;

protected:
    ColorTestWithParam() {
        auto t = GetParam();
        d0 = std::get<0>(t);
        d1 = std::get<1>(t);
        d2 = std::get<2>(t);
    }

    virtual ~ColorTestWithParam() {
    }
};

TEST_P(ColorTestWithParam, DefaultInstance) {
    Color c0;
    EXPECT_EQ(0.0, c0.red());
    EXPECT_EQ(0.0, c0.green());
    EXPECT_EQ(0.0, c0.blue());
}

TEST_P(ColorTestWithParam, InstanceWithParams) {
    Color c1(d0, d1, d2);
    EXPECT_EQ(d0, c1.red());
    EXPECT_EQ(d1, c1.green());
    EXPECT_EQ(d2, c1.blue());
}

TEST_P(ColorTestWithParam, CopyConstructor) {
    Color c0(d0, d1, d2);
    Color c1(c0);
    EXPECT_EQ(d0, c1.red());
    EXPECT_EQ(d1, c1.green());
    EXPECT_EQ(d2, c1.blue());
}

TEST_P(ColorTestWithParam, Assignment) {
    Color c;

    c = Color(d0, d1, d2);
    EXPECT_EQ(d0, c.red());
    EXPECT_EQ(d1, c.green());
    EXPECT_EQ(d2, c.blue());

    double lum = c.red() * 0.2126 + c.green() * 0.7152 + c.blue() * 0.0722;
    EXPECT_DOUBLE_EQ(lum, c.luminance());
}

TEST_P(ColorTestWithParam, ValidSqrt) {
    Color u(d0, d1, d2);
    Color v = Color::sqrt(u);
    EXPECT_EQ(sqrt(u.red()), v.red());
    EXPECT_EQ(sqrt(u.green()), v.green());
    EXPECT_EQ(sqrt(u.blue()), v.blue());
}

TEST_F(ColorTest, InvalidSqrt) {
    Color c(-1.0, 2.0, 3.0);
    ASSERT_DEATH(Color::sqrt(c), "");
}

TEST_P(ColorTestWithParam, ExpTest) {
    Color u(d0, d1, d2);
    Color v = Color::exp(u);
    EXPECT_EQ(exp(u.red()), v.red());
    EXPECT_EQ(exp(u.green()), v.green());
    EXPECT_EQ(exp(u.blue()), v.blue());
}

const std::vector<double> values = { 0.0, 0.25, 0.50, 0.75 };
INSTANTIATE_TEST_CASE_P(, ColorTestWithParam,
    ::testing::Combine(::testing::ValuesIn(values),
                       ::testing::ValuesIn(values),
                       ::testing::ValuesIn(values)));<commit_msg>Add unit tests for the Color class.<commit_after>#include "gtest/gtest.h"

#include <tuple>

#include "../include/spica.h"
using namespace spica;

// -----------------------------------------------------------------------------
// Color class test
// -----------------------------------------------------------------------------

using ColorPair = std::tuple<Color, Color>;

//! Fixture class for non-parametric tests
class ColorTest : public ::testing::Test {
protected:
    ColorTest() {}
    virtual ~ColorTest() {}
}; 

//! Fixture class for value-parameterized tests
class ColorTestWithParam : public ColorTest, public ::testing::WithParamInterface<ColorPair> {
protected:
    Color c1, c2;

protected:
    ColorTestWithParam() {}
    virtual ~ColorTestWithParam() {}

    void SetUp() {
        c1 = std::get<0>(GetParam());
        c2 = std::get<1>(GetParam());
    }
};

TEST_F(ColorTest, DefaultInstance) {
    Color c0;
    EXPECT_EQ(0.0, c0.red());
    EXPECT_EQ(0.0, c0.green());
    EXPECT_EQ(0.0, c0.blue());
}

TEST_P(ColorTestWithParam, InstanceWithParams) {
    Color c(c1.red(), c1.green(), c1.blue());
    EXPECT_EQ(c1.red(), c.red());
    EXPECT_EQ(c1.green(), c.green());
    EXPECT_EQ(c1.blue(), c.blue());
}

TEST_P(ColorTestWithParam, CopyConstructor) {
    Color c(c1);
    EXPECT_EQ(c1.red(), c.red());
    EXPECT_EQ(c1.green(), c.green());
    EXPECT_EQ(c1.blue(), c.blue());
}

TEST_P(ColorTestWithParam, Assignment) {
    Color c;
    c = c1;
    EXPECT_EQ(c1.red(), c.red());
    EXPECT_EQ(c1.green(), c.green());
    EXPECT_EQ(c1.blue(), c.blue());

    const double lum = c.red()   * 0.2126 +
                       c.green() * 0.7152 +
                       c.blue()  * 0.0722;
    EXPECT_DOUBLE_EQ(lum, c.luminance());
}

TEST_P(ColorTestWithParam, PlusOperator) {
    Color c3 = c1 + c2;
    EXPECT_EQ(c1.red() + c2.red(), c3.red());
    EXPECT_EQ(c1.green() + c2.green(), c3.green());
    EXPECT_EQ(c1.blue() + c2.blue(), c3.blue());
}

TEST_P(ColorTestWithParam, MinusOperator) {
    Color c3 = c1 + c2;
    EXPECT_EQ(c1.red() + c2.red(), c3.red());
    EXPECT_EQ(c1.green() + c2.green(), c3.green());
    EXPECT_EQ(c1.blue() + c2.blue(), c3.blue());
}

TEST_P(ColorTestWithParam, ScalarMultiplication) {
    const double d = c2.red();
    const Color c = c1 * d;
    EXPECT_EQ(c1.red() * d, c.red());
    EXPECT_EQ(c1.green() * d, c.green());
    EXPECT_EQ(c1.blue() * d, c.blue());
}

TEST_P(ColorTestWithParam, ComponentWiseMultiplication) {
    Color c3 = c1 * c2;
    EXPECT_EQ(c1.red() * c2.red(), c3.red());
    EXPECT_EQ(c1.green() * c2.green(), c3.green());
    EXPECT_EQ(c1.blue() * c2.blue(), c3.blue());
}

TEST_P(ColorTestWithParam, Division) {
    const double d = c2.red();
    if (d != 0.0) {
        Color c = c1 / d;
        EXPECT_EQ(c1.red() / d, c.red());
        EXPECT_EQ(c1.green() / d, c.green());
        EXPECT_EQ(c1.blue() / d, c.blue());
    } else {
        ASSERT_DEATH(c1 / d, "");
    }
}

TEST_P(ColorTestWithParam, Norm) {
    const double sqnrm = c1.red() * c1.red() +
                         c1.green() * c1.green() + 
                         c1.blue() * c1.blue();
    EXPECT_EQ(sqnrm, c1.squaredNorm());
    EXPECT_EQ(sqrt(sqnrm), c1.norm());
}

TEST_P(ColorTestWithParam, MinimumAndMaximum) {
    const Color c3 = Color::minimum(c1, c2);
    EXPECT_EQ(std::min(c1.red(), c2.red()), c3.red());
    EXPECT_EQ(std::min(c1.green(), c2.green()), c3.green());
    EXPECT_EQ(std::min(c1.blue(), c2.blue()), c3.blue());

    const Color c4 = Color::maximum(c1, c2);
    EXPECT_EQ(std::max(c1.red(), c2.red()), c4.red());
    EXPECT_EQ(std::max(c1.green(), c2.green()), c4.green());
    EXPECT_EQ(std::max(c1.blue(), c2.blue()), c4.blue());
}

TEST_P(ColorTestWithParam, ComponentWiseSqrt) {
    if (c1.red() >= 0.0 && c1.green() >= 0.0 && c1.blue() >= 0.0) {
        Color v = Color::sqrt(c1);
        EXPECT_EQ(sqrt(c1.red()), v.red());
        EXPECT_EQ(sqrt(c1.green()), v.green());
        EXPECT_EQ(sqrt(c1.blue()), v.blue());
    } else {
        ASSERT_DEATH(Color::sqrt(c1), "");
    }
}

TEST_P(ColorTestWithParam, ExpTest) {
    const Color v = Color::exp(c1);
    EXPECT_EQ(exp(c1.red()), v.red());
    EXPECT_EQ(exp(c1.green()), v.green());
    EXPECT_EQ(exp(c1.blue()), v.blue());
}

std::vector<Color> colors = {
    Color(0.0, 1.0, 2.0),
    Color(-2.0, -1.0, 0.0),
    Color(3.14, 1.59, 2.65),
    Color(1.0e8, 1.0e8, 1.0e8),
    Color(1.0e-8, 1.0e-8, 1.0e-8)
};

INSTANTIATE_TEST_CASE_P(, ColorTestWithParam,
    ::testing::Combine(::testing::ValuesIn(colors),
                       ::testing::ValuesIn(colors)));
                       
{'fraction_non_alphanumeric': 0.2379389095061376, 'fraction_numerical': 0.03825292606337425, 'mean_word_length': 2.584143222506394, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2713332', 'n_tokens_mistral': 2709, 'n_tokens_neox': 2704, 'n_words': 457}