diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9a9627c9e..b46357b2f 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,7 +23,6 @@ RotationGizmo.cpp TranslationGizmo.cpp ScaleGizmo.cpp TransformOperator.cpp -TransformWidget.cpp PrimitivesWidget.cpp PrimitiveObject.cpp ViewportGrid.cpp @@ -84,7 +83,6 @@ RotationGizmo.h TranslationGizmo.h ScaleGizmo.h TransformOperator.h -TransformWidget.h PrimitivesWidget.h PrimitiveObject.h ViewportGrid.h @@ -446,6 +444,20 @@ if(BUILD_TESTS) # find them. The app bundle has these in Contents/MacOS/ via INSTALL # commands, but UnitTests is a plain executable — not a bundle. gtest_discover_tests(UnitTests) + + # Copy RTSS shader resources to the UnitTests binary directory so that + # RTSSResourcesTest can find them without requiring cmake --install. + # The test looks for media/RTShaderLib/ and media/Main/ relative to + # applicationDirPath(). + add_custom_command(TARGET UnitTests POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_SOURCE_DIR}/media/RTShaderLib + $/media/RTShaderLib + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_SOURCE_DIR}/media/Main + $/media/Main + COMMENT "Copying RTSS shader resources to test binary directory" + ) endif() diff --git a/src/LLMManager_test.cpp b/src/LLMManager_test.cpp index f9f97d0af..306f26536 100644 --- a/src/LLMManager_test.cpp +++ b/src/LLMManager_test.cpp @@ -559,31 +559,44 @@ TEST_F(LLMManagerTest, GetAndSetSettingsStruct) // Settings save/load persistence tests // ============================================================================= -// DISABLED: QSettings caching on macOS causes loadSettings() to not reflect saveSettings() within same process -TEST_F(LLMManagerTest, DISABLED_SaveAndLoadSettingsPersistence) +// Fixed: the original test was flawed because each setter (setContextSize etc.) +// internally calls saveSettings(), so modifying in-memory values also overwrote +// the saved values. The fix: write known values to QSettings directly, then +// verify loadSettings() reads them back correctly. +TEST_F(LLMManagerTest, SaveAndLoadSettingsPersistence) { - // Save known values + // Remember original values to restore later int origCtx = manager->contextSize(); int origMax = manager->maxTokens(); float origTemp = manager->temperature(); int origGpu = manager->gpuLayers(); bool origAuto = manager->autoLoadModel(); - manager->setContextSize(1024); - manager->setMaxTokens(512); - manager->setTemperature(0.9f); - manager->setGpuLayers(8); - manager->setAutoLoadModel(true); - manager->saveSettings(); - - // Now modify in-memory values - manager->setContextSize(9999); - manager->setMaxTokens(9999); - manager->setTemperature(0.1f); - manager->setGpuLayers(1); - manager->setAutoLoadModel(false); + // Write known test values directly to QSettings (bypassing the setters + // which would also update in-memory state via saveSettings()) + { + QSettings settings; + settings.beginGroup("LLM"); + settings.setValue("contextSize", 1024); + settings.setValue("maxTokens", 512); + settings.setValue("temperature", 0.9); + settings.setValue("gpuLayers", 8); + settings.setValue("autoLoadModel", true); + settings.endGroup(); + settings.sync(); + } - // Reload from storage + // Set different in-memory values (use the internal settings struct directly + // is not possible via public API, so we just verify loadSettings overrides) + // First, put different values in memory by using setters. The setters will + // call saveSettings() which overwrites our QSettings values, so we need to + // re-write QSettings afterwards. + // Simpler approach: just call loadSettings() now and verify it reads the + // QSettings values we wrote above. + // But setters already called saveSettings with the original values... + // The cleanest approach: write to QSettings, then loadSettings(). + + // Load from the QSettings we just wrote manager->loadSettings(); EXPECT_EQ(manager->contextSize(), 1024); @@ -592,13 +605,29 @@ TEST_F(LLMManagerTest, DISABLED_SaveAndLoadSettingsPersistence) EXPECT_EQ(manager->gpuLayers(), 8); EXPECT_EQ(manager->autoLoadModel(), true); + // Now test the reverse direction: use setters (which call saveSettings), + // then loadSettings() should get those same values back. + manager->setContextSize(2048); + manager->setMaxTokens(1024); + manager->setTemperature(0.5f); + manager->setGpuLayers(4); + manager->setAutoLoadModel(false); + + // Reload from storage — should match what the setters saved + manager->loadSettings(); + + EXPECT_EQ(manager->contextSize(), 2048); + EXPECT_EQ(manager->maxTokens(), 1024); + EXPECT_FLOAT_EQ(manager->temperature(), 0.5f); + EXPECT_EQ(manager->gpuLayers(), 4); + EXPECT_EQ(manager->autoLoadModel(), false); + // Restore originals manager->setContextSize(origCtx); manager->setMaxTokens(origMax); manager->setTemperature(origTemp); manager->setGpuLayers(origGpu); manager->setAutoLoadModel(origAuto); - manager->saveSettings(); } // ============================================================================= diff --git a/src/ModelDownloader_test.cpp b/src/ModelDownloader_test.cpp index 6cf44e37a..5e3ba153a 100644 --- a/src/ModelDownloader_test.cpp +++ b/src/ModelDownloader_test.cpp @@ -77,11 +77,11 @@ TEST_F(ModelDownloaderTest, InitialModelNameIsEmpty) { } // --- startDownload state transitions --- -// DISABLED: startDownload triggers real network I/O via QNetworkAccessManager on a singleton, -// which causes segfaults during processEvents/cancelDownload cleanup on macOS. -// These tests may work on Linux CI where the singleton lifecycle is more predictable. +// Re-enabled: these tests use real network I/O but are safe on Linux CI where +// the singleton lifecycle is predictable. On macOS, processEvents cleanup was +// the issue but these pass reliably on Linux with Xvfb. -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadSetsIsDownloading) { +TEST_F(ModelDownloaderTest, StartDownloadSetsIsDownloading) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -90,7 +90,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadSetsIsDownloading) { EXPECT_TRUE(downloader->isDownloading()); } -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadSetsModelName) { +TEST_F(ModelDownloaderTest, StartDownloadSetsModelName) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "MyModel"); @@ -99,7 +99,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadSetsModelName) { EXPECT_EQ(downloader->currentModelName(), "MyModel"); } -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadEmitsIsDownloadingChanged) { +TEST_F(ModelDownloaderTest, StartDownloadEmitsIsDownloadingChanged) { QSignalSpy spy(downloader, &ModelDownloader::isDownloadingChanged); QString dest = tempFilePath("test_model.gguf"); @@ -109,7 +109,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadEmitsIsDownloadingChanged) { EXPECT_GE(spy.count(), 1); } -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadEmitsCurrentModelNameChanged) { +TEST_F(ModelDownloaderTest, StartDownloadEmitsCurrentModelNameChanged) { QSignalSpy spy(downloader, &ModelDownloader::currentModelNameChanged); QString dest = tempFilePath("test_model.gguf"); @@ -119,7 +119,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadEmitsCurrentModelNameChanged) EXPECT_GE(spy.count(), 1); } -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadEmitsDownloadStarted) { +TEST_F(ModelDownloaderTest, StartDownloadEmitsDownloadStarted) { QSignalSpy spy(downloader, &ModelDownloader::downloadStarted); QString dest = tempFilePath("test_model.gguf"); @@ -130,7 +130,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadEmitsDownloadStarted) { EXPECT_EQ(spy.at(0).at(0).toString(), "TestModel"); } -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadResetsProgress) { +TEST_F(ModelDownloaderTest, StartDownloadResetsProgress) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -143,7 +143,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadResetsProgress) { // --- Duplicate download rejection --- -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadWhileAlreadyDownloadingEmitsError) { +TEST_F(ModelDownloaderTest, StartDownloadWhileAlreadyDownloadingEmitsError) { QString dest1 = tempFilePath("model1.gguf"); QString dest2 = tempFilePath("model2.gguf"); @@ -160,7 +160,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadWhileAlreadyDownloadingEmitsEr EXPECT_TRUE(errorSpy.at(0).at(1).toString().contains("already in progress")); } -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadWhileAlreadyDownloadingDoesNotChangeModel) { +TEST_F(ModelDownloaderTest, StartDownloadWhileAlreadyDownloadingDoesNotChangeModel) { QString dest1 = tempFilePath("model1.gguf"); QString dest2 = tempFilePath("model2.gguf"); @@ -176,7 +176,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadWhileAlreadyDownloadingDoesNot // --- Temp file path construction --- -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadCreatesTempPartFile) { +TEST_F(ModelDownloaderTest, StartDownloadCreatesTempPartFile) { QString dest = tempFilePath("test_model.gguf"); QString expectedTempFile = dest + ".part"; @@ -188,7 +188,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadCreatesTempPartFile) { // --- Directory creation --- -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadCreatesDestinationDirectory) { +TEST_F(ModelDownloaderTest, StartDownloadCreatesDestinationDirectory) { QString nestedDir = tempDir.path() + "/nested/deep/dir"; QString dest = nestedDir + "/model.gguf"; @@ -200,7 +200,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadCreatesDestinationDirectory) { // --- cancelDownload --- -TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadResetsIsDownloading) { +TEST_F(ModelDownloaderTest, CancelDownloadResetsIsDownloading) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -213,7 +213,7 @@ TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadResetsIsDownloading) { EXPECT_FALSE(downloader->isDownloading()); } -TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadClearsModelName) { +TEST_F(ModelDownloaderTest, CancelDownloadClearsModelName) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -225,7 +225,7 @@ TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadClearsModelName) { EXPECT_TRUE(downloader->currentModelName().isEmpty()); } -TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadResetsBytesReceived) { +TEST_F(ModelDownloaderTest, CancelDownloadResetsBytesReceived) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -238,7 +238,7 @@ TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadResetsBytesReceived) { EXPECT_EQ(downloader->bytesTotal(), 0); } -TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadResetsProgress) { +TEST_F(ModelDownloaderTest, CancelDownloadResetsProgress) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -250,7 +250,7 @@ TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadResetsProgress) { EXPECT_FLOAT_EQ(downloader->downloadProgress(), 0.0f); } -TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadResetsSpeed) { +TEST_F(ModelDownloaderTest, CancelDownloadResetsSpeed) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -262,7 +262,7 @@ TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadResetsSpeed) { EXPECT_FLOAT_EQ(downloader->downloadSpeed(), 0.0f); } -TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadRemovesTempFile) { +TEST_F(ModelDownloaderTest, CancelDownloadRemovesTempFile) { QString dest = tempFilePath("test_model.gguf"); QString tempFile = dest + ".part"; @@ -276,7 +276,7 @@ TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadRemovesTempFile) { EXPECT_FALSE(QFile::exists(tempFile)); } -TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadEmitsDownloadCanceled) { +TEST_F(ModelDownloaderTest, CancelDownloadEmitsDownloadCanceled) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -291,7 +291,7 @@ TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadEmitsDownloadCanceled) { EXPECT_EQ(spy.at(0).at(0).toString(), "TestModel"); } -TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadEmitsIsDownloadingChanged) { +TEST_F(ModelDownloaderTest, CancelDownloadEmitsIsDownloadingChanged) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -317,7 +317,7 @@ TEST_F(ModelDownloaderTest, CancelDownloadWhenNotDownloadingDoesNotEmitCanceled) // --- pauseDownload --- -TEST_F(ModelDownloaderTest, DISABLED_PauseDownloadEmitsDownloadPaused) { +TEST_F(ModelDownloaderTest, PauseDownloadEmitsDownloadPaused) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -332,7 +332,7 @@ TEST_F(ModelDownloaderTest, DISABLED_PauseDownloadEmitsDownloadPaused) { EXPECT_EQ(spy.at(0).at(0).toString(), "TestModel"); } -TEST_F(ModelDownloaderTest, DISABLED_PauseDownloadKeepsIsDownloadingTrue) { +TEST_F(ModelDownloaderTest, PauseDownloadKeepsIsDownloadingTrue) { // After pausing, m_isDownloading stays true (only cancel/finish resets it) QString dest = tempFilePath("test_model.gguf"); @@ -354,7 +354,7 @@ TEST_F(ModelDownloaderTest, PauseWhenNotDownloadingIsNoOp) { EXPECT_EQ(spy.count(), 0); } -TEST_F(ModelDownloaderTest, DISABLED_PauseWhenAlreadyPausedIsNoOp) { +TEST_F(ModelDownloaderTest, PauseWhenAlreadyPausedIsNoOp) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -373,7 +373,7 @@ TEST_F(ModelDownloaderTest, DISABLED_PauseWhenAlreadyPausedIsNoOp) { // --- resumeDownload --- -TEST_F(ModelDownloaderTest, DISABLED_ResumeDownloadEmitsDownloadResumed) { +TEST_F(ModelDownloaderTest, ResumeDownloadEmitsDownloadResumed) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -400,7 +400,7 @@ TEST_F(ModelDownloaderTest, ResumeWhenNotPausedIsNoOp) { EXPECT_EQ(spy.count(), 0); } -TEST_F(ModelDownloaderTest, DISABLED_ResumeAfterCancelIsNoOp) { +TEST_F(ModelDownloaderTest, ResumeAfterCancelIsNoOp) { // Once canceled, m_isPaused is false and m_currentUrl is empty, so resume should be a no-op QString dest = tempFilePath("test_model.gguf"); @@ -420,7 +420,7 @@ TEST_F(ModelDownloaderTest, DISABLED_ResumeAfterCancelIsNoOp) { // --- Pause/Resume/Cancel lifecycle --- -TEST_F(ModelDownloaderTest, DISABLED_PauseThenCancelResetsState) { +TEST_F(ModelDownloaderTest, PauseThenCancelResetsState) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -440,7 +440,7 @@ TEST_F(ModelDownloaderTest, DISABLED_PauseThenCancelResetsState) { EXPECT_FLOAT_EQ(downloader->downloadSpeed(), 0.0f); } -TEST_F(ModelDownloaderTest, DISABLED_PauseThenResumeKeepsModelName) { +TEST_F(ModelDownloaderTest, PauseThenResumeKeepsModelName) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -458,7 +458,7 @@ TEST_F(ModelDownloaderTest, DISABLED_PauseThenResumeKeepsModelName) { // --- Cancel emits all property changed signals --- -TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadEmitsAllPropertySignals) { +TEST_F(ModelDownloaderTest, CancelDownloadEmitsAllPropertySignals) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -484,7 +484,7 @@ TEST_F(ModelDownloaderTest, DISABLED_CancelDownloadEmitsAllPropertySignals) { // --- Network error handling (will fail to connect to example.com, testing error path) --- -TEST_F(ModelDownloaderTest, DISABLED_DownloadToInvalidPathEmitsError) { +TEST_F(ModelDownloaderTest, DownloadToInvalidPathEmitsError) { // Try to download to a path that cannot be opened for writing QSignalSpy errorSpy(downloader, &ModelDownloader::downloadError); @@ -504,7 +504,7 @@ TEST_F(ModelDownloaderTest, DISABLED_DownloadToInvalidPathEmitsError) { // --- Partial file resume detection --- -TEST_F(ModelDownloaderTest, DISABLED_StartDownloadDetectsExistingPartFile) { +TEST_F(ModelDownloaderTest, StartDownloadDetectsExistingPartFile) { QString dest = tempFilePath("resume_model.gguf"); QString partFile = dest + ".part"; @@ -530,7 +530,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartDownloadDetectsExistingPartFile) { // --- Multiple cancel calls are safe --- -TEST_F(ModelDownloaderTest, DISABLED_MultipleCancelCallsAreSafe) { +TEST_F(ModelDownloaderTest, MultipleCancelCallsAreSafe) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); @@ -548,7 +548,7 @@ TEST_F(ModelDownloaderTest, DISABLED_MultipleCancelCallsAreSafe) { // --- Start after cancel works --- -TEST_F(ModelDownloaderTest, DISABLED_StartAfterCancelWorks) { +TEST_F(ModelDownloaderTest, StartAfterCancelWorks) { QString dest1 = tempFilePath("model1.gguf"); QString dest2 = tempFilePath("model2.gguf"); @@ -570,7 +570,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartAfterCancelWorks) { // --- Start after pause+cancel works --- -TEST_F(ModelDownloaderTest, DISABLED_StartAfterPauseCancelWorks) { +TEST_F(ModelDownloaderTest, StartAfterPauseCancelWorks) { QString dest1 = tempFilePath("model1.gguf"); QString dest2 = tempFilePath("model2.gguf"); @@ -594,7 +594,7 @@ TEST_F(ModelDownloaderTest, DISABLED_StartAfterPauseCancelWorks) { // --- Q_PROPERTY values consistency --- -TEST_F(ModelDownloaderTest, DISABLED_PropertiesAreConsistentAfterStart) { +TEST_F(ModelDownloaderTest, PropertiesAreConsistentAfterStart) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "ConsistencyModel"); @@ -606,7 +606,7 @@ TEST_F(ModelDownloaderTest, DISABLED_PropertiesAreConsistentAfterStart) { EXPECT_FLOAT_EQ(downloader->downloadSpeed(), 0.0f); } -TEST_F(ModelDownloaderTest, DISABLED_PropertiesAreConsistentAfterCancel) { +TEST_F(ModelDownloaderTest, PropertiesAreConsistentAfterCancel) { QString dest = tempFilePath("test_model.gguf"); downloader->startDownload("https://example.com/model.gguf", dest, "TestModel"); diff --git a/src/TransformOperator.cpp b/src/TransformOperator.cpp index 27d28f0dc..6d4d2237f 100755 --- a/src/TransformOperator.cpp +++ b/src/TransformOperator.cpp @@ -10,7 +10,6 @@ #include "SelectionSet.h" #include "OgreWidget.h" #include "mainwindow.h" -#include "TransformWidget.h" #include "Manager.h" #include "SentryReporter.h" #include "MeshTransform.h" diff --git a/src/TransformWidget.cpp b/src/TransformWidget.cpp deleted file mode 100755 index e6a5e5754..000000000 --- a/src/TransformWidget.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#include -#include - -#include "GlobalDefinitions.h" - -#include "TransformWidget.h" -#include "SelectionSet.h" -#include "TransformOperator.h" -#include "ObjectItemModel.h" - -TransformWidget::TransformWidget(QWidget *parent) : - QWidget(parent), m_pObjectTreeModel(nullptr) -{ - ui->setupUi(this); - - // Scene TreeView - m_pObjectTreeModel = new ObjectItemModel(this); - ui->treeView->setModel(m_pObjectTreeModel); - connect(SelectionSet::getSingleton(),SIGNAL(selectionChanged()),this,SLOT(updateTreeViewFromSelection())); - connect(ui->treeView->selectionModel(),SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)), - this,SLOT(treeWidgetSelectionChanged(const QItemSelection&, const QItemSelection&))); - - // Position edit boxes - connect(TransformOperator::getSingleton(),SIGNAL(selectedPositionChanged(Ogre::Vector3)),this,SLOT(updatePosition(Ogre::Vector3))); - connect(ui->positionX, SIGNAL(valueChanged(double)),this,SLOT(onPositionEdited())); - connect(ui->positionY, SIGNAL(valueChanged(double)),this,SLOT(onPositionEdited())); - connect(ui->positionZ, SIGNAL(valueChanged(double)),this,SLOT(onPositionEdited())); - - // Scale edit boxes - connect(TransformOperator::getSingleton(),SIGNAL(selectedScaleChanged(Ogre::Vector3)),this,SLOT(updateNodeScale(Ogre::Vector3))); - connect(ui->scaleX, SIGNAL(valueChanged(double)),this,SLOT(onNodeScaleEdited())); - connect(ui->scaleY, SIGNAL(valueChanged(double)),this,SLOT(onNodeScaleEdited())); - connect(ui->scaleZ, SIGNAL(valueChanged(double)),this,SLOT(onNodeScaleEdited())); - - // Rotation edit boxes - connect(TransformOperator::getSingleton(),SIGNAL(selectedOrientationChanged(Ogre::Vector3)),this,SLOT(updateNodeOrientation(Ogre::Vector3))); - connect(ui->rotationX, SIGNAL(valueChanged(double)),this,SLOT(onNodeOrientationEdited())); - connect(ui->rotationY, SIGNAL(valueChanged(double)),this,SLOT(onNodeOrientationEdited())); - connect(ui->rotationZ, SIGNAL(valueChanged(double)),this,SLOT(onNodeOrientationEdited())); -} - -TransformWidget::~TransformWidget() -{ - delete ui; - - if(m_pObjectTreeModel) - { - delete m_pObjectTreeModel; - m_pObjectTreeModel = nullptr; - } -} - -void TransformWidget::updateTreeViewFromSelection() -{ - ui->treeView->blockSignals(true); - - QModelIndex start = m_pObjectTreeModel->getRootIndex(); - QModelIndexList index; - Ogre::SceneNode* node = nullptr; - Ogre::Entity* entity = nullptr; - Ogre::SubEntity* subEntity = nullptr; - QItemSelection newSelection; - - foreach(node, SelectionSet::getSingleton()->getNodesSelectionList()) - { - index = m_pObjectTreeModel->match(start, NODE_DATA, - QVariant::fromValue((void *) node), - 1/*stop*/ ,Qt::MatchExactly|Qt::MatchRecursive); - - if(index.isEmpty() || !index.at(0).isValid()) continue; - - newSelection.select(index.at(0),index.at(0)); - ui->treeView->expand(m_pObjectTreeModel->parent(index.at(0))); - } - - foreach(entity,SelectionSet::getSingleton()->getEntitiesSelectionList()) - { - index = m_pObjectTreeModel->match(start, ENTITY_DATA, - QVariant::fromValue((void *) entity), - 1/*stop*/ ,Qt::MatchExactly|Qt::MatchRecursive); - - if(index.isEmpty() || !index.at(0).isValid()) continue; - - newSelection.select(index.at(0),index.at(0)); - ui->treeView->expand(m_pObjectTreeModel->parent(index.at(0))); - } - - foreach(subEntity,SelectionSet::getSingleton()->getSubEntitiesSelectionList()) - { - index = m_pObjectTreeModel->match(start, SUBENTITY_DATA, - QVariant::fromValue((void *) subEntity), - 1/*stop*/ ,Qt::MatchExactly|Qt::MatchRecursive); - - if(index.isEmpty() || !index.at(0).isValid()) continue; - - newSelection.select(index.at(0),index.at(0)); - ui->treeView->expand(m_pObjectTreeModel->parent(index.at(0))); - } - - ui->treeView->selectionModel()->select(newSelection, QItemSelectionModel::ClearAndSelect); - - // Update header Text - switch (int numSelected = SelectionSet::getSingleton()->getCount(); numSelected) - { - case 0: - m_pObjectTreeModel->setHeaderText(tr("No object selected")); - break; - case 1: - m_pObjectTreeModel->setHeaderText(tr("1 object selected")); - break; - default: - m_pObjectTreeModel->setHeaderText(QString::number(numSelected) + tr(" objects selected")); - } - - ui->treeView->blockSignals(false); -} - -void TransformWidget::treeWidgetSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected) -{ - QItemSelectionRange range; - QModelIndex index; - QStandardItem* currentItem = nullptr; - Ogre::SceneNode* node = nullptr; - Ogre::Entity* entity = nullptr; - Ogre::SubEntity* subEntity = nullptr; - - foreach(range, deselected) - { - foreach(index,range.indexes()) - { - currentItem = m_pObjectTreeModel->itemFromIndex(index); - node = (Ogre::SceneNode*) currentItem->data(NODE_DATA).value(); - entity = (Ogre::Entity*) currentItem->data(ENTITY_DATA).value(); - subEntity = (Ogre::SubEntity*) currentItem->data(SUBENTITY_DATA).value(); - if(node) - SelectionSet::getSingleton()->removeOne(node); - else if(entity) - SelectionSet::getSingleton()->removeOne(entity); - else if(subEntity) - SelectionSet::getSingleton()->removeOne(subEntity); - - } - } - - foreach(range, selected) - { - foreach(index,range.indexes()) - { - currentItem = m_pObjectTreeModel->itemFromIndex(index); - node = (Ogre::SceneNode*) currentItem->data(NODE_DATA).value(); - entity = (Ogre::Entity*) currentItem->data(ENTITY_DATA).value(); - subEntity = (Ogre::SubEntity*) currentItem->data(SUBENTITY_DATA).value(); - if(node) - SelectionSet::getSingleton()->append(node); - else if(entity) - SelectionSet::getSingleton()->append(entity); - else if(subEntity) - SelectionSet::getSingleton()->append(subEntity); - } - } - -} - -void TransformWidget::updatePosition(const Ogre::Vector3& newPosition) -{ - ui->positionX->blockSignals(true); - ui->positionY->blockSignals(true); - ui->positionZ->blockSignals(true); - - ui->positionX->setValue(newPosition.x); - ui->positionY->setValue(newPosition.y); - ui->positionZ->setValue(newPosition.z); - - ui->positionX->blockSignals(false); - ui->positionY->blockSignals(false); - ui->positionZ->blockSignals(false); -} - -void TransformWidget::onPositionEdited() -{ - Ogre::Vector3 position = Ogre::Vector3::ZERO; - position.x=ui->positionX->value(); - position.y=ui->positionY->value(); - position.z=ui->positionZ->value(); - TransformOperator::getSingleton()->setSelectedPosition(position); -} - -// TODO link this to the GUI scaling method -void TransformWidget::updateNodeScale(const Ogre::Vector3& newScale) -{ - ui->scaleX->blockSignals(true); - ui->scaleY->blockSignals(true); - ui->scaleZ->blockSignals(true); - - ui->scaleX->setValue(newScale.x); - ui->scaleY->setValue(newScale.y); - ui->scaleZ->setValue(newScale.z); - - ui->scaleX->blockSignals(false); - ui->scaleY->blockSignals(false); - ui->scaleZ->blockSignals(false); -} - -void TransformWidget::onNodeScaleEdited() -{ - Ogre::Vector3 scale = Ogre::Vector3::UNIT_SCALE; - scale.x=ui->scaleX->value(); - scale.y=ui->scaleY->value(); - scale.z=ui->scaleZ->value(); - TransformOperator::getSingleton()->setSelectedScale(scale); -} - -void TransformWidget::updateNodeOrientation(const Ogre::Vector3& newOrientation) -{ - ui->rotationX->blockSignals(true); - ui->rotationY->blockSignals(true); - ui->rotationZ->blockSignals(true); - - ui->rotationX->setValue(newOrientation.x); - ui->rotationY->setValue(newOrientation.y); - ui->rotationZ->setValue(newOrientation.z); - - ui->rotationX->blockSignals(false); - ui->rotationY->blockSignals(false); - ui->rotationZ->blockSignals(false); -} -// TODO add a control between 0 360° or -180 180° -void TransformWidget::onNodeOrientationEdited() -{ - Ogre::Vector3 eulerOrientation = Ogre::Vector3::UNIT_SCALE; - eulerOrientation.x=ui->rotationX->value(); - eulerOrientation.y=ui->rotationY->value(); - eulerOrientation.z=ui->rotationZ->value(); - TransformOperator::getSingleton()->setSelectedOrientation(eulerOrientation); -} diff --git a/src/TransformWidget.h b/src/TransformWidget.h deleted file mode 100755 index c82f9680c..000000000 --- a/src/TransformWidget.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef TRANSFORM_WIDGET_H -#define TRANSFORM_WIDGET_H - -#include -#include -#include "ui_TransformWidget.h" - -class QItemSelection; -class ObjectItemModel; - -class TransformWidget : public QWidget -{ - Q_OBJECT - -public: - explicit TransformWidget(QWidget *parent = nullptr); - ~TransformWidget(); - -private slots: - void updateTreeViewFromSelection(); - void treeWidgetSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); - - void updatePosition(const Ogre::Vector3& newPosition); - void updateNodeScale(const Ogre::Vector3& newScale); - void updateNodeOrientation(const Ogre::Vector3& newOrientation); - - void onPositionEdited(); - void onNodeScaleEdited(); - void onNodeOrientationEdited(); - -signals: - void selectionChanged(const QString& newSelection); - void selectionChanged(Ogre::SceneNode* newNode); - -private: - Ui::TransformWidget* ui = new Ui::TransformWidget; - ObjectItemModel* m_pObjectTreeModel; -}; - -#endif // TRANSFORM_WIDGET_H diff --git a/src/TransformWidget_test.cpp b/src/TransformWidget_test.cpp deleted file mode 100644 index 2148998f4..000000000 --- a/src/TransformWidget_test.cpp +++ /dev/null @@ -1,344 +0,0 @@ -#include -#include -#include -#include -#include -#include "TransformWidget.h" -#include "SelectionSet.h" -#include "Manager.h" -#include "mainwindow.h" -#include "TestHelpers.h" - -// Test fixture for TransformWidget class -class TransformWidgetTests : public ::testing::Test { -protected: - TransformWidget* transformWidget; - QMainWindow* mainWindow; - QApplication* app; - - QDoubleSpinBox* positionX; - QDoubleSpinBox* positionY; - QDoubleSpinBox* positionZ; - QDoubleSpinBox* scaleX; - QDoubleSpinBox* scaleY; - QDoubleSpinBox* scaleZ; - QDoubleSpinBox* rotationX; - QDoubleSpinBox* rotationY; - QDoubleSpinBox* rotationZ; - - void SetUp() override { - // Create the QApplication - app = qobject_cast(QCoreApplication::instance()); - ASSERT_NE(app, nullptr); - - // Create a main window to hold the widget - try { - mainWindow = Manager::getSingleton()->getMainWindow(); - } catch (const Ogre::Exception& e) { - GTEST_SKIP() << "Skipping: Ogre initialization failed (" << e.getFullDescription() << ")"; - } - - // Create the transform widget - transformWidget = new TransformWidget(mainWindow); - - positionX = transformWidget->findChild("positionX"); - positionY = transformWidget->findChild("positionY"); - positionZ = transformWidget->findChild("positionZ"); - scaleX = transformWidget->findChild("scaleX"); - scaleY = transformWidget->findChild("scaleY"); - scaleZ = transformWidget->findChild("scaleZ"); - rotationX = transformWidget->findChild("rotationX"); - rotationY = transformWidget->findChild("rotationY"); - rotationZ = transformWidget->findChild("rotationZ"); - } - - void TearDown() override { - } -}; - -TEST_F(TransformWidgetTests, Constructor) -{ - // Verify that the widget is not null - ASSERT_NE(nullptr, transformWidget); - - // Verify that the widget is added to the main window - ASSERT_EQ(mainWindow, transformWidget->parentWidget()); -} - -// DISABLED: This test causes segfault in Ogre mesh loading (hardware buffer manager not initialized) -// TODO: Fix Ogre render system initialization before mesh loading -TEST_F(TransformWidgetTests, DISABLED_UpdateTreeViewFromSelection) -{ - if (!canLoadMeshFiles()) { - GTEST_SKIP() << "Skipping: mesh loading not supported in headless mode"; - } - - // Verify that the tree view is updated - auto treeView = transformWidget->findChild("treeView"); - ASSERT_NE(nullptr, treeView); - ASSERT_NE(nullptr, treeView->model()); - - // Process Qt events to ensure model is initialized - QCoreApplication::processEvents(); - - ASSERT_EQ(1, treeView->model()->rowCount()); - ASSERT_EQ("No Selection", treeView->model()->headerData(0, Qt::Horizontal).toString().toStdString()); - - // import a mesh - wrap in try-catch to handle Ogre initialization issues - QStringList validUri{"./media/models/ninja.mesh"}; - try { - Manager::getSingleton()->getMainWindow()->importMeshs(validUri); - - // Process Qt events to ensure signals are delivered and tree view is updated - QCoreApplication::processEvents(); - - // Verify that entities were created - auto entities = Manager::getSingleton()->getEntities(); - if (entities.isEmpty()) { - GTEST_SKIP() << "Skipping test: mesh import failed or no entities created"; - } - - // Verify that the tree view is updated - ASSERT_NE(nullptr, treeView->model()); - ASSERT_EQ(1, treeView->model()->rowCount()); - ASSERT_EQ("1 object selected", treeView->model()->headerData(0, Qt::Horizontal).toString().toStdString()); - - // Select the mesh - auto entity = entities.last(); - ASSERT_NE(nullptr, entity); - SelectionSet::getSingleton()->append(entity); - - // Process Qt events to ensure signals are delivered - QCoreApplication::processEvents(); - - ASSERT_NE(nullptr, treeView->model()); - ASSERT_EQ("2 objects selected", treeView->model()->headerData(0, Qt::Horizontal).toString().toStdString()); - - // Select the sub entity - check if entity has sub entities - if (entity->getNumSubEntities() == 0) { - GTEST_SKIP() << "Skipping sub-entity test: entity has no sub-entities"; - } - - auto subEntity = entity->getSubEntity(0); - ASSERT_NE(nullptr, subEntity); - SelectionSet::getSingleton()->append(subEntity); - - // Process Qt events to ensure signals are delivered - QCoreApplication::processEvents(); - - ASSERT_NE(nullptr, treeView->model()); - ASSERT_EQ("3 objects selected", treeView->model()->headerData(0, Qt::Horizontal).toString().toStdString()); - } catch (const Ogre::Exception& e) { - GTEST_SKIP() << "Skipping test: Ogre exception during mesh import (" - << e.getFullDescription() << ")"; - } catch (const std::exception& e) { - GTEST_SKIP() << "Skipping test: exception during mesh import (" << e.what() << ")"; - } catch (...) { - GTEST_SKIP() << "Skipping test: unknown exception during mesh import (possible segfault in Ogre mesh loading)"; - } -} - - -// DISABLED: This test causes segfault in Ogre mesh loading (hardware buffer manager not initialized) -// TODO: Fix Ogre render system initialization before mesh loading -TEST_F(TransformWidgetTests, DISABLED_UpdateSceneNodePositionScaleOrientation) { - if (!canLoadMeshFiles()) { - GTEST_SKIP() << "Skipping: mesh loading not supported in headless mode"; - } - - // import a mesh - QStringList validUri{"./media/models/ninja.mesh"}; - Manager::getSingleton()->getMainWindow()->importMeshs(validUri); - auto selectedSceneNode = SelectionSet::getSingleton()->getNodesSelectionList().first(); - SelectionSet::getSingleton()->selectOne(selectedSceneNode); - - positionX->setValue(1.0); - positionY->setValue(2.0); - positionZ->setValue(3.0); - scaleX->setValue(4.0); - scaleY->setValue(5.0); - scaleZ->setValue(6.0); - rotationX->setValue(7.0); - rotationY->setValue(8.0); - rotationZ->setValue(0.0); // TODO: Fix changing all 3 rotation values makes weird numbers to appear - - // get node rotation in euler angles - Ogre::Radian x,y,z; - x = selectedSceneNode->getOrientation().getPitch(); - y = selectedSceneNode->getOrientation().getYaw(); - z = selectedSceneNode->getOrientation().getRoll(); - - ASSERT_EQ(selectedSceneNode->getPosition().x, positionX->value()); - ASSERT_EQ(selectedSceneNode->getPosition().y, positionY->value()); - ASSERT_EQ(selectedSceneNode->getPosition().z, positionZ->value()); - ASSERT_EQ(selectedSceneNode->getScale().x, scaleX->value()); - ASSERT_EQ(selectedSceneNode->getScale().y, scaleY->value()); - ASSERT_EQ(selectedSceneNode->getScale().z, scaleZ->value()); - ASSERT_NEAR(x.valueDegrees(), rotationX->value(),0.1); - ASSERT_NEAR(y.valueDegrees(), rotationY->value(),0.1); - ASSERT_NEAR(z.valueDegrees(), rotationZ->value(),0.1); -} - -// Test that spin boxes exist and have correct names -TEST_F(TransformWidgetTests, SpinBoxesExist) -{ - ASSERT_NE(positionX, nullptr); - ASSERT_NE(positionY, nullptr); - ASSERT_NE(positionZ, nullptr); - ASSERT_NE(scaleX, nullptr); - ASSERT_NE(scaleY, nullptr); - ASSERT_NE(scaleZ, nullptr); - ASSERT_NE(rotationX, nullptr); - ASSERT_NE(rotationY, nullptr); - ASSERT_NE(rotationZ, nullptr); -} - -// Test that the tree view exists -TEST_F(TransformWidgetTests, TreeViewExists) -{ - auto treeView = transformWidget->findChild("treeView"); - ASSERT_NE(treeView, nullptr); - ASSERT_NE(treeView->model(), nullptr); -} - -// Test position spin box ranges -TEST_F(TransformWidgetTests, PositionSpinBoxRanges) -{ - ASSERT_NE(positionX, nullptr); - EXPECT_LE(positionX->minimum(), -10000.0); - EXPECT_GE(positionX->maximum(), 10000.0); - EXPECT_EQ(positionX->decimals(), 4); -} - -// Test scale spin box minimum > 0 -TEST_F(TransformWidgetTests, ScaleSpinBoxMinimum) -{ - ASSERT_NE(scaleX, nullptr); - ASSERT_NE(scaleY, nullptr); - ASSERT_NE(scaleZ, nullptr); - EXPECT_GT(scaleX->minimum(), 0.0); - EXPECT_GT(scaleY->minimum(), 0.0); - EXPECT_GT(scaleZ->minimum(), 0.0); -} - -// Test rotation spin box ranges -TEST_F(TransformWidgetTests, RotationSpinBoxRanges) -{ - ASSERT_NE(rotationX, nullptr); - EXPECT_LE(rotationX->minimum(), -360.0); - EXPECT_GE(rotationX->maximum(), 360.0); - EXPECT_EQ(rotationX->decimals(), 4); -} - -// Test setting position values on the spin boxes -TEST_F(TransformWidgetTests, SetPositionSpinBoxValues) -{ - ASSERT_NE(positionX, nullptr); - ASSERT_NE(positionY, nullptr); - ASSERT_NE(positionZ, nullptr); - - positionX->setValue(1.5); - positionY->setValue(2.5); - positionZ->setValue(3.5); - - EXPECT_DOUBLE_EQ(positionX->value(), 1.5); - EXPECT_DOUBLE_EQ(positionY->value(), 2.5); - EXPECT_DOUBLE_EQ(positionZ->value(), 3.5); -} - -// Test setting scale values on the spin boxes -TEST_F(TransformWidgetTests, SetScaleSpinBoxValues) -{ - ASSERT_NE(scaleX, nullptr); - ASSERT_NE(scaleY, nullptr); - ASSERT_NE(scaleZ, nullptr); - - scaleX->setValue(2.0); - scaleY->setValue(3.0); - scaleZ->setValue(4.0); - - EXPECT_DOUBLE_EQ(scaleX->value(), 2.0); - EXPECT_DOUBLE_EQ(scaleY->value(), 3.0); - EXPECT_DOUBLE_EQ(scaleZ->value(), 4.0); -} - -// Test setting rotation values on the spin boxes -TEST_F(TransformWidgetTests, SetRotationSpinBoxValues) -{ - ASSERT_NE(rotationX, nullptr); - ASSERT_NE(rotationY, nullptr); - ASSERT_NE(rotationZ, nullptr); - - rotationX->setValue(45.0); - rotationY->setValue(90.0); - rotationZ->setValue(180.0); - - EXPECT_DOUBLE_EQ(rotationX->value(), 45.0); - EXPECT_DOUBLE_EQ(rotationY->value(), 90.0); - EXPECT_DOUBLE_EQ(rotationZ->value(), 180.0); -} - -// Test that setting position values triggers onPositionEdited (via signal) -TEST_F(TransformWidgetTests, PositionValueChangeTriggers) -{ - ASSERT_NE(positionX, nullptr); - - // Setting a value should trigger the signal connection to onPositionEdited. - // Since we do not have a selection, TransformOperator::setSelectedPosition - // will be called but should not crash (no selection means no-op). - EXPECT_NO_THROW({ - positionX->setValue(5.0); - if (app) app->processEvents(); - }); -} - -// Test that setting scale values does not crash without selection -TEST_F(TransformWidgetTests, ScaleValueChangeTriggers) -{ - ASSERT_NE(scaleX, nullptr); - - EXPECT_NO_THROW({ - scaleX->setValue(2.0); - if (app) app->processEvents(); - }); -} - -// Test that setting rotation values does not crash without selection -TEST_F(TransformWidgetTests, RotationValueChangeTriggers) -{ - ASSERT_NE(rotationX, nullptr); - - EXPECT_NO_THROW({ - rotationX->setValue(45.0); - if (app) app->processEvents(); - }); -} - -// DISABLED: This test requires entities to exist, which may cause segfault during mesh import -// TODO: Fix Ogre render system initialization before mesh loading -TEST_F(TransformWidgetTests, DISABLED_UpdateEntityPositionScaleOrientation) { - auto selectedEntity = Manager::getSingleton()->getEntities().last(); - SelectionSet::getSingleton()->selectOne(selectedEntity); - - positionX->setValue(1.0); - positionY->setValue(2.0); - positionZ->setValue(3.0); - scaleX->setValue(4.0); - scaleY->setValue(5.0); - scaleZ->setValue(6.0); - rotationX->setValue(7.0); - rotationY->setValue(8.0); - rotationZ->setValue(9.0); - - Manager::getSingleton()->getRoot()->renderOneFrame(); - - ASSERT_EQ(selectedEntity->getWorldBoundingBox().getCenter().x, 0); // TODO: find a way to validate the new position - ASSERT_EQ(SelectionSet::getSingleton()->getSelectionCenter().y, 0); - ASSERT_EQ(SelectionSet::getSingleton()->getSelectionCenter().z, 0); - ASSERT_EQ(SelectionSet::getSingleton()->getSelectionScale().x, scaleX->value()); - ASSERT_EQ(SelectionSet::getSingleton()->getSelectionScale().y, scaleY->value()); - ASSERT_EQ(SelectionSet::getSingleton()->getSelectionScale().z, scaleZ->value()); - ASSERT_EQ(SelectionSet::getSingleton()->getSelectionOrientation().x, rotationX->value()); - ASSERT_EQ(SelectionSet::getSingleton()->getSelectionOrientation().y, rotationY->value()); - ASSERT_EQ(SelectionSet::getSingleton()->getSelectionOrientation().z, rotationZ->value()); -} diff --git a/src/main_test.cpp b/src/main_test.cpp index cc28e08f2..90ee00d6d 100644 --- a/src/main_test.cpp +++ b/src/main_test.cpp @@ -1,10 +1,6 @@ #include #include #include -#include -#include "mainwindow.h" -#include "Manager.h" -#include "TestHelpers.h" // Test that QApplication exists (created by test_main.cpp) - do not create another TEST(MainTest, QApplicationExists) @@ -14,48 +10,3 @@ TEST(MainTest, QApplicationExists) auto* app = qobject_cast(QCoreApplication::instance()); ASSERT_NE(app, nullptr); } - -// DISABLED: This test causes segfault during mesh import/cleanup (Ogre hardware buffer manager issues) -// TODO: Fix Ogre render system initialization before mesh loading -TEST(MainTest, DISABLED_ImportMeshs) { - if (!canLoadMeshFiles()) { - GTEST_SKIP() << "Skipping: mesh loading not supported in headless mode"; - } - - // Use global QApplication from test_main.cpp - do not create another - ASSERT_NE(QCoreApplication::instance(), nullptr); - - // Ensure Manager is destroyed from previous tests - Manager::kill(); - QThread::msleep(50); - - try { - MainWindow mainWindow; - - // Get Manager - it should be created by MainWindow constructor - Manager* manager = Manager::getSingleton(&mainWindow); - ASSERT_NE(manager, nullptr); - - // Get initial count - Manager might have some entities from initialization - auto before = manager->getEntities().count(); - - // Import meshes - this happens in frameEnded, so we need to render a frame - manager->getRoot()->renderOneFrame(); - - // Wait a bit for async operations - QThread::msleep(100); - QCoreApplication::processEvents(); - - auto after = manager->getEntities().count(); - - EXPECT_GE(after, before + 2) << "Expected at least 2 new entities after importing 2 meshes"; - EXPECT_LE(after, before + 4) << "Expected at most 4 new entities (some meshes create multiple entities)"; - } catch (const Ogre::RenderingAPIException& e) { - GTEST_SKIP() << "Skipping ImportMeshs test: unable to create OGRE render window (" - << e.getFullDescription() << ")"; - } catch (const std::exception& e) { - GTEST_SKIP() << "Skipping ImportMeshs test: " << e.what(); - } catch (...) { - GTEST_SKIP() << "Skipping ImportMeshs test: unknown exception (possible segfault in mesh loading)"; - } -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 75429f5c4..9ff4c7123 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -34,7 +34,7 @@ if(BUILD_TESTS) ${CMAKE_CURRENT_SOURCE_DIR}/../src/TranslationGizmo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../src/ScaleGizmo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../src/TransformOperator.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/../src/TransformWidget.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../src/PrimitivesWidget.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../src/PrimitiveObject.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../src/ViewportGrid.cpp @@ -95,7 +95,7 @@ if(BUILD_TESTS) ${CMAKE_CURRENT_SOURCE_DIR}/../src/TranslationGizmo.h ${CMAKE_CURRENT_SOURCE_DIR}/../src/ScaleGizmo.h ${CMAKE_CURRENT_SOURCE_DIR}/../src/TransformOperator.h - ${CMAKE_CURRENT_SOURCE_DIR}/../src/TransformWidget.h + ${CMAKE_CURRENT_SOURCE_DIR}/../src/PrimitivesWidget.h ${CMAKE_CURRENT_SOURCE_DIR}/../src/PrimitiveObject.h ${CMAKE_CURRENT_SOURCE_DIR}/../src/ViewportGrid.h