[mapguide-commits] r9651 - sandbox/jng/catch2/Server/src/UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue Jul 7 06:24:43 PDT 2020


Author: jng
Date: 2020-07-07 06:24:42 -0700 (Tue, 07 Jul 2020)
New Revision: 9651

Modified:
   sandbox/jng/catch2/Server/src/UnitTesting/TestMisc.cpp
   sandbox/jng/catch2/Server/src/UnitTesting/UnitTesting.cpp
   sandbox/jng/catch2/Server/src/UnitTesting/UnitTesting.vcxproj
Log:
Fully port over TestMisc over to catch2. The catch2 listener is the closest analogy to our existing TestStart/TestEnd pair and our custom listener is what is used to setup/teardown any required data

Modified: sandbox/jng/catch2/Server/src/UnitTesting/TestMisc.cpp
===================================================================
--- sandbox/jng/catch2/Server/src/UnitTesting/TestMisc.cpp	2020-07-07 12:06:40 UTC (rev 9650)
+++ sandbox/jng/catch2/Server/src/UnitTesting/TestMisc.cpp	2020-07-07 13:24:42 UTC (rev 9651)
@@ -16,15 +16,15 @@
 //
 
 #include "MapGuideCommon.h"
-#include "TestMisc.h"
 #include "ServiceManager.h"
 #include "ServerResourceService.h"
 #include "ServerSiteService.h"
-#include "../UnitTesting/CppUnitExtensions.h"
 #include "FoundationDefs.h"
 #include "FdoConnectionManager.h"
 #include "LineBuffer.h"
 #include "RS_BufferOutputStream.h"
+
+#define CATCH_CONFIG_EXTERNAL_INTERFACES
 #include "catch.hpp"
 
 const STRING TEST_LOCALE = L"en";
@@ -34,415 +34,246 @@
 #define THREAD_GROUP 65520
 #define TESTREQUESTS 5000
 
-TEST_CASE("Common Exception Messages", "[TestMisc]")
+struct TestMiscSetup : Catch::TestEventListenerBase
 {
-    try
-    {
-        MgObject* ptr = NULL;
-        CHECKNULL(ptr, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"ptr") != STRING::npos);
-        ex->Release();
-    }
+    using TestEventListenerBase::TestEventListenerBase; // inherit constructor
 
-    try
-    {
-        MgObject* ptr2 = NULL;
-        CHECKNULL((void*)ptr2, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"ptr2") != STRING::npos);
-        ex->Release();
-    }
+   // Get rid of Wweak-tables
+    ~TestMiscSetup();
 
-    try
-    {
-        MgObject* ptr3 = NULL;
-        CHECKARGUMENTNULL(ptr3, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"ptr3") != STRING::npos);
-        ex->Release();
-    }
+    // The whole test run starting
+    void testRunStarting(Catch::TestRunInfo const& testRunInfo) override {
+        
+        Ptr<MgResourceService> m_svcResource = CreateResourceService();
 
-    try
-    {
-        MgObject* ptr4 = NULL;
-        CHECKARGUMENTNULL((void*)ptr4, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"ptr4") != STRING::npos);
-        ex->Release();
-    }
+        // Initialize a site connection.
+        Ptr<MgServerSiteService> svcSite = CreateSiteService();
 
-    try
-    {
-        STRING arg5;
-        CHECKARGUMENTEMPTYSTRING(arg5, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch (MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"arg5") != STRING::npos);
-        ex->Release();
-    }
+        printf("Setting up test data for TestMisc\n");
 
-    try
-    {
-        INT32 val = 1;
-        MG_CHECK_RANGE(val, 2, 3, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"val") != STRING::npos);
-        ex->Release();
-    }
+        //Reusing Mapping Service test data
+        try
+        {
+#ifdef _DEBUG
+            MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
+            if (pFdoConnectionManager)
+            {
+                pFdoConnectionManager->ShowCache();
+            }
+#endif
 
-    try
-    {
-        INT32 val = 1;
-        INT32 min = 2;
-        INT32 max = 3;
-        MG_CHECK_RANGE(val, min, max, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"val") != STRING::npos);
-        ex->Release();
-    }
+            //set user info
+            Ptr<MgUserInformation> userInfo = new MgUserInformation(L"Administrator", L"admin");
+            userInfo->SetLocale(TEST_LOCALE);
+            MgUserInformation::SetCurrentUserInfo(userInfo);
 
-    try
-    {
-        INT64 val = 1L;
-        MG_CHECK_RANGE(val, 2L, 3L, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"val") != STRING::npos);
-        ex->Release();
-    }
+            //publish the map definition
+            Ptr<MgResourceIdentifier> mapres = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+            Ptr<MgByteSource> mdfsrc = new MgByteSource(L"../UnitTestFiles/UT_Sheboygan.mdf", false);
+            Ptr<MgByteReader> mdfrdr = mdfsrc->GetReader();
+            m_svcResource->SetResource(mapres, mdfrdr, NULL);
 
-    try
-    {
-        INT64 val = 1L;
-        INT64 min = 2L;
-        INT64 max = 3L;
-        MG_CHECK_RANGE(val, min, max, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"val") != STRING::npos);
-        ex->Release();
-    }
+            Ptr<MgResourceIdentifier> mapres2 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan_833.MapDefinition");
+            Ptr<MgByteSource> mdfsrc2 = new MgByteSource(L"../UnitTestFiles/UT_Sheboygan_833.mdf", false);
+            Ptr<MgByteReader> mdfrdr2 = mdfsrc2->GetReader();
+            m_svcResource->SetResource(mapres2, mdfrdr2, NULL);
 
-    try
-    {
-        float val = 1.0f;
-        MG_CHECK_RANGE(val, 2.0f, 3.0f, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"val") != STRING::npos);
-        ex->Release();
-    }
+            //publish the layer definitions
+            Ptr<MgResourceIdentifier> ldfres1 = new MgResourceIdentifier(L"Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition");
+            Ptr<MgByteSource> ldfsrc1 = new MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.ldf", false);
+            Ptr<MgByteReader> ldfrdr1 = ldfsrc1->GetReader();
+            m_svcResource->SetResource(ldfres1, ldfrdr1, NULL);
 
-    try
-    {
-        float val = 1.0f;
-        float min = 2.0f;
-        float max = 3.0f;
-        MG_CHECK_RANGE(val, min, max, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"val") != STRING::npos);
-        ex->Release();
-    }
+            Ptr<MgResourceIdentifier> ldfres2 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Parcels.LayerDefinition");
+            Ptr<MgByteSource> ldfsrc2 = new MgByteSource(L"../UnitTestFiles/UT_Parcels.ldf", false);
+            Ptr<MgByteReader> ldfrdr2 = ldfsrc2->GetReader();
+            m_svcResource->SetResource(ldfres2, ldfrdr2, NULL);
 
-    try
-    {
-        double val = 1.0;
-        MG_CHECK_RANGE(val, 2.0, 3.0, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"val") != STRING::npos);
-        ex->Release();
-    }
+            Ptr<MgResourceIdentifier> ldfres3 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Rail.LayerDefinition");
+            Ptr<MgByteSource> ldfsrc3 = new MgByteSource(L"../UnitTestFiles/UT_Rail.ldf", false);
+            Ptr<MgByteReader> ldfrdr3 = ldfsrc3->GetReader();
+            m_svcResource->SetResource(ldfres3, ldfrdr3, NULL);
 
-    try
-    {
-        double val = 1.0;
-        double min = 2.0;
-        double max = 3.0;
-        MG_CHECK_RANGE(val, min, max, L"TestMisc::TestCase_CommonExceptionMessages");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"val") != STRING::npos);
-        ex->Release();
-    }
+            //publish the feature sources
+            Ptr<MgResourceIdentifier> fsres1 = new MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
+            Ptr<MgByteSource> fssrc1 = new MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.fs", false);
+            Ptr<MgByteReader> fsrdr1 = fssrc1->GetReader();
+            m_svcResource->SetResource(fsres1, fsrdr1, NULL);
 
-    try
-    {
-        Ptr<MgNamedCollection> coll = new MgNamedCollection(false);
-        coll->GetItem(L"Foo");
-    }
-    catch(MgException* ex)
-    {
-        STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        REQUIRE(msg.find(L"Foo") != STRING::npos);
-        ex->Release();
-    }
-}
+            Ptr<MgResourceIdentifier> fsres2 = new MgResourceIdentifier(L"Library://UnitTests/Data/Parcels.FeatureSource");
+            Ptr<MgByteSource> fssrc2 = new MgByteSource(L"../UnitTestFiles/UT_Parcels.fs", false);
+            Ptr<MgByteReader> fsrdr2 = fssrc2->GetReader();
+            m_svcResource->SetResource(fsres2, fsrdr2, NULL);
 
-CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TestMisc, "TestMisc");
+            Ptr<MgResourceIdentifier> fsres3 = new MgResourceIdentifier(L"Library://UnitTests/Data/Rail.FeatureSource");
+            Ptr<MgByteSource> fssrc3 = new MgByteSource(L"../UnitTestFiles/UT_Rail.fs", false);
+            Ptr<MgByteReader> fsrdr3 = fssrc3->GetReader();
+            m_svcResource->SetResource(fsres3, fsrdr3, NULL);
 
