From 386f68aa818651b844b7380217b58f9de83232fc Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Fri, 25 Feb 2022 23:17:59 -0600 Subject: [PATCH] Addon Manager: Add unit test framework Adds the framework for unit testing, and a few tests of the utilities functions. --- .../AddonManager/AddonManagerTest/__init__.py | 0 .../AddonManagerTest/app/__init__.py | 0 .../AddonManagerTest/app/test_utilities.py | 142 ++++++++++++++++++ .../AddonManagerTest/data/__init__.py | 0 .../data/bad_macro_metadata.FCStd | 37 +++++ .../data/good_macro_metadata.FCStd | 37 +++++ .../data/missing_macro_metadata.FCStd | 25 +++ .../AddonManagerTest/gui/__init__.py | 0 .../AddonManagerTest/gui/test_gui.py | 33 ++++ .../AddonManagerTest/test_information.md | 3 + src/Mod/AddonManager/CMakeLists.txt | 47 +++++- src/Mod/AddonManager/Init.py | 3 + src/Mod/AddonManager/InitGui.py | 3 + src/Mod/AddonManager/TestAddonManagerApp.py | 29 ++++ src/Mod/AddonManager/TestAddonManagerGui.py | 29 ++++ 15 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 src/Mod/AddonManager/AddonManagerTest/__init__.py create mode 100644 src/Mod/AddonManager/AddonManagerTest/app/__init__.py create mode 100644 src/Mod/AddonManager/AddonManagerTest/app/test_utilities.py create mode 100644 src/Mod/AddonManager/AddonManagerTest/data/__init__.py create mode 100644 src/Mod/AddonManager/AddonManagerTest/data/bad_macro_metadata.FCStd create mode 100644 src/Mod/AddonManager/AddonManagerTest/data/good_macro_metadata.FCStd create mode 100644 src/Mod/AddonManager/AddonManagerTest/data/missing_macro_metadata.FCStd create mode 100644 src/Mod/AddonManager/AddonManagerTest/gui/__init__.py create mode 100644 src/Mod/AddonManager/AddonManagerTest/gui/test_gui.py create mode 100644 src/Mod/AddonManager/AddonManagerTest/test_information.md create mode 100644 src/Mod/AddonManager/TestAddonManagerApp.py create mode 100644 src/Mod/AddonManager/TestAddonManagerGui.py diff --git a/src/Mod/AddonManager/AddonManagerTest/__init__.py b/src/Mod/AddonManager/AddonManagerTest/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Mod/AddonManager/AddonManagerTest/app/__init__.py b/src/Mod/AddonManager/AddonManagerTest/app/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Mod/AddonManager/AddonManagerTest/app/test_utilities.py b/src/Mod/AddonManager/AddonManagerTest/app/test_utilities.py new file mode 100644 index 0000000000..1cb3fc6f42 --- /dev/null +++ b/src/Mod/AddonManager/AddonManagerTest/app/test_utilities.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * Copyright (c) 2022 FreeCAD Project Association * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This library is free software; you can redistribute it and/or * +# * modify it under the terms of the GNU Lesser General Public * +# * License as published by the Free Software Foundation; either * +# * version 2.1 of the License, or (at your option) any later version. * +# * * +# * This library 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 * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with this library; if not, write to the Free Software * +# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * +# * 02110-1301 USA * +# * * +# *************************************************************************** + +import unittest +import os +import FreeCAD + +from AddonManagerRepo import AddonManagerRepo + +from addonmanager_utilities import ( + recognized_git_location, + get_readme_url, + get_assigned_string_literal, + get_macro_version_from_file, +) + + +class TestUtilities(unittest.TestCase): + + MODULE = "test_utilities" # file name without extension + + def setUp(self): + self.test_dir = os.path.join(FreeCAD.getHomePath(), "Mod", "AddonManager", "AddonManagerTest", "data") + + def test_recognized_git_location(self): + recognized_urls = [ + "https://github.com/FreeCAD/FreeCAD", + "https://gitlab.com/freecad/FreeCAD", + "https://framagit.org/freecad/FreeCAD", + "https://salsa.debian.org/science-team/freecad", + ] + for url in recognized_urls: + repo = AddonManagerRepo( + "Test Repo", url, AddonManagerRepo.UpdateStatus.NOT_INSTALLED, "branch" + ) + self.assertTrue( + recognized_git_location(repo), f"{url} was unexpectedly not recognized" + ) + + unrecognized_urls = [ + "https://google.com", + "https://freecad.org", + "https://not.quite.github.com/FreeCAD/FreeCAD", + "https://github.com.malware.com/", + ] + for url in unrecognized_urls: + repo = AddonManagerRepo( + "Test Repo", url, AddonManagerRepo.UpdateStatus.NOT_INSTALLED, "branch" + ) + self.assertFalse( + recognized_git_location(repo), f"{url} was unexpectedly recognized" + ) + + def test_get_readme_url(self): + github_urls = [ + "https://github.com/FreeCAD/FreeCAD", + ] + gitlab_urls = [ + "https://gitlab.com/freecad/FreeCAD", + "https://framagit.org/freecad/FreeCAD", + "https://salsa.debian.org/science-team/freecad", + "https://unknown.location/and/path", + ] + + # GitHub and Gitlab have two different schemes for file URLs: unrecognized URLs are + # presumed to be local instances of a GitLab server. Note that in neither case does this + # take into account the redirects that are used to actually fetch the data. + + for url in github_urls: + branch = "branchname" + expected_result = f"{url}/raw/{branch}/README.md" + repo = AddonManagerRepo( + "Test Repo", url, AddonManagerRepo.UpdateStatus.NOT_INSTALLED, branch + ) + actual_result = get_readme_url(repo) + self.assertEqual(actual_result, expected_result) + + for url in gitlab_urls: + branch = "branchname" + expected_result = f"{url}/-/raw/{branch}/README.md" + repo = AddonManagerRepo( + "Test Repo", url, AddonManagerRepo.UpdateStatus.NOT_INSTALLED, branch + ) + actual_result = get_readme_url(repo) + self.assertEqual(actual_result, expected_result) + + def test_get_assigned_string_literal(self): + good_lines = [ + ["my_var = 'Single-quoted literal'", "Single-quoted literal"], + ['my_var = "Double-quoted literal"', "Double-quoted literal"], + ["my_var = \t 'Extra whitespace'", "Extra whitespace"], + ["my_var = 42", "42"], + ["my_var = 1.23", "1.23"], + ] + for line in good_lines: + result = get_assigned_string_literal(line[0]) + self.assertEquals(result, line[1]) + + bad_lines = [ + "my_var = __date__", + "my_var 'No equals sign'", + "my_var = 'Unmatched quotes\"", + "my_var = No quotes at all", + "my_var = 1.2.3", + ] + for line in bad_lines: + result = get_assigned_string_literal(line) + self.assertIsNone(result) + + def test_get_macro_version_from_file(self): + good_file = os.path.join(self.test_dir, "good_macro_metadata.FCStd") + version = get_macro_version_from_file(good_file) + self.assertEqual(version, "1.2.3") + + bad_file = os.path.join(self.test_dir, "bad_macro_metadata.FCStd") + version = get_macro_version_from_file(bad_file) + self.assertEqual(version, "", "Bad version did not yield empty string") + + empty_file = os.path.join(self.test_dir, "missing_macro_metadata.FCStd") + version = get_macro_version_from_file(empty_file) + self.assertEqual(version, "", "Missing version did not yield empty string") \ No newline at end of file diff --git a/src/Mod/AddonManager/AddonManagerTest/data/__init__.py b/src/Mod/AddonManager/AddonManagerTest/data/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Mod/AddonManager/AddonManagerTest/data/bad_macro_metadata.FCStd b/src/Mod/AddonManager/AddonManagerTest/data/bad_macro_metadata.FCStd new file mode 100644 index 0000000000..12b1562194 --- /dev/null +++ b/src/Mod/AddonManager/AddonManagerTest/data/bad_macro_metadata.FCStd @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * Copyright (c) 2022 FreeCAD Project Association * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This library is free software; you can redistribute it and/or * +# * modify it under the terms of the GNU Lesser General Public * +# * License as published by the Free Software Foundation; either * +# * version 2.1 of the License, or (at your option) any later version. * +# * * +# * This library 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 * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with this library; if not, write to the Free Software * +# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * +# * 02110-1301 USA * +# * * +# *************************************************************************** + +__Title__ = "Test Macro' # Mismatched quotes +__Author__ = Chris Hennes # Not in quotes +__Version__ = 1.2.3 # Not in quotes and not a number +__Date__ = "2022-2-25 # Missing quote +__Comment__ = """For use with the FreeCAD unit test suite""" # Triple-quotes not allowed +__Web__ = "https://freecad.org" +__Wiki__ = "" +__Icon__ = "" +__Help__ = "" +__Status__ = "" +__Requires__ = "" +__Communication__ = "" +__Files__ = "" \ No newline at end of file diff --git a/src/Mod/AddonManager/AddonManagerTest/data/good_macro_metadata.FCStd b/src/Mod/AddonManager/AddonManagerTest/data/good_macro_metadata.FCStd new file mode 100644 index 0000000000..aa2955c197 --- /dev/null +++ b/src/Mod/AddonManager/AddonManagerTest/data/good_macro_metadata.FCStd @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * Copyright (c) 2022 FreeCAD Project Association * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This library is free software; you can redistribute it and/or * +# * modify it under the terms of the GNU Lesser General Public * +# * License as published by the Free Software Foundation; either * +# * version 2.1 of the License, or (at your option) any later version. * +# * * +# * This library 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 * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with this library; if not, write to the Free Software * +# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * +# * 02110-1301 USA * +# * * +# *************************************************************************** + +__Title__ = "Test Macro" +__Author__ = "Chris Hennes" +__Version__ = "1.2.3" +__Date__ = "2022-2-25" +__Comment__ = "For use with the FreeCAD unit test suite" +__Web__ = "https://freecad.org" +__Wiki__ = "" +__Icon__ = "" +__Help__ = "" +__Status__ = "" +__Requires__ = "" +__Communication__ = "" +__Files__ = "" \ No newline at end of file diff --git a/src/Mod/AddonManager/AddonManagerTest/data/missing_macro_metadata.FCStd b/src/Mod/AddonManager/AddonManagerTest/data/missing_macro_metadata.FCStd new file mode 100644 index 0000000000..e6a77399bb --- /dev/null +++ b/src/Mod/AddonManager/AddonManagerTest/data/missing_macro_metadata.FCStd @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * Copyright (c) 2022 FreeCAD Project Association * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This library is free software; you can redistribute it and/or * +# * modify it under the terms of the GNU Lesser General Public * +# * License as published by the Free Software Foundation; either * +# * version 2.1 of the License, or (at your option) any later version. * +# * * +# * This library 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 * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with this library; if not, write to the Free Software * +# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * +# * 02110-1301 USA * +# * * +# *************************************************************************** + +# This file contains no metadata \ No newline at end of file diff --git a/src/Mod/AddonManager/AddonManagerTest/gui/__init__.py b/src/Mod/AddonManager/AddonManagerTest/gui/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Mod/AddonManager/AddonManagerTest/gui/test_gui.py b/src/Mod/AddonManager/AddonManagerTest/gui/test_gui.py new file mode 100644 index 0000000000..bfc0676585 --- /dev/null +++ b/src/Mod/AddonManager/AddonManagerTest/gui/test_gui.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * Copyright (c) 2022 FreeCAD Project Association * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This library is free software; you can redistribute it and/or * +# * modify it under the terms of the GNU Lesser General Public * +# * License as published by the Free Software Foundation; either * +# * version 2.1 of the License, or (at your option) any later version. * +# * * +# * This library 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 * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with this library; if not, write to the Free Software * +# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * +# * 02110-1301 USA * +# * * +# *************************************************************************** + +import unittest +import FreeCAD + +class TestGui(unittest.TestCase): + + MODULE = 'test_gui' # file name without extension + + def setUp(self): + pass \ No newline at end of file diff --git a/src/Mod/AddonManager/AddonManagerTest/test_information.md b/src/Mod/AddonManager/AddonManagerTest/test_information.md new file mode 100644 index 0000000000..60d832127c --- /dev/null +++ b/src/Mod/AddonManager/AddonManagerTest/test_information.md @@ -0,0 +1,3 @@ +## Unit tests for the Addon Manager + +Data files are located in the data/ subdirectory. \ No newline at end of file diff --git a/src/Mod/AddonManager/CMakeLists.txt b/src/Mod/AddonManager/CMakeLists.txt index 4c24bfb158..dc7bb74ed4 100644 --- a/src/Mod/AddonManager/CMakeLists.txt +++ b/src/Mod/AddonManager/CMakeLists.txt @@ -23,16 +23,58 @@ SET(AddonManager_SRCS package_list.py package_details.py loading.html + TestAddonManagerApp.py ) +IF (BUILD_GUI) + LIST(APPEND AddonManager_SRCS TestAddonManagerGui.py) +ENDIF (BUILD_GUI) SOURCE_GROUP("" FILES ${AddonManager_SRCS}) +SET(AddonManagerTests_SRCS + AddonManagerTest/__init__.py + AddonManagerTest/test_information.md +) + +SET(AddonManagerTestsApp_SRCS + AddonManagerTest/app/__init__.py + AddonManagerTest/app/test_utilities.py +) + +SET(AddonManagerTestsGui_SRCS + AddonManagerTest/gui/__init__.py + AddonManagerTest/gui/test_gui.py +) + +SET(AddonManagerTestsFiles_SRCS + AddonManagerTest/data/__init__.py + AddonManagerTest/data/bad_macro_metadata.FCStd + AddonManagerTest/data/good_macro_metadata.FCStd + AddonManagerTest/data/missing_macro_metadata.FCStd +) + +SET(AddonManagerTests_ALL + ${AddonManagerTests_SRCS} + ${AddonManagerTestsApp_SRCS} + ${AddonManagerTestsFiles_SRCS} + ) + +IF (BUILD_GUI) + LIST(APPEND AddonManagerTests_ALL ${AddonManagerTestsGui_SRCS}) +ENDIF (BUILD_GUI) + ADD_CUSTOM_TARGET(AddonManager ALL SOURCES ${AddonManager_SRCS} ${AddonManager_QRC_SRCS} ) +ADD_CUSTOM_TARGET(AddonManagerTests ALL + SOURCES ${AddonManagerTests_ALL} +) + fc_copy_sources(AddonManager "${CMAKE_BINARY_DIR}/Mod/AddonManager" ${AddonManager_SRCS}) +fc_copy_sources(AddonManagerTests "${CMAKE_BINARY_DIR}/Mod/AddonManager" ${AddonManagerTests_ALL}) + IF (BUILD_GUI) fc_target_copy_resource(AddonManager ${CMAKE_CURRENT_BINARY_DIR} @@ -48,4 +90,7 @@ INSTALL( Mod/AddonManager ) - +INSTALL(FILES ${AddonManagerTests_SRCS} DESTINATION Mod/AddonManager/AddonManagerTest) +INSTALL(FILES ${AddonManagerTestsApp_SRCS} DESTINATION Mod/AddonManager/AddonManagerTest/app) +INSTALL(FILES ${AddonManagerTestsGui_SRCS} DESTINATION Mod/AddonManager/AddonManagerTest/gui) +INSTALL(FILES ${AddonManagerTestsFiles_SRCS} DESTINATION Mod/AddonManager/AddonManagerTest/data) diff --git a/src/Mod/AddonManager/Init.py b/src/Mod/AddonManager/Init.py index 86fc9fc2bf..5a1ad04997 100644 --- a/src/Mod/AddonManager/Init.py +++ b/src/Mod/AddonManager/Init.py @@ -2,3 +2,6 @@ # FreeCAD init script of the AddonManager module # (c) 2001 Juergen Riegel # License LGPL + +import FreeCAD +FreeCAD.__unit_test__ += ["TestAddonManagerApp"] \ No newline at end of file diff --git a/src/Mod/AddonManager/InitGui.py b/src/Mod/AddonManager/InitGui.py index 57650d3bb3..4436af989c 100644 --- a/src/Mod/AddonManager/InitGui.py +++ b/src/Mod/AddonManager/InitGui.py @@ -7,3 +7,6 @@ import AddonManager FreeCADGui.addLanguagePath(":/translations") FreeCADGui.addCommand("Std_AddonMgr", AddonManager.CommandAddonManager()) + +import FreeCAD +FreeCAD.__unit_test__ += ["TestAddonManagerGui"] \ No newline at end of file diff --git a/src/Mod/AddonManager/TestAddonManagerApp.py b/src/Mod/AddonManager/TestAddonManagerApp.py new file mode 100644 index 0000000000..1ab74a1421 --- /dev/null +++ b/src/Mod/AddonManager/TestAddonManagerApp.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * Copyright (c) 2022 FreeCAD Project Association * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This library is free software; you can redistribute it and/or * +# * modify it under the terms of the GNU Lesser General Public * +# * License as published by the Free Software Foundation; either * +# * version 2.1 of the License, or (at your option) any later version. * +# * * +# * This library 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 * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with this library; if not, write to the Free Software * +# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * +# * 02110-1301 USA * +# * * +# *************************************************************************** + +# Unit test for the Addon Manager module +from AddonManagerTest.app.test_utilities import TestUtilities as AddonManagerTestUtilities + +# dummy usage to get flake8 and lgtm quiet +False if AddonManagerTestUtilities.__name__ else True diff --git a/src/Mod/AddonManager/TestAddonManagerGui.py b/src/Mod/AddonManager/TestAddonManagerGui.py new file mode 100644 index 0000000000..6a7bb6b297 --- /dev/null +++ b/src/Mod/AddonManager/TestAddonManagerGui.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * Copyright (c) 2022 FreeCAD Project Association * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This library is free software; you can redistribute it and/or * +# * modify it under the terms of the GNU Lesser General Public * +# * License as published by the Free Software Foundation; either * +# * version 2.1 of the License, or (at your option) any later version. * +# * * +# * This library 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 * +# * Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Lesser General Public * +# * License along with this library; if not, write to the Free Software * +# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * +# * 02110-1301 USA * +# * * +# *************************************************************************** + +# Unit test for the Addon Manager module GUI +from AddonManagerTest.gui.test_gui import TestGui as AddonManagerTestGui + +# dummy usage to get flake8 and lgtm quiet +False if AddonManagerTestGui.__name__ else True