diff --git a/.gitignore b/.gitignore index 26d12263..139ca0d5 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ overlay/ .vs/ obj/ bin/ +TestResults/ ########### # Windows # diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..0360b22a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,59 @@ +# Control file for continuous integration testing at http://travis-ci.org/ + +# ignore release tags +branches: + except: + /^RAIntegration.\d+\.\d+(\.\d+)?(-\S*)?$/ + +language: cpp + + +jobs: + include: + - name: "Win32 DLL" + os: windows + # builds with visualstudio2017buildtools - implicitly supports v141_xp target + script: ./BuildAll.bat Release x86 + + - name: "Win64 DLL" + os: windows + # builds with visualstudio2017buildtools - implicitly supports v141_xp target + script: ./BuildAll.bat Release x64 + + - name: "Win32 Tests" + os: windows + install: + # CppUnitTestFramework, v141_xp, afxres.h + - choco install visualstudio2019community --package-parameters "--add Microsoft.VisualStudio.Component.WinXP --add Microsoft.VisualStudio.Component.VC.ATLMFC" + # atlbase.h + - choco install visualstudio2019-workload-nativedesktop + script: ./BuildAll.bat Tests x86 + + - name: "Win64 Tests" + os: windows + install: + # CppUnitTestFramework, v141_xp, afxres.h + - choco install visualstudio2019community --package-parameters "--add Microsoft.VisualStudio.Component.WinXP --add Microsoft.VisualStudio.Component.VC.ATLMFC" + # atlbase.h + - choco install visualstudio2019-workload-nativedesktop + script: ./BuildAll.bat Tests x64 + + - name: "Win32 Analysis" + os: windows + install: + # CppUnitTestFramework, atlbase.h, afxres.h + - choco install visualstudio2019community --package-parameters "--add Microsoft.VisualStudio.Component.VC.ATLMFC" + # Microsoft.Cpp.Default.props + - choco install visualstudio2019-workload-vctools + # atlbase.h + - choco install visualstudio2019-workload-nativedesktop + script: ./BuildAll.bat Analysis x86 + + - name: "Win64 Analysis" + os: windows + install: + # CppUnitTestFramework, atlbase.h, afxres.h + - choco install visualstudio2019community --package-parameters "--add Microsoft.VisualStudio.Component.VC.ATLMFC" + # Microsoft.Cpp.Default.props, atlbase.h + - choco install visualstudio2019-workload-nativedesktop + script: ./BuildAll.bat Analysis x64 diff --git a/BuildAll.bat b/BuildAll.bat index 9799a24f..5335a2b3 100644 --- a/BuildAll.bat +++ b/BuildAll.bat @@ -17,6 +17,7 @@ set W64=0 for %%A in (%*) do ( if /I "%%A" == "Clean" ( set BUILDCLEAN=1 + del %BUILDLOG% ) else if /I "%%A" == "Debug" ( set DEBUG=1 set BUILDALL=0 @@ -48,6 +49,12 @@ if %W32% equ 0 if %W64% equ 0 ( set W64=1 ) +rem === If building tests, make sure the DLL exists for the Integration test === +if %TESTS% equ 1 if %RELEASE% equ 0 ( + if %W32% equ 1 if not exist bin\Win32\Release\RA_Integration.dll set RELEASE=1 + if %W64% equ 1 if not exist bin\x64\Release\RA_Integration.dll set RELEASE=1 +) + rem === Get hash for current code state === git log --oneline -1 > Temp.txt @@ -72,14 +79,20 @@ rem === Initialize Visual Studio environment === echo Initializing Visual Studio environment if "%VSINSTALLDIR%"=="" set VSINSTALLDIR=%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\ -if not exist "%VSINSTALLDIR%" set VSINSTALLDIR="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\" +if not exist "%VSINSTALLDIR%" set VSINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\ +if not exist "%VSINSTALLDIR%" set VSINSTALLDIR=%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\ +if not exist "%VSINSTALLDIR%" set VSINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\ if not exist "%VSINSTALLDIR%" ( echo Could not determine VSINSTALLDIR exit /B 1 ) echo using VSINSTALLDIR=%VSINSTALLDIR% -call "%VSINSTALLDIR%VC\Auxiliary\Build\vcvars32.bat" +if "%VSDEVCMD%"=="" set VSDEVCMD=%VSINSTALLDIR%Common7\Tools\VsDevCmd.bat +if not exist "%VSDEVCMD%" set VSDEVCMD=%VSINSTALLDIR%VC\Auxiliary\Build\vcvars32.bat +set VSCMD_SKIP_SENDTELEMETRY=1 +echo calling "%VSDEVCMD%" +call "%VSDEVCMD%" rem === Build each project === @@ -116,7 +129,7 @@ if %BUILDCLEAN% equ 1 ( ) ) -exit /B 0 +exit /B %ERRORLEVEL% rem === Build subroutine === @@ -128,7 +141,7 @@ set CONFIG=%~2 if %W32% equ 1 call :build2 %PROJECT% %CONFIG% Win32 if %W64% equ 1 call :build2 %PROJECT% %CONFIG% x64 -exit /B 0 +exit /B %ERRORLEVEL% :build2 @@ -170,7 +183,7 @@ set RESULT=%ERRORLEVEL% rem === If build failed, bail === if not %RESULT% equ 0 ( - echo %~1 %~2 failed: %RESULT% + echo %~1 %~2 %~3 failed: %RESULT% exit /B %RESULT% ) @@ -178,12 +191,12 @@ rem === If test project, run tests === if "%ESCAPEDKEY:~-6%" neq "_Tests" goto not_tests -set DLL_PATH=bin\%~2\tests\%~1.dll -if not exist %DLL_PATH% set DLL_PATH=bin\%~2\tests\%ESCAPEDKEY:~0,-6%\%~1.dll +set DLL_PATH=bin\%~3\%~2\tests\%~1.dll +if not exist %DLL_PATH% set DLL_PATH=bin\%~3\%~2\tests\%ESCAPEDKEY:~0,-6%\%~1.dll if not exist %DLL_PATH% ( - echo Could not locate %~1.dll - goto eof + echo "Could not locate %~1.dll (%~2 %~3)" + exit /B 1 ) rem -- the default VsTest.Console.exe (in CommonExtensions) does not return ERRORLEVEL, use one in Extensions instead @@ -191,9 +204,23 @@ rem -- see https://github.com/Microsoft/vstest/issues/1113 rem -- also, cannot use exists on path with spaces, so use dir and check result set VSTEST_PATH=%VSINSTALLDIR%Common7\IDE\Extensions\TestPlatform\VsTest.Console.exe dir "%VSTEST_PATH%" > nul || set VSTEST_PATH=VsTest.Console.exe -"%VSTEST_PATH%" %DLL_PATH% + +echo. +echo Calling %VSTEST_PATH% %DLL_PATH% + +"%VSTEST_PATH%" /Blame %DLL_PATH% set RESULT=%ERRORLEVEL% + +rem -- report any errors captured by /Blame -- +rem if exist TestResults ( +rem cd TestResults +rem for /R %%f in (*.xml) do ( +rem type "%%f" +rem ) +rem cd .. +rem ) + if not %RESULT% equ 0 exit /B %RESULT% :not_tests @@ -205,4 +232,4 @@ echo %PROJECTKEY% >> %BUILDLOG% rem === For termination from within function === :eof -exit /B 0 +exit /B %ERRORLEVEL% diff --git a/src/RA_Defs.h b/src/RA_Defs.h index 0076f21a..b2469b5d 100644 --- a/src/RA_Defs.h +++ b/src/RA_Defs.h @@ -31,10 +31,6 @@ // RA-Only using namespace std::string_literals; -_CONSTANT_VAR BUFSIZ{ 512U }; // ANSI buffer size -_CONSTANT_VAR BYTESTRING_BUFSIZ{ BUFSIZ*4U }; // should be the same for MultiByte -_CONSTANT_VAR WIDESTRING_BUFSIZ{ BUFSIZ*8U }; -_CONSTANT_VAR MAX_BUFSIZ{ BUFSIZ*128U }; // Try not to use this one #endif // RA_EXPORTS #include "data\Types.hh" diff --git a/src/RA_Integration.vcxproj b/src/RA_Integration.vcxproj index 9ecce2cd..a5ad38ff 100644 --- a/src/RA_Integration.vcxproj +++ b/src/RA_Integration.vcxproj @@ -363,7 +363,6 @@ RA_Integration {825CB292-F069-4B27-82CF-3417746ACDF3} RA_Integration - 10.0.16299.0 diff --git a/src/pch.h b/src/pch.h index 17e443cf..254d7a0d 100644 --- a/src/pch.h +++ b/src/pch.h @@ -36,7 +36,6 @@ /* C Stuff */ #include -#undef BUFSIZ // make it constexpr in RA_Defs /* STL Stuff */ #include // algorithm, iterator, tuple diff --git a/src/rcheevos.vcxproj b/src/rcheevos.vcxproj index 8a66e2f5..a427848b 100644 --- a/src/rcheevos.vcxproj +++ b/src/rcheevos.vcxproj @@ -23,29 +23,28 @@ {9D55EBE7-1392-4FA1-A9B9-F022F764CE35} Win32Proj RAIntegrationRcheevos - 7.0 rcheevos StaticLibrary true - v141_xp + $(DefaultPlatformToolset) StaticLibrary true - v141_xp + $(DefaultPlatformToolset) StaticLibrary false - v141_xp + $(DefaultPlatformToolset) StaticLibrary false - v141_xp + $(DefaultPlatformToolset) diff --git a/src/ui/ViewModelBase.hh b/src/ui/ViewModelBase.hh index 7a1e0793..a3b46505 100644 --- a/src/ui/ViewModelBase.hh +++ b/src/ui/ViewModelBase.hh @@ -12,7 +12,16 @@ namespace ui { class ViewModelBase { public: +#ifdef RA_UTEST + virtual ~ViewModelBase() noexcept { + m_bDestructed = true; + } + + bool m_bDestructed = false; +#else virtual ~ViewModelBase() noexcept = default; +#endif + ViewModelBase(const ViewModelBase&) = delete; ViewModelBase& operator=(const ViewModelBase&) = delete; GSL_SUPPRESS_F6 ViewModelBase(ViewModelBase&&) = default; @@ -34,7 +43,16 @@ public: }; void AddNotifyTarget(NotifyTarget& pTarget) noexcept { GSL_SUPPRESS_F6 m_vNotifyTargets.insert(&pTarget); } + +#ifdef RA_UTEST + void RemoveNotifyTarget(NotifyTarget& pTarget) noexcept + { + GSL_SUPPRESS_F6 Expects(!m_bDestructed); + GSL_SUPPRESS_F6 m_vNotifyTargets.erase(&pTarget); + } +#else void RemoveNotifyTarget(NotifyTarget& pTarget) noexcept { GSL_SUPPRESS_F6 m_vNotifyTargets.erase(&pTarget); } +#endif private: using NotifyTargetSet = std::set; diff --git a/src/ui/ViewModelCollection.hh b/src/ui/ViewModelCollection.hh index 8e2da2b8..b3aa30fa 100644 --- a/src/ui/ViewModelCollection.hh +++ b/src/ui/ViewModelCollection.hh @@ -17,6 +17,10 @@ protected: public: virtual ~ViewModelCollectionBase() noexcept { +#ifdef RA_UTEST + m_bDisposed = true; +#endif + if (!m_bFrozen) StopWatching(); } @@ -72,6 +76,10 @@ public: void RemoveNotifyTarget(NotifyTarget& pTarget) { +#ifdef RA_UTEST + Expects(!m_bDisposed); +#endif + if (!m_vNotifyTargets.empty()) { m_vNotifyTargets.erase(&pTarget); @@ -380,6 +388,10 @@ private: void OnViewModelStringValueChanged(gsl::index nIndex, const StringModelProperty::ChangeArgs& args); void OnViewModelIntValueChanged(gsl::index nIndex, const IntModelProperty::ChangeArgs& args); +#ifdef RA_UTEST + bool m_bDisposed = false; +#endif + bool m_bFrozen = false; unsigned int m_nUpdateCount = 0; size_t m_nSize = 0; diff --git a/src/ui/viewmodels/MemoryViewerViewModel.cpp b/src/ui/viewmodels/MemoryViewerViewModel.cpp index 63814251..edc995fd 100644 --- a/src/ui/viewmodels/MemoryViewerViewModel.cpp +++ b/src/ui/viewmodels/MemoryViewerViewModel.cpp @@ -114,6 +114,11 @@ void MemoryViewerViewModel::InitializeNotifyTargets() m_pBookmarkMonitor.reset(new MemoryBookmarkMonitor(*this)); } +void MemoryViewerViewModel::DetachNotifyTargets() noexcept +{ + m_pBookmarkMonitor.reset(); +} + MemoryViewerViewModel::~MemoryViewerViewModel() { // empty function definition required to generate destroy for forward-declared MemoryBookmarkMonitor diff --git a/src/ui/viewmodels/MemoryViewerViewModel.hh b/src/ui/viewmodels/MemoryViewerViewModel.hh index 1d387893..04af15c1 100644 --- a/src/ui/viewmodels/MemoryViewerViewModel.hh +++ b/src/ui/viewmodels/MemoryViewerViewModel.hh @@ -31,6 +31,7 @@ public: MemoryViewerViewModel& operator=(MemoryViewerViewModel&&) noexcept = delete; void InitializeNotifyTargets(); + void DetachNotifyTargets() noexcept; void DoFrame(); diff --git a/tests/RA_Integration.Tests.vcxproj b/tests/RA_Integration.Tests.vcxproj index 5aa26ffb..c6ab657a 100644 --- a/tests/RA_Integration.Tests.vcxproj +++ b/tests/RA_Integration.Tests.vcxproj @@ -171,6 +171,9 @@ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) DebugFull + + if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION + @@ -188,6 +191,9 @@ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) DebugFull + + if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION + @@ -206,6 +212,9 @@ DebugFull libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib + + if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION + @@ -224,6 +233,9 @@ DebugFull libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib + + if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION + @@ -242,6 +254,9 @@ true $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION + @@ -260,6 +275,9 @@ true $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION + diff --git a/tests/RA_Interface.Tests.vcxproj b/tests/RA_Interface.Tests.vcxproj index abe61343..785ad811 100644 --- a/tests/RA_Interface.Tests.vcxproj +++ b/tests/RA_Interface.Tests.vcxproj @@ -24,27 +24,27 @@ Win32Proj RA_InterfaceTests NativeUnitTestProject - 7.0 + 10.0 DynamicLibrary true - v141_xp MultiByte false + $(DefaultPlatformToolset) DynamicLibrary true - v141_xp + $(DefaultPlatformToolset) MultiByte false DynamicLibrary false - v141_xp + $(DefaultPlatformToolset) true MultiByte false @@ -52,7 +52,7 @@ DynamicLibrary false - v141_xp + $(DefaultPlatformToolset) true MultiByte false @@ -116,6 +116,9 @@ DebugFull kernel32.lib;user32.lib;Winhttp.lib;%(AdditionalDependencies) + + if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION + @@ -154,6 +157,9 @@ Windows $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION + @@ -178,6 +184,9 @@ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) kernel32.lib;user32.lib;Winhttp.lib;%(AdditionalDependencies) + + if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION + @@ -222,6 +231,9 @@ true $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION + diff --git a/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp index 05e6ed8d..cb41b0a1 100644 --- a/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp @@ -43,10 +43,20 @@ private: for (size_t i = 0; i < memory.size(); ++i) memory.at(i) = gsl::narrow_cast(i); - Viewer().InitializeNotifyTargets(); mockEmulatorContext.MockMemory(memory); } + ~MemoryInspectorViewModelHarness() + { + // ensure we stop monitoring the MemoryBookmarksViewModel before the MockWindowManager is destroyed + Viewer().DetachNotifyTargets(); + } + + MemoryInspectorViewModelHarness(const MemoryInspectorViewModelHarness&) noexcept = delete; + MemoryInspectorViewModelHarness& operator=(const MemoryInspectorViewModelHarness&) noexcept = delete; + MemoryInspectorViewModelHarness(MemoryInspectorViewModelHarness&&) noexcept = delete; + MemoryInspectorViewModelHarness& operator=(MemoryInspectorViewModelHarness&&) noexcept = delete; + bool CanModifyCodeNotes() const { return GetValue(CanModifyNotesProperty); } }; diff --git a/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp index 54f5269b..b9dfac6b 100644 --- a/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp @@ -43,6 +43,17 @@ private: m_szChar.Height = CHAR_HEIGHT; } + ~MemoryViewerViewModelHarness() + { + // ensure we stop monitoring the MemoryBookmarksViewModel before the MockWindowManager is destroyed + DetachNotifyTargets(); + } + + MemoryViewerViewModelHarness(const MemoryViewerViewModelHarness&) noexcept = delete; + MemoryViewerViewModelHarness& operator=(const MemoryViewerViewModelHarness&) noexcept = delete; + MemoryViewerViewModelHarness(MemoryViewerViewModelHarness&&) noexcept = delete; + MemoryViewerViewModelHarness& operator=(MemoryViewerViewModelHarness&&) noexcept = delete; + int GetSelectedNibble() const noexcept { return m_nSelectedNibble; } size_t GetTotalMemorySize() const noexcept { return m_nTotalMemorySize; }