Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/controllers/scripting/controllerscriptenginebase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ void ControllerScriptEngineBase::registerPlayerManager(
ControllerScriptEngineBase::s_pPlayerManager = pPlayerManager;
}

#ifdef MIXXX_USE_QML
void ControllerScriptEngineBase::registerTrackCollectionManager(
std::shared_ptr<TrackCollectionManager> pTrackCollectionManager) {
s_pTrackCollectionManager = std::move(pTrackCollectionManager);
}

#ifdef MIXXX_USE_QML
void ControllerScriptEngineBase::handleQMLErrors(const QList<QQmlError>& qmlErrors) {
for (const QQmlError& error : std::as_const(qmlErrors)) {
showQMLExceptionDialog(error, m_bErrorsAreFatal);
Expand Down
7 changes: 2 additions & 5 deletions src/controllers/scripting/controllerscriptenginebase.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@

class Controller;
class QJSEngine;
#ifdef MIXXX_USE_QML
class TrackCollectionManager;
#endif

/// ControllerScriptEngineBase manages the JavaScript engine for controller scripts.
/// ControllerScriptModuleEngine implements the current system using JS modules.
Expand Down Expand Up @@ -59,10 +57,9 @@ class ControllerScriptEngineBase : public QObject {

static void registerPlayerManager(std::shared_ptr<PlayerManager> pPlayerManager);

#ifdef MIXXX_USE_QML
static void registerTrackCollectionManager(
std::shared_ptr<TrackCollectionManager> pTrackCollectionManager);
#endif

signals:
void beforeShutdown();

Expand Down Expand Up @@ -99,9 +96,9 @@ class ControllerScriptEngineBase : public QObject {

private:
static inline std::shared_ptr<PlayerManager> s_pPlayerManager;
#ifdef MIXXX_USE_QML
static inline std::shared_ptr<TrackCollectionManager> s_pTrackCollectionManager;

#ifdef MIXXX_USE_QML
protected:
/// Pause the GUI main thread. Pause is required by rendering
/// thread (https://doc.qt.io/qt-6/qquickrendercontrol.html#sync). This
Expand Down
23 changes: 10 additions & 13 deletions src/test/controller_mapping_validation_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@
#include "controllers/defs_controllers.h"
#include "controllers/scripting/legacy/controllerscriptenginelegacy.h"
#include "track/track.h"
#ifdef MIXXX_USE_QML
#include "effects/effectsmanager.h"
#include "engine/channelhandle.h"
#include "engine/enginemixer.h"
#include "library/coverartcache.h"
#include "library/library.h"
#include "mixer/playerinfo.h"
#include "mixer/playermanager.h"
#ifdef MIXXX_USE_QML
#include "qml/qmlplayermanagerproxy.h"
#include "soundio/soundmanager.h"
#endif
#include "moc_controller_mapping_validation_test.cpp"
#include "soundio/soundmanager.h"

FakeMidiControllerJSProxy::FakeMidiControllerJSProxy()
: ControllerJSProxy(nullptr) {
Expand Down Expand Up @@ -122,18 +122,10 @@ bool FakeController::isMappable() const {
return false;
}

#ifdef MIXXX_USE_QML
void deleteTrack(Track* pTrack) {
// Delete track objects directly in unit tests with
// no main event loop
delete pTrack;
};
#endif

void LegacyControllerMappingValidationTest::SetUp() {
m_mappingPath = getTestDir().filePath(QStringLiteral("../../res/controllers/"));
m_pEnumerator.reset(new MappingInfoEnumerator(QList<QString>{m_mappingPath.absolutePath()}));
#ifdef MIXXX_USE_QML

// This setup mirrors coreservices -- it would be nice if we could use coreservices instead
// but it does a lot of local disk / settings setup.
auto pChannelHandleFactory = std::make_shared<ChannelHandleFactory>();
Expand Down Expand Up @@ -165,7 +157,7 @@ void LegacyControllerMappingValidationTest::SetUp() {
nullptr,
m_pConfig,
dbConnectionPooler(),
deleteTrack);
[](Track* pTrack) { delete pTrack; });

m_pRecordingManager = std::make_shared<RecordingManager>(m_pConfig, m_pEngine.get());
CoverArtCache::createInstance();
Expand All @@ -178,16 +170,21 @@ void LegacyControllerMappingValidationTest::SetUp() {
m_pRecordingManager.get());

m_pPlayerManager->bindToLibrary(m_pLibrary.get());
#ifdef MIXXX_USE_QML
mixxx::qml::QmlPlayerManagerProxy::registerPlayerManager(m_pPlayerManager);
#endif
ControllerScriptEngineBase::registerPlayerManager(m_pPlayerManager);
ControllerScriptEngineBase::registerTrackCollectionManager(m_pTrackCollectionManager);
}

void LegacyControllerMappingValidationTest::TearDown() {
PlayerInfo::destroy();
CoverArtCache::destroy();
#ifdef MIXXX_USE_QML
mixxx::qml::QmlPlayerManagerProxy::registerPlayerManager(nullptr);
ControllerScriptEngineBase::registerTrackCollectionManager(nullptr);
#endif
ControllerScriptEngineBase::registerPlayerManager(nullptr);
ControllerScriptEngineBase::registerTrackCollectionManager(nullptr);
}

bool LegacyControllerMappingValidationTest::testLoadMapping(const MappingInfo& mapping) {
Expand Down
3 changes: 0 additions & 3 deletions src/test/controller_mapping_validation_test.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include <QObject>

#include "control/controlindicatortimer.h"
#include "controllers/controller.h"
#include "controllers/controllermappinginfoenumerator.h"
Expand Down Expand Up @@ -222,7 +221,6 @@ class LegacyControllerMappingValidationTest : public MixxxDbTest, SoundSourcePro

protected:
void SetUp() override;
#ifdef MIXXX_USE_QML
void TearDown() override;

TrackPointer getOrAddTrackByLocation(
Expand All @@ -239,7 +237,6 @@ class LegacyControllerMappingValidationTest : public MixxxDbTest, SoundSourcePro
std::shared_ptr<TrackCollectionManager> m_pTrackCollectionManager;
std::shared_ptr<RecordingManager> m_pRecordingManager;
std::shared_ptr<Library> m_pLibrary;
#endif

bool testLoadMapping(const MappingInfo& mapping);

Expand Down
98 changes: 97 additions & 1 deletion src/test/controllerscriptenginelegacy_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@
#include "test/mixxxtest.h"
#include "util/color/colorpalette.h"
#include "util/time.h"
#include "track/track.h"
#include "sources/soundsourceproxy.h"
#include "control/controlindicatortimer.h"
#include "database/mixxxdb.h"
#include "test/mixxxdbtest.h"
#include "test/soundsourceproviderregistration.h"
#include "effects/effectsmanager.h"
#include "engine/enginemixer.h"
#include "library/coverartcache.h"
#include "soundio/soundmanager.h"
#include "library/trackcollectionmanager.h"
#include "mixer/playerinfo.h"
#include "mixer/playermanager.h"
#include "recording/recordingmanager.h"
#include "library/library.h"
#include "engine/channelhandle.h"

using ::testing::_;
using namespace std::chrono_literals;
Expand All @@ -38,7 +54,7 @@ typedef std::unique_ptr<QTemporaryFile> ScopedTemporaryFile;

const RuntimeLoggingCategory logger(QString("test").toLocal8Bit());

class ControllerScriptEngineLegacyTest : public ControllerScriptEngineLegacy, public MixxxTest {
class ControllerScriptEngineLegacyTest : public ControllerScriptEngineLegacy, public MixxxDbTest, SoundSourceProviderRegistration {
protected:
ControllerScriptEngineLegacyTest()
: ControllerScriptEngineLegacy(nullptr, logger) {
Expand All @@ -57,13 +73,84 @@ class ControllerScriptEngineLegacyTest : public ControllerScriptEngineLegacy, pu
mixxx::Time::addTestTime(10ms);
QThread::currentThread()->setObjectName("Main");
initialize();

// This setup mirrors coreservices -- it would be nice if we could use coreservices instead
// but it does a lot of local disk / settings setup.
auto pChannelHandleFactory = std::make_shared<ChannelHandleFactory>();
m_pEffectsManager = std::make_shared<EffectsManager>(config(), pChannelHandleFactory);
m_pEngine = std::make_shared<EngineMixer>(
config(),
"[Master]",
m_pEffectsManager.get(),
pChannelHandleFactory,
true);
m_pSoundManager = std::make_shared<SoundManager>(config(), m_pEngine.get());
m_pControlIndicatorTimer = std::make_shared<mixxx::ControlIndicatorTimer>(nullptr);
m_pEngine->registerNonEngineChannelSoundIO(gsl::make_not_null(m_pSoundManager.get()));

CoverArtCache::createInstance();

m_pPlayerManager = std::make_shared<PlayerManager>(config(),
m_pSoundManager.get(),
m_pEffectsManager.get(),
m_pEngine.get());

m_pPlayerManager->addConfiguredDecks();
m_pPlayerManager->addSampler();
PlayerInfo::create();
m_pEffectsManager->setup();

const auto dbConnection = mixxx::DbConnectionPooled(dbConnectionPooler());
if (!MixxxDb::initDatabaseSchema(dbConnection)) {
exit(1);
}

m_pTrackCollectionManager = std::make_shared<TrackCollectionManager>(
nullptr,
config(),
dbConnectionPooler(),
[](Track* pTrack) { delete pTrack; });

m_pRecordingManager = std::make_shared<RecordingManager>(config(), m_pEngine.get());
m_pLibrary = std::make_shared<Library>(
nullptr,
config(),
dbConnectionPooler(),
m_pTrackCollectionManager.get(),
m_pPlayerManager.get(),
m_pRecordingManager.get());

m_pPlayerManager->bindToLibrary(m_pLibrary.get());
ControllerScriptEngineBase::registerPlayerManager(m_pPlayerManager);
ControllerScriptEngineBase::registerTrackCollectionManager(m_pTrackCollectionManager);
}

// Helper to get or add a track by location, like in PlayerManagerTest
TrackPointer getOrAddTrackByLocation(const QString& trackLocation) {
return m_pTrackCollectionManager->getOrAddTrack(
TrackRef::fromFilePath(trackLocation));
}
void TearDown() override {
mixxx::Time::setTestMode(false);
#ifdef MIXXX_USE_QML
m_rootItems.clear();
#endif
CoverArtCache::destroy();
ControllerScriptEngineBase::registerPlayerManager(nullptr);
ControllerScriptEngineBase::registerTrackCollectionManager(nullptr);
}

~ControllerScriptEngineLegacyTest() {
// Reset in the correct order to avoid singleton destruction issues
m_pSoundManager.reset();
Comment on lines 133 to +145
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if you can have both TearDown and a dtor in a test. I guess if so teardown gets called first?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same as in other tests. TearDown() is called by GTest after each test case and if an error happens in TearDown(), GTest will flag the test as fail. I tested this code, it is working!

m_pPlayerManager.reset();
PlayerInfo::destroy();
m_pLibrary.reset();
m_pRecordingManager.reset();
m_pEngine.reset();
m_pEffectsManager.reset();
m_pTrackCollectionManager.reset();
m_pControlIndicatorTimer.reset();
}

bool evaluateScriptFile(const QFileInfo& scriptFile) {
Expand Down Expand Up @@ -107,6 +194,15 @@ class ControllerScriptEngineLegacyTest : public ControllerScriptEngineLegacy, pu
handleScreenFrame(screeninfo, frame, timestamp);
}
#endif

std::shared_ptr<EffectsManager> m_pEffectsManager;
std::shared_ptr<EngineMixer> m_pEngine;
std::shared_ptr<SoundManager> m_pSoundManager;
std::shared_ptr<mixxx::ControlIndicatorTimer> m_pControlIndicatorTimer;
std::shared_ptr<PlayerManager> m_pPlayerManager;
std::shared_ptr<RecordingManager> m_pRecordingManager;
std::shared_ptr<Library> m_pLibrary;
std::shared_ptr<TrackCollectionManager> m_pTrackCollectionManager;
};

TEST_F(ControllerScriptEngineLegacyTest, commonScriptHasNoErrors) {
Expand Down