diff --git a/src/Mod/Material/App/MaterialFilter.cpp b/src/Mod/Material/App/MaterialFilter.cpp index 60fdc18e35..3efe8087f7 100644 --- a/src/Mod/Material/App/MaterialFilter.cpp +++ b/src/Mod/Material/App/MaterialFilter.cpp @@ -108,3 +108,9 @@ void MaterialFilter::addRequiredComplete(const QString& uuid) } _requiredComplete.insert(uuid); } + +void MaterialFilter::clear() +{ + _required.clear(); + _requiredComplete.clear(); +} diff --git a/src/Mod/Material/App/MaterialFilter.h b/src/Mod/Material/App/MaterialFilter.h index 44285a2d94..0d2b5d7b21 100644 --- a/src/Mod/Material/App/MaterialFilter.h +++ b/src/Mod/Material/App/MaterialFilter.h @@ -184,6 +184,8 @@ public: return &_requiredComplete; } + void clear(); + private: QString _name; QSet _required; diff --git a/src/Mod/Material/App/Materials.cpp b/src/Mod/Material/App/Materials.cpp index c4c5e5daab..5c199240ca 100644 --- a/src/Mod/Material/App/Materials.cpp +++ b/src/Mod/Material/App/Materials.cpp @@ -448,7 +448,10 @@ Material::Material() : _dereferenced(false) , _oldFormat(false) , _editState(ModelEdit_None) -{} +{ + // Create an initial UUID + newUuid(); +} Material::Material(const std::shared_ptr& library, const QString& directory, @@ -1439,7 +1442,6 @@ void Material::save(QTextStream& stream, bool overwrite, bool saveAsCopy, bool s if (materialManager.exists(_uuid) && !overwrite) { // Make a new version based on the current setParentUUID(_uuid); - // newUuid(); } } diff --git a/src/Mod/Material/CMakeLists.txt b/src/Mod/Material/CMakeLists.txt index de9a075915..fc6113bd21 100644 --- a/src/Mod/Material/CMakeLists.txt +++ b/src/Mod/Material/CMakeLists.txt @@ -297,23 +297,6 @@ fc_target_copy_resource(MaterialTest ${CMAKE_BINARY_DIR}/Mod/Material ${MaterialTest_Files}) -set(MaterialTestData_Files - materialtests/Materials/TestAcrylicLegacy.FCMat - materialtests/Materials/TestAluminumAppearance.FCMat - materialtests/Materials/TestAluminumMixed.FCMat - materialtests/Materials/TestAluminumPhysical.FCMat - materialtests/Materials/TestBrassAppearance.FCMat -) - -ADD_CUSTOM_TARGET(MaterialTestData ALL - SOURCES ${MaterialTestData_Files} -) - -fc_target_copy_resource(MaterialTestData - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_BINARY_DIR}/Mod/Material - ${MaterialTestData_Files}) - ADD_CUSTOM_TARGET(MaterialScripts ALL SOURCES ${MaterialScripts_Files} ${Material_Ui_Files} ${Material_QRC_SRCS} ) diff --git a/src/Mod/Material/materialtests/TestMaterialCreation.py b/src/Mod/Material/materialtests/TestMaterialCreation.py index faf1a48f38..3b9d4ff48a 100644 --- a/src/Mod/Material/materialtests/TestMaterialCreation.py +++ b/src/Mod/Material/materialtests/TestMaterialCreation.py @@ -57,7 +57,7 @@ class MaterialCreationTestCases(unittest.TestCase): def checkNewMaterial(self, material): """ Check the state of a newly created material """ - self.assertEqual(len(material.UUID), 0) + self.assertEqual(len(material.UUID), 36) self.assertEqual(len(material.Name), 0) self.assertEqual(len(material.Author), 0) self.assertEqual(len(material.License), 0) @@ -79,8 +79,9 @@ class MaterialCreationTestCases(unittest.TestCase): material.URL = "https://www.example.com" material.Reference = "ISBN 978-1673287882" - # UUID isn't valid until the file is saved - self.assertEqual(material.UUID, '') + # Ensure a valid UUID + self.assertEqual(len(material.UUID), 36) + uuid = material.UUID self.assertEqual(material.Name, "Frankenstein") self.assertEqual(material.Author, "Mary Shelley") @@ -127,11 +128,24 @@ class MaterialCreationTestCases(unittest.TestCase): self.assertEqual(material.getPhysicalValue("Density").UserString, parseQuantity("99.90 kg/m^3").UserString) # MaterialManager is unaware of the material until it is saved - self.MaterialManager.save("User", material, "Example/Frakenstein.FCMat") + # + # When initially creating the material, setting overwrite=True preserves the UUID. This should not + # be used when saving after properties have been edited as this could adversely affect other + # documents or parts using the same material. Setting overwrite=False, or omitting it, will change + # the UUID. It will also fail if the material file already exists. + # + # Similarly, saveAsCopy=True preserves the UUID and should be used carefully. It will save an + # identical copy of the original but in a different location. + # + # The third optional parameter is saveInherited. When set to true it will mark models and properties + # as inherited without duplicating them. When false, they will be copied as uninherited. Avoid + # self-inheritance as this creates an invalid model. It will have a different UUID than the original. + # + self.MaterialManager.save("User", material, "Example/Frakenstein.FCMat", overwrite=True) # Now the UUID is valid - uuid = material.UUID self.assertEqual(len(material.UUID), 36) + self.assertEqual(material.UUID, uuid) self.assertIn(uuid, self.MaterialManager.Materials) self.assertIsNotNone(self.MaterialManager.getMaterialByPath("Example/Frakenstein.FCMat", "User")) self.assertIsNotNone(self.MaterialManager.getMaterial(uuid)) diff --git a/tests/src/Mod/Material/App/CMakeLists.txt b/tests/src/Mod/Material/App/CMakeLists.txt index a53373a5a9..53345f1fd7 100644 --- a/tests/src/Mod/Material/App/CMakeLists.txt +++ b/tests/src/Mod/Material/App/CMakeLists.txt @@ -3,6 +3,7 @@ target_sources( Material_tests_run PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/TestMaterialCards.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestMaterialFilter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TestMaterialProperties.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TestMaterials.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TestMaterialValue.cpp @@ -13,3 +14,25 @@ target_sources( target_include_directories(Material_tests_run PUBLIC ${QtCore_INCLUDE_DIRS} ) + +set(MaterialTestData_Files + Materials/TestAcrylicLegacy.FCMat + Materials/TestAluminumAppearance.FCMat + Materials/TestAluminumMixed.FCMat + Materials/TestAluminumPhysical.FCMat + Materials/TestBrassAppearance.FCMat +) + +ADD_CUSTOM_TARGET(MaterialTestData ALL + SOURCES ${MaterialTestData_Files} +) + +fc_target_copy_resource(MaterialTestData + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_BINARY_DIR}/tests + ${MaterialTestData_Files}) + +# INSTALL( +# FILES ${MaterialTest_Files} +# DESTINATION Mod/Material/materialtests +# ) diff --git a/src/Mod/Material/materialtests/Materials/TestAcrylicLegacy.FCMat b/tests/src/Mod/Material/App/Materials/TestAcrylicLegacy.FCMat similarity index 95% rename from src/Mod/Material/materialtests/Materials/TestAcrylicLegacy.FCMat rename to tests/src/Mod/Material/App/Materials/TestAcrylicLegacy.FCMat index 2ee4db5583..a25c1f3e04 100644 --- a/src/Mod/Material/materialtests/Materials/TestAcrylicLegacy.FCMat +++ b/tests/src/Mod/Material/App/Materials/TestAcrylicLegacy.FCMat @@ -10,3 +10,4 @@ KindOfMaterial = Solid [Mechanical] Density = 1190.0 kg/m^3 +Hardness = 10 diff --git a/src/Mod/Material/materialtests/Materials/TestAluminumAppearance.FCMat b/tests/src/Mod/Material/App/Materials/TestAluminumAppearance.FCMat similarity index 100% rename from src/Mod/Material/materialtests/Materials/TestAluminumAppearance.FCMat rename to tests/src/Mod/Material/App/Materials/TestAluminumAppearance.FCMat diff --git a/src/Mod/Material/materialtests/Materials/TestAluminumMixed.FCMat b/tests/src/Mod/Material/App/Materials/TestAluminumMixed.FCMat similarity index 100% rename from src/Mod/Material/materialtests/Materials/TestAluminumMixed.FCMat rename to tests/src/Mod/Material/App/Materials/TestAluminumMixed.FCMat diff --git a/src/Mod/Material/materialtests/Materials/TestAluminumPhysical.FCMat b/tests/src/Mod/Material/App/Materials/TestAluminumPhysical.FCMat similarity index 97% rename from src/Mod/Material/materialtests/Materials/TestAluminumPhysical.FCMat rename to tests/src/Mod/Material/App/Materials/TestAluminumPhysical.FCMat index 9173fcac1a..97312c28e6 100644 --- a/src/Mod/Material/materialtests/Materials/TestAluminumPhysical.FCMat +++ b/tests/src/Mod/Material/App/Materials/TestAluminumPhysical.FCMat @@ -19,7 +19,7 @@ Models: Density: "2700 kg/m^3" PoissonRatio: "0.3" ShearModulus: "27000 MPa" - UltimateStrain: "5" + # UltimateStrain: "5" UltimateTensileStrength: "250 MPa" YieldStrength: "180 MPa" YoungsModulus: "70000 MPa" diff --git a/src/Mod/Material/materialtests/Materials/TestBrassAppearance.FCMat b/tests/src/Mod/Material/App/Materials/TestBrassAppearance.FCMat similarity index 100% rename from src/Mod/Material/materialtests/Materials/TestBrassAppearance.FCMat rename to tests/src/Mod/Material/App/Materials/TestBrassAppearance.FCMat diff --git a/tests/src/Mod/Material/App/TestMaterialFilter.cpp b/tests/src/Mod/Material/App/TestMaterialFilter.cpp new file mode 100644 index 0000000000..2d27cd464b --- /dev/null +++ b/tests/src/Mod/Material/App/TestMaterialFilter.cpp @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/*************************************************************************** + * Copyright (c) 2023 David Carter * + * * + * 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 * + * . * + * * + **************************************************************************/ + +#include "gtest/gtest.h" + +#include +#ifndef _PreComp_ +#endif + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// clang-format off + +class TestMaterialFilter : public ::testing::Test { +protected: + static void SetUpTestSuite() { + if (App::Application::GetARGC() == 0) { + tests::initApplication(); + } + } + + void SetUp() override { + _modelManager = new Materials::ModelManager(); + _materialManager = new Materials::MaterialManager(); + + // Use our test files as a custom directory + ParameterGrp::handle hGrp = + App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Material/Resources"); + + _customDir = hGrp->GetASCII("CustomMaterialsDir", ""); + _useBuiltInDir = hGrp->GetBool("UseBuiltInMaterials", true); + _useWorkbenchDir = hGrp->GetBool("UseMaterialsFromWorkbenches", true); + _useUserDir = hGrp->GetBool("UseMaterialsFromConfigDir", true); + _useCustomDir = hGrp->GetBool("UseMaterialsFromCustomDir", false); + + std::string testPath = App::Application::getHomePath() + "/tests/Materials/"; + hGrp->SetASCII("CustomMaterialsDir", testPath); + hGrp->SetBool("UseBuiltInMaterials", false); + hGrp->SetBool("UseMaterialsFromWorkbenches", false); + hGrp->SetBool("UseMaterialsFromConfigDir", false); + hGrp->SetBool("UseMaterialsFromCustomDir", true); + + _materialManager->refresh(); + + _library = _materialManager->getLibrary(QLatin1String("Custom")); + } + + void TearDown() override { + ParameterGrp::handle hGrp = + App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Material/Resources"); + + // Restore preferences + hGrp->SetASCII("CustomMaterialsDir", _customDir); + hGrp->SetBool("UseBuiltInMaterials", _useBuiltInDir); + hGrp->SetBool("UseMaterialsFromWorkbenches", _useWorkbenchDir); + hGrp->SetBool("UseMaterialsFromConfigDir", _useUserDir); + hGrp->SetBool("UseMaterialsFromCustomDir", _useCustomDir); + + _materialManager->refresh(); + } + + Materials::ModelManager* _modelManager; + Materials::MaterialManager* _materialManager; + std::shared_ptr _library; + QString _testMaterialUUID; + + std::string _customDir; + bool _useBuiltInDir; + bool _useWorkbenchDir; + bool _useUserDir; + bool _useCustomDir; + + const char* UUIDAcrylicLegacy = ""; // This can't be known until it is loaded + const char* UUIDAluminumAppearance = "3c6d0407-66b3-48ea-a2e8-ee843edf0311"; + const char* UUIDAluminumMixed = "5f546608-fcbb-40db-98d7-d8e104eb33ce"; + const char* UUIDAluminumPhysical = "a8e60089-550d-4370-8e7e-1734db12a3a9"; + const char* UUIDBrassAppearance = "fff3d5c8-98c3-4ee2-8fe5-7e17403c48fcc"; +}; + +TEST_F(TestMaterialFilter, TestFilters) +{ + ASSERT_NE(_modelManager, nullptr); + + // First check that our materials are loading + auto material = _materialManager->getMaterial(QString::fromLatin1(UUIDAluminumAppearance)); + ASSERT_TRUE(material); + ASSERT_EQ(material->getName(), QString::fromLatin1("TestAluminumAppearance")); + ASSERT_EQ(material->getUUID(), QString::fromLatin1(UUIDAluminumAppearance)); + + material = _materialManager->getMaterial(QString::fromLatin1(UUIDAluminumMixed)); + ASSERT_TRUE(material); + ASSERT_EQ(material->getName(), QString::fromLatin1("TestAluminumMixed")); + ASSERT_EQ(material->getUUID(), QString::fromLatin1(UUIDAluminumMixed)); + + material = _materialManager->getMaterial(QString::fromLatin1(UUIDAluminumPhysical)); + ASSERT_TRUE(material); + ASSERT_EQ(material->getName(), QString::fromLatin1("TestAluminumPhysical")); + ASSERT_EQ(material->getUUID(), QString::fromLatin1(UUIDAluminumPhysical)); + + material = _materialManager->getMaterial(QString::fromLatin1(UUIDBrassAppearance)); + ASSERT_TRUE(material); + ASSERT_EQ(material->getName(), QString::fromLatin1("TestBrassAppearance")); + ASSERT_EQ(material->getUUID(), QString::fromLatin1(UUIDBrassAppearance)); + + material = _materialManager->getMaterialByPath(QString::fromLatin1("TestAcrylicLegacy.FCMat"), + QString::fromLatin1("Custom")); + ASSERT_TRUE(material); + ASSERT_EQ(material->getName(), QString::fromLatin1("TestAcrylicLegacy")); + ASSERT_EQ(material->getUUID().size(), 36); // We don't know the UUID + + // Create an empty filter + auto filter = std::make_shared(); + Materials::MaterialFilterOptions options; + ASSERT_TRUE(_library); + + auto tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 4); + + options.setIncludeLegacy(true); + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 5); + + // Create a basic rendering filter + filter->setName(QLatin1String("Basic Appearance")); + filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Rendering_Basic); + options.setIncludeLegacy(false); + + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 3); + + options.setIncludeLegacy(true); + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 3); + + // Create an advanced rendering filter + filter->clear(); + filter->setName(QLatin1String("Advanced Appearance")); + filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Rendering_Advanced); + options.setIncludeLegacy(false); + + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 0); + + options.setIncludeLegacy(true); + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 0); + + // Create a Density filter + filter->clear(); + filter->setName(QLatin1String("Density")); + filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Mechanical_Density); + options.setIncludeLegacy(false); + + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 2); + + options.setIncludeLegacy(true); + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 3); + + // Create a Hardness filter + filter->clear(); + filter->setName(QLatin1String("Hardness")); + filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Mechanical_Hardness); + options.setIncludeLegacy(false); + + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 0); + + options.setIncludeLegacy(true); + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 0); + + // Create a Density and Basic Rendering filter + filter->clear(); + filter->setName(QLatin1String("Density and Basic Rendering")); + filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Rendering_Basic); + filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Mechanical_Density); + options.setIncludeLegacy(false); + + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 1); + + options.setIncludeLegacy(true); + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 1); + + // Create a Linear Elastic filter + filter->clear(); + filter->setName(QLatin1String("Linear Elastic")); + filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Mechanical_LinearElastic); + options.setIncludeLegacy(false); + + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 0); + + options.setIncludeLegacy(true); + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 0); + + filter->clear(); + filter->setName(QLatin1String("Linear Elastic")); + filter->addRequired(Materials::ModelUUIDs::ModelUUID_Mechanical_LinearElastic); + options.setIncludeLegacy(false); + + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 2); + + options.setIncludeLegacy(true); + tree = _materialManager->getMaterialTree(_library, filter, options); + ASSERT_EQ(tree->size(), 2); +} diff --git a/tests/src/Mod/Material/App/TestMaterialFilter.py b/tests/src/Mod/Material/App/TestMaterialFilter.py new file mode 100644 index 0000000000..7b5fa85675 --- /dev/null +++ b/tests/src/Mod/Material/App/TestMaterialFilter.py @@ -0,0 +1,104 @@ +# ************************************************************************** +# Copyright (c) 2023 David Carter * +# * +# This file is part of the FreeCAD CAx development system. * +# * +# This program is free software; you can redistribute it and/or modify * +# it under the terms of the GNU Lesser General Public License (LGPL) * +# as published by the Free Software Foundation; either version 2 of * +# the License, or (at your option) any later version. * +# for detail see the LICENCE text file. * +# * +# 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 Library General Public License for more details. * +# * +# You should have received a copy of the GNU Library General Public * +# License along with FreeCAD; if not, write to the Free Software * +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# USA * +# ************************************************************************** + +""" +Test module for FreeCAD material cards and APIs +""" +import os + +import unittest +import FreeCAD +import Materials + +parseQuantity = FreeCAD.Units.parseQuantity + +UUIDAcrylicLegacy = "" # This can't be known until it is loaded +UUIDAluminumAppearance = "3c6d0407-66b3-48ea-a2e8-ee843edf0311" +UUIDAluminumMixed = "5f546608-fcbb-40db-98d7-d8e104eb33ce" +UUIDAluminumPhysical = "a8e60089-550d-4370-8e7e-1734db12a3a9" +UUIDBrassAppearance = "fff3d5c8-98c3-4ee2-8fe5-7e17403c48fcc" + + +class MaterialFilterTestCases(unittest.TestCase): + """ + Test class for FreeCAD material cards and APIs + """ + + def setUp(self): + """Setup function to initialize test data""" + self.ModelManager = Materials.ModelManager() + self.MaterialManager = Materials.MaterialManager() + self.uuids = Materials.UUIDs() + + # Use our test files as a custom directory + param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material/Resources") + self.customDir = param.GetString("CustomMaterialsDir", "") + self.useBuiltInDir = param.GetBool("UseBuiltInMaterials", False) + self.useWorkbenchDir = param.GetBool("UseMaterialsFromWorkbenches", False) + self.useUserDir = param.GetBool("UseMaterialsFromConfigDir", False) + self.useCustomDir = param.GetBool("UseMaterialsFromCustomDir", False) + + filePath = os.path.dirname(__file__) + os.sep + testPath = filePath + "Materials" + param.SetString("CustomMaterialsDir", testPath) + param.SetBool("UseBuiltInMaterials", False) + param.SetBool("UseMaterialsFromWorkbenches", False) + param.SetBool("UseMaterialsFromConfigDir", False) + param.SetBool("UseMaterialsFromCustomDir", True) + + self.MaterialManager.refresh() + + def tearDown(self): + param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material/Resources") + + # Restore preferences + param.SetString("CustomMaterialsDir", self.customDir) + param.SetBool("UseBuiltInMaterials", self.useBuiltInDir) + param.SetBool("UseMaterialsFromWorkbenches", self.useWorkbenchDir) + param.SetBool("UseMaterialsFromConfigDir", self.useUserDir) + param.SetBool("UseMaterialsFromCustomDir", self.useCustomDir) + + self.MaterialManager.refresh() + + def testFilter(self): + """Test that our filter returns the correct materials""" + + # First check that our materials are loading + material = self.MaterialManager.getMaterial(UUIDAluminumAppearance) + self.assertIsNotNone(material) + self.assertEqual(material.Name, "TestAluminumAppearance") + self.assertEqual(material.UUID, UUIDAluminumAppearance) + + material = self.MaterialManager.getMaterial(UUIDAluminumMixed) + self.assertIsNotNone(material) + self.assertEqual(material.Name, "TestAluminumMixed") + self.assertEqual(material.UUID, UUIDAluminumMixed) + + material = self.MaterialManager.getMaterial(UUIDAluminumPhysical) + self.assertIsNotNone(material) + self.assertEqual(material.Name, "TestAluminumPhysical") + self.assertEqual(material.UUID, UUIDAluminumPhysical) + + material = self.MaterialManager.getMaterial(UUIDBrassAppearance) + self.assertIsNotNone(material) + self.assertEqual(material.Name, "TestBrassAppearance") + self.assertEqual(material.UUID, UUIDBrassAppearance)