-TestMisc::TestMisc()
-{
-    // Initialize service objects.
-    MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+            // publish the resource data
+            Ptr<MgByteSource> dataSource1 = new MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.sdf", false);
+            Ptr<MgByteReader> dataReader1 = dataSource1->GetReader();
+            m_svcResource->SetResourceData(fsres1, L"UT_HydrographicPolygons.sdf", L"File", dataReader1);
 
-    m_svcResource = dynamic_cast<MgResourceService*>(
-        serviceManager->RequestService(MgServiceType::ResourceService));
-    assert(m_svcResource != NULL);
+            Ptr<MgByteSource> dataSource2 = new MgByteSource(L"../UnitTestFiles/UT_Parcels.sdf", false);
+            Ptr<MgByteReader> dataReader2 = dataSource2->GetReader();
+            m_svcResource->SetResourceData(fsres2, L"UT_Parcels.sdf", L"File", dataReader2);
 
-    // Initialize a site connection.
-    Ptr<MgServerSiteService> svcSite = dynamic_cast<MgServerSiteService*>(
-        serviceManager->RequestService(MgServiceType::SiteService));
-    assert(svcSite != NULL);
+            Ptr<MgByteSource> dataSource3 = new MgByteSource(L"../UnitTestFiles/UT_Rail.sdf", false);
+            Ptr<MgByteReader> dataReader3 = dataSource3->GetReader();
+            m_svcResource->SetResourceData(fsres3, L"UT_Rail.sdf", L"File", dataReader3);
 
-    Ptr<MgUserInformation> userInfo = new MgUserInformation(
-        L"Administrator", L"admin");
-    userInfo->SetLocale(TEST_LOCALE);
+            // publish the print layouts
+            Ptr<MgResourceIdentifier> plres1 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/AllElements.PrintLayout");
+            Ptr<MgByteSource> plsrc1 = new MgByteSource(L"../UnitTestFiles/UT_AllElements.pl", false);
+            Ptr<MgByteReader> plrdr1 = plsrc1->GetReader();
+            m_svcResource->SetResource(plres1, plrdr1, NULL);
 
-    // Set the current MgUserInformation
-    // This must be done before calling CreateSession()
-    MgUserInformation::SetCurrentUserInfo(userInfo);
+            Ptr<MgResourceIdentifier> plres2 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/NoLegend.PrintLayout");
+            Ptr<MgByteSource> plsrc2 = new MgByteSource(L"../UnitTestFiles/UT_NoLegend.pl", false);
+            Ptr<MgByteReader> plrdr2 = plsrc2->GetReader();
+            m_svcResource->SetResource(plres2, plrdr2, NULL);
 
-    STRING session = svcSite->CreateSession();
-    assert(!session.empty());
-    userInfo->SetMgSessionId(session);
-
-    // Set the current MgUserInformation
-    MgUserInformation::SetCurrentUserInfo(userInfo);
-
-    m_siteConnection = new MgSiteConnection();
-    m_siteConnection->Open(userInfo);
-}
-
-
-TestMisc::~TestMisc()
-{
-}
-
-
-void TestMisc::setUp()
-{
-}
-
-
-void TestMisc::tearDown()
-{
-}
-
-
-void TestMisc::TestStart()
-{
-    ACE_DEBUG((LM_INFO, ACE_TEXT("\nRunning Miscellaneous tests.\n")));
-
-    //Reusing Mapping Service test data
-    try
-    {
-        #ifdef _DEBUG
-        MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
-        if(pFdoConnectionManager)
+            // publish the symbol library
+            Ptr<MgResourceIdentifier> slres1 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/SymbolMart.SymbolLibrary");
+            Ptr<MgByteSource> slsrc1 = new MgByteSource(L"../UnitTestFiles/UT_SymbolMart.sl", false);
+            Ptr<MgByteReader> slrdr1 = slsrc1->GetReader();
+            m_svcResource->SetResource(slres1, slrdr1, NULL);
+            Ptr<MgByteSource> datasrc = new MgByteSource(L"../UnitTestFiles/UT_Symbols.dwf", false);
+            Ptr<MgByteReader> datardr = datasrc->GetReader();
+            m_svcResource->SetResourceData(slres1, L"symbols.dwf", L"File", datardr);
+        }
+        catch (MgException* e)
         {
-            pFdoConnectionManager->ShowCache();
+            STRING message = e->GetDetails(TEST_LOCALE);
+            SAFE_RELEASE(e);
+            FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
         }
-        #endif
+        catch (...)
+        {
+            throw;
+        }
+    }
 
-        //set user info
-        Ptr<MgUserInformation> userInfo = new MgUserInformation(L"Administrator", L"admin");
+    static MgSiteConnection* CreateSiteConnection(MgServerSiteService* svcSite) 
+    {
+        Ptr<MgUserInformation> userInfo = new MgUserInformation(
+            L"Administrator", L"admin");
         userInfo->SetLocale(TEST_LOCALE);
+
+        // Set the current MgUserInformation
+        // This must be done before calling CreateSession()
         MgUserInformation::SetCurrentUserInfo(userInfo);
 
-        //publish the map definition
-        Ptr<MgResourceIdentifier> mapres = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
-        Ptr<MgByteSource> mdfsrc = new MgByteSource(L"../UnitTestFiles/UT_Sheboygan.mdf", false);
-        Ptr<MgByteReader> mdfrdr = mdfsrc->GetReader();
-        m_svcResource->SetResource(mapres, mdfrdr, NULL);
+        STRING session = svcSite->CreateSession();
+        assert(!session.empty());
+        userInfo->SetMgSessionId(session);
 
-        Ptr<MgResourceIdentifier> mapres2 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan_833.MapDefinition");
-        Ptr<MgByteSource> mdfsrc2 = new MgByteSource(L"../UnitTestFiles/UT_Sheboygan_833.mdf", false);
-        Ptr<MgByteReader> mdfrdr2 = mdfsrc2->GetReader();
-        m_svcResource->SetResource(mapres2, mdfrdr2, NULL);
+        // Set the current MgUserInformation
+        MgUserInformation::SetCurrentUserInfo(userInfo);
 
-        //publish the layer definitions
-        Ptr<MgResourceIdentifier> ldfres1 = new MgResourceIdentifier(L"Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition");
-        Ptr<MgByteSource> ldfsrc1 = new MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.ldf", false);
-        Ptr<MgByteReader> ldfrdr1 = ldfsrc1->GetReader();
-        m_svcResource->SetResource(ldfres1, ldfrdr1, NULL);
+        Ptr<MgSiteConnection> m_siteConnection = new MgSiteConnection();
+        m_siteConnection->Open(userInfo);
+        return m_siteConnection.Detach();
+    }
 
-        Ptr<MgResourceIdentifier> ldfres2 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Parcels.LayerDefinition");
-        Ptr<MgByteSource> ldfsrc2 = new MgByteSource(L"../UnitTestFiles/UT_Parcels.ldf", false);
-        Ptr<MgByteReader> ldfrdr2 = ldfsrc2->GetReader();
-        m_svcResource->SetResource(ldfres2, ldfrdr2, NULL);
+    static MgServerSiteService* CreateSiteService() 
+    {
+        // Initialize service objects.
+        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
 
-        Ptr<MgResourceIdentifier> ldfres3 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Rail.LayerDefinition");
-        Ptr<MgByteSource> ldfsrc3 = new MgByteSource(L"../UnitTestFiles/UT_Rail.ldf", false);
-        Ptr<MgByteReader> ldfrdr3 = ldfsrc3->GetReader();
-        m_svcResource->SetResource(ldfres3, ldfrdr3, NULL);
+        return dynamic_cast<MgServerSiteService*>(
+            serviceManager->RequestService(MgServiceType::SiteService));
+    }
 
-        //publish the feature sources
-        Ptr<MgResourceIdentifier> fsres1 = new MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
-        Ptr<MgByteSource> fssrc1 = new MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.fs", false);
-        Ptr<MgByteReader> fsrdr1 = fssrc1->GetReader();
-        m_svcResource->SetResource(fsres1, fsrdr1, NULL);
+    static MgResourceService* CreateResourceService()
+    {
+        // Initialize service objects.
+        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
 
-        Ptr<MgResourceIdentifier> fsres2 = new MgResourceIdentifier(L"Library://UnitTests/Data/Parcels.FeatureSource");
-        Ptr<MgByteSource> fssrc2 = new MgByteSource(L"../UnitTestFiles/UT_Parcels.fs", false);
-        Ptr<MgByteReader> fsrdr2 = fssrc2->GetReader();
-        m_svcResource->SetResource(fsres2, fsrdr2, NULL);
-
-        Ptr<MgResourceIdentifier> fsres3 = new MgResourceIdentifier(L"Library://UnitTests/Data/Rail.FeatureSource");
-        Ptr<MgByteSource> fssrc3 = new MgByteSource(L"../UnitTestFiles/UT_Rail.fs", false);
-        Ptr<MgByteReader> fsrdr3 = fssrc3->GetReader();
-        m_svcResource->SetResource(fsres3, fsrdr3, NULL);
-
-        // publish the resource data
-        Ptr<MgByteSource> dataSource1 = new MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.sdf", false);
-        Ptr<MgByteReader> dataReader1 = dataSource1->GetReader();
-        m_svcResource->SetResourceData(fsres1, L"UT_HydrographicPolygons.sdf", L"File", dataReader1);
-
-        Ptr<MgByteSource> dataSource2 = new MgByteSource(L"../UnitTestFiles/UT_Parcels.sdf", false);
-        Ptr<MgByteReader> dataReader2 = dataSource2->GetReader();
-        m_svcResource->SetResourceData(fsres2, L"UT_Parcels.sdf", L"File", dataReader2);
-
-        Ptr<MgByteSource> dataSource3 = new MgByteSource(L"../UnitTestFiles/UT_Rail.sdf", false);
-        Ptr<MgByteReader> dataReader3 = dataSource3->GetReader();
-        m_svcResource->SetResourceData(fsres3, L"UT_Rail.sdf", L"File", dataReader3);
-
-        // publish the print layouts
-        Ptr<MgResourceIdentifier> plres1 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/AllElements.PrintLayout");
-        Ptr<MgByteSource> plsrc1 = new MgByteSource(L"../UnitTestFiles/UT_AllElements.pl", false);
-        Ptr<MgByteReader> plrdr1 = plsrc1->GetReader();
-        m_svcResource->SetResource(plres1, plrdr1, NULL);
-
-        Ptr<MgResourceIdentifier> plres2 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/NoLegend.PrintLayout");
-        Ptr<MgByteSource> plsrc2 = new MgByteSource(L"../UnitTestFiles/UT_NoLegend.pl", false);
-        Ptr<MgByteReader> plrdr2 = plsrc2->GetReader();
-        m_svcResource->SetResource(plres2, plrdr2, NULL);
-
-        // publish the symbol library
-        Ptr<MgResourceIdentifier> slres1 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/SymbolMart.SymbolLibrary");
-        Ptr<MgByteSource> slsrc1 = new MgByteSource(L"../UnitTestFiles/UT_SymbolMart.sl", false);
-        Ptr<MgByteReader> slrdr1 = slsrc1->GetReader();
-        m_svcResource->SetResource(slres1, slrdr1, NULL);
-        Ptr<MgByteSource> datasrc = new MgByteSource(L"../UnitTestFiles/UT_Symbols.dwf", false);
-        Ptr<MgByteReader> datardr = datasrc->GetReader();
-        m_svcResource->SetResourceData(slres1, L"symbols.dwf", L"File", datardr);
+        return dynamic_cast<MgResourceService*>(
+            serviceManager->RequestService(MgServiceType::ResourceService));
     }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
 
