From b71684955d095bac9eb92ee4c93de9da51a21d5e Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 3 Sep 2021 14:11:15 +1000 Subject: [PATCH] Simplify packaging, add create project smoke test. New license target. --- .github/workflows/ci.yml | 7 +- .gitignore | 8 + src/blenderbim/Makefile | 42 +++ src/blenderbim/blenderbim/__init__.py | 36 +-- src/blenderbim/blenderbim/bim/__init__.py | 276 +++++++++--------- .../blenderbim/bim/module/__init__.py | 19 ++ .../blenderbim/bim/module/project/operator.py | 1 - .../blenderbim/libs/site/packages/.gitignore | 0 .../blenderbim/libs/site/packages/hppfcl.pth | 3 - .../libs/site/packages/ifcopenshell.pth | 3 - .../libs/site/packages/svgwrite.pth | 3 - src/blenderbim/test/__init__.py | 19 ++ src/blenderbim/test/bim/__init__.py | 19 ++ src/blenderbim/test/bim/bootstrap.py | 28 ++ src/blenderbim/test/bim/module/__init__.py | 19 ++ .../test/bim/module/drawing/__init__.py | 19 ++ .../module/drawing}/test_segment_clipping.py | 15 +- .../test/bim/module/project/__init__.py | 19 ++ .../test/bim/module/project/test_operator.py | 29 ++ src/ifcopenshell-python/Makefile | 2 +- src/ifcopenshell-python/ifcopenshell/ids.py | 2 +- src/ifcopenshell-python/test/__init__.py | 0 src/ifcopenshell-python/test/test_file.py | 6 +- src/ifcopenshell-python/test/util/__init__.py | 0 .../test/util/test_element.py | 30 +- 25 files changed, 400 insertions(+), 205 deletions(-) create mode 100644 src/blenderbim/blenderbim/bim/module/__init__.py create mode 100644 src/blenderbim/blenderbim/libs/site/packages/.gitignore delete mode 100644 src/blenderbim/blenderbim/libs/site/packages/hppfcl.pth delete mode 100644 src/blenderbim/blenderbim/libs/site/packages/ifcopenshell.pth delete mode 100644 src/blenderbim/blenderbim/libs/site/packages/svgwrite.pth create mode 100644 src/blenderbim/test/__init__.py create mode 100644 src/blenderbim/test/bim/__init__.py create mode 100644 src/blenderbim/test/bim/bootstrap.py create mode 100644 src/blenderbim/test/bim/module/__init__.py create mode 100644 src/blenderbim/test/bim/module/drawing/__init__.py rename src/blenderbim/test/{ => bim/module/drawing}/test_segment_clipping.py (88%) create mode 100644 src/blenderbim/test/bim/module/project/__init__.py create mode 100644 src/blenderbim/test/bim/module/project/test_operator.py create mode 100644 src/ifcopenshell-python/test/__init__.py create mode 100644 src/ifcopenshell-python/test/util/__init__.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d67b13540..44741f7639 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/checkout@v2 with: submodules: recursive - - name: Install dependencies + - name: Install C++ dependencies run: | sudo apt update sudo apt-get install --no-install-recommends \ @@ -68,16 +68,17 @@ jobs: sudo make -j $(nproc) sudo make install - - name: install dependencies + - name: Install Python dependencies run: | sudo /usr/bin/python -m pip install -U pip sudo /usr/bin/python -m pip install xmlschema numpy lxml sudo /usr/bin/python -m pip install src/bcf + sudo /usr/bin/python -m pip install pytest - name: Test run: | cd test sudo /usr/bin/python tests.py cd ../src/ifcopenshell-python - sudo /usr/bin/python -m pip install pytest + mv ifcopenshell ifcopenshell-local # Force testing on installed module make test diff --git a/.gitignore b/.gitignore index a2c6c45d16..82204797f3 100644 --- a/.gitignore +++ b/.gitignore @@ -32,8 +32,10 @@ Pipfile.lock # gettext binary translation files *.mo + # Vim *.swp +*.swo # Flask instance/* @@ -53,3 +55,9 @@ Pipfile.lock # Database *.db +# PyTest +htmlcov +.coverage + +# Blender +*.blend1 diff --git a/src/blenderbim/Makefile b/src/blenderbim/Makefile index 12453aea8d..71ddad9744 100644 --- a/src/blenderbim/Makefile +++ b/src/blenderbim/Makefile @@ -1,3 +1,21 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2020, 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + VERSION:=`date '+%y%m%d'` PYVERSION:=py37 @@ -413,6 +431,30 @@ endif cd dist && zip -r blenderbim-$(VERSION)-$(PYVERSION)-$(PLATFORM).zip ./* rm -rf dist/blenderbim +.PHONY: test +test: + make test-core + make test-bim + +.PHONY: test-core +test-core: + pytest -p no:pytest-blender test/core + +.PHONY: test-bim +test-bim: + pytest test/bim + +.PHONY: coverage +coverage: + coverage run --source blenderbim.core -m pytest -p no:pytest-blender test/core + coverage html + xdg-open htmlcov/index.html + +.PHONY: license +license: + copyright-header --license GPL3 --copyright-holder "Dion Moult " --copyright-year "2021" --copyright-software "BlenderBIM Add-on" --copyright-software-description "OpenBIM Blender Add-on" -a ./ -o ./ + .PHONY: clean clean: rm -rf dist + rm -rf htmlcov diff --git a/src/blenderbim/blenderbim/__init__.py b/src/blenderbim/blenderbim/__init__.py index 1fd0f93247..1e80592560 100644 --- a/src/blenderbim/blenderbim/__init__.py +++ b/src/blenderbim/blenderbim/__init__.py @@ -17,10 +17,14 @@ # You should have received a copy of the GNU General Public License # along with BlenderBIM Add-on. If not, see . +import os +import sys +import site + bl_info = { "name": "BlenderBIM", - "description": "Author, import, and export files in the " "Industry Foundation Classes (.ifc) file format", - "author": "Dion Moult, IfcOpenShell", + "description": "Author, import, and export data using the Industry Foundation Classes schema", + "author": "IfcOpenShell Contributors", "blender": (2, 80, 0), "version": (0, 0, 999999), "location": "File > Export, File > Import, Scene / Object / Material / Mesh Properties", @@ -28,25 +32,15 @@ bl_info = { "category": "Import-Export", } -import os -import site +if sys.modules.get("bpy", None): + # Process *.pth in /libs/site/packages to setup globally importable modules + # This is 3 levels deep as required by the static RPATH of ../../ from dependencies taken from Anaconda + site.addsitedir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "libs", "site", "packages")) + import blenderbim.bim -# process *.pth in /libs/site/packages to setup globally importable modules -# 3 levels deep required by occ static ../../ path -# TODO: 3 levels deep is no longer required as we no longer bundle OCC -cwd = os.path.dirname(os.path.realpath(__file__)) -site.addsitedir(os.path.join(cwd, "libs", "site", "packages")) + def register(): + blenderbim.bim.register() - -# main import -from .bim import * - - -# Explicitely expose bim.xx when imported with from blenderbim import * -# Other bim still are importable using explicit from blenderbim.bim import xxx -__all__ = ["export_ifc", "import_ifc"] - - -if __name__ == "__main__": - register() + def unregister(): + blenderbim.bim.unregister() diff --git a/src/blenderbim/blenderbim/bim/__init__.py b/src/blenderbim/blenderbim/bim/__init__.py index 5df49888d9..60da57ebf0 100644 --- a/src/blenderbim/blenderbim/bim/__init__.py +++ b/src/blenderbim/blenderbim/bim/__init__.py @@ -17,157 +17,147 @@ # You should have received a copy of the GNU General Public License # along with BlenderBIM Add-on. If not, see . -# Check if we are running in Blender before loading, to allow for multiprocessing -import sys +import bpy +import importlib +from . import handler, ui, prop, operator -bpy = sys.modules.get("bpy") +modules = { + "project": None, + "search": None, + "bcf": None, + "root": None, + "unit": None, + "model": None, + "georeference": None, + "context": None, + "drawing": None, + "attribute": None, + "type": None, + "spatial": None, + "void": None, + "aggregate": None, + "geometry": None, + "cobie": None, + "resource": None, + "cost": None, + "sequence": None, + "group": None, + "system": None, + "structural": None, + "boundary": None, + "profile": None, + "material": None, + "style": None, + "layer": None, + "owner": None, + "pset": None, + "qto": None, + "classification": None, + "constraint": None, + "document": None, + "pset_template": None, + "clash": None, + "lca": None, + "csv": None, + "bimtester": None, + "diff": None, + "patch": None, + "covetool": None, + "augin": None, + "debug": None, +} -if bpy is not None: - import bpy - import importlib - from . import handler, ui, prop, operator +for name in modules.keys(): + modules[name] = importlib.import_module(f"blenderbim.bim.module.{name}") - modules = { - "project": None, - "search": None, - "bcf": None, - "root": None, - "unit": None, - "model": None, - "georeference": None, - "context": None, - "drawing": None, - "attribute": None, - "type": None, - "spatial": None, - "void": None, - "aggregate": None, - "geometry": None, - "cobie": None, - "resource": None, - "cost": None, - "sequence": None, - "group": None, - "system": None, - "structural": None, - "boundary": None, - "profile": None, - "material": None, - "style": None, - "layer": None, - "owner": None, - "pset": None, - "qto": None, - "classification": None, - "constraint": None, - "document": None, - "pset_template": None, - "clash": None, - "lca": None, - "csv": None, - "bimtester": None, - "diff": None, - "patch": None, - "covetool": None, - "augin": None, - "debug": None, - } +classes = [ + operator.OpenUri, + operator.SelectDataDir, + operator.SelectSchemaDir, + operator.SelectIfcFile, + operator.ExportIFC, + operator.ImportIFC, + operator.OpenUpstream, + operator.AddSectionPlane, + operator.RemoveSectionPlane, + operator.ReloadIfcFile, + operator.AddIfcFile, + operator.RemoveIfcFile, + operator.SetOverrideColour, + operator.SetViewportShadowFromSun, + operator.LinkIfc, + operator.SnapSpacesTogether, + prop.StrProperty, + prop.Attribute, + prop.BIMProperties, + prop.IfcParameter, + prop.PsetQto, + prop.GlobalId, + prop.BIMObjectProperties, + prop.BIMMaterialProperties, + prop.BIMMeshProperties, + ui.BIM_PT_section_plane, + ui.BIM_UL_generic, + ui.BIM_UL_topics, + ui.BIM_ADDON_preferences, +] - for name in modules.keys(): - modules[name] = importlib.import_module(f"blenderbim.bim.module.{name}") +for mod in modules.values(): + classes.extend(mod.classes) - classes = [ - operator.OpenUri, - operator.SelectDataDir, - operator.SelectSchemaDir, - operator.SelectIfcFile, - operator.ExportIFC, - operator.ImportIFC, - operator.OpenUpstream, - operator.AddSectionPlane, - operator.RemoveSectionPlane, - operator.ReloadIfcFile, - operator.AddIfcFile, - operator.RemoveIfcFile, - operator.SetOverrideColour, - operator.SetViewportShadowFromSun, - operator.LinkIfc, - operator.SnapSpacesTogether, - prop.StrProperty, - prop.Attribute, - prop.BIMProperties, - prop.IfcParameter, - prop.PsetQto, - prop.GlobalId, - prop.BIMObjectProperties, - prop.BIMMaterialProperties, - prop.BIMMeshProperties, - ui.BIM_PT_section_plane, - ui.BIM_UL_generic, - ui.BIM_UL_topics, - ui.BIM_ADDON_preferences, - ] +def menu_func_export(self, context): + self.layout.operator(operator.ExportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcjson)") - for module in modules.values(): - classes.extend(module.classes) +def menu_func_import(self, context): + self.layout.operator(operator.ImportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcxml)") - def menu_func_export(self, context): - self.layout.operator(operator.ExportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcjson)") +def on_register(scene): + handler.setDefaultProperties(scene) + bpy.app.handlers.depsgraph_update_post.remove(on_register) - def menu_func_import(self, context): - self.layout.operator(operator.ImportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcxml)") +def register(): + for cls in classes: + bpy.utils.register_class(cls) + bpy.app.handlers.depsgraph_update_post.append(on_register) + bpy.app.handlers.undo_pre.append(handler.undo_pre) + bpy.app.handlers.undo_post.append(handler.undo_post) + bpy.app.handlers.redo_pre.append(handler.redo_pre) + bpy.app.handlers.redo_post.append(handler.redo_post) + bpy.app.handlers.load_post.append(handler.setDefaultProperties) + bpy.app.handlers.load_post.append(handler.loadIfcStore) + bpy.app.handlers.save_pre.append(handler.ensureIfcExported) + bpy.types.TOPBAR_MT_file_export.append(menu_func_export) + bpy.types.TOPBAR_MT_file_import.append(menu_func_import) + bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties) + bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) + bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) + bpy.types.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties) + bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) + bpy.types.Curve.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) + bpy.types.Camera.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) + bpy.types.PointLight.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) + bpy.types.SCENE_PT_unit.append(ui.ifc_units) - def on_register(scene): - handler.setDefaultProperties(scene) - bpy.app.handlers.depsgraph_update_post.remove(on_register) + for mod in modules.values(): + mod.register() - def register(): - for cls in classes: - bpy.utils.register_class(cls) - bpy.app.handlers.depsgraph_update_post.append(on_register) - bpy.app.handlers.undo_pre.append(handler.undo_pre) - bpy.app.handlers.undo_post.append(handler.undo_post) - bpy.app.handlers.redo_pre.append(handler.redo_pre) - bpy.app.handlers.redo_post.append(handler.redo_post) - bpy.app.handlers.load_post.append(handler.setDefaultProperties) - bpy.app.handlers.load_post.append(handler.loadIfcStore) - bpy.app.handlers.save_pre.append(handler.ensureIfcExported) - bpy.types.TOPBAR_MT_file_export.append(menu_func_export) - bpy.types.TOPBAR_MT_file_import.append(menu_func_import) - bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties) - bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) - bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) - bpy.types.Collection.BIMObjectProperties = bpy.props.PointerProperty( - type=prop.BIMObjectProperties - ) # Check if we need this - bpy.types.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties) - bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) - bpy.types.Curve.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) - bpy.types.Camera.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) - bpy.types.PointLight.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) - bpy.types.SCENE_PT_unit.append(ui.ifc_units) +def unregister(): + for cls in reversed(classes): + bpy.utils.unregister_class(cls) + bpy.app.handlers.load_post.remove(handler.setDefaultProperties) + bpy.app.handlers.load_post.remove(handler.loadIfcStore) + bpy.app.handlers.save_pre.remove(handler.ensureIfcExported) + bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) + bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) + del bpy.types.Scene.BIMProperties + del bpy.types.Object.BIMObjectProperties + del bpy.types.Material.BIMObjectProperties + del bpy.types.Material.BIMMaterialProperties + del bpy.types.Mesh.BIMMeshProperties + del bpy.types.Curve.BIMMeshProperties + del bpy.types.Camera.BIMMeshProperties + del bpy.types.PointLight.BIMMeshProperties + bpy.types.SCENE_PT_unit.remove(ui.ifc_units) - for module in modules.values(): - module.register() - - def unregister(): - for cls in reversed(classes): - bpy.utils.unregister_class(cls) - bpy.app.handlers.load_post.remove(handler.setDefaultProperties) - bpy.app.handlers.load_post.remove(handler.loadIfcStore) - bpy.app.handlers.save_pre.remove(handler.ensureIfcExported) - bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) - bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) - del bpy.types.Scene.BIMProperties - del bpy.types.Object.BIMObjectProperties - del bpy.types.Material.BIMObjectProperties - del bpy.types.Collection.BIMObjectProperties # Check if we need this - del bpy.types.Material.BIMMaterialProperties - del bpy.types.Mesh.BIMMeshProperties - del bpy.types.Curve.BIMMeshProperties - del bpy.types.Camera.BIMMeshProperties - del bpy.types.PointLight.BIMMeshProperties - bpy.types.SCENE_PT_unit.remove(ui.ifc_units) - - for module in reversed(list(modules.values())): - module.unregister() + for mod in reversed(list(modules.values())): + mod.unregister() diff --git a/src/blenderbim/blenderbim/bim/module/__init__.py b/src/blenderbim/blenderbim/bim/module/__init__.py new file mode 100644 index 0000000000..3a32fe4bf7 --- /dev/null +++ b/src/blenderbim/blenderbim/bim/module/__init__.py @@ -0,0 +1,19 @@ + +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2020, 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + diff --git a/src/blenderbim/blenderbim/bim/module/project/operator.py b/src/blenderbim/blenderbim/bim/module/project/operator.py index d0618f16ae..28267662a5 100644 --- a/src/blenderbim/blenderbim/bim/module/project/operator.py +++ b/src/blenderbim/blenderbim/bim/module/project/operator.py @@ -21,7 +21,6 @@ import logging import ifcopenshell import ifcopenshell.api import ifcopenshell.util.representation -import bpy import blenderbim.bim.handler from blenderbim.bim.ifc import IfcStore from blenderbim.bim import import_ifc diff --git a/src/blenderbim/blenderbim/libs/site/packages/.gitignore b/src/blenderbim/blenderbim/libs/site/packages/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/blenderbim/blenderbim/libs/site/packages/hppfcl.pth b/src/blenderbim/blenderbim/libs/site/packages/hppfcl.pth deleted file mode 100644 index c0d165217a..0000000000 --- a/src/blenderbim/blenderbim/libs/site/packages/hppfcl.pth +++ /dev/null @@ -1,3 +0,0 @@ -# expose hppfcl as site-package - -hppfcl diff --git a/src/blenderbim/blenderbim/libs/site/packages/ifcopenshell.pth b/src/blenderbim/blenderbim/libs/site/packages/ifcopenshell.pth deleted file mode 100644 index 55ebfa3025..0000000000 --- a/src/blenderbim/blenderbim/libs/site/packages/ifcopenshell.pth +++ /dev/null @@ -1,3 +0,0 @@ -# expose ifcopenshell as site-package - -ifcopenshell diff --git a/src/blenderbim/blenderbim/libs/site/packages/svgwrite.pth b/src/blenderbim/blenderbim/libs/site/packages/svgwrite.pth deleted file mode 100644 index 7cd7e50c2b..0000000000 --- a/src/blenderbim/blenderbim/libs/site/packages/svgwrite.pth +++ /dev/null @@ -1,3 +0,0 @@ -# setup svgwrite - -svgwrite diff --git a/src/blenderbim/test/__init__.py b/src/blenderbim/test/__init__.py new file mode 100644 index 0000000000..6e0329dd57 --- /dev/null +++ b/src/blenderbim/test/__init__.py @@ -0,0 +1,19 @@ + +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + diff --git a/src/blenderbim/test/bim/__init__.py b/src/blenderbim/test/bim/__init__.py new file mode 100644 index 0000000000..6e0329dd57 --- /dev/null +++ b/src/blenderbim/test/bim/__init__.py @@ -0,0 +1,19 @@ + +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + diff --git a/src/blenderbim/test/bim/bootstrap.py b/src/blenderbim/test/bim/bootstrap.py new file mode 100644 index 0000000000..8f232ac681 --- /dev/null +++ b/src/blenderbim/test/bim/bootstrap.py @@ -0,0 +1,28 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + + +import bpy +import pytest +from blenderbim.bim.ifc import IfcStore + +class NewFile: + @pytest.fixture(autouse=True) + def setup(self): + IfcStore.purge() + bpy.ops.wm.read_homefile(app_template="") diff --git a/src/blenderbim/test/bim/module/__init__.py b/src/blenderbim/test/bim/module/__init__.py new file mode 100644 index 0000000000..6e0329dd57 --- /dev/null +++ b/src/blenderbim/test/bim/module/__init__.py @@ -0,0 +1,19 @@ + +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + diff --git a/src/blenderbim/test/bim/module/drawing/__init__.py b/src/blenderbim/test/bim/module/drawing/__init__.py new file mode 100644 index 0000000000..6e0329dd57 --- /dev/null +++ b/src/blenderbim/test/bim/module/drawing/__init__.py @@ -0,0 +1,19 @@ + +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + diff --git a/src/blenderbim/test/test_segment_clipping.py b/src/blenderbim/test/bim/module/drawing/test_segment_clipping.py similarity index 88% rename from src/blenderbim/test/test_segment_clipping.py rename to src/blenderbim/test/bim/module/drawing/test_segment_clipping.py index 6211104359..4048a6ad23 100644 --- a/src/blenderbim/test/test_segment_clipping.py +++ b/src/blenderbim/test/bim/module/drawing/test_segment_clipping.py @@ -1,4 +1,3 @@ - # BlenderBIM Add-on - OpenBIM Blender Add-on # Copyright (C) 2020, 2021 Maxim Vasilyev # @@ -19,11 +18,10 @@ import pytest from mathutils import Vector - -from blenderbim.bim.helper import clip_segment +from blenderbim.bim.module.drawing.helper import clip_segment -BOUNDS = (10, 30, 10, 30) +BOUNDS = (10, 30, 10, 30, None, None) SEGMENTS_INSIDE = ( (Vector((15, 20)), Vector((25, 20))), @@ -40,7 +38,7 @@ SEGMENTS_OUTSIDE = ( (Vector((25, 5)), Vector((15, 5))), (Vector((15, 5)), Vector((5, 15))), (Vector((5, 15)), Vector((5, 25))), - (Vector((5, 25)), Vector((15, 35))) + (Vector((5, 25)), Vector((15, 35))), ) SEGMENTS_CLIPPED = ( @@ -54,19 +52,20 @@ SEGMENTS_CLIPPED = ( ((Vector((35, 20)), Vector((20, 5))), (Vector((30, 15)), Vector((25, 10)))), ) -@pytest.mark.parametrize('segment', SEGMENTS_INSIDE) + +@pytest.mark.parametrize("segment", SEGMENTS_INSIDE) def test_clip_inside(segment): clipped = clip_segment(BOUNDS, segment) assert clipped == segment -@pytest.mark.parametrize('segment', SEGMENTS_OUTSIDE) +@pytest.mark.parametrize("segment", SEGMENTS_OUTSIDE) def test_clip_outside(segment): clipped = clip_segment(BOUNDS, segment) assert clipped is None -@pytest.mark.parametrize('segment,expected', SEGMENTS_CLIPPED) +@pytest.mark.parametrize("segment,expected", SEGMENTS_CLIPPED) def test_clip_crossing(segment, expected): clipped = clip_segment(BOUNDS, segment) assert clipped == expected diff --git a/src/blenderbim/test/bim/module/project/__init__.py b/src/blenderbim/test/bim/module/project/__init__.py new file mode 100644 index 0000000000..6e0329dd57 --- /dev/null +++ b/src/blenderbim/test/bim/module/project/__init__.py @@ -0,0 +1,19 @@ + +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + diff --git a/src/blenderbim/test/bim/module/project/test_operator.py b/src/blenderbim/test/bim/module/project/test_operator.py new file mode 100644 index 0000000000..a995246b90 --- /dev/null +++ b/src/blenderbim/test/bim/module/project/test_operator.py @@ -0,0 +1,29 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import bpy +import pytest +import test.bim.bootstrap +from blenderbim.bim.ifc import IfcStore + + +class TestCreateProject(test.bim.bootstrap.NewFile): + def test_creating_a_project(self): + assert IfcStore.get_file() is None + bpy.ops.bim.create_project() + assert IfcStore.get_file() diff --git a/src/ifcopenshell-python/Makefile b/src/ifcopenshell-python/Makefile index 914fdbae0e..30fc3fab6b 100644 --- a/src/ifcopenshell-python/Makefile +++ b/src/ifcopenshell-python/Makefile @@ -1,6 +1,6 @@ .PHONY: test test: - cd test && pytest + pytest -p no:pytest-blender test .PHONY: coverage coverage: diff --git a/src/ifcopenshell-python/ifcopenshell/ids.py b/src/ifcopenshell-python/ifcopenshell/ids.py index b3ac926a79..adb2bf3ee6 100644 --- a/src/ifcopenshell-python/ifcopenshell/ids.py +++ b/src/ifcopenshell-python/ifcopenshell/ids.py @@ -1092,7 +1092,7 @@ class BcfHandler(logging.StreamHandler): bcf_handler = BcfHandler( project_name="Default IDS Project", author="your@email.com", - filepath=r".\example.bcfzip", + filepath="example.bcf", ) logger = logging.getLogger("IDS_Logger") logging.basicConfig(level=logging.INFO, format="%(message)s") diff --git a/src/ifcopenshell-python/test/__init__.py b/src/ifcopenshell-python/test/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/ifcopenshell-python/test/test_file.py b/src/ifcopenshell-python/test/test_file.py index 4fc40084ed..f40bb4eda7 100644 --- a/src/ifcopenshell-python/test/test_file.py +++ b/src/ifcopenshell-python/test/test_file.py @@ -1,11 +1,11 @@ import pytest -import bootstrap +import test.bootstrap import ifcopenshell import ifcopenshell.api import ifcopenshell.util.element -class TestTransaction(bootstrap.IFC4): +class TestTransaction(test.bootstrap.IFC4): def test_that_nothing_happens_without_a_transaction(self): wall = self.file.createIfcWall() self.file.undo() @@ -134,7 +134,7 @@ class TestTransaction(bootstrap.IFC4): assert len(list(self.file)) == 2 -class TestFile(bootstrap.IFC4): +class TestFile(test.bootstrap.IFC4): def test_creating_a_new_file(self): f = ifcopenshell.file(schema="IFC4") assert f.schema == "IFC4" diff --git a/src/ifcopenshell-python/test/util/__init__.py b/src/ifcopenshell-python/test/util/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/ifcopenshell-python/test/util/test_element.py b/src/ifcopenshell-python/test/util/test_element.py index 4444548911..320f0a2287 100644 --- a/src/ifcopenshell-python/test/util/test_element.py +++ b/src/ifcopenshell-python/test/util/test_element.py @@ -1,10 +1,10 @@ import pytest -import bootstrap +import test.bootstrap import ifcopenshell.api import ifcopenshell.util.element -class TestGetPsetsIFC4(bootstrap.IFC4): +class TestGetPsetsIFC4(test.bootstrap.IFC4): def test_getting_the_psets_of_a_product_as_a_dictionary(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") assert ifcopenshell.util.element.get_psets(element) == {} @@ -23,7 +23,7 @@ class TestGetPsetsIFC4(bootstrap.IFC4): assert ifcopenshell.util.element.get_psets(self.file.create_entity("IfcPerson")) == {} -class TestGetPropertyDefinitionIFC4(bootstrap.IFC4): +class TestGetPropertyDefinitionIFC4(test.bootstrap.IFC4): def test_getting_the_properties_of_a_pset(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name") @@ -42,7 +42,7 @@ class TestGetPropertyDefinitionIFC4(bootstrap.IFC4): assert ifcopenshell.util.element.get_property_definition(pset) == {"LiningDepth": 42} -class TestGetQuantitiesIFC4(bootstrap.IFC4): +class TestGetQuantitiesIFC4(test.bootstrap.IFC4): def test_getting_quantities_from_a_qto(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") qto = ifcopenshell.api.run("pset.add_qto", self.file, product=element, name="name") @@ -50,7 +50,7 @@ class TestGetQuantitiesIFC4(bootstrap.IFC4): assert ifcopenshell.util.element.get_quantities(qto.Quantities) == {"x": 42} -class TestGetPropertiesIFC4(bootstrap.IFC4): +class TestGetPropertiesIFC4(test.bootstrap.IFC4): def test_getting_single_properties_from_a_list_of_properties(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name") @@ -73,7 +73,7 @@ class TestGetPropertiesIFC4(bootstrap.IFC4): } -class TestGetTypeIFC4(bootstrap.IFC4): +class TestGetTypeIFC4(test.bootstrap.IFC4): def test_getting_the_type_of_a_product(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") @@ -82,7 +82,7 @@ class TestGetTypeIFC4(bootstrap.IFC4): assert ifcopenshell.util.element.get_type(element_type) == element_type -class TestGetTypeIFC2X3(bootstrap.IFC2X3): +class TestGetTypeIFC2X3(test.bootstrap.IFC2X3): def test_getting_the_type_of_a_product(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") @@ -91,7 +91,7 @@ class TestGetTypeIFC2X3(bootstrap.IFC2X3): assert ifcopenshell.util.element.get_type(element_type) == element_type -class TestGetMaterial(bootstrap.IFC4): +class TestGetMaterial(test.bootstrap.IFC4): def test_getting_the_material_of_a_product(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") material = ifcopenshell.api.run("material.add_material", self.file) @@ -158,7 +158,7 @@ class TestGetMaterial(bootstrap.IFC4): assert ifcopenshell.util.element.get_material(element) == material -class TestGetContainerIFC4(bootstrap.IFC4): +class TestGetContainerIFC4(test.bootstrap.IFC4): def test_getting_the_spatial_container_of_an_element(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") building = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding") @@ -166,7 +166,7 @@ class TestGetContainerIFC4(bootstrap.IFC4): assert ifcopenshell.util.element.get_container(element) == building -class TestGetAggregateIFC4(bootstrap.IFC4): +class TestGetAggregateIFC4(test.bootstrap.IFC4): def test_getting_the_containing_aggregate_of_a_subelement(self): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcCovering") @@ -174,7 +174,7 @@ class TestGetAggregateIFC4(bootstrap.IFC4): assert ifcopenshell.util.element.get_aggregate(subelement) == element -class TestReplaceAttributeIFC4(bootstrap.IFC4): +class TestReplaceAttributeIFC4(test.bootstrap.IFC4): def test_replacing_an_elements_attribute(self): element = self.file.createIfcWall("foo") ifcopenshell.util.element.replace_attribute(element, "foo", "bar") @@ -189,7 +189,7 @@ class TestReplaceAttributeIFC4(bootstrap.IFC4): assert rel.RelatedObjects == (new,) -class TestHasElementReferenceIFC4(bootstrap.IFC4): +class TestHasElementReferenceIFC4(test.bootstrap.IFC4): def test_if_a_element_attribute_references_another_element(self): old = self.file.createIfcWall() new = self.file.createIfcWall() @@ -199,7 +199,7 @@ class TestHasElementReferenceIFC4(bootstrap.IFC4): assert ifcopenshell.util.element.has_element_reference(rel.RelatedObjects, new) is False -class TestRemoveDeepIFC4(bootstrap.IFC4): +class TestRemoveDeepIFC4(test.bootstrap.IFC4): def test_removing_an_element_along_with_all_direct_attributes_recursively(self): owner = self.file.createIfcOwnerHistory() element = self.file.createIfcWall(GlobalId="id", OwnerHistory=owner) @@ -219,7 +219,7 @@ class TestRemoveDeepIFC4(bootstrap.IFC4): assert self.file.by_guid("id2") -class TestCopyIFC4(bootstrap.IFC4): +class TestCopyIFC4(test.bootstrap.IFC4): def test_copying_an_element(self): element = self.file.createIfcWall(GlobalId="id", Name="name") element2 = ifcopenshell.util.element.copy(self.file, element) @@ -228,7 +228,7 @@ class TestCopyIFC4(bootstrap.IFC4): assert element.Name == element2.Name -class TestCopyDeepIFC4(bootstrap.IFC4): +class TestCopyDeepIFC4(test.bootstrap.IFC4): def test_copying_an_element_recursively(self): owner = self.file.createIfcOwnerHistory() owner.State = "READWRITE"