From 6c2bbd3fc5fb2b71ee678b1404378f061b61b08d Mon Sep 17 00:00:00 2001 From: azv Date: Fri, 7 Dec 2018 14:42:04 +0300 Subject: [PATCH] [Code coverage ConstructionPlugin]: Unit tests to check error messages --- src/ConstructionPlugin/CMakeLists.txt | 6 +- .../ConstructionPlugin_Axis.cpp | 6 + .../ConstructionPlugin_Plane.cpp | 18 ++- .../ConstructionPlugin_Validators.cpp | 2 +- .../Test/TestAxis_ErrorMsg.py | 120 ++++++++++++++++ .../Test/TestPlane_ErrorMsg.py | 133 ++++++++++++++++++ .../Test/TestPoint_ErrorMsg.py | 77 ++++++++++ 7 files changed, 358 insertions(+), 4 deletions(-) create mode 100644 src/ConstructionPlugin/Test/TestAxis_ErrorMsg.py create mode 100644 src/ConstructionPlugin/Test/TestPlane_ErrorMsg.py create mode 100644 src/ConstructionPlugin/Test/TestPoint_ErrorMsg.py diff --git a/src/ConstructionPlugin/CMakeLists.txt b/src/ConstructionPlugin/CMakeLists.txt index 3c5423b1f..300cd7b46 100644 --- a/src/ConstructionPlugin/CMakeLists.txt +++ b/src/ConstructionPlugin/CMakeLists.txt @@ -78,6 +78,7 @@ INCLUDE_DIRECTORIES( ADD_UNIT_TESTS(TestAxisCreation.py + TestAxis_ErrorMsg.py UnitTestAxis.py TestPoint_XYZ.py TestPoint_IntersectLines.py @@ -90,4 +91,7 @@ ADD_UNIT_TESTS(TestAxisCreation.py TestPoint_GeometricalPropertyCenterOfCircle.py TestPoint_VertexSelection.py TestPointName.py - TestPlane.py) + TestPoint_ErrorMsg.py + TestPlane.py + TestPlane_ErrorMsg.py +) diff --git a/src/ConstructionPlugin/ConstructionPlugin_Axis.cpp b/src/ConstructionPlugin/ConstructionPlugin_Axis.cpp index 0dd9a851c..857dfd739 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Axis.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Axis.cpp @@ -268,6 +268,8 @@ void ConstructionPlugin_Axis::createAxisByPlaneAndPoint() GeomAPI_ShapeIterator anIt(aFaceShape); aFace = anIt.current()->face(); } + if (!aFace) + return; std::shared_ptr aPln = aFace->getPlane(); // Get point. @@ -309,6 +311,8 @@ void ConstructionPlugin_Axis::createAxisByTwoPlanes() GeomAPI_ShapeIterator anIt(aFaceShape1); aFace1 = anIt.current()->face(); } + if (!aFace1) + return; std::shared_ptr aPln1 = aFace1->getPlane(); std::string useOffset1 = string(USE_OFFSET1())->value(); @@ -335,6 +339,8 @@ void ConstructionPlugin_Axis::createAxisByTwoPlanes() GeomAPI_ShapeIterator anIt(aFaceShape2); aFace2 = anIt.current()->face(); } + if (!aFace2) + return; std::shared_ptr aPln2 = aFace2->getPlane(); std::string useOffset2 = string(USE_OFFSET2())->value(); diff --git a/src/ConstructionPlugin/ConstructionPlugin_Plane.cpp b/src/ConstructionPlugin/ConstructionPlugin_Plane.cpp index 1189cb761..9c3770bd4 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Plane.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Plane.cpp @@ -240,6 +240,8 @@ std::shared_ptr ConstructionPlugin_Plane::createByLineAndPoint() GeomAPI_ShapeIterator anIt(aLineShape); anEdge = anIt.current()->edge(); } + if (!anEdge) + return GeomShapePtr(); // Get point. AttributeSelectionPtr aPointSelection = selection(POINT()); @@ -285,7 +287,7 @@ std::shared_ptr ConstructionPlugin_Plane::createByDistanceFromOth bool anIsReverse = boolean(REVERSE())->value(); if(anIsReverse) aDist = -aDist; GeomShapePtr aShape = aFaceAttr->value(); - if (!aShape.get()) { + if (!aShape.get() && aFaceAttr->context()) { aShape = aFaceAttr->context()->shape(); } @@ -301,6 +303,8 @@ std::shared_ptr ConstructionPlugin_Plane::createByDistanceFromOth GeomAPI_ShapeIterator anIt(aShape); aFace = anIt.current()->face(); } + if (!aFace) + return GeomShapePtr(); std::shared_ptr aPln = aFace->getPlane(); std::shared_ptr aOrig = aPln->location(); @@ -338,7 +342,9 @@ std::shared_ptr ConstructionPlugin_Plane::createByCoincidentPoint if(!aPointShape.get()) { aPointShape = aPointSelection->context()->shape(); } - std::shared_ptr aVertex(new GeomAPI_Vertex(aPointShape)); + std::shared_ptr aVertex = aPointShape->vertex(); + if (!aVertex) + return GeomShapePtr(); std::shared_ptr anOrig = aVertex->point(); std::shared_ptr aPln = aFace->getPlane(); @@ -366,6 +372,8 @@ std::shared_ptr ConstructionPlugin_Plane::createByRotation() GeomAPI_ShapeIterator anIt(aFaceShape); aFace = anIt.current()->face(); } + if (!aFace) + return GeomShapePtr(); aFace = makeRectangularFace(aFace, aFace->getPlane()); // Get axis. @@ -382,6 +390,8 @@ std::shared_ptr ConstructionPlugin_Plane::createByRotation() GeomAPI_ShapeIterator anIt(anAxisShape); anEdge = anIt.current()->edge(); } + if (!anEdge) + return GeomShapePtr(); std::shared_ptr anAxis = std::shared_ptr(new GeomAPI_Ax1(anEdge->line()->location(), @@ -422,6 +432,8 @@ std::shared_ptr ConstructionPlugin_Plane::createByTwoParallelPlan GeomAPI_ShapeIterator anIt(aFaceShape1); aFace1 = anIt.current()->face(); } + if (!aFace1) + return GeomShapePtr(); std::shared_ptr aPln1 = aFace1->getPlane(); // Get plane 2. @@ -438,6 +450,8 @@ std::shared_ptr ConstructionPlugin_Plane::createByTwoParallelPlan GeomAPI_ShapeIterator anIt(aFaceShape2); aFace2 = anIt.current()->face(); } + if (!aFace2) + return GeomShapePtr(); std::shared_ptr aPln2 = aFace2->getPlane(); std::shared_ptr anOrig1 = aPln1->location(); diff --git a/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp b/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp index 50047dd69..a06ef0fda 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp @@ -547,7 +547,7 @@ std::shared_ptr getPln(const GeomShapePtr theShape) return aPln; } - if(!aFace->isPlanar()) { + if(!aFace || !aFace->isPlanar()) { return aPln; } diff --git a/src/ConstructionPlugin/Test/TestAxis_ErrorMsg.py b/src/ConstructionPlugin/Test/TestAxis_ErrorMsg.py new file mode 100644 index 000000000..321512831 --- /dev/null +++ b/src/ConstructionPlugin/Test/TestAxis_ErrorMsg.py @@ -0,0 +1,120 @@ +## Copyright (C) 2018-20xx CEA/DEN, EDF R&D +## +## This library 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. +## +## This library 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 this library; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## +## See http:##www.salome-platform.org/ or +## email : webmaster.salome@opencascade.com +## + + +from ModelAPI import * +aSession = ModelAPI_Session.get() +aDocument = aSession.moduleDocument() + +# Create a part +aSession.startOperation() +aPartFeature = aDocument.addFeature("Part") +aSession.finishOperation() +aPartResult = modelAPI_ResultPart(aPartFeature.firstResult()) +aPart = aPartResult.partDoc() + +# Create auxiliary box +aSession.startOperation() +aBox = aPart.addFeature("Box") +aBox.string("CreationMethod").setValue("BoxByDimensions") +aBox.real("dx").setValue(50) +aBox.real("dy").setValue(50) +aBox.real("dz").setValue(50) +aSession.finishOperation() + +# Create auxiliary compound +aSession.startOperation() +aCompound = aPart.addFeature("Compound") +aCompoundList = aCompound.selectionList("base_objects") +aCompoundList.append("Box_1_1/Front", "FACE") +aCompoundList.append("[Box_1_1/Left][Box_1_1/Top]", "EDGE") +aSession.finishOperation() + +# Create auxiliary box 2 +aSession.startOperation() +aBox = aPart.addFeature("Box") +aBox.string("CreationMethod").setValue("BoxByDimensions") +aBox.real("dx").setValue(50) +aBox.real("dy").setValue(50) +aBox.real("dz").setValue(50) +aSession.finishOperation() + +# Create auxiliary compound 2 +aSession.startOperation() +aCompound = aPart.addFeature("Compound") +aCompoundList = aCompound.selectionList("base_objects") +aCompoundList.append("[Box_2_1/Left][Box_2_1/Top]", "EDGE") +aCompoundList.append("Box_2_1/Front", "FACE") +aSession.finishOperation() + + +# Axis by cylindrical face +aSession.startOperation() +Axis_1 = aPart.addFeature("Axis") +Axis_1.string("CreationMethod").setValue("AxisByCylindricalFaceCase") +Axis_1.selection("CylindricalFace").selectSubShape("COMPOUND", "Compound_2_1") +Axis_1.execute() +aSession.finishOperation() +assert(Axis_1.error() != "") + +# Axis by dimensions +aSession.startOperation() +Axis_1.string("CreationMethod").setValue("AxisByDimensionsCase") +Axis_1.real("DX").setValue(0) +Axis_1.real("DY").setValue(0) +Axis_1.real("DZ").setValue(0) +Axis_1.execute() +assert(Axis_1.error() != "") +aSession.finishOperation() + +# Axis by line +aSession.startOperation() +Axis_1.string("CreationMethod").setValue("by_line") +Axis_1.selection("line").selectSubShape("COMPOUND", "Compound_1_1") +Axis_1.execute() +assert(Axis_1.error() != "") +aSession.finishOperation() + +# Axis by plane and point +aSession.startOperation() +Axis_1.string("CreationMethod").setValue("by_plane_and_point") +Axis_1.selection("point").selectSubShape("COMPOUND", "Compound_1_1") +Axis_1.selection("plane").selectSubShape("COMPOUND", "Compound_2_1") +Axis_1.execute() +assert(Axis_1.error() != "") +aSession.finishOperation() + +# Axis by two planes +aSession.startOperation() +Axis_1.string("CreationMethod").setValue("by_two_planes") +Axis_1.selection("plane1").selectSubShape("COMPOUND", "Compound_2_1") +Axis_1.selection("plane2").selectSubShape("COMPOUND", "Compound_2_1") +Axis_1.execute() +assert(Axis_1.error() != "") +aSession.finishOperation() + +aSession.startOperation() +Axis_1.selection("plane1").selectSubShape("COMPOUND", "Compound_1_1") +Axis_1.string("use_offset1").setValue("true") +Axis_1.real("offset1").setValue(10) +Axis_1.boolean("reverse_offset1").setValue(True) +Axis_1.execute() +assert(Axis_1.error() != "") +aSession.finishOperation() diff --git a/src/ConstructionPlugin/Test/TestPlane_ErrorMsg.py b/src/ConstructionPlugin/Test/TestPlane_ErrorMsg.py new file mode 100644 index 000000000..506b78b1a --- /dev/null +++ b/src/ConstructionPlugin/Test/TestPlane_ErrorMsg.py @@ -0,0 +1,133 @@ +## Copyright (C) 2018-20xx CEA/DEN, EDF R&D +## +## This library 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. +## +## This library 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 this library; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## +## See http:##www.salome-platform.org/ or +## email : webmaster.salome@opencascade.com +## + + +from ModelAPI import * +aSession = ModelAPI_Session.get() +aDocument = aSession.moduleDocument() + +# Create a part +aSession.startOperation() +aPartFeature = aDocument.addFeature("Part") +aSession.finishOperation() +aPartResult = modelAPI_ResultPart(aPartFeature.firstResult()) +aPart = aPartResult.partDoc() + +# Create auxiliary box +aSession.startOperation() +aBox = aPart.addFeature("Box") +aBox.string("CreationMethod").setValue("BoxByDimensions") +aBox.real("dx").setValue(50) +aBox.real("dy").setValue(50) +aBox.real("dz").setValue(50) +aSession.finishOperation() + +# Create auxiliary compound +aSession.startOperation() +aCompound = aPart.addFeature("Compound") +aCompoundList = aCompound.selectionList("base_objects") +aCompoundList.append("Box_1_1/Front", "FACE") +aCompoundList.append("[Box_1_1/Left][Box_1_1/Top]", "EDGE") +aSession.finishOperation() + +# Create auxiliary box 2 +aSession.startOperation() +aBox = aPart.addFeature("Box") +aBox.string("CreationMethod").setValue("BoxByDimensions") +aBox.real("dx").setValue(50) +aBox.real("dy").setValue(50) +aBox.real("dz").setValue(50) +aSession.finishOperation() + +# Create auxiliary compound 2 +aSession.startOperation() +aCompound = aPart.addFeature("Compound") +aCompoundList = aCompound.selectionList("base_objects") +aCompoundList.append("[Box_2_1/Left][Box_2_1/Top]", "EDGE") +aCompoundList.append("Box_2_1/Front", "FACE") +aSession.finishOperation() + + +# Plane by line and point +aSession.startOperation() +Plane_1 = aPart.addFeature("Plane") +Plane_1.string("creation_method").setValue("by_line_and_point") +Plane_1.selection("line").selectSubShape("COMPOUND", "Compound_1_1") +Plane_1.selection("point").selectSubShape("VERTEX", "PartSet/Origin") +Plane_1.execute() +assert(Plane_1.error() != "") +aSession.finishOperation() + +# Unsupported type +aSession.startOperation() +Plane_1.string("creation_method").setValue("by_rotation") +Plane_1.selection("plane").selectSubShape("COMPOUND", "Compound_1_1") +Plane_1.selection("axis").selectSubShape("COMPOUND", "Compound_1_1") +Plane_1.execute() +assert(Plane_1.error() != "") +aSession.finishOperation() + +# By two parallel planes +aSession.startOperation() +Plane_1.string("creation_method").setValue("by_two_parallel_planes") +Plane_1.selection("plane1").selectSubShape("COMPOUND", "Compound_2_1") +Plane_1.selection("plane2").selectSubShape("COMPOUND", "Compound_2_1") +Plane_1.execute() +assert(Plane_1.error() != "") +aSession.finishOperation() + +aSession.startOperation() +Plane_1.selection("plane1").selectSubShape("COMPOUND", "Compound_1_1") +Plane_1.execute() +assert(Plane_1.error() != "") +aSession.finishOperation() + +# By distance from other plane +aSession.startOperation() +Plane_1.string("creation_method").setValue("by_other_plane") +Plane_1.string("by_other_plane_option").setValue("by_distance_from_other") +Plane_1.selection("plane").selectSubShape("COMPOUND", "Compound_2_1") +Plane_1.real("distance").setValue(10) +Plane_1.execute() +assert(Plane_1.error() != "") +aSession.finishOperation() + +# By coincident point +aSession.startOperation() +Plane_1.string("by_other_plane_option").setValue("by_coincident_to_point") +Plane_1.selection("coincident_point").selectSubShape("COMPOUND", "Compound_1_1") +Plane_1.execute() +assert(Plane_1.error() != "") +aSession.finishOperation() + +# By rotation +aSession.startOperation() +Plane_1.string("by_other_plane_option").setValue("by_rotation") +Plane_1.selection("axis").selectSubShape("COMPOUND", "Compound_1_1") +Plane_1.real("angle").setValue(90) +Plane_1.execute() +assert(Plane_1.error() != "") +aSession.finishOperation() + +aSession.startOperation() +Plane_1.selection("plane").selectSubShape("COMPOUND", "Compound_1_1") +Plane_1.execute() +assert(Plane_1.error() != "") +aSession.finishOperation() diff --git a/src/ConstructionPlugin/Test/TestPoint_ErrorMsg.py b/src/ConstructionPlugin/Test/TestPoint_ErrorMsg.py new file mode 100644 index 000000000..2d711644f --- /dev/null +++ b/src/ConstructionPlugin/Test/TestPoint_ErrorMsg.py @@ -0,0 +1,77 @@ +## Copyright (C) 2018-20xx CEA/DEN, EDF R&D +## +## This library 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. +## +## This library 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 this library; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## +## See http:##www.salome-platform.org/ or +## email : webmaster.salome@opencascade.com +## + + +from ModelAPI import * +aSession = ModelAPI_Session.get() +aDocument = aSession.moduleDocument() + +# Create a part +aSession.startOperation() +aPartFeature = aDocument.addFeature("Part") +aSession.finishOperation() +aPartResult = modelAPI_ResultPart(aPartFeature.firstResult()) +aPart = aPartResult.partDoc() + +# Create auxiliary box +aSession.startOperation() +aBox = aPart.addFeature("Box") +aBox.string("CreationMethod").setValue("BoxByDimensions") +aBox.real("dx").setValue(50) +aBox.real("dy").setValue(50) +aBox.real("dz").setValue(50) +aSession.finishOperation() + +# Create auxiliary compound +aSession.startOperation() +aCompound = aPart.addFeature("Compound") +aCompoundList = aCompound.selectionList("base_objects") +aCompoundList.append("Box_1_1/Front", "FACE") +aCompoundList.append("[Box_1_1/Left][Box_1_1/Top]", "EDGE") +aSession.finishOperation() + +# Create auxiliary box 2 +aSession.startOperation() +aBox = aPart.addFeature("Box") +aBox.string("CreationMethod").setValue("BoxByDimensions") +aBox.real("dx").setValue(50) +aBox.real("dy").setValue(50) +aBox.real("dz").setValue(50) +aSession.finishOperation() + +# Create auxiliary compound 2 +aSession.startOperation() +aCompound = aPart.addFeature("Compound") +aCompoundList = aCompound.selectionList("base_objects") +aCompoundList.append("[Box_2_1/Left][Box_2_1/Top]", "EDGE") +aCompoundList.append("Box_2_1/Front", "FACE") +aSession.finishOperation() + + +# Point by line and plane +aSession.startOperation() +Point_1 = aPart.addFeature("Point") +Point_1.string("creation_method").setValue("by_intersection") +Point_1.string("intersection_type").setValue("intersection_type_by_line_and_plane") +Point_1.selection("intersection_line").selectSubShape("COMPOUND", "Compound_1_1") +Point_1.selection("intersection_plane").selectSubShape("COMPOUND", "Compound_2_1") +Point_1.execute() +assert(Point_1.error() != "") +aSession.finishOperation() -- 2.39.2