Download tests/src/Gui/StyleParameters/ParameterManagerTest.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 12.1 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp
-
curl -L -o ParameterManagerTest.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp
12.1 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later | |
| /**************************************************************************** | |
| * * | |
| * Copyright (c) 2025 Kacper Donat <kacper@kadet.net> * | |
| * * | |
| * This file is part of FreeCAD. * | |
| * * | |
| * FreeCAD is free software: you can redistribute it and/or modify it * | |
| * under the terms of the GNU Lesser General Public License as * | |
| * published by the Free Software Foundation, either version 2.1 of the * | |
| * License, or (at your option) any later version. * | |
| * * | |
| * FreeCAD is distributed in the hope that it will be useful, but * | |
| * WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * | |
| * Lesser General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Lesser General Public * | |
| * License along with FreeCAD. If not, see * | |
| * <https://www.gnu.org/licenses/>. * | |
| * * | |
| ***************************************************************************/ | |
| using namespace Gui::StyleParameters; | |
| class ParameterManagerTest: public ::testing::Test | |
| { | |
| protected: | |
| void SetUp() override | |
| { | |
| // Create test sources | |
| auto source1 = std::make_unique<InMemoryParameterSource>( | |
| std::list<Parameter> { | |
| {"BaseSize", "8px"}, | |
| {"PrimaryColor", "#ff0000"}, | |
| {"SecondaryColor", "#00ff00"}, | |
| }, | |
| ParameterSource::Metadata {"Source 1"} | |
| ); | |
| auto source2 = std::make_unique<InMemoryParameterSource>( | |
| std::list<Parameter> { | |
| {"BaseSize", "16px"}, // Override from source1 | |
| {"Margin", "@BaseSize * 2"}, | |
| {"Padding", "@BaseSize / 2"}, | |
| }, | |
| ParameterSource::Metadata {"Source 2"} | |
| ); | |
| manager.addSource(source1.get()); | |
| manager.addSource(source2.get()); | |
| sources.push_back(std::move(source1)); | |
| sources.push_back(std::move(source2)); | |
| } | |
| Gui::StyleParameters::ParameterManager manager; | |
| std::vector<std::unique_ptr<ParameterSource>> sources; | |
| }; | |
| // Test basic parameter resolution | |
| TEST_F(ParameterManagerTest, BasicParameterResolution) | |
| { | |
| { | |
| auto result = manager.resolve("BaseSize"); | |
| EXPECT_TRUE(result.has_value()); | |
| EXPECT_TRUE(std::holds_alternative<Numeric>(*result)); | |
| auto length = std::get<Numeric>(*result); | |
| EXPECT_DOUBLE_EQ(length.value, 16.0); // Should get value from source2 (later source) | |
| EXPECT_EQ(length.unit, "px"); | |
| } | |
| { | |
| auto result = manager.resolve("PrimaryColor"); | |
| EXPECT_TRUE(result.has_value()); | |
| 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); | |
| } | |
| { | |
| auto result = manager.resolve("SecondaryColor"); | |
| EXPECT_TRUE(result.has_value()); | |
| 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); | |
| } | |
| } | |
| // Test parameter references | |
| TEST_F(ParameterManagerTest, ParameterReferences) | |
| { | |
| { | |
| auto result = manager.resolve("Margin"); | |
| EXPECT_TRUE(std::holds_alternative<Numeric>(*result)); | |
| auto length = std::get<Numeric>(*result); | |
| EXPECT_DOUBLE_EQ(length.value, 32.0); // @BaseSize * 2 = 16 * 2 = 32 | |
| EXPECT_EQ(length.unit, "px"); | |
| } | |
| { | |
| auto result = manager.resolve("Padding"); | |
| EXPECT_TRUE(std::holds_alternative<Numeric>(*result)); | |
| auto length = std::get<Numeric>(*result); | |
| EXPECT_DOUBLE_EQ(length.value, 8.0); // @BaseSize / 2 = 16 / 2 = 8 | |
| EXPECT_EQ(length.unit, "px"); | |
| } | |
| } | |
| // Test caching | |
| TEST_F(ParameterManagerTest, Caching) | |
| { | |
| // First resolution should cache the result | |
| auto result1 = manager.resolve("BaseSize"); | |
| EXPECT_TRUE(std::holds_alternative<Numeric>(*result1)); | |
| // Second resolution should use cached value | |
| auto result2 = manager.resolve("BaseSize"); | |
| EXPECT_TRUE(std::holds_alternative<Numeric>(*result2)); | |
| // Results should be identical | |
| auto length1 = std::get<Numeric>(*result1); | |
| auto length2 = std::get<Numeric>(*result2); | |
| EXPECT_DOUBLE_EQ(length1.value, length2.value); | |
| EXPECT_EQ(length1.unit, length2.unit); | |
| } | |
| // Test cache invalidation | |
| TEST_F(ParameterManagerTest, CacheInvalidation) | |
| { | |
| // Initial resolution | |
| auto result1 = manager.resolve("BaseSize"); | |
| EXPECT_TRUE(std::holds_alternative<Numeric>(*result1)); | |
| auto length1 = std::get<Numeric>(*result1); | |
| EXPECT_DOUBLE_EQ(length1.value, 16.0); | |
| // Reload should clear cache | |
| manager.reload(); | |
| // Resolution after reload should work the same | |
| auto result2 = manager.resolve("BaseSize"); | |
| EXPECT_TRUE(std::holds_alternative<Numeric>(*result2)); | |
| auto length2 = std::get<Numeric>(*result2); | |
| EXPECT_DOUBLE_EQ(length2.value, 16.0); | |
| EXPECT_EQ(length1.unit, length2.unit); | |
| } | |
| // Test source priority | |
| TEST_F(ParameterManagerTest, SourcePriority) | |
| { | |
| // Create a third source with higher priority | |
| auto source3 = std::make_unique<InMemoryParameterSource>( | |
| std::list<Parameter> { | |
| {"BaseSize", "24px"}, // Should override both previous sources | |
| }, | |
| ParameterSource::Metadata {"Source 3"} | |
| ); | |
| manager.addSource(source3.get()); | |
| sources.push_back(std::move(source3)); | |
| // Should get value from the latest source (highest priority) | |
| auto result = manager.resolve("BaseSize"); | |
| EXPECT_TRUE(std::holds_alternative<Numeric>(*result)); | |
| auto length = std::get<Numeric>(*result); | |
| EXPECT_DOUBLE_EQ(length.value, 24.0); | |
| EXPECT_EQ(length.unit, "px"); | |
| } | |
| // Test parameter listing | |
| TEST_F(ParameterManagerTest, ParameterListing) | |
| { | |
| auto params = manager.parameters(); | |
| // Should contain all parameters from all sources | |
| std::set<std::string> paramNames; | |
| for (const auto& param : params) { | |
| paramNames.insert(param.name); | |
| } | |
| EXPECT_TRUE(paramNames.contains("BaseSize")); | |
| EXPECT_TRUE(paramNames.contains("PrimaryColor")); | |
| EXPECT_TRUE(paramNames.contains("SecondaryColor")); | |
| EXPECT_TRUE(paramNames.contains("Margin")); | |
| EXPECT_TRUE(paramNames.contains("Padding")); | |
| // Should not contain duplicates (BaseSize should appear only once) | |
| EXPECT_EQ(paramNames.count("BaseSize"), 1); | |
| } | |
| // Test expression retrieval | |
| TEST_F(ParameterManagerTest, ExpressionRetrieval) | |
| { | |
| { | |
| auto expr = manager.expression("BaseSize"); | |
| EXPECT_TRUE(expr.has_value()); | |
| EXPECT_EQ(*expr, "16px"); | |
| } | |
| { | |
| auto expr = manager.expression("Margin"); | |
| EXPECT_TRUE(expr.has_value()); | |
| EXPECT_EQ(*expr, "@BaseSize * 2"); | |
| } | |
| { | |
| auto expr = manager.expression("NonExistent"); | |
| EXPECT_FALSE(expr.has_value()); | |
| } | |
| } | |
| // Test parameter retrieval | |
| TEST_F(ParameterManagerTest, ParameterRetrieval) | |
| { | |
| { | |
| auto param = manager.parameter("BaseSize"); | |
| EXPECT_TRUE(param.has_value()); | |
| EXPECT_EQ(param->name, "BaseSize"); | |
| EXPECT_EQ(param->value, "16px"); | |
| } | |
| { | |
| auto param = manager.parameter("NonExistent"); | |
| EXPECT_FALSE(param.has_value()); | |
| } | |
| } | |
| // Test source management | |
| TEST_F(ParameterManagerTest, SourceManagement) | |
| { | |
| auto sources = manager.sources(); | |
| EXPECT_EQ(sources.size(), 2); // We added 2 sources in SetUp | |
| // Test that we can access the sources | |
| for (auto source : sources) { | |
| EXPECT_NE(source, nullptr); | |
| auto params = source->all(); | |
| EXPECT_FALSE(params.empty()); | |
| } | |
| } | |
| // Test circular reference detection | |
| TEST_F(ParameterManagerTest, CircularReferenceDetection) | |
| { | |
| // Create a source with circular reference | |
| auto circularSource = std::make_unique<InMemoryParameterSource>( | |
| std::list<Parameter> { | |
| {"A", "@B"}, | |
| {"B", "@A"}, | |
| }, | |
| ParameterSource::Metadata {"Circular Source"} | |
| ); | |
| manager.addSource(circularSource.get()); | |
| sources.push_back(std::move(circularSource)); | |
| // Should handle circular reference gracefully | |
| auto result = manager.resolve("A"); | |
| // Should return the expression string as fallback | |
| EXPECT_TRUE(std::holds_alternative<std::string>(*result)); | |
| } | |
| // Test complex expressions | |
| TEST_F(ParameterManagerTest, ComplexExpressions) | |
| { | |
| // Create a source with complex expressions | |
| auto complexSource = std::make_unique<InMemoryParameterSource>( | |
| std::list<Parameter> { | |
| {"ComplexMargin", "(@BaseSize + 4px) * 2"}, | |
| {"ComplexPadding", "(@BaseSize - 2px) / 2"}, | |
| {"ColorWithFunction", "lighten(@PrimaryColor, 20)"}, | |
| }, | |
| ParameterSource::Metadata {"Complex Source"} | |
| ); | |
| manager.addSource(complexSource.get()); | |
| sources.push_back(std::move(complexSource)); | |
| { | |
| auto result = manager.resolve("ComplexMargin"); | |
| EXPECT_TRUE(std::holds_alternative<Numeric>(*result)); | |
| auto length = std::get<Numeric>(*result); | |
| EXPECT_DOUBLE_EQ(length.value, 40.0); // (16 + 4) * 2 = 20 * 2 = 40 | |
| EXPECT_EQ(length.unit, "px"); | |
| } | |
| { | |
| auto result = manager.resolve("ComplexPadding"); | |
| EXPECT_TRUE(std::holds_alternative<Numeric>(*result)); | |
| auto length = std::get<Numeric>(*result); | |
| EXPECT_DOUBLE_EQ(length.value, 7.0); // (16 - 2) / 2 = 14 / 2 = 7 | |
| EXPECT_EQ(length.unit, "px"); | |
| } | |
| { | |
| auto result = manager.resolve("ColorWithFunction"); | |
| EXPECT_TRUE(std::holds_alternative<Base::Color>(*result)); | |
| auto color = std::get<Base::Color>(*result).asValue<QColor>(); | |
| // Should be lighter than the original red | |
| EXPECT_GT(color.lightness(), QColor(0xff0000).lightness()); | |
| } | |
| } | |
| // Test error handling | |
| TEST_F(ParameterManagerTest, ErrorHandling) | |
| { | |
| // Test non-existent parameter | |
| auto result = manager.resolve("NonExistent"); | |
| EXPECT_FALSE(result.has_value()); | |
| // Test invalid expression | |
| auto invalidSource = std::make_unique<InMemoryParameterSource>( | |
| std::list<Parameter> { | |
| {"Invalid", "invalid expression that will fail"}, | |
| }, | |
| ParameterSource::Metadata {"Invalid Source"} | |
| ); | |
| manager.addSource(invalidSource.get()); | |
| sources.push_back(std::move(invalidSource)); | |
| // Should handle invalid expression gracefully | |
| auto invalidResult = manager.resolve("Invalid"); | |
| // Should return the expression string as fallback | |
| EXPECT_TRUE(invalidResult.has_value()); | |
| EXPECT_TRUE(std::holds_alternative<std::string>(*invalidResult)); | |
| } | |
| DEFINE_STYLE_PARAMETER(BaseSize, Numeric(8, "px")); | |
| TEST_F(ParameterManagerTest, ResolveParameterDefinition) | |
| { | |
| auto result = manager.resolve(BaseSize); | |
| EXPECT_DOUBLE_EQ(result.value, 16); | |
| EXPECT_EQ(result.unit, "px"); | |
| } | |
| DEFINE_STYLE_PARAMETER(MarginSize, Numeric(16, "px")); | |
| TEST_F(ParameterManagerTest, ResolveParameterDefinitionDefault) | |
| { | |
| auto result = manager.resolve(MarginSize); | |
| EXPECT_DOUBLE_EQ(result.value, 16); | |
| EXPECT_EQ(result.unit, "px"); | |
| } | |