buildzr 0.0.11__tar.gz → 0.0.13__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. {buildzr-0.0.11 → buildzr-0.0.13}/PKG-INFO +1 -1
  2. buildzr-0.0.13/buildzr/__about__.py +1 -0
  3. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/dsl/dsl.py +93 -156
  4. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/dsl/explorer.py +7 -2
  5. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/dsl/expression.py +47 -21
  6. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/dsl/interfaces/__init__.py +0 -1
  7. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/dsl/interfaces/interfaces.py +0 -27
  8. {buildzr-0.0.11 → buildzr-0.0.13}/tests/samples/component_view.py +1 -1
  9. {buildzr-0.0.11 → buildzr-0.0.13}/tests/samples/container_view.py +1 -1
  10. buildzr-0.0.13/tests/samples/groups.py +44 -0
  11. {buildzr-0.0.11 → buildzr-0.0.13}/tests/samples/implied_relationships.py +2 -2
  12. {buildzr-0.0.11 → buildzr-0.0.13}/tests/samples/nested_groups.py +0 -2
  13. {buildzr-0.0.11 → buildzr-0.0.13}/tests/samples/system_context_view.py +1 -1
  14. {buildzr-0.0.11 → buildzr-0.0.13}/tests/samples/system_landscape_view.py +1 -1
  15. {buildzr-0.0.11 → buildzr-0.0.13}/tests/test_views.py +86 -23
  16. buildzr-0.0.11/buildzr/__about__.py +0 -1
  17. buildzr-0.0.11/tests/samples/groups.py +0 -44
  18. {buildzr-0.0.11 → buildzr-0.0.13}/.gitignore +0 -0
  19. {buildzr-0.0.11 → buildzr-0.0.13}/CONTRIBUTING.md +0 -0
  20. {buildzr-0.0.11 → buildzr-0.0.13}/LICENSE.md +0 -0
  21. {buildzr-0.0.11 → buildzr-0.0.13}/README.md +0 -0
  22. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/__init__.py +0 -0
  23. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/dsl/__init__.py +0 -0
  24. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/dsl/color.py +0 -0
  25. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/dsl/factory/__init__.py +0 -0
  26. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/dsl/factory/gen_id.py +0 -0
  27. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/dsl/relations.py +0 -0
  28. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/encoders/__init__.py +0 -0
  29. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/encoders/encoder.py +0 -0
  30. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/models/__init__.py +0 -0
  31. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/models/generate.sh +0 -0
  32. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/models/models.py +0 -0
  33. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/sinks/__init__.py +0 -0
  34. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/sinks/interfaces.py +0 -0
  35. {buildzr-0.0.11 → buildzr-0.0.13}/buildzr/sinks/json_sink.py +0 -0
  36. {buildzr-0.0.11 → buildzr-0.0.13}/pyproject.toml +0 -0
  37. {buildzr-0.0.11 → buildzr-0.0.13}/tests/__init__.py +0 -0
  38. {buildzr-0.0.11 → buildzr-0.0.13}/tests/abstract_builder.py +0 -0
  39. {buildzr-0.0.11 → buildzr-0.0.13}/tests/samples/__init__.py +0 -0
  40. {buildzr-0.0.11 → buildzr-0.0.13}/tests/samples/container_view_sugar.py +0 -0
  41. {buildzr-0.0.11 → buildzr-0.0.13}/tests/samples/simple.py +0 -0
  42. {buildzr-0.0.11 → buildzr-0.0.13}/tests/samples/simple_dsl.py +0 -0
  43. {buildzr-0.0.11 → buildzr-0.0.13}/tests/test_dsl.py +0 -0
  44. {buildzr-0.0.11 → buildzr-0.0.13}/tests/test_explorer.py +0 -0
  45. {buildzr-0.0.11 → buildzr-0.0.13}/tests/test_expression.py +0 -0
  46. {buildzr-0.0.11 → buildzr-0.0.13}/tests/test_typehints.py +0 -0
  47. {buildzr-0.0.11 → buildzr-0.0.13}/tests/test_workspaces.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: buildzr
3
- Version: 0.0.11
3
+ Version: 0.0.13
4
4
  Summary: Structurizr for the `buildzr`s 🧱⚒️
5
5
  Project-URL: homepage, https://github.com/amirulmenjeni/buildzr
6
6
  Project-URL: issues, https://github.com/amirulmenjeni/buildzr/issues
@@ -0,0 +1 @@
1
+ VERSION = "0.0.13"
@@ -29,7 +29,6 @@ from buildzr.dsl.interfaces import (
29
29
  DslWorkspaceElement,
30
30
  DslElement,
31
31
  DslViewElement,
32
- DslViewsElement,
33
32
  )
34
33
  from buildzr.dsl.relations import (
35
34
  DslElementRelationOverrides,
@@ -181,13 +180,43 @@ class Workspace(DslWorkspaceElement):
181
180
  else:
182
181
  raise ValueError('Invalid element type: Trying to add an element of type {} to a workspace.'.format(type(model)))
183
182
 
184
- def apply_views( self, *views: Union[ 'SystemLandscapeView',
183
+ def apply_view(
184
+ self,
185
+ view: Union[
186
+ 'SystemLandscapeView',
185
187
  'SystemContextView',
186
188
  'ContainerView',
187
189
  'ComponentView',
188
190
  ]
189
191
  ) -> None:
190
- Views(self).add_views(*views)
192
+
193
+ view._on_added(self)
194
+
195
+ if not self.model.views:
196
+ self.model.views = buildzr.models.Views()
197
+
198
+ if isinstance(view, SystemLandscapeView):
199
+ if not self.model.views.systemLandscapeViews:
200
+ self.model.views.systemLandscapeViews = [view.model]
201
+ else:
202
+ self.model.views.systemLandscapeViews.append(view.model)
203
+ elif isinstance(view, SystemContextView):
204
+ if not self.model.views.systemContextViews:
205
+ self.model.views.systemContextViews = [view.model]
206
+ else:
207
+ self.model.views.systemContextViews.append(view.model)
208
+ elif isinstance(view, ContainerView):
209
+ if not self.model.views.containerViews:
210
+ self.model.views.containerViews = [view.model]
211
+ else:
212
+ self.model.views.containerViews.append(view.model)
213
+ elif isinstance(view, ComponentView):
214
+ if not self.model.views.componentViews:
215
+ self.model.views.componentViews = [view.model]
216
+ else:
217
+ self.model.views.componentViews.append(view.model)
218
+ else:
219
+ raise NotImplementedError("The view {0} is currently not supported", type(view))
191
220
 
192
221
  def apply_style( self,
193
222
  style: Union['StyleElements', 'StyleRelationships'],
@@ -273,7 +302,7 @@ class SoftwareSystem(DslElementRelationOverrides[
273
302
  return self._destinations
274
303
 
275
304
  @property
276
- def relationships(self) -> Set[_Relationship]:
305
+ def relationships(self) -> Set[DslRelationship]:
277
306
  return self._relationships
278
307
 
279
308
  @property
@@ -287,7 +316,7 @@ class SoftwareSystem(DslElementRelationOverrides[
287
316
  self._children: Optional[List['Container']] = []
288
317
  self._sources: List[DslElement] = []
289
318
  self._destinations: List[DslElement] = []
290
- self._relationships: Set[_Relationship] = set()
319
+ self._relationships: Set[DslRelationship] = set()
291
320
  self._tags = {'Element', 'Software System'}.union(tags)
292
321
  self._dynamic_attrs: Dict[str, 'Container'] = {}
293
322
  self._label: Optional[str] = None
@@ -387,7 +416,7 @@ class Person(DslElementRelationOverrides[
387
416
  return self._destinations
388
417
 
389
418
  @property
390
- def relationships(self) -> Set[_Relationship]:
419
+ def relationships(self) -> Set[DslRelationship]:
391
420
  return self._relationships
392
421
 
393
422
  @property
@@ -399,7 +428,7 @@ class Person(DslElementRelationOverrides[
399
428
  self._parent: Optional[Workspace] = None
400
429
  self._sources: List[DslElement] = []
401
430
  self._destinations: List[DslElement] = []
402
- self._relationships: Set[_Relationship] = set()
431
+ self._relationships: Set[DslRelationship] = set()
403
432
  self._tags = {'Element', 'Person'}.union(tags)
404
433
  self._label: Optional[str] = None
405
434
  self.model.id = GenerateId.for_element()
@@ -458,7 +487,7 @@ class Container(DslElementRelationOverrides[
458
487
  return self._destinations
459
488
 
460
489
  @property
461
- def relationships(self) -> Set[_Relationship]:
490
+ def relationships(self) -> Set[DslRelationship]:
462
491
  return self._relationships
463
492
 
464
493
  @property
@@ -472,7 +501,7 @@ class Container(DslElementRelationOverrides[
472
501
  self._children: Optional[List['Component']] = []
473
502
  self._sources: List[DslElement] = []
474
503
  self._destinations: List[DslElement] = []
475
- self._relationships: Set[_Relationship] = set()
504
+ self._relationships: Set[DslRelationship] = set()
476
505
  self._tags = {'Element', 'Container'}.union(tags)
477
506
  self._dynamic_attrs: Dict[str, 'Component'] = {}
478
507
  self._label: Optional[str] = None
@@ -570,7 +599,7 @@ class Component(DslElementRelationOverrides[
570
599
  return self._destinations
571
600
 
572
601
  @property
573
- def relationships(self) -> Set[_Relationship]:
602
+ def relationships(self) -> Set[DslRelationship]:
574
603
  return self._relationships
575
604
 
576
605
  @property
@@ -582,7 +611,7 @@ class Component(DslElementRelationOverrides[
582
611
  self._parent: Optional[Container] = None
583
612
  self._sources: List[DslElement] = []
584
613
  self._destinations: List[DslElement] = []
585
- self._relationships: Set[_Relationship] = set()
614
+ self._relationships: Set[DslRelationship] = set()
586
615
  self._tags = {'Element', 'Component'}.union(tags)
587
616
  self._label: Optional[str] = None
588
617
  self.model.id = GenerateId.for_element()
@@ -738,30 +767,25 @@ def _auto_layout_to_model(auto_layout: _AutoLayout) -> buildzr.models.AutomaticL
738
767
 
739
768
  class SystemLandscapeView(DslViewElement):
740
769
 
741
- from buildzr.dsl.expression import Expression, Element, Relationship
770
+ from buildzr.dsl.expression import Expression, WorkspaceExpression, ElementExpression, RelationshipExpression
742
771
 
743
772
  @property
744
773
  def model(self) -> buildzr.models.SystemLandscapeView:
745
774
  return self._m
746
775
 
747
- @property
748
- def parent(self) -> Optional['Views']:
749
- return self._parent
750
-
751
776
  def __init__(
752
777
  self,
753
778
  key: str,
754
779
  description: str,
755
780
  auto_layout: _AutoLayout='tb',
756
781
  title: Optional[str]=None,
757
- include_elements: List[Union[DslElement, Callable[[Workspace, Element], bool]]]=[],
758
- exclude_elements: List[Union[DslElement, Callable[[Workspace, Element], bool]]]=[],
759
- include_relationships: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]]=[],
760
- exclude_relationships: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]]=[],
782
+ include_elements: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]]=[],
783
+ exclude_elements: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]]=[],
784
+ include_relationships: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]]=[],
785
+ exclude_relationships: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]]=[],
761
786
  properties: Optional[Dict[str, str]]=None,
762
787
  ) -> None:
763
788
  self._m = buildzr.models.SystemLandscapeView()
764
- self._parent: Optional['Views'] = None
765
789
 
766
790
  self._m.key = key
767
791
  self._m.description = description
@@ -777,11 +801,11 @@ class SystemLandscapeView(DslViewElement):
777
801
 
778
802
  workspace = _current_workspace.get()
779
803
  if workspace is not None:
780
- workspace.apply_views(self)
804
+ workspace.apply_view(self)
781
805
 
782
- def _on_added(self) -> None:
806
+ def _on_added(self, workspace: Workspace) -> None:
783
807
 
784
- from buildzr.dsl.expression import Expression, Element, Relationship
808
+ from buildzr.dsl.expression import Expression, WorkspaceExpression, ElementExpression, RelationshipExpression
785
809
  from buildzr.models import ElementView, RelationshipView
786
810
 
787
811
  expression = Expression(
@@ -791,19 +815,17 @@ class SystemLandscapeView(DslViewElement):
791
815
  exclude_relationships=self._exclude_relationships,
792
816
  )
793
817
 
794
- workspace = self._parent._parent
795
-
796
- include_view_elements_filter: List[Union[DslElement, Callable[[Workspace, Element], bool]]] = [
818
+ include_view_elements_filter: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]] = [
797
819
  lambda w, e: e.type == Person,
798
820
  lambda w, e: e.type == SoftwareSystem
799
821
  ]
800
822
 
801
- exclude_view_elements_filter: List[Union[DslElement, Callable[[Workspace, Element], bool]]] = [
823
+ exclude_view_elements_filter: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]] = [
802
824
  lambda w, e: e.type == Container,
803
825
  lambda w, e: e.type == Component,
804
826
  ]
805
827
 
806
- include_view_relationships_filter: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]] = [
828
+ include_view_relationships_filter: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]] = [
807
829
  lambda w, r: r.source.type == Person,
808
830
  lambda w, r: r.source.type == SoftwareSystem,
809
831
  lambda w, r: r.destination.type == Person,
@@ -842,31 +864,26 @@ class SystemContextView(DslViewElement):
842
864
  relationship with the selected `SoftwareSystem`.
843
865
  """
844
866
 
845
- from buildzr.dsl.expression import Expression, Element, Relationship
867
+ from buildzr.dsl.expression import Expression, WorkspaceExpression, ElementExpression, RelationshipExpression
846
868
 
847
869
  @property
848
870
  def model(self) -> buildzr.models.SystemContextView:
849
871
  return self._m
850
872
 
851
- @property
852
- def parent(self) -> Optional['Views']:
853
- return self._parent
854
-
855
873
  def __init__(
856
874
  self,
857
- software_system_selector: Union[SoftwareSystem, Callable[[Workspace], SoftwareSystem]],
875
+ software_system_selector: Union[SoftwareSystem, Callable[[WorkspaceExpression], SoftwareSystem]],
858
876
  key: str,
859
877
  description: str,
860
878
  auto_layout: _AutoLayout='tb',
861
879
  title: Optional[str]=None,
862
- include_elements: List[Union[DslElement, Callable[[Workspace, Element], bool]]]=[],
863
- exclude_elements: List[Union[DslElement, Callable[[Workspace, Element], bool]]]=[],
864
- include_relationships: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]]=[],
865
- exclude_relationships: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]]=[],
880
+ include_elements: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]]=[],
881
+ exclude_elements: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]]=[],
882
+ include_relationships: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]]=[],
883
+ exclude_relationships: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]]=[],
866
884
  properties: Optional[Dict[str, str]]=None,
867
885
  ) -> None:
868
886
  self._m = buildzr.models.SystemContextView()
869
- self._parent: Optional['Views'] = None
870
887
 
871
888
  self._m.key = key
872
889
  self._m.description = description
@@ -883,25 +900,25 @@ class SystemContextView(DslViewElement):
883
900
 
884
901
  workspace = _current_workspace.get()
885
902
  if workspace is not None:
886
- workspace.apply_views(self)
903
+ workspace.apply_view(self)
887
904
 
888
- def _on_added(self) -> None:
905
+ def _on_added(self, workspace: Workspace) -> None:
889
906
 
890
- from buildzr.dsl.expression import Expression, Element, Relationship
907
+ from buildzr.dsl.expression import Expression, WorkspaceExpression, ElementExpression, RelationshipExpression
891
908
  from buildzr.models import ElementView, RelationshipView
892
909
 
893
910
  if isinstance(self._selector, SoftwareSystem):
894
911
  software_system = self._selector
895
912
  else:
896
- software_system = self._selector(self._parent._parent)
913
+ software_system = self._selector(WorkspaceExpression(workspace))
897
914
  self._m.softwareSystemId = software_system.model.id
898
- view_elements_filter: List[Union[DslElement, Callable[[Workspace, Element], bool]]] = [
915
+ view_elements_filter: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]] = [
899
916
  lambda w, e: e == software_system,
900
917
  lambda w, e: software_system.model.id in e.sources.ids,
901
918
  lambda w, e: software_system.model.id in e.destinations.ids,
902
919
  ]
903
920
 
904
- view_relationships_filter: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]] = [
921
+ view_relationships_filter: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]] = [
905
922
  lambda w, r: software_system == r.source,
906
923
  lambda w, r: software_system == r.destination,
907
924
  ]
@@ -913,8 +930,6 @@ class SystemContextView(DslViewElement):
913
930
  exclude_relationships=self._exclude_relationships,
914
931
  )
915
932
 
916
- workspace = self._parent._parent
917
-
918
933
  element_ids = map(
919
934
  lambda x: str(x.model.id),
920
935
  expression.elements(workspace)
@@ -935,31 +950,26 @@ class SystemContextView(DslViewElement):
935
950
 
936
951
  class ContainerView(DslViewElement):
937
952
 
938
- from buildzr.dsl.expression import Expression, Element, Relationship
953
+ from buildzr.dsl.expression import Expression, WorkspaceExpression, ElementExpression, RelationshipExpression
939
954
 
940
955
  @property
941
956
  def model(self) -> buildzr.models.ContainerView:
942
957
  return self._m
943
958
 
944
- @property
945
- def parent(self) -> Optional['Views']:
946
- return self._parent
947
-
948
959
  def __init__(
949
960
  self,
950
- software_system_selector: Union[SoftwareSystem, Callable[[Workspace], SoftwareSystem]],
961
+ software_system_selector: Union[SoftwareSystem, Callable[[WorkspaceExpression], SoftwareSystem]],
951
962
  key: str,
952
963
  description: str,
953
964
  auto_layout: _AutoLayout='tb',
954
965
  title: Optional[str]=None,
955
- include_elements: List[Union[DslElement, Callable[[Workspace, Element], bool]]]=[],
956
- exclude_elements: List[Union[DslElement, Callable[[Workspace, Element], bool]]]=[],
957
- include_relationships: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]]=[],
958
- exclude_relationships: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]]=[],
966
+ include_elements: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]]=[],
967
+ exclude_elements: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]]=[],
968
+ include_relationships: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]]=[],
969
+ exclude_relationships: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]]=[],
959
970
  properties: Optional[Dict[str, str]]=None,
960
971
  ) -> None:
961
972
  self._m = buildzr.models.ContainerView()
962
- self._parent: Optional['Views'] = None
963
973
 
964
974
  self._m.key = key
965
975
  self._m.description = description
@@ -976,28 +986,28 @@ class ContainerView(DslViewElement):
976
986
 
977
987
  workspace = _current_workspace.get()
978
988
  if workspace is not None:
979
- workspace.apply_views(self)
989
+ workspace.apply_view(self)
980
990
 
981
- def _on_added(self) -> None:
991
+ def _on_added(self, workspace: Workspace) -> None:
982
992
 
983
- from buildzr.dsl.expression import Expression, Element, Relationship
993
+ from buildzr.dsl.expression import Expression, WorkspaceExpression, ElementExpression, RelationshipExpression
984
994
  from buildzr.models import ElementView, RelationshipView
985
995
 
986
996
  if isinstance(self._selector, SoftwareSystem):
987
997
  software_system = self._selector
988
998
  else:
989
- software_system = self._selector(self._parent._parent)
999
+ software_system = self._selector(WorkspaceExpression(workspace))
990
1000
  self._m.softwareSystemId = software_system.model.id
991
1001
 
992
1002
  container_ids = { container.model.id for container in software_system.children}
993
1003
 
994
- view_elements_filter: List[Union[DslElement, Callable[[Workspace, Element], bool]]] = [
1004
+ view_elements_filter: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]] = [
995
1005
  lambda w, e: e.parent == software_system,
996
1006
  lambda w, e: any(container_ids.intersection({ id for id in e.sources.ids })),
997
1007
  lambda w, e: any(container_ids.intersection({ id for id in e.destinations.ids })),
998
1008
  ]
999
1009
 
1000
- view_relationships_filter: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]] = [
1010
+ view_relationships_filter: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]] = [
1001
1011
  lambda w, r: software_system == r.source.parent,
1002
1012
  lambda w, r: software_system == r.destination.parent,
1003
1013
  ]
@@ -1009,8 +1019,6 @@ class ContainerView(DslViewElement):
1009
1019
  exclude_relationships=self._exclude_relationships,
1010
1020
  )
1011
1021
 
1012
- workspace = self._parent._parent
1013
-
1014
1022
  element_ids = map(
1015
1023
  lambda x: str(x.model.id),
1016
1024
  expression.elements(workspace)
@@ -1031,31 +1039,26 @@ class ContainerView(DslViewElement):
1031
1039
 
1032
1040
  class ComponentView(DslViewElement):
1033
1041
 
1034
- from buildzr.dsl.expression import Expression, Element, Relationship
1042
+ from buildzr.dsl.expression import Expression, WorkspaceExpression, ElementExpression, RelationshipExpression
1035
1043
 
1036
1044
  @property
1037
1045
  def model(self) -> buildzr.models.ComponentView:
1038
1046
  return self._m
1039
1047
 
1040
- @property
1041
- def parent(self) -> Optional['Views']:
1042
- return self._parent
1043
-
1044
1048
  def __init__(
1045
1049
  self,
1046
- container_selector: Union[Container, Callable[[Workspace], Container]],
1050
+ container_selector: Union[Container, Callable[[WorkspaceExpression], Container]],
1047
1051
  key: str,
1048
1052
  description: str,
1049
1053
  auto_layout: _AutoLayout='tb',
1050
1054
  title: Optional[str]=None,
1051
- include_elements: List[Union[DslElement, Callable[[Workspace, Element], bool]]]=[],
1052
- exclude_elements: List[Union[DslElement, Callable[[Workspace, Element], bool]]]=[],
1053
- include_relationships: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]]=[],
1054
- exclude_relationships: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]]=[],
1055
+ include_elements: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]]=[],
1056
+ exclude_elements: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]]=[],
1057
+ include_relationships: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]]=[],
1058
+ exclude_relationships: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]]=[],
1055
1059
  properties: Optional[Dict[str, str]]=None,
1056
1060
  ) -> None:
1057
1061
  self._m = buildzr.models.ComponentView()
1058
- self._parent: Optional['Views'] = None
1059
1062
 
1060
1063
  self._m.key = key
1061
1064
  self._m.description = description
@@ -1072,28 +1075,28 @@ class ComponentView(DslViewElement):
1072
1075
 
1073
1076
  workspace = _current_workspace.get()
1074
1077
  if workspace is not None:
1075
- workspace.apply_views(self)
1078
+ workspace.apply_view(self)
1076
1079
 
1077
- def _on_added(self) -> None:
1080
+ def _on_added(self, workspace: Workspace) -> None:
1078
1081
 
1079
- from buildzr.dsl.expression import Expression, Element, Relationship
1082
+ from buildzr.dsl.expression import Expression, WorkspaceExpression, ElementExpression, RelationshipExpression
1080
1083
  from buildzr.models import ElementView, RelationshipView
1081
1084
 
1082
1085
  if isinstance(self._selector, Container):
1083
1086
  container = self._selector
1084
1087
  else:
1085
- container = self._selector(self._parent._parent)
1088
+ container = self._selector(WorkspaceExpression(workspace))
1086
1089
  self._m.containerId = container.model.id
1087
1090
 
1088
1091
  component_ids = { component.model.id for component in container.children }
1089
1092
 
1090
- view_elements_filter: List[Union[DslElement, Callable[[Workspace, Element], bool]]] = [
1093
+ view_elements_filter: List[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]] = [
1091
1094
  lambda w, e: e.parent == container,
1092
1095
  lambda w, e: any(component_ids.intersection({ id for id in e.sources.ids })),
1093
1096
  lambda w, e: any(component_ids.intersection({ id for id in e.destinations.ids })),
1094
1097
  ]
1095
1098
 
1096
- view_relationships_filter: List[Union[DslElement, Callable[[Workspace, Relationship], bool]]] = [
1099
+ view_relationships_filter: List[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]] = [
1097
1100
  lambda w, r: container == r.source.parent,
1098
1101
  lambda w, r: container == r.destination.parent,
1099
1102
  ]
@@ -1105,8 +1108,6 @@ class ComponentView(DslViewElement):
1105
1108
  exclude_relationships=self._exclude_relationships,
1106
1109
  )
1107
1110
 
1108
- workspace = self._parent._parent
1109
-
1110
1111
  element_ids = map(
1111
1112
  lambda x: str(x.model.id),
1112
1113
  expression.elements(workspace)
@@ -1125,73 +1126,9 @@ class ComponentView(DslViewElement):
1125
1126
  for relationship_id in relationship_ids:
1126
1127
  self._m.relationships.append(RelationshipView(id=relationship_id))
1127
1128
 
1128
- class Views(DslViewsElement):
1129
-
1130
- # TODO: Make this view a "hidden" class -- it's not a "first class citizen"
1131
- # in buildzr DSL.
1132
-
1133
- @property
1134
- def model(self) -> buildzr.models.Views:
1135
- return self._m
1136
-
1137
- @property
1138
- def parent(self) -> Optional[Workspace]:
1139
- return self._parent
1140
-
1141
- def __init__(
1142
- self,
1143
- workspace: Workspace,
1144
- ) -> None:
1145
- self._m = buildzr.models.Views()
1146
- self._parent = workspace
1147
- self._parent._m.views = self._m
1148
-
1149
- def add_views(
1150
- self,
1151
- *views: DslViewElement
1152
- ) -> None:
1153
-
1154
- for view in views:
1155
- if isinstance(view, SystemLandscapeView):
1156
- view._parent = self
1157
- view._on_added()
1158
- if self._m.systemLandscapeViews:
1159
- self._m.systemLandscapeViews.append(view.model)
1160
- else:
1161
- self._m.systemLandscapeViews = [view.model]
1162
- elif isinstance(view, SystemContextView):
1163
- view._parent = self
1164
- view._on_added()
1165
- if self._m.systemContextViews:
1166
- self._m.systemContextViews.append(view.model)
1167
- else:
1168
- self._m.systemContextViews = [view.model]
1169
- elif isinstance(view, ContainerView):
1170
- view._parent = self
1171
- view._on_added()
1172
- if self._m.containerViews:
1173
- self._m.containerViews.append(view.model)
1174
- else:
1175
- self._m.containerViews = [view.model]
1176
- elif isinstance(view, ComponentView):
1177
- view._parent = self
1178
- view._on_added()
1179
- if self._m.componentViews:
1180
- self._m.componentViews.append(view.model)
1181
- else:
1182
- self._m.componentViews = [view.model]
1183
- else:
1184
- raise NotImplementedError("The view {0} is currently not supported", type(view))
1185
-
1186
- def get_workspace(self) -> Workspace:
1187
- """
1188
- Get the `Workspace` which contain this views definition.
1189
- """
1190
- return self._parent
1191
-
1192
1129
  class StyleElements:
1193
1130
 
1194
- from buildzr.dsl.expression import Element
1131
+ from buildzr.dsl.expression import WorkspaceExpression, ElementExpression
1195
1132
 
1196
1133
  Shapes = Union[
1197
1134
  Literal['Box'],
@@ -1224,7 +1161,7 @@ class StyleElements:
1224
1161
  on: List[Union[
1225
1162
  DslElement,
1226
1163
  Group,
1227
- Callable[[Workspace, Element], bool],
1164
+ Callable[[WorkspaceExpression, ElementExpression], bool],
1228
1165
  Type[Union['Person', 'SoftwareSystem', 'Container', 'Component']],
1229
1166
  str
1230
1167
  ]],
@@ -1267,7 +1204,7 @@ class StyleElements:
1267
1204
  # item, not for each of `StyleElements` instance. This makes the styling
1268
1205
  # makes more concise and flexible.
1269
1206
 
1270
- from buildzr.dsl.expression import Element
1207
+ from buildzr.dsl.expression import ElementExpression
1271
1208
  from uuid import uuid4
1272
1209
 
1273
1210
  if background:
@@ -1340,7 +1277,7 @@ class StyleElements:
1340
1277
  elif isinstance(element, str):
1341
1278
  element_style.tag = element
1342
1279
  elif callable(element):
1343
- from buildzr.dsl.expression import Element, Expression
1280
+ from buildzr.dsl.expression import ElementExpression, Expression
1344
1281
  if self._parent:
1345
1282
  matched_elems = Expression(include_elements=[element]).elements(self._parent)
1346
1283
  for e in matched_elems:
@@ -1356,7 +1293,7 @@ class StyleElements:
1356
1293
 
1357
1294
  class StyleRelationships:
1358
1295
 
1359
- from buildzr.dsl.expression import Relationship
1296
+ from buildzr.dsl.expression import WorkspaceExpression, RelationshipExpression
1360
1297
 
1361
1298
  @property
1362
1299
  def model(self) -> List[buildzr.models.RelationshipStyle]:
@@ -1371,7 +1308,7 @@ class StyleRelationships:
1371
1308
  on: Optional[List[Union[
1372
1309
  DslRelationship,
1373
1310
  Group,
1374
- Callable[[Workspace, Relationship], bool],
1311
+ Callable[[WorkspaceExpression, RelationshipExpression], bool],
1375
1312
  str
1376
1313
  ]]]=None,
1377
1314
  thickness: Optional[int]=None,
@@ -14,12 +14,17 @@ from typing import (
14
14
  Union,
15
15
  Generator,
16
16
  Iterable,
17
+ cast,
17
18
  )
18
19
 
19
20
  from buildzr.dsl.dsl import (
20
21
  Workspace,
21
22
  )
22
23
 
24
+ from buildzr.dsl.interfaces import (
25
+ DslRelationship,
26
+ )
27
+
23
28
  class Explorer:
24
29
 
25
30
  def __init__(self, workspace_or_element: Union[Workspace, Person, SoftwareSystem, Container, Component]):
@@ -32,7 +37,7 @@ class Explorer:
32
37
  yield child
33
38
  yield from explorer
34
39
 
35
- def walk_relationships(self) -> Generator[_Relationship, None, None]:
40
+ def walk_relationships(self) -> Generator[DslRelationship, None, None]:
36
41
 
37
42
  if self._workspace_or_element.children:
38
43
 
@@ -40,7 +45,7 @@ class Explorer:
40
45
 
41
46
  if child.relationships:
42
47
  for relationship in child.relationships:
43
- yield relationship
48
+ yield cast(_Relationship, relationship) # TODO: Temporary fix. Use a better approach - Generics?
44
49
 
45
50
  explorer = Explorer(child).walk_relationships()
46
51
  yield from explorer
@@ -10,6 +10,7 @@ from buildzr.dsl.dsl import (
10
10
  SoftwareSystem,
11
11
  Container,
12
12
  Component,
13
+ TypedDynamicAttribute,
13
14
  )
14
15
 
15
16
  from buildzr.dsl.relations import _Relationship
@@ -47,12 +48,37 @@ class FlattenElement:
47
48
  all_tags = all_tags.union(tags)
48
49
  return all_tags
49
50
 
50
- class Element:
51
+ class WorkspaceExpression:
52
+
53
+ """
54
+ A class used to filter the allowable methods and properties of the
55
+ `Structurizr DSL` workspace. This is used to filter the elements and
56
+ relationships in the workspace.
57
+ """
58
+
59
+ def __init__(self, workspace: Workspace):
60
+ self._workspace = workspace
61
+ self._dynamic_attributes = self._workspace._dynamic_attrs
62
+
63
+ def software_system(self) -> TypedDynamicAttribute['SoftwareSystem']:
64
+ """
65
+ Returns the software system of the workspace. This is used to filter the
66
+ elements and relationships in the workspace.
67
+ """
68
+ return TypedDynamicAttribute['SoftwareSystem'](self._dynamic_attributes)
69
+
70
+ def person(self) -> TypedDynamicAttribute['Person']:
71
+ """
72
+ Returns the person of the workspace. This is used to filter the elements
73
+ and relationships in the workspace.
74
+ """
75
+ return TypedDynamicAttribute['Person'](self._dynamic_attributes)
76
+
77
+ class ElementExpression:
51
78
 
52
79
  def __init__(self, element: DslElement):
53
80
  self._element = element
54
81
 
55
- # TODO: Make a test for this in `tests/test_expression.py`
56
82
  @property
57
83
  def id(self) -> str:
58
84
  return cast(str, self._element.model.id)
@@ -102,9 +128,9 @@ class Element:
102
128
  return isinstance(element, type(self._element)) and\
103
129
  element.model.id == self._element.model.id
104
130
 
105
- class Relationship:
131
+ class RelationshipExpression:
106
132
 
107
- def __init__(self, relationship: _Relationship):
133
+ def __init__(self, relationship: DslRelationship):
108
134
  self._relationship = relationship
109
135
 
110
136
  # TODO: Make a test for this in `tests/test_expression.py`
@@ -121,12 +147,12 @@ class Relationship:
121
147
  return self._relationship.model.technology
122
148
 
123
149
  @property
124
- def source(self) -> Element:
125
- return Element(self._relationship.source)
150
+ def source(self) -> ElementExpression:
151
+ return ElementExpression(self._relationship.source)
126
152
 
127
153
  @property
128
- def destination(self) -> Element:
129
- return Element(self._relationship.destination)
154
+ def destination(self) -> ElementExpression:
155
+ return ElementExpression(self._relationship.destination)
130
156
 
131
157
  @property
132
158
  def properties(self) -> Dict[str, Any]:
@@ -146,10 +172,10 @@ class Expression:
146
172
 
147
173
  def __init__(
148
174
  self,
149
- include_elements: Iterable[Union[DslElement, Callable[[Workspace, Element], bool]]]=[lambda w, e: True],
150
- exclude_elements: Iterable[Union[DslElement, Callable[[Workspace, Element], bool]]]=[],
151
- include_relationships: Iterable[Union[DslElement, Callable[[Workspace, Relationship], bool]]]=[lambda w, e: True],
152
- exclude_relationships: Iterable[Union[DslElement, Callable[[Workspace, Relationship], bool]]]=[],
175
+ include_elements: Iterable[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]]=[lambda w, e: True],
176
+ exclude_elements: Iterable[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]]=[],
177
+ include_relationships: Iterable[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]]=[lambda w, e: True],
178
+ exclude_relationships: Iterable[Union[DslElement, Callable[[WorkspaceExpression, RelationshipExpression], bool]]]=[],
153
179
  ) -> 'None':
154
180
  self._include_elements = include_elements
155
181
  self._exclude_elements = exclude_elements
@@ -171,12 +197,12 @@ class Expression:
171
197
  if isinstance(f, DslElement):
172
198
  includes.append(f == element)
173
199
  else:
174
- includes.append(f(workspace, Element(element)))
200
+ includes.append(f(WorkspaceExpression(workspace), ElementExpression(element)))
175
201
  for f in self._exclude_elements:
176
202
  if isinstance(f, DslElement):
177
203
  excludes.append(f == element)
178
204
  else:
179
- excludes.append(f(workspace, Element(element)))
205
+ excludes.append(f(WorkspaceExpression(workspace), ElementExpression(element)))
180
206
  if any(includes) and not any(excludes):
181
207
  filtered_elements.append(element)
182
208
 
@@ -198,9 +224,9 @@ class Expression:
198
224
  filtered_relationships: List[DslRelationship] = []
199
225
 
200
226
  def _is_relationship_of_excluded_elements(
201
- workspace: Workspace,
202
- relationship: Relationship,
203
- exclude_element_predicates: Iterable[Union[DslElement, Callable[[Workspace, Element], bool]]],
227
+ workspace: WorkspaceExpression,
228
+ relationship: RelationshipExpression,
229
+ exclude_element_predicates: Iterable[Union[DslElement, Callable[[WorkspaceExpression, ElementExpression], bool]]],
204
230
  ) -> bool:
205
231
  for f in exclude_element_predicates:
206
232
  if isinstance(f, DslElement):
@@ -222,20 +248,20 @@ class Expression:
222
248
  if isinstance(f, DslElement):
223
249
  includes.append(f == relationship)
224
250
  else:
225
- includes.append(f(workspace, Relationship(relationship)))
251
+ includes.append(f(WorkspaceExpression(workspace), RelationshipExpression(relationship)))
226
252
 
227
253
  for f in self._exclude_relationships:
228
254
  if isinstance(f, DslElement):
229
255
  excludes.append(f == relationship)
230
256
  else:
231
- excludes.append(f(workspace, Relationship(relationship)))
257
+ excludes.append(f(WorkspaceExpression(workspace), RelationshipExpression(relationship)))
232
258
 
233
259
  # Also exclude relationships whose source or destination elements
234
260
  # are excluded.
235
261
  excludes.append(
236
262
  _is_relationship_of_excluded_elements(
237
- workspace,
238
- Relationship(relationship),
263
+ WorkspaceExpression(workspace),
264
+ RelationshipExpression(relationship),
239
265
  self._exclude_elements,
240
266
  )
241
267
  )
@@ -3,7 +3,6 @@ from .interfaces import (
3
3
  DslRelationship,
4
4
  DslWorkspaceElement,
5
5
  DslViewElement,
6
- DslViewsElement,
7
6
  BindLeft,
8
7
  BindRight,
9
8
  BindLeftLate,
@@ -205,31 +205,4 @@ class DslViewElement(ABC):
205
205
  @property
206
206
  @abstractmethod
207
207
  def model(self) -> ViewModel:
208
- pass
209
-
210
- @property
211
- @abstractmethod
212
- def parent(self) -> 'DslViewsElement':
213
- pass
214
-
215
- def _on_added(self) -> None:
216
- pass
217
-
218
- class DslViewsElement(ABC):
219
-
220
- @property
221
- @abstractmethod
222
- def model(self) -> buildzr.models.Views:
223
- pass
224
-
225
- @property
226
- @abstractmethod
227
- def parent(self) -> DslWorkspaceElement:
228
- pass
229
-
230
- @abstractmethod
231
- def add_views(
232
- self,
233
- *views: Union[DslViewElement],
234
- ) -> None:
235
208
  pass
@@ -20,7 +20,7 @@ class SampleComponentView(AbstractBuilder):
20
20
  db = Container("Database")
21
21
  web_app.component_2 >> "Reads from and writes to" >> db
22
22
  user >> "Uses" >> c1
23
- w.apply_views(
23
+ w.apply_view(
24
24
  ComponentView(
25
25
  container_selector=lambda w: w.software_system().software_system.web_application,
26
26
  key="web_application_container_00",
@@ -19,7 +19,7 @@ class SampleContainerView(AbstractBuilder):
19
19
  user >> "Uses" >> web_application
20
20
  user >> "Hacks" >> git_repo
21
21
  git_repo >> "Uses" >> external_system
22
- w.apply_views(
22
+ w.apply_view(
23
23
  ContainerView(
24
24
  software_system_selector=lambda w: w.software_system().app,
25
25
  key="ss_business_app",
@@ -0,0 +1,44 @@
1
+ import buildzr
2
+ from buildzr.dsl import *
3
+ from typing import cast
4
+ from ..abstract_builder import AbstractBuilder
5
+
6
+ class GroupsSample(AbstractBuilder):
7
+
8
+ def build(self) -> buildzr.models.Workspace:
9
+ with Workspace("w", scope=None) as w:
10
+ with Group("Company 1"):
11
+ with SoftwareSystem("A") as a:
12
+ Container("a1")
13
+ Container("a2")
14
+ with Group("Company 2"):
15
+ with SoftwareSystem("B") as b:
16
+ Container("b1")
17
+ with Container("b2") as b2:
18
+ Component("c1")
19
+ c = SoftwareSystem("C")
20
+ a >> "Uses" >> b
21
+ a.a1 >> "Uses" >> b.b1
22
+ a >> "Uses" >> c
23
+
24
+ SystemLandscapeView(
25
+ key='groups-sample',
26
+ description="Groups Sample"
27
+ )
28
+ SystemContextView(
29
+ key='groups-sample-a',
30
+ software_system_selector=lambda w: w.software_system().a,
31
+ description="Groups Sample - Software System A"
32
+ )
33
+ SystemContextView(
34
+ key='groups-sample-b',
35
+ software_system_selector=lambda w: w.software_system().b,
36
+ description="Groups Sample - Software System B"
37
+ )
38
+ ContainerView(
39
+ key='groups-sample-b2',
40
+ software_system_selector=lambda w: w.software_system().b,
41
+ description="Groups Sample - Container B2"
42
+ )
43
+
44
+ return w.model
@@ -21,10 +21,10 @@ class SampleImpliedRelationships(AbstractBuilder):
21
21
  database = Container("database")
22
22
  ui_layer >> "Uses" >> database
23
23
  u >> "Runs SQL queries" >> database
24
- w.apply_views(
24
+ w.apply_view(
25
25
  SystemContextView(
26
26
  key='sample-implied-relationships',
27
- software_system_selector=lambda w: cast(SoftwareSystem, w.s),
27
+ software_system_selector=lambda w: w.software_system().s,
28
28
  description="Sample Implied Relationships"
29
29
  )
30
30
  )
@@ -21,8 +21,6 @@ class NestedGroups(AbstractBuilder):
21
21
  c >> d
22
22
  b >> c
23
23
 
24
- # TODO: Ensure multiple views work.
25
-
26
24
  SystemLandscapeView(
27
25
  key='nested-groups',
28
26
  description="Nested Groups Sample"
@@ -19,7 +19,7 @@ class SystemContextViewSample(AbstractBuilder):
19
19
  email_system = SoftwareSystem('email_system')
20
20
  user >> "uses" >> web_app
21
21
  web_app >> "sends notification using" >> email_system
22
- w.apply_views(
22
+ w.apply_view(
23
23
  SystemContextView(
24
24
  lambda w: w.software_system().web_app,
25
25
  key='web_app_system_context_00',
@@ -32,7 +32,7 @@ class SystemLandscapeViewSample(AbstractBuilder):
32
32
  internet_banking_system >> "Gets account information from, and makes payments using" >> mainframe_banking_system
33
33
  internet_banking_system >> "Sends e-mail using" >> email_system
34
34
 
35
- w.apply_views(
35
+ w.apply_view(
36
36
  SystemLandscapeView(
37
37
  key='landscape_00',
38
38
  description="System Landscape",
@@ -34,7 +34,7 @@ def test_system_landscape_view(use_context: bool) -> Optional[None]:
34
34
  )
35
35
 
36
36
  if not use_context:
37
- w.apply_views(
37
+ w.apply_view(
38
38
  SystemLandscapeView(
39
39
  key="system_landscape_view_00",
40
40
  description="System Landscape View Test",
@@ -48,8 +48,8 @@ def test_system_landscape_view(use_context: bool) -> Optional[None]:
48
48
  system_a = w.software_system().system_a
49
49
  system_b = w.software_system().system_b
50
50
 
51
- element_ids = list(map(lambda x: x.id, w.model.views.systemLandscapeViews[0].elements))
52
- relationship_ids = list(map(lambda x: x.id, w.model.views.systemLandscapeViews[0].relationships))
51
+ element_ids = [x.id for x in w.model.views.systemLandscapeViews[0].elements]
52
+ relationship_ids = [x.id for x in w.model.views.systemLandscapeViews[0].relationships]
53
53
 
54
54
  assert len(element_ids) == 3
55
55
  assert {
@@ -91,7 +91,7 @@ def test_system_context_view(use_context: bool) -> Optional[None]:
91
91
  )
92
92
 
93
93
  if not use_context:
94
- w.apply_views(
94
+ w.apply_view(
95
95
  SystemContextView(
96
96
  software_system_selector=lambda w: w.software_system().business_app,
97
97
  key="ss_business_app",
@@ -99,8 +99,8 @@ def test_system_context_view(use_context: bool) -> Optional[None]:
99
99
  )
100
100
  )
101
101
 
102
- element_ids = list(map(lambda x: x.id, w.model.views.systemContextViews[0].elements))
103
- relationship_ids = list(map(lambda x: x.id, w.model.views.systemContextViews[0].relationships))
102
+ element_ids = [x.id for x in w.model.views.systemContextViews[0].elements]
103
+ relationship_ids = [x.id for x in w.model.views.systemContextViews[0].relationships]
104
104
 
105
105
  print('element ids:', element_ids)
106
106
  print('person id:', w.person().u.model.id)
@@ -157,7 +157,7 @@ def test_system_context_view_with_exclude_user(use_context: bool) -> Optional[No
157
157
  )
158
158
 
159
159
  if not use_context:
160
- w.apply_views(
160
+ w.apply_view(
161
161
  SystemContextView(
162
162
  software_system_selector=lambda w: w.software_system().business_app,
163
163
  key="ss_business_app",
@@ -168,8 +168,8 @@ def test_system_context_view_with_exclude_user(use_context: bool) -> Optional[No
168
168
  )
169
169
  )
170
170
 
171
- element_ids = list(map(lambda x: x.id, w.model.views.systemContextViews[0].elements))
172
- relationship_ids = list(map(lambda x: x.id, w.model.views.systemContextViews[0].relationships))
171
+ element_ids = [x.id for x in w.model.views.systemContextViews[0].elements]
172
+ relationship_ids = [x.id for x in w.model.views.systemContextViews[0].relationships]
173
173
 
174
174
  print('element ids:', element_ids)
175
175
  print('person id:', w.person().u.model.id)
@@ -221,7 +221,7 @@ def test_container_view(use_context: bool) -> Optional[None]:
221
221
  )
222
222
 
223
223
  if not use_context:
224
- w.apply_views(
224
+ w.apply_view(
225
225
  ContainerView(
226
226
  software_system_selector=lambda w: w.software_system().app,
227
227
  key="ss_business_app",
@@ -229,8 +229,8 @@ def test_container_view(use_context: bool) -> Optional[None]:
229
229
  )
230
230
  )
231
231
 
232
- element_ids = list(map(lambda x: x.id, w.model.views.containerViews[0].elements))
233
- relationship_ids = list(map(lambda x: x.id, w.model.views.containerViews[0].relationships))
232
+ element_ids = [x.id for x in w.model.views.containerViews[0].elements]
233
+ relationship_ids = [x.id for x in w.model.views.containerViews[0].relationships]
234
234
 
235
235
  print('element ids:', element_ids)
236
236
  print('person id:', w.person().user.model.id)
@@ -272,7 +272,7 @@ def test_component_view(use_context: bool) -> Optional[None]:
272
272
  )
273
273
 
274
274
  if not use_context:
275
- w.apply_views(
275
+ w.apply_view(
276
276
  ComponentView(
277
277
  container_selector=lambda w: w.software_system().software_system.web_application,
278
278
  key="web_application_container_00",
@@ -280,8 +280,8 @@ def test_component_view(use_context: bool) -> Optional[None]:
280
280
  )
281
281
  )
282
282
 
283
- element_ids = list(map(lambda x: x.id, w.model.views.componentViews[0].elements))
284
- relationship_ids = list(map(lambda x: x.id, w.model.views.componentViews[0].relationships))
283
+ element_ids = [x.id for x in w.model.views.componentViews[0].elements]
284
+ relationship_ids = [x.id for x in w.model.views.componentViews[0].relationships]
285
285
 
286
286
  print("user id:", w.person().user.model.id)
287
287
  print("software system id", w.software_system().software_system.model.id)
@@ -330,7 +330,7 @@ def test_component_view_with_exclude_user(use_context: bool) -> Optional[None]:
330
330
  )
331
331
 
332
332
  if not use_context:
333
- w.apply_views(
333
+ w.apply_view(
334
334
  ComponentView(
335
335
  container_selector=lambda w: w.software_system().software_system.web_application,
336
336
  key="web_application_container_00",
@@ -341,8 +341,8 @@ def test_component_view_with_exclude_user(use_context: bool) -> Optional[None]:
341
341
  )
342
342
  )
343
343
 
344
- element_ids = list(map(lambda x: x.id, w.model.views.componentViews[0].elements))
345
- relationship_ids = list(map(lambda x: x.id, w.model.views.componentViews[0].relationships))
344
+ element_ids = [x.id for x in w.model.views.componentViews[0].elements]
345
+ relationship_ids = [x.id for x in w.model.views.componentViews[0].relationships]
346
346
 
347
347
  print("user id:", w.person().user.model.id)
348
348
  print("software system id", w.software_system().software_system.model.id)
@@ -384,7 +384,7 @@ def test_container_view_with_multiple_software_systems(use_context: bool) -> Opt
384
384
  )
385
385
 
386
386
  if not use_context:
387
- w.apply_views(
387
+ w.apply_view(
388
388
  ContainerView(
389
389
  key="container_view_00",
390
390
  description="Container View Test",
@@ -400,8 +400,8 @@ def test_container_view_with_multiple_software_systems(use_context: bool) -> Opt
400
400
  c1 = app1.c1
401
401
  c2 = app2.c2
402
402
 
403
- element_ids = list(map(lambda x: x.id, w.model.views.containerViews[0].elements))
404
- relationship_ids = list(map(lambda x: x.id, w.model.views.containerViews[0].relationships))
403
+ element_ids = [x.id for x in w.model.views.containerViews[0].elements]
404
+ relationship_ids = [x.id for x in w.model.views.containerViews[0].relationships]
405
405
 
406
406
  assert len(element_ids) == 2
407
407
  assert {
@@ -414,9 +414,72 @@ def test_container_view_with_multiple_software_systems(use_context: bool) -> Opt
414
414
  c1.model.relationships[0].id,
415
415
  }.issubset(set(relationship_ids))
416
416
 
417
- # TODO: Soon.
418
417
  def test_multiple_views() -> Optional[None]:
419
- pass
418
+
419
+ with Workspace("w", scope='landscape', group_separator="/") as w:
420
+ with Group("Company 1") as company1:
421
+ with Group("Department 1"):
422
+ a = SoftwareSystem("A")
423
+ with Group("Department 2") as c1d2:
424
+ b = SoftwareSystem("B")
425
+ with Group("Company 2") as company2:
426
+ with Group("Department 1"):
427
+ c = SoftwareSystem("C")
428
+ with Group("Department 2") as c2d2:
429
+ d = SoftwareSystem("D")
430
+ a >> b
431
+ c >> d
432
+ b >> c
433
+
434
+ SystemLandscapeView(
435
+ key='nested-groups',
436
+ description="Nested Groups Sample"
437
+ )
438
+
439
+ SystemContextView(
440
+ software_system_selector=b,
441
+ key='nested-groups-context-0',
442
+ description="Nested Groups Sample Context",
443
+ include_elements=[c, d],
444
+ )
445
+
446
+ SystemContextView(
447
+ software_system_selector=c,
448
+ key='nested-groups-context-1',
449
+ description="Nested Groups Sample Context",
450
+ include_elements=[b, d],
451
+ )
452
+
453
+ StyleElements(
454
+ on=[a, b],
455
+ shape='Box',
456
+ )
457
+
458
+ StyleElements(
459
+ on=[c, d],
460
+ shape='RoundedBox',
461
+ )
462
+
463
+ StyleElements(
464
+ on=[company1],
465
+ stroke='yellow',
466
+ border='dotted',
467
+ )
468
+
469
+ StyleElements(
470
+ on=[c1d2, c2d2],
471
+ color='green',
472
+ )
473
+
474
+ assert w.model.views.systemLandscapeViews is not None
475
+ assert w.model.views.systemContextViews is not None
476
+
477
+ assert len(w.model.views.systemLandscapeViews) == 1
478
+ assert len(w.model.views.systemContextViews) == 2
479
+
480
+ assert w.model.views.systemLandscapeViews[0].key == 'nested-groups'
481
+ assert w.model.views.systemContextViews[0].key == 'nested-groups-context-0'
482
+ assert w.model.views.systemContextViews[1].key == 'nested-groups-context-1'
420
483
 
421
484
  def test_style_elements_on_dslelements() -> Optional[None]:
422
485
 
@@ -1 +0,0 @@
1
- VERSION = "0.0.11"
@@ -1,44 +0,0 @@
1
- import buildzr
2
- from buildzr.dsl import *
3
- from typing import cast
4
- from ..abstract_builder import AbstractBuilder
5
-
6
- class GroupsSample(AbstractBuilder):
7
-
8
- def build(self) -> buildzr.models.Workspace:
9
- with Workspace("w", scope=None) as w:
10
- with Group("Company 1"):
11
- with SoftwareSystem("A") as a:
12
- Container("a1")
13
- Container("a2")
14
- with Group("Company 2"):
15
- with SoftwareSystem("B") as b:
16
- Container("b1")
17
- with Container("b2") as b2:
18
- Component("c1")
19
- c = SoftwareSystem("C")
20
- a >> "Uses" >> b
21
- a.a1 >> "Uses" >> b.b1
22
- a >> "Uses" >> c
23
- w.apply_views(
24
- SystemLandscapeView(
25
- key='groups-sample',
26
- description="Groups Sample"
27
- ),
28
- SystemContextView(
29
- key='groups-sample-a',
30
- software_system_selector=lambda w: cast(SoftwareSystem, w.a),
31
- description="Groups Sample - Software System A"
32
- ),
33
- SystemContextView(
34
- key='groups-sample-b',
35
- software_system_selector=lambda w: cast(SoftwareSystem, w.b),
36
- description="Groups Sample - Software System B"
37
- ),
38
- ContainerView(
39
- key='groups-sample-b2',
40
- software_system_selector=lambda w: w.software_system().b,
41
- description="Groups Sample - Container B2"
42
- ),
43
- )
44
- return w.model
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes