From 9a61557932b3a923f7f22eadca63cbbd0f097495 Mon Sep 17 00:00:00 2001 From: mgwynn Date: Thu, 10 Jun 2021 21:17:24 -0400 Subject: [PATCH 1/6] Adding unit test for project properties cli --- scripts/o3de/o3de/project_properties.py | 4 +- .../tests/unit_test_project_properties.py | 62 +++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 scripts/o3de/tests/unit_test_project_properties.py diff --git a/scripts/o3de/o3de/project_properties.py b/scripts/o3de/o3de/project_properties.py index 52f1346b51..aefe5c53e9 100644 --- a/scripts/o3de/o3de/project_properties.py +++ b/scripts/o3de/o3de/project_properties.py @@ -54,9 +54,9 @@ def edit_project_props(proj_path, proj_name, new_origin, new_display, if tag in proj_json['user_tags']: proj_json['user_tags'].remove(tag) else: - logger.warn(f'{tag} not found in user_tags for removal.') + logger.warning(f'{tag} not found in user_tags for removal.') else: - logger.warn(f'user_tags property not found for removal of {remove_tags}.') + logger.warning(f'user_tags property not found for removal of {remove_tags}.') if replace_tags: tag_list = [replace_tags] if isinstance(replace_tags, str) else replace_tags proj_json['user_tags'] = tag_list diff --git a/scripts/o3de/tests/unit_test_project_properties.py b/scripts/o3de/tests/unit_test_project_properties.py new file mode 100644 index 0000000000..e93824cdf7 --- /dev/null +++ b/scripts/o3de/tests/unit_test_project_properties.py @@ -0,0 +1,62 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +import pytest +import pathlib +from unittest.mock import patch +from o3de import project_properties + + +TEST_DEFAULT_PROJECT_DATA = { + "template_name": "DefaultProject", + "restricted_name": "o3de", + "restricted_platform_relative_path": "Templates", + "origin": "The primary repo for DefaultProject goes here: i.e. http://www.mydomain.com", + "license": "What license DefaultProject uses goes here: i.e. https://opensource.org/licenses/MIT", + "display_name": "Default", + "summary": "A short description of DefaultProject.", + "included_gems": ["Atom","Camera","EMotionFX","UI","Maestro","Input","ImGui"], + "canonical_tags": [], + "user_tags": [ + "DefaultProject" + ], + "icon_path": "preview.png" +} + +def get_project_json_data(project_name, project_path) -> str: + return TEST_DEFAULT_PROJECT_DATA + +def save_o3de_manifest(new_proj_data, project_path): + temp = new_proj_data + +@pytest.mark.parametrize("project_path, project_name, project_origin, project_display,\ + project_summary, project_icon, add_tags, delete_tags,\ + replace_tags, expected_result", [ + pytest.param(pathlib.PurePath('E:/TestProject'), + 'test', 'editing by pytest', 'Unit Test', 'pyTest project', 'pytest.bmp', 'A B C', + 'B', 'D E F', 0), + pytest.param(pathlib.PurePath(None), + 'test', 'editing by pytest', 'Unit Test', 'pyTest project', 'pytest.bmp', 'A B C', + 'B', 'D E F', 1), + ] +) + +def test_edit_project_properties(project_path, project_name, project_origin, project_display, + project_summary, project_icon, add_tags, delete_tags, + replace_tags, expected_result): + + with patch('o3de.manifest.get_project_json_data', side_effect=get_project_json_data) as get_project_json_data_patch, \ + patch('o3de.manifest.save_o3de_manifest', side_effect=save_o3de_manifest) as save_o3de_manifest_patch: + result = project_properties.edit_project_props(project_path, project_name, project_origin, + project_display, project_summary, project_icon, + add_tags, delete_tags, replace_tags) + assert result == expected_result + From d029ba894eb0d9db1b4de05a925eb0f8d7404edc Mon Sep 17 00:00:00 2001 From: mgwynn Date: Thu, 10 Jun 2021 21:24:27 -0400 Subject: [PATCH 2/6] Added failure condition for fail case test --- scripts/o3de/tests/unit_test_project_properties.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/o3de/tests/unit_test_project_properties.py b/scripts/o3de/tests/unit_test_project_properties.py index e93824cdf7..957b5a19df 100644 --- a/scripts/o3de/tests/unit_test_project_properties.py +++ b/scripts/o3de/tests/unit_test_project_properties.py @@ -32,6 +32,8 @@ TEST_DEFAULT_PROJECT_DATA = { } def get_project_json_data(project_name, project_path) -> str: + if project_path == '': + return None return TEST_DEFAULT_PROJECT_DATA def save_o3de_manifest(new_proj_data, project_path): @@ -43,9 +45,9 @@ def save_o3de_manifest(new_proj_data, project_path): pytest.param(pathlib.PurePath('E:/TestProject'), 'test', 'editing by pytest', 'Unit Test', 'pyTest project', 'pytest.bmp', 'A B C', 'B', 'D E F', 0), - pytest.param(pathlib.PurePath(None), + pytest.param('', 'test', 'editing by pytest', 'Unit Test', 'pyTest project', 'pytest.bmp', 'A B C', - 'B', 'D E F', 1), + 'B', 'D E F', 1) ] ) From e80ba41bdd11c71927137ae3e5790057f30476ec Mon Sep 17 00:00:00 2001 From: mgwynn Date: Thu, 10 Jun 2021 22:08:05 -0400 Subject: [PATCH 3/6] Adding project properties test to cmakeLists --- scripts/o3de/tests/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/o3de/tests/CMakeLists.txt b/scripts/o3de/tests/CMakeLists.txt index 82b994e387..98c4be3b2f 100644 --- a/scripts/o3de/tests/CMakeLists.txt +++ b/scripts/o3de/tests/CMakeLists.txt @@ -41,3 +41,10 @@ ly_add_pytest( TEST_SUITE smoke EXCLUDE_TEST_RUN_TARGET_FROM_IDE ) + +ly_add_pytest( + NAME o3de_project_properties + PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_project_properties.py + TEST_SUITE smoke + EXCLUDE_TEST_RUN_TARGET_FROM_IDE +) From 0b3a56d031f65db47f8aad84577c7ef1f0eeae5c Mon Sep 17 00:00:00 2001 From: mgwynn Date: Fri, 11 Jun 2021 15:00:57 -0400 Subject: [PATCH 4/6] Incorporating review comments. Adding checks for json contents. Added class. Minor reformatting. --- scripts/o3de/o3de/project_properties.py | 2 +- .../tests/unit_test_project_properties.py | 72 ++++++++++++------- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/scripts/o3de/o3de/project_properties.py b/scripts/o3de/o3de/project_properties.py index aefe5c53e9..166ae9ac5f 100644 --- a/scripts/o3de/o3de/project_properties.py +++ b/scripts/o3de/o3de/project_properties.py @@ -58,7 +58,7 @@ def edit_project_props(proj_path, proj_name, new_origin, new_display, else: logger.warning(f'user_tags property not found for removal of {remove_tags}.') if replace_tags: - tag_list = [replace_tags] if isinstance(replace_tags, str) else replace_tags + tag_list = replace_tags.split() if isinstance(replace_tags, str) else replace_tags proj_json['user_tags'] = tag_list manifest.save_o3de_manifest(proj_json, pathlib.Path(proj_path) / 'project.json') diff --git a/scripts/o3de/tests/unit_test_project_properties.py b/scripts/o3de/tests/unit_test_project_properties.py index 957b5a19df..d467d9c3d0 100644 --- a/scripts/o3de/tests/unit_test_project_properties.py +++ b/scripts/o3de/tests/unit_test_project_properties.py @@ -31,34 +31,52 @@ TEST_DEFAULT_PROJECT_DATA = { "icon_path": "preview.png" } -def get_project_json_data(project_name, project_path) -> str: - if project_path == '': - return None - return TEST_DEFAULT_PROJECT_DATA +@pytest.fixture(scope='class') +def init_project_json_data(request): + class ProjectJsonData: + def __init__(self): + self.data = TEST_DEFAULT_PROJECT_DATA + request.cls.project_json = ProjectJsonData() -def save_o3de_manifest(new_proj_data, project_path): - temp = new_proj_data +@pytest.mark.usefixtures('init_project_json_data') +class TestEditProjectProperties: + @pytest.mark.parametrize("project_path, project_name, project_origin, project_display,\ + project_summary, project_icon, add_tags, delete_tags,\ + replace_tags, expected_result", [ + pytest.param(pathlib.PurePath('E:/TestProject'), + 'test', 'editing by pytest', 'Unit Test', 'pyTest project', 'pytest.bmp', 'A B C', + 'B', 'D E F', 0), + pytest.param('', + 'test', 'editing by pytest', 'Unit Test', 'pyTest project', 'pytest.bmp', 'A B C', + 'B', 'D E F', 1) + ] + ) + def test_edit_project_properties(self,project_path, project_name, project_origin, project_display, + project_summary, project_icon, add_tags, delete_tags, + replace_tags, expected_result): -@pytest.mark.parametrize("project_path, project_name, project_origin, project_display,\ - project_summary, project_icon, add_tags, delete_tags,\ - replace_tags, expected_result", [ - pytest.param(pathlib.PurePath('E:/TestProject'), - 'test', 'editing by pytest', 'Unit Test', 'pyTest project', 'pytest.bmp', 'A B C', - 'B', 'D E F', 0), - pytest.param('', - 'test', 'editing by pytest', 'Unit Test', 'pyTest project', 'pytest.bmp', 'A B C', - 'B', 'D E F', 1) - ] -) + def get_project_json_data(project_name: str, project_path) -> dict: + if not project_path: + self.project_json.data = None + return None + return self.project_json.data -def test_edit_project_properties(project_path, project_name, project_origin, project_display, - project_summary, project_icon, add_tags, delete_tags, - replace_tags, expected_result): - - with patch('o3de.manifest.get_project_json_data', side_effect=get_project_json_data) as get_project_json_data_patch, \ - patch('o3de.manifest.save_o3de_manifest', side_effect=save_o3de_manifest) as save_o3de_manifest_patch: - result = project_properties.edit_project_props(project_path, project_name, project_origin, - project_display, project_summary, project_icon, - add_tags, delete_tags, replace_tags) - assert result == expected_result + def save_o3de_manifest(new_proj_data: dict, project_path) -> None: + self.project_json.data = new_proj_data + with patch('o3de.manifest.get_project_json_data', side_effect=get_project_json_data) as get_project_json_data_patch, \ + patch('o3de.manifest.save_o3de_manifest', side_effect=save_o3de_manifest) as save_o3de_manifest_patch: + result = project_properties.edit_project_props(project_path, project_name, project_origin, + project_display, project_summary, project_icon, + add_tags, delete_tags, replace_tags) + assert result == expected_result + if project_path: + assert self.project_json.data + assert self.project_json.data.get('origin', '') == project_origin + assert self.project_json.data.get('display_name', '') == project_display + assert self.project_json.data.get('summary', '') == project_summary + assert self.project_json.data.get('icon_path', '') == project_icon + expected_tag_set = set(replace_tags.split()) + assert expected_tag_set.issubset(self.project_json.data.get('user_tags', set())) + else: + assert not self.project_json.data From 3127bf74772bfe8b3387b92358116472ba6ad9db Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 11 Jun 2021 15:02:15 -0500 Subject: [PATCH 5/6] Making sure the expected tag set exactly matches the "user_tags" in the project_json --- scripts/o3de/tests/unit_test_project_properties.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/o3de/tests/unit_test_project_properties.py b/scripts/o3de/tests/unit_test_project_properties.py index d467d9c3d0..5e9aea3964 100644 --- a/scripts/o3de/tests/unit_test_project_properties.py +++ b/scripts/o3de/tests/unit_test_project_properties.py @@ -51,7 +51,7 @@ class TestEditProjectProperties: 'B', 'D E F', 1) ] ) - def test_edit_project_properties(self,project_path, project_name, project_origin, project_display, + def test_edit_project_properties(self, project_path, project_name, project_origin, project_display, project_summary, project_icon, add_tags, delete_tags, replace_tags, expected_result): @@ -77,6 +77,7 @@ class TestEditProjectProperties: assert self.project_json.data.get('summary', '') == project_summary assert self.project_json.data.get('icon_path', '') == project_icon expected_tag_set = set(replace_tags.split()) - assert expected_tag_set.issubset(self.project_json.data.get('user_tags', set())) + project_json_tag_set = set(self.project_json.data.get('user_tags', [])) + assert project_json_tag_set == expected_tag_set else: assert not self.project_json.data From fe441b01a09af4cbef4fa27f75d6f88b5319b6ed Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 11 Jun 2021 15:04:51 -0500 Subject: [PATCH 6/6] Split the new_tags and delete_tags paramaters if they are strings on spaces. --- scripts/o3de/o3de/project_properties.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/o3de/o3de/project_properties.py b/scripts/o3de/o3de/project_properties.py index 166ae9ac5f..38dab18894 100644 --- a/scripts/o3de/o3de/project_properties.py +++ b/scripts/o3de/o3de/project_properties.py @@ -45,10 +45,10 @@ def edit_project_props(proj_path, proj_name, new_origin, new_display, if new_icon: proj_json['icon_path'] = new_icon if new_tags: - tag_list = [new_tags] if isinstance(new_tags, str) else new_tags + tag_list = new_tags.split() if isinstance(new_tags, str) else new_tags proj_json.setdefault('user_tags', []).extend(tag_list) if delete_tags: - removal_list = [delete_tags] if isinstance(delete_tags, str) else delete_tags + removal_list = delete_tags.split() if isinstance(delete_tags, str) else delete_tags if 'user_tags' in proj_json: for tag in removal_list: if tag in proj_json['user_tags']: