File size: 7,138 Bytes
985c397 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | // SPDX-License-Identifier: LGPL-2.1-or-later
#include "gtest/gtest.h"
#include <gmock/gmock.h>
#include <src/App/InitApplication.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObject.h>
#include <App/GeoFeatureGroupExtension.h>
#include <Base/Interpreter.h>
using namespace App;
// NOLINTBEGIN(readability-magic-numbers,cppcoreguidelines-avoid-magic-numbers)
class DocumentObjectTest: public ::testing::Test
{
protected:
static void SetUpTestSuite()
{
tests::initApplication();
}
void SetUp() override
{
_docName = App::GetApplication().getUniqueDocumentName("test");
_doc = App::GetApplication().newDocument(_docName.c_str(), "testUser");
}
void TearDown() override
{
App::GetApplication().closeDocument(_docName.c_str());
}
// NOLINTBEGIN(cppcoreguidelines-non-private-member-variables-in-classes)
std::string _docName {};
App::Document* _doc {};
// NOLINTEND(cppcoreguidelines-non-private-member-variables-in-classes)
};
TEST_F(DocumentObjectTest, getSubObjectList)
{
// Arrange
// The name of a Part::Box added to the document
auto boxName {_doc->addObject("Part::Box")->getNameInDocument()};
// The name of a Part::Cylinder added to the document
auto cylName {_doc->addObject("Part::Cylinder")->getNameInDocument()};
// An App::Part object added to the document
auto part {_doc->addObject("App::Part")};
// The name of the App::Part added to the document
auto partName {part->getNameInDocument()};
// The name of the object used as argument for the calls of DocumentObject::getSubObjectList()
auto subName {std::string()};
// A vector of int used as argument for the call of DocumentObject::getSubObjectList() with
// argument flatten not set (or set to false)
auto sizesNoFlatten {std::vector<int>()};
// A vector of int used as argument for the call of DocumentObject::getSubObjectList() with
// argument flatten set to true
auto sizesFlatten {std::vector<int>()};
// A helper string used to compose the argument of some calls of
// Base::Interpreter().runString()
auto cmd {std::string()};
// Performing a fusion to create an object that will be searched with the calls of
// DocumentObject::getSubObjectList()
Base::Interpreter().runString("from BOPTools import BOPFeatures");
Base::Interpreter().runString("bp = BOPFeatures.BOPFeatures(App.activeDocument())");
cmd = "bp.make_multi_fuse([\"";
cmd += boxName;
cmd += "\", \"";
cmd += cylName;
cmd += "\", ])";
Base::Interpreter().runString(cmd.c_str());
Base::Interpreter().runString("App.ActiveDocument.recompute()");
// The name of the fusion object
auto fuseName {_doc->getObject("Fusion")->getNameInDocument()};
// Defining the name of the object that will be searched with the calls of
// DocumentObject::getSubObjectList()
subName = fuseName;
subName += ".";
subName += boxName;
subName += ".Edge1";
// Adding the fusion to the App::Part object to test the differences between calling
// DocumentObject::getSubObjectList() with the flatten argument set to false or set to true
cmd = "App.ActiveDocument.getObject(\"";
cmd += partName;
cmd += "\").addObject(App.ActiveDocument.getObject(\"";
cmd += fuseName;
cmd += "\"))";
Base::Interpreter().runString(cmd.c_str());
Base::Interpreter().runString("App.ActiveDocument.recompute()");
// A vector of DocumentObjects used to store the result of the call to
// DocumentObject::getSubObjectList() without the subname parameter
auto docSubObjsNoSubName {std::vector<DocumentObject*>()};
// A vector of DocumentObjects used to store the result of the call to
// DocumentObject::getSubObjectList() with only the subname parameter
auto docSubObjsWithSubName {std::vector<DocumentObject*>()};
// A vector of DocumentObjects used to store the result of the call to
// DocumentObject::getSubObjectList() with the parameters subname and subsizes
auto docSubObjsWithSubSizes {std::vector<DocumentObject*>()};
// A vector of DocumentObjects used to store the result of the call to
// DocumentObject::getSubObjectList() with the flatten parameter set to true
auto docSubObjsFlatten {std::vector<DocumentObject*>()};
// Act
docSubObjsNoSubName = part->getSubObjectList(nullptr);
docSubObjsWithSubName = part->getSubObjectList(subName.c_str());
docSubObjsWithSubSizes = part->getSubObjectList(subName.c_str(), &sizesNoFlatten);
docSubObjsFlatten = part->getSubObjectList(subName.c_str(), &sizesFlatten, true);
// Assert
// If DocumentObject::getSubObjectList() is called without giving the subname argument it
// returns a vector with only one entry, corresponding to the object that called the method
EXPECT_EQ(docSubObjsNoSubName.size(), 1);
EXPECT_EQ(docSubObjsNoSubName[0]->getID(), _doc->getObject(partName)->getID());
// If DocumentObject::getSubObjectList() is called with the subname argument it returns a vector
// with one entry for each sub object in the subname plus one entry with the object that called
// the method
EXPECT_EQ(docSubObjsWithSubName.size(), 3);
EXPECT_EQ(docSubObjsWithSubName[0]->getID(), _doc->getObject(partName)->getID());
EXPECT_EQ(docSubObjsWithSubName[1]->getID(), _doc->getObject(fuseName)->getID());
EXPECT_EQ(docSubObjsWithSubName[2]->getID(), _doc->getObject(boxName)->getID());
// If DocumentObject::getSubObjectList() is called with the subsizes argument it returns the
// same vector of the previous case and the subsizes argument stores the positions in the
// subname string corresponding to start of the sub objects names.
// The position takes into account also the '.' in the subname
EXPECT_EQ(docSubObjsWithSubSizes.size(), 3);
EXPECT_EQ(docSubObjsWithSubSizes[0]->getID(), _doc->getObject(partName)->getID());
EXPECT_EQ(docSubObjsWithSubSizes[1]->getID(), _doc->getObject(fuseName)->getID());
EXPECT_EQ(docSubObjsWithSubSizes[2]->getID(), _doc->getObject(boxName)->getID());
EXPECT_EQ(sizesNoFlatten.size(), 3);
EXPECT_EQ(sizesNoFlatten[0], 0);
EXPECT_EQ(sizesNoFlatten[1], strlen(fuseName) + 1);
EXPECT_EQ(sizesNoFlatten[2], strlen(fuseName) + strlen(boxName) + 2);
// If DocumentObject::getSubObjectList() is called with the flattened argument set to true, it
// returns a vector with all the sub objects in the subname that don't belong to the same
// App::GeoFeatureGroupExtension object, plus one entry with the object that called the method
EXPECT_EQ(docSubObjsFlatten.size(), 2);
EXPECT_EQ(docSubObjsFlatten[0]->getID(), _doc->getObject(partName)->getID());
EXPECT_EQ(docSubObjsFlatten[1]->getID(), _doc->getObject(boxName)->getID());
EXPECT_EQ(sizesFlatten.size(), 2);
EXPECT_EQ(sizesFlatten[0], 0);
EXPECT_EQ(sizesFlatten[1], strlen(fuseName) + strlen(boxName) + 2);
}
// NOLINTEND(readability-magic-numbers, cppcoreguidelines-avoid-magic-numbers)
|