diff --git a/src/blenderbim/blenderbim/bim/module/sequence/prop.py b/src/blenderbim/blenderbim/bim/module/sequence/prop.py
index a0d1e7f188..b305a0ba0c 100644
--- a/src/blenderbim/blenderbim/bim/module/sequence/prop.py
+++ b/src/blenderbim/blenderbim/bim/module/sequence/prop.py
@@ -287,7 +287,6 @@ class BIMWorkPlanProperties(PropertyGroup):
active_work_plan_index: IntProperty(name="Active Work Plan Index")
active_work_plan_id: IntProperty(name="Active Work Plan Id")
work_schedules: EnumProperty(items=getWorkSchedules, name="Work Schedules")
- show_work_plan_hints: BoolProperty(name="Show Hints", default=False)
class BIMWorkScheduleProperties(PropertyGroup):
diff --git a/src/blenderbim/blenderbim/bim/module/sequence/ui.py b/src/blenderbim/blenderbim/bim/module/sequence/ui.py
index 5f5957d5fe..df58c85ea7 100644
--- a/src/blenderbim/blenderbim/bim/module/sequence/ui.py
+++ b/src/blenderbim/blenderbim/bim/module/sequence/ui.py
@@ -101,7 +101,7 @@ class BIM_PT_work_plans(Panel):
op.work_schedule = int(self.props.work_schedules)
else:
row = self.layout.row()
- row.label(text="Must Create a WorkSchedule First. See Work Schedule Panel", icon="INFO")
+ row.label(text="No schedules found. See Work Schedule Panel", icon="INFO")
class BIM_PT_work_schedules(Panel):
diff --git a/src/blenderbim/blenderbim/core/sequence.py b/src/blenderbim/blenderbim/core/sequence.py
index 68e7329a6a..4bc5babc38 100644
--- a/src/blenderbim/blenderbim/core/sequence.py
+++ b/src/blenderbim/blenderbim/core/sequence.py
@@ -42,7 +42,7 @@ def edit_work_plan(ifc, sequence, work_plan=None):
def edit_work_schedule(ifc, sequence, work_schedule=None):
attributes = sequence.get_work_schedule_attributes()
- ifc.run("sequence.edit_work_schedule", **{"work_schedule": work_schedule, "attributes": attributes})
+ ifc.run("sequence.edit_work_schedule", work_schedule=work_schedule, attributes=attributes)
sequence.disable_editing_work_schedule()
@@ -55,19 +55,16 @@ def add_work_schedule(ifc):
def remove_work_schedule(ifc, work_schedule=None):
- ifc.run("sequence.remove_work_schedule", **{"work_schedule": work_schedule})
+ ifc.run("sequence.remove_work_schedule", work_schedule=work_schedule)
def assign_work_schedule(ifc, sequence, work_plan=None, work_schedule=None):
if work_schedule:
- sequence.hide_work_plan_hints()
- return ifc.run("aggregate.assign_object", **{"relating_object": work_plan, "product": work_schedule})
- else:
- sequence.show_work_plan_hints()
+ return ifc.run("aggregate.assign_object", relating_object=work_plan, product=work_schedule)
def unassign_work_schedule(ifc, work_plan=None, work_schedule=None):
- ifc.run("aggregate.unassign_object", **{"relating_object": work_plan, "product": work_schedule})
+ ifc.run("aggregate.unassign_object", relating_object=work_plan, product=work_schedule)
def enable_editing_work_schedule(sequence, work_schedule=None):
@@ -101,11 +98,10 @@ def contract_task(sequence, task=None):
def remove_task(ifc, sequence, task=None):
- ifc.run("sequence.remove_task", **{"task": task})
+ ifc.run("sequence.remove_task", task=task)
work_schedule = sequence.get_active_work_schedule()
sequence.create_task_tree(work_schedule)
sequence.load_task_properties()
-
sequence.disable_selecting_deleted_task()
@@ -118,13 +114,13 @@ def disable_editing_work_schedule(sequence):
def add_summary_task(ifc, sequence, work_schedule=None):
- ifc.run("sequence.add_task", **{"work_schedule": work_schedule})
+ ifc.run("sequence.add_task", work_schedule=work_schedule)
sequence.create_task_tree(work_schedule)
sequence.load_task_properties()
def add_task(ifc, sequence, parent_task=None):
- ifc.run("sequence.add_task", **{"parent_task": parent_task})
+ ifc.run("sequence.add_task", parent_task=parent_task)
work_schedule = sequence.get_active_work_schedule()
sequence.create_task_tree(work_schedule)
sequence.load_task_properties()
@@ -137,7 +133,7 @@ def enable_editing_task(sequence, task=None):
def edit_task(ifc, sequence, task=None):
attributes = sequence.get_task_attributes()
- ifc.run("sequence.edit_task", **{"task": task, "attributes": attributes})
+ ifc.run("sequence.edit_task", task=task, attributes=attributes)
sequence.load_task_properties(task=task)
sequence.disable_editing_task()
@@ -146,7 +142,8 @@ def copy_task_attribute(ifc, sequence, attribute_name=None):
for task in sequence.get_checked_tasks():
ifc.run(
"sequence.edit_task",
- **{"task": task, "attributes": {attribute_name: sequence.get_task_attribute_value(attribute_name)}}
+ task=task,
+ attributes={attribute_name: sequence.get_task_attribute_value(attribute_name)},
)
sequence.load_task_properties(task)
@@ -158,15 +155,15 @@ def disable_editing_task(sequence):
def enable_editing_task_time(ifc, sequence, task=None):
task_time = sequence.get_task_time(task)
if task_time is None:
- task_time = ifc.run("sequence.add_task_time", **{"task": task})
+ task_time = ifc.run("sequence.add_task_time", task=task)
sequence.load_task_time_attributes(task_time)
sequence.enable_editing_task_time(task)
def edit_task_time(ifc, sequence, task_time=None):
attributes = sequence.get_task_time_attributes()
- print(task_time)
- ifc.run("sequence.edit_task_time", **{"task_time": task_time, "attributes": attributes}) # nasty loop goes on when calendar props are messed up
+ # TODO: nasty loop goes on when calendar props are messed up
+ ifc.run("sequence.edit_task_time", task_time=task_time, attributes=attributes)
task = sequence.get_active_task()
sequence.load_task_properties(task=task)
sequence.disable_editing_task_time()
@@ -174,25 +171,25 @@ def edit_task_time(ifc, sequence, task_time=None):
def assign_predecessor(ifc, sequence, task=None):
predecessor_task = sequence.get_active_task()
- ifc.run("sequence.assign_sequence", **{"relating_process": task, "related_process": predecessor_task})
+ ifc.run("sequence.assign_sequence", relating_process=task, related_process=predecessor_task)
sequence.load_task_properties()
def unassign_predecessor(ifc, sequence, task=None):
predecessor_task = sequence.get_active_task()
- ifc.run("sequence.unassign_sequence", **{"relating_process": task, "related_process": predecessor_task})
+ ifc.run("sequence.unassign_sequence", relating_process=task, related_process=predecessor_task)
sequence.load_task_properties()
def assign_successor(ifc, sequence, task=None):
successor_task = sequence.get_active_task()
- ifc.run("sequence.assign_sequence", **{"relating_process": successor_task, "related_process": task})
+ ifc.run("sequence.assign_sequence", relating_process=successor_task, related_process=task)
sequence.load_task_properties()
def unassign_successor(ifc, sequence, task=None):
successor_task = sequence.get_active_task()
- ifc.run("sequence.unassign_sequence", **{"relating_process": successor_task, "related_process": task})
+ ifc.run("sequence.unassign_sequence", relating_process=successor_task, related_process=task)
sequence.load_task_properties()
@@ -200,7 +197,7 @@ def assign_products(ifc, sequence, task=None, products=None):
if not products:
products = sequence.get_selected_products()
for product in products:
- ifc.run("sequence.assign_product", **{"relating_product": product, "related_object": task})
+ ifc.run("sequence.assign_product", relating_product=product, related_object=task)
outputs = sequence.get_task_outputs(task)
sequence.load_task_outputs(outputs)
@@ -209,7 +206,7 @@ def unassign_products(ifc, sequence, task=None, products=None):
if not products:
products = sequence.get_selected_products()
for product in products:
- ifc.run("sequence.unassign_product", **{"relating_product": product, "related_object": task})
+ ifc.run("sequence.unassign_product", relating_product=product, related_object=task)
outputs = sequence.get_task_outputs(task)
sequence.load_task_outputs(outputs)
@@ -218,7 +215,7 @@ def assign_input_products(ifc, sequence, task=None, products=None):
if not products:
products = sequence.get_selected_products()
for product in products:
- ifc.run("sequence.assign_process", **{"relating_process": task, "related_object": product})
+ ifc.run("sequence.assign_process", relating_process=task, related_object=product)
inputs = sequence.get_task_inputs(task)
sequence.load_task_inputs(inputs)
@@ -227,7 +224,7 @@ def unassign_input_products(ifc, sequence, task=None, products=None):
if not products:
products = sequence.get_selected_products()
for product in products:
- ifc.run("sequence.unassign_process", **{"relating_process": task, "related_object": product})
+ ifc.run("sequence.unassign_process", relating_process=task, related_object=product)
inputs = sequence.get_task_inputs(task)
sequence.load_task_inputs(inputs)
@@ -235,17 +232,17 @@ def unassign_input_products(ifc, sequence, task=None, products=None):
def assign_resource(ifc, sequence, task=None):
resource = sequence.get_selected_resource()
sub_resource = ifc.run(
- "resource.add_resource", **{"parent_resource": resource, "ifc_class": resource.is_a(), "name": resource.Name}
+ "resource.add_resource", parent_resource=resource, ifc_class=resource.is_a(), name=resource.Name
)
- ifc.run("sequence.assign_process", **{"relating_process": task, "related_object": sub_resource})
+ ifc.run("sequence.assign_process", relating_process=task, related_object=sub_resource)
resources = sequence.get_task_resources(task)
sequence.load_task_resources(resources)
sequence.load_resources()
def unassign_resource(ifc, sequence, task=None, resource=None):
- ifc.run("sequence.unassign_process", **{"relating_process": task, "related_object": resource})
- ifc.run("resource.remove_resource", **{"resource": resource})
+ ifc.run("sequence.unassign_process", relating_process=task, related_object=resource)
+ ifc.run("resource.remove_resource", resource=resource)
resources = sequence.get_task_resources(task)
sequence.load_task_resources(resources)
sequence.load_resources()
@@ -270,7 +267,7 @@ def load_task_resources(sequence):
def remove_work_calendar(ifc, work_calendar=None):
- ifc.run("sequence.remove_work_calendar", **{"work_calendar": work_calendar})
+ ifc.run("sequence.remove_work_calendar", work_calendar=work_calendar)
def add_work_calendar(ifc):
@@ -279,7 +276,7 @@ def add_work_calendar(ifc):
def edit_work_calendar(ifc, sequence, work_calendar=None):
attributes = sequence.get_work_calendar_attributes()
- ifc.run("sequence.edit_work_calendar", **{"work_calendar": work_calendar, "attributes": attributes})
+ ifc.run("sequence.edit_work_calendar", work_calendar=work_calendar, attributes=attributes)
sequence.disable_editing_work_calendar()
sequence.load_task_properties()
@@ -298,7 +295,7 @@ def enable_editing_work_calendar_times(sequence, work_calendar=None):
def add_work_time(ifc, work_calendar=None, time_type=None):
- return ifc.run("sequence.add_work_time", **{"work_calendar": work_calendar, "time_type": time_type})
+ return ifc.run("sequence.add_work_time", work_calendar=work_calendar, time_type=time_type)
def enable_editing_work_time(sequence, work_time=None):
@@ -311,43 +308,38 @@ def disable_editing_work_time(sequence):
def remove_work_time(ifc, work_time=None):
- ifc.run("sequence.remove_work_time", **{"work_time": work_time})
+ ifc.run("sequence.remove_work_time", work_time=work_time)
def edit_work_time(ifc, sequence):
work_time = sequence.get_active_work_time()
- ifc.run("sequence.edit_work_time", **{"work_time": work_time, "attributes": sequence.get_work_time_attributes()})
+ ifc.run("sequence.edit_work_time", work_time=work_time, attributes=sequence.get_work_time_attributes())
recurrence_pattern = work_time.RecurrencePattern
if recurrence_pattern:
ifc.run(
"sequence.edit_recurrence_pattern",
- **{
- "recurrence_pattern": recurrence_pattern,
- "attributes": sequence.get_recurrence_pattern_attributes(recurrence_pattern),
- }
+ recurrence_pattern=recurrence_pattern,
+ attributes=sequence.get_recurrence_pattern_attributes(recurrence_pattern),
)
sequence.disable_editing_work_time()
def assign_recurrence_pattern(ifc, work_time=None, recurrence_type=None):
- return ifc.run("sequence.assign_recurrence_pattern", **{"parent": work_time, "recurrence_type": recurrence_type})
+ return ifc.run("sequence.assign_recurrence_pattern", parent=work_time, recurrence_type=recurrence_type)
def unassign_recurrence_pattern(ifc, recurrence_pattern=None):
- ifc.run("sequence.unassign_recurrence_pattern", **{"recurrence_pattern": recurrence_pattern})
+ ifc.run("sequence.unassign_recurrence_pattern", recurrence_pattern=recurrence_pattern)
def add_time_period(ifc, sequence, recurrence_pattern=None):
start_time, end_time = sequence.get_recurrence_pattern_times()
- ifc.run(
- "sequence.add_time_period",
- **{"recurrence_pattern": recurrence_pattern, "start_time": start_time, "end_time": end_time}
- )
+ ifc.run("sequence.add_time_period", recurrence_pattern=recurrence_pattern, start_time=start_time, end_time=end_time)
sequence.reset_time_period()
def remove_time_period(ifc, time_period=None):
- ifc.run("sequence.remove_time_period", **{"time_period": time_period})
+ ifc.run("sequence.remove_time_period", time_period=time_period)
def enable_editing_task_calendar(sequence, task=None):
@@ -355,14 +347,14 @@ def enable_editing_task_calendar(sequence, task=None):
def edit_task_calendar(ifc, sequence, task=None, work_calendar=None):
- ifc.run("control.assign_control", **{"relating_control": work_calendar, "related_object": task})
- ifc.run("sequence.cascade_schedule", **{"task": task})
+ ifc.run("control.assign_control", relating_control=work_calendar, related_object=task)
+ ifc.run("sequence.cascade_schedule", task=task)
sequence.load_task_properties()
def remove_task_calendar(ifc, sequence, task=None, work_calendar=None):
- ifc.run("control.unassign_control", **{"relating_control": work_calendar, "related_object": task})
- ifc.run("sequence.cascade_schedule", **{"task": task})
+ ifc.run("control.unassign_control", relating_control=work_calendar, related_object=task)
+ ifc.run("sequence.cascade_schedule", task=task)
sequence.load_task_properties()
@@ -391,24 +383,24 @@ def enable_editing_sequence_lag_time(sequence, rel_sequence=None, lag_time=None)
def unassign_lag_time(ifc, sequence, rel_sequence=None):
- ifc.run("sequence.unassign_lag_time", **{"rel_sequence": rel_sequence})
+ ifc.run("sequence.unassign_lag_time", rel_sequence=rel_sequence)
sequence.load_task_properties()
def assign_lag_time(ifc, rel_sequence=None):
- ifc.run("sequence.assign_lag_time", **{"rel_sequence": rel_sequence, "lag_value": "P1D"})
+ ifc.run("sequence.assign_lag_time", rel_sequence=rel_sequence, lag_value="P1D")
def edit_sequence_attributes(ifc, sequence, rel_sequence=None):
attributes = sequence.get_rel_sequence_attributes()
- ifc.run("sequence.edit_sequence", **{"rel_sequence": rel_sequence, "attributes": attributes})
+ ifc.run("sequence.edit_sequence", rel_sequence=rel_sequence, attributes=attributes)
sequence.disable_editing_rel_sequence()
sequence.load_task_properties()
def edit_sequence_lag_time(ifc, sequence, lag_time=None):
attributes = sequence.get_lag_time_attributes()
- ifc.run("sequence.edit_lag_time", **{"lag_time": lag_time, "attributes": attributes})
+ ifc.run("sequence.edit_lag_time", lag_time=lag_time, attributes=attributes)
sequence.disable_editing_rel_sequence()
sequence.load_task_properties()
@@ -418,18 +410,17 @@ def disable_editing_rel_sequence(sequence):
def select_task_outputs(ifc, sequence, task=None):
- outputs = sequence.get_task_outputs(task) ## should this be from the api instead ?
+ outputs = sequence.get_task_outputs(task)
sequence.select_task_products(outputs)
def select_task_inputs(ifc, sequence, task=None):
- inputs = sequence.get_task_inputs(task) ## should this be from the api instead ?
- print(inputs)
+ inputs = sequence.get_task_inputs(task)
sequence.select_task_products(inputs)
def recalculate_schedule(ifc, work_schedule=None):
- ifc.run("sequence.recalculate_schedule", **{"work_schedule": work_schedule})
+ ifc.run("sequence.recalculate_schedule", work_schedule=work_schedule)
def add_task_column(sequence, column_type=None, name=None, data_type=None):
@@ -445,7 +436,7 @@ def set_task_sort_column(sequence, column=None):
def calculate_task_duration(ifc, sequence, task=None):
- ifc.run("sequence.calculate_task_duration", **{"task": task})
+ ifc.run("sequence.calculate_task_duration", task=task)
work_schedule = sequence.get_active_work_schedule()
if work_schedule:
sequence.create_task_tree(work_schedule)
diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py
index f086674d5b..67de3896db 100644
--- a/src/blenderbim/blenderbim/core/tool.py
+++ b/src/blenderbim/blenderbim/core/tool.py
@@ -436,8 +436,6 @@ class Sequence:
def enable_editing_work_schedule_tasks(cls, work_schedule): pass
def create_task_tree(cls, work_schedule): pass
def load_task_properties(cls, task): pass
- def hide_work_plan_hints(cls): pass
- def show_work_plan_hints(cls): pass
def get_active_work_schedule_id(cls): pass
def get_selected_resource(cls): pass
def expand_task(cls, task): pass
diff --git a/src/blenderbim/blenderbim/tool/sequence.py b/src/blenderbim/blenderbim/tool/sequence.py
index 2c27335196..aaf8508f29 100644
--- a/src/blenderbim/blenderbim/tool/sequence.py
+++ b/src/blenderbim/blenderbim/tool/sequence.py
@@ -247,14 +247,6 @@ class Sequence(blenderbim.core.tool.Sequence):
bpy.context.scene.BIMWorkScheduleProperties.is_task_update_enabled = True
- @classmethod
- def hide_work_plan_hints(cls):
- bpy.context.scene.BIMWorkPlanProperties.show_hints = False
-
- @classmethod
- def show_work_plan_hints(cls):
- bpy.context.scene.BIMWorkPlanProperties.show_hints = True
-
@classmethod
def get_active_work_schedule(cls):
if not bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id:
diff --git a/src/blenderbim/test/bim/feature/bimtester.feature b/src/blenderbim/test/bim/feature/bimtester.feature
index 911fe93969..dd4629ad7e 100644
--- a/src/blenderbim/test/bim/feature/bimtester.feature
+++ b/src/blenderbim/test/bim/feature/bimtester.feature
@@ -4,8 +4,6 @@ Feature: Bimtester
Scenario: Execute Bimtester
Given an empty IFC project
When I set "scene.BimTesterProperties.should_load_from_memory" to "True"
- And I set "scene.BimTesterProperties.feature" to "{cwd}/test/files/sample-ids.xml"
+ And I set "scene.BimTesterProperties.feature" to "{cwd}/test/files/sample.feature"
And I press "bim.execute_bim_tester"
Then nothing happens
- # IDS is continuously changing right now. Stable release scheduled for March 2022.
- #Then the file "{cwd}/test/files/sample-ids.xml.html" should contain "Tests passed: 1 / 1 (100%)"
diff --git a/src/blenderbim/test/core/bootstrap.py b/src/blenderbim/test/core/bootstrap.py
index 686d23ab65..2f71c5bd37 100644
--- a/src/blenderbim/test/core/bootstrap.py
+++ b/src/blenderbim/test/core/bootstrap.py
@@ -175,6 +175,13 @@ def selector():
prophet.verify()
+@pytest.fixture
+def sequence():
+ prophet = Prophecy(blenderbim.core.tool.Sequence)
+ yield prophet
+ prophet.verify()
+
+
@pytest.fixture
def spatial():
prophet = Prophecy(blenderbim.core.tool.Spatial)
diff --git a/src/blenderbim/test/core/test_sequence.py b/src/blenderbim/test/core/test_sequence.py
new file mode 100644
index 0000000000..cac866e266
--- /dev/null
+++ b/src/blenderbim/test/core/test_sequence.py
@@ -0,0 +1,56 @@
+# BlenderBIM Add-on - OpenBIM Blender Add-on
+# Copyright (C) 2022 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 blenderbim.core.sequence as subject
+from test.core.bootstrap import ifc, sequence
+
+
+class TestAddWorkPlan:
+ def test_run(self, ifc):
+ ifc.run("sequence.add_work_plan").should_be_called().will_return("work_plan")
+ assert subject.add_work_plan(ifc) == "work_plan"
+
+
+class TestRemoveWorkPlan:
+ def test_run(self, ifc):
+ ifc.run("sequence.remove_work_plan", work_plan="work_plan").should_be_called()
+ subject.remove_work_plan(ifc, work_plan="work_plan")
+
+
+class TestEnableEditingWorkPlan:
+ def test_run(self, sequence):
+ sequence.load_work_plan_attributes("work_plan").should_be_called()
+ sequence.enable_editing_work_plan("work_plan").should_be_called()
+ subject.enable_editing_work_plan(sequence, work_plan="work_plan")
+
+
+class TestDisableEditingWorkPlan:
+ def test_run(self, sequence):
+ sequence.disable_editing_work_plan().should_be_called()
+ subject.disable_editing_work_plan(sequence)
+
+
+class TestEditWorkPlan:
+ def test_run(self, ifc, sequence):
+ sequence.get_work_plan_attributes().should_be_called().will_return("attributes")
+ ifc.run("sequence.edit_work_plan", work_plan="work_plan", attributes="attributes").should_be_called()
+ sequence.disable_editing_work_plan().should_be_called()
+ subject.edit_work_plan(ifc, sequence, work_plan="work_plan")
+
+# TODO continue writing tests
diff --git a/src/blenderbim/test/files/sample.feature b/src/blenderbim/test/files/sample.feature
new file mode 100644
index 0000000000..a3b4428ecd
--- /dev/null
+++ b/src/blenderbim/test/files/sample.feature
@@ -0,0 +1,8 @@
+Feature: Project setup
+
+In order to view the BIM data
+As any interested stakeholder
+We need an IFC file
+
+Scenario: Receiving a file
+ * IFC data must use the "IFC4" schema