+    // The whole test run ending
+    void testRunEnded(Catch::TestRunStats const& testRunStats) override {
+        Ptr<MgResourceService> m_svcResource = CreateResourceService();
 
-void TestMisc::TestEnd()
-{
-    try
-    {
-        //set user info
-        Ptr<MgUserInformation> userInfo = new MgUserInformation(L"Administrator", L"admin");
-        userInfo->SetLocale(TEST_LOCALE);
-        MgUserInformation::SetCurrentUserInfo(userInfo);
+        printf("Tearing down test data for TestMisc\n");
+        try
+        {
+            //set user info
+            Ptr<MgUserInformation> userInfo = new MgUserInformation(L"Administrator", L"admin");
+            userInfo->SetLocale(TEST_LOCALE);
+            MgUserInformation::SetCurrentUserInfo(userInfo);
 
-        //delete the map definition
-        Ptr<MgResourceIdentifier> mapres = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
-        m_svcResource->DeleteResource(mapres);
+            //delete the map definition
+            Ptr<MgResourceIdentifier> mapres = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+            m_svcResource->DeleteResource(mapres);
 
-        Ptr<MgResourceIdentifier> mapres2 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan_833.MapDefinition");
-        m_svcResource->DeleteResource(mapres2);
+            Ptr<MgResourceIdentifier> mapres2 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan_833.MapDefinition");
+            m_svcResource->DeleteResource(mapres2);
 
-        //delete the layer definitions
-        Ptr<MgResourceIdentifier> ldfres1 = new MgResourceIdentifier(L"Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition");
-        m_svcResource->DeleteResource(ldfres1);
+            //delete the layer definitions
+            Ptr<MgResourceIdentifier> ldfres1 = new MgResourceIdentifier(L"Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition");
+            m_svcResource->DeleteResource(ldfres1);
 
-        Ptr<MgResourceIdentifier> ldfres2 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Parcels.LayerDefinition");
-        m_svcResource->DeleteResource(ldfres2);
+            Ptr<MgResourceIdentifier> ldfres2 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Parcels.LayerDefinition");
+            m_svcResource->DeleteResource(ldfres2);
 
-        Ptr<MgResourceIdentifier> ldfres3 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Rail.LayerDefinition");
-        m_svcResource->DeleteResource(ldfres3);
+            Ptr<MgResourceIdentifier> ldfres3 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Rail.LayerDefinition");
+            m_svcResource->DeleteResource(ldfres3);
 
-        //delete the feature sources
-        Ptr<MgResourceIdentifier> fsres1 = new MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
-        m_svcResource->DeleteResource(fsres1);
+            //delete the feature sources
+            Ptr<MgResourceIdentifier> fsres1 = new MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
+            m_svcResource->DeleteResource(fsres1);
 
-        Ptr<MgResourceIdentifier> fsres2 = new MgResourceIdentifier(L"Library://UnitTests/Data/Parcels.FeatureSource");
-        m_svcResource->DeleteResource(fsres2);
+            Ptr<MgResourceIdentifier> fsres2 = new MgResourceIdentifier(L"Library://UnitTests/Data/Parcels.FeatureSource");
+            m_svcResource->DeleteResource(fsres2);
 
-        Ptr<MgResourceIdentifier> fsres3 = new MgResourceIdentifier(L"Library://UnitTests/Data/Rail.FeatureSource");
-        m_svcResource->DeleteResource(fsres3);
+            Ptr<MgResourceIdentifier> fsres3 = new MgResourceIdentifier(L"Library://UnitTests/Data/Rail.FeatureSource");
+            m_svcResource->DeleteResource(fsres3);
 
-        // delete the print layouts
-        Ptr<MgResourceIdentifier> plres1 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/AllElements.PrintLayout");
-        m_svcResource->DeleteResource(plres1);
+            // delete the print layouts
+            Ptr<MgResourceIdentifier> plres1 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/AllElements.PrintLayout");
+            m_svcResource->DeleteResource(plres1);
 
-        Ptr<MgResourceIdentifier> plres2 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/NoLegend.PrintLayout");
-        m_svcResource->DeleteResource(plres2);
+            Ptr<MgResourceIdentifier> plres2 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/NoLegend.PrintLayout");
+            m_svcResource->DeleteResource(plres2);
 
-        // delete the symbol library
-        Ptr<MgResourceIdentifier> slres1 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/SymbolMart.SymbolLibrary");
-        m_svcResource->DeleteResource(slres1);
+            // delete the symbol library
+            Ptr<MgResourceIdentifier> slres1 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/SymbolMart.SymbolLibrary");
+            m_svcResource->DeleteResource(slres1);
 
-        #ifdef _DEBUG
-        MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
-        if(pFdoConnectionManager)
+#ifdef _DEBUG
+            MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
+            if (pFdoConnectionManager)
+            {
+                pFdoConnectionManager->ShowCache();
+            }
+#endif
+        }
+        catch (MgException* e)
         {
-            pFdoConnectionManager->ShowCache();
+            STRING message = e->GetDetails(TEST_LOCALE);
+            SAFE_RELEASE(e);
+            FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
         }
-        #endif
+        catch (...)
+        {
+            throw;
+        }
+
+        ACE_DEBUG((LM_INFO, ACE_TEXT("\nMiscellaneous tests completed.\n\n")));
     }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
+};
 
-    ACE_DEBUG((LM_INFO, ACE_TEXT("\nMiscellaneous tests completed.\n\n")));
-}
+CATCH_REGISTER_LISTENER(TestMiscSetup)
 
-void TestMisc::TestCase_CommonExceptionMessages()
+// Get rid of Wweak-tables
+TestMiscSetup::~TestMiscSetup() {}
+
+TEST_CASE("Common Exception Messages", "[TestMisc]")
 {
     try
     {
@@ -452,10 +283,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier 'ptr' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"ptr") != STRING::npos);
+        REQUIRE(msg.find(L"ptr") != STRING::npos);
         ex->Release();
     }
 
@@ -467,10 +295,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier 'ptr2' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"ptr2") != STRING::npos);
+        REQUIRE(msg.find(L"ptr2") != STRING::npos);
         ex->Release();
     }
 
@@ -482,10 +307,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier 'ptr3' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"ptr3") != STRING::npos);
+        REQUIRE(msg.find(L"ptr3") != STRING::npos);
         ex->Release();
     }
 
@@ -497,10 +319,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier 'ptr4' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"ptr4") != STRING::npos);
+        REQUIRE(msg.find(L"ptr4") != STRING::npos);
         ex->Release();
     }
 
@@ -512,10 +331,7 @@
     catch (MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier 'arg5' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"arg5") != STRING::npos);
+        REQUIRE(msg.find(L"arg5") != STRING::npos);
         ex->Release();
     }
 
@@ -527,10 +343,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier 'val' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"val") != STRING::npos);
+        REQUIRE(msg.find(L"val") != STRING::npos);
         ex->Release();
     }
 
@@ -544,10 +357,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier '' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"") != STRING::npos);
+        REQUIRE(msg.find(L"val") != STRING::npos);
         ex->Release();
     }
 
@@ -559,10 +369,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier '' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"") != STRING::npos);
+        REQUIRE(msg.find(L"val") != STRING::npos);
         ex->Release();
     }
 
@@ -576,10 +383,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier '' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"") != STRING::npos);
+        REQUIRE(msg.find(L"val") != STRING::npos);
         ex->Release();
     }
 
@@ -591,10 +395,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier '' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"") != STRING::npos);
+        REQUIRE(msg.find(L"val") != STRING::npos);
         ex->Release();
     }
 
@@ -608,10 +409,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier '' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"") != STRING::npos);
+        REQUIRE(msg.find(L"val") != STRING::npos);
         ex->Release();
     }
 
@@ -623,10 +421,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier '' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"") != STRING::npos);
+        REQUIRE(msg.find(L"val") != STRING::npos);
         ex->Release();
     }
 
@@ -640,10 +435,7 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected identifier '' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"") != STRING::npos);
+        REQUIRE(msg.find(L"val") != STRING::npos);
         ex->Release();
     }
 
@@ -655,449 +447,13 @@
     catch(MgException* ex)
     {
         STRING msg = ex->GetExceptionMessage(TEST_LOCALE);
-        //ACE_DEBUG((LM_INFO, ACE_TEXT("Exception: %W\n"), msg.c_str()));
-        std::string assertMsg = "Expected string 'Foo' in exception message: ";
-        assertMsg += MgUtil::WideCharToMultiByte(msg);
-        CPPUNIT_ASSERT_MESSAGE(assertMsg, msg.find(L"Foo") != STRING::npos);
+        REQUIRE(msg.find(L"Foo") != STRING::npos);
         ex->Release();
     }
 }
 
-void TestMisc::TestCase_611()
+TEST_CASE("LineBuffer Conversion", "[TestMisc]")
 {
-    try
-    {
-        Ptr<MgResourceIdentifier> mapRes1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
-        Ptr<MgMap> map1 = new MgMap(m_siteConnection);
-        map1->Create(mapRes1, L"UnitTestSheboygan1");
-
-        Ptr<MgLayerGroup> detachedGroup = new MgLayerGroup(L"Detached");
-        Ptr<MgResourceIdentifier> ldf = new MgResourceIdentifier(L"Library://UnitTests/Layers/Parcels.LayerDefinition");
-        Ptr<MgLayer> layer = new MgLayer(ldf, m_svcResource);
-        layer->SetName(L"BelongsToDetachedGroup");
-        layer->SetLegendLabel(L"BelongsToDetachedGroup");
-        layer->SetGroup(detachedGroup);
-        Ptr<MgLayerCollection> mapLayers = map1->GetLayers();
-        mapLayers->Insert(0, layer);
-
-        CPPUNIT_ASSERT_THROW_MG(map1->Save(), MgGroupNotFoundException*);
-    }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
-
-void TestMisc::TestCase_833()
-{
-    try
-    {
-        Ptr<MgResourceIdentifier> mapRes1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan_833.MapDefinition");
-        Ptr<MgMap> map1 = new MgMap(m_siteConnection);
-        map1->Create(mapRes1, L"UnitTestSheboygan1");
-
-        Ptr<MgLayerGroupCollection> groups = map1->GetLayerGroups();
-        Ptr<MgLayerCollection> layers = map1->GetLayers();
-
-        //These are the ones initially hidden from the legend
-        Ptr<MgLayerGroup> group = groups->GetItem(L"Municipal");
-        Ptr<MgLayerBase> layer = layers->GetItem(L"HydrographicPolygons");
-
-        CPPUNIT_ASSERT(!group->GetLegendLabel().empty());
-        CPPUNIT_ASSERT(!layer->GetLegendLabel().empty());
-    }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
-
-void TestMisc::TestCase_1304()
-{
-    try
-    {
-        Ptr<MgResourceIdentifier> mapRes1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
-        Ptr<MgMap> map1 = new MgMap(m_siteConnection);
-        map1->Create(mapRes1, L"UnitTestSheboygan1");
-
-        Ptr<MgSelection> sel = new MgSelection(map1, L"");
-        Ptr<MgReadOnlyLayerCollection> selLayers = sel->GetLayers();
-        CPPUNIT_ASSERT_MESSAGE("Expected null MgReadOnlyLayerCollection", NULL == selLayers.p); 
-        sel->FromXml(L""); //Should be same result
-        selLayers = sel->GetLayers();
-        CPPUNIT_ASSERT_MESSAGE("Expected null MgReadOnlyLayerCollection", NULL == selLayers.p); 
-    }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
-
-void TestMisc::TestCase_CreateMapWithInitialDisplayParams()
-{
-    try 
-    {
-        Ptr<MgResourceIdentifier> mapRes1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
-        Ptr<MgMap> map = new MgMap(m_siteConnection);
-        map->Create(mapRes1, L"TestCase_CreateMapWithInitialDisplayParams", 800, 600, -87.45, 43.32, 8000.0, 256);
-
-        CPPUNIT_ASSERT_MESSAGE("Expected width of 800", map->GetDisplayWidth() == 800);
-        CPPUNIT_ASSERT_MESSAGE("Expected height of 600", map->GetDisplayHeight() == 600);
-        Ptr<MgPoint> pt = map->GetViewCenter();
-        Ptr<MgCoordinate> coord = pt->GetCoordinate();
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(coord->GetX(), -87.45, 0.001);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(coord->GetY(), 43.32, 0.001);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(map->GetViewScale(), 8000.0, 0.0001);
-        CPPUNIT_ASSERT_MESSAGE("Expected DPI of 256", map->GetDisplayDpi() == 256);
-    }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
-
-void TestMisc::TestCase_ApiVersionCheck()
-{
-    try
-    {
-        //Just making sure this macro behaves as we expect
-        CPPUNIT_ASSERT_MESSAGE("Expected 4.1.0 >= 4.0.0", MG_API_VERSION(4, 1, 0) >= MG_API_VERSION(4, 0, 0));
-        CPPUNIT_ASSERT_MESSAGE("Expected 4.0.0 >= 4.0.0", MG_API_VERSION(4, 0, 0) >= MG_API_VERSION(4, 0, 0));
-    }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
-
-void TestMisc::TestCase_MapLayerCollections()
-{
-    try
-    {
-        Ptr<MgResourceIdentifier> mapRes1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
-        Ptr<MgMap> map1 = new MgMap(m_siteConnection);
-        map1->Create(mapRes1, L"UnitTestSheboygan1");
-
-        Ptr<MgLayerGroup> detachedGroup = new MgLayerGroup(L"DetachedGroup");
-        Ptr<MgResourceIdentifier> ldf = new MgResourceIdentifier(L"Library://UnitTests/Layers/Parcels.LayerDefinition");
-        Ptr<MgLayer> detachedLayer = new MgLayer(ldf, m_svcResource);
-        detachedLayer->SetName(L"DetachedLayer");
-
-        Ptr<MgLayerCollection> mapLayers = map1->GetLayers();
-        Ptr<MgLayerGroupCollection> mapGroups = map1->GetLayerGroups();
-
-        //Remove() should be returning false when passing in layers/groups that don't belong
-        CPPUNIT_ASSERT(!mapLayers->Remove(detachedLayer));
-        CPPUNIT_ASSERT(!mapGroups->Remove(detachedGroup));
-    }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
-
-void TestMisc::TestCase_DoubleToStringWithDecimals()
-{
-    try
-    {
-        double d = 1.23456789032748754;
-
-        std::string s;
-        STRING ws;
-
-        MgUtil::DoubleToString(d, ws, 4);
-        MgUtil::DoubleToString(d, s, 4);
-
-        CPPUNIT_ASSERT(L"1.2346" == ws);
-        CPPUNIT_ASSERT("1.2346" == s);
-
-        ws.clear();
-        s.clear();
-
-        MgUtil::DoubleToString(d, ws, 8);
-        MgUtil::DoubleToString(d, s, 8);
-
-        CPPUNIT_ASSERT(L"1.23456789" == ws);
-        CPPUNIT_ASSERT("1.23456789" == s);
-
-        ws.clear();
-        s.clear();
-
-        std::string s1;
-        STRING ws1;
-        //This should be the equivalent to not even passing in precision at all
-        MgUtil::DoubleToString(d, ws, -1);
-        MgUtil::DoubleToString(d, s, -1);
-        MgUtil::DoubleToString(d, ws1);
-        MgUtil::DoubleToString(d, s1);
-
-        CPPUNIT_ASSERT(ws1 == ws);
-        CPPUNIT_ASSERT(s1 == s);
-
-        double d1 = 1.1;
-
-        ws.clear();
-        s.clear();
-
-        MgUtil::DoubleToString(d1, ws, 4);
-        MgUtil::DoubleToString(d1, s, 4);
-
-        CPPUNIT_ASSERT(L"1.1" == ws);
-        CPPUNIT_ASSERT("1.1" == s);
-
-        double d2 = 123.3457483434945;
-
-        ws.clear();
-        s.clear();
-
-        MgUtil::DoubleToString(d2, ws, 8);
-        MgUtil::DoubleToString(d2, s, 8);
-
-        CPPUNIT_ASSERT(L"123.34574834" == ws);
-        CPPUNIT_ASSERT("123.34574834" == s);
-    }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
-
-void TestMisc::TestCase_TryParseDouble()
-{
-    try
-    {
-        double dBad = 0.0;
-        CPPUNIT_ASSERT(!MgUtil::TryParseDouble(L"", dBad));
-        CPPUNIT_ASSERT(!MgUtil::TryParseDouble(L"abc", dBad));
-        CPPUNIT_ASSERT(!MgUtil::TryParseDouble(L"abc123", dBad));
-        CPPUNIT_ASSERT(!MgUtil::TryParseDouble(L"123.asd", dBad));
-        double d1 = 0.0;
-        CPPUNIT_ASSERT(MgUtil::TryParseDouble(L"123", d1));
-        CPPUNIT_ASSERT(123 == d1);
-        double d2 = 0.0;
-        CPPUNIT_ASSERT(MgUtil::TryParseDouble(L"123.23", d2));
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(123.23, d2, 0.001);
-        double d3 = 0.0;
-        CPPUNIT_ASSERT(MgUtil::TryParseDouble(L"0.1237483", d3));
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1237483, d3, 0.00000001);
-        double d4 = 0.0;
-        CPPUNIT_ASSERT(MgUtil::TryParseDouble(L"123.", d4));
-        CPPUNIT_ASSERT(123 == d4);
-        double d5 = 0.0;
-        CPPUNIT_ASSERT(MgUtil::TryParseDouble(L".1235", d5));
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1235, d5, 0.00001);
-    }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
-
-void TestMisc::TestCase_BadResourceIdentifier()
-{
-    try
-    {
-        Ptr<MgResourceIdentifier> resId = new MgResourceIdentifier(L"I'm a baaaaad id");
-        CPPUNIT_FAIL("This should've thrown");
-    }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_ASSERT(message.find(L"I'm a baaaaad id") != STRING::npos);
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
-
-// data structure which is passed to each thread
-struct GetConfigValueThreadData
-{
-    INT32 threadId;
-    bool success;
-    bool done;
-    STRING section;
-    STRING key;
-};
-
-ACE_THR_FUNC_RETURN GetConfigValueWorker(void* param)
-{
-    // get the data for this thread
-    GetConfigValueThreadData* threadData = (GetConfigValueThreadData*)param;
-    INT32 threadId = threadData->threadId;
-#ifdef _DEBUG
-    printf("> thread %d started\n", threadId);
-#endif
-
-    try
-    {
-        MgConfiguration* conf = MgConfiguration::GetInstance();
-        bool b = false;
-        conf->GetBoolValue(threadData->section, threadData->key, b, false);
-
-        threadData->success = true;
-    }
-    catch (MgException* e)
-    {
-        threadData->success = false;
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        threadData->success = false;
-        throw;
-    }
-
-#ifdef _DEBUG
-    //  printf("> thread %d done\n", threadId);
-#endif
-
-    threadData->done = true;
-    return 0;
-}
-
-void TestMisc::TestCase_ThreadSafeConfiguration()
-{
-    try
-    {
-        // specify the number of threads to use
-        const INT32 numThreads = MG_TEST_THREADS;
-        GetConfigValueThreadData threadData[numThreads];
-
-        // need a thread manager
-        ACE_Thread_Manager* manager = ACE_Thread_Manager::instance();
-
-        // initialize the thread data
-        for (INT32 i = 0; i < numThreads; i++)
-        {
-            threadData[i].threadId = i;
-            threadData[i].done = true;
-            threadData[i].success = true;
-            threadData[i].section = MgConfigProperties::GeneralPropertiesSection;
-            threadData[i].key = MgConfigProperties::GeneralPropertyMaxLogFileSizeEnabled;
-        }
-
-        INT32 nRequest = 0;
-        INT32 nSuccessful = 0;
-        INT32 nFailed = 0;
-        bool bExceptionOcurred = false;
-        for (;;)
-        {
-            INT32 dc = 0;
-            for (INT32 i = 0; i < numThreads; i++)
-            {
-                // check if the thread is available
-                if (threadData[i].done)
-                {
-                    if (threadData[i].success)
-                        nSuccessful++;
-                    else
-                        nFailed++;
-
-                    // Reset for next run
-                    threadData[i].success = true;
-                    threadData[i].done = false;
-
-                    // spawn a new thread using a specific group id
-                    int thid = manager->spawn(ACE_THR_FUNC(GetConfigValueWorker), &threadData[i], 0, NULL, NULL, 0, THREAD_GROUP);
-                    nRequest++;
-                }
-            }
-
-            // move on if all threads are done
-            if ((nRequest > TESTREQUESTS) || (bExceptionOcurred))
-                break;
-
-            // under Linux we get a deadlock if we don't call this every once in a while
-            if (nRequest % 25 == 0)
-                manager->wait_grp(THREAD_GROUP);
-            else
-            {
-                // pause briefly (10ms) before checking again
-                ACE_Time_Value t(0, 10000);
-                ACE_OS::sleep(t);
-            }
-        }
-
-        // make sure all threads in the group have completed
-        manager->wait_grp(THREAD_GROUP);
-
-        for (INT32 i = 0; i < numThreads; i++)
-        {
-            if (threadData[i].success)
-                nSuccessful++;
-            else
-                nFailed++;
-        }
-
-        CPPUNIT_ASSERT(nFailed == 0);
-    }
-    catch (MgException* e)
-    {
-        STRING message = e->GetDetails(TEST_LOCALE);
-        SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
-    }
-    catch (...)
-    {
-        throw;
-    }
-}
-
-void TestMisc::TestCase_LineBuffer_Conversion()
-{
     //This isn't really a test, it's more verification and internal documentation
     //of how LineBuffers are meant to be represented for various geometry types
     try
@@ -1123,10 +479,10 @@
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(1 == lb.geom_count());
-            CPPUNIT_ASSERT(1 == lb.point_count());
-            CPPUNIT_ASSERT(30 == lb.x_coord(0));
-            CPPUNIT_ASSERT(10 == lb.y_coord(0));
+            REQUIRE(1 == lb.geom_count());
+            REQUIRE(1 == lb.point_count());
+            REQUIRE(30 == lb.x_coord(0));
+            REQUIRE(10 == lb.y_coord(0));
         }
 
         //MultiPoint
@@ -1137,16 +493,16 @@
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(4 == lb.geom_count());
-            CPPUNIT_ASSERT(4 == lb.point_count());
-            CPPUNIT_ASSERT(10 == lb.x_coord(0));
-            CPPUNIT_ASSERT(40 == lb.y_coord(0));
-            CPPUNIT_ASSERT(40 == lb.x_coord(1));
-            CPPUNIT_ASSERT(30 == lb.y_coord(1));
-            CPPUNIT_ASSERT(20 == lb.x_coord(2));
-            CPPUNIT_ASSERT(20 == lb.y_coord(2));
-            CPPUNIT_ASSERT(30 == lb.x_coord(3));
-            CPPUNIT_ASSERT(10 == lb.y_coord(3));
+            REQUIRE(4 == lb.geom_count());
+            REQUIRE(4 == lb.point_count());
+            REQUIRE(10 == lb.x_coord(0));
+            REQUIRE(40 == lb.y_coord(0));
+            REQUIRE(40 == lb.x_coord(1));
+            REQUIRE(30 == lb.y_coord(1));
+            REQUIRE(20 == lb.x_coord(2));
+            REQUIRE(20 == lb.y_coord(2));
+            REQUIRE(30 == lb.x_coord(3));
+            REQUIRE(10 == lb.y_coord(3));
         }
 
         //LineString
@@ -1158,9 +514,9 @@
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
             int lineIdx = 0;
-            CPPUNIT_ASSERT(1 == lb.geom_count());
-            CPPUNIT_ASSERT(1 == lb.cntr_count());
-            CPPUNIT_ASSERT(3 == lb.cntr_size(lineIdx));
+            REQUIRE(1 == lb.geom_count());
+            REQUIRE(1 == lb.cntr_count());
+            REQUIRE(3 == lb.cntr_size(lineIdx));
 
             auto ptOffset = lb.contour_start_point(lineIdx);
             for (int i = 0; i < lb.cntr_size(lineIdx); i++)
@@ -1170,16 +526,16 @@
                 switch (i)
                 {
                 case 0:
-                    CPPUNIT_ASSERT(30 == x);
-                    CPPUNIT_ASSERT(10 == y);
+                    REQUIRE(30 == x);
+                    REQUIRE(10 == y);
                     break;
                 case 1:
-                    CPPUNIT_ASSERT(10 == x);
-                    CPPUNIT_ASSERT(30 == y);
+                    REQUIRE(10 == x);
+                    REQUIRE(30 == y);
                     break;
                 case 2:
-                    CPPUNIT_ASSERT(40 == x);
-                    CPPUNIT_ASSERT(40 == y);
+                    REQUIRE(40 == x);
+                    REQUIRE(40 == y);
                     break;
                 }
             }
@@ -1193,12 +549,12 @@
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(2 == lb.geom_count());
-            CPPUNIT_ASSERT(1 == lb.geom_size(0));
-            CPPUNIT_ASSERT(1 == lb.geom_size(1));
-            CPPUNIT_ASSERT(2 == lb.cntr_count());
-            CPPUNIT_ASSERT(3 == lb.cntr_size(0));
-            CPPUNIT_ASSERT(4 == lb.cntr_size(1));
+            REQUIRE(2 == lb.geom_count());
+            REQUIRE(1 == lb.geom_size(0));
+            REQUIRE(1 == lb.geom_size(1));
+            REQUIRE(2 == lb.cntr_count());
+            REQUIRE(3 == lb.cntr_size(0));
+            REQUIRE(4 == lb.cntr_size(1));
 
             //LineString 1
             {
@@ -1210,16 +566,16 @@
                     switch (i)
                     {
                     case 0:
-                        CPPUNIT_ASSERT(10 == x);
-                        CPPUNIT_ASSERT(10 == y);
+                        REQUIRE(10 == x);
+                        REQUIRE(10 == y);
                         break;
                     case 1:
-                        CPPUNIT_ASSERT(20 == x);
-                        CPPUNIT_ASSERT(20 == y);
+                        REQUIRE(20 == x);
+                        REQUIRE(20 == y);
                         break;
                     case 2:
-                        CPPUNIT_ASSERT(10 == x);
-                        CPPUNIT_ASSERT(40 == y);
+                        REQUIRE(10 == x);
+                        REQUIRE(40 == y);
                         break;
                     }
                 }
@@ -1235,20 +591,20 @@
                     switch (i)
                     {
                     case 0:
-                        CPPUNIT_ASSERT(40 == x);
-                        CPPUNIT_ASSERT(40 == y);
+                        REQUIRE(40 == x);
+                        REQUIRE(40 == y);
                         break;
                     case 1:
-                        CPPUNIT_ASSERT(30 == x);
-                        CPPUNIT_ASSERT(30 == y);
+                        REQUIRE(30 == x);
+                        REQUIRE(30 == y);
                         break;
                     case 2:
-                        CPPUNIT_ASSERT(40 == x);
-                        CPPUNIT_ASSERT(20 == y);
+                        REQUIRE(40 == x);
+                        REQUIRE(20 == y);
                         break;
                     case 3:
-                        CPPUNIT_ASSERT(30 == x);
-                        CPPUNIT_ASSERT(10 == y);
+                        REQUIRE(30 == x);
+                        REQUIRE(10 == y);
                         break;
                     }
                 }
@@ -1263,13 +619,13 @@
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(1 == lb.geom_count());
-            CPPUNIT_ASSERT(1 == lb.geom_size(0));
+            REQUIRE(1 == lb.geom_count());
+            REQUIRE(1 == lb.geom_size(0));
             auto cc = lb.cntr_count();
-            CPPUNIT_ASSERT(1 == cc);
+            REQUIRE(1 == cc);
 
             int lineIdx = 0;
-            CPPUNIT_ASSERT(5 == lb.cntr_size(lineIdx));
+            REQUIRE(5 == lb.cntr_size(lineIdx));
 
             auto ptOffset = lb.contour_start_point(lineIdx);
             for (int i = 0; i < lb.cntr_size(lineIdx); i++)
@@ -1279,24 +635,24 @@
                 switch (i)
                 {
                 case 0:
-                    CPPUNIT_ASSERT(30 == x);
-                    CPPUNIT_ASSERT(10 == y);
+                    REQUIRE(30 == x);
+                    REQUIRE(10 == y);
                     break;
                 case 1:
-                    CPPUNIT_ASSERT(40 == x);
-                    CPPUNIT_ASSERT(40 == y);
+                    REQUIRE(40 == x);
+                    REQUIRE(40 == y);
                     break;
                 case 2:
-                    CPPUNIT_ASSERT(20 == x);
-                    CPPUNIT_ASSERT(40 == y);
+                    REQUIRE(20 == x);
+                    REQUIRE(40 == y);
                     break;
                 case 3:
-                    CPPUNIT_ASSERT(10 == x);
-                    CPPUNIT_ASSERT(20 == y);
+                    REQUIRE(10 == x);
+                    REQUIRE(20 == y);
                     break;
                 case 4:
-                    CPPUNIT_ASSERT(30 == x);
-                    CPPUNIT_ASSERT(10 == y);
+                    REQUIRE(30 == x);
+                    REQUIRE(10 == y);
                     break;
                 }
             }
@@ -1310,14 +666,14 @@
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(1 == lb.geom_count());
-            CPPUNIT_ASSERT(2 == lb.geom_size(0));
+            REQUIRE(1 == lb.geom_count());
+            REQUIRE(2 == lb.geom_size(0));
             auto cc = lb.cntr_count();
-            CPPUNIT_ASSERT(2 == cc);
+            REQUIRE(2 == cc);
 
             //Outer Ring
             {
-                CPPUNIT_ASSERT(5 == lb.cntr_size(0));
+                REQUIRE(5 == lb.cntr_size(0));
                 auto ptOffset = lb.contour_start_point(0);
                 for (int i = 0; i < lb.cntr_size(0); i++)
                 {
@@ -1326,24 +682,24 @@
                     switch (i)
                     {
                     case 0:
-                        CPPUNIT_ASSERT(35 == x);
-                        CPPUNIT_ASSERT(10 == y);
+                        REQUIRE(35 == x);
+                        REQUIRE(10 == y);
                         break;
                     case 1:
-                        CPPUNIT_ASSERT(45 == x);
-                        CPPUNIT_ASSERT(45 == y);
+                        REQUIRE(45 == x);
+                        REQUIRE(45 == y);
                         break;
                     case 2:
-                        CPPUNIT_ASSERT(15 == x);
-                        CPPUNIT_ASSERT(40 == y);
+                        REQUIRE(15 == x);
+                        REQUIRE(40 == y);
                         break;
                     case 3:
-                        CPPUNIT_ASSERT(10 == x);
-                        CPPUNIT_ASSERT(20 == y);
+                        REQUIRE(10 == x);
+                        REQUIRE(20 == y);
                         break;
                     case 4:
-                        CPPUNIT_ASSERT(35 == x);
-                        CPPUNIT_ASSERT(10 == y);
+                        REQUIRE(35 == x);
+                        REQUIRE(10 == y);
                         break;
                     }
                 }
@@ -1351,7 +707,7 @@
 
             //Inner Ring
             {
-                CPPUNIT_ASSERT(4 == lb.cntr_size(1));
+                REQUIRE(4 == lb.cntr_size(1));
                 auto ptOffset = lb.contour_start_point(1);
                 for (int i = 0; i < lb.cntr_size(1); i++)
                 {
@@ -1360,20 +716,20 @@
                     switch (i)
                     {
                     case 0:
-                        CPPUNIT_ASSERT(20 == x);
-                        CPPUNIT_ASSERT(30 == y);
+                        REQUIRE(20 == x);
+                        REQUIRE(30 == y);
                         break;
                     case 1:
-                        CPPUNIT_ASSERT(35 == x);
-                        CPPUNIT_ASSERT(35 == y);
+                        REQUIRE(35 == x);
+                        REQUIRE(35 == y);
                         break;
                     case 2:
-                        CPPUNIT_ASSERT(30 == x);
-                        CPPUNIT_ASSERT(20 == y);
+                        REQUIRE(30 == x);
+                        REQUIRE(20 == y);
                         break;
                     case 3:
-                        CPPUNIT_ASSERT(20 == x);
-                        CPPUNIT_ASSERT(30 == y);
+                        REQUIRE(20 == x);
+                        REQUIRE(30 == y);
                         break;
                     }
                 }
@@ -1388,17 +744,17 @@
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(2 == lb.geom_count());
-            CPPUNIT_ASSERT(1 == lb.geom_size(0));
-            CPPUNIT_ASSERT(1 == lb.geom_size(1));
+            REQUIRE(2 == lb.geom_count());
+            REQUIRE(1 == lb.geom_size(0));
+            REQUIRE(1 == lb.geom_size(1));
             auto cc = lb.cntr_count();
-            CPPUNIT_ASSERT(2 == cc);
+            REQUIRE(2 == cc);
             auto closed1 = lb.contour_closed(0);
             auto closed2 = lb.contour_closed(1);
 
             //Polygon 1
             {
-                CPPUNIT_ASSERT(4 == lb.cntr_size(0));
+                REQUIRE(4 == lb.cntr_size(0));
                 auto ptOffset = lb.contour_start_point(0);
                 for (int i = 0; i < lb.cntr_size(0); i++)
                 {
@@ -1407,20 +763,20 @@
                     switch (i)
                     {
                     case 0:
-                        CPPUNIT_ASSERT(30 == x);
-                        CPPUNIT_ASSERT(20 == y);
+                        REQUIRE(30 == x);
+                        REQUIRE(20 == y);
                         break;
                     case 1:
-                        CPPUNIT_ASSERT(45 == x);
-                        CPPUNIT_ASSERT(40 == y);
+                        REQUIRE(45 == x);
+                        REQUIRE(40 == y);
                         break;
                     case 2:
-                        CPPUNIT_ASSERT(10 == x);
-                        CPPUNIT_ASSERT(40 == y);
+                        REQUIRE(10 == x);
+                        REQUIRE(40 == y);
                         break;
                     case 3:
-                        CPPUNIT_ASSERT(30 == x);
-                        CPPUNIT_ASSERT(20 == y);
+                        REQUIRE(30 == x);
+                        REQUIRE(20 == y);
                         break;
                     }
                 }
@@ -1428,7 +784,7 @@
 
             //Polygon 2
             {
-                CPPUNIT_ASSERT(5 == lb.cntr_size(1));
+                REQUIRE(5 == lb.cntr_size(1));
                 auto ptOffset = lb.contour_start_point(1);
                 for (int i = 0; i < lb.cntr_size(1); i++)
                 {
@@ -1437,24 +793,24 @@
                     switch (i)
                     {
                     case 0:
-                        CPPUNIT_ASSERT(15 == x);
-                        CPPUNIT_ASSERT(5 == y);
+                        REQUIRE(15 == x);
+                        REQUIRE(5 == y);
                         break;
                     case 1:
-                        CPPUNIT_ASSERT(40 == x);
-                        CPPUNIT_ASSERT(10 == y);
+                        REQUIRE(40 == x);
+                        REQUIRE(10 == y);
                         break;
                     case 2:
-                        CPPUNIT_ASSERT(10 == x);
-                        CPPUNIT_ASSERT(20 == y);
+                        REQUIRE(10 == x);
+                        REQUIRE(20 == y);
                         break;
                     case 3:
-                        CPPUNIT_ASSERT(5 == x);
-                        CPPUNIT_ASSERT(10 == y);
+                        REQUIRE(5 == x);
+                        REQUIRE(10 == y);
                         break;
                     case 4:
-                        CPPUNIT_ASSERT(15 == x);
-                        CPPUNIT_ASSERT(5 == y);
+                        REQUIRE(15 == x);
+                        REQUIRE(5 == y);
                         break;
                     }
                 }
@@ -1469,7 +825,7 @@
 
             Ptr<MgGeometry> g2 = agfRw.Read(oagf);
             STRING owkt = wktRw.Write(g2);
-            CPPUNIT_ASSERT(owkt == mpWkt1);
+            REQUIRE(owkt == mpWkt1);
         }
 
         //MultiPolygon 2
@@ -1480,11 +836,11 @@
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(2 == lb.geom_count());
-            CPPUNIT_ASSERT(1 == lb.geom_size(0));
-            CPPUNIT_ASSERT(2 == lb.geom_size(1));
+            REQUIRE(2 == lb.geom_count());
+            REQUIRE(1 == lb.geom_size(0));
+            REQUIRE(2 == lb.geom_size(1));
             auto cc = lb.cntr_count();
-            CPPUNIT_ASSERT(3 == cc);
+            REQUIRE(3 == cc);
             auto closed1 = lb.contour_closed(0);
             auto closed2 = lb.contour_closed(1);
             auto closed3 = lb.contour_closed(2);
@@ -1491,7 +847,7 @@
 
             //Polygon 1
             {
-                CPPUNIT_ASSERT(4 == lb.cntr_size(0));
+                REQUIRE(4 == lb.cntr_size(0));
                 auto ptOffset = lb.contour_start_point(0);
                 for (int i = 0; i < lb.cntr_size(0); i++)
                 {
@@ -1500,20 +856,20 @@
                     switch (i)
                     {
                     case 0:
-                        CPPUNIT_ASSERT(40 == x);
-                        CPPUNIT_ASSERT(40 == y);
+                        REQUIRE(40 == x);
+                        REQUIRE(40 == y);
                         break;
                     case 1:
-                        CPPUNIT_ASSERT(20 == x);
-                        CPPUNIT_ASSERT(45 == y);
+                        REQUIRE(20 == x);
+                        REQUIRE(45 == y);
                         break;
                     case 2:
-                        CPPUNIT_ASSERT(45 == x);
-                        CPPUNIT_ASSERT(30 == y);
+                        REQUIRE(45 == x);
+                        REQUIRE(30 == y);
                         break;
                     case 3:
-                        CPPUNIT_ASSERT(40 == x);
-                        CPPUNIT_ASSERT(40 == y);
+                        REQUIRE(40 == x);
+                        REQUIRE(40 == y);
                         break;
                     }
                 }
@@ -1521,7 +877,7 @@
 
             //Polygon 2 (inner ring)
             {
-                CPPUNIT_ASSERT(6 == lb.cntr_size(1));
+                REQUIRE(6 == lb.cntr_size(1));
                 auto ptOffset = lb.contour_start_point(1);
                 for (int i = 0; i < lb.cntr_size(1); i++)
                 {
@@ -1530,28 +886,28 @@
                     switch (i)
                     {
                     case 0:
-                        CPPUNIT_ASSERT(20 == x);
-                        CPPUNIT_ASSERT(35 == y);
+                        REQUIRE(20 == x);
+                        REQUIRE(35 == y);
                         break;
                     case 1:
-                        CPPUNIT_ASSERT(10 == x);
-                        CPPUNIT_ASSERT(30 == y);
+                        REQUIRE(10 == x);
+                        REQUIRE(30 == y);
                         break;
                     case 2:
-                        CPPUNIT_ASSERT(10 == x);
-                        CPPUNIT_ASSERT(10 == y);
+                        REQUIRE(10 == x);
+                        REQUIRE(10 == y);
                         break;
                     case 3:
-                        CPPUNIT_ASSERT(30 == x);
-                        CPPUNIT_ASSERT(5 == y);
+                        REQUIRE(30 == x);
+                        REQUIRE(5 == y);
                         break;
                     case 4:
-                        CPPUNIT_ASSERT(45 == x);
-                        CPPUNIT_ASSERT(20 == y);
+                        REQUIRE(45 == x);
+                        REQUIRE(20 == y);
                         break;
                     case 5:
-                        CPPUNIT_ASSERT(20 == x);
-                        CPPUNIT_ASSERT(35 == y);
+                        REQUIRE(20 == x);
+                        REQUIRE(35 == y);
                         break;
                     }
                 }
@@ -1559,7 +915,7 @@
 
             //Polygon 2 (outer ring)
             {
-                CPPUNIT_ASSERT(4 == lb.cntr_size(2));
+                REQUIRE(4 == lb.cntr_size(2));
                 auto ptOffset = lb.contour_start_point(2);
                 for (int i = 0; i < lb.cntr_size(2); i++)
                 {
@@ -1568,20 +924,20 @@
                     switch (i)
                     {
                     case 0:
-                        CPPUNIT_ASSERT(30 == x);
-                        CPPUNIT_ASSERT(20 == y);
+                        REQUIRE(30 == x);
+                        REQUIRE(20 == y);
                         break;
                     case 1:
-                        CPPUNIT_ASSERT(20 == x);
-                        CPPUNIT_ASSERT(15 == y);
+                        REQUIRE(20 == x);
+                        REQUIRE(15 == y);
                         break;
                     case 2:
-                        CPPUNIT_ASSERT(20 == x);
-                        CPPUNIT_ASSERT(25 == y);
+                        REQUIRE(20 == x);
+                        REQUIRE(25 == y);
                         break;
                     case 3:
-                        CPPUNIT_ASSERT(30 == x);
-                        CPPUNIT_ASSERT(20 == y);
+                        REQUIRE(30 == x);
+                        REQUIRE(20 == y);
                         break;
                     }
                 }
@@ -1596,7 +952,7 @@
 
             Ptr<MgGeometry> g2 = agfRw.Read(oagf);
             STRING owkt = wktRw.Write(g2);
-            CPPUNIT_ASSERT(owkt == mpWkt2);
+            REQUIRE(owkt == mpWkt2);
         }
     }
     catch (MgException* e)
@@ -1603,10 +959,483 @@
     {
         STRING message = e->GetDetails(TEST_LOCALE);
         SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
     }
     catch (...)
     {
         throw;
     }
+}
+
+TEST_CASE("MgUtil::TryParseDouble", "[TestMisc]")
+{
+    try
+    {
+        double dBad = 0.0;
+        REQUIRE(!MgUtil::TryParseDouble(L"", dBad));
+        REQUIRE(!MgUtil::TryParseDouble(L"abc", dBad));
+        REQUIRE(!MgUtil::TryParseDouble(L"abc123", dBad));
+        REQUIRE(!MgUtil::TryParseDouble(L"123.asd", dBad));
+        double d1 = 0.0;
+        REQUIRE(MgUtil::TryParseDouble(L"123", d1));
+        REQUIRE(123 == d1);
+        double d2 = 0.0;
+        REQUIRE(MgUtil::TryParseDouble(L"123.23", d2));
+        REQUIRE(d2 == Approx(123.23));
+        double d3 = 0.0;
+        REQUIRE(MgUtil::TryParseDouble(L"0.1237483", d3));
+        REQUIRE(d3 == Approx(0.1237483));
+        double d4 = 0.0;
+        REQUIRE(MgUtil::TryParseDouble(L"123.", d4));
+        REQUIRE(123 == d4);
+        double d5 = 0.0;
+        REQUIRE(MgUtil::TryParseDouble(L".1235", d5));
+        REQUIRE(d5 == Approx(0.1235));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+TEST_CASE("Bad resource identifier", "[TestMisc]")
+{
+    try
+    {
+        Ptr<MgResourceIdentifier> resId = new MgResourceIdentifier(L"I'm a baaaaad id");
+        FAIL("This should've thrown");
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        REQUIRE(message.find(L"I'm a baaaaad id") != STRING::npos);
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+TEST_CASE("Double to String with decimals", "[TestMisc]")
+{
+    try
+    {
+        double d = 1.23456789032748754;
+
+        std::string s;
+        STRING ws;
+
+        MgUtil::DoubleToString(d, ws, 4);
+        MgUtil::DoubleToString(d, s, 4);
+
+        REQUIRE(L"1.2346" == ws);
+        REQUIRE("1.2346" == s);
+
+        ws.clear();
+        s.clear();
+
+        MgUtil::DoubleToString(d, ws, 8);
+        MgUtil::DoubleToString(d, s, 8);
+
+        REQUIRE(L"1.23456789" == ws);
+        REQUIRE("1.23456789" == s);
+
+        ws.clear();
+        s.clear();
+
+        std::string s1;
+        STRING ws1;
+        //This should be the equivalent to not even passing in precision at all
+        MgUtil::DoubleToString(d, ws, -1);
+        MgUtil::DoubleToString(d, s, -1);
+        MgUtil::DoubleToString(d, ws1);
+        MgUtil::DoubleToString(d, s1);
+
+        REQUIRE(ws1 == ws);
+        REQUIRE(s1 == s);
+
+        double d1 = 1.1;
+
+        ws.clear();
+        s.clear();
+
+        MgUtil::DoubleToString(d1, ws, 4);
+        MgUtil::DoubleToString(d1, s, 4);
+
+        REQUIRE(L"1.1" == ws);
+        REQUIRE("1.1" == s);
+
+        double d2 = 123.3457483434945;
+
+        ws.clear();
+        s.clear();
+
+        MgUtil::DoubleToString(d2, ws, 8);
+        MgUtil::DoubleToString(d2, s, 8);
+
+        REQUIRE(L"123.34574834" == ws);
+        REQUIRE("123.34574834" == s);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+TEST_CASE("API Version Check", "[TestMisc]")
+{
+    try
+    {
+        //Just making sure this macro behaves as we expect
+        REQUIRE(MG_API_VERSION(4, 1, 0) >= MG_API_VERSION(4, 0, 0));
+        REQUIRE(MG_API_VERSION(4, 0, 0) >= MG_API_VERSION(4, 0, 0));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+TEST_CASE("Trac #611", "[TestMisc]")
+{
+    try
+    {
+        Ptr<MgResourceService> m_svcResource = TestMiscSetup::CreateResourceService();
+        // Initialize a site connection.
+        Ptr<MgServerSiteService> svcSite = TestMiscSetup::CreateSiteService();
+        Ptr<MgSiteConnection> m_siteConnection = TestMiscSetup::CreateSiteConnection(svcSite);
+
+        // ========================== Begin Test ======================== //
+
+        Ptr<MgResourceIdentifier> mapRes1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+        Ptr<MgMap> map1 = new MgMap(m_siteConnection);
+        map1->Create(mapRes1, L"UnitTestSheboygan1");
+
+        Ptr<MgLayerGroup> detachedGroup = new MgLayerGroup(L"Detached");
+        Ptr<MgResourceIdentifier> ldf = new MgResourceIdentifier(L"Library://UnitTests/Layers/Parcels.LayerDefinition");
+        Ptr<MgLayer> layer = new MgLayer(ldf, m_svcResource);
+        layer->SetName(L"BelongsToDetachedGroup");
+        layer->SetLegendLabel(L"BelongsToDetachedGroup");
+        layer->SetGroup(detachedGroup);
+        Ptr<MgLayerCollection> mapLayers = map1->GetLayers();
+        mapLayers->Insert(0, layer);
+
+        try
+        {
+            map1->Save();
+            FAIL("Expected MgGroupNotFoundException to be thrown");
+        }
+        catch (MgGroupNotFoundException* gnex)
+        {
+            SAFE_RELEASE(gnex);
+        }
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+TEST_CASE("Trac #833", "[TestMisc]")
+{
+    try
+    {
+        // Initialize a site connection.
+        Ptr<MgServerSiteService> svcSite = TestMiscSetup::CreateSiteService();
+        Ptr<MgSiteConnection> m_siteConnection = TestMiscSetup::CreateSiteConnection(svcSite);
+
+        // ========================== Begin Test ======================== //
+
+        Ptr<MgResourceIdentifier> mapRes1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan_833.MapDefinition");
+        Ptr<MgMap> map1 = new MgMap(m_siteConnection);
+        map1->Create(mapRes1, L"UnitTestSheboygan1");
+
+        Ptr<MgLayerGroupCollection> groups = map1->GetLayerGroups();
+        Ptr<MgLayerCollection> layers = map1->GetLayers();
+
+        //These are the ones initially hidden from the legend
+        Ptr<MgLayerGroup> group = groups->GetItem(L"Municipal");
+        Ptr<MgLayerBase> layer = layers->GetItem(L"HydrographicPolygons");
+
+        REQUIRE(!group->GetLegendLabel().empty());
+        REQUIRE(!layer->GetLegendLabel().empty());
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+TEST_CASE("Trac #1304", "[TestMisc]")
+{
+    try
+    {
+        // Initialize a site connection.
+        Ptr<MgServerSiteService> svcSite = TestMiscSetup::CreateSiteService();
+        Ptr<MgSiteConnection> m_siteConnection = TestMiscSetup::CreateSiteConnection(svcSite);
+
+        // ========================== Begin Test ======================== //
+
+        Ptr<MgResourceIdentifier> mapRes1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+        Ptr<MgMap> map1 = new MgMap(m_siteConnection);
+        map1->Create(mapRes1, L"UnitTestSheboygan1");
+
+        Ptr<MgSelection> sel = new MgSelection(map1, L"");
+        Ptr<MgReadOnlyLayerCollection> selLayers = sel->GetLayers();
+        REQUIRE(nullptr == selLayers.p);
+        sel->FromXml(L""); //Should be same result
+        selLayers = sel->GetLayers();
+        REQUIRE(nullptr == selLayers.p);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+TEST_CASE("Create Map w/ initial display params", "[TestMisc]")
+{
+    try 
+    {
+        // Initialize a site connection.
+        Ptr<MgServerSiteService> svcSite = TestMiscSetup::CreateSiteService();
+        Ptr<MgSiteConnection> m_siteConnection = TestMiscSetup::CreateSiteConnection(svcSite);
+
+        // ========================== Begin Test ======================== //
+
+        Ptr<MgResourceIdentifier> mapRes1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+        Ptr<MgMap> map = new MgMap(m_siteConnection);
+        map->Create(mapRes1, L"TestCase_CreateMapWithInitialDisplayParams", 800, 600, -87.45, 43.32, 8000.0, 256);
+
+        REQUIRE(map->GetDisplayWidth() == 800);
+        REQUIRE(map->GetDisplayHeight() == 600);
+        Ptr<MgPoint> pt = map->GetViewCenter();
+        Ptr<MgCoordinate> coord = pt->GetCoordinate();
+        REQUIRE(coord->GetX() == Approx(-87.45));
+        REQUIRE(coord->GetY() == Approx(43.32));
+        REQUIRE(map->GetViewScale() == Approx(8000.0));
+        REQUIRE(map->GetDisplayDpi() == 256);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+TEST_CASE("Map Layer Collection", "[TestMisc]")
+{
+    try
+    {
+        Ptr<MgResourceService> m_svcResource = TestMiscSetup::CreateResourceService();
+        // Initialize a site connection.
+        Ptr<MgServerSiteService> svcSite = TestMiscSetup::CreateSiteService();
+        Ptr<MgSiteConnection> m_siteConnection = TestMiscSetup::CreateSiteConnection(svcSite);
+
+        // ========================== Begin Test ======================== //
+
+        Ptr<MgResourceIdentifier> mapRes1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+        Ptr<MgMap> map1 = new MgMap(m_siteConnection);
+        map1->Create(mapRes1, L"UnitTestSheboygan1");
+
+        Ptr<MgLayerGroup> detachedGroup = new MgLayerGroup(L"DetachedGroup");
+        Ptr<MgResourceIdentifier> ldf = new MgResourceIdentifier(L"Library://UnitTests/Layers/Parcels.LayerDefinition");
+        Ptr<MgLayer> detachedLayer = new MgLayer(ldf, m_svcResource);
+        detachedLayer->SetName(L"DetachedLayer");
+
+        Ptr<MgLayerCollection> mapLayers = map1->GetLayers();
+        Ptr<MgLayerGroupCollection> mapGroups = map1->GetLayerGroups();
+
+        //Remove() should be returning false when passing in layers/groups that don't belong
+        REQUIRE(!mapLayers->Remove(detachedLayer));
+        REQUIRE(!mapGroups->Remove(detachedGroup));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+// data structure which is passed to each thread
+struct GetConfigValueThreadData
+{
+    INT32 threadId;
+    bool success;
+    bool done;
+    STRING section;
+    STRING key;
+};
+
+ACE_THR_FUNC_RETURN GetConfigValueWorker(void* param)
+{
+    // get the data for this thread
+    GetConfigValueThreadData* threadData = (GetConfigValueThreadData*)param;
+    INT32 threadId = threadData->threadId;
+#ifdef _DEBUG
+    printf("> thread %d started\n", threadId);
+#endif
+
+    try
+    {
+        MgConfiguration* conf = MgConfiguration::GetInstance();
+        bool b = false;
+        conf->GetBoolValue(threadData->section, threadData->key, b, false);
+
+        threadData->success = true;
+    }
+    catch (MgException* e)
+    {
+        threadData->success = false;
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        threadData->success = false;
+        throw;
+    }
+
+#ifdef _DEBUG
+    //  printf("> thread %d done\n", threadId);
+#endif
+
+    threadData->done = true;
+    return 0;
+}
+
+TEST_CASE("Thread-safe configuration", "[TestMisc]")
+{
+    try
+    {
+        // specify the number of threads to use
+        const INT32 numThreads = MG_TEST_THREADS;
+        GetConfigValueThreadData threadData[numThreads];
+
+        // need a thread manager
+        ACE_Thread_Manager* manager = ACE_Thread_Manager::instance();
+
+        // initialize the thread data
+        for (INT32 i = 0; i < numThreads; i++)
+        {
+            threadData[i].threadId = i;
+            threadData[i].done = true;
+            threadData[i].success = true;
+            threadData[i].section = MgConfigProperties::GeneralPropertiesSection;
+            threadData[i].key = MgConfigProperties::GeneralPropertyMaxLogFileSizeEnabled;
+        }
+
+        INT32 nRequest = 0;
+        INT32 nSuccessful = 0;
+        INT32 nFailed = 0;
+        bool bExceptionOcurred = false;
+        for (;;)
+        {
+            INT32 dc = 0;
+            for (INT32 i = 0; i < numThreads; i++)
+            {
+                // check if the thread is available
+                if (threadData[i].done)
+                {
+                    if (threadData[i].success)
+                        nSuccessful++;
+                    else
+                        nFailed++;
+
+                    // Reset for next run
+                    threadData[i].success = true;
+                    threadData[i].done = false;
+
+                    // spawn a new thread using a specific group id
+                    int thid = manager->spawn(ACE_THR_FUNC(GetConfigValueWorker), &threadData[i], 0, NULL, NULL, 0, THREAD_GROUP);
+                    nRequest++;
+                }
+            }
+
+            // move on if all threads are done
+            if ((nRequest > TESTREQUESTS) || (bExceptionOcurred))
+                break;
+
+            // under Linux we get a deadlock if we don't call this every once in a while
+            if (nRequest % 25 == 0)
+                manager->wait_grp(THREAD_GROUP);
+            else
+            {
+                // pause briefly (10ms) before checking again
+                ACE_Time_Value t(0, 10000);
+                ACE_OS::sleep(t);
+            }
+        }
+
+        // make sure all threads in the group have completed
+        manager->wait_grp(THREAD_GROUP);
+
+        for (INT32 i = 0; i < numThreads; i++)
+        {
+            if (threadData[i].success)
+                nSuccessful++;
+            else
+                nFailed++;
+        }
+
+        REQUIRE(nFailed == 0);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
 }
\ No newline at end of file

Modified: sandbox/jng/catch2/Server/src/UnitTesting/UnitTesting.cpp
===================================================================
--- sandbox/jng/catch2/Server/src/UnitTesting/UnitTesting.cpp	2020-07-07 12:06:40 UTC (rev 9650)
+++ sandbox/jng/catch2/Server/src/UnitTesting/UnitTesting.cpp	2020-07-07 13:24:42 UTC (rev 9651)
@@ -29,6 +29,11 @@
 
 int Execute(CREFSTRING fileName, CREFSTRING test)
 {
+    // Set the default user information for this test run.
+    // Any specific test case may overwrite these information.
+    Ptr<MgUserInformation> userInfo = new MgUserInformation(MgUser::Administrator, L"");
+    MgUserInformation::SetCurrentUserInfo(userInfo);
+
     Catch::Session session;
     int nResult = session.run();
 

Modified: sandbox/jng/catch2/Server/src/UnitTesting/UnitTesting.vcxproj
===================================================================
--- sandbox/jng/catch2/Server/src/UnitTesting/UnitTesting.vcxproj	2020-07-07 12:06:40 UTC (rev 9650)
+++ sandbox/jng/catch2/Server/src/UnitTesting/UnitTesting.vcxproj	2020-07-07 13:24:42 UTC (rev 9651)
@@ -208,7 +208,6 @@
     <ClInclude Include="TestLogManagerThread.h" />
     <ClInclude Include="TestMappingService.h" />
     <ClInclude Include="TestMdfModel.h" />
-    <ClInclude Include="TestMisc.h" />
     <ClInclude Include="TestPerformance.h" />
     <ClInclude Include="TestProfilingService.h" />
     <ClInclude Include="TestRenderingService.h" />



More information about the mapguide-commits mailing list