| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include <gtest/gtest.h> |
| |
|
| | #include <Gui/Utilities.h> |
| |
|
| | #include <Gui/StyleParameters/Parser.h> |
| | #include <Gui/StyleParameters/ParameterManager.h> |
| |
|
| | using namespace Gui::StyleParameters; |
| |
|
| | class ParserTest: public ::testing::Test |
| | { |
| | protected: |
| | void SetUp() override |
| | { |
| | |
| | auto source = std::make_unique<InMemoryParameterSource>( |
| | std::list<Parameter> { |
| | {"TestParam", "10px"}, |
| | {"TestColor", "#ff0000"}, |
| | {"TestNumber", "5"}, |
| | }, |
| | ParameterSource::Metadata {"Test Source"} |
| | ); |
| |
|
| | manager.addSource(source.get()); |
| | sources.push_back(std::move(source)); |
| | } |
| |
|
| | Gui::StyleParameters::ParameterManager manager; |
| | std::vector<std::unique_ptr<ParameterSource>> sources; |
| | }; |
| |
|
| | |
| | TEST_F(ParserTest, ParseNumbers) |
| | { |
| | { |
| | Parser parser("42"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 42.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("10.5px"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 10.5); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| |
|
| | { |
| | Parser parser("2.5em"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 2.5); |
| | EXPECT_EQ(length.unit, "em"); |
| | } |
| |
|
| | { |
| | Parser parser("100%"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 100.0); |
| | EXPECT_EQ(length.unit, "%"); |
| | } |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseColors) |
| | { |
| | { |
| | Parser parser("#ff0000"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result); |
| | EXPECT_EQ(color.r, 1); |
| | EXPECT_EQ(color.g, 0); |
| | EXPECT_EQ(color.b, 0); |
| | } |
| |
|
| | { |
| | Parser parser("#00ff00"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result); |
| | EXPECT_EQ(color.r, 0); |
| | EXPECT_EQ(color.g, 1); |
| | EXPECT_EQ(color.b, 0); |
| | } |
| |
|
| | { |
| | Parser parser("#0000ff"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result); |
| | EXPECT_EQ(color.r, 0); |
| | EXPECT_EQ(color.g, 0); |
| | EXPECT_EQ(color.b, 1); |
| | } |
| |
|
| | { |
| | Parser parser("rgb(255, 0, 0)"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result); |
| | EXPECT_EQ(color.r, 1); |
| | EXPECT_EQ(color.g, 0); |
| | EXPECT_EQ(color.b, 0); |
| | } |
| |
|
| | { |
| | Parser parser("rgba(255, 0, 0, 128)"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result); |
| | EXPECT_DOUBLE_EQ(color.r, 1); |
| | EXPECT_DOUBLE_EQ(color.g, 0); |
| | EXPECT_DOUBLE_EQ(color.b, 0); |
| | EXPECT_NEAR(color.a, 128 / 255.0, 1e-6); |
| | } |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseParameterReferences) |
| | { |
| | { |
| | Parser parser("@TestParam"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 10.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| |
|
| | { |
| | Parser parser("@TestColor"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({.manager = &manager, .context = {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result); |
| | EXPECT_EQ(color.r, 1); |
| | EXPECT_EQ(color.g, 0); |
| | EXPECT_EQ(color.b, 0); |
| | } |
| |
|
| | { |
| | Parser parser("@TestNumber"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({.manager = &manager, .context = {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 5.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseArithmeticOperations) |
| | { |
| | { |
| | Parser parser("10 + 5"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 15.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("10px + 5px"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 15.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| |
|
| | { |
| | Parser parser("10 - 5"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 5.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("10px - 5px"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 5.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| |
|
| | { |
| | Parser parser("10 * 5"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 50.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("10px * 2"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 20.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| |
|
| | { |
| | Parser parser("10 / 2"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 5.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("10px / 2"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 5.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseComplexExpressions) |
| | { |
| | { |
| | Parser parser("(10 + 5) * 2"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 30.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("(10px + 5px) * 2"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 30.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| |
|
| | { |
| | Parser parser("@TestParam + 5px"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 15.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| |
|
| | { |
| | Parser parser("@TestParam * @TestNumber"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 50.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseUnaryOperations) |
| | { |
| | { |
| | Parser parser("+10"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 10.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("-10"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, -10.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("-10px"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, -10.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseFunctionCalls) |
| | { |
| | { |
| | Parser parser("lighten(#ff0000, 20)"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result).asValue<QColor>(); |
| | |
| | EXPECT_GT(color.lightness(), QColor(0xff0000).lightness()); |
| | } |
| |
|
| | { |
| | Parser parser("darken(#ff0000, 20)"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result).asValue<QColor>(); |
| | |
| | EXPECT_LT(color.lightness(), QColor(0xff0000).lightness()); |
| | } |
| |
|
| | { |
| | Parser parser("lighten(@TestColor, 20)"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result).asValue<QColor>(); |
| | |
| | EXPECT_GT(color.lightness(), QColor(0xff0000).lightness()); |
| | } |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseErrors) |
| | { |
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser("#invalid"); |
| | parser.parse(); |
| | }, |
| | Base::ParserError |
| | ); |
| |
|
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser("rgb(invalid)"); |
| | parser.parse(); |
| | }, |
| | Base::ParserError |
| | ); |
| |
|
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser("(10 + 5"); |
| | parser.parse(); |
| | }, |
| | Base::ParserError |
| | ); |
| |
|
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser("invalid()"); |
| | auto expr = parser.parse(); |
| | expr->evaluate({&manager, {}}); |
| | }, |
| | Base::ExpressionError |
| | ); |
| |
|
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser("10 / 0"); |
| | auto expr = parser.parse(); |
| | expr->evaluate({&manager, {}}); |
| | }, |
| | Base::RuntimeError |
| | ); |
| |
|
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser("10px + 5em"); |
| | auto expr = parser.parse(); |
| | expr->evaluate({&manager, {}}); |
| | }, |
| | Base::RuntimeError |
| | ); |
| |
|
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser("-@TestColor"); |
| | auto expr = parser.parse(); |
| | expr->evaluate({&manager, {}}); |
| | }, |
| | Base::ExpressionError |
| | ); |
| |
|
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser("lighten(#ff0000)"); |
| | auto expr = parser.parse(); |
| | expr->evaluate({&manager, {}}); |
| | }, |
| | Base::ExpressionError |
| | ); |
| |
|
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser("lighten(10px, 20)"); |
| | auto expr = parser.parse(); |
| | expr->evaluate({&manager, {}}); |
| | }, |
| | Base::ExpressionError |
| | ); |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseWhitespace) |
| | { |
| | { |
| | Parser parser(" 10 + 5 "); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 15.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("10px+5px"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 15.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| |
|
| | { |
| | Parser parser("rgb(255,0,0)"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result); |
| | EXPECT_EQ(color.r, 1); |
| | EXPECT_EQ(color.g, 0); |
| | EXPECT_EQ(color.b, 0); |
| | } |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseEdgeCases) |
| | { |
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser(""); |
| | parser.parse(); |
| | }, |
| | Base::ParserError |
| | ); |
| |
|
| | |
| | EXPECT_THROW( |
| | { |
| | Parser parser(" "); |
| | parser.parse(); |
| | }, |
| | Base::ParserError |
| | ); |
| |
|
| | |
| | { |
| | Parser parser("42"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 42.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | |
| | { |
| | Parser parser("#ff0000"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Base::Color>(result)); |
| | auto color = std::get<Base::Color>(result); |
| | EXPECT_EQ(color.r, 1); |
| | EXPECT_EQ(color.g, 0); |
| | EXPECT_EQ(color.b, 0); |
| | } |
| |
|
| | |
| | { |
| | Parser parser("@TestParam"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 10.0); |
| | EXPECT_EQ(length.unit, "px"); |
| | } |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseOperatorPrecedence) |
| | { |
| | { |
| | Parser parser("2 + 3 * 4"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 14.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("10 - 3 * 2"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 4.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("20 / 4 + 3"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 8.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| | } |
| |
|
| | |
| | TEST_F(ParserTest, ParseNestedParentheses) |
| | { |
| | { |
| | Parser parser("((2 + 3) * 4)"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 20.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| |
|
| | { |
| | Parser parser("(10 - (3 + 2)) * 2"); |
| | auto expr = parser.parse(); |
| | auto result = expr->evaluate({&manager, {}}); |
| | EXPECT_TRUE(std::holds_alternative<Numeric>(result)); |
| | auto length = std::get<Numeric>(result); |
| | EXPECT_DOUBLE_EQ(length.value, 10.0); |
| | EXPECT_EQ(length.unit, ""); |
| | } |
| | } |
| |
|