From ac39d763777742004cb89bb6920b8591c8aba5f3 Mon Sep 17 00:00:00 2001 From: yt-ms <71541861+yt-ms@users.noreply.github.com> Date: Fri, 25 Dec 2020 10:30:32 +0000 Subject: [PATCH 01/11] fix(StaticView): demonstrate duplication of relationships --- src/structurizr/view/static_view.py | 2 +- tests/unit/view/test_static_view.py | 76 +++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 tests/unit/view/test_static_view.py diff --git a/src/structurizr/view/static_view.py b/src/structurizr/view/static_view.py index f60cf48e..7bffdc2d 100644 --- a/src/structurizr/view/static_view.py +++ b/src/structurizr/view/static_view.py @@ -72,7 +72,7 @@ def hydrate_arguments(cls, static_view_io: StaticViewIO) -> Dict: @abstractmethod def add_all_elements(self) -> None: """Add all permitted elements from a model to this view.""" - pass + pass # pragma: no cover def add( self, diff --git a/tests/unit/view/test_static_view.py b/tests/unit/view/test_static_view.py new file mode 100644 index 00000000..5effdf5b --- /dev/null +++ b/tests/unit/view/test_static_view.py @@ -0,0 +1,76 @@ +# Copyright (c) 2020 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Ensure the expected behaviour of StaticView.""" + + +import pytest + +from structurizr.model import Model, Person, SoftwareSystem +from structurizr.view.static_view import StaticView + + +class DerivedView(StaticView): + """Mock class for testing.""" + + def add_all_elements(self) -> None: + """Stub method because base is abstract.""" + pass + + +def test_add_nearest_neighbours(): + """Test basic behaviour of add_nearest_neighbours.""" + model = Model() + sys1 = model.add_software_system(name="System 1") + sys2 = model.add_software_system(name="System 2") + person = model.add_person(name="Person 1") + sys1.uses(sys2) + person.uses(sys1) + + # Check neighbours from outbound relationships + view = DerivedView(software_system=sys1, description="") + view.add_nearest_neighbours(sys1, SoftwareSystem) + assert any((elt_view.element is sys1 for elt_view in view.element_views)) + assert any((elt_view.element is sys2 for elt_view in view.element_views)) + assert not any((elt_view.element is person for elt_view in view.element_views)) + assert len(view.relationship_views) == 1 + + # Check neighbours from inbound relationships + view = DerivedView(software_system=sys1, description="") + view.add_nearest_neighbours(sys2, SoftwareSystem) + assert any((elt_view.element is sys1 for elt_view in view.element_views)) + assert any((elt_view.element is sys2 for elt_view in view.element_views)) + assert not any((elt_view.element is person for elt_view in view.element_views)) + assert len(view.relationship_views) == 1 + + +@pytest.mark.xfail(strict=True) +def test_add_nearest_neighbours_doesnt_dupe_relationships(): + """Test relationships aren't duplicated if neighbours added more than once. + + See https://github.com/Midnighter/structurizr-python/issues/63. + """ + + model = Model() + sys1 = model.add_software_system(name="System 1") + sys2 = model.add_software_system(name="System 2") + sys1.uses(sys2) + view = DerivedView(software_system=sys1, description="") + view.add_nearest_neighbours(sys1, SoftwareSystem) + assert len(view.relationship_views) == 1 + + # The next line will currently dupe the relationship + view.add_nearest_neighbours(sys1, Person) + assert len(view.relationship_views) == 1 # This fails as it's 2 From 7946a7d542353533fa82d53b40d7ca703d022e23 Mon Sep 17 00:00:00 2001 From: yt-ms <71541861+yt-ms@users.noreply.github.com> Date: Fri, 25 Dec 2020 10:43:14 +0000 Subject: [PATCH 02/11] fix(StaticView): stop add_nearest_neighbour duplicating relationships --- CHANGELOG.rst | 1 + src/structurizr/view/static_view.py | 2 +- tests/unit/view/test_static_view.py | 8 ++------ 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5db3bec3..9124675f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,7 @@ History Next Release ------------ +* Fix: Don't duplicate relationships if ``add_nearest_neighbours()`` called twice (#63) 0.3.0 (2020-11-29) ------------------ diff --git a/src/structurizr/view/static_view.py b/src/structurizr/view/static_view.py index 7bffdc2d..14bba512 100644 --- a/src/structurizr/view/static_view.py +++ b/src/structurizr/view/static_view.py @@ -106,7 +106,7 @@ def add_nearest_neighbours( element_type: Union[Type[Person], Type[SoftwareSystem], Type[Container]], ) -> None: """Add all permitted elements from a model to this view.""" - self._add_element(element, True) + self._add_element(element, False) # TODO(ilaif): @midnighter - Should we move to @property instead # of get_X()? More pythonic. diff --git a/tests/unit/view/test_static_view.py b/tests/unit/view/test_static_view.py index 5effdf5b..d7eb9a30 100644 --- a/tests/unit/view/test_static_view.py +++ b/tests/unit/view/test_static_view.py @@ -16,8 +16,6 @@ """Ensure the expected behaviour of StaticView.""" -import pytest - from structurizr.model import Model, Person, SoftwareSystem from structurizr.view.static_view import StaticView @@ -56,13 +54,11 @@ def test_add_nearest_neighbours(): assert len(view.relationship_views) == 1 -@pytest.mark.xfail(strict=True) def test_add_nearest_neighbours_doesnt_dupe_relationships(): """Test relationships aren't duplicated if neighbours added more than once. See https://github.com/Midnighter/structurizr-python/issues/63. """ - model = Model() sys1 = model.add_software_system(name="System 1") sys2 = model.add_software_system(name="System 2") @@ -71,6 +67,6 @@ def test_add_nearest_neighbours_doesnt_dupe_relationships(): view.add_nearest_neighbours(sys1, SoftwareSystem) assert len(view.relationship_views) == 1 - # The next line will currently dupe the relationship + # The next line should not add any new relationships view.add_nearest_neighbours(sys1, Person) - assert len(view.relationship_views) == 1 # This fails as it's 2 + assert len(view.relationship_views) == 1 From dab5b86f54cf4f1edb465a4cc86473fdf4b42ccd Mon Sep 17 00:00:00 2001 From: yt-ms <71541861+yt-ms@users.noreply.github.com> Date: Fri, 25 Dec 2020 13:15:29 +0000 Subject: [PATCH 03/11] fix(View): ignore if trying to add the same relationship to a view twice --- src/structurizr/view/view.py | 17 ++++++-- tests/unit/view/test_view.py | 81 ++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 tests/unit/view/test_view.py diff --git a/src/structurizr/view/view.py b/src/structurizr/view/view.py index 6bd81529..ad8d07f2 100644 --- a/src/structurizr/view/view.py +++ b/src/structurizr/view/view.py @@ -173,14 +173,23 @@ def _add_relationship(self, relationship: Relationship) -> RelationshipView: """Add a single relationship to this view. Returns: - The new view if both the source and destination for the relationship are - in this view, else `None`. + The new (or existing) view if both the source and destination for the + relationship are in this view, else `None`. """ if self.is_element_in_view(relationship.source) and self.is_element_in_view( relationship.destination ): - view = RelationshipView(relationship=relationship) - self.relationship_views.add(view) + view = next( + ( + rv + for rv in self.relationship_views + if rv.relationship is relationship + ), + None, + ) + if not view: + view = RelationshipView(relationship=relationship) + self.relationship_views.add(view) return view return None diff --git a/tests/unit/view/test_view.py b/tests/unit/view/test_view.py new file mode 100644 index 00000000..ac020259 --- /dev/null +++ b/tests/unit/view/test_view.py @@ -0,0 +1,81 @@ +# Copyright (c) 2020 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Ensure the expected behaviour of View.""" + + +from structurizr.model import Model, SoftwareSystem +from structurizr.view.view import View + + +class DerivedView(View): + """Mock class for testing.""" + + pass + + +def test_add_relationship_doesnt_duplicate(): + """Test that adding a relationships twice doesn't duplicate it.""" + model = Model() + sys1 = model.add_software_system(name="System 1") + sys2 = model.add_software_system(name="System 2") + rel = sys1.uses(sys2) + + view = DerivedView(software_system=sys1, description="") + view._add_element(sys1, False) + view._add_element(sys2, False) + + rel_view1 = view._add_relationship(rel) + assert len(view.relationship_views) == 1 + rel_view2 = view._add_relationship(rel) + assert len(view.relationship_views) == 1 + assert rel_view2 is rel_view1 + + +def test_add_relationship_for_element_not_in_view(): + """Ensures relationships for elements outside the view are ignored.""" + model = Model() + sys1 = model.add_software_system(name="System 1") + sys2 = model.add_software_system(name="System 2") + rel = sys1.uses(sys2) + + view = DerivedView(software_system=sys1, description="") + view._add_element(sys1, False) + + # This relationship should be ignored as sys2 isn't in the view + rel_view1 = view._add_relationship(rel) + assert rel_view1 is None + assert view.relationship_views == set() + + +def test_adding_all_relationships(): + """Test adding all relationships for elements in the view.""" + model = Model() + sys1 = model.add_software_system(name="System 1") + sys2 = model.add_software_system(name="System 2") + sys3 = model.add_software_system(name="System 3") + rel1 = sys1.uses(sys2) + rel2 = sys3.uses(sys1) + + view = DerivedView(software_system=sys1, description="") + view._add_element(sys1, False) + view._add_element(sys2, False) + view._add_element(sys3, False) + assert view.relationship_views == set() + + view._add_relationships(sys1) + assert len(view.relationship_views) == 2 + assert rel1 in [vr.relationship for vr in view.relationship_views] + assert rel2 in [vr.relationship for vr in view.relationship_views] From 7a639a44809623da25fcec1b8200f07f374b27d6 Mon Sep 17 00:00:00 2001 From: yt-ms <71541861+yt-ms@users.noreply.github.com> Date: Fri, 25 Dec 2020 13:22:27 +0000 Subject: [PATCH 04/11] chore: fix flake8 errors --- tests/unit/view/test_view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/view/test_view.py b/tests/unit/view/test_view.py index ac020259..667c759f 100644 --- a/tests/unit/view/test_view.py +++ b/tests/unit/view/test_view.py @@ -16,7 +16,7 @@ """Ensure the expected behaviour of View.""" -from structurizr.model import Model, SoftwareSystem +from structurizr.model import Model from structurizr.view.view import View From 6ba54f3e3242cd526ac7ffa943dda27ea1d5d258 Mon Sep 17 00:00:00 2001 From: yt-ms <71541861+yt-ms@users.noreply.github.com> Date: Fri, 25 Dec 2020 13:31:06 +0000 Subject: [PATCH 05/11] style: fix flake8 errors in examples --- Makefile | 1 + examples/big_bank.py | 38 ++++++++++++++++++++----------- examples/financial_risk_system.py | 5 +++- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index fc743d75..8a4bb65b 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ qa: isort src/structurizr/ tests/ examples/ setup.py black src/structurizr/ tests/ examples/ setup.py + flake8 src/structurizr/ tests/ examples/ setup.py ## Prepare a release by generating the automatic code documentation. release: diff --git a/examples/big_bank.py b/examples/big_bank.py index 1d222313..962dc99c 100644 --- a/examples/big_bank.py +++ b/examples/big_bank.py @@ -152,14 +152,16 @@ def create_big_bank_workspace(): single_page_application.tags.add(web_browser_tag) mobile_app = internet_banking_system.add_container( "Mobile App", - "Provides a limited subset of the Internet banking functionality to customers via their mobile device.", + "Provides a limited subset of the Internet banking functionality to " + + "customers via their mobile device.", "Xamarin", id="mobileApp", ) mobile_app.tags.add(mobile_app_tag) web_application = internet_banking_system.add_container( "Web Application", - "Delivers the static content and the Internet banking single page application.", + "Delivers the static content and the Internet banking single page " + + "application.", "Java and Spring MVC", id="webApplication", ) @@ -171,7 +173,8 @@ def create_big_bank_workspace(): ) database = internet_banking_system.add_container( "Database", - "Stores user registration information, hashed authentication credentials, access logs, etc.", + "Stores user registration information, hashed authentication credentials, " + + "access logs, etc.", "Relational Database Schema", id="database", ) @@ -188,8 +191,9 @@ def create_big_bank_workspace(): api_application.uses(email_system, "Sends e-mail using", technology="SMTP") # components - # - for a real-world software system, you would probably want to extract the components using - # - static analysis/reflection rather than manually specifying them all + # - for a real-world software system, you would probably want to extract the + # components using static analysis/reflection rather than manually specifying + # them all signin_controller = api_application.add_component( name="Sign In Controller", @@ -211,7 +215,8 @@ def create_big_bank_workspace(): ) security_component = api_application.add_component( name="Security Component", - description="Provides functionality related to signing in, changing passwords, etc.", + description="Provides functionality related to signing in, changing passwords, " + + "etc.", technology="Spring Bean", id="securityComponent", ) @@ -353,7 +358,8 @@ def create_big_bank_workspace(): secondary_database_server.tags.add(failover_tag) secondary_database = secondary_database_server.add_container(database) - # # model.Relationships.Where(r=>r.Destination.Equals(secondary_database)).ToList().ForEach(r=>r.tags.add(failover_tag)) + # model.Relationships.Where(r=>r.Destination.Equals(secondary_database)).ToList() + # .ForEach(r=>r.tags.add(failover_tag)) data_replication_relationship = primary_database_server.uses( secondary_database_server, "Replicates data to" ) @@ -400,7 +406,8 @@ def create_big_bank_workspace(): component_view.add(email_system) component_view.paper_size = PaperSize.A5_Landscape - # systemLandscapeView.AddAnimation(internet_banking_system, customer, mainframe_banking_system, emailSystem) + # systemLandscapeView.AddAnimation(internet_banking_system, customer, + # mainframe_banking_system, emailSystem) # systemLandscapeView.AddAnimation(atm) # systemLandscapeView.AddAnimation(customerServiceStaff, back_office_staff) @@ -418,20 +425,24 @@ def create_big_bank_workspace(): # componentView.AddAnimation(singlePageApplication, mobile_app) # componentView.AddAnimation(signinController, securityComponent, database) - # componentView.AddAnimation(accountsSummaryController, mainframe_banking_systemFacade, mainframe_banking_system) + # componentView.AddAnimation(accountsSummaryController, + # mainframe_banking_systemFacade, mainframe_banking_system) # componentView.AddAnimation(resetPasswordController, emailComponent, database) # # dynamic diagrams and deployment diagrams are not available with the Free Plan - # DynamicView dynamicView = views.CreateDynamicView(apiApplication, "SignIn", "Summarises how the sign in feature works in the single-page application.") + # DynamicView dynamicView = views.CreateDynamicView(apiApplication, "SignIn", + # "Summarises how the sign in feature works in the single-page application.") # dynamicView.Add(singlePageApplication, "Submits credentials to", signinController) # dynamicView.Add(signinController, "Calls isAuthenticated() on", securityComponent) - # dynamicView.Add(securityComponent, "select * from users where username = ?", database) + # dynamicView.Add(securityComponent, "select * from users where username = ?", + # database) # dynamicView.PaperSize = PaperSize.A5_Landscape development_deployment_view = views.create_deployment_view( software_system=internet_banking_system, key="DevelopmentDeployment", - description="An example development deployment scenario for the Internet Banking System.", + description="An example development deployment scenario for the Internet " + + "Banking System.", environment="Development", ) development_deployment_view.add(developer_laptop) @@ -440,7 +451,8 @@ def create_big_bank_workspace(): live_deployment_view = views.create_deployment_view( software_system=internet_banking_system, key="LiveDeployment", - description="An example live deployment scenario for the Internet Banking System.", + description="An example live deployment scenario for the Internet Banking " + + "System.", environment="Live", ) live_deployment_view += big_bank_data_center diff --git a/examples/financial_risk_system.py b/examples/financial_risk_system.py index 37dd2650..7e920ca7 100644 --- a/examples/financial_risk_system.py +++ b/examples/financial_risk_system.py @@ -127,7 +127,10 @@ def main() -> Workspace: contextView = views.create_system_context_view( software_system=financial_risk_system, key="Context", - description="An example System Context diagram for the Financial Risk System architecture kata.", + description=( + "An example System Context diagram for the Financial Risk System " + "architecture kata." + ), ) contextView.add_all_software_systems() contextView.add_all_people() From f92e98fd44301dc37f8eb62c7ec03704fbec8f20 Mon Sep 17 00:00:00 2001 From: yt-ms <71541861+yt-ms@users.noreply.github.com> Date: Sun, 27 Dec 2020 09:12:54 +0000 Subject: [PATCH 06/11] fix(View): demonstrate problem with missing descriptions (issue #40) --- tests/unit/view/test_view.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tests/unit/view/test_view.py b/tests/unit/view/test_view.py index 667c759f..c27fa9d9 100644 --- a/tests/unit/view/test_view.py +++ b/tests/unit/view/test_view.py @@ -15,9 +15,10 @@ """Ensure the expected behaviour of View.""" +import pytest from structurizr.model import Model -from structurizr.view.view import View +from structurizr.view.view import View, ViewIO class DerivedView(View): @@ -79,3 +80,22 @@ def test_adding_all_relationships(): assert len(view.relationship_views) == 2 assert rel1 in [vr.relationship for vr in view.relationship_views] assert rel2 in [vr.relationship for vr in view.relationship_views] + + +@pytest.mark.xfail(strict=True) +def test_missing_json_description_allowed(): + """ + Ensure that missing descriptions in the JSON form are supported. + + Raised as https://github.com/Midnighter/structurizr-python/issues/40, it is + permitted through the Structurizr UI to create views with a blank description, + which then gets ommitted from the workspace JSON, so this needs to be allowed by + the Pydantic validation also. + """ + + json = """ + { + "key": "System1-SystemContext" + } + """ + ViewIO.parse_raw(json) # Fails as description is missing From b5d7f0512e77bac84066f3cc565e0396aae91ae8 Mon Sep 17 00:00:00 2001 From: yt-ms <71541861+yt-ms@users.noreply.github.com> Date: Sun, 27 Dec 2020 09:25:03 +0000 Subject: [PATCH 07/11] fix(View): support blank descriptions in diagrams from the Structurizr UI (issue #40) --- CHANGELOG.rst | 1 + src/structurizr/view/view.py | 2 +- tests/unit/view/test_view.py | 6 ++---- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9124675f..eb193a5e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,7 @@ History Next Release ------------ * Fix: Don't duplicate relationships if ``add_nearest_neighbours()`` called twice (#63) +* Fix: Support blank diagrams descriptions from the Structurizr UI (#40) 0.3.0 (2020-11-29) ------------------ diff --git a/src/structurizr/view/view.py b/src/structurizr/view/view.py index ad8d07f2..205b18b4 100644 --- a/src/structurizr/view/view.py +++ b/src/structurizr/view/view.py @@ -42,7 +42,7 @@ class ViewIO(BaseModel, ABC): """ key: str - description: str + description: str = "" software_system_id: Optional[str] = Field(default=None, alias="softwareSystemId") paper_size: Optional[PaperSize] = Field(default=None, alias="paperSize") automatic_layout: Optional[AutomaticLayoutIO] = Field( diff --git a/tests/unit/view/test_view.py b/tests/unit/view/test_view.py index c27fa9d9..1d47a9fd 100644 --- a/tests/unit/view/test_view.py +++ b/tests/unit/view/test_view.py @@ -15,8 +15,6 @@ """Ensure the expected behaviour of View.""" -import pytest - from structurizr.model import Model from structurizr.view.view import View, ViewIO @@ -82,7 +80,6 @@ def test_adding_all_relationships(): assert rel2 in [vr.relationship for vr in view.relationship_views] -@pytest.mark.xfail(strict=True) def test_missing_json_description_allowed(): """ Ensure that missing descriptions in the JSON form are supported. @@ -98,4 +95,5 @@ def test_missing_json_description_allowed(): "key": "System1-SystemContext" } """ - ViewIO.parse_raw(json) # Fails as description is missing + io = ViewIO.parse_raw(json) + assert io is not None From 7629dd2cdf23b3227c5221c31822905d507ecaf4 Mon Sep 17 00:00:00 2001 From: Yan <71541861+yt-ms@users.noreply.github.com> Date: Wed, 3 Feb 2021 13:07:49 +0000 Subject: [PATCH 08/11] Fix string concatenation (PR feedback) Co-authored-by: Moritz E. Beber --- examples/big_bank.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/big_bank.py b/examples/big_bank.py index 962dc99c..d53de416 100644 --- a/examples/big_bank.py +++ b/examples/big_bank.py @@ -153,7 +153,7 @@ def create_big_bank_workspace(): mobile_app = internet_banking_system.add_container( "Mobile App", "Provides a limited subset of the Internet banking functionality to " - + "customers via their mobile device.", + "customers via their mobile device.", "Xamarin", id="mobileApp", ) From 3d4aa90e2fea13daab51ff8694a7752b26c35ff6 Mon Sep 17 00:00:00 2001 From: Yan <71541861+yt-ms@users.noreply.github.com> Date: Wed, 3 Feb 2021 13:08:31 +0000 Subject: [PATCH 09/11] fix: string concatenation (PR feedback) Co-authored-by: Moritz E. Beber --- examples/big_bank.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/big_bank.py b/examples/big_bank.py index d53de416..85e4ad29 100644 --- a/examples/big_bank.py +++ b/examples/big_bank.py @@ -161,7 +161,7 @@ def create_big_bank_workspace(): web_application = internet_banking_system.add_container( "Web Application", "Delivers the static content and the Internet banking single page " - + "application.", + "application.", "Java and Spring MVC", id="webApplication", ) From eabef7ad440e69b93b42eb8a296fd069349341a9 Mon Sep 17 00:00:00 2001 From: Yan <71541861+yt-ms@users.noreply.github.com> Date: Wed, 3 Feb 2021 13:10:29 +0000 Subject: [PATCH 10/11] fix: string concatenation (PR feedback) Co-authored-by: Moritz E. Beber --- examples/big_bank.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/big_bank.py b/examples/big_bank.py index 85e4ad29..2ab97eb3 100644 --- a/examples/big_bank.py +++ b/examples/big_bank.py @@ -174,7 +174,7 @@ def create_big_bank_workspace(): database = internet_banking_system.add_container( "Database", "Stores user registration information, hashed authentication credentials, " - + "access logs, etc.", + "access logs, etc.", "Relational Database Schema", id="database", ) @@ -216,7 +216,7 @@ def create_big_bank_workspace(): security_component = api_application.add_component( name="Security Component", description="Provides functionality related to signing in, changing passwords, " - + "etc.", + "etc.", technology="Spring Bean", id="securityComponent", ) @@ -442,7 +442,7 @@ def create_big_bank_workspace(): software_system=internet_banking_system, key="DevelopmentDeployment", description="An example development deployment scenario for the Internet " - + "Banking System.", + "Banking System.", environment="Development", ) development_deployment_view.add(developer_laptop) @@ -452,7 +452,7 @@ def create_big_bank_workspace(): software_system=internet_banking_system, key="LiveDeployment", description="An example live deployment scenario for the Internet Banking " - + "System.", + "System.", environment="Live", ) live_deployment_view += big_bank_data_center From 883dde04ebee7af2666412dced270941f127cef9 Mon Sep 17 00:00:00 2001 From: yt-ms <71541861+yt-ms@users.noreply.github.com> Date: Wed, 3 Feb 2021 13:18:25 +0000 Subject: [PATCH 11/11] fix: remove flake8 from make qa (PR feedback) --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 8a4bb65b..fc743d75 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,6 @@ qa: isort src/structurizr/ tests/ examples/ setup.py black src/structurizr/ tests/ examples/ setup.py - flake8 src/structurizr/ tests/ examples/ setup.py ## Prepare a release by generating the automatic code documentation. release: