Resolve #11965 - no proper execute() for cross-property references
Solution B: parsequant() function
This commit is contained in:
committed by
Chris Hennes
parent
0589deb7b3
commit
9e1edf36f0
105
tests/src/App/ExpressionParser.cpp
Normal file
105
tests/src/App/ExpressionParser.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "Base/Quantity.h"
|
||||
|
||||
#include "App/Application.h"
|
||||
#include "App/Document.h"
|
||||
#include "App/DocumentObject.h"
|
||||
#include "App/Expression.h"
|
||||
#include "App/ExpressionParser.h"
|
||||
|
||||
#include "src/App/InitApplication.h"
|
||||
|
||||
// clang-format off
|
||||
|
||||
class ExpressionParserTest: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
static void SetUpTestSuite()
|
||||
{
|
||||
tests::initApplication();
|
||||
}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
_doc_name = App::GetApplication().getUniqueDocumentName("test");
|
||||
_this_doc = App::GetApplication().newDocument(_doc_name.c_str(), "testUser");
|
||||
_this_obj = _this_doc -> addObject("Sketcher::SketchObject");
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
App::GetApplication().closeDocument(_doc_name.c_str());
|
||||
}
|
||||
|
||||
std::string doc_name() { return _doc_name; }
|
||||
App::Document* this_doc() { return _this_doc; }
|
||||
App::DocumentObject* this_obj() { return _this_obj; }
|
||||
|
||||
Base::Quantity parse_expression_text_as_quantity(const char* expression_text) {
|
||||
auto expression = App::ExpressionParser::parse(this_obj(), expression_text);
|
||||
auto expression_value = expression->getValueAsAny();
|
||||
auto quantity_result = App::any_cast<Base::Quantity>(expression_value);
|
||||
return quantity_result;
|
||||
}
|
||||
|
||||
Base::Quantity parse_quantity_text_as_quantity(const char* quantity_text) {
|
||||
auto quantity_qstr = QString::fromStdString(std::string(quantity_text));
|
||||
auto quantity_result = Base::Quantity::parse(quantity_qstr);
|
||||
return quantity_result;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _doc_name;
|
||||
App::Document* _this_doc {};
|
||||
App::DocumentObject* _this_obj {};
|
||||
};
|
||||
|
||||
// https://github.com/FreeCAD/FreeCAD/issues/11965
|
||||
TEST_F(ExpressionParserTest, functionPARSEQUANT)
|
||||
{
|
||||
|
||||
EXPECT_ANY_THROW(App::ExpressionParser::parse(this_obj(), "parsequant()")) << "should not parse empty";
|
||||
|
||||
EXPECT_NO_THROW(App::ExpressionParser::parse(this_obj(), "parsequant(1 mm)")) << "should parse simple quantity";
|
||||
EXPECT_NO_THROW(App::ExpressionParser::parse(this_obj(), "parsequant(<<(1 + 2) m>>)")) << "should parse literal quantity";
|
||||
EXPECT_NO_THROW(App::ExpressionParser::parse(this_obj(), "parsequant(str(1 m + 2 mm))")) << "should parse str-function quantity";
|
||||
|
||||
EXPECT_ANY_THROW(parse_quantity_text_as_quantity("parsequant(1 mm)")) << "should not treat parsequant-function as quantity";
|
||||
EXPECT_EQ(parse_quantity_text_as_quantity("1 mm"), parse_quantity_text_as_quantity("1 mm")) << "equality sanity check";
|
||||
EXPECT_NE(parse_quantity_text_as_quantity("1 mm"), parse_quantity_text_as_quantity("2 mm")) << "inequality sanity check";
|
||||
|
||||
std::array<std::pair<const char*,const char*>, 12> expression_vs_quantity_list = {{
|
||||
// length
|
||||
{ "1 mm", "1 mm" },
|
||||
{ "parsequant(1 mm)", "1 mm" },
|
||||
{ "parsequant(<<(1 + 2) m>>)", "3000 mm" },
|
||||
{ "parsequant(str(1 m + 2 mm))", "1002 mm"},
|
||||
// angle
|
||||
{ "10 deg", "10 deg" },
|
||||
{ "parsequant(10 deg)", "10 deg" },
|
||||
{ "parsequant(<<(10 + 20) deg>>)", "30 deg" },
|
||||
{ "parsequant(str(10 deg + 20 deg))", "30 deg" },
|
||||
// mass
|
||||
{ "10 g", "10 g" },
|
||||
{ "parsequant(10 g)", "10 g" },
|
||||
{ "parsequant(<<(10 + 20) kg>>)", "30000 g" },
|
||||
{ "parsequant(str(10 kg + 20010 g))", "30.01 kg" },
|
||||
}};
|
||||
|
||||
for ( const auto& expression_vs_quantity_pair : expression_vs_quantity_list ) {
|
||||
auto expression_text = expression_vs_quantity_pair.first;
|
||||
auto quantity_text = expression_vs_quantity_pair.second;
|
||||
auto expression_result = parse_expression_text_as_quantity(expression_text);
|
||||
auto quantity_result = parse_quantity_text_as_quantity(quantity_text);
|
||||
EXPECT_EQ(expression_result, quantity_result) << "mismatch:"
|
||||
" expression_text='" + std::string(expression_text) + "'"
|
||||
" quantity_text='" + std::string(quantity_text) + "'"
|
||||
" expression_representation='" + expression_result.getUserString().toStdString() + "'"
|
||||
" quantity_representation='" + quantity_result.getUserString().toStdString() + "'"
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
Reference in New Issue
Block a user