-
Notifications
You must be signed in to change notification settings - Fork 3.1k
add workspace manager unit tests #32861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| /* | ||
| * SPDX-License-Identifier: GPL-3.0-only | ||
| * MuseScore-CLA-applies | ||
| * | ||
| * MuseScore | ||
| * Music Composition & Notation | ||
| * | ||
| * Copyright (C) 2026 MuseScore Limited and others | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License version 3 as | ||
| * published by the Free Software Foundation. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
| */ | ||
| #pragma once | ||
|
|
||
| #include <gmock/gmock.h> | ||
|
|
||
| #include "multiwindows/imultiwindowsprovider.h" | ||
|
|
||
| namespace muse::mi { | ||
| class MultiWindowsProviderMock : public IMultiWindowsProvider | ||
| { | ||
| public: | ||
| MOCK_METHOD(size_t, windowCount, (), (const, override)); | ||
| MOCK_METHOD(bool, isFirstWindow, (), (const, override)); | ||
| MOCK_METHOD(bool, isProjectAlreadyOpened, (const io::path_t&), (const, override)); | ||
| MOCK_METHOD(void, activateWindowWithProject, (const io::path_t&), (override)); | ||
| MOCK_METHOD(bool, isHasWindowWithoutProject, (), (const, override)); | ||
| MOCK_METHOD(void, activateWindowWithoutProject, (const QStringList&), (override)); | ||
| MOCK_METHOD(bool, openNewWindow, (const QStringList&), (override)); | ||
| MOCK_METHOD(bool, isPreferencesAlreadyOpened, (), (const, override)); | ||
| MOCK_METHOD(void, activateWindowWithOpenedPreferences, (), (const, override)); | ||
| MOCK_METHOD(void, settingsBeginTransaction, (), (override)); | ||
| MOCK_METHOD(void, settingsCommitTransaction, (), (override)); | ||
| MOCK_METHOD(void, settingsRollbackTransaction, (), (override)); | ||
| MOCK_METHOD(void, settingsReset, (), (override)); | ||
| MOCK_METHOD(void, settingsSetValue, (const std::string&, const Val&), (override)); | ||
| MOCK_METHOD(bool, lockResource, (const std::string&), (override)); | ||
| MOCK_METHOD(bool, unlockResource, (const std::string&), (override)); | ||
| MOCK_METHOD(void, notifyAboutResourceChanged, (const std::string&), (override)); | ||
| MOCK_METHOD(async::Channel<std::string>, resourceChanged, (), (override)); | ||
| MOCK_METHOD(void, notifyAboutWindowWasQuited, (), (override)); | ||
| MOCK_METHOD(void, quitForAll, (), (override)); | ||
| MOCK_METHOD(void, quitWindow, (const modularity::ContextPtr&), (override)); | ||
| MOCK_METHOD(void, quitAllAndRestartLast, (), (override)); | ||
| MOCK_METHOD(void, quitAllAndRunInstallation, (const io::path_t&), (override)); | ||
| }; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # SPDX-License-Identifier: GPL-3.0-only | ||
| # MuseScore-CLA-applies | ||
| # | ||
| # MuseScore | ||
| # Music Composition & Notation | ||
| # | ||
| # Copyright (C) 2026 MuseScore Limited and others | ||
| # | ||
| # This program is free software: you can redistribute it and/or modify | ||
| # it under the terms of the GNU General Public License version 3 as | ||
| # published by the Free Software Foundation. | ||
| # | ||
| # This program is distributed in the hope that it will be useful, | ||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| # GNU General Public License for more details. | ||
| # | ||
| # You should have received a copy of the GNU General Public License | ||
| # along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
|
|
||
| set(MODULE_TEST muse_workspace_tests) | ||
|
|
||
| set(MODULE_TEST_SRC | ||
luapmartin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ${CMAKE_CURRENT_LIST_DIR}/mocks/workspaceconfigurationmock.h | ||
| ${MUSE_FRAMEWORK_SRC_PATH}/multiwindows/tests/mocks/multiwindowsprovidermock.h | ||
| ${CMAKE_CURRENT_LIST_DIR}/environment.cpp | ||
| ${CMAKE_CURRENT_LIST_DIR}/workspacemanager_tests.cpp | ||
| ) | ||
|
|
||
| set(MODULE_TEST_LINK | ||
| muse::workspace | ||
| ) | ||
|
|
||
| set(MODULE_TEST_INCLUDE | ||
| ${MUSE_FRAMEWORK_SRC_PATH}/workspace | ||
| ${MUSE_FRAMEWORK_SRC_PATH}/workspace/internal | ||
| ${MUSE_FRAMEWORK_SRC_PATH}/multiwindows | ||
| ) | ||
|
|
||
| set(MODULE_TEST_DEF | ||
| BUILTIN_WORKSPACES_DIR="${CMAKE_SOURCE_DIR}/share/workspaces" | ||
| ) | ||
|
|
||
| include(SetupGTest) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| /* | ||
| * SPDX-License-Identifier: GPL-3.0-only | ||
| * MuseScore-CLA-applies | ||
| * | ||
| * MuseScore | ||
| * Music Composition & Notation | ||
| * | ||
| * Copyright (C) 2026 MuseScore Limited and others | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License version 3 as | ||
| * published by the Free Software Foundation. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
||
| #include "testing/environment.h" | ||
|
|
||
| #include "workspace/tests/mocks/workspaceconfigurationmock.h" | ||
|
|
||
| using namespace ::testing; | ||
|
|
||
| static muse::testing::SuiteEnvironment workspace_se | ||
| = muse::testing::SuiteEnvironment() | ||
| .setPreInit([](){ | ||
| auto workspaceConfig = std::make_shared<::testing::NiceMock<muse::workspace::WorkspaceConfigurationMock> >(); | ||
|
|
||
| ON_CALL(*workspaceConfig, defaultWorkspaceName()) | ||
| .WillByDefault(Return("Default")); | ||
|
|
||
| muse::modularity::globalIoc()->registerExport<muse::workspace::IWorkspaceConfiguration>("utests", workspaceConfig); | ||
| }).setDeInit([](){ | ||
| muse::modularity::globalIoc()->unregister<muse::workspace::IWorkspaceConfiguration>("utests"); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| /* | ||
| * SPDX-License-Identifier: GPL-3.0-only | ||
| * MuseScore-CLA-applies | ||
| * | ||
| * MuseScore | ||
| * Music Composition & Notation | ||
| * | ||
| * Copyright (C) 2026 MuseScore Limited and others | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License version 3 as | ||
| * published by the Free Software Foundation. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
| */ | ||
| #pragma once | ||
|
|
||
| #include <gmock/gmock.h> | ||
|
|
||
| #include "workspace/iworkspaceconfiguration.h" | ||
|
|
||
| namespace muse::workspace { | ||
| class WorkspaceConfigurationMock : public IWorkspaceConfiguration | ||
| { | ||
| public: | ||
| MOCK_METHOD(io::paths_t, workspacePaths, (), (const, override)); | ||
| MOCK_METHOD(io::paths_t, builtinWorkspacesFilePaths, (), (const, override)); | ||
| MOCK_METHOD(io::path_t, userWorkspacesPath, (), (const, override)); | ||
| MOCK_METHOD(std::string, defaultWorkspaceName, (), (const, override)); | ||
| MOCK_METHOD(std::string, currentWorkspaceName, (), (const, override)); | ||
| MOCK_METHOD(void, setCurrentWorkspaceName, (const std::string&), (override)); | ||
| MOCK_METHOD(async::Channel<std::string>, currentWorkspaceNameChanged, (), (const, override)); | ||
| }; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| /* | ||
| * SPDX-License-Identifier: GPL-3.0-only | ||
| * MuseScore-CLA-applies | ||
| * | ||
| * MuseScore | ||
| * Music Composition & Notation | ||
| * | ||
| * Copyright (C) 2026 MuseScore Limited and others | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License version 3 as | ||
| * published by the Free Software Foundation. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
| */ | ||
| #include <gtest/gtest.h> | ||
| #include <gmock/gmock.h> | ||
|
|
||
| #include <QTemporaryDir> | ||
|
|
||
| #include "modularity/ioc.h" | ||
| #include "workspace/internal/workspacemanager.h" | ||
| #include "workspace/iworkspaceconfiguration.h" | ||
| #include "workspace/tests/mocks/workspaceconfigurationmock.h" | ||
| #include "multiwindows/tests/mocks/multiwindowsprovidermock.h" | ||
|
|
||
| using ::testing::Return; | ||
|
|
||
| using namespace muse; | ||
| using namespace muse::workspace; | ||
|
|
||
| static const std::string BUILTIN_WORKSPACE_DIR = BUILTIN_WORKSPACES_DIR; | ||
|
|
||
| namespace muse::workspace { | ||
| class Workspace_WorkspaceManagerTests : public ::testing::Test | ||
| { | ||
| public: | ||
| void SetUp() override | ||
| { | ||
| m_userWorkspacesDir = std::make_unique<QTemporaryDir>(); | ||
| ASSERT_TRUE(m_userWorkspacesDir->isValid()); | ||
|
|
||
| m_multiWindowsProvider = std::make_shared<::testing::NiceMock<mi::MultiWindowsProviderMock> >(); | ||
| modularity::globalIoc()->registerExport<mi::IMultiWindowsProvider>("utests", m_multiWindowsProvider); | ||
|
|
||
| m_workspaceConfig = std::dynamic_pointer_cast<muse::workspace::WorkspaceConfigurationMock>( | ||
| modularity::globalIoc()->resolve<IWorkspaceConfiguration>("utests")); | ||
| ASSERT_NE(m_workspaceConfig, nullptr); | ||
|
|
||
| m_userWorkspacesPath = m_userWorkspacesDir->path().toStdString(); | ||
| } | ||
|
|
||
| void TearDown() override | ||
| { | ||
| m_manager.reset(); | ||
| modularity::globalIoc()->unregister<mi::IMultiWindowsProvider>("utests"); | ||
| } | ||
|
Comment on lines
+59
to
+63
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move manager deinitialization into Right now cleanup depends on reaching the end of each test body. A fatal assertion can skip Proposed fix void TearDown() override
{
- m_manager.reset();
+ if (m_manager) {
+ m_manager->deinit();
+ m_manager.reset();
+ }
modularity::globalIoc()->unregister<mi::IMultiWindowsProvider>("utests");
}
@@
- m_manager->deinit();
}
@@
- m_manager->deinit();
}
@@
- m_manager->deinit();
}Also applies to: 118-119, 143-144, 169-170 |
||
|
|
||
| void setupBuiltinPaths(const std::vector<std::string>& filenames) | ||
| { | ||
| io::paths_t paths; | ||
| for (const auto& name : filenames) { | ||
| paths.push_back(io::path_t(BUILTIN_WORKSPACE_DIR + "/" + name)); | ||
| } | ||
|
|
||
| ON_CALL(*m_workspaceConfig, builtinWorkspacesFilePaths()) | ||
| .WillByDefault(Return(paths)); | ||
|
|
||
| ON_CALL(*m_workspaceConfig, userWorkspacesPath()) | ||
| .WillByDefault(Return(io::path_t(m_userWorkspacesPath))); | ||
| } | ||
|
|
||
| void initManager() | ||
| { | ||
| m_manager = std::make_unique<WorkspaceManager>(modularity::globalCtx()); | ||
| m_manager->init(); | ||
| } | ||
|
|
||
| protected: | ||
| std::unique_ptr<QTemporaryDir> m_userWorkspacesDir; | ||
| std::string m_userWorkspacesPath; | ||
|
|
||
| std::shared_ptr<::testing::NiceMock<mi::MultiWindowsProviderMock> > m_multiWindowsProvider; | ||
| std::shared_ptr<muse::workspace::WorkspaceConfigurationMock> m_workspaceConfig; | ||
|
|
||
| std::unique_ptr<WorkspaceManager> m_manager; | ||
| }; | ||
|
|
||
| TEST_F(Workspace_WorkspaceManagerTests, BuiltinWorkspaceLoadsOnInit) | ||
| { | ||
| //! [GIVEN] Builtin workspace file exists | ||
| setupBuiltinPaths({ "Default.mws" }); | ||
|
|
||
| //! [GIVEN] Current workspace is "Default" | ||
| ON_CALL(*m_workspaceConfig, currentWorkspaceName()) | ||
| .WillByDefault(Return("Default")); | ||
|
|
||
| //! [WHEN] WorkspaceManager is initialized | ||
| initManager(); | ||
|
|
||
| //! [THEN] Default workspace is loaded | ||
| EXPECT_NE(m_manager->defaultWorkspace(), nullptr); | ||
| EXPECT_EQ(m_manager->defaultWorkspace()->name(), "Default"); | ||
|
|
||
| //! [THEN] Current workspace matches default | ||
| EXPECT_NE(m_manager->currentWorkspace(), nullptr); | ||
| EXPECT_EQ(m_manager->currentWorkspace()->name(), "Default"); | ||
|
|
||
| //! [THEN] Builtin workspace is available | ||
| EXPECT_EQ(m_manager->workspaces().size(), 1); | ||
|
|
||
| m_manager->deinit(); | ||
| } | ||
|
|
||
| TEST_F(Workspace_WorkspaceManagerTests, FallbackToDefaultOnMissingCurrentWorkspace) | ||
| { | ||
| //! [GIVEN] Builtin workspace file exists | ||
| setupBuiltinPaths({ "Default.mws" }); | ||
|
|
||
| //! [GIVEN] Current workspace name references a workspace that no longer exists | ||
| ON_CALL(*m_workspaceConfig, currentWorkspaceName()) | ||
| .WillByDefault(Return("MyDeletedWorkspace")); | ||
|
|
||
| //! [GIVEN] Manager will correct the setting to default | ||
| EXPECT_CALL(*m_workspaceConfig, setCurrentWorkspaceName("Default")) | ||
| .Times(1); | ||
|
|
||
| //! [WHEN] WorkspaceManager is initialized | ||
| initManager(); | ||
|
|
||
| //! [THEN] Falls back to default workspace | ||
| EXPECT_NE(m_manager->currentWorkspace(), nullptr); | ||
| EXPECT_EQ(m_manager->currentWorkspace()->name(), "Default"); | ||
| EXPECT_NE(m_manager->defaultWorkspace(), nullptr); | ||
| EXPECT_EQ(m_manager->defaultWorkspace()->name(), "Default"); | ||
|
|
||
| m_manager->deinit(); | ||
| } | ||
|
|
||
| TEST_F(Workspace_WorkspaceManagerTests, EmptyUserDirUsesBuiltinWorkspaces) | ||
| { | ||
| //! [GIVEN] Builtin workspace file exists, user dir is empty | ||
| setupBuiltinPaths({ "Default.mws" }); | ||
|
|
||
| ON_CALL(*m_workspaceConfig, currentWorkspaceName()) | ||
| .WillByDefault(Return("Default")); | ||
|
|
||
| //! [WHEN] WorkspaceManager is initialized | ||
| initManager(); | ||
|
|
||
| //! [THEN] Workspaces are loaded from builtins only | ||
| EXPECT_EQ(m_manager->workspaces().size(), 1); | ||
|
|
||
| //! [THEN] Current workspace is loaded and usable | ||
| auto current = m_manager->currentWorkspace(); | ||
| ASSERT_NE(current, nullptr); | ||
| EXPECT_EQ(current->name(), "Default"); | ||
|
|
||
| //! [THEN] Reading workspace data does not crash | ||
| auto data = current->rawData("ui_settings"); | ||
| EXPECT_TRUE(data.ret); | ||
|
|
||
| m_manager->deinit(); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: musescore/MuseScore
Length of output: 350
Add or declare the
MUSE_MODULE_WORKSPACE_TESTStoggle before use.The variable
MUSE_MODULE_WORKSPACE_TESTSis checked at line 57 but is never declared or set anywhere in the codebase. In CMake, undefined variables evaluate to false in conditionals, which means the tests directory will never be included regardless of intent. Either remove this check if tests are always needed, or declare the option/variable (e.g.,option(MUSE_MODULE_WORKSPACE_TESTS "Enable workspace tests" OFF)) in the parent CMakeLists.txt or cmake configuration.