diff options
| author | Rob Mensching <rob@firegiant.com> | 2021-04-22 06:38:23 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2021-04-29 16:21:09 -0700 |
| commit | 7f642e51670bc38a4ef782a363936850bc2b0ba9 (patch) | |
| tree | 19684b2d94979f130c0935328f0d44cf006e45ef /src/test/DUtilUnitTest | |
| parent | f39e7a3e164d0736e45049e5726d0da2013da3c9 (diff) | |
| download | wix-7f642e51670bc38a4ef782a363936850bc2b0ba9.tar.gz wix-7f642e51670bc38a4ef782a363936850bc2b0ba9.tar.bz2 wix-7f642e51670bc38a4ef782a363936850bc2b0ba9.zip | |
Move dutil into libs/dutil
Diffstat (limited to 'src/test/DUtilUnitTest')
25 files changed, 0 insertions, 4010 deletions
diff --git a/src/test/DUtilUnitTest/ApupUtilTests.cpp b/src/test/DUtilUnitTest/ApupUtilTests.cpp deleted file mode 100644 index 30a45f5a..00000000 --- a/src/test/DUtilUnitTest/ApupUtilTests.cpp +++ /dev/null | |||
| @@ -1,46 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | namespace DutilTests | ||
| 10 | { | ||
| 11 | public ref class ApupUtil | ||
| 12 | { | ||
| 13 | public: | ||
| 14 | [Fact] | ||
| 15 | void AllocChainFromAtomSortsDescending() | ||
| 16 | { | ||
| 17 | HRESULT hr = S_OK; | ||
| 18 | ATOM_FEED* pFeed = NULL; | ||
| 19 | APPLICATION_UPDATE_CHAIN* pChain = NULL; | ||
| 20 | |||
| 21 | DutilInitialize(&DutilTestTraceError); | ||
| 22 | |||
| 23 | try | ||
| 24 | { | ||
| 25 | XmlInitialize(); | ||
| 26 | NativeAssert::Succeeded(hr, "Failed to initialize Xml."); | ||
| 27 | |||
| 28 | pin_ptr<const wchar_t> feedFilePath = PtrToStringChars(TestData::Get("TestData", "ApupUtilTests", "FeedBv2.0.xml")); | ||
| 29 | hr = AtomParseFromFile(feedFilePath, &pFeed); | ||
| 30 | NativeAssert::Succeeded(hr, "Failed to parse feed: {0}", feedFilePath); | ||
| 31 | |||
| 32 | hr = ApupAllocChainFromAtom(pFeed, &pChain); | ||
| 33 | NativeAssert::Succeeded(hr, "Failed to get chain from feed."); | ||
| 34 | |||
| 35 | Assert::Equal(3ul, pChain->cEntries); | ||
| 36 | NativeAssert::StringEqual(L"Bundle v2.0", pChain->rgEntries[0].wzTitle); | ||
| 37 | NativeAssert::StringEqual(L"Bundle v1.0", pChain->rgEntries[1].wzTitle); | ||
| 38 | NativeAssert::StringEqual(L"Bundle v1.0-preview", pChain->rgEntries[2].wzTitle); | ||
| 39 | } | ||
| 40 | finally | ||
| 41 | { | ||
| 42 | DutilUninitialize(); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | }; | ||
| 46 | } | ||
diff --git a/src/test/DUtilUnitTest/AssemblyInfo.cpp b/src/test/DUtilUnitTest/AssemblyInfo.cpp deleted file mode 100644 index 2d527910..00000000 --- a/src/test/DUtilUnitTest/AssemblyInfo.cpp +++ /dev/null | |||
| @@ -1,12 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System::Reflection; | ||
| 6 | using namespace System::Runtime::CompilerServices; | ||
| 7 | using namespace System::Runtime::InteropServices; | ||
| 8 | |||
| 9 | [assembly: AssemblyTitleAttribute("Windows Installer XML Dutil unit tests")]; | ||
| 10 | [assembly: AssemblyDescriptionAttribute("Dutil unit tests")]; | ||
| 11 | [assembly: AssemblyCultureAttribute("")]; | ||
| 12 | [assembly: ComVisible(false)]; | ||
diff --git a/src/test/DUtilUnitTest/DUtilTests.cpp b/src/test/DUtilUnitTest/DUtilTests.cpp deleted file mode 100644 index 55e81d46..00000000 --- a/src/test/DUtilUnitTest/DUtilTests.cpp +++ /dev/null | |||
| @@ -1,35 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | namespace DutilTests | ||
| 10 | { | ||
| 11 | public ref class DUtil | ||
| 12 | { | ||
| 13 | public: | ||
| 14 | [Fact] | ||
| 15 | void DUtilTraceErrorSourceFiltersOnTraceLevel() | ||
| 16 | { | ||
| 17 | DutilInitialize(&DutilTestTraceError); | ||
| 18 | |||
| 19 | CallDutilTraceErrorSource(); | ||
| 20 | |||
| 21 | Dutil_TraceSetLevel(REPORT_DEBUG, FALSE); | ||
| 22 | |||
| 23 | Action^ action = gcnew Action(this, &DUtil::CallDutilTraceErrorSource); | ||
| 24 | Assert::Throws<Exception^>(action); | ||
| 25 | |||
| 26 | DutilUninitialize(); | ||
| 27 | } | ||
| 28 | |||
| 29 | private: | ||
| 30 | void CallDutilTraceErrorSource() | ||
| 31 | { | ||
| 32 | Dutil_TraceErrorSource(__FILE__, __LINE__, REPORT_DEBUG, DUTIL_SOURCE_EXTERNAL, E_FAIL, "Error message"); | ||
| 33 | } | ||
| 34 | }; | ||
| 35 | } | ||
diff --git a/src/test/DUtilUnitTest/DUtilUnitTest.vcxproj b/src/test/DUtilUnitTest/DUtilUnitTest.vcxproj deleted file mode 100644 index 18410e5d..00000000 --- a/src/test/DUtilUnitTest/DUtilUnitTest.vcxproj +++ /dev/null | |||
| @@ -1,99 +0,0 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 3 | |||
| 4 | <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
| 5 | <Import Project="..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.47\build\WixBuildTools.TestSupport.Native.props" Condition="Exists('..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.47\build\WixBuildTools.TestSupport.Native.props')" /> | ||
| 6 | <ItemGroup Label="ProjectConfigurations"> | ||
| 7 | <ProjectConfiguration Include="Debug|Win32"> | ||
| 8 | <Configuration>Debug</Configuration> | ||
| 9 | <Platform>Win32</Platform> | ||
| 10 | </ProjectConfiguration> | ||
| 11 | <ProjectConfiguration Include="Release|Win32"> | ||
| 12 | <Configuration>Release</Configuration> | ||
| 13 | <Platform>Win32</Platform> | ||
| 14 | </ProjectConfiguration> | ||
| 15 | </ItemGroup> | ||
| 16 | |||
| 17 | <PropertyGroup Label="Globals"> | ||
| 18 | <ProjectTypes>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}</ProjectTypes> | ||
| 19 | <ProjectGuid>{AB7EE608-E5FB-42A5-831F-0DEEEA141223}</ProjectGuid> | ||
| 20 | <RootNamespace>DUtilUnitTests</RootNamespace> | ||
| 21 | <Keyword>ManagedCProj</Keyword> | ||
| 22 | <ConfigurationType>DynamicLibrary</ConfigurationType> | ||
| 23 | <CharacterSet>Unicode</CharacterSet> | ||
| 24 | <CLRSupport>true</CLRSupport> | ||
| 25 | <SignOutput>false</SignOutput> | ||
| 26 | </PropertyGroup> | ||
| 27 | |||
| 28 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||
| 29 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||
| 30 | |||
| 31 | <PropertyGroup> | ||
| 32 | <ProjectAdditionalIncludeDirectories>..\..\dutil\inc</ProjectAdditionalIncludeDirectories> | ||
| 33 | <ProjectAdditionalLinkLibraries>rpcrt4.lib;Mpr.lib;Ws2_32.lib;urlmon.lib;wininet.lib</ProjectAdditionalLinkLibraries> | ||
| 34 | </PropertyGroup> | ||
| 35 | |||
| 36 | <ItemGroup> | ||
| 37 | <ClCompile Include="ApupUtilTests.cpp" /> | ||
| 38 | <ClCompile Include="AssemblyInfo.cpp" /> | ||
| 39 | <ClCompile Include="DictUtilTest.cpp" /> | ||
| 40 | <ClCompile Include="DirUtilTests.cpp" /> | ||
| 41 | <ClCompile Include="DUtilTests.cpp" /> | ||
| 42 | <ClCompile Include="error.cpp" /> | ||
| 43 | <ClCompile Include="FileUtilTest.cpp" /> | ||
| 44 | <ClCompile Include="GuidUtilTest.cpp" /> | ||
| 45 | <ClCompile Include="IniUtilTest.cpp" /> | ||
| 46 | <ClCompile Include="MemUtilTest.cpp" /> | ||
| 47 | <ClCompile Include="MonUtilTest.cpp" /> | ||
| 48 | <ClCompile Include="PathUtilTest.cpp" /> | ||
| 49 | <ClCompile Include="precomp.cpp"> | ||
| 50 | <PrecompiledHeader>Create</PrecompiledHeader> | ||
| 51 | <!-- Warnings from referencing netstandard dlls --> | ||
| 52 | <DisableSpecificWarnings>4564;4691</DisableSpecificWarnings> | ||
| 53 | </ClCompile> | ||
| 54 | <ClCompile Include="SceUtilTest.cpp" Condition=" Exists('$(SqlCESdkIncludePath)') " /> | ||
| 55 | <ClCompile Include="StrUtilTest.cpp" /> | ||
| 56 | <ClCompile Include="UriUtilTest.cpp" /> | ||
| 57 | <ClCompile Include="VerUtilTests.cpp" /> | ||
| 58 | </ItemGroup> | ||
| 59 | |||
| 60 | <ItemGroup> | ||
| 61 | <ClInclude Include="precomp.h" /> | ||
| 62 | <ClInclude Include="error.h" /> | ||
| 63 | </ItemGroup> | ||
| 64 | |||
| 65 | <ItemGroup> | ||
| 66 | <None Include="packages.config" /> | ||
| 67 | <ResourceCompile Include="UnitTest.rc" /> | ||
| 68 | </ItemGroup> | ||
| 69 | |||
| 70 | <ItemGroup> | ||
| 71 | <None Include="TestData\ApupUtilTests\FeedBv2.0.xml" CopyToOutputDirectory="PreserveNewest" /> | ||
| 72 | </ItemGroup> | ||
| 73 | |||
| 74 | <ItemGroup> | ||
| 75 | <Reference Include="System" /> | ||
| 76 | <Reference Include="System.Core" /> | ||
| 77 | <Reference Include="WixBuildTools.TestSupport"> | ||
| 78 | <HintPath>..\..\..\packages\WixBuildTools.TestSupport.4.0.47\lib\net472\WixBuildTools.TestSupport.dll</HintPath> | ||
| 79 | </Reference> | ||
| 80 | <Reference Include="WixBuildTools.TestSupport.Native"> | ||
| 81 | <HintPath>..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.47\lib\net472\WixBuildTools.TestSupport.Native.dll</HintPath> | ||
| 82 | </Reference> | ||
| 83 | </ItemGroup> | ||
| 84 | |||
| 85 | <ItemGroup> | ||
| 86 | <ProjectReference Include="..\..\dutil\dutil.vcxproj"> | ||
| 87 | <Project>{1244E671-F108-4334-BA52-8A7517F26ECD}</Project> | ||
| 88 | </ProjectReference> | ||
| 89 | </ItemGroup> | ||
| 90 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||
| 91 | <Import Project="..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.47\build\WixBuildTools.TestSupport.Native.targets" Condition="Exists('..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.47\build\WixBuildTools.TestSupport.Native.targets')" /> | ||
| 92 | <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | ||
| 93 | <PropertyGroup> | ||
| 94 | <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | ||
| 95 | </PropertyGroup> | ||
| 96 | <Error Condition="!Exists('..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.47\build\WixBuildTools.TestSupport.Native.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.47\build\WixBuildTools.TestSupport.Native.props'))" /> | ||
| 97 | <Error Condition="!Exists('..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.47\build\WixBuildTools.TestSupport.Native.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.47\build\WixBuildTools.TestSupport.Native.targets'))" /> | ||
| 98 | </Target> | ||
| 99 | </Project> \ No newline at end of file | ||
diff --git a/src/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters b/src/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters deleted file mode 100644 index 4df7af89..00000000 --- a/src/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters +++ /dev/null | |||
| @@ -1,80 +0,0 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
| 3 | <ItemGroup> | ||
| 4 | <Filter Include="Source Files"> | ||
| 5 | <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> | ||
| 6 | <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> | ||
| 7 | </Filter> | ||
| 8 | <Filter Include="Header Files"> | ||
| 9 | <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> | ||
| 10 | <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> | ||
| 11 | </Filter> | ||
| 12 | <Filter Include="Resource Files"> | ||
| 13 | <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> | ||
| 14 | <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> | ||
| 15 | </Filter> | ||
| 16 | </ItemGroup> | ||
| 17 | <ItemGroup> | ||
| 18 | <ClCompile Include="ApupUtilTests.cpp"> | ||
| 19 | <Filter>Source Files</Filter> | ||
| 20 | </ClCompile> | ||
| 21 | <ClCompile Include="AssemblyInfo.cpp"> | ||
| 22 | <Filter>Source Files</Filter> | ||
| 23 | </ClCompile> | ||
| 24 | <ClCompile Include="DictUtilTest.cpp"> | ||
| 25 | <Filter>Source Files</Filter> | ||
| 26 | </ClCompile> | ||
| 27 | <ClCompile Include="DirUtilTests.cpp"> | ||
| 28 | <Filter>Source Files</Filter> | ||
| 29 | </ClCompile> | ||
| 30 | <ClCompile Include="DUtilTests.cpp"> | ||
| 31 | <Filter>Source Files</Filter> | ||
| 32 | </ClCompile> | ||
| 33 | <ClCompile Include="error.cpp"> | ||
| 34 | <Filter>Source Files</Filter> | ||
| 35 | </ClCompile> | ||
| 36 | <ClCompile Include="FileUtilTest.cpp"> | ||
| 37 | <Filter>Source Files</Filter> | ||
| 38 | </ClCompile> | ||
| 39 | <ClCompile Include="GuidUtilTest.cpp"> | ||
| 40 | <Filter>Source Files</Filter> | ||
| 41 | </ClCompile> | ||
| 42 | <ClCompile Include="IniUtilTest.cpp"> | ||
| 43 | <Filter>Source Files</Filter> | ||
| 44 | </ClCompile> | ||
| 45 | <ClCompile Include="MemUtilTest.cpp"> | ||
| 46 | <Filter>Source Files</Filter> | ||
| 47 | </ClCompile> | ||
| 48 | <ClCompile Include="MonUtilTest.cpp"> | ||
| 49 | <Filter>Source Files</Filter> | ||
| 50 | </ClCompile> | ||
| 51 | <ClCompile Include="PathUtilTest.cpp"> | ||
| 52 | <Filter>Source Files</Filter> | ||
| 53 | </ClCompile> | ||
| 54 | <ClCompile Include="precomp.cpp"> | ||
| 55 | <Filter>Source Files</Filter> | ||
| 56 | </ClCompile> | ||
| 57 | <ClCompile Include="StrUtilTest.cpp"> | ||
| 58 | <Filter>Source Files</Filter> | ||
| 59 | </ClCompile> | ||
| 60 | <ClCompile Include="UriUtilTest.cpp"> | ||
| 61 | <Filter>Source Files</Filter> | ||
| 62 | </ClCompile> | ||
| 63 | <ClCompile Include="VerUtilTests.cpp"> | ||
| 64 | <Filter>Source Files</Filter> | ||
| 65 | </ClCompile> | ||
| 66 | </ItemGroup> | ||
| 67 | <ItemGroup> | ||
| 68 | <ResourceCompile Include="UnitTest.rc"> | ||
| 69 | <Filter>Resource Files</Filter> | ||
| 70 | </ResourceCompile> | ||
| 71 | </ItemGroup> | ||
| 72 | <ItemGroup> | ||
| 73 | <ClInclude Include="precomp.h"> | ||
| 74 | <Filter>Header Files</Filter> | ||
| 75 | </ClInclude> | ||
| 76 | <ClInclude Include="error.h"> | ||
| 77 | <Filter>Header Files</Filter> | ||
| 78 | </ClInclude> | ||
| 79 | </ItemGroup> | ||
| 80 | </Project> \ No newline at end of file | ||
diff --git a/src/test/DUtilUnitTest/DictUtilTest.cpp b/src/test/DUtilUnitTest/DictUtilTest.cpp deleted file mode 100644 index 4b4777d7..00000000 --- a/src/test/DUtilUnitTest/DictUtilTest.cpp +++ /dev/null | |||
| @@ -1,191 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | const DWORD numIterations = 100000; | ||
| 10 | |||
| 11 | namespace DutilTests | ||
| 12 | { | ||
| 13 | struct Value | ||
| 14 | { | ||
| 15 | DWORD dwNum; | ||
| 16 | LPWSTR sczKey; | ||
| 17 | }; | ||
| 18 | |||
| 19 | public ref class DictUtil | ||
| 20 | { | ||
| 21 | public: | ||
| 22 | [Fact] | ||
| 23 | void DictUtilTest() | ||
| 24 | { | ||
| 25 | DutilInitialize(&DutilTestTraceError); | ||
| 26 | |||
| 27 | EmbeddedKeyTestHelper(DICT_FLAG_NONE, numIterations); | ||
| 28 | |||
| 29 | EmbeddedKeyTestHelper(DICT_FLAG_CASEINSENSITIVE, numIterations); | ||
| 30 | |||
| 31 | StringListTestHelper(DICT_FLAG_NONE, numIterations); | ||
| 32 | |||
| 33 | StringListTestHelper(DICT_FLAG_CASEINSENSITIVE, numIterations); | ||
| 34 | |||
| 35 | DutilUninitialize(); | ||
| 36 | } | ||
| 37 | |||
| 38 | private: | ||
| 39 | void EmbeddedKeyTestHelper(DICT_FLAG dfFlags, DWORD dwNumIterations) | ||
| 40 | { | ||
| 41 | HRESULT hr = S_OK; | ||
| 42 | Value *rgValues = NULL; | ||
| 43 | Value *valueFound = NULL; | ||
| 44 | DWORD cValues = 0; | ||
| 45 | LPWSTR sczExpectedKey = NULL; | ||
| 46 | STRINGDICT_HANDLE sdValues = NULL; | ||
| 47 | |||
| 48 | try | ||
| 49 | { | ||
| 50 | hr = DictCreateWithEmbeddedKey(&sdValues, 0, (void **)&rgValues, offsetof(Value, sczKey), dfFlags); | ||
| 51 | NativeAssert::Succeeded(hr, "Failed to create dictionary of values"); | ||
| 52 | |||
| 53 | for (DWORD i = 0; i < dwNumIterations; ++i) | ||
| 54 | { | ||
| 55 | cValues++; | ||
| 56 | |||
| 57 | hr = MemEnsureArraySize((void **)&rgValues, cValues, sizeof(Value), 5); | ||
| 58 | NativeAssert::Succeeded(hr, "Failed to grow value array"); | ||
| 59 | |||
| 60 | hr = StrAllocFormatted(&rgValues[i].sczKey, L"%u_a_%u", i, i); | ||
| 61 | NativeAssert::Succeeded(hr, "Failed to allocate key for value {0}", i); | ||
| 62 | |||
| 63 | hr = DictAddValue(sdValues, rgValues + i); | ||
| 64 | NativeAssert::Succeeded(hr, "Failed to add item {0} to dict", i); | ||
| 65 | } | ||
| 66 | |||
| 67 | for (DWORD i = 0; i < dwNumIterations; ++i) | ||
| 68 | { | ||
| 69 | hr = StrAllocFormatted(&sczExpectedKey, L"%u_a_%u", i, i); | ||
| 70 | NativeAssert::Succeeded(hr, "Failed to allocate expected key {0}", i); | ||
| 71 | |||
| 72 | hr = DictGetValue(sdValues, sczExpectedKey, (void **)&valueFound); | ||
| 73 | NativeAssert::Succeeded(hr, "Failed to find value {0}", sczExpectedKey); | ||
| 74 | |||
| 75 | NativeAssert::StringEqual(sczExpectedKey, valueFound->sczKey); | ||
| 76 | |||
| 77 | hr = StrAllocFormatted(&sczExpectedKey, L"%u_A_%u", i, i); | ||
| 78 | NativeAssert::Succeeded(hr, "Failed to allocate uppercase expected key {0}", i); | ||
| 79 | |||
| 80 | hr = DictGetValue(sdValues, sczExpectedKey, (void **)&valueFound); | ||
| 81 | |||
| 82 | if (dfFlags & DICT_FLAG_CASEINSENSITIVE) | ||
| 83 | { | ||
| 84 | NativeAssert::Succeeded(hr, "Failed to find value {0}", sczExpectedKey); | ||
| 85 | |||
| 86 | NativeAssert::StringEqual(sczExpectedKey, valueFound->sczKey, TRUE); | ||
| 87 | } | ||
| 88 | else | ||
| 89 | { | ||
| 90 | if (E_NOTFOUND != hr) | ||
| 91 | { | ||
| 92 | hr = E_FAIL; | ||
| 93 | ExitOnFailure(hr, "This embedded key is case sensitive, but it seemed to have found something case using case insensitivity!: %ls", sczExpectedKey); | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | hr = StrAllocFormatted(&sczExpectedKey, L"%u_b_%u", i, i); | ||
| 98 | NativeAssert::Succeeded(hr, "Failed to allocate unexpected key {0}", i); | ||
| 99 | |||
| 100 | hr = DictGetValue(sdValues, sczExpectedKey, (void **)&valueFound); | ||
| 101 | if (E_NOTFOUND != hr) | ||
| 102 | { | ||
| 103 | hr = E_FAIL; | ||
| 104 | ExitOnFailure(hr, "Item shouldn't have been found in dictionary: %ls", sczExpectedKey); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | finally | ||
| 109 | { | ||
| 110 | for (DWORD i = 0; i < cValues; ++i) | ||
| 111 | { | ||
| 112 | ReleaseStr(rgValues[i].sczKey); | ||
| 113 | } | ||
| 114 | ReleaseMem(rgValues); | ||
| 115 | ReleaseStr(sczExpectedKey); | ||
| 116 | ReleaseDict(sdValues); | ||
| 117 | } | ||
| 118 | |||
| 119 | LExit: | ||
| 120 | return; | ||
| 121 | } | ||
| 122 | |||
| 123 | void StringListTestHelper(DICT_FLAG dfFlags, DWORD dwNumIterations) | ||
| 124 | { | ||
| 125 | HRESULT hr = S_OK; | ||
| 126 | LPWSTR sczKey = NULL; | ||
| 127 | LPWSTR sczExpectedKey = NULL; | ||
| 128 | STRINGDICT_HANDLE sdValues = NULL; | ||
| 129 | |||
| 130 | try | ||
| 131 | { | ||
| 132 | hr = DictCreateStringList(&sdValues, 0, dfFlags); | ||
| 133 | NativeAssert::Succeeded(hr, "Failed to create dictionary of keys"); | ||
| 134 | |||
| 135 | for (DWORD i = 0; i < dwNumIterations; ++i) | ||
| 136 | { | ||
| 137 | hr = StrAllocFormatted(&sczKey, L"%u_a_%u", i, i); | ||
| 138 | NativeAssert::Succeeded(hr, "Failed to allocate key for value {0}", i); | ||
| 139 | |||
| 140 | hr = DictAddKey(sdValues, sczKey); | ||
| 141 | NativeAssert::Succeeded(hr, "Failed to add key {0} to dict", i); | ||
| 142 | } | ||
| 143 | |||
| 144 | for (DWORD i = 0; i < dwNumIterations; ++i) | ||
| 145 | { | ||
| 146 | hr = StrAllocFormatted(&sczExpectedKey, L"%u_a_%u", i, i); | ||
| 147 | NativeAssert::Succeeded(hr, "Failed to allocate expected key {0}", i); | ||
| 148 | |||
| 149 | hr = DictKeyExists(sdValues, sczExpectedKey); | ||
| 150 | NativeAssert::Succeeded(hr, "Failed to find value {0}", sczExpectedKey); | ||
| 151 | |||
| 152 | hr = StrAllocFormatted(&sczExpectedKey, L"%u_A_%u", i, i); | ||
| 153 | NativeAssert::Succeeded(hr, "Failed to allocate uppercase expected key {0}", i); | ||
| 154 | |||
| 155 | hr = DictKeyExists(sdValues, sczExpectedKey); | ||
| 156 | if (dfFlags & DICT_FLAG_CASEINSENSITIVE) | ||
| 157 | { | ||
| 158 | NativeAssert::Succeeded(hr, "Failed to find value {0}", sczExpectedKey); | ||
| 159 | } | ||
| 160 | else | ||
| 161 | { | ||
| 162 | if (E_NOTFOUND != hr) | ||
| 163 | { | ||
| 164 | hr = E_FAIL; | ||
| 165 | ExitOnFailure(hr, "This stringlist dict is case sensitive, but it seemed to have found something case using case insensitivity!: %ls", sczExpectedKey); | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | hr = StrAllocFormatted(&sczExpectedKey, L"%u_b_%u", i, i); | ||
| 170 | NativeAssert::Succeeded(hr, "Failed to allocate unexpected key {0}", i); | ||
| 171 | |||
| 172 | hr = DictKeyExists(sdValues, sczExpectedKey); | ||
| 173 | if (E_NOTFOUND != hr) | ||
| 174 | { | ||
| 175 | hr = E_FAIL; | ||
| 176 | ExitOnFailure(hr, "Item shouldn't have been found in dictionary: %ls", sczExpectedKey); | ||
| 177 | } | ||
| 178 | } | ||
| 179 | } | ||
| 180 | finally | ||
| 181 | { | ||
| 182 | ReleaseStr(sczKey); | ||
| 183 | ReleaseStr(sczExpectedKey); | ||
| 184 | ReleaseDict(sdValues); | ||
| 185 | } | ||
| 186 | |||
| 187 | LExit: | ||
| 188 | return; | ||
| 189 | } | ||
| 190 | }; | ||
| 191 | } | ||
diff --git a/src/test/DUtilUnitTest/DirUtilTests.cpp b/src/test/DUtilUnitTest/DirUtilTests.cpp deleted file mode 100644 index 7643366f..00000000 --- a/src/test/DUtilUnitTest/DirUtilTests.cpp +++ /dev/null | |||
| @@ -1,70 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | namespace DutilTests | ||
| 10 | { | ||
| 11 | public ref class DirUtil | ||
| 12 | { | ||
| 13 | public: | ||
| 14 | [Fact] | ||
| 15 | void DirUtilTest() | ||
| 16 | { | ||
| 17 | HRESULT hr = S_OK; | ||
| 18 | LPWSTR sczCurrentDir = NULL; | ||
| 19 | LPWSTR sczGuid = NULL; | ||
| 20 | LPWSTR sczFolder = NULL; | ||
| 21 | LPWSTR sczSubFolder = NULL; | ||
| 22 | |||
| 23 | try | ||
| 24 | { | ||
| 25 | hr = GuidCreate(&sczGuid); | ||
| 26 | NativeAssert::Succeeded(hr, "Failed to create guid."); | ||
| 27 | |||
| 28 | hr = DirGetCurrent(&sczCurrentDir); | ||
| 29 | NativeAssert::Succeeded(hr, "Failed to get current directory."); | ||
| 30 | |||
| 31 | hr = PathConcat(sczCurrentDir, sczGuid, &sczFolder); | ||
| 32 | NativeAssert::Succeeded(hr, "Failed to combine current directory: '{0}' with Guid: '{1}'", sczCurrentDir, sczGuid); | ||
| 33 | |||
| 34 | BOOL fExists = DirExists(sczFolder, NULL); | ||
| 35 | Assert::False(fExists == TRUE); | ||
| 36 | |||
| 37 | hr = PathConcat(sczFolder, L"foo", &sczSubFolder); | ||
| 38 | NativeAssert::Succeeded(hr, "Failed to combine folder: '%ls' with subfolder: 'foo'", sczFolder); | ||
| 39 | |||
| 40 | hr = DirEnsureExists(sczSubFolder, NULL); | ||
| 41 | NativeAssert::Succeeded(hr, "Failed to create multiple directories: %ls", sczSubFolder); | ||
| 42 | |||
| 43 | // Test failure to delete non-empty folder. | ||
| 44 | hr = DirEnsureDelete(sczFolder, FALSE, FALSE); | ||
| 45 | Assert::Equal(HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY), hr); | ||
| 46 | |||
| 47 | hr = DirEnsureDelete(sczSubFolder, FALSE, FALSE); | ||
| 48 | NativeAssert::Succeeded(hr, "Failed to delete single directory: %ls", sczSubFolder); | ||
| 49 | |||
| 50 | // Put the directory back and we'll test deleting tree. | ||
| 51 | hr = DirEnsureExists(sczSubFolder, NULL); | ||
| 52 | NativeAssert::Succeeded(hr, "Failed to create single directory: %ls", sczSubFolder); | ||
| 53 | |||
| 54 | hr = DirEnsureDelete(sczFolder, FALSE, TRUE); | ||
| 55 | NativeAssert::Succeeded(hr, "Failed to delete directory tree: %ls", sczFolder); | ||
| 56 | |||
| 57 | // Finally, try to create "C:\" which would normally fail, but we want success | ||
| 58 | hr = DirEnsureExists(L"C:\\", NULL); | ||
| 59 | NativeAssert::Succeeded(hr, "Failed to create C:\\"); | ||
| 60 | } | ||
| 61 | finally | ||
| 62 | { | ||
| 63 | ReleaseStr(sczSubFolder); | ||
| 64 | ReleaseStr(sczFolder); | ||
| 65 | ReleaseStr(sczGuid); | ||
| 66 | ReleaseStr(sczCurrentDir); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | }; | ||
| 70 | } | ||
diff --git a/src/test/DUtilUnitTest/FileUtilTest.cpp b/src/test/DUtilUnitTest/FileUtilTest.cpp deleted file mode 100644 index ac071ef2..00000000 --- a/src/test/DUtilUnitTest/FileUtilTest.cpp +++ /dev/null | |||
| @@ -1,125 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | namespace DutilTests | ||
| 10 | { | ||
| 11 | public ref class FileUtil | ||
| 12 | { | ||
| 13 | public: | ||
| 14 | [Fact(Skip="Skipped until we have a good way to reference ANSI.txt.")] | ||
| 15 | void FileUtilTest() | ||
| 16 | { | ||
| 17 | HRESULT hr = S_OK; | ||
| 18 | LPWSTR sczTempDir = NULL; | ||
| 19 | LPWSTR sczFileDir = NULL; | ||
| 20 | |||
| 21 | DutilInitialize(&DutilTestTraceError); | ||
| 22 | |||
| 23 | try | ||
| 24 | { | ||
| 25 | hr = PathExpand(&sczTempDir, L"%TEMP%\\FileUtilTest\\", PATH_EXPAND_ENVIRONMENT); | ||
| 26 | NativeAssert::Succeeded(hr, "Failed to get temp dir"); | ||
| 27 | |||
| 28 | hr = PathExpand(&sczFileDir, L"%WIX_ROOT%\\examples\\data\\TextEncodings\\", PATH_EXPAND_ENVIRONMENT); | ||
| 29 | NativeAssert::Succeeded(hr, "Failed to get path to encodings file dir"); | ||
| 30 | |||
| 31 | hr = DirEnsureExists(sczTempDir, NULL); | ||
| 32 | NativeAssert::Succeeded(hr, "Failed to ensure directory exists: {0}", sczTempDir); | ||
| 33 | |||
| 34 | TestFile(sczFileDir, sczTempDir, L"ANSI.txt", 32, FILE_ENCODING_UTF8); | ||
| 35 | // Big endian not supported today! | ||
| 36 | //TestFile(sczFileDir, L"UnicodeBENoBOM.txt", 34); | ||
| 37 | //TestFile(sczFileDir, L"UnicodeBEWithBOM.txt", 34); | ||
| 38 | TestFile(sczFileDir, sczTempDir, L"UnicodeLENoBOM.txt", 34, FILE_ENCODING_UTF16); | ||
| 39 | TestFile(sczFileDir, sczTempDir, L"UnicodeLEWithBOM.txt", 34, FILE_ENCODING_UTF16_WITH_BOM); | ||
| 40 | TestFile(sczFileDir, sczTempDir, L"UTF8WithSignature.txt", 34, FILE_ENCODING_UTF8_WITH_BOM); | ||
| 41 | |||
| 42 | hr = DirEnsureDelete(sczTempDir, TRUE, TRUE); | ||
| 43 | } | ||
| 44 | finally | ||
| 45 | { | ||
| 46 | ReleaseStr(sczTempDir); | ||
| 47 | ReleaseStr(sczFileDir); | ||
| 48 | DutilUninitialize(); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | private: | ||
| 53 | void TestFile(LPWSTR wzDir, LPCWSTR wzTempDir, LPWSTR wzFileName, size_t cbExpectedStringLength, FILE_ENCODING feExpectedEncoding) | ||
| 54 | { | ||
| 55 | HRESULT hr = S_OK; | ||
| 56 | LPWSTR sczFullPath = NULL; | ||
| 57 | LPWSTR sczContents = NULL; | ||
| 58 | LPWSTR sczOutputPath = NULL; | ||
| 59 | FILE_ENCODING feEncodingFound = FILE_ENCODING_UNSPECIFIED; | ||
| 60 | BYTE *pbFile1 = NULL; | ||
| 61 | DWORD cbFile1 = 0; | ||
| 62 | BYTE *pbFile2 = NULL; | ||
| 63 | DWORD cbFile2 = 0; | ||
| 64 | size_t cbActualStringLength = 0; | ||
| 65 | |||
| 66 | try | ||
| 67 | { | ||
| 68 | hr = PathConcat(wzDir, wzFileName, &sczFullPath); | ||
| 69 | NativeAssert::Succeeded(hr, "Failed to create path to test file: {0}", sczFullPath); | ||
| 70 | |||
| 71 | hr = FileToString(sczFullPath, &sczContents, &feEncodingFound); | ||
| 72 | hr = E_FAIL; | ||
| 73 | NativeAssert::Succeeded(hr, "Failed to read text from file: {0}", sczFullPath); | ||
| 74 | |||
| 75 | if (!sczContents) | ||
| 76 | { | ||
| 77 | hr = E_FAIL; | ||
| 78 | NativeAssert::Succeeded(hr, "FileToString() returned NULL for file: {0}", sczFullPath); | ||
| 79 | } | ||
| 80 | |||
| 81 | hr = ::StringCchLengthW(sczContents, STRSAFE_MAX_CCH, &cbActualStringLength); | ||
| 82 | NativeAssert::Succeeded(hr, "Failed to get length of text from file: {0}", sczFullPath); | ||
| 83 | |||
| 84 | if (cbActualStringLength != cbExpectedStringLength) | ||
| 85 | { | ||
| 86 | hr = E_FAIL; | ||
| 87 | ExitOnFailure(hr, "FileToString() returned wrong size for file: %ls (expected size %Iu, found size %Iu)", sczFullPath, cbExpectedStringLength, cbActualStringLength); | ||
| 88 | } | ||
| 89 | |||
| 90 | if (feEncodingFound != feExpectedEncoding) | ||
| 91 | { | ||
| 92 | hr = E_FAIL; | ||
| 93 | ExitOnFailure(hr, "FileToString() returned unexpected encoding type for file: %ls (expected type %u, found type %u)", sczFullPath, feExpectedEncoding, feEncodingFound); | ||
| 94 | } | ||
| 95 | |||
| 96 | hr = PathConcat(wzTempDir, wzFileName, &sczOutputPath); | ||
| 97 | NativeAssert::Succeeded(hr, "Failed to get output path"); | ||
| 98 | |||
| 99 | hr = FileFromString(sczOutputPath, 0, sczContents, feExpectedEncoding); | ||
| 100 | NativeAssert::Succeeded(hr, "Failed to write contents of file back out to disk"); | ||
| 101 | |||
| 102 | hr = FileRead(&pbFile1, &cbFile1, sczFullPath); | ||
| 103 | NativeAssert::Succeeded(hr, "Failed to read input file as binary"); | ||
| 104 | |||
| 105 | hr = FileRead(&pbFile2, &cbFile2, sczOutputPath); | ||
| 106 | NativeAssert::Succeeded(hr, "Failed to read output file as binary"); | ||
| 107 | |||
| 108 | if (cbFile1 != cbFile2 || 0 != memcmp(pbFile1, pbFile2, cbFile1)) | ||
| 109 | { | ||
| 110 | hr = E_FAIL; | ||
| 111 | ExitOnFailure(hr, "Outputted file doesn't match input file: \"%ls\" and \"%ls\"", sczFullPath, sczOutputPath); | ||
| 112 | } | ||
| 113 | } | ||
| 114 | finally | ||
| 115 | { | ||
| 116 | ReleaseStr(sczOutputPath); | ||
| 117 | ReleaseStr(sczFullPath); | ||
| 118 | ReleaseStr(sczContents); | ||
| 119 | } | ||
| 120 | |||
| 121 | LExit: | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | }; | ||
| 125 | } | ||
diff --git a/src/test/DUtilUnitTest/GuidUtilTest.cpp b/src/test/DUtilUnitTest/GuidUtilTest.cpp deleted file mode 100644 index a6e27a09..00000000 --- a/src/test/DUtilUnitTest/GuidUtilTest.cpp +++ /dev/null | |||
| @@ -1,60 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | namespace DutilTests | ||
| 10 | { | ||
| 11 | public ref class GuidUtil | ||
| 12 | { | ||
| 13 | public: | ||
| 14 | [Fact] | ||
| 15 | void GuidCreateTest() | ||
| 16 | { | ||
| 17 | HRESULT hr = S_OK; | ||
| 18 | WCHAR wzGuid1[GUID_STRING_LENGTH]; | ||
| 19 | WCHAR wzGuid2[GUID_STRING_LENGTH]; | ||
| 20 | |||
| 21 | hr = GuidFixedCreate(wzGuid1); | ||
| 22 | NativeAssert::Succeeded(hr, "Failed to create first guid."); | ||
| 23 | Guid firstGuid = Guid::Parse(gcnew String(wzGuid1)); | ||
| 24 | |||
| 25 | hr = GuidFixedCreate(wzGuid2); | ||
| 26 | NativeAssert::Succeeded(hr, "Failed to create second guid."); | ||
| 27 | Guid secondGuid = Guid::Parse(gcnew String(wzGuid2)); | ||
| 28 | |||
| 29 | NativeAssert::NotStringEqual(wzGuid1, wzGuid2); | ||
| 30 | NativeAssert::NotEqual(firstGuid, secondGuid); | ||
| 31 | } | ||
| 32 | |||
| 33 | [Fact] | ||
| 34 | void GuidCreateSczTest() | ||
| 35 | { | ||
| 36 | HRESULT hr = S_OK; | ||
| 37 | LPWSTR sczGuid1 = NULL; | ||
| 38 | LPWSTR sczGuid2 = NULL; | ||
| 39 | |||
| 40 | try | ||
| 41 | { | ||
| 42 | hr = GuidCreate(&sczGuid1); | ||
| 43 | NativeAssert::Succeeded(hr, "Failed to create first guid."); | ||
| 44 | Guid firstGuid = Guid::Parse(gcnew String(sczGuid1)); | ||
| 45 | |||
| 46 | hr = GuidCreate(&sczGuid2); | ||
| 47 | NativeAssert::Succeeded(hr, "Failed to create second guid."); | ||
| 48 | Guid secondGuid = Guid::Parse(gcnew String(sczGuid2)); | ||
| 49 | |||
| 50 | NativeAssert::NotStringEqual(sczGuid1, sczGuid2); | ||
| 51 | NativeAssert::NotEqual(firstGuid, secondGuid); | ||
| 52 | } | ||
| 53 | finally | ||
| 54 | { | ||
| 55 | ReleaseStr(sczGuid1); | ||
| 56 | ReleaseStr(sczGuid2); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | }; | ||
| 60 | } | ||
diff --git a/src/test/DUtilUnitTest/IniUtilTest.cpp b/src/test/DUtilUnitTest/IniUtilTest.cpp deleted file mode 100644 index 946f19c5..00000000 --- a/src/test/DUtilUnitTest/IniUtilTest.cpp +++ /dev/null | |||
| @@ -1,345 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | typedef HRESULT (__clrcall *IniFormatParameters)( | ||
| 10 | INI_HANDLE | ||
| 11 | ); | ||
| 12 | |||
| 13 | namespace DutilTests | ||
| 14 | { | ||
| 15 | public ref class IniUtil | ||
| 16 | { | ||
| 17 | public: | ||
| 18 | [Fact] | ||
| 19 | void IniUtilTest() | ||
| 20 | { | ||
| 21 | HRESULT hr = S_OK; | ||
| 22 | LPWSTR sczTempIniFilePath = NULL; | ||
| 23 | LPWSTR sczTempIniFileDir = NULL; | ||
| 24 | LPWSTR wzIniContents = L" PlainValue = \t Blah \r\n;CommentHere\r\n[Section1]\r\n ;Another Comment With = Equal Sign\r\nSection1ValueA=Foo\r\n\r\nSection1ValueB=Bar\r\n[Section2]\r\nSection2ValueA=Cha\r\nArray[0]=Arr\r\n"; | ||
| 25 | LPWSTR wzScriptContents = L"setf ~PlainValue Blah\r\n;CommentHere\r\n\r\nsetf ~Section1\\Section1ValueA Foo\r\n\r\nsetf ~Section1\\Section1ValueB Bar\r\nsetf ~Section2\\Section2ValueA Cha\r\nsetf ~Section2\\Array[0] Arr\r\n"; | ||
| 26 | |||
| 27 | DutilInitialize(&DutilTestTraceError); | ||
| 28 | |||
| 29 | try | ||
| 30 | { | ||
| 31 | hr = PathExpand(&sczTempIniFilePath, L"%TEMP%\\IniUtilTest\\Test.ini", PATH_EXPAND_ENVIRONMENT); | ||
| 32 | NativeAssert::Succeeded(hr, "Failed to get path to temp INI file"); | ||
| 33 | |||
| 34 | hr = PathGetDirectory(sczTempIniFilePath, &sczTempIniFileDir); | ||
| 35 | NativeAssert::Succeeded(hr, "Failed to get directory to temp INI file"); | ||
| 36 | |||
| 37 | hr = DirEnsureDelete(sczTempIniFileDir, TRUE, TRUE); | ||
| 38 | if (E_PATHNOTFOUND == hr) | ||
| 39 | { | ||
| 40 | hr = S_OK; | ||
| 41 | } | ||
| 42 | NativeAssert::Succeeded(hr, "Failed to delete IniUtilTest directory: {0}", sczTempIniFileDir); | ||
| 43 | |||
| 44 | hr = DirEnsureExists(sczTempIniFileDir, NULL); | ||
| 45 | NativeAssert::Succeeded(hr, "Failed to ensure temp directory exists: {0}", sczTempIniFileDir); | ||
| 46 | |||
| 47 | // Tests parsing, then modifying a regular INI file | ||
| 48 | TestReadThenWrite(sczTempIniFilePath, StandardIniFormat, wzIniContents); | ||
| 49 | |||
| 50 | // Tests programmatically creating from scratch, then parsing an INI file | ||
| 51 | TestWriteThenRead(sczTempIniFilePath, StandardIniFormat); | ||
| 52 | |||
| 53 | // Tests parsing, then modifying a regular INI file | ||
| 54 | TestReadThenWrite(sczTempIniFilePath, ScriptFormat, wzScriptContents); | ||
| 55 | |||
| 56 | // Tests programmatically creating from scratch, then parsing an INI file | ||
| 57 | TestWriteThenRead(sczTempIniFilePath, ScriptFormat); | ||
| 58 | } | ||
| 59 | finally | ||
| 60 | { | ||
| 61 | ReleaseStr(sczTempIniFilePath); | ||
| 62 | ReleaseStr(sczTempIniFileDir); | ||
| 63 | DutilUninitialize(); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | private: | ||
| 68 | void AssertValue(INI_HANDLE iniHandle, LPCWSTR wzValueName, LPCWSTR wzValue) | ||
| 69 | { | ||
| 70 | HRESULT hr = S_OK; | ||
| 71 | LPWSTR sczValue = NULL; | ||
| 72 | |||
| 73 | try | ||
| 74 | { | ||
| 75 | hr = IniGetValue(iniHandle, wzValueName, &sczValue); | ||
| 76 | NativeAssert::Succeeded(hr, "Failed to get ini value: {0}", wzValueName); | ||
| 77 | |||
| 78 | if (0 != wcscmp(sczValue, wzValue)) | ||
| 79 | { | ||
| 80 | hr = E_FAIL; | ||
| 81 | ExitOnFailure(hr, "Expected to find value in INI: '%ls'='%ls' - but found value '%ls' instead", wzValueName, wzValue, sczValue); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | finally | ||
| 85 | { | ||
| 86 | ReleaseStr(sczValue); | ||
| 87 | } | ||
| 88 | |||
| 89 | LExit: | ||
| 90 | return; | ||
| 91 | } | ||
| 92 | |||
| 93 | void AssertNoValue(INI_HANDLE iniHandle, LPCWSTR wzValueName) | ||
| 94 | { | ||
| 95 | HRESULT hr = S_OK; | ||
| 96 | LPWSTR sczValue = NULL; | ||
| 97 | |||
| 98 | try | ||
| 99 | { | ||
| 100 | hr = IniGetValue(iniHandle, wzValueName, &sczValue); | ||
| 101 | if (E_NOTFOUND != hr) | ||
| 102 | { | ||
| 103 | if (SUCCEEDED(hr)) | ||
| 104 | { | ||
| 105 | hr = E_FAIL; | ||
| 106 | } | ||
| 107 | ExitOnFailure(hr, "INI value shouldn't have been found: %ls", wzValueName); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | finally | ||
| 111 | { | ||
| 112 | ReleaseStr(sczValue); | ||
| 113 | } | ||
| 114 | |||
| 115 | LExit: | ||
| 116 | return; | ||
| 117 | } | ||
| 118 | |||
| 119 | static HRESULT StandardIniFormat(__inout INI_HANDLE iniHandle) | ||
| 120 | { | ||
| 121 | HRESULT hr = S_OK; | ||
| 122 | |||
| 123 | hr = IniSetOpenTag(iniHandle, L"[", L"]"); | ||
| 124 | NativeAssert::Succeeded(hr, "Failed to set open tag settings on ini handle"); | ||
| 125 | |||
| 126 | hr = IniSetValueStyle(iniHandle, NULL, L"="); | ||
| 127 | NativeAssert::Succeeded(hr, "Failed to set value separator setting on ini handle"); | ||
| 128 | |||
| 129 | hr = IniSetCommentStyle(iniHandle, L";"); | ||
| 130 | NativeAssert::Succeeded(hr, "Failed to set comment style setting on ini handle"); | ||
| 131 | |||
| 132 | return hr; | ||
| 133 | } | ||
| 134 | |||
| 135 | static HRESULT ScriptFormat(__inout INI_HANDLE iniHandle) | ||
| 136 | { | ||
| 137 | HRESULT hr = S_OK; | ||
| 138 | |||
| 139 | hr = IniSetValueStyle(iniHandle, L"setf ~", L" "); | ||
| 140 | NativeAssert::Succeeded(hr, "Failed to set value separator setting on ini handle"); | ||
| 141 | |||
| 142 | return hr; | ||
| 143 | } | ||
| 144 | |||
| 145 | void TestReadThenWrite(LPWSTR wzIniFilePath, IniFormatParameters SetFormat, LPCWSTR wzContents) | ||
| 146 | { | ||
| 147 | HRESULT hr = S_OK; | ||
| 148 | INI_HANDLE iniHandle = NULL; | ||
| 149 | INI_HANDLE iniHandle2 = NULL; | ||
| 150 | INI_VALUE *rgValues = NULL; | ||
| 151 | DWORD cValues = 0; | ||
| 152 | |||
| 153 | try | ||
| 154 | { | ||
| 155 | hr = FileWrite(wzIniFilePath, 0, reinterpret_cast<LPCBYTE>(wzContents), lstrlenW(wzContents) * sizeof(WCHAR), NULL); | ||
| 156 | NativeAssert::Succeeded(hr, "Failed to write out INI file"); | ||
| 157 | |||
| 158 | hr = IniInitialize(&iniHandle); | ||
| 159 | NativeAssert::Succeeded(hr, "Failed to initialize INI object"); | ||
| 160 | |||
| 161 | hr = SetFormat(iniHandle); | ||
| 162 | NativeAssert::Succeeded(hr, "Failed to set parameters for INI file"); | ||
| 163 | |||
| 164 | hr = IniParse(iniHandle, wzIniFilePath, NULL); | ||
| 165 | NativeAssert::Succeeded(hr, "Failed to parse INI file"); | ||
| 166 | |||
| 167 | hr = IniGetValueList(iniHandle, &rgValues, &cValues); | ||
| 168 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
| 169 | |||
| 170 | NativeAssert::Equal<DWORD>(5, cValues); | ||
| 171 | |||
| 172 | AssertValue(iniHandle, L"PlainValue", L"Blah"); | ||
| 173 | AssertNoValue(iniHandle, L"PlainValue2"); | ||
| 174 | AssertValue(iniHandle, L"Section1\\Section1ValueA", L"Foo"); | ||
| 175 | AssertValue(iniHandle, L"Section1\\Section1ValueB", L"Bar"); | ||
| 176 | AssertValue(iniHandle, L"Section2\\Section2ValueA", L"Cha"); | ||
| 177 | AssertNoValue(iniHandle, L"Section1\\ValueDoesntExist"); | ||
| 178 | AssertValue(iniHandle, L"Section2\\Array[0]", L"Arr"); | ||
| 179 | |||
| 180 | hr = IniSetValue(iniHandle, L"PlainValue2", L"Blah2"); | ||
| 181 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 182 | |||
| 183 | hr = IniSetValue(iniHandle, L"Section1\\CreatedValue", L"Woo"); | ||
| 184 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 185 | |||
| 186 | hr = IniSetValue(iniHandle, L"Section2\\Array[0]", L"Arrmod"); | ||
| 187 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 188 | |||
| 189 | hr = IniGetValueList(iniHandle, &rgValues, &cValues); | ||
| 190 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
| 191 | |||
| 192 | NativeAssert::Equal<DWORD>(7, cValues); | ||
| 193 | |||
| 194 | AssertValue(iniHandle, L"PlainValue", L"Blah"); | ||
| 195 | AssertValue(iniHandle, L"PlainValue2", L"Blah2"); | ||
| 196 | AssertValue(iniHandle, L"Section1\\Section1ValueA", L"Foo"); | ||
| 197 | AssertValue(iniHandle, L"Section1\\Section1ValueB", L"Bar"); | ||
| 198 | AssertValue(iniHandle, L"Section2\\Section2ValueA", L"Cha"); | ||
| 199 | AssertNoValue(iniHandle, L"Section1\\ValueDoesntExist"); | ||
| 200 | AssertValue(iniHandle, L"Section1\\CreatedValue", L"Woo"); | ||
| 201 | AssertValue(iniHandle, L"Section2\\Array[0]", L"Arrmod"); | ||
| 202 | |||
| 203 | // Try deleting a value as well | ||
| 204 | hr = IniSetValue(iniHandle, L"Section1\\Section1ValueB", NULL); | ||
| 205 | NativeAssert::Succeeded(hr, "Failed to kill value in INI"); | ||
| 206 | |||
| 207 | hr = IniWriteFile(iniHandle, NULL, FILE_ENCODING_UNSPECIFIED); | ||
| 208 | NativeAssert::Succeeded(hr, "Failed to write ini file back out to disk"); | ||
| 209 | |||
| 210 | ReleaseNullIni(iniHandle); | ||
| 211 | // Now re-parse the INI we just wrote and make sure it matches the values we expect | ||
| 212 | hr = IniInitialize(&iniHandle2); | ||
| 213 | NativeAssert::Succeeded(hr, "Failed to initialize INI object"); | ||
| 214 | |||
| 215 | hr = SetFormat(iniHandle2); | ||
| 216 | NativeAssert::Succeeded(hr, "Failed to set parameters for INI file"); | ||
| 217 | |||
| 218 | hr = IniParse(iniHandle2, wzIniFilePath, NULL); | ||
| 219 | NativeAssert::Succeeded(hr, "Failed to parse INI file"); | ||
| 220 | |||
| 221 | hr = IniGetValueList(iniHandle2, &rgValues, &cValues); | ||
| 222 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
| 223 | |||
| 224 | NativeAssert::Equal<DWORD>(6, cValues); | ||
| 225 | |||
| 226 | AssertValue(iniHandle2, L"PlainValue", L"Blah"); | ||
| 227 | AssertValue(iniHandle2, L"PlainValue2", L"Blah2"); | ||
| 228 | AssertValue(iniHandle2, L"Section1\\Section1ValueA", L"Foo"); | ||
| 229 | AssertNoValue(iniHandle2, L"Section1\\Section1ValueB"); | ||
| 230 | AssertValue(iniHandle2, L"Section2\\Section2ValueA", L"Cha"); | ||
| 231 | AssertNoValue(iniHandle2, L"Section1\\ValueDoesntExist"); | ||
| 232 | AssertValue(iniHandle2, L"Section1\\CreatedValue", L"Woo"); | ||
| 233 | AssertValue(iniHandle2, L"Section2\\Array[0]", L"Arrmod"); | ||
| 234 | } | ||
| 235 | finally | ||
| 236 | { | ||
| 237 | ReleaseIni(iniHandle); | ||
| 238 | ReleaseIni(iniHandle2); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | void TestWriteThenRead(LPWSTR wzIniFilePath, IniFormatParameters SetFormat) | ||
| 243 | { | ||
| 244 | HRESULT hr = S_OK; | ||
| 245 | INI_HANDLE iniHandle = NULL; | ||
| 246 | INI_HANDLE iniHandle2 = NULL; | ||
| 247 | INI_VALUE *rgValues = NULL; | ||
| 248 | DWORD cValues = 0; | ||
| 249 | |||
| 250 | try | ||
| 251 | { | ||
| 252 | hr = FileEnsureDelete(wzIniFilePath); | ||
| 253 | NativeAssert::Succeeded(hr, "Failed to ensure file is deleted"); | ||
| 254 | |||
| 255 | hr = IniInitialize(&iniHandle); | ||
| 256 | NativeAssert::Succeeded(hr, "Failed to initialize INI object"); | ||
| 257 | |||
| 258 | hr = SetFormat(iniHandle); | ||
| 259 | NativeAssert::Succeeded(hr, "Failed to set parameters for INI file"); | ||
| 260 | |||
| 261 | hr = IniGetValueList(iniHandle, &rgValues, &cValues); | ||
| 262 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
| 263 | |||
| 264 | NativeAssert::Equal<DWORD>(0, cValues); | ||
| 265 | |||
| 266 | hr = IniSetValue(iniHandle, L"Value1", L"BlahTypo"); | ||
| 267 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 268 | |||
| 269 | hr = IniSetValue(iniHandle, L"Value2", L"Blah2"); | ||
| 270 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 271 | |||
| 272 | hr = IniSetValue(iniHandle, L"Section1\\Value1", L"Section1Value1"); | ||
| 273 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 274 | |||
| 275 | hr = IniSetValue(iniHandle, L"Section1\\Value2", L"Section1Value2"); | ||
| 276 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 277 | |||
| 278 | hr = IniSetValue(iniHandle, L"Section2\\Value1", L"Section2Value1"); | ||
| 279 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 280 | |||
| 281 | hr = IniSetValue(iniHandle, L"Section2\\Array[0]", L"Arr"); | ||
| 282 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 283 | |||
| 284 | hr = IniSetValue(iniHandle, L"Value3", L"Blah3"); | ||
| 285 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 286 | |||
| 287 | hr = IniSetValue(iniHandle, L"Value4", L"Blah4"); | ||
| 288 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 289 | |||
| 290 | hr = IniSetValue(iniHandle, L"Value4", NULL); | ||
| 291 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 292 | |||
| 293 | hr = IniSetValue(iniHandle, L"Value1", L"Blah1"); | ||
| 294 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
| 295 | |||
| 296 | hr = IniGetValueList(iniHandle, &rgValues, &cValues); | ||
| 297 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
| 298 | |||
| 299 | NativeAssert::Equal<DWORD>(8, cValues); | ||
| 300 | |||
| 301 | AssertValue(iniHandle, L"Value1", L"Blah1"); | ||
| 302 | AssertValue(iniHandle, L"Value2", L"Blah2"); | ||
| 303 | AssertValue(iniHandle, L"Value3", L"Blah3"); | ||
| 304 | AssertNoValue(iniHandle, L"Value4"); | ||
| 305 | AssertValue(iniHandle, L"Section1\\Value1", L"Section1Value1"); | ||
| 306 | AssertValue(iniHandle, L"Section1\\Value2", L"Section1Value2"); | ||
| 307 | AssertValue(iniHandle, L"Section2\\Value1", L"Section2Value1"); | ||
| 308 | AssertValue(iniHandle, L"Section2\\Array[0]", L"Arr"); | ||
| 309 | |||
| 310 | hr = IniWriteFile(iniHandle, wzIniFilePath, FILE_ENCODING_UNSPECIFIED); | ||
| 311 | NativeAssert::Succeeded(hr, "Failed to write ini file back out to disk"); | ||
| 312 | |||
| 313 | ReleaseNullIni(iniHandle); | ||
| 314 | // Now re-parse the INI we just wrote and make sure it matches the values we expect | ||
| 315 | hr = IniInitialize(&iniHandle2); | ||
| 316 | NativeAssert::Succeeded(hr, "Failed to initialize INI object"); | ||
| 317 | |||
| 318 | hr = SetFormat(iniHandle2); | ||
| 319 | NativeAssert::Succeeded(hr, "Failed to set parameters for INI file"); | ||
| 320 | |||
| 321 | hr = IniParse(iniHandle2, wzIniFilePath, NULL); | ||
| 322 | NativeAssert::Succeeded(hr, "Failed to parse INI file"); | ||
| 323 | |||
| 324 | hr = IniGetValueList(iniHandle2, &rgValues, &cValues); | ||
| 325 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
| 326 | |||
| 327 | NativeAssert::Equal<DWORD>(7, cValues); | ||
| 328 | |||
| 329 | AssertValue(iniHandle2, L"Value1", L"Blah1"); | ||
| 330 | AssertValue(iniHandle2, L"Value2", L"Blah2"); | ||
| 331 | AssertValue(iniHandle2, L"Value3", L"Blah3"); | ||
| 332 | AssertNoValue(iniHandle2, L"Value4"); | ||
| 333 | AssertValue(iniHandle2, L"Section1\\Value1", L"Section1Value1"); | ||
| 334 | AssertValue(iniHandle2, L"Section1\\Value2", L"Section1Value2"); | ||
| 335 | AssertValue(iniHandle2, L"Section2\\Value1", L"Section2Value1"); | ||
| 336 | AssertValue(iniHandle2, L"Section2\\Array[0]", L"Arr"); | ||
| 337 | } | ||
| 338 | finally | ||
| 339 | { | ||
| 340 | ReleaseIni(iniHandle); | ||
| 341 | ReleaseIni(iniHandle2); | ||
| 342 | } | ||
| 343 | } | ||
| 344 | }; | ||
| 345 | } | ||
diff --git a/src/test/DUtilUnitTest/MemUtilTest.cpp b/src/test/DUtilUnitTest/MemUtilTest.cpp deleted file mode 100644 index 09692bfb..00000000 --- a/src/test/DUtilUnitTest/MemUtilTest.cpp +++ /dev/null | |||
| @@ -1,505 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | namespace DutilTests | ||
| 10 | { | ||
| 11 | struct ArrayValue | ||
| 12 | { | ||
| 13 | DWORD dwNum; | ||
| 14 | void *pvNull1; | ||
| 15 | LPWSTR sczString; | ||
| 16 | void *pvNull2; | ||
| 17 | }; | ||
| 18 | |||
| 19 | public ref class MemUtil | ||
| 20 | { | ||
| 21 | public: | ||
| 22 | [Fact] | ||
| 23 | void MemUtilAppendTest() | ||
| 24 | { | ||
| 25 | HRESULT hr = S_OK; | ||
| 26 | DWORD dwSize; | ||
| 27 | ArrayValue *rgValues = NULL; | ||
| 28 | DWORD cValues = 0; | ||
| 29 | |||
| 30 | DutilInitialize(&DutilTestTraceError); | ||
| 31 | |||
| 32 | try | ||
| 33 | { | ||
| 34 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5); | ||
| 35 | NativeAssert::Succeeded(hr, "Failed to grow array size to 1"); | ||
| 36 | ++cValues; | ||
| 37 | SetItem(rgValues + 0, 0); | ||
| 38 | |||
| 39 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5); | ||
| 40 | NativeAssert::Succeeded(hr, "Failed to grow array size to 2"); | ||
| 41 | ++cValues; | ||
| 42 | SetItem(rgValues + 1, 1); | ||
| 43 | |||
| 44 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5); | ||
| 45 | NativeAssert::Succeeded(hr, "Failed to grow array size to 3"); | ||
| 46 | ++cValues; | ||
| 47 | SetItem(rgValues + 2, 2); | ||
| 48 | |||
| 49 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5); | ||
| 50 | NativeAssert::Succeeded(hr, "Failed to grow array size to 4"); | ||
| 51 | ++cValues; | ||
| 52 | SetItem(rgValues + 3, 3); | ||
| 53 | |||
| 54 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5); | ||
| 55 | NativeAssert::Succeeded(hr, "Failed to grow array size to 5"); | ||
| 56 | ++cValues; | ||
| 57 | SetItem(rgValues + 4, 4); | ||
| 58 | |||
| 59 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5); | ||
| 60 | NativeAssert::Succeeded(hr, "Failed to grow array size to 6"); | ||
| 61 | ++cValues; | ||
| 62 | SetItem(rgValues + 5, 5); | ||
| 63 | |||
| 64 | // OK, we used growth size 5, so let's try ensuring we have space for 6 (5 + first item) items | ||
| 65 | // and make sure it doesn't grow since we already have enough space | ||
| 66 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues, sizeof(ArrayValue), 5); | ||
| 67 | NativeAssert::Succeeded(hr, "Failed to ensure array size matches what it should already be"); | ||
| 68 | dwSize = MemSize(rgValues); | ||
| 69 | if (dwSize != 6 * sizeof(ArrayValue)) | ||
| 70 | { | ||
| 71 | hr = E_FAIL; | ||
| 72 | ExitOnFailure(hr, "MemEnsureArraySize is growing an array that is already big enough!"); | ||
| 73 | } | ||
| 74 | |||
| 75 | for (DWORD i = 0; i < cValues; ++i) | ||
| 76 | { | ||
| 77 | CheckItem(rgValues + i, i); | ||
| 78 | } | ||
| 79 | |||
| 80 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5); | ||
| 81 | NativeAssert::Succeeded(hr, "Failed to grow array size to 7"); | ||
| 82 | ++cValues; | ||
| 83 | SetItem(rgValues + 6, 6); | ||
| 84 | |||
| 85 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5); | ||
| 86 | NativeAssert::Succeeded(hr, "Failed to grow array size to 7"); | ||
| 87 | ++cValues; | ||
| 88 | SetItem(rgValues + 7, 7); | ||
| 89 | |||
| 90 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5); | ||
| 91 | NativeAssert::Succeeded(hr, "Failed to grow array size to 7"); | ||
| 92 | ++cValues; | ||
| 93 | SetItem(rgValues + 8, 8); | ||
| 94 | |||
| 95 | for (DWORD i = 0; i < cValues; ++i) | ||
| 96 | { | ||
| 97 | CheckItem(rgValues + i, i); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | finally | ||
| 101 | { | ||
| 102 | ReleaseMem(rgValues); | ||
| 103 | } | ||
| 104 | |||
| 105 | LExit: | ||
| 106 | DutilUninitialize(); | ||
| 107 | } | ||
| 108 | |||
| 109 | [Fact] | ||
| 110 | void MemUtilInsertTest() | ||
| 111 | { | ||
| 112 | HRESULT hr = S_OK; | ||
| 113 | ArrayValue *rgValues = NULL; | ||
| 114 | DWORD cValues = 0; | ||
| 115 | |||
| 116 | DutilInitialize(&DutilTestTraceError); | ||
| 117 | |||
| 118 | try | ||
| 119 | { | ||
| 120 | hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 0, 1, cValues + 1, sizeof(ArrayValue), 5); | ||
| 121 | NativeAssert::Succeeded(hr, "Failed to insert into beginning of empty array"); | ||
| 122 | ++cValues; | ||
| 123 | CheckNullItem(rgValues + 0); | ||
| 124 | SetItem(rgValues + 0, 5); | ||
| 125 | |||
| 126 | hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 1, 1, cValues + 1, sizeof(ArrayValue), 5); | ||
| 127 | NativeAssert::Succeeded(hr, "Failed to insert at end of array"); | ||
| 128 | ++cValues; | ||
| 129 | CheckNullItem(rgValues + 1); | ||
| 130 | SetItem(rgValues + 1, 6); | ||
| 131 | |||
| 132 | hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 0, 1, cValues + 1, sizeof(ArrayValue), 5); | ||
| 133 | NativeAssert::Succeeded(hr, "Failed to insert into beginning of array"); | ||
| 134 | ++cValues; | ||
| 135 | CheckNullItem(rgValues + 0); | ||
| 136 | SetItem(rgValues + 0, 4); | ||
| 137 | |||
| 138 | hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 0, 1, cValues + 1, sizeof(ArrayValue), 5); | ||
| 139 | NativeAssert::Succeeded(hr, "Failed to insert into beginning of array"); | ||
| 140 | ++cValues; | ||
| 141 | CheckNullItem(rgValues + 0); | ||
| 142 | SetItem(rgValues + 0, 3); | ||
| 143 | |||
| 144 | hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 0, 1, cValues + 1, sizeof(ArrayValue), 5); | ||
| 145 | NativeAssert::Succeeded(hr, "Failed to insert into beginning of array"); | ||
| 146 | ++cValues; | ||
| 147 | CheckNullItem(rgValues + 0); | ||
| 148 | SetItem(rgValues + 0, 1); | ||
| 149 | |||
| 150 | hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 1, 1, cValues + 1, sizeof(ArrayValue), 5); | ||
| 151 | NativeAssert::Succeeded(hr, "Failed to insert into beginning of array"); | ||
| 152 | ++cValues; | ||
| 153 | CheckNullItem(rgValues + 1); | ||
| 154 | SetItem(rgValues + 1, 2); | ||
| 155 | |||
| 156 | hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 0, 1, cValues + 1, sizeof(ArrayValue), 5); | ||
| 157 | NativeAssert::Succeeded(hr, "Failed to insert into beginning of array"); | ||
| 158 | ++cValues; | ||
| 159 | CheckNullItem(rgValues + 0); | ||
| 160 | SetItem(rgValues + 0, 0); | ||
| 161 | |||
| 162 | for (DWORD i = 0; i < cValues; ++i) | ||
| 163 | { | ||
| 164 | CheckItem(rgValues + i, i); | ||
| 165 | } | ||
| 166 | |||
| 167 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5); | ||
| 168 | NativeAssert::Succeeded(hr, "Failed to grow array size to 7"); | ||
| 169 | ++cValues; | ||
| 170 | CheckNullItem(rgValues + 7); | ||
| 171 | SetItem(rgValues + 7, 7); | ||
| 172 | |||
| 173 | hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 8, 1, cValues + 1, sizeof(ArrayValue), 5); | ||
| 174 | NativeAssert::Succeeded(hr, "Failed to insert into beginning of array"); | ||
| 175 | ++cValues; | ||
| 176 | CheckNullItem(rgValues + 8); | ||
| 177 | SetItem(rgValues + 8, 8); | ||
| 178 | |||
| 179 | for (DWORD i = 0; i < cValues; ++i) | ||
| 180 | { | ||
| 181 | CheckItem(rgValues + i, i); | ||
| 182 | } | ||
| 183 | } | ||
| 184 | finally | ||
| 185 | { | ||
| 186 | ReleaseMem(rgValues); | ||
| 187 | DutilUninitialize(); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | [Fact] | ||
| 192 | void MemUtilRemovePreserveOrderTest() | ||
| 193 | { | ||
| 194 | HRESULT hr = S_OK; | ||
| 195 | ArrayValue *rgValues = NULL; | ||
| 196 | DWORD cValues = 0; | ||
| 197 | |||
| 198 | DutilInitialize(&DutilTestTraceError); | ||
| 199 | |||
| 200 | try | ||
| 201 | { | ||
| 202 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), 10, sizeof(ArrayValue), 10); | ||
| 203 | NativeAssert::Succeeded(hr, "Failed to grow array size to 10"); | ||
| 204 | |||
| 205 | cValues = 10; | ||
| 206 | for (DWORD i = 0; i < cValues; ++i) | ||
| 207 | { | ||
| 208 | SetItem(rgValues + i, i); | ||
| 209 | } | ||
| 210 | |||
| 211 | // Remove last item | ||
| 212 | MemRemoveFromArray(rgValues, 9, 1, cValues, sizeof(ArrayValue), TRUE); | ||
| 213 | --cValues; | ||
| 214 | |||
| 215 | for (DWORD i = 0; i < cValues; ++i) | ||
| 216 | { | ||
| 217 | CheckItem(rgValues + i, i); | ||
| 218 | } | ||
| 219 | |||
| 220 | // Remove last two items | ||
| 221 | MemRemoveFromArray(rgValues, 7, 2, cValues, sizeof(ArrayValue), TRUE); | ||
| 222 | cValues -= 2; | ||
| 223 | |||
| 224 | for (DWORD i = 0; i < cValues; ++i) | ||
| 225 | { | ||
| 226 | CheckItem(rgValues + i, i); | ||
| 227 | } | ||
| 228 | |||
| 229 | // Remove first item | ||
| 230 | MemRemoveFromArray(rgValues, 0, 1, cValues, sizeof(ArrayValue), TRUE); | ||
| 231 | --cValues; | ||
| 232 | |||
| 233 | for (DWORD i = 0; i < cValues; ++i) | ||
| 234 | { | ||
| 235 | CheckItem(rgValues + i, i + 1); | ||
| 236 | } | ||
| 237 | |||
| 238 | |||
| 239 | // Remove first two items | ||
| 240 | MemRemoveFromArray(rgValues, 0, 2, cValues, sizeof(ArrayValue), TRUE); | ||
| 241 | cValues -= 2; | ||
| 242 | |||
| 243 | for (DWORD i = 0; i < cValues; ++i) | ||
| 244 | { | ||
| 245 | CheckItem(rgValues + i, i + 3); | ||
| 246 | } | ||
| 247 | |||
| 248 | // Remove middle two items | ||
| 249 | MemRemoveFromArray(rgValues, 1, 2, cValues, sizeof(ArrayValue), TRUE); | ||
| 250 | cValues -= 2; | ||
| 251 | |||
| 252 | CheckItem(rgValues, 3); | ||
| 253 | CheckItem(rgValues + 1, 6); | ||
| 254 | |||
| 255 | // Remove last 2 items to ensure we don't crash | ||
| 256 | MemRemoveFromArray(rgValues, 0, 2, cValues, sizeof(ArrayValue), TRUE); | ||
| 257 | cValues -= 2; | ||
| 258 | } | ||
| 259 | finally | ||
| 260 | { | ||
| 261 | ReleaseMem(rgValues); | ||
| 262 | DutilUninitialize(); | ||
| 263 | } | ||
| 264 | } | ||
| 265 | |||
| 266 | [Fact] | ||
| 267 | void MemUtilRemoveFastTest() | ||
| 268 | { | ||
| 269 | HRESULT hr = S_OK; | ||
| 270 | ArrayValue *rgValues = NULL; | ||
| 271 | DWORD cValues = 0; | ||
| 272 | |||
| 273 | DutilInitialize(&DutilTestTraceError); | ||
| 274 | |||
| 275 | try | ||
| 276 | { | ||
| 277 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), 10, sizeof(ArrayValue), 10); | ||
| 278 | NativeAssert::Succeeded(hr, "Failed to grow array size to 10"); | ||
| 279 | |||
| 280 | cValues = 10; | ||
| 281 | for (DWORD i = 0; i < cValues; ++i) | ||
| 282 | { | ||
| 283 | SetItem(rgValues + i, i); | ||
| 284 | } | ||
| 285 | |||
| 286 | // Remove last item | ||
| 287 | MemRemoveFromArray(rgValues, 9, 1, cValues, sizeof(ArrayValue), FALSE); | ||
| 288 | --cValues; | ||
| 289 | |||
| 290 | for (DWORD i = 0; i < cValues; ++i) | ||
| 291 | { | ||
| 292 | CheckItem(rgValues + i, i); | ||
| 293 | } | ||
| 294 | |||
| 295 | // Remove last two items | ||
| 296 | MemRemoveFromArray(rgValues, 7, 2, cValues, sizeof(ArrayValue), FALSE); | ||
| 297 | cValues -= 2; | ||
| 298 | |||
| 299 | for (DWORD i = 0; i < cValues; ++i) | ||
| 300 | { | ||
| 301 | CheckItem(rgValues + i, i); | ||
| 302 | } | ||
| 303 | |||
| 304 | // Remove first item | ||
| 305 | MemRemoveFromArray(rgValues, 0, 1, cValues, sizeof(ArrayValue), FALSE); | ||
| 306 | --cValues; | ||
| 307 | |||
| 308 | CheckItem(rgValues, 6); | ||
| 309 | CheckItem(rgValues + 1, 1); | ||
| 310 | CheckItem(rgValues + 2, 2); | ||
| 311 | CheckItem(rgValues + 3, 3); | ||
| 312 | CheckItem(rgValues + 4, 4); | ||
| 313 | CheckItem(rgValues + 5, 5); | ||
| 314 | |||
| 315 | // Remove first two items | ||
| 316 | MemRemoveFromArray(rgValues, 0, 2, cValues, sizeof(ArrayValue), FALSE); | ||
| 317 | cValues -= 2; | ||
| 318 | |||
| 319 | CheckItem(rgValues, 4); | ||
| 320 | CheckItem(rgValues + 1, 5); | ||
| 321 | CheckItem(rgValues + 2, 2); | ||
| 322 | CheckItem(rgValues + 3, 3); | ||
| 323 | |||
| 324 | |||
| 325 | // Remove middle two items | ||
| 326 | MemRemoveFromArray(rgValues, 1, 2, cValues, sizeof(ArrayValue), FALSE); | ||
| 327 | cValues -= 2; | ||
| 328 | |||
| 329 | CheckItem(rgValues, 4); | ||
| 330 | CheckItem(rgValues + 1, 3); | ||
| 331 | |||
| 332 | // Remove last 2 items to ensure we don't crash | ||
| 333 | MemRemoveFromArray(rgValues, 0, 2, cValues, sizeof(ArrayValue), FALSE); | ||
| 334 | cValues -= 2; | ||
| 335 | } | ||
| 336 | finally | ||
| 337 | { | ||
| 338 | ReleaseMem(rgValues); | ||
| 339 | DutilUninitialize(); | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | [Fact] | ||
| 344 | void MemUtilSwapTest() | ||
| 345 | { | ||
| 346 | HRESULT hr = S_OK; | ||
| 347 | ArrayValue *rgValues = NULL; | ||
| 348 | DWORD cValues = 0; | ||
| 349 | |||
| 350 | DutilInitialize(&DutilTestTraceError); | ||
| 351 | |||
| 352 | try | ||
| 353 | { | ||
| 354 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), 10, sizeof(ArrayValue), 10); | ||
| 355 | NativeAssert::Succeeded(hr, "Failed to grow array size to 10"); | ||
| 356 | |||
| 357 | cValues = 10; | ||
| 358 | for (DWORD i = 0; i < cValues; ++i) | ||
| 359 | { | ||
| 360 | SetItem(rgValues + i, i); | ||
| 361 | } | ||
| 362 | |||
| 363 | // Swap first two | ||
| 364 | MemArraySwapItems(rgValues, 0, 1, sizeof(ArrayValue)); | ||
| 365 | --cValues; | ||
| 366 | |||
| 367 | CheckItem(rgValues, 1); | ||
| 368 | CheckItem(rgValues + 1, 0); | ||
| 369 | for (DWORD i = 2; i < cValues; ++i) | ||
| 370 | { | ||
| 371 | CheckItem(rgValues + i, i); | ||
| 372 | } | ||
| 373 | |||
| 374 | // Swap them back | ||
| 375 | MemArraySwapItems(rgValues, 0, 1, sizeof(ArrayValue)); | ||
| 376 | --cValues; | ||
| 377 | |||
| 378 | for (DWORD i = 0; i < cValues; ++i) | ||
| 379 | { | ||
| 380 | CheckItem(rgValues + i, i); | ||
| 381 | } | ||
| 382 | |||
| 383 | // Swap first and last items (index 0 and 9) | ||
| 384 | MemArraySwapItems(rgValues, 0, 9, sizeof(ArrayValue)); | ||
| 385 | --cValues; | ||
| 386 | |||
| 387 | CheckItem(rgValues, 9); | ||
| 388 | CheckItem(rgValues + 9, 0); | ||
| 389 | for (DWORD i = 1; i < cValues - 1; ++i) | ||
| 390 | { | ||
| 391 | CheckItem(rgValues + i, i); | ||
| 392 | } | ||
| 393 | |||
| 394 | // Swap index 1 and 8 | ||
| 395 | MemArraySwapItems(rgValues, 1, 8, sizeof(ArrayValue)); | ||
| 396 | --cValues; | ||
| 397 | |||
| 398 | CheckItem(rgValues, 9); | ||
| 399 | CheckItem(rgValues + 1, 8); | ||
| 400 | CheckItem(rgValues + 8, 1); | ||
| 401 | CheckItem(rgValues + 9, 0); | ||
| 402 | for (DWORD i = 2; i < cValues - 2; ++i) | ||
| 403 | { | ||
| 404 | CheckItem(rgValues + i, i); | ||
| 405 | } | ||
| 406 | |||
| 407 | // Swap index 2 and 7 | ||
| 408 | MemArraySwapItems(rgValues, 2, 7, sizeof(ArrayValue)); | ||
| 409 | --cValues; | ||
| 410 | |||
| 411 | CheckItem(rgValues, 9); | ||
| 412 | CheckItem(rgValues + 1, 8); | ||
| 413 | CheckItem(rgValues + 2, 7); | ||
| 414 | CheckItem(rgValues + 7, 2); | ||
| 415 | CheckItem(rgValues + 8, 1); | ||
| 416 | CheckItem(rgValues + 9, 0); | ||
| 417 | for (DWORD i = 3; i < cValues - 3; ++i) | ||
| 418 | { | ||
| 419 | CheckItem(rgValues + i, i); | ||
| 420 | } | ||
| 421 | |||
| 422 | // Swap index 0 and 1 | ||
| 423 | MemArraySwapItems(rgValues, 0, 1, sizeof(ArrayValue)); | ||
| 424 | --cValues; | ||
| 425 | |||
| 426 | CheckItem(rgValues, 8); | ||
| 427 | CheckItem(rgValues + 1, 9); | ||
| 428 | CheckItem(rgValues + 2, 7); | ||
| 429 | CheckItem(rgValues + 7, 2); | ||
| 430 | CheckItem(rgValues + 8, 1); | ||
| 431 | CheckItem(rgValues + 9, 0); | ||
| 432 | for (DWORD i = 3; i < cValues - 3; ++i) | ||
| 433 | { | ||
| 434 | CheckItem(rgValues + i, i); | ||
| 435 | } | ||
| 436 | } | ||
| 437 | finally | ||
| 438 | { | ||
| 439 | ReleaseMem(rgValues); | ||
| 440 | DutilUninitialize(); | ||
| 441 | } | ||
| 442 | } | ||
| 443 | |||
| 444 | private: | ||
| 445 | void SetItem(ArrayValue *pValue, DWORD dwValue) | ||
| 446 | { | ||
| 447 | HRESULT hr = S_OK; | ||
| 448 | pValue->dwNum = dwValue; | ||
| 449 | |||
| 450 | hr = StrAllocFormatted(&pValue->sczString, L"%u", dwValue); | ||
| 451 | NativeAssert::Succeeded(hr, "Failed to allocate string"); | ||
| 452 | } | ||
| 453 | |||
| 454 | void CheckItem(ArrayValue *pValue, DWORD dwValue) | ||
| 455 | { | ||
| 456 | HRESULT hr = S_OK; | ||
| 457 | LPWSTR sczTemp = NULL; | ||
| 458 | |||
| 459 | try | ||
| 460 | { | ||
| 461 | NativeAssert::Equal(dwValue, pValue->dwNum); | ||
| 462 | |||
| 463 | hr = StrAllocFormatted(&sczTemp, L"%u", dwValue); | ||
| 464 | NativeAssert::Succeeded(hr, "Failed to allocate temp string"); | ||
| 465 | |||
| 466 | NativeAssert::StringEqual(sczTemp, pValue->sczString, TRUE); | ||
| 467 | |||
| 468 | if (pValue->pvNull1 || pValue->pvNull2) | ||
| 469 | { | ||
| 470 | hr = E_FAIL; | ||
| 471 | ExitOnFailure(hr, "One of the expected NULL values wasn't NULL!"); | ||
| 472 | } | ||
| 473 | } | ||
| 474 | finally | ||
| 475 | { | ||
| 476 | ReleaseStr(sczTemp); | ||
| 477 | } | ||
| 478 | |||
| 479 | LExit: | ||
| 480 | return; | ||
| 481 | } | ||
| 482 | |||
| 483 | void CheckNullItem(ArrayValue *pValue) | ||
| 484 | { | ||
| 485 | HRESULT hr = S_OK; | ||
| 486 | |||
| 487 | NativeAssert::Equal<DWORD>(0, pValue->dwNum); | ||
| 488 | |||
| 489 | if (pValue->sczString) | ||
| 490 | { | ||
| 491 | hr = E_FAIL; | ||
| 492 | ExitOnFailure(hr, "Item found isn't NULL!"); | ||
| 493 | } | ||
| 494 | |||
| 495 | if (pValue->pvNull1 || pValue->pvNull2) | ||
| 496 | { | ||
| 497 | hr = E_FAIL; | ||
| 498 | ExitOnFailure(hr, "One of the expected NULL values wasn't NULL!"); | ||
| 499 | } | ||
| 500 | |||
| 501 | LExit: | ||
| 502 | return; | ||
| 503 | } | ||
| 504 | }; | ||
| 505 | } | ||
diff --git a/src/test/DUtilUnitTest/MonUtilTest.cpp b/src/test/DUtilUnitTest/MonUtilTest.cpp deleted file mode 100644 index 273f2eb6..00000000 --- a/src/test/DUtilUnitTest/MonUtilTest.cpp +++ /dev/null | |||
| @@ -1,487 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | #undef RemoveDirectory | ||
| 5 | |||
| 6 | using namespace System; | ||
| 7 | using namespace System::Collections::Generic; | ||
| 8 | using namespace System::Runtime::InteropServices; | ||
| 9 | using namespace Xunit; | ||
| 10 | using namespace WixBuildTools::TestSupport; | ||
| 11 | |||
| 12 | namespace DutilTests | ||
| 13 | { | ||
| 14 | const int PREWAIT = 20; | ||
| 15 | const int POSTWAIT = 480; | ||
| 16 | const int FULLWAIT = 500; | ||
| 17 | const int SILENCEPERIOD = 100; | ||
| 18 | |||
| 19 | struct RegKey | ||
| 20 | { | ||
| 21 | HRESULT hr; | ||
| 22 | HKEY hkRoot; | ||
| 23 | LPCWSTR wzSubKey; | ||
| 24 | REG_KEY_BITNESS kbKeyBitness; | ||
| 25 | BOOL fRecursive; | ||
| 26 | }; | ||
| 27 | struct Directory | ||
| 28 | { | ||
| 29 | HRESULT hr; | ||
| 30 | LPCWSTR wzPath; | ||
| 31 | BOOL fRecursive; | ||
| 32 | }; | ||
| 33 | struct Results | ||
| 34 | { | ||
| 35 | RegKey *rgRegKeys; | ||
| 36 | DWORD cRegKeys; | ||
| 37 | Directory *rgDirectories; | ||
| 38 | DWORD cDirectories; | ||
| 39 | }; | ||
| 40 | |||
| 41 | public delegate void MonGeneralDelegate(HRESULT, LPVOID); | ||
| 42 | |||
| 43 | public delegate void MonDriveStatusDelegate(WCHAR, BOOL, LPVOID); | ||
| 44 | |||
| 45 | public delegate void MonDirectoryDelegate(HRESULT, LPCWSTR, BOOL, LPVOID, LPVOID); | ||
| 46 | |||
| 47 | public delegate void MonRegKeyDelegate(HRESULT, HKEY, LPCWSTR, REG_KEY_BITNESS, BOOL, LPVOID, LPVOID); | ||
| 48 | |||
| 49 | static void MonGeneral( | ||
| 50 | __in HRESULT /*hrResult*/, | ||
| 51 | __in_opt LPVOID /*pvContext*/ | ||
| 52 | ) | ||
| 53 | { | ||
| 54 | Assert::True(false); | ||
| 55 | } | ||
| 56 | |||
| 57 | static void MonDriveStatus( | ||
| 58 | __in WCHAR /*chDrive*/, | ||
| 59 | __in BOOL /*fArriving*/, | ||
| 60 | __in_opt LPVOID /*pvContext*/ | ||
| 61 | ) | ||
| 62 | { | ||
| 63 | } | ||
| 64 | |||
| 65 | static void MonDirectory( | ||
| 66 | __in HRESULT hrResult, | ||
| 67 | __in_z LPCWSTR wzPath, | ||
| 68 | __in_z BOOL fRecursive, | ||
| 69 | __in_opt LPVOID pvContext, | ||
| 70 | __in_opt LPVOID pvDirectoryContext | ||
| 71 | ) | ||
| 72 | { | ||
| 73 | Assert::Equal(S_OK, hrResult); | ||
| 74 | Assert::Equal<DWORD_PTR>(0, reinterpret_cast<DWORD_PTR>(pvDirectoryContext)); | ||
| 75 | |||
| 76 | HRESULT hr = S_OK; | ||
| 77 | Results *pResults = reinterpret_cast<Results *>(pvContext); | ||
| 78 | |||
| 79 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pResults->rgDirectories), pResults->cDirectories + 1, sizeof(Directory), 5); | ||
| 80 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 81 | ++pResults->cDirectories; | ||
| 82 | |||
| 83 | pResults->rgDirectories[pResults->cDirectories - 1].hr = hrResult; | ||
| 84 | pResults->rgDirectories[pResults->cDirectories - 1].wzPath = wzPath; | ||
| 85 | pResults->rgDirectories[pResults->cDirectories - 1].fRecursive = fRecursive; | ||
| 86 | } | ||
| 87 | |||
| 88 | static void MonRegKey( | ||
| 89 | __in HRESULT hrResult, | ||
| 90 | __in HKEY hkRoot, | ||
| 91 | __in_z LPCWSTR wzSubKey, | ||
| 92 | __in REG_KEY_BITNESS kbKeyBitness, | ||
| 93 | __in_z BOOL fRecursive, | ||
| 94 | __in_opt LPVOID pvContext, | ||
| 95 | __in_opt LPVOID pvRegKeyContext | ||
| 96 | ) | ||
| 97 | { | ||
| 98 | Assert::Equal<HRESULT>(S_OK, hrResult); | ||
| 99 | Assert::Equal<DWORD_PTR>(0, reinterpret_cast<DWORD_PTR>(pvRegKeyContext)); | ||
| 100 | |||
| 101 | HRESULT hr = S_OK; | ||
| 102 | Results *pResults = reinterpret_cast<Results *>(pvContext); | ||
| 103 | |||
| 104 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pResults->rgRegKeys), pResults->cRegKeys + 1, sizeof(RegKey), 5); | ||
| 105 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 106 | ++pResults->cRegKeys; | ||
| 107 | |||
| 108 | pResults->rgRegKeys[pResults->cRegKeys - 1].hr = hrResult; | ||
| 109 | pResults->rgRegKeys[pResults->cRegKeys - 1].hkRoot = hkRoot; | ||
| 110 | pResults->rgRegKeys[pResults->cRegKeys - 1].wzSubKey = wzSubKey; | ||
| 111 | pResults->rgRegKeys[pResults->cRegKeys - 1].kbKeyBitness = kbKeyBitness; | ||
| 112 | pResults->rgRegKeys[pResults->cRegKeys - 1].fRecursive = fRecursive; | ||
| 113 | } | ||
| 114 | |||
| 115 | public ref class MonUtil | ||
| 116 | { | ||
| 117 | public: | ||
| 118 | void ClearResults(Results *pResults) | ||
| 119 | { | ||
| 120 | ReleaseNullMem(pResults->rgDirectories); | ||
| 121 | pResults->cDirectories = 0; | ||
| 122 | ReleaseNullMem(pResults->rgRegKeys); | ||
| 123 | pResults->cRegKeys = 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | void RemoveDirectory(LPCWSTR wzPath) | ||
| 127 | { | ||
| 128 | DWORD dwRetryCount = 0; | ||
| 129 | const DWORD c_dwMaxRetryCount = 100; | ||
| 130 | const DWORD c_dwRetryInterval = 50; | ||
| 131 | |||
| 132 | HRESULT hr = DirEnsureDelete(wzPath, TRUE, TRUE); | ||
| 133 | |||
| 134 | // Monitoring a directory opens a handle to that directory, which means delete requests for that directory will succeed | ||
| 135 | // (and deletion will be "pending" until our monitor handle is closed) | ||
| 136 | // but deletion of the directory containing that directory cannot complete until the handle is closed. This means DirEnsureDelete() | ||
| 137 | // can sometimes encounter HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) failures, which just means it needs to retry a bit later | ||
| 138 | // (after the waiter thread wakes up, it will release the handle) | ||
| 139 | while (HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) == hr && c_dwMaxRetryCount > dwRetryCount) | ||
| 140 | { | ||
| 141 | ::Sleep(c_dwRetryInterval); | ||
| 142 | ++dwRetryCount; | ||
| 143 | hr = DirEnsureDelete(wzPath, TRUE, TRUE); | ||
| 144 | } | ||
| 145 | |||
| 146 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE, E_PATHNOTFOUND); | ||
| 147 | } | ||
| 148 | |||
| 149 | void TestDirectory(MON_HANDLE handle, Results *pResults) | ||
| 150 | { | ||
| 151 | HRESULT hr = S_OK; | ||
| 152 | LPWSTR sczShallowPath = NULL; | ||
| 153 | LPWSTR sczParentPath = NULL; | ||
| 154 | LPWSTR sczDeepPath = NULL; | ||
| 155 | LPWSTR sczChildPath = NULL; | ||
| 156 | LPWSTR sczChildFilePath = NULL; | ||
| 157 | |||
| 158 | try | ||
| 159 | { | ||
| 160 | hr = PathExpand(&sczShallowPath, L"%TEMP%\\MonUtilTest\\", PATH_EXPAND_ENVIRONMENT); | ||
| 161 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 162 | |||
| 163 | hr = PathExpand(&sczParentPath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\", PATH_EXPAND_ENVIRONMENT); | ||
| 164 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 165 | |||
| 166 | hr = PathExpand(&sczDeepPath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\", PATH_EXPAND_ENVIRONMENT); | ||
| 167 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 168 | |||
| 169 | hr = PathExpand(&sczChildPath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\some\\sub\\folder\\", PATH_EXPAND_ENVIRONMENT); | ||
| 170 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 171 | |||
| 172 | hr = PathExpand(&sczChildFilePath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\some\\sub\\folder\\file.txt", PATH_EXPAND_ENVIRONMENT); | ||
| 173 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 174 | |||
| 175 | RemoveDirectory(sczShallowPath); | ||
| 176 | |||
| 177 | hr = MonAddDirectory(handle, sczDeepPath, TRUE, SILENCEPERIOD, NULL); | ||
| 178 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 179 | |||
| 180 | hr = DirEnsureExists(sczParentPath, NULL); | ||
| 181 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 182 | // Make sure creating the parent directory does nothing, even after silence period | ||
| 183 | ::Sleep(FULLWAIT); | ||
| 184 | Assert::Equal<DWORD>(0, pResults->cDirectories); | ||
| 185 | |||
| 186 | // Now create the target path, no notification until after the silence period | ||
| 187 | hr = DirEnsureExists(sczDeepPath, NULL); | ||
| 188 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 189 | ::Sleep(PREWAIT); | ||
| 190 | Assert::Equal<DWORD>(0, pResults->cDirectories); | ||
| 191 | |||
| 192 | // Now after the full silence period, it should have triggered | ||
| 193 | ::Sleep(POSTWAIT); | ||
| 194 | Assert::Equal<DWORD>(1, pResults->cDirectories); | ||
| 195 | NativeAssert::ValidReturnCode(pResults->rgDirectories[0].hr, S_OK); | ||
| 196 | |||
| 197 | // Now delete the directory, along with a ton of parents. This verifies MonUtil will keep watching the closest parent that still exists. | ||
| 198 | RemoveDirectory(sczShallowPath); | ||
| 199 | |||
| 200 | ::Sleep(FULLWAIT); | ||
| 201 | Assert::Equal<DWORD>(2, pResults->cDirectories); | ||
| 202 | NativeAssert::ValidReturnCode(pResults->rgDirectories[1].hr, S_OK); | ||
| 203 | |||
| 204 | // Create the parent directory again, still should be nothing even after full silence period | ||
| 205 | hr = DirEnsureExists(sczParentPath, NULL); | ||
| 206 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 207 | ::Sleep(FULLWAIT); | ||
| 208 | Assert::Equal<DWORD>(2, pResults->cDirectories); | ||
| 209 | |||
| 210 | hr = DirEnsureExists(sczChildPath, NULL); | ||
| 211 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 212 | ::Sleep(PREWAIT); | ||
| 213 | Assert::Equal<DWORD>(2, pResults->cDirectories); | ||
| 214 | |||
| 215 | ::Sleep(POSTWAIT); | ||
| 216 | Assert::Equal<DWORD>(3, pResults->cDirectories); | ||
| 217 | NativeAssert::ValidReturnCode(pResults->rgDirectories[2].hr, S_OK); | ||
| 218 | |||
| 219 | // Write a file to a deep child subfolder, and make sure it's detected | ||
| 220 | hr = FileFromString(sczChildFilePath, 0, L"contents", FILE_ENCODING_UTF16_WITH_BOM); | ||
| 221 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 222 | ::Sleep(PREWAIT); | ||
| 223 | Assert::Equal<DWORD>(3, pResults->cDirectories); | ||
| 224 | |||
| 225 | ::Sleep(POSTWAIT); | ||
| 226 | Assert::Equal<DWORD>(4, pResults->cDirectories); | ||
| 227 | NativeAssert::ValidReturnCode(pResults->rgDirectories[2].hr, S_OK); | ||
| 228 | |||
| 229 | RemoveDirectory(sczParentPath); | ||
| 230 | |||
| 231 | ::Sleep(FULLWAIT); | ||
| 232 | Assert::Equal<DWORD>(5, pResults->cDirectories); | ||
| 233 | NativeAssert::ValidReturnCode(pResults->rgDirectories[3].hr, S_OK); | ||
| 234 | |||
| 235 | // Now remove the directory from the list of things to monitor, and confirm changes are no longer tracked | ||
| 236 | hr = MonRemoveDirectory(handle, sczDeepPath, TRUE); | ||
| 237 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 238 | ::Sleep(PREWAIT); | ||
| 239 | |||
| 240 | hr = DirEnsureExists(sczDeepPath, NULL); | ||
| 241 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 242 | ::Sleep(FULLWAIT); | ||
| 243 | Assert::Equal<DWORD>(5, pResults->cDirectories); | ||
| 244 | NativeAssert::ValidReturnCode(pResults->rgDirectories[3].hr, S_OK); | ||
| 245 | |||
| 246 | // Finally, add it back so we can test multiple things to monitor at once | ||
| 247 | hr = MonAddDirectory(handle, sczDeepPath, TRUE, SILENCEPERIOD, NULL); | ||
| 248 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 249 | } | ||
| 250 | finally | ||
| 251 | { | ||
| 252 | ReleaseStr(sczShallowPath); | ||
| 253 | ReleaseStr(sczDeepPath); | ||
| 254 | ReleaseStr(sczParentPath); | ||
| 255 | } | ||
| 256 | } | ||
| 257 | |||
| 258 | void TestRegKey(MON_HANDLE handle, Results *pResults) | ||
| 259 | { | ||
| 260 | HRESULT hr = S_OK; | ||
| 261 | LPCWSTR wzShallowRegKey = L"Software\\MonUtilTest\\"; | ||
| 262 | LPCWSTR wzParentRegKey = L"Software\\MonUtilTest\\sub\\folder\\that\\might\\not\\"; | ||
| 263 | LPCWSTR wzDeepRegKey = L"Software\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\"; | ||
| 264 | LPCWSTR wzChildRegKey = L"Software\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\some\\sub\\folder\\"; | ||
| 265 | HKEY hk = NULL; | ||
| 266 | |||
| 267 | try | ||
| 268 | { | ||
| 269 | hr = RegDelete(HKEY_CURRENT_USER, wzShallowRegKey, REG_KEY_32BIT, TRUE); | ||
| 270 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE, E_PATHNOTFOUND); | ||
| 271 | |||
| 272 | hr = MonAddRegKey(handle, HKEY_CURRENT_USER, wzDeepRegKey, REG_KEY_DEFAULT, TRUE, SILENCEPERIOD, NULL); | ||
| 273 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 274 | |||
| 275 | hr = RegCreate(HKEY_CURRENT_USER, wzParentRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk); | ||
| 276 | ReleaseRegKey(hk); | ||
| 277 | // Make sure creating the parent key does nothing, even after silence period | ||
| 278 | ::Sleep(FULLWAIT); | ||
| 279 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 280 | Assert::Equal<DWORD>(0, pResults->cRegKeys); | ||
| 281 | |||
| 282 | // Now create the target path, no notification until after the silence period | ||
| 283 | hr = RegCreate(HKEY_CURRENT_USER, wzDeepRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk); | ||
| 284 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 285 | ReleaseRegKey(hk); | ||
| 286 | ::Sleep(PREWAIT); | ||
| 287 | Assert::Equal<DWORD>(0, pResults->cRegKeys); | ||
| 288 | |||
| 289 | // Now after the full silence period, it should have triggered | ||
| 290 | ::Sleep(POSTWAIT); | ||
| 291 | Assert::Equal<DWORD>(1, pResults->cRegKeys); | ||
| 292 | NativeAssert::ValidReturnCode(pResults->rgRegKeys[0].hr, S_OK); | ||
| 293 | |||
| 294 | // Now delete the directory, along with a ton of parents. This verifies MonUtil will keep watching the closest parent that still exists. | ||
| 295 | hr = RegDelete(HKEY_CURRENT_USER, wzShallowRegKey, REG_KEY_32BIT, TRUE); | ||
| 296 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE, E_PATHNOTFOUND); | ||
| 297 | ::Sleep(PREWAIT); | ||
| 298 | Assert::Equal<DWORD>(1, pResults->cRegKeys); | ||
| 299 | |||
| 300 | ::Sleep(FULLWAIT); | ||
| 301 | Assert::Equal<DWORD>(2, pResults->cRegKeys); | ||
| 302 | NativeAssert::ValidReturnCode(pResults->rgRegKeys[1].hr, S_OK); | ||
| 303 | |||
| 304 | // Create the parent directory again, still should be nothing even after full silence period | ||
| 305 | hr = RegCreate(HKEY_CURRENT_USER, wzParentRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk); | ||
| 306 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 307 | ReleaseRegKey(hk); | ||
| 308 | ::Sleep(FULLWAIT); | ||
| 309 | Assert::Equal<DWORD>(2, pResults->cRegKeys); | ||
| 310 | |||
| 311 | hr = RegCreate(HKEY_CURRENT_USER, wzChildRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk); | ||
| 312 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 313 | ::Sleep(PREWAIT); | ||
| 314 | Assert::Equal<DWORD>(2, pResults->cRegKeys); | ||
| 315 | |||
| 316 | ::Sleep(FULLWAIT); | ||
| 317 | Assert::Equal<DWORD>(3, pResults->cRegKeys); | ||
| 318 | NativeAssert::ValidReturnCode(pResults->rgRegKeys[2].hr, S_OK); | ||
| 319 | |||
| 320 | // Write a registry value to some deep child subkey, and make sure it's detected | ||
| 321 | hr = RegWriteString(hk, L"valuename", L"testvalue"); | ||
| 322 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 323 | ReleaseRegKey(hk); | ||
| 324 | ::Sleep(PREWAIT); | ||
| 325 | Assert::Equal<DWORD>(3, pResults->cRegKeys); | ||
| 326 | |||
| 327 | ::Sleep(FULLWAIT); | ||
| 328 | Assert::Equal<DWORD>(4, pResults->cRegKeys); | ||
| 329 | NativeAssert::ValidReturnCode(pResults->rgRegKeys[2].hr, S_OK); | ||
| 330 | |||
| 331 | hr = RegDelete(HKEY_CURRENT_USER, wzDeepRegKey, REG_KEY_32BIT, TRUE); | ||
| 332 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 333 | |||
| 334 | ::Sleep(FULLWAIT); | ||
| 335 | Assert::Equal<DWORD>(5, pResults->cRegKeys); | ||
| 336 | |||
| 337 | // Now remove the regkey from the list of things to monitor, and confirm changes are no longer tracked | ||
| 338 | hr = MonRemoveRegKey(handle, HKEY_CURRENT_USER, wzDeepRegKey, REG_KEY_DEFAULT, TRUE); | ||
| 339 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 340 | |||
| 341 | hr = RegCreate(HKEY_CURRENT_USER, wzDeepRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk); | ||
| 342 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 343 | ReleaseRegKey(hk); | ||
| 344 | ::Sleep(FULLWAIT); | ||
| 345 | Assert::Equal<DWORD>(5, pResults->cRegKeys); | ||
| 346 | } | ||
| 347 | finally | ||
| 348 | { | ||
| 349 | ReleaseRegKey(hk); | ||
| 350 | } | ||
| 351 | } | ||
| 352 | |||
| 353 | void TestMoreThan64(MON_HANDLE handle, Results *pResults) | ||
| 354 | { | ||
| 355 | HRESULT hr = S_OK; | ||
| 356 | LPWSTR sczBaseDir = NULL; | ||
| 357 | LPWSTR sczDir = NULL; | ||
| 358 | LPWSTR sczFile = NULL; | ||
| 359 | |||
| 360 | try | ||
| 361 | { | ||
| 362 | hr = PathExpand(&sczBaseDir, L"%TEMP%\\ScalabilityTest\\", PATH_EXPAND_ENVIRONMENT); | ||
| 363 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 364 | |||
| 365 | for (DWORD i = 0; i < 200; ++i) | ||
| 366 | { | ||
| 367 | hr = StrAllocFormatted(&sczDir, L"%ls%u\\", sczBaseDir, i); | ||
| 368 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 369 | |||
| 370 | hr = DirEnsureExists(sczDir, NULL); | ||
| 371 | NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); | ||
| 372 | |||
| 373 | hr = MonAddDirectory(handle, sczDir, FALSE, SILENCEPERIOD, NULL); | ||
| 374 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 375 | } | ||
| 376 | |||
| 377 | hr = PathConcat(sczDir, L"file.txt", &sczFile); | ||
| 378 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 379 | |||
| 380 | hr = FileFromString(sczFile, 0, L"contents", FILE_ENCODING_UTF16_WITH_BOM); | ||
| 381 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 382 | |||
| 383 | ::Sleep(FULLWAIT); | ||
| 384 | Assert::Equal<DWORD>(1, pResults->cDirectories); | ||
| 385 | |||
| 386 | for (DWORD i = 0; i < 199; ++i) | ||
| 387 | { | ||
| 388 | hr = StrAllocFormatted(&sczDir, L"%ls%u\\", sczBaseDir, i); | ||
| 389 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 390 | |||
| 391 | hr = MonRemoveDirectory(handle, sczDir, FALSE); | ||
| 392 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 393 | } | ||
| 394 | ::Sleep(FULLWAIT); | ||
| 395 | |||
| 396 | hr = FileFromString(sczFile, 0, L"contents2", FILE_ENCODING_UTF16_WITH_BOM); | ||
| 397 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 398 | |||
| 399 | ::Sleep(FULLWAIT); | ||
| 400 | Assert::Equal<DWORD>(2, pResults->cDirectories); | ||
| 401 | |||
| 402 | for (DWORD i = 0; i < 199; ++i) | ||
| 403 | { | ||
| 404 | hr = StrAllocFormatted(&sczDir, L"%ls%u\\", sczBaseDir, i); | ||
| 405 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 406 | |||
| 407 | hr = MonAddDirectory(handle, sczDir, FALSE, SILENCEPERIOD, NULL); | ||
| 408 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 409 | } | ||
| 410 | ::Sleep(FULLWAIT); | ||
| 411 | |||
| 412 | hr = FileFromString(sczFile, 0, L"contents3", FILE_ENCODING_UTF16_WITH_BOM); | ||
| 413 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 414 | |||
| 415 | ::Sleep(FULLWAIT); | ||
| 416 | Assert::Equal<DWORD>(3, pResults->cDirectories); | ||
| 417 | } | ||
| 418 | finally | ||
| 419 | { | ||
| 420 | ReleaseStr(sczBaseDir); | ||
| 421 | ReleaseStr(sczDir); | ||
| 422 | ReleaseStr(sczFile); | ||
| 423 | } | ||
| 424 | } | ||
| 425 | |||
| 426 | [Fact(Skip = "Test demonstrates failure")] | ||
| 427 | void MonUtilTest() | ||
| 428 | { | ||
| 429 | HRESULT hr = S_OK; | ||
| 430 | MON_HANDLE handle = NULL; | ||
| 431 | List<GCHandle>^ gcHandles = gcnew List<GCHandle>(); | ||
| 432 | Results *pResults = (Results *)MemAlloc(sizeof(Results), TRUE); | ||
| 433 | Assert::True(NULL != pResults); | ||
| 434 | |||
| 435 | try | ||
| 436 | { | ||
| 437 | // These ensure the function pointers we send point to this thread's appdomain, which helps with assembly binding when running tests within msbuild | ||
| 438 | MonGeneralDelegate^ fpMonGeneral = gcnew MonGeneralDelegate(MonGeneral); | ||
| 439 | GCHandle gchMonGeneral = GCHandle::Alloc(fpMonGeneral); | ||
| 440 | gcHandles->Add(gchMonGeneral); | ||
| 441 | IntPtr ipMonGeneral = Marshal::GetFunctionPointerForDelegate(fpMonGeneral); | ||
| 442 | |||
| 443 | MonDriveStatusDelegate^ fpMonDriveStatus = gcnew MonDriveStatusDelegate(MonDriveStatus); | ||
| 444 | GCHandle gchMonDriveStatus = GCHandle::Alloc(fpMonDriveStatus); | ||
| 445 | gcHandles->Add(gchMonDriveStatus); | ||
| 446 | IntPtr ipMonDriveStatus = Marshal::GetFunctionPointerForDelegate(fpMonDriveStatus); | ||
| 447 | |||
| 448 | MonDirectoryDelegate^ fpMonDirectory = gcnew MonDirectoryDelegate(MonDirectory); | ||
| 449 | GCHandle gchMonDirectory = GCHandle::Alloc(fpMonDirectory); | ||
| 450 | gcHandles->Add(gchMonDirectory); | ||
| 451 | IntPtr ipMonDirectory = Marshal::GetFunctionPointerForDelegate(fpMonDirectory); | ||
| 452 | |||
| 453 | MonRegKeyDelegate^ fpMonRegKey = gcnew MonRegKeyDelegate(MonRegKey); | ||
| 454 | GCHandle gchMonRegKey = GCHandle::Alloc(fpMonRegKey); | ||
| 455 | gcHandles->Add(gchMonRegKey); | ||
| 456 | IntPtr ipMonRegKey = Marshal::GetFunctionPointerForDelegate(fpMonRegKey); | ||
| 457 | |||
| 458 | // "Silence period" is 100 ms | ||
| 459 | hr = MonCreate(&handle, static_cast<PFN_MONGENERAL>(ipMonGeneral.ToPointer()), static_cast<PFN_MONDRIVESTATUS>(ipMonDriveStatus.ToPointer()), static_cast<PFN_MONDIRECTORY>(ipMonDirectory.ToPointer()), static_cast<PFN_MONREGKEY>(ipMonRegKey.ToPointer()), pResults); | ||
| 460 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 461 | |||
| 462 | hr = RegInitialize(); | ||
| 463 | NativeAssert::ValidReturnCode(hr, S_OK); | ||
| 464 | |||
| 465 | TestDirectory(handle, pResults); | ||
| 466 | ClearResults(pResults); | ||
| 467 | TestRegKey(handle, pResults); | ||
| 468 | ClearResults(pResults); | ||
| 469 | TestMoreThan64(handle, pResults); | ||
| 470 | ClearResults(pResults); | ||
| 471 | } | ||
| 472 | finally | ||
| 473 | { | ||
| 474 | ReleaseMon(handle); | ||
| 475 | |||
| 476 | for each (GCHandle gcHandle in gcHandles) | ||
| 477 | { | ||
| 478 | gcHandle.Free(); | ||
| 479 | } | ||
| 480 | |||
| 481 | ReleaseMem(pResults->rgDirectories); | ||
| 482 | ReleaseMem(pResults->rgRegKeys); | ||
| 483 | ReleaseMem(pResults); | ||
| 484 | } | ||
| 485 | } | ||
| 486 | }; | ||
| 487 | } | ||
diff --git a/src/test/DUtilUnitTest/PathUtilTest.cpp b/src/test/DUtilUnitTest/PathUtilTest.cpp deleted file mode 100644 index 5a1f06fd..00000000 --- a/src/test/DUtilUnitTest/PathUtilTest.cpp +++ /dev/null | |||
| @@ -1,80 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | namespace DutilTests | ||
| 10 | { | ||
| 11 | public ref class PathUtil | ||
| 12 | { | ||
| 13 | public: | ||
| 14 | [Fact] | ||
| 15 | void PathGetHierarchyArrayTest() | ||
| 16 | { | ||
| 17 | HRESULT hr = S_OK; | ||
| 18 | LPWSTR *rgsczPaths = NULL; | ||
| 19 | UINT cPaths = 0; | ||
| 20 | |||
| 21 | try | ||
| 22 | { | ||
| 23 | hr = PathGetHierarchyArray(L"c:\\foo\\bar\\bas\\a.txt", &rgsczPaths, &cPaths); | ||
| 24 | NativeAssert::Succeeded(hr, "Failed to get parent directories array for regular file path"); | ||
| 25 | Assert::Equal<DWORD>(5, cPaths); | ||
| 26 | NativeAssert::StringEqual(L"c:\\", rgsczPaths[0]); | ||
| 27 | NativeAssert::StringEqual(L"c:\\foo\\", rgsczPaths[1]); | ||
| 28 | NativeAssert::StringEqual(L"c:\\foo\\bar\\", rgsczPaths[2]); | ||
| 29 | NativeAssert::StringEqual(L"c:\\foo\\bar\\bas\\", rgsczPaths[3]); | ||
| 30 | NativeAssert::StringEqual(L"c:\\foo\\bar\\bas\\a.txt", rgsczPaths[4]); | ||
| 31 | ReleaseNullStrArray(rgsczPaths, cPaths); | ||
| 32 | |||
| 33 | hr = PathGetHierarchyArray(L"c:\\foo\\bar\\bas\\", &rgsczPaths, &cPaths); | ||
| 34 | NativeAssert::Succeeded(hr, "Failed to get parent directories array for regular directory path"); | ||
| 35 | Assert::Equal<DWORD>(4, cPaths); | ||
| 36 | NativeAssert::StringEqual(L"c:\\", rgsczPaths[0]); | ||
| 37 | NativeAssert::StringEqual(L"c:\\foo\\", rgsczPaths[1]); | ||
| 38 | NativeAssert::StringEqual(L"c:\\foo\\bar\\", rgsczPaths[2]); | ||
| 39 | NativeAssert::StringEqual(L"c:\\foo\\bar\\bas\\", rgsczPaths[3]); | ||
| 40 | ReleaseNullStrArray(rgsczPaths, cPaths); | ||
| 41 | |||
| 42 | hr = PathGetHierarchyArray(L"\\\\server\\share\\subdir\\file.txt", &rgsczPaths, &cPaths); | ||
| 43 | NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC file path"); | ||
| 44 | Assert::Equal<DWORD>(3, cPaths); | ||
| 45 | NativeAssert::StringEqual(L"\\\\server\\share\\", rgsczPaths[0]); | ||
| 46 | NativeAssert::StringEqual(L"\\\\server\\share\\subdir\\", rgsczPaths[1]); | ||
| 47 | NativeAssert::StringEqual(L"\\\\server\\share\\subdir\\file.txt", rgsczPaths[2]); | ||
| 48 | ReleaseNullStrArray(rgsczPaths, cPaths); | ||
| 49 | |||
| 50 | hr = PathGetHierarchyArray(L"\\\\server\\share\\subdir\\", &rgsczPaths, &cPaths); | ||
| 51 | NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path"); | ||
| 52 | Assert::Equal<DWORD>(2, cPaths); | ||
| 53 | NativeAssert::StringEqual(L"\\\\server\\share\\", rgsczPaths[0]); | ||
| 54 | NativeAssert::StringEqual(L"\\\\server\\share\\subdir\\", rgsczPaths[1]); | ||
| 55 | ReleaseNullStrArray(rgsczPaths, cPaths); | ||
| 56 | |||
| 57 | hr = PathGetHierarchyArray(L"Software\\Microsoft\\Windows\\ValueName", &rgsczPaths, &cPaths); | ||
| 58 | NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path"); | ||
| 59 | Assert::Equal<DWORD>(4, cPaths); | ||
| 60 | NativeAssert::StringEqual(L"Software\\", rgsczPaths[0]); | ||
| 61 | NativeAssert::StringEqual(L"Software\\Microsoft\\", rgsczPaths[1]); | ||
| 62 | NativeAssert::StringEqual(L"Software\\Microsoft\\Windows\\", rgsczPaths[2]); | ||
| 63 | NativeAssert::StringEqual(L"Software\\Microsoft\\Windows\\ValueName", rgsczPaths[3]); | ||
| 64 | ReleaseNullStrArray(rgsczPaths, cPaths); | ||
| 65 | |||
| 66 | hr = PathGetHierarchyArray(L"Software\\Microsoft\\Windows\\", &rgsczPaths, &cPaths); | ||
| 67 | NativeAssert::Succeeded(hr, "Failed to get parent directories array for UNC directory path"); | ||
| 68 | Assert::Equal<DWORD>(3, cPaths); | ||
| 69 | NativeAssert::StringEqual(L"Software\\", rgsczPaths[0]); | ||
| 70 | NativeAssert::StringEqual(L"Software\\Microsoft\\", rgsczPaths[1]); | ||
| 71 | NativeAssert::StringEqual(L"Software\\Microsoft\\Windows\\", rgsczPaths[2]); | ||
| 72 | ReleaseNullStrArray(rgsczPaths, cPaths); | ||
| 73 | } | ||
| 74 | finally | ||
| 75 | { | ||
| 76 | ReleaseStrArray(rgsczPaths, cPaths); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | }; | ||
| 80 | } | ||
diff --git a/src/test/DUtilUnitTest/SceUtilTest.cpp b/src/test/DUtilUnitTest/SceUtilTest.cpp deleted file mode 100644 index 75b9222a..00000000 --- a/src/test/DUtilUnitTest/SceUtilTest.cpp +++ /dev/null | |||
| @@ -1,488 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | #include <sqlce_oledb.h> | ||
| 6 | #include <sceutil.h> | ||
| 7 | |||
| 8 | using namespace System; | ||
| 9 | using namespace Xunit; | ||
| 10 | using namespace WixTest; | ||
| 11 | |||
| 12 | #define ASSIGN_INDEX_STRUCT(a, b, c) {a.wzName = c; a.rgColumns = b; a.cColumns = countof(b);}; | ||
| 13 | |||
| 14 | namespace DutilTests | ||
| 15 | { | ||
| 16 | enum TABLES | ||
| 17 | { | ||
| 18 | TABLE_A, | ||
| 19 | TABLE_COUNT | ||
| 20 | }; | ||
| 21 | |||
| 22 | enum TABLE_A_COLUMNS | ||
| 23 | { | ||
| 24 | TABLE_A_KEY, | ||
| 25 | TABLE_A_BINARY, | ||
| 26 | TABLE_A_DWORD, | ||
| 27 | TABLE_A_QWORD, | ||
| 28 | TABLE_A_BOOL, | ||
| 29 | TABLE_A_STRING, | ||
| 30 | TABLE_A_DWORD_NULLABLE, | ||
| 31 | TABLE_A_INITIAL_COLUMNS, | ||
| 32 | |||
| 33 | TABLE_A_EXTRA_STRING = TABLE_A_INITIAL_COLUMNS, | ||
| 34 | TABLE_A_FINAL_COLUMNS | ||
| 35 | }; | ||
| 36 | |||
| 37 | struct TableARowValue | ||
| 38 | { | ||
| 39 | DWORD dwAutoGenKey; | ||
| 40 | |||
| 41 | BYTE *pbBinary; | ||
| 42 | DWORD cBinary; | ||
| 43 | |||
| 44 | DWORD dw; | ||
| 45 | DWORD64 qw; | ||
| 46 | BOOL f; | ||
| 47 | LPWSTR scz; | ||
| 48 | |||
| 49 | BOOL fNullablePresent; | ||
| 50 | DWORD dwNullable; | ||
| 51 | |||
| 52 | BOOL fSchemaV2; | ||
| 53 | LPWSTR sczExtra; | ||
| 54 | }; | ||
| 55 | |||
| 56 | public ref class SceUtil | ||
| 57 | { | ||
| 58 | public: | ||
| 59 | void ReleaseSceSchema(SCE_DATABASE_SCHEMA *pdsSchema) | ||
| 60 | { | ||
| 61 | DWORD dwTable; | ||
| 62 | |||
| 63 | for (dwTable = 0; dwTable < pdsSchema->cTables; ++dwTable) | ||
| 64 | { | ||
| 65 | ReleaseNullMem(pdsSchema->rgTables[dwTable].rgColumns); | ||
| 66 | ReleaseNullMem(pdsSchema->rgTables[dwTable].rgIndexes); | ||
| 67 | } | ||
| 68 | |||
| 69 | ReleaseMem(pdsSchema->rgTables); | ||
| 70 | |||
| 71 | return; | ||
| 72 | } | ||
| 73 | |||
| 74 | void SetupSchema(SCE_DATABASE_SCHEMA *pSchema, BOOL fIncludeExtended) | ||
| 75 | { | ||
| 76 | pSchema->cTables = TABLE_COUNT; | ||
| 77 | pSchema->rgTables = static_cast<SCE_TABLE_SCHEMA*>(MemAlloc(TABLE_COUNT * sizeof(SCE_TABLE_SCHEMA), TRUE)); | ||
| 78 | NativeAssert::True(pSchema->rgTables != NULL); | ||
| 79 | |||
| 80 | pSchema->rgTables[TABLE_A].wzName = L"TableA"; | ||
| 81 | pSchema->rgTables[TABLE_A].cColumns = fIncludeExtended ? TABLE_A_FINAL_COLUMNS : TABLE_A_INITIAL_COLUMNS; | ||
| 82 | pSchema->rgTables[TABLE_A].cIndexes = 2; | ||
| 83 | |||
| 84 | for (DWORD i = 0; i < pSchema->cTables; ++i) | ||
| 85 | { | ||
| 86 | pSchema->rgTables[i].rgColumns = static_cast<SCE_COLUMN_SCHEMA*>(MemAlloc(sizeof(SCE_COLUMN_SCHEMA) * pSchema->rgTables[i].cColumns, TRUE)); | ||
| 87 | NativeAssert::True(pSchema->rgTables[i].rgColumns != NULL); | ||
| 88 | |||
| 89 | pSchema->rgTables[i].rgIndexes = static_cast<SCE_INDEX_SCHEMA*>(MemAlloc(sizeof(SCE_COLUMN_SCHEMA) * pSchema->rgTables[i].cIndexes, TRUE)); | ||
| 90 | NativeAssert::True(pSchema->rgTables[i].rgIndexes != NULL); | ||
| 91 | } | ||
| 92 | |||
| 93 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_KEY].wzName = L"Key"; | ||
| 94 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_KEY].dbtColumnType = DBTYPE_I4; | ||
| 95 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_KEY].fPrimaryKey = TRUE; | ||
| 96 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_KEY].fAutoIncrement = TRUE; | ||
| 97 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_BINARY].wzName = L"Binary"; | ||
| 98 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_BINARY].dbtColumnType = DBTYPE_BYTES; | ||
| 99 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_DWORD].wzName = L"Dword"; | ||
| 100 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_DWORD].dbtColumnType = DBTYPE_I4; | ||
| 101 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_QWORD].wzName = L"Qword"; | ||
| 102 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_QWORD].dbtColumnType = DBTYPE_I8; | ||
| 103 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_BOOL].wzName = L"Bool"; | ||
| 104 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_BOOL].dbtColumnType = DBTYPE_BOOL; | ||
| 105 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_STRING].wzName = L"String"; | ||
| 106 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_STRING].dbtColumnType = DBTYPE_WSTR; | ||
| 107 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_DWORD_NULLABLE].wzName = L"Nullable"; | ||
| 108 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_DWORD_NULLABLE].dbtColumnType = DBTYPE_I4; | ||
| 109 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_DWORD_NULLABLE].fNullable = TRUE; | ||
| 110 | |||
| 111 | if (fIncludeExtended) | ||
| 112 | { | ||
| 113 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_EXTRA_STRING].wzName = L"ExtraString"; | ||
| 114 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_EXTRA_STRING].dbtColumnType = DBTYPE_WSTR; | ||
| 115 | pSchema->rgTables[TABLE_A].rgColumns[TABLE_A_EXTRA_STRING].fNullable = TRUE; | ||
| 116 | } | ||
| 117 | |||
| 118 | static DWORD rgdwTableA_Index1[] = { TABLE_A_DWORD, TABLE_A_STRING, TABLE_A_QWORD }; | ||
| 119 | static DWORD rgdwTableA_Index2[] = { TABLE_A_DWORD, TABLE_A_STRING }; | ||
| 120 | |||
| 121 | ASSIGN_INDEX_STRUCT(pSchema->rgTables[TABLE_A].rgIndexes[0], rgdwTableA_Index1, L"Dword_String_Qword"); | ||
| 122 | ASSIGN_INDEX_STRUCT(pSchema->rgTables[TABLE_A].rgIndexes[1], rgdwTableA_Index2, L"Dword_String"); | ||
| 123 | } | ||
| 124 | |||
| 125 | void SetStructValues(TableARowValue *pValue, BYTE *pbBinary, DWORD cBinary, DWORD dw, DWORD64 qw, BOOL f, LPWSTR scz, DWORD *pdw, LPWSTR sczExtra) | ||
| 126 | { | ||
| 127 | pValue->pbBinary = pbBinary; | ||
| 128 | pValue->cBinary = cBinary; | ||
| 129 | pValue->dw = dw; | ||
| 130 | pValue->qw = qw; | ||
| 131 | pValue->f = f; | ||
| 132 | pValue->scz = scz; | ||
| 133 | |||
| 134 | if (pdw) | ||
| 135 | { | ||
| 136 | pValue->fNullablePresent = TRUE; | ||
| 137 | pValue->dwNullable = *pdw; | ||
| 138 | } | ||
| 139 | else | ||
| 140 | { | ||
| 141 | pValue->fNullablePresent = FALSE; | ||
| 142 | } | ||
| 143 | |||
| 144 | if (sczExtra) | ||
| 145 | { | ||
| 146 | pValue->fSchemaV2 = TRUE; | ||
| 147 | pValue->sczExtra = sczExtra; | ||
| 148 | } | ||
| 149 | else | ||
| 150 | { | ||
| 151 | pValue->fSchemaV2 = FALSE; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | void AssertStructValuesSame(TableARowValue *pValueExpected, TableARowValue *pValueOther) | ||
| 156 | { | ||
| 157 | NativeAssert::Equal(pValueExpected->cBinary, pValueOther->cBinary); | ||
| 158 | NativeAssert::True(0 == memcmp(pValueExpected->pbBinary, pValueOther->pbBinary, pValueOther->cBinary)); | ||
| 159 | |||
| 160 | NativeAssert::Equal(pValueExpected->dw, pValueOther->dw); | ||
| 161 | NativeAssert::Equal(pValueExpected->qw, pValueOther->qw); | ||
| 162 | NativeAssert::Equal(pValueExpected->f, pValueOther->f); | ||
| 163 | NativeAssert::True(0 == wcscmp(pValueExpected->scz, pValueOther->scz)); | ||
| 164 | |||
| 165 | NativeAssert::Equal(pValueExpected->fNullablePresent, pValueOther->fNullablePresent); | ||
| 166 | if (pValueExpected->fNullablePresent) | ||
| 167 | { | ||
| 168 | NativeAssert::Equal(pValueExpected->dwNullable, pValueOther->dwNullable); | ||
| 169 | } | ||
| 170 | |||
| 171 | NativeAssert::Equal(pValueExpected->fSchemaV2, pValueOther->fSchemaV2); | ||
| 172 | if (pValueExpected->fSchemaV2) | ||
| 173 | { | ||
| 174 | NativeAssert::True(0 == wcscmp(pValueExpected->sczExtra, pValueOther->sczExtra)); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | void InsertRow(SCE_DATABASE *pDatabase, TableARowValue *pValue, BOOL fRollback) | ||
| 179 | { | ||
| 180 | HRESULT hr = S_OK; | ||
| 181 | SCE_ROW_HANDLE sceRow = NULL; | ||
| 182 | |||
| 183 | hr = SceBeginTransaction(pDatabase); | ||
| 184 | NativeAssert::Succeeded(hr, "Failed to begin transaction"); | ||
| 185 | |||
| 186 | hr = ScePrepareInsert(pDatabase, TABLE_A, &sceRow); | ||
| 187 | NativeAssert::Succeeded(hr, "Failed to prepare to insert row"); | ||
| 188 | |||
| 189 | hr = SceSetColumnBinary(sceRow, TABLE_A_BINARY, pValue->pbBinary, pValue->cBinary); | ||
| 190 | NativeAssert::Succeeded(hr, "Failed to set binary value"); | ||
| 191 | |||
| 192 | hr = SceSetColumnDword(sceRow, TABLE_A_DWORD, pValue->dw); | ||
| 193 | NativeAssert::Succeeded(hr, "Failed to set dword value"); | ||
| 194 | |||
| 195 | hr = SceSetColumnQword(sceRow, TABLE_A_QWORD, pValue->qw); | ||
| 196 | NativeAssert::Succeeded(hr, "Failed to set qword value"); | ||
| 197 | |||
| 198 | hr = SceSetColumnBool(sceRow, TABLE_A_BOOL, pValue->f); | ||
| 199 | NativeAssert::Succeeded(hr, "Failed to set bool value"); | ||
| 200 | |||
| 201 | hr = SceSetColumnString(sceRow, TABLE_A_STRING, pValue->scz); | ||
| 202 | NativeAssert::Succeeded(hr, "Failed to set string value"); | ||
| 203 | |||
| 204 | if (pValue->fNullablePresent) | ||
| 205 | { | ||
| 206 | hr = SceSetColumnDword(sceRow, TABLE_A_DWORD_NULLABLE, pValue->dwNullable); | ||
| 207 | NativeAssert::Succeeded(hr, "Failed to set dword value"); | ||
| 208 | } | ||
| 209 | else | ||
| 210 | { | ||
| 211 | hr = SceSetColumnNull(sceRow, TABLE_A_DWORD_NULLABLE); | ||
| 212 | NativeAssert::Succeeded(hr, "Failed to set null value"); | ||
| 213 | } | ||
| 214 | |||
| 215 | if (pValue->fSchemaV2) | ||
| 216 | { | ||
| 217 | hr = SceSetColumnString(sceRow, TABLE_A_EXTRA_STRING, pValue->sczExtra); | ||
| 218 | NativeAssert::Succeeded(hr, "Failed to set extra string value"); | ||
| 219 | } | ||
| 220 | |||
| 221 | hr = SceFinishUpdate(sceRow); | ||
| 222 | NativeAssert::Succeeded(hr, "Failed to finish insert"); | ||
| 223 | |||
| 224 | if (fRollback) | ||
| 225 | { | ||
| 226 | hr = SceRollbackTransaction(pDatabase); | ||
| 227 | NativeAssert::Succeeded(hr, "Failed to rollback transaction"); | ||
| 228 | } | ||
| 229 | else | ||
| 230 | { | ||
| 231 | hr = SceCommitTransaction(pDatabase); | ||
| 232 | NativeAssert::Succeeded(hr, "Failed to commit transaction"); | ||
| 233 | |||
| 234 | hr = SceGetColumnDword(sceRow, TABLE_A_KEY, &pValue->dwAutoGenKey); | ||
| 235 | NativeAssert::Succeeded(hr, "Failed to get autogen key after insert"); | ||
| 236 | |||
| 237 | NativeAssert::True(pValue->dwAutoGenKey != 0); | ||
| 238 | } | ||
| 239 | |||
| 240 | ReleaseSceRow(sceRow); | ||
| 241 | } | ||
| 242 | |||
| 243 | void VerifyRow(TableARowValue *pExpectedValue, SCE_ROW_HANDLE sceRow) | ||
| 244 | { | ||
| 245 | HRESULT hr = S_OK; | ||
| 246 | TableARowValue value = {}; | ||
| 247 | |||
| 248 | hr = SceGetColumnBinary(sceRow, TABLE_A_BINARY, &value.pbBinary, &value.cBinary); | ||
| 249 | NativeAssert::Succeeded(hr, "Failed to get binary value from result row"); | ||
| 250 | |||
| 251 | hr = SceGetColumnDword(sceRow, TABLE_A_DWORD, &value.dw); | ||
| 252 | NativeAssert::Succeeded(hr, "Failed to get dword value from result row"); | ||
| 253 | |||
| 254 | hr = SceGetColumnQword(sceRow, TABLE_A_QWORD, &value.qw); | ||
| 255 | NativeAssert::Succeeded(hr, "Failed to get qword value from result row"); | ||
| 256 | |||
| 257 | hr = SceGetColumnBool(sceRow, TABLE_A_BOOL, &value.f); | ||
| 258 | NativeAssert::Succeeded(hr, "Failed to get bool value from result row"); | ||
| 259 | |||
| 260 | hr = SceGetColumnString(sceRow, TABLE_A_STRING, &value.scz); | ||
| 261 | NativeAssert::Succeeded(hr, "Failed to get string value from result row"); | ||
| 262 | |||
| 263 | hr = SceGetColumnDword(sceRow, TABLE_A_DWORD_NULLABLE, &value.dwNullable); | ||
| 264 | if (hr == E_NOTFOUND) | ||
| 265 | { | ||
| 266 | value.fNullablePresent = FALSE; | ||
| 267 | hr = S_OK; | ||
| 268 | } | ||
| 269 | else | ||
| 270 | { | ||
| 271 | NativeAssert::Succeeded(hr, "Failed to get string value from result row"); | ||
| 272 | value.fNullablePresent = TRUE; | ||
| 273 | } | ||
| 274 | |||
| 275 | if (pExpectedValue->fSchemaV2) | ||
| 276 | { | ||
| 277 | value.fSchemaV2 = TRUE; | ||
| 278 | hr = SceGetColumnString(sceRow, TABLE_A_EXTRA_STRING, &value.sczExtra); | ||
| 279 | NativeAssert::Succeeded(hr, "Failed to get extra string value from result row"); | ||
| 280 | } | ||
| 281 | |||
| 282 | AssertStructValuesSame(pExpectedValue, &value); | ||
| 283 | |||
| 284 | ReleaseNullMem(value.pbBinary); | ||
| 285 | ReleaseNullStr(value.scz); | ||
| 286 | } | ||
| 287 | |||
| 288 | void VerifyQuery(TableARowValue **rgExpectedValues, DWORD cExpectedValues, SCE_QUERY_RESULTS_HANDLE queryResults) | ||
| 289 | { | ||
| 290 | HRESULT hr = S_OK; | ||
| 291 | SCE_ROW_HANDLE sceRow = NULL; | ||
| 292 | |||
| 293 | for (DWORD i = 0; i < cExpectedValues; ++i) | ||
| 294 | { | ||
| 295 | hr = SceGetNextResultRow(queryResults, &sceRow); | ||
| 296 | NativeAssert::Succeeded(hr, "Failed to get next result row"); | ||
| 297 | |||
| 298 | VerifyRow(rgExpectedValues[i], sceRow); | ||
| 299 | ReleaseNullSceRow(sceRow); | ||
| 300 | } | ||
| 301 | |||
| 302 | // No more results | ||
| 303 | NativeAssert::True(NULL == queryResults || FAILED(SceGetNextResultRow(queryResults, &sceRow))); | ||
| 304 | } | ||
| 305 | |||
| 306 | void TestIndex(SCE_DATABASE *pDatabase) | ||
| 307 | { | ||
| 308 | HRESULT hr = S_OK; | ||
| 309 | BYTE binary1[50] = { 0x80, 0x70 }; | ||
| 310 | BYTE binary2[40] = { 0x90, 0xAB }; | ||
| 311 | BYTE binary3[40] = { 0x85, 0x88 }; | ||
| 312 | DWORD dwValue1 = 0x55555555, dwValue2 = 0x88888888; | ||
| 313 | TableARowValue value1 = {}, value2 = {}, value3 = {}, value4 = {}, value5 = {}; | ||
| 314 | SCE_QUERY_HANDLE query = NULL; | ||
| 315 | SCE_QUERY_RESULTS_HANDLE results = NULL; | ||
| 316 | |||
| 317 | SetStructValues(&value1, static_cast<BYTE *>(binary1), sizeof(binary1), 3, 1, TRUE, L"zzz", &dwValue1, NULL); | ||
| 318 | SetStructValues(&value2, static_cast<BYTE *>(binary2), sizeof(binary2), 3, 2, TRUE, L"yyy", &dwValue2, NULL); | ||
| 319 | SetStructValues(&value3, static_cast<BYTE *>(binary3), sizeof(binary3), 3, 3, TRUE, L"xxx", NULL, NULL); | ||
| 320 | SetStructValues(&value4, static_cast<BYTE *>(binary2), sizeof(binary2), 4, 4, TRUE, L"xyz", &dwValue2, NULL); | ||
| 321 | SetStructValues(&value5, static_cast<BYTE *>(binary3), sizeof(binary3), 3, 1, TRUE, L"yyy", &dwValue2, NULL); | ||
| 322 | |||
| 323 | // Rollback an insert to confirm the insert doesn't happen and database can still be interacted with normally afterwards | ||
| 324 | InsertRow(pDatabase, &value1, TRUE); | ||
| 325 | |||
| 326 | InsertRow(pDatabase, &value1, FALSE); | ||
| 327 | InsertRow(pDatabase, &value2, FALSE); | ||
| 328 | InsertRow(pDatabase, &value3, FALSE); | ||
| 329 | InsertRow(pDatabase, &value4, FALSE); | ||
| 330 | InsertRow(pDatabase, &value5, FALSE); | ||
| 331 | |||
| 332 | NativeAssert::True(value1.dwAutoGenKey != value2.dwAutoGenKey); | ||
| 333 | |||
| 334 | // Test setting 1 column | ||
| 335 | hr = SceBeginQuery(pDatabase, TABLE_A, 0, &query); | ||
| 336 | NativeAssert::Succeeded(hr, "Failed to begin query"); | ||
| 337 | |||
| 338 | hr = SceSetQueryColumnDword(query, 3); | ||
| 339 | NativeAssert::Succeeded(hr, "Failed to set query column dword"); | ||
| 340 | |||
| 341 | hr = SceRunQueryRange(&query, &results); | ||
| 342 | NativeAssert::Succeeded(hr, "Failed to run query"); | ||
| 343 | NativeAssert::True(query == NULL); | ||
| 344 | |||
| 345 | TableARowValue *sortedAfterQuery1[] = { &value3, &value5, &value2, &value1 }; | ||
| 346 | VerifyQuery(sortedAfterQuery1, _countof(sortedAfterQuery1), results); | ||
| 347 | ReleaseNullSceQueryResults(results); | ||
| 348 | |||
| 349 | // Test setting 2 columns, third column is unspecified so results are sorted by it | ||
| 350 | hr = SceBeginQuery(pDatabase, TABLE_A, 0, &query); | ||
| 351 | NativeAssert::Succeeded(hr, "Failed to begin query"); | ||
| 352 | |||
| 353 | hr = SceSetQueryColumnDword(query, 3); | ||
| 354 | NativeAssert::Succeeded(hr, "Failed to set query column dword"); | ||
| 355 | |||
| 356 | hr = SceSetQueryColumnString(query, L"yyy"); | ||
| 357 | NativeAssert::Succeeded(hr, "Failed to set query column dword"); | ||
| 358 | |||
| 359 | hr = SceRunQueryRange(&query, &results); | ||
| 360 | NativeAssert::Succeeded(hr, "Failed to run query"); | ||
| 361 | NativeAssert::True(query == NULL); | ||
| 362 | |||
| 363 | TableARowValue *sortedAfterQuery2[] = { &value5, &value2 }; | ||
| 364 | VerifyQuery(sortedAfterQuery2, _countof(sortedAfterQuery2), results); | ||
| 365 | ReleaseNullSceQueryResults(results); | ||
| 366 | |||
| 367 | // Test setting 2 columns, third column of index is unspecified so results are sorted by it | ||
| 368 | hr = SceBeginQuery(pDatabase, TABLE_A, 0, &query); | ||
| 369 | NativeAssert::Succeeded(hr, "Failed to begin query"); | ||
| 370 | |||
| 371 | hr = SceSetQueryColumnDword(query, 3); | ||
| 372 | NativeAssert::Succeeded(hr, "Failed to set query column dword"); | ||
| 373 | |||
| 374 | hr = SceSetQueryColumnString(query, L"yyy"); | ||
| 375 | NativeAssert::Succeeded(hr, "Failed to set query column dword"); | ||
| 376 | |||
| 377 | hr = SceRunQueryRange(&query, &results); | ||
| 378 | NativeAssert::Succeeded(hr, "Failed to run query"); | ||
| 379 | NativeAssert::True(query == NULL); | ||
| 380 | |||
| 381 | TableARowValue *sortedAfterQuery3[] = { &value5, &value2 }; | ||
| 382 | VerifyQuery(sortedAfterQuery3, _countof(sortedAfterQuery3), results); | ||
| 383 | ReleaseNullSceQueryResults(results); | ||
| 384 | |||
| 385 | // Test setting 2 columns in a different (2 column) index, so there is no 3rd column in index to sort by | ||
| 386 | hr = SceBeginQuery(pDatabase, TABLE_A, 1, &query); | ||
| 387 | NativeAssert::Succeeded(hr, "Failed to begin query"); | ||
| 388 | |||
| 389 | hr = SceSetQueryColumnDword(query, 3); | ||
| 390 | NativeAssert::Succeeded(hr, "Failed to set query column dword"); | ||
| 391 | |||
| 392 | hr = SceSetQueryColumnString(query, L"yyy"); | ||
| 393 | NativeAssert::Succeeded(hr, "Failed to set query column dword"); | ||
| 394 | |||
| 395 | hr = SceRunQueryRange(&query, &results); | ||
| 396 | NativeAssert::Succeeded(hr, "Failed to run query"); | ||
| 397 | NativeAssert::True(query == NULL); | ||
| 398 | |||
| 399 | TableARowValue *sortedAfterQuery4[] = { &value2, &value5 }; | ||
| 400 | VerifyQuery(sortedAfterQuery4, _countof(sortedAfterQuery4), results); | ||
| 401 | ReleaseNullSceQueryResults(results); | ||
| 402 | } | ||
| 403 | |||
| 404 | void TestReadWriteSchemaV2(SCE_DATABASE *pDatabase) | ||
| 405 | { | ||
| 406 | HRESULT hr = S_OK; | ||
| 407 | BYTE binary1[40] = { 0x55, 0x44 }; | ||
| 408 | DWORD dwValue1 = 58; | ||
| 409 | TableARowValue value1 = {}; | ||
| 410 | SCE_QUERY_HANDLE query = NULL; | ||
| 411 | SCE_ROW_HANDLE row = NULL; | ||
| 412 | |||
| 413 | SetStructValues(&value1, static_cast<BYTE *>(binary1), sizeof(binary1), 5, 1, TRUE, L"zzz", &dwValue1, L"newextrastring"); | ||
| 414 | |||
| 415 | InsertRow(pDatabase, &value1, FALSE); | ||
| 416 | |||
| 417 | // Test setting 1 column | ||
| 418 | hr = SceBeginQuery(pDatabase, TABLE_A, 0, &query); | ||
| 419 | NativeAssert::Succeeded(hr, "Failed to begin query"); | ||
| 420 | |||
| 421 | hr = SceSetQueryColumnDword(query, 5); | ||
| 422 | NativeAssert::Succeeded(hr, "Failed to set query column dword"); | ||
| 423 | |||
| 424 | hr = SceRunQueryExact(&query, &row); | ||
| 425 | NativeAssert::Succeeded(hr, "Failed to run query exact"); | ||
| 426 | |||
| 427 | VerifyRow(&value1, row); | ||
| 428 | } | ||
| 429 | |||
| 430 | [Fact] | ||
| 431 | void SceUtilTest() | ||
| 432 | { | ||
| 433 | HRESULT hr = S_OK; | ||
| 434 | BOOL fComInitialized = FALSE; | ||
| 435 | LPWSTR sczDbPath = NULL; | ||
| 436 | SCE_DATABASE *pDatabase = NULL; | ||
| 437 | SCE_DATABASE_SCHEMA schema1 = {}; | ||
| 438 | SCE_DATABASE_SCHEMA schema2 = {}; | ||
| 439 | |||
| 440 | try | ||
| 441 | { | ||
| 442 | hr = ::CoInitialize(0); | ||
| 443 | NativeAssert::Succeeded(hr, "Failed to initialize COM"); | ||
| 444 | fComInitialized = TRUE; | ||
| 445 | |||
| 446 | SetupSchema(&schema1, FALSE); | ||
| 447 | SetupSchema(&schema2, TRUE); | ||
| 448 | |||
| 449 | hr = PathExpand(&sczDbPath, L"%TEMP%\\SceUtilTest\\UnitTest.sdf", PATH_EXPAND_ENVIRONMENT); | ||
| 450 | NativeAssert::Succeeded(hr, "Failed to get path to test database"); | ||
| 451 | |||
| 452 | FileEnsureDelete(sczDbPath); | ||
| 453 | |||
| 454 | hr = SceEnsureDatabase(sczDbPath, L"sqlceoledb40.dll", L"Test", 1, &schema1, &pDatabase); | ||
| 455 | NativeAssert::Succeeded(hr, "Failed to ensure database schema"); | ||
| 456 | |||
| 457 | TestIndex(pDatabase); | ||
| 458 | |||
| 459 | hr = SceCloseDatabase(pDatabase); | ||
| 460 | pDatabase = NULL; | ||
| 461 | NativeAssert::Succeeded(hr, "Failed to close database"); | ||
| 462 | |||
| 463 | // Add column to schema | ||
| 464 | hr = SceEnsureDatabase(sczDbPath, L"sqlceoledb40.dll", L"Test", 1, &schema2, &pDatabase); | ||
| 465 | NativeAssert::Succeeded(hr, "Failed to ensure database schema"); | ||
| 466 | |||
| 467 | TestReadWriteSchemaV2(pDatabase); | ||
| 468 | } | ||
| 469 | finally | ||
| 470 | { | ||
| 471 | ReleaseSceSchema(&schema1); | ||
| 472 | ReleaseSceSchema(&schema2); | ||
| 473 | |||
| 474 | if (NULL != pDatabase) | ||
| 475 | { | ||
| 476 | hr = SceCloseDatabase(pDatabase); | ||
| 477 | NativeAssert::Succeeded(hr, "Failed to close database"); | ||
| 478 | } | ||
| 479 | ReleaseStr(sczDbPath); | ||
| 480 | |||
| 481 | if (fComInitialized) | ||
| 482 | { | ||
| 483 | ::CoUninitialize(); | ||
| 484 | } | ||
| 485 | } | ||
| 486 | } | ||
| 487 | }; | ||
| 488 | } | ||
diff --git a/src/test/DUtilUnitTest/StrUtilTest.cpp b/src/test/DUtilUnitTest/StrUtilTest.cpp deleted file mode 100644 index 94fee280..00000000 --- a/src/test/DUtilUnitTest/StrUtilTest.cpp +++ /dev/null | |||
| @@ -1,192 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | namespace DutilTests | ||
| 10 | { | ||
| 11 | public ref class StrUtil | ||
| 12 | { | ||
| 13 | public: | ||
| 14 | [Fact] | ||
| 15 | void StrUtilFormattedTest() | ||
| 16 | { | ||
| 17 | HRESULT hr = S_OK; | ||
| 18 | LPWSTR sczText = NULL; | ||
| 19 | |||
| 20 | try | ||
| 21 | { | ||
| 22 | hr = StrAllocFormatted(&sczText, L"%hs - %ls - %u", "ansi string", L"unicode string", 1234); | ||
| 23 | NativeAssert::Succeeded(hr, "Failed to format string."); | ||
| 24 | NativeAssert::StringEqual(L"ansi string - unicode string - 1234", sczText); | ||
| 25 | |||
| 26 | ReleaseNullStr(sczText); | ||
| 27 | |||
| 28 | hr = StrAllocString(&sczText, L"repeat", 0); | ||
| 29 | NativeAssert::Succeeded(hr, "Failed to allocate string."); | ||
| 30 | |||
| 31 | hr = StrAllocFormatted(&sczText, L"%ls and %ls", sczText, sczText); | ||
| 32 | NativeAssert::Succeeded(hr, "Failed to format string unto itself."); | ||
| 33 | NativeAssert::StringEqual(L"repeat and repeat", sczText); | ||
| 34 | } | ||
| 35 | finally | ||
| 36 | { | ||
| 37 | ReleaseStr(sczText); | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | [Fact] | ||
| 42 | void StrUtilTrimTest() | ||
| 43 | { | ||
| 44 | TestTrim(L"", L""); | ||
| 45 | TestTrim(L"Blah", L"Blah"); | ||
| 46 | TestTrim(L"\t\t\tBlah", L"Blah"); | ||
| 47 | TestTrim(L"\t Blah ", L"Blah"); | ||
| 48 | TestTrim(L"Blah ", L"Blah"); | ||
| 49 | TestTrim(L"\t Spaces \t Between \t", L"Spaces \t Between"); | ||
| 50 | TestTrim(L" \t\t\t ", L""); | ||
| 51 | |||
| 52 | TestTrimAnsi("", ""); | ||
| 53 | TestTrimAnsi("Blah", "Blah"); | ||
| 54 | TestTrimAnsi("\t\t\tBlah", "Blah"); | ||
| 55 | TestTrimAnsi(" Blah ", "Blah"); | ||
| 56 | TestTrimAnsi("Blah ", "Blah"); | ||
| 57 | TestTrimAnsi("\t Spaces \t Between \t", "Spaces \t Between"); | ||
| 58 | TestTrimAnsi(" \t\t\t ", ""); | ||
| 59 | } | ||
| 60 | |||
| 61 | [Fact] | ||
| 62 | void StrUtilConvertTest() | ||
| 63 | { | ||
| 64 | char a[] = { 'a', 'b', 'C', 'd', '\0', '\0' }; | ||
| 65 | |||
| 66 | TestStrAllocStringAnsi(a, 5, L"abCd"); | ||
| 67 | TestStrAllocStringAnsi(a, 4, L"abCd"); | ||
| 68 | TestStrAllocStringAnsi(a, 3, L"abC"); | ||
| 69 | TestStrAllocStringAnsi(a, 2, L"ab"); | ||
| 70 | TestStrAllocStringAnsi(a, 1, L"a"); | ||
| 71 | TestStrAllocStringAnsi(a, 0, L"abCd"); | ||
| 72 | |||
| 73 | wchar_t b[] = { L'a', L'b', L'C', L'd', L'\0', L'\0' }; | ||
| 74 | |||
| 75 | TestStrAnsiAllocString(b, 5, "abCd"); | ||
| 76 | TestStrAnsiAllocString(b, 4, "abCd"); | ||
| 77 | TestStrAnsiAllocString(b, 3, "abC"); | ||
| 78 | TestStrAnsiAllocString(b, 2, "ab"); | ||
| 79 | TestStrAnsiAllocString(b, 1, "a"); | ||
| 80 | TestStrAnsiAllocString(b, 0, "abCd"); | ||
| 81 | } | ||
| 82 | |||
| 83 | private: | ||
| 84 | void TestTrim(LPCWSTR wzInput, LPCWSTR wzExpectedResult) | ||
| 85 | { | ||
| 86 | HRESULT hr = S_OK; | ||
| 87 | LPWSTR sczOutput = NULL; | ||
| 88 | |||
| 89 | DutilInitialize(&DutilTestTraceError); | ||
| 90 | |||
| 91 | try | ||
| 92 | { | ||
| 93 | hr = StrTrimWhitespace(&sczOutput, wzInput); | ||
| 94 | NativeAssert::Succeeded(hr, "Failed to trim whitespace from string: {0}", wzInput); | ||
| 95 | |||
| 96 | if (0 != wcscmp(wzExpectedResult, sczOutput)) | ||
| 97 | { | ||
| 98 | hr = E_FAIL; | ||
| 99 | ExitOnFailure(hr, "Trimmed string \"%ls\", expected result \"%ls\", actual result \"%ls\"", wzInput, wzExpectedResult, sczOutput); | ||
| 100 | } | ||
| 101 | } | ||
| 102 | finally | ||
| 103 | { | ||
| 104 | ReleaseStr(sczOutput); | ||
| 105 | } | ||
| 106 | |||
| 107 | LExit: | ||
| 108 | DutilUninitialize(); | ||
| 109 | } | ||
| 110 | |||
| 111 | void TestTrimAnsi(LPCSTR szInput, LPCSTR szExpectedResult) | ||
| 112 | { | ||
| 113 | HRESULT hr = S_OK; | ||
| 114 | LPSTR sczOutput = NULL; | ||
| 115 | |||
| 116 | DutilInitialize(&DutilTestTraceError); | ||
| 117 | |||
| 118 | try | ||
| 119 | { | ||
| 120 | hr = StrAnsiTrimWhitespace(&sczOutput, szInput); | ||
| 121 | NativeAssert::Succeeded(hr, "Failed to trim whitespace from string: \"{0}\"", szInput); | ||
| 122 | |||
| 123 | if (0 != strcmp(szExpectedResult, sczOutput)) | ||
| 124 | { | ||
| 125 | hr = E_FAIL; | ||
| 126 | ExitOnFailure(hr, "Trimmed string \"%hs\", expected result \"%hs\", actual result \"%hs\"", szInput, szExpectedResult, sczOutput); | ||
| 127 | } | ||
| 128 | } | ||
| 129 | finally | ||
| 130 | { | ||
| 131 | ReleaseStr(sczOutput); | ||
| 132 | } | ||
| 133 | |||
| 134 | LExit: | ||
| 135 | DutilUninitialize(); | ||
| 136 | } | ||
| 137 | |||
| 138 | void TestStrAllocStringAnsi(LPCSTR szSource, DWORD cchSource, LPCWSTR wzExpectedResult) | ||
| 139 | { | ||
| 140 | HRESULT hr = S_OK; | ||
| 141 | LPWSTR sczOutput = NULL; | ||
| 142 | |||
| 143 | DutilInitialize(&DutilTestTraceError); | ||
| 144 | |||
| 145 | try | ||
| 146 | { | ||
| 147 | hr = StrAllocStringAnsi(&sczOutput, szSource, cchSource, CP_UTF8); | ||
| 148 | NativeAssert::Succeeded(hr, "Failed to call StrAllocStringAnsi on string: \"{0}\"", szSource); | ||
| 149 | |||
| 150 | if (0 != wcscmp(sczOutput, wzExpectedResult)) | ||
| 151 | { | ||
| 152 | hr = E_FAIL; | ||
| 153 | ExitOnFailure(hr, "String doesn't match, expected result \"%ls\", actual result \"%ls\"", wzExpectedResult, sczOutput); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | finally | ||
| 157 | { | ||
| 158 | ReleaseStr(sczOutput); | ||
| 159 | } | ||
| 160 | |||
| 161 | LExit: | ||
| 162 | DutilUninitialize(); | ||
| 163 | } | ||
| 164 | |||
| 165 | void TestStrAnsiAllocString(LPWSTR wzSource, DWORD cchSource, LPCSTR szExpectedResult) | ||
| 166 | { | ||
| 167 | HRESULT hr = S_OK; | ||
| 168 | LPSTR sczOutput = NULL; | ||
| 169 | |||
| 170 | DutilInitialize(&DutilTestTraceError); | ||
| 171 | |||
| 172 | try | ||
| 173 | { | ||
| 174 | hr = StrAnsiAllocString(&sczOutput, wzSource, cchSource, CP_UTF8); | ||
| 175 | NativeAssert::Succeeded(hr, "Failed to call StrAllocStringAnsi on string: \"{0}\"", wzSource); | ||
| 176 | |||
| 177 | if (0 != strcmp(sczOutput, szExpectedResult)) | ||
| 178 | { | ||
| 179 | hr = E_FAIL; | ||
| 180 | ExitOnFailure(hr, "String doesn't match, expected result \"%hs\", actual result \"%hs\"", szExpectedResult, sczOutput); | ||
| 181 | } | ||
| 182 | } | ||
| 183 | finally | ||
| 184 | { | ||
| 185 | ReleaseStr(sczOutput); | ||
| 186 | } | ||
| 187 | |||
| 188 | LExit: | ||
| 189 | DutilUninitialize(); | ||
| 190 | } | ||
| 191 | }; | ||
| 192 | } | ||
diff --git a/src/test/DUtilUnitTest/TestData/ApupUtilTests/FeedBv2.0.xml b/src/test/DUtilUnitTest/TestData/ApupUtilTests/FeedBv2.0.xml deleted file mode 100644 index d9f961fe..00000000 --- a/src/test/DUtilUnitTest/TestData/ApupUtilTests/FeedBv2.0.xml +++ /dev/null | |||
| @@ -1,68 +0,0 @@ | |||
| 1 | <?xml version='1.0' ?> | ||
| 2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 3 | |||
| 4 | |||
| 5 | <feed xmlns="http://www.w3.org/2005/Atom" xmlns:as="http://appsyndication.org/2006/appsyn"> | ||
| 6 | <title type="text">BundleB v2.0</title> | ||
| 7 | <subtitle type="text">Bundle Subtitle.</subtitle> | ||
| 8 | <as:application type="application/exe">1116353B-7C6E-4C29-BFA1-D4A972CD421D</as:application> | ||
| 9 | <updated>2014-07-14T12:39:00.000Z</updated> | ||
| 10 | <id>http://localhost:9999/wix4/BundleB/feed</id> | ||
| 11 | <link rel="self" type="application/atom+xml" href="http://localhost:9999/wix4/BundleB/feed"/> | ||
| 12 | <generator version="0.1">manual build</generator> | ||
| 13 | <entry> | ||
| 14 | <title>Bundle v2.0</title> | ||
| 15 | <id>v2.0</id> | ||
| 16 | <author> | ||
| 17 | <name>Bundle_Author</name> | ||
| 18 | <uri>http://mycompany.com/software</uri> | ||
| 19 | <email>Bundle_Author@mycompany.com</email> | ||
| 20 | </author> | ||
| 21 | <link rel="alternate" href="http://www.mycompany.com/content/view/software"/> | ||
| 22 | <link rel="enclosure" href="http://localhost:9999/wix4/BundleB/2.0/BundleB.exe" length="0" type="application/octet-stream"/> | ||
| 23 | <content type="html"> | ||
| 24 | <p>Change list:</p><ul> | ||
| 25 | <li>Updated release.</li> | ||
| 26 | </ul> | ||
| 27 | </content> | ||
| 28 | <as:version>2.0.0.0</as:version> | ||
| 29 | <updated>2014-11-10T12:39:00.000Z</updated> | ||
| 30 | </entry> | ||
| 31 | <entry> | ||
| 32 | <title>Bundle v1.0</title> | ||
| 33 | <id>v1.0</id> | ||
| 34 | <author> | ||
| 35 | <name>Bundle_Author</name> | ||
| 36 | <uri>http://mycompany.com/software</uri> | ||
| 37 | <email>Bundle_Author@mycompany.com</email> | ||
| 38 | </author> | ||
| 39 | <link rel="alternate" href="http://www.mycompany.com/content/view/software"/> | ||
| 40 | <link rel="enclosure" href="http://localhost:9999/wix4/BundleB/1.0/BundleB.exe" length="0" type="application/octet-stream"/> | ||
| 41 | <content type="html"> | ||
| 42 | <p>Change list:</p><ul> | ||
| 43 | <li>Initial release.</li> | ||
| 44 | </ul> | ||
| 45 | </content> | ||
| 46 | <as:upgrade version="1.0.0.0-preview" /> | ||
| 47 | <as:version>1.0.0.0</as:version> | ||
| 48 | <updated>2014-11-09T12:39:00.000Z</updated> | ||
| 49 | </entry> | ||
| 50 | <entry> | ||
| 51 | <title>Bundle v1.0-preview</title> | ||
| 52 | <id>v1.0-preview</id> | ||
| 53 | <author> | ||
| 54 | <name>Bundle_Author</name> | ||
| 55 | <uri>http://mycompany.com/software</uri> | ||
| 56 | <email>Bundle_Author@mycompany.com</email> | ||
| 57 | </author> | ||
| 58 | <link rel="alternate" href="http://www.mycompany.com/content/view/software"/> | ||
| 59 | <link rel="enclosure" href="http://localhost:9999/wix4/BundleB/1.0-preview/BundleB.exe" length="10000" type="application/octet-stream"/> | ||
| 60 | <content type="html"> | ||
| 61 | <p>Change list:</p><ul> | ||
| 62 | <li>Initial release.</li> | ||
| 63 | </ul> | ||
| 64 | </content> | ||
| 65 | <as:version>1.0.0.0</as:version> | ||
| 66 | <updated>2014-11-09T12:39:00.000Z</updated> | ||
| 67 | </entry> | ||
| 68 | </feed> | ||
diff --git a/src/test/DUtilUnitTest/UnitTest.rc b/src/test/DUtilUnitTest/UnitTest.rc deleted file mode 100644 index 14cebe1a..00000000 --- a/src/test/DUtilUnitTest/UnitTest.rc +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #define VER_APP | ||
| 4 | #define VER_ORIGINAL_FILENAME "UnitTest.dll" | ||
| 5 | #define VER_INTERNAL_NAME "setup" | ||
| 6 | #define VER_FILE_DESCRIPTION "WiX Toolset Bootstrapper unit tests" | ||
diff --git a/src/test/DUtilUnitTest/UriUtilTest.cpp b/src/test/DUtilUnitTest/UriUtilTest.cpp deleted file mode 100644 index b3bf87a2..00000000 --- a/src/test/DUtilUnitTest/UriUtilTest.cpp +++ /dev/null | |||
| @@ -1,98 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace System::Text; | ||
| 7 | using namespace System::Collections::Generic; | ||
| 8 | using namespace Xunit; | ||
| 9 | |||
| 10 | namespace CfgTests | ||
| 11 | { | ||
| 12 | public ref class UriUtil | ||
| 13 | { | ||
| 14 | public: | ||
| 15 | [Fact] | ||
| 16 | void UriProtocolTest() | ||
| 17 | { | ||
| 18 | HRESULT hr = S_OK; | ||
| 19 | |||
| 20 | DutilInitialize(&DutilTestTraceError); | ||
| 21 | |||
| 22 | LPCWSTR uri = L"https://localhost/"; | ||
| 23 | URI_PROTOCOL uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 24 | hr = UriProtocol(uri, &uriProtocol); | ||
| 25 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 26 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_HTTPS, (int)uriProtocol); | ||
| 27 | |||
| 28 | uri = L"HTTPS://localhost/"; | ||
| 29 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 30 | hr = UriProtocol(uri, &uriProtocol); | ||
| 31 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 32 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_HTTPS, (int)uriProtocol); | ||
| 33 | |||
| 34 | uri = L"HtTpS://localhost/"; | ||
| 35 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 36 | hr = UriProtocol(uri, &uriProtocol); | ||
| 37 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 38 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_HTTPS, (int)uriProtocol); | ||
| 39 | |||
| 40 | uri = L"HTTP://localhost/"; | ||
| 41 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 42 | hr = UriProtocol(uri, &uriProtocol); | ||
| 43 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 44 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_HTTP, (int)uriProtocol); | ||
| 45 | |||
| 46 | uri = L"http://localhost/"; | ||
| 47 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 48 | hr = UriProtocol(uri, &uriProtocol); | ||
| 49 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 50 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_HTTP, (int)uriProtocol); | ||
| 51 | |||
| 52 | uri = L"HtTp://localhost/"; | ||
| 53 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 54 | hr = UriProtocol(uri, &uriProtocol); | ||
| 55 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 56 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_HTTP, (int)uriProtocol); | ||
| 57 | |||
| 58 | uri = L"file://localhost/"; | ||
| 59 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 60 | hr = UriProtocol(uri, &uriProtocol); | ||
| 61 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 62 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_FILE, (int)uriProtocol); | ||
| 63 | |||
| 64 | uri = L"FILE://localhost/"; | ||
| 65 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 66 | hr = UriProtocol(uri, &uriProtocol); | ||
| 67 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 68 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_FILE, (int)uriProtocol); | ||
| 69 | |||
| 70 | uri = L"FiLe://localhost/"; | ||
| 71 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 72 | hr = UriProtocol(uri, &uriProtocol); | ||
| 73 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 74 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_FILE, (int)uriProtocol); | ||
| 75 | |||
| 76 | uri = L"FTP://localhost/"; | ||
| 77 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 78 | hr = UriProtocol(uri, &uriProtocol); | ||
| 79 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 80 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_FTP, (int)uriProtocol); | ||
| 81 | |||
| 82 | uri = L"ftp://localhost/"; | ||
| 83 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 84 | hr = UriProtocol(uri, &uriProtocol); | ||
| 85 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 86 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_FTP, (int)uriProtocol); | ||
| 87 | |||
| 88 | uri = L"FtP://localhost/"; | ||
| 89 | uriProtocol = URI_PROTOCOL::URI_PROTOCOL_UNKNOWN; | ||
| 90 | hr = UriProtocol(uri, &uriProtocol); | ||
| 91 | ExitOnFailure(hr, "Failed to determine UriProtocol"); | ||
| 92 | Assert::Equal((int)URI_PROTOCOL::URI_PROTOCOL_FTP, (int)uriProtocol); | ||
| 93 | |||
| 94 | LExit: | ||
| 95 | DutilUninitialize(); | ||
| 96 | } | ||
| 97 | }; | ||
| 98 | } | ||
diff --git a/src/test/DUtilUnitTest/VerUtilTests.cpp b/src/test/DUtilUnitTest/VerUtilTests.cpp deleted file mode 100644 index 8f24ad1a..00000000 --- a/src/test/DUtilUnitTest/VerUtilTests.cpp +++ /dev/null | |||
| @@ -1,933 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | using namespace System; | ||
| 6 | using namespace Xunit; | ||
| 7 | using namespace WixBuildTools::TestSupport; | ||
| 8 | |||
| 9 | namespace DutilTests | ||
| 10 | { | ||
| 11 | public ref class VerUtil | ||
| 12 | { | ||
| 13 | public: | ||
| 14 | [Fact] | ||
| 15 | void VerCompareVersionsTreatsMissingRevisionAsZero() | ||
| 16 | { | ||
| 17 | HRESULT hr = S_OK; | ||
| 18 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 19 | VERUTIL_VERSION* pVersion2 = NULL; | ||
| 20 | VERUTIL_VERSION* pVersion3 = NULL; | ||
| 21 | LPCWSTR wzVersion1 = L"1.2.3.4"; | ||
| 22 | LPCWSTR wzVersion2 = L"1.2.3"; | ||
| 23 | LPCWSTR wzVersion3 = L"1.2.3.0"; | ||
| 24 | |||
| 25 | try | ||
| 26 | { | ||
| 27 | hr = VerParseVersion(wzVersion1, 0, FALSE, &pVersion1); | ||
| 28 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion1); | ||
| 29 | |||
| 30 | hr = VerParseVersion(wzVersion2, 0, FALSE, &pVersion2); | ||
| 31 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2); | ||
| 32 | |||
| 33 | hr = VerParseVersion(wzVersion3, 0, FALSE, &pVersion3); | ||
| 34 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3); | ||
| 35 | |||
| 36 | NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion); | ||
| 37 | Assert::Equal<DWORD>(1, pVersion1->dwMajor); | ||
| 38 | Assert::Equal<DWORD>(2, pVersion1->dwMinor); | ||
| 39 | Assert::Equal<DWORD>(3, pVersion1->dwPatch); | ||
| 40 | Assert::Equal<DWORD>(4, pVersion1->dwRevision); | ||
| 41 | Assert::Equal<DWORD>(0, pVersion1->cReleaseLabels); | ||
| 42 | Assert::Equal<DWORD>(7, pVersion1->cchMetadataOffset); | ||
| 43 | Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid); | ||
| 44 | |||
| 45 | NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion); | ||
| 46 | Assert::Equal<DWORD>(1, pVersion2->dwMajor); | ||
| 47 | Assert::Equal<DWORD>(2, pVersion2->dwMinor); | ||
| 48 | Assert::Equal<DWORD>(3, pVersion2->dwPatch); | ||
| 49 | Assert::Equal<DWORD>(0, pVersion2->dwRevision); | ||
| 50 | Assert::Equal<DWORD>(0, pVersion2->cReleaseLabels); | ||
| 51 | Assert::Equal<DWORD>(5, pVersion2->cchMetadataOffset); | ||
| 52 | Assert::Equal<BOOL>(FALSE, pVersion2->fInvalid); | ||
| 53 | |||
| 54 | NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion); | ||
| 55 | Assert::Equal<DWORD>(1, pVersion3->dwMajor); | ||
| 56 | Assert::Equal<DWORD>(2, pVersion3->dwMinor); | ||
| 57 | Assert::Equal<DWORD>(3, pVersion3->dwPatch); | ||
| 58 | Assert::Equal<DWORD>(0, pVersion3->dwRevision); | ||
| 59 | Assert::Equal<DWORD>(0, pVersion3->cReleaseLabels); | ||
| 60 | Assert::Equal<DWORD>(7, pVersion3->cchMetadataOffset); | ||
| 61 | Assert::Equal<BOOL>(FALSE, pVersion3->fInvalid); | ||
| 62 | |||
| 63 | TestVerutilCompareParsedVersions(pVersion1, pVersion2, 1); | ||
| 64 | TestVerutilCompareParsedVersions(pVersion3, pVersion2, 0); | ||
| 65 | } | ||
| 66 | finally | ||
| 67 | { | ||
| 68 | ReleaseVerutilVersion(pVersion1); | ||
| 69 | ReleaseVerutilVersion(pVersion2); | ||
| 70 | ReleaseVerutilVersion(pVersion3); | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | [Fact] | ||
| 75 | void VerCompareVersionsTreatsNumericReleaseLabelsAsNumbers() | ||
| 76 | { | ||
| 77 | HRESULT hr = S_OK; | ||
| 78 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 79 | VERUTIL_VERSION* pVersion2 = NULL; | ||
| 80 | LPCWSTR wzVersion1 = L"1.0-2.0"; | ||
| 81 | LPCWSTR wzVersion2 = L"1.0-19"; | ||
| 82 | |||
| 83 | try | ||
| 84 | { | ||
| 85 | hr = VerParseVersion(wzVersion1, 0, FALSE, &pVersion1); | ||
| 86 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion1); | ||
| 87 | |||
| 88 | hr = VerParseVersion(wzVersion2, 0, FALSE, &pVersion2); | ||
| 89 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2); | ||
| 90 | |||
| 91 | NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion); | ||
| 92 | Assert::Equal<DWORD>(1, pVersion1->dwMajor); | ||
| 93 | Assert::Equal<DWORD>(0, pVersion1->dwMinor); | ||
| 94 | Assert::Equal<DWORD>(0, pVersion1->dwPatch); | ||
| 95 | Assert::Equal<DWORD>(0, pVersion1->dwRevision); | ||
| 96 | Assert::Equal<DWORD>(2, pVersion1->cReleaseLabels); | ||
| 97 | |||
| 98 | Assert::Equal<BOOL>(TRUE, pVersion1->rgReleaseLabels[0].fNumeric); | ||
| 99 | Assert::Equal<DWORD>(2, pVersion1->rgReleaseLabels[0].dwValue); | ||
| 100 | Assert::Equal<DWORD>(1, pVersion1->rgReleaseLabels[0].cchLabel); | ||
| 101 | Assert::Equal<DWORD>(4, pVersion1->rgReleaseLabels[0].cchLabelOffset); | ||
| 102 | |||
| 103 | Assert::Equal<BOOL>(TRUE, pVersion1->rgReleaseLabels[1].fNumeric); | ||
| 104 | Assert::Equal<DWORD>(0, pVersion1->rgReleaseLabels[1].dwValue); | ||
| 105 | Assert::Equal<DWORD>(1, pVersion1->rgReleaseLabels[1].cchLabel); | ||
| 106 | Assert::Equal<DWORD>(6, pVersion1->rgReleaseLabels[1].cchLabelOffset); | ||
| 107 | |||
| 108 | Assert::Equal<DWORD>(7, pVersion1->cchMetadataOffset); | ||
| 109 | Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid); | ||
| 110 | |||
| 111 | NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion); | ||
| 112 | Assert::Equal<DWORD>(1, pVersion2->dwMajor); | ||
| 113 | Assert::Equal<DWORD>(0, pVersion2->dwMinor); | ||
| 114 | Assert::Equal<DWORD>(0, pVersion2->dwPatch); | ||
| 115 | Assert::Equal<DWORD>(0, pVersion2->dwRevision); | ||
| 116 | Assert::Equal<DWORD>(1, pVersion2->cReleaseLabels); | ||
| 117 | |||
| 118 | Assert::Equal<BOOL>(TRUE, pVersion2->rgReleaseLabels[0].fNumeric); | ||
| 119 | Assert::Equal<DWORD>(19, pVersion2->rgReleaseLabels[0].dwValue); | ||
| 120 | Assert::Equal<DWORD>(2, pVersion2->rgReleaseLabels[0].cchLabel); | ||
| 121 | Assert::Equal<DWORD>(4, pVersion2->rgReleaseLabels[0].cchLabelOffset); | ||
| 122 | |||
| 123 | Assert::Equal<DWORD>(6, pVersion2->cchMetadataOffset); | ||
| 124 | Assert::Equal<BOOL>(FALSE, pVersion2->fInvalid); | ||
| 125 | |||
| 126 | TestVerutilCompareParsedVersions(pVersion1, pVersion2, -1); | ||
| 127 | } | ||
| 128 | finally | ||
| 129 | { | ||
| 130 | ReleaseVerutilVersion(pVersion1); | ||
| 131 | ReleaseVerutilVersion(pVersion2); | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | [Fact] | ||
| 136 | void VerCompareVersionsHandlesNormallyInvalidVersions() | ||
| 137 | { | ||
| 138 | HRESULT hr = S_OK; | ||
| 139 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 140 | VERUTIL_VERSION* pVersion2 = NULL; | ||
| 141 | VERUTIL_VERSION* pVersion3 = NULL; | ||
| 142 | VERUTIL_VERSION* pVersion4 = NULL; | ||
| 143 | VERUTIL_VERSION* pVersion5 = NULL; | ||
| 144 | VERUTIL_VERSION* pVersion6 = NULL; | ||
| 145 | LPCWSTR wzVersion1 = L"10.-4.0"; | ||
| 146 | LPCWSTR wzVersion2 = L"10.-2.0"; | ||
| 147 | LPCWSTR wzVersion3 = L"0"; | ||
| 148 | LPCWSTR wzVersion4 = L""; | ||
| 149 | LPCWSTR wzVersion5 = L"10-2"; | ||
| 150 | LPCWSTR wzVersion6 = L"10-4.@"; | ||
| 151 | |||
| 152 | try | ||
| 153 | { | ||
| 154 | hr = VerParseVersion(wzVersion1, 0, FALSE, &pVersion1); | ||
| 155 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion1); | ||
| 156 | |||
| 157 | hr = VerParseVersion(wzVersion2, 0, FALSE, &pVersion2); | ||
| 158 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2); | ||
| 159 | |||
| 160 | hr = VerParseVersion(wzVersion3, 0, FALSE, &pVersion3); | ||
| 161 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3); | ||
| 162 | |||
| 163 | hr = VerParseVersion(wzVersion4, 0, FALSE, &pVersion4); | ||
| 164 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion4); | ||
| 165 | |||
| 166 | hr = VerParseVersion(wzVersion5, 0, FALSE, &pVersion5); | ||
| 167 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion5); | ||
| 168 | |||
| 169 | hr = VerParseVersion(wzVersion6, 0, FALSE, &pVersion6); | ||
| 170 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion6); | ||
| 171 | |||
| 172 | NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion); | ||
| 173 | Assert::Equal<DWORD>(10, pVersion1->dwMajor); | ||
| 174 | Assert::Equal<DWORD>(0, pVersion1->dwMinor); | ||
| 175 | Assert::Equal<DWORD>(0, pVersion1->dwPatch); | ||
| 176 | Assert::Equal<DWORD>(0, pVersion1->dwRevision); | ||
| 177 | Assert::Equal<DWORD>(0, pVersion1->cReleaseLabels); | ||
| 178 | Assert::Equal<DWORD>(3, pVersion1->cchMetadataOffset); | ||
| 179 | Assert::Equal<BOOL>(TRUE, pVersion1->fInvalid); | ||
| 180 | |||
| 181 | NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion); | ||
| 182 | Assert::Equal<DWORD>(10, pVersion2->dwMajor); | ||
| 183 | Assert::Equal<DWORD>(0, pVersion2->dwMinor); | ||
| 184 | Assert::Equal<DWORD>(0, pVersion2->dwPatch); | ||
| 185 | Assert::Equal<DWORD>(0, pVersion2->dwRevision); | ||
| 186 | Assert::Equal<DWORD>(0, pVersion2->cReleaseLabels); | ||
| 187 | Assert::Equal<DWORD>(3, pVersion2->cchMetadataOffset); | ||
| 188 | Assert::Equal<BOOL>(TRUE, pVersion2->fInvalid); | ||
| 189 | |||
| 190 | NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion); | ||
| 191 | Assert::Equal<DWORD>(0, pVersion3->dwMajor); | ||
| 192 | Assert::Equal<DWORD>(0, pVersion3->dwMinor); | ||
| 193 | Assert::Equal<DWORD>(0, pVersion3->dwPatch); | ||
| 194 | Assert::Equal<DWORD>(0, pVersion3->dwRevision); | ||
| 195 | Assert::Equal<DWORD>(0, pVersion3->cReleaseLabels); | ||
| 196 | Assert::Equal<DWORD>(1, pVersion3->cchMetadataOffset); | ||
| 197 | Assert::Equal<BOOL>(FALSE, pVersion3->fInvalid); | ||
| 198 | |||
| 199 | NativeAssert::StringEqual(wzVersion4, pVersion4->sczVersion); | ||
| 200 | Assert::Equal<DWORD>(0, pVersion4->dwMajor); | ||
| 201 | Assert::Equal<DWORD>(0, pVersion4->dwMinor); | ||
| 202 | Assert::Equal<DWORD>(0, pVersion4->dwPatch); | ||
| 203 | Assert::Equal<DWORD>(0, pVersion4->dwRevision); | ||
| 204 | Assert::Equal<DWORD>(0, pVersion4->cReleaseLabels); | ||
| 205 | Assert::Equal<DWORD>(0, pVersion4->cchMetadataOffset); | ||
| 206 | Assert::Equal<BOOL>(TRUE, pVersion4->fInvalid); | ||
| 207 | |||
| 208 | NativeAssert::StringEqual(wzVersion5, pVersion5->sczVersion); | ||
| 209 | Assert::Equal<DWORD>(10, pVersion5->dwMajor); | ||
| 210 | Assert::Equal<DWORD>(0, pVersion5->dwMinor); | ||
| 211 | Assert::Equal<DWORD>(0, pVersion5->dwPatch); | ||
| 212 | Assert::Equal<DWORD>(0, pVersion5->dwRevision); | ||
| 213 | Assert::Equal<DWORD>(1, pVersion5->cReleaseLabels); | ||
| 214 | |||
| 215 | Assert::Equal<BOOL>(TRUE, pVersion5->rgReleaseLabels[0].fNumeric); | ||
| 216 | Assert::Equal<DWORD>(2, pVersion5->rgReleaseLabels[0].dwValue); | ||
| 217 | Assert::Equal<DWORD>(1, pVersion5->rgReleaseLabels[0].cchLabel); | ||
| 218 | Assert::Equal<DWORD>(3, pVersion5->rgReleaseLabels[0].cchLabelOffset); | ||
| 219 | |||
| 220 | Assert::Equal<DWORD>(4, pVersion5->cchMetadataOffset); | ||
| 221 | Assert::Equal<BOOL>(FALSE, pVersion5->fInvalid); | ||
| 222 | |||
| 223 | NativeAssert::StringEqual(wzVersion6, pVersion6->sczVersion); | ||
| 224 | Assert::Equal<DWORD>(10, pVersion6->dwMajor); | ||
| 225 | Assert::Equal<DWORD>(0, pVersion6->dwMinor); | ||
| 226 | Assert::Equal<DWORD>(0, pVersion6->dwPatch); | ||
| 227 | Assert::Equal<DWORD>(0, pVersion6->dwRevision); | ||
| 228 | Assert::Equal<DWORD>(1, pVersion6->cReleaseLabels); | ||
| 229 | |||
| 230 | Assert::Equal<BOOL>(TRUE, pVersion6->rgReleaseLabels[0].fNumeric); | ||
| 231 | Assert::Equal<DWORD>(4, pVersion6->rgReleaseLabels[0].dwValue); | ||
| 232 | Assert::Equal<DWORD>(1, pVersion6->rgReleaseLabels[0].cchLabel); | ||
| 233 | Assert::Equal<DWORD>(3, pVersion6->rgReleaseLabels[0].cchLabelOffset); | ||
| 234 | |||
| 235 | Assert::Equal<DWORD>(5, pVersion6->cchMetadataOffset); | ||
| 236 | Assert::Equal<BOOL>(TRUE, pVersion6->fInvalid); | ||
| 237 | |||
| 238 | TestVerutilCompareParsedVersions(pVersion1, pVersion2, 1); | ||
| 239 | TestVerutilCompareParsedVersions(pVersion3, pVersion4, 1); | ||
| 240 | TestVerutilCompareParsedVersions(pVersion5, pVersion6, -1); | ||
| 241 | } | ||
| 242 | finally | ||
| 243 | { | ||
| 244 | ReleaseVerutilVersion(pVersion1); | ||
| 245 | ReleaseVerutilVersion(pVersion2); | ||
| 246 | ReleaseVerutilVersion(pVersion3); | ||
| 247 | ReleaseVerutilVersion(pVersion4); | ||
| 248 | ReleaseVerutilVersion(pVersion5); | ||
| 249 | ReleaseVerutilVersion(pVersion6); | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 253 | [Fact] | ||
| 254 | void VerCompareVersionsTreatsHyphenAsVersionSeparator() | ||
| 255 | { | ||
| 256 | HRESULT hr = S_OK; | ||
| 257 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 258 | VERUTIL_VERSION* pVersion2 = NULL; | ||
| 259 | VERUTIL_VERSION* pVersion3 = NULL; | ||
| 260 | LPCWSTR wzVersion1 = L"0.0.1-a"; | ||
| 261 | LPCWSTR wzVersion2 = L"0-2"; | ||
| 262 | LPCWSTR wzVersion3 = L"1-2"; | ||
| 263 | |||
| 264 | try | ||
| 265 | { | ||
| 266 | hr = VerParseVersion(wzVersion1, 0, FALSE, &pVersion1); | ||
| 267 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion1); | ||
| 268 | |||
| 269 | hr = VerParseVersion(wzVersion2, 0, FALSE, &pVersion2); | ||
| 270 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2); | ||
| 271 | |||
| 272 | hr = VerParseVersion(wzVersion3, 0, FALSE, &pVersion3); | ||
| 273 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3); | ||
| 274 | |||
| 275 | NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion); | ||
| 276 | Assert::Equal<DWORD>(0, pVersion1->dwMajor); | ||
| 277 | Assert::Equal<DWORD>(0, pVersion1->dwMinor); | ||
| 278 | Assert::Equal<DWORD>(1, pVersion1->dwPatch); | ||
| 279 | Assert::Equal<DWORD>(0, pVersion1->dwRevision); | ||
| 280 | Assert::Equal<DWORD>(1, pVersion1->cReleaseLabels); | ||
| 281 | |||
| 282 | Assert::Equal<BOOL>(FALSE, pVersion1->rgReleaseLabels[0].fNumeric); | ||
| 283 | Assert::Equal<DWORD>(1, pVersion1->rgReleaseLabels[0].cchLabel); | ||
| 284 | Assert::Equal<DWORD>(6, pVersion1->rgReleaseLabels[0].cchLabelOffset); | ||
| 285 | |||
| 286 | Assert::Equal<DWORD>(7, pVersion1->cchMetadataOffset); | ||
| 287 | Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid); | ||
| 288 | |||
| 289 | NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion); | ||
| 290 | Assert::Equal<DWORD>(0, pVersion2->dwMajor); | ||
| 291 | Assert::Equal<DWORD>(0, pVersion2->dwMinor); | ||
| 292 | Assert::Equal<DWORD>(0, pVersion2->dwPatch); | ||
| 293 | Assert::Equal<DWORD>(0, pVersion2->dwRevision); | ||
| 294 | Assert::Equal<DWORD>(1, pVersion2->cReleaseLabels); | ||
| 295 | |||
| 296 | Assert::Equal<BOOL>(TRUE, pVersion2->rgReleaseLabels[0].fNumeric); | ||
| 297 | Assert::Equal<DWORD>(2, pVersion2->rgReleaseLabels[0].dwValue); | ||
| 298 | Assert::Equal<DWORD>(1, pVersion2->rgReleaseLabels[0].cchLabel); | ||
| 299 | Assert::Equal<DWORD>(2, pVersion2->rgReleaseLabels[0].cchLabelOffset); | ||
| 300 | |||
| 301 | Assert::Equal<DWORD>(3, pVersion2->cchMetadataOffset); | ||
| 302 | Assert::Equal<BOOL>(FALSE, pVersion2->fInvalid); | ||
| 303 | |||
| 304 | NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion); | ||
| 305 | Assert::Equal<DWORD>(1, pVersion3->dwMajor); | ||
| 306 | Assert::Equal<DWORD>(0, pVersion3->dwMinor); | ||
| 307 | Assert::Equal<DWORD>(0, pVersion3->dwPatch); | ||
| 308 | Assert::Equal<DWORD>(0, pVersion3->dwRevision); | ||
| 309 | Assert::Equal<DWORD>(1, pVersion3->cReleaseLabels); | ||
| 310 | |||
| 311 | Assert::Equal<BOOL>(TRUE, pVersion3->rgReleaseLabels[0].fNumeric); | ||
| 312 | Assert::Equal<DWORD>(2, pVersion3->rgReleaseLabels[0].dwValue); | ||
| 313 | Assert::Equal<DWORD>(1, pVersion3->rgReleaseLabels[0].cchLabel); | ||
| 314 | Assert::Equal<DWORD>(2, pVersion3->rgReleaseLabels[0].cchLabelOffset); | ||
| 315 | |||
| 316 | Assert::Equal<DWORD>(3, pVersion3->cchMetadataOffset); | ||
| 317 | Assert::Equal<BOOL>(FALSE, pVersion3->fInvalid); | ||
| 318 | |||
| 319 | TestVerutilCompareParsedVersions(pVersion1, pVersion2, 1); | ||
| 320 | TestVerutilCompareParsedVersions(pVersion1, pVersion3, -1); | ||
| 321 | } | ||
| 322 | finally | ||
| 323 | { | ||
| 324 | ReleaseVerutilVersion(pVersion1); | ||
| 325 | ReleaseVerutilVersion(pVersion2); | ||
| 326 | ReleaseVerutilVersion(pVersion3); | ||
| 327 | } | ||
| 328 | } | ||
| 329 | |||
| 330 | [Fact] | ||
| 331 | void VerCompareVersionsIgnoresLeadingZeroes() | ||
| 332 | { | ||
| 333 | HRESULT hr = S_OK; | ||
| 334 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 335 | VERUTIL_VERSION* pVersion2 = NULL; | ||
| 336 | VERUTIL_VERSION* pVersion3 = NULL; | ||
| 337 | VERUTIL_VERSION* pVersion4 = NULL; | ||
| 338 | LPCWSTR wzVersion1 = L"0.01-a.1"; | ||
| 339 | LPCWSTR wzVersion2 = L"0.1.0-a.1"; | ||
| 340 | LPCWSTR wzVersion3 = L"0.1-a.b.0"; | ||
| 341 | LPCWSTR wzVersion4 = L"0.1.0-a.b.000"; | ||
| 342 | |||
| 343 | try | ||
| 344 | { | ||
| 345 | hr = VerParseVersion(wzVersion1, 0, FALSE, &pVersion1); | ||
| 346 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion1); | ||
| 347 | |||
| 348 | hr = VerParseVersion(wzVersion2, 0, FALSE, &pVersion2); | ||
| 349 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2); | ||
| 350 | |||
| 351 | hr = VerParseVersion(wzVersion3, 0, FALSE, &pVersion3); | ||
| 352 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3); | ||
| 353 | |||
| 354 | hr = VerParseVersion(wzVersion4, 0, FALSE, &pVersion4); | ||
| 355 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion4); | ||
| 356 | |||
| 357 | NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion); | ||
| 358 | Assert::Equal<DWORD>(0, pVersion1->dwMajor); | ||
| 359 | Assert::Equal<DWORD>(1, pVersion1->dwMinor); | ||
| 360 | Assert::Equal<DWORD>(0, pVersion1->dwPatch); | ||
| 361 | Assert::Equal<DWORD>(0, pVersion1->dwRevision); | ||
| 362 | Assert::Equal<DWORD>(2, pVersion1->cReleaseLabels); | ||
| 363 | |||
| 364 | Assert::Equal<BOOL>(FALSE, pVersion1->rgReleaseLabels[0].fNumeric); | ||
| 365 | Assert::Equal<DWORD>(1, pVersion1->rgReleaseLabels[0].cchLabel); | ||
| 366 | Assert::Equal<DWORD>(5, pVersion1->rgReleaseLabels[0].cchLabelOffset); | ||
| 367 | |||
| 368 | Assert::Equal<BOOL>(TRUE, pVersion1->rgReleaseLabels[1].fNumeric); | ||
| 369 | Assert::Equal<DWORD>(1, pVersion1->rgReleaseLabels[1].dwValue); | ||
| 370 | Assert::Equal<DWORD>(1, pVersion1->rgReleaseLabels[1].cchLabel); | ||
| 371 | Assert::Equal<DWORD>(7, pVersion1->rgReleaseLabels[1].cchLabelOffset); | ||
| 372 | |||
| 373 | Assert::Equal<DWORD>(8, pVersion1->cchMetadataOffset); | ||
| 374 | Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid); | ||
| 375 | |||
| 376 | NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion); | ||
| 377 | Assert::Equal<DWORD>(0, pVersion2->dwMajor); | ||
| 378 | Assert::Equal<DWORD>(1, pVersion2->dwMinor); | ||
| 379 | Assert::Equal<DWORD>(0, pVersion2->dwPatch); | ||
| 380 | Assert::Equal<DWORD>(0, pVersion2->dwRevision); | ||
| 381 | Assert::Equal<DWORD>(2, pVersion2->cReleaseLabels); | ||
| 382 | |||
| 383 | Assert::Equal<BOOL>(FALSE, pVersion2->rgReleaseLabels[0].fNumeric); | ||
| 384 | Assert::Equal<DWORD>(1, pVersion2->rgReleaseLabels[0].cchLabel); | ||
| 385 | Assert::Equal<DWORD>(6, pVersion2->rgReleaseLabels[0].cchLabelOffset); | ||
| 386 | |||
| 387 | Assert::Equal<BOOL>(TRUE, pVersion2->rgReleaseLabels[1].fNumeric); | ||
| 388 | Assert::Equal<DWORD>(1, pVersion2->rgReleaseLabels[1].dwValue); | ||
| 389 | Assert::Equal<DWORD>(1, pVersion2->rgReleaseLabels[1].cchLabel); | ||
| 390 | Assert::Equal<DWORD>(8, pVersion2->rgReleaseLabels[1].cchLabelOffset); | ||
| 391 | |||
| 392 | Assert::Equal<DWORD>(9, pVersion2->cchMetadataOffset); | ||
| 393 | Assert::Equal<BOOL>(FALSE, pVersion2->fInvalid); | ||
| 394 | |||
| 395 | NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion); | ||
| 396 | Assert::Equal<DWORD>(0, pVersion3->dwMajor); | ||
| 397 | Assert::Equal<DWORD>(1, pVersion3->dwMinor); | ||
| 398 | Assert::Equal<DWORD>(0, pVersion3->dwPatch); | ||
| 399 | Assert::Equal<DWORD>(0, pVersion3->dwRevision); | ||
| 400 | Assert::Equal<DWORD>(3, pVersion3->cReleaseLabels); | ||
| 401 | |||
| 402 | Assert::Equal<BOOL>(FALSE, pVersion3->rgReleaseLabels[0].fNumeric); | ||
| 403 | Assert::Equal<DWORD>(1, pVersion3->rgReleaseLabels[0].cchLabel); | ||
| 404 | Assert::Equal<DWORD>(4, pVersion3->rgReleaseLabels[0].cchLabelOffset); | ||
| 405 | |||
| 406 | Assert::Equal<BOOL>(FALSE, pVersion3->rgReleaseLabels[1].fNumeric); | ||
| 407 | Assert::Equal<DWORD>(1, pVersion3->rgReleaseLabels[1].cchLabel); | ||
| 408 | Assert::Equal<DWORD>(6, pVersion3->rgReleaseLabels[1].cchLabelOffset); | ||
| 409 | |||
| 410 | Assert::Equal<BOOL>(TRUE, pVersion3->rgReleaseLabels[2].fNumeric); | ||
| 411 | Assert::Equal<DWORD>(0, pVersion3->rgReleaseLabels[2].dwValue); | ||
| 412 | Assert::Equal<DWORD>(1, pVersion3->rgReleaseLabels[2].cchLabel); | ||
| 413 | Assert::Equal<DWORD>(8, pVersion3->rgReleaseLabels[2].cchLabelOffset); | ||
| 414 | |||
| 415 | Assert::Equal<DWORD>(9, pVersion3->cchMetadataOffset); | ||
| 416 | Assert::Equal<BOOL>(FALSE, pVersion3->fInvalid); | ||
| 417 | |||
| 418 | NativeAssert::StringEqual(wzVersion4, pVersion4->sczVersion); | ||
| 419 | Assert::Equal<DWORD>(0, pVersion4->dwMajor); | ||
| 420 | Assert::Equal<DWORD>(1, pVersion4->dwMinor); | ||
| 421 | Assert::Equal<DWORD>(0, pVersion4->dwPatch); | ||
| 422 | Assert::Equal<DWORD>(0, pVersion4->dwRevision); | ||
| 423 | Assert::Equal<DWORD>(3, pVersion4->cReleaseLabels); | ||
| 424 | |||
| 425 | Assert::Equal<BOOL>(FALSE, pVersion4->rgReleaseLabels[0].fNumeric); | ||
| 426 | Assert::Equal<DWORD>(1, pVersion4->rgReleaseLabels[0].cchLabel); | ||
| 427 | Assert::Equal<DWORD>(6, pVersion4->rgReleaseLabels[0].cchLabelOffset); | ||
| 428 | |||
| 429 | Assert::Equal<BOOL>(FALSE, pVersion4->rgReleaseLabels[1].fNumeric); | ||
| 430 | Assert::Equal<DWORD>(1, pVersion4->rgReleaseLabels[1].cchLabel); | ||
| 431 | Assert::Equal<DWORD>(8, pVersion4->rgReleaseLabels[1].cchLabelOffset); | ||
| 432 | |||
| 433 | Assert::Equal<BOOL>(TRUE, pVersion4->rgReleaseLabels[2].fNumeric); | ||
| 434 | Assert::Equal<DWORD>(0, pVersion4->rgReleaseLabels[2].dwValue); | ||
| 435 | Assert::Equal<DWORD>(3, pVersion4->rgReleaseLabels[2].cchLabel); | ||
| 436 | Assert::Equal<DWORD>(10, pVersion4->rgReleaseLabels[2].cchLabelOffset); | ||
| 437 | |||
| 438 | Assert::Equal<DWORD>(13, pVersion4->cchMetadataOffset); | ||
| 439 | Assert::Equal<BOOL>(FALSE, pVersion4->fInvalid); | ||
| 440 | |||
| 441 | TestVerutilCompareParsedVersions(pVersion1, pVersion2, 0); | ||
| 442 | TestVerutilCompareParsedVersions(pVersion3, pVersion4, 0); | ||
| 443 | } | ||
| 444 | finally | ||
| 445 | { | ||
| 446 | ReleaseVerutilVersion(pVersion1); | ||
| 447 | ReleaseVerutilVersion(pVersion2); | ||
| 448 | ReleaseVerutilVersion(pVersion3); | ||
| 449 | ReleaseVerutilVersion(pVersion4); | ||
| 450 | } | ||
| 451 | } | ||
| 452 | |||
| 453 | [Fact] | ||
| 454 | void VerCompareVersionsTreatsUnexpectedContentAsMetadata() | ||
| 455 | { | ||
| 456 | HRESULT hr = S_OK; | ||
| 457 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 458 | VERUTIL_VERSION* pVersion2 = NULL; | ||
| 459 | VERUTIL_VERSION* pVersion3 = NULL; | ||
| 460 | LPCWSTR wzVersion1 = L"1.2.3+abcd"; | ||
| 461 | LPCWSTR wzVersion2 = L"1.2.3.abcd"; | ||
| 462 | LPCWSTR wzVersion3 = L"1.2.3.-abcd"; | ||
| 463 | |||
| 464 | try | ||
| 465 | { | ||
| 466 | hr = VerParseVersion(wzVersion1, 0, FALSE, &pVersion1); | ||
| 467 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion1); | ||
| 468 | |||
| 469 | hr = VerParseVersion(wzVersion2, 0, FALSE, &pVersion2); | ||
| 470 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2); | ||
| 471 | |||
| 472 | hr = VerParseVersion(wzVersion3, 0, FALSE, &pVersion3); | ||
| 473 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3); | ||
| 474 | |||
| 475 | NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion); | ||
| 476 | Assert::Equal<DWORD>(1, pVersion1->dwMajor); | ||
| 477 | Assert::Equal<DWORD>(2, pVersion1->dwMinor); | ||
| 478 | Assert::Equal<DWORD>(3, pVersion1->dwPatch); | ||
| 479 | Assert::Equal<DWORD>(0, pVersion1->dwRevision); | ||
| 480 | Assert::Equal<DWORD>(0, pVersion1->cReleaseLabels); | ||
| 481 | Assert::Equal<DWORD>(6, pVersion1->cchMetadataOffset); | ||
| 482 | Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid); | ||
| 483 | |||
| 484 | NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion); | ||
| 485 | Assert::Equal<DWORD>(1, pVersion2->dwMajor); | ||
| 486 | Assert::Equal<DWORD>(2, pVersion2->dwMinor); | ||
| 487 | Assert::Equal<DWORD>(3, pVersion2->dwPatch); | ||
| 488 | Assert::Equal<DWORD>(0, pVersion2->dwRevision); | ||
| 489 | Assert::Equal<DWORD>(0, pVersion2->cReleaseLabels); | ||
| 490 | Assert::Equal<DWORD>(6, pVersion2->cchMetadataOffset); | ||
| 491 | Assert::Equal<BOOL>(TRUE, pVersion2->fInvalid); | ||
| 492 | |||
| 493 | NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion); | ||
| 494 | Assert::Equal<DWORD>(1, pVersion3->dwMajor); | ||
| 495 | Assert::Equal<DWORD>(2, pVersion3->dwMinor); | ||
| 496 | Assert::Equal<DWORD>(3, pVersion3->dwPatch); | ||
| 497 | Assert::Equal<DWORD>(0, pVersion3->dwRevision); | ||
| 498 | Assert::Equal<DWORD>(0, pVersion3->cReleaseLabels); | ||
| 499 | Assert::Equal<DWORD>(6, pVersion3->cchMetadataOffset); | ||
| 500 | Assert::Equal<BOOL>(TRUE, pVersion3->fInvalid); | ||
| 501 | |||
| 502 | TestVerutilCompareParsedVersions(pVersion1, pVersion2, 1); | ||
| 503 | TestVerutilCompareParsedVersions(pVersion1, pVersion3, 1); | ||
| 504 | TestVerutilCompareParsedVersions(pVersion2, pVersion3, -1); | ||
| 505 | } | ||
| 506 | finally | ||
| 507 | { | ||
| 508 | ReleaseVerutilVersion(pVersion1); | ||
| 509 | ReleaseVerutilVersion(pVersion2); | ||
| 510 | ReleaseVerutilVersion(pVersion3); | ||
| 511 | } | ||
| 512 | } | ||
| 513 | |||
| 514 | [Fact] | ||
| 515 | void VerCompareVersionsIgnoresLeadingV() | ||
| 516 | { | ||
| 517 | HRESULT hr = S_OK; | ||
| 518 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 519 | VERUTIL_VERSION* pVersion2 = NULL; | ||
| 520 | VERUTIL_VERSION* pVersion3 = NULL; | ||
| 521 | LPCWSTR wzVersion1 = L"10.20.30.40"; | ||
| 522 | LPCWSTR wzVersion2 = L"v10.20.30.40"; | ||
| 523 | LPCWSTR wzVersion3 = L"V10.20.30.40"; | ||
| 524 | |||
| 525 | try | ||
| 526 | { | ||
| 527 | hr = VerParseVersion(wzVersion1, 0, FALSE, &pVersion1); | ||
| 528 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion1); | ||
| 529 | |||
| 530 | hr = VerParseVersion(wzVersion2, 0, FALSE, &pVersion2); | ||
| 531 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2); | ||
| 532 | |||
| 533 | hr = VerParseVersion(wzVersion3, 0, FALSE, &pVersion3); | ||
| 534 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3); | ||
| 535 | |||
| 536 | NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion); | ||
| 537 | Assert::Equal<DWORD>(10, pVersion1->dwMajor); | ||
| 538 | Assert::Equal<DWORD>(20, pVersion1->dwMinor); | ||
| 539 | Assert::Equal<DWORD>(30, pVersion1->dwPatch); | ||
| 540 | Assert::Equal<DWORD>(40, pVersion1->dwRevision); | ||
| 541 | Assert::Equal<DWORD>(0, pVersion1->cReleaseLabels); | ||
| 542 | Assert::Equal<DWORD>(11, pVersion1->cchMetadataOffset); | ||
| 543 | Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid); | ||
| 544 | |||
| 545 | NativeAssert::StringEqual(wzVersion1, pVersion2->sczVersion); | ||
| 546 | Assert::Equal<DWORD>(10, pVersion2->dwMajor); | ||
| 547 | Assert::Equal<DWORD>(20, pVersion2->dwMinor); | ||
| 548 | Assert::Equal<DWORD>(30, pVersion2->dwPatch); | ||
| 549 | Assert::Equal<DWORD>(40, pVersion2->dwRevision); | ||
| 550 | Assert::Equal<DWORD>(0, pVersion2->cReleaseLabels); | ||
| 551 | Assert::Equal<DWORD>(11, pVersion2->cchMetadataOffset); | ||
| 552 | Assert::Equal<BOOL>(FALSE, pVersion2->fInvalid); | ||
| 553 | |||
| 554 | NativeAssert::StringEqual(wzVersion1, pVersion3->sczVersion); | ||
| 555 | Assert::Equal<DWORD>(10, pVersion3->dwMajor); | ||
| 556 | Assert::Equal<DWORD>(20, pVersion3->dwMinor); | ||
| 557 | Assert::Equal<DWORD>(30, pVersion3->dwPatch); | ||
| 558 | Assert::Equal<DWORD>(40, pVersion3->dwRevision); | ||
| 559 | Assert::Equal<DWORD>(0, pVersion3->cReleaseLabels); | ||
| 560 | Assert::Equal<DWORD>(11, pVersion3->cchMetadataOffset); | ||
| 561 | Assert::Equal<BOOL>(FALSE, pVersion3->fInvalid); | ||
| 562 | |||
| 563 | TestVerutilCompareParsedVersions(pVersion1, pVersion2, 0); | ||
| 564 | TestVerutilCompareParsedVersions(pVersion1, pVersion3, 0); | ||
| 565 | } | ||
| 566 | finally | ||
| 567 | { | ||
| 568 | ReleaseVerutilVersion(pVersion1); | ||
| 569 | ReleaseVerutilVersion(pVersion2); | ||
| 570 | ReleaseVerutilVersion(pVersion3); | ||
| 571 | } | ||
| 572 | } | ||
| 573 | |||
| 574 | [Fact] | ||
| 575 | void VerCompareVersionsHandlesTooLargeNumbers() | ||
| 576 | { | ||
| 577 | HRESULT hr = S_OK; | ||
| 578 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 579 | VERUTIL_VERSION* pVersion2 = NULL; | ||
| 580 | LPCWSTR wzVersion1 = L"4294967295.4294967295.4294967295.4294967295"; | ||
| 581 | LPCWSTR wzVersion2 = L"4294967296.4294967296.4294967296.4294967296"; | ||
| 582 | |||
| 583 | try | ||
| 584 | { | ||
| 585 | hr = VerParseVersion(wzVersion1, 0, FALSE, &pVersion1); | ||
| 586 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion1); | ||
| 587 | |||
| 588 | hr = VerParseVersion(wzVersion2, 0, FALSE, &pVersion2); | ||
| 589 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2); | ||
| 590 | |||
| 591 | NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion); | ||
| 592 | Assert::Equal<DWORD>(4294967295, pVersion1->dwMajor); | ||
| 593 | Assert::Equal<DWORD>(4294967295, pVersion1->dwMinor); | ||
| 594 | Assert::Equal<DWORD>(4294967295, pVersion1->dwPatch); | ||
| 595 | Assert::Equal<DWORD>(4294967295, pVersion1->dwRevision); | ||
| 596 | Assert::Equal<DWORD>(0, pVersion1->cReleaseLabels); | ||
| 597 | Assert::Equal<DWORD>(43, pVersion1->cchMetadataOffset); | ||
| 598 | Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid); | ||
| 599 | |||
| 600 | NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion); | ||
| 601 | Assert::Equal<DWORD>(0, pVersion2->dwMajor); | ||
| 602 | Assert::Equal<DWORD>(0, pVersion2->dwMinor); | ||
| 603 | Assert::Equal<DWORD>(0, pVersion2->dwPatch); | ||
| 604 | Assert::Equal<DWORD>(0, pVersion2->dwRevision); | ||
| 605 | Assert::Equal<DWORD>(0, pVersion2->cReleaseLabels); | ||
| 606 | Assert::Equal<DWORD>(0, pVersion2->cchMetadataOffset); | ||
| 607 | Assert::Equal<BOOL>(TRUE, pVersion2->fInvalid); | ||
| 608 | |||
| 609 | TestVerutilCompareParsedVersions(pVersion1, pVersion2, 1); | ||
| 610 | } | ||
| 611 | finally | ||
| 612 | { | ||
| 613 | ReleaseVerutilVersion(pVersion1); | ||
| 614 | ReleaseVerutilVersion(pVersion2); | ||
| 615 | } | ||
| 616 | } | ||
| 617 | |||
| 618 | [Fact] | ||
| 619 | void VerCompareVersionsIgnoresMetadataForValidVersions() | ||
| 620 | { | ||
| 621 | HRESULT hr = S_OK; | ||
| 622 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 623 | VERUTIL_VERSION* pVersion2 = NULL; | ||
| 624 | LPCWSTR wzVersion1 = L"1.2.3+abc"; | ||
| 625 | LPCWSTR wzVersion2 = L"1.2.3+xyz"; | ||
| 626 | |||
| 627 | try | ||
| 628 | { | ||
| 629 | hr = VerParseVersion(wzVersion1, 0, FALSE, &pVersion1); | ||
| 630 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion1); | ||
| 631 | |||
| 632 | hr = VerParseVersion(wzVersion2, 0, FALSE, &pVersion2); | ||
| 633 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2); | ||
| 634 | |||
| 635 | NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion); | ||
| 636 | Assert::Equal<DWORD>(1, pVersion1->dwMajor); | ||
| 637 | Assert::Equal<DWORD>(2, pVersion1->dwMinor); | ||
| 638 | Assert::Equal<DWORD>(3, pVersion1->dwPatch); | ||
| 639 | Assert::Equal<DWORD>(0, pVersion1->dwRevision); | ||
| 640 | Assert::Equal<DWORD>(0, pVersion1->cReleaseLabels); | ||
| 641 | Assert::Equal<DWORD>(6, pVersion1->cchMetadataOffset); | ||
| 642 | Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid); | ||
| 643 | |||
| 644 | NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion); | ||
| 645 | Assert::Equal<DWORD>(1, pVersion2->dwMajor); | ||
| 646 | Assert::Equal<DWORD>(2, pVersion2->dwMinor); | ||
| 647 | Assert::Equal<DWORD>(3, pVersion2->dwPatch); | ||
| 648 | Assert::Equal<DWORD>(0, pVersion2->dwRevision); | ||
| 649 | Assert::Equal<DWORD>(0, pVersion2->cReleaseLabels); | ||
| 650 | Assert::Equal<DWORD>(6, pVersion2->cchMetadataOffset); | ||
| 651 | Assert::Equal<BOOL>(FALSE, pVersion2->fInvalid); | ||
| 652 | |||
| 653 | TestVerutilCompareParsedVersions(pVersion1, pVersion2, 0); | ||
| 654 | } | ||
| 655 | finally | ||
| 656 | { | ||
| 657 | ReleaseVerutilVersion(pVersion1); | ||
| 658 | ReleaseVerutilVersion(pVersion2); | ||
| 659 | } | ||
| 660 | } | ||
| 661 | |||
| 662 | [Fact] | ||
| 663 | void VerCopyVersionCopiesVersion() | ||
| 664 | { | ||
| 665 | HRESULT hr = S_OK; | ||
| 666 | LPCWSTR wzVersion = L"1.2.3.4+abc123"; | ||
| 667 | VERUTIL_VERSION* pSource = NULL; | ||
| 668 | VERUTIL_VERSION* pCopy = NULL; | ||
| 669 | int nResult = 0; | ||
| 670 | |||
| 671 | try | ||
| 672 | { | ||
| 673 | hr = VerParseVersion(wzVersion, 0, FALSE, &pSource); | ||
| 674 | NativeAssert::Succeeded(hr, "VerParseVersion failed"); | ||
| 675 | |||
| 676 | NativeAssert::StringEqual(wzVersion, pSource->sczVersion); | ||
| 677 | Assert::Equal<DWORD>(1, pSource->dwMajor); | ||
| 678 | Assert::Equal<DWORD>(2, pSource->dwMinor); | ||
| 679 | Assert::Equal<DWORD>(3, pSource->dwPatch); | ||
| 680 | Assert::Equal<DWORD>(4, pSource->dwRevision); | ||
| 681 | Assert::Equal<DWORD>(0, pSource->cReleaseLabels); | ||
| 682 | |||
| 683 | Assert::Equal<DWORD>(8, pSource->cchMetadataOffset); | ||
| 684 | Assert::Equal<BOOL>(FALSE, pSource->fInvalid); | ||
| 685 | |||
| 686 | hr = VerCopyVersion(pSource, &pCopy); | ||
| 687 | NativeAssert::Succeeded(hr, "VerCopyVersion failed"); | ||
| 688 | |||
| 689 | Assert::False(pSource == pCopy); | ||
| 690 | Assert::False(pSource->sczVersion == pCopy->sczVersion); | ||
| 691 | |||
| 692 | hr = VerCompareParsedVersions(pSource, pCopy, &nResult); | ||
| 693 | NativeAssert::Succeeded(hr, "VerCompareParsedVersions failed"); | ||
| 694 | |||
| 695 | Assert::Equal<int>(nResult, 0); | ||
| 696 | } | ||
| 697 | finally | ||
| 698 | { | ||
| 699 | ReleaseVerutilVersion(pCopy); | ||
| 700 | ReleaseVerutilVersion(pSource); | ||
| 701 | } | ||
| 702 | } | ||
| 703 | |||
| 704 | [Fact] | ||
| 705 | void VerCopyVersionCopiesPrereleaseVersion() | ||
| 706 | { | ||
| 707 | HRESULT hr = S_OK; | ||
| 708 | LPCWSTR wzVersion = L"1.2.3.4-a.b.c.d.5.+abc123"; | ||
| 709 | VERUTIL_VERSION* pSource = NULL; | ||
| 710 | VERUTIL_VERSION* pCopy = NULL; | ||
| 711 | int nResult = 0; | ||
| 712 | |||
| 713 | try | ||
| 714 | { | ||
| 715 | hr = VerParseVersion(wzVersion, 0, FALSE, &pSource); | ||
| 716 | NativeAssert::Succeeded(hr, "VerParseVersion failed"); | ||
| 717 | |||
| 718 | NativeAssert::StringEqual(wzVersion, pSource->sczVersion); | ||
| 719 | Assert::Equal<DWORD>(1, pSource->dwMajor); | ||
| 720 | Assert::Equal<DWORD>(2, pSource->dwMinor); | ||
| 721 | Assert::Equal<DWORD>(3, pSource->dwPatch); | ||
| 722 | Assert::Equal<DWORD>(4, pSource->dwRevision); | ||
| 723 | Assert::Equal<DWORD>(5, pSource->cReleaseLabels); | ||
| 724 | |||
| 725 | Assert::Equal<BOOL>(FALSE, pSource->rgReleaseLabels[0].fNumeric); | ||
| 726 | Assert::Equal<DWORD>(1, pSource->rgReleaseLabels[0].cchLabel); | ||
| 727 | Assert::Equal<DWORD>(8, pSource->rgReleaseLabels[0].cchLabelOffset); | ||
| 728 | |||
| 729 | Assert::Equal<BOOL>(FALSE, pSource->rgReleaseLabels[1].fNumeric); | ||
| 730 | Assert::Equal<DWORD>(1, pSource->rgReleaseLabels[1].cchLabel); | ||
| 731 | Assert::Equal<DWORD>(10, pSource->rgReleaseLabels[1].cchLabelOffset); | ||
| 732 | |||
| 733 | Assert::Equal<BOOL>(FALSE, pSource->rgReleaseLabels[2].fNumeric); | ||
| 734 | Assert::Equal<DWORD>(1, pSource->rgReleaseLabels[2].cchLabel); | ||
| 735 | Assert::Equal<DWORD>(12, pSource->rgReleaseLabels[2].cchLabelOffset); | ||
| 736 | |||
| 737 | Assert::Equal<BOOL>(FALSE, pSource->rgReleaseLabels[3].fNumeric); | ||
| 738 | Assert::Equal<DWORD>(1, pSource->rgReleaseLabels[3].cchLabel); | ||
| 739 | Assert::Equal<DWORD>(14, pSource->rgReleaseLabels[3].cchLabelOffset); | ||
| 740 | |||
| 741 | Assert::Equal<BOOL>(TRUE, pSource->rgReleaseLabels[4].fNumeric); | ||
| 742 | Assert::Equal<DWORD>(5, pSource->rgReleaseLabels[4].dwValue); | ||
| 743 | Assert::Equal<DWORD>(1, pSource->rgReleaseLabels[4].cchLabel); | ||
| 744 | Assert::Equal<DWORD>(16, pSource->rgReleaseLabels[4].cchLabelOffset); | ||
| 745 | |||
| 746 | Assert::Equal<DWORD>(18, pSource->cchMetadataOffset); | ||
| 747 | Assert::Equal<BOOL>(TRUE, pSource->fInvalid); | ||
| 748 | |||
| 749 | hr = VerCopyVersion(pSource, &pCopy); | ||
| 750 | NativeAssert::Succeeded(hr, "VerCopyVersion failed"); | ||
| 751 | |||
| 752 | Assert::False(pSource == pCopy); | ||
| 753 | Assert::False(pSource->sczVersion == pCopy->sczVersion); | ||
| 754 | Assert::False(pSource->rgReleaseLabels == pCopy->rgReleaseLabels); | ||
| 755 | |||
| 756 | hr = VerCompareParsedVersions(pSource, pCopy, &nResult); | ||
| 757 | NativeAssert::Succeeded(hr, "VerCompareParsedVersions failed"); | ||
| 758 | |||
| 759 | Assert::Equal<int>(nResult, 0); | ||
| 760 | } | ||
| 761 | finally | ||
| 762 | { | ||
| 763 | ReleaseVerutilVersion(pCopy); | ||
| 764 | ReleaseVerutilVersion(pSource); | ||
| 765 | } | ||
| 766 | } | ||
| 767 | |||
| 768 | [Fact] | ||
| 769 | void VerParseVersionTreatsTrailingDotsAsInvalid() | ||
| 770 | { | ||
| 771 | HRESULT hr = S_OK; | ||
| 772 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 773 | VERUTIL_VERSION* pVersion2 = NULL; | ||
| 774 | VERUTIL_VERSION* pVersion3 = NULL; | ||
| 775 | VERUTIL_VERSION* pVersion4 = NULL; | ||
| 776 | VERUTIL_VERSION* pVersion5 = NULL; | ||
| 777 | VERUTIL_VERSION* pVersion6 = NULL; | ||
| 778 | VERUTIL_VERSION* pVersion7 = NULL; | ||
| 779 | LPCWSTR wzVersion1 = L"."; | ||
| 780 | LPCWSTR wzVersion2 = L"1."; | ||
| 781 | LPCWSTR wzVersion3 = L"2.1."; | ||
| 782 | LPCWSTR wzVersion4 = L"3.2.1."; | ||
| 783 | LPCWSTR wzVersion5 = L"4.3.2.1."; | ||
| 784 | LPCWSTR wzVersion6 = L"5-."; | ||
| 785 | LPCWSTR wzVersion7 = L"6-a."; | ||
| 786 | |||
| 787 | try | ||
| 788 | { | ||
| 789 | hr = VerParseVersion(wzVersion1, 0, FALSE, &pVersion1); | ||
| 790 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion1); | ||
| 791 | |||
| 792 | hr = VerParseVersion(wzVersion2, 0, FALSE, &pVersion2); | ||
| 793 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion2); | ||
| 794 | |||
| 795 | hr = VerParseVersion(wzVersion3, 0, FALSE, &pVersion3); | ||
| 796 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion3); | ||
| 797 | |||
| 798 | hr = VerParseVersion(wzVersion4, 0, FALSE, &pVersion4); | ||
| 799 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion4); | ||
| 800 | |||
| 801 | hr = VerParseVersion(wzVersion5, 0, FALSE, &pVersion5); | ||
| 802 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion5); | ||
| 803 | |||
| 804 | hr = VerParseVersion(wzVersion6, 0, FALSE, &pVersion6); | ||
| 805 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion6); | ||
| 806 | |||
| 807 | hr = VerParseVersion(wzVersion7, 0, FALSE, &pVersion7); | ||
| 808 | NativeAssert::Succeeded(hr, "Failed to parse version '{0}'", wzVersion7); | ||
| 809 | |||
| 810 | NativeAssert::StringEqual(wzVersion1, pVersion1->sczVersion); | ||
| 811 | Assert::Equal<DWORD>(0, pVersion1->dwMajor); | ||
| 812 | Assert::Equal<DWORD>(0, pVersion1->dwMinor); | ||
| 813 | Assert::Equal<DWORD>(0, pVersion1->dwPatch); | ||
| 814 | Assert::Equal<DWORD>(0, pVersion1->dwRevision); | ||
| 815 | Assert::Equal<DWORD>(0, pVersion1->cReleaseLabels); | ||
| 816 | Assert::Equal<DWORD>(0, pVersion1->cchMetadataOffset); | ||
| 817 | Assert::Equal<BOOL>(TRUE, pVersion1->fInvalid); | ||
| 818 | |||
| 819 | NativeAssert::StringEqual(wzVersion2, pVersion2->sczVersion); | ||
| 820 | Assert::Equal<DWORD>(1, pVersion2->dwMajor); | ||
| 821 | Assert::Equal<DWORD>(0, pVersion2->dwMinor); | ||
| 822 | Assert::Equal<DWORD>(0, pVersion2->dwPatch); | ||
| 823 | Assert::Equal<DWORD>(0, pVersion2->dwRevision); | ||
| 824 | Assert::Equal<DWORD>(0, pVersion2->cReleaseLabels); | ||
| 825 | Assert::Equal<DWORD>(2, pVersion2->cchMetadataOffset); | ||
| 826 | Assert::Equal<BOOL>(TRUE, pVersion2->fInvalid); | ||
| 827 | |||
| 828 | NativeAssert::StringEqual(wzVersion3, pVersion3->sczVersion); | ||
| 829 | Assert::Equal<DWORD>(2, pVersion3->dwMajor); | ||
| 830 | Assert::Equal<DWORD>(1, pVersion3->dwMinor); | ||
| 831 | Assert::Equal<DWORD>(0, pVersion3->dwPatch); | ||
| 832 | Assert::Equal<DWORD>(0, pVersion3->dwRevision); | ||
| 833 | Assert::Equal<DWORD>(0, pVersion3->cReleaseLabels); | ||
| 834 | Assert::Equal<DWORD>(4, pVersion3->cchMetadataOffset); | ||
| 835 | Assert::Equal<BOOL>(TRUE, pVersion3->fInvalid); | ||
| 836 | |||
| 837 | NativeAssert::StringEqual(wzVersion4, pVersion4->sczVersion); | ||
| 838 | Assert::Equal<DWORD>(3, pVersion4->dwMajor); | ||
| 839 | Assert::Equal<DWORD>(2, pVersion4->dwMinor); | ||
| 840 | Assert::Equal<DWORD>(1, pVersion4->dwPatch); | ||
| 841 | Assert::Equal<DWORD>(0, pVersion4->dwRevision); | ||
| 842 | Assert::Equal<DWORD>(0, pVersion4->cReleaseLabels); | ||
| 843 | Assert::Equal<DWORD>(6, pVersion4->cchMetadataOffset); | ||
| 844 | Assert::Equal<BOOL>(TRUE, pVersion4->fInvalid); | ||
| 845 | |||
| 846 | NativeAssert::StringEqual(wzVersion5, pVersion5->sczVersion); | ||
| 847 | Assert::Equal<DWORD>(4, pVersion5->dwMajor); | ||
| 848 | Assert::Equal<DWORD>(3, pVersion5->dwMinor); | ||
| 849 | Assert::Equal<DWORD>(2, pVersion5->dwPatch); | ||
| 850 | Assert::Equal<DWORD>(1, pVersion5->dwRevision); | ||
| 851 | Assert::Equal<DWORD>(0, pVersion5->cReleaseLabels); | ||
| 852 | Assert::Equal<DWORD>(8, pVersion5->cchMetadataOffset); | ||
| 853 | Assert::Equal<BOOL>(TRUE, pVersion5->fInvalid); | ||
| 854 | |||
| 855 | NativeAssert::StringEqual(wzVersion6, pVersion6->sczVersion); | ||
| 856 | Assert::Equal<DWORD>(5, pVersion6->dwMajor); | ||
| 857 | Assert::Equal<DWORD>(0, pVersion6->dwMinor); | ||
| 858 | Assert::Equal<DWORD>(0, pVersion6->dwPatch); | ||
| 859 | Assert::Equal<DWORD>(0, pVersion6->dwRevision); | ||
| 860 | Assert::Equal<DWORD>(0, pVersion6->cReleaseLabels); | ||
| 861 | Assert::Equal<DWORD>(2, pVersion6->cchMetadataOffset); | ||
| 862 | Assert::Equal<BOOL>(TRUE, pVersion6->fInvalid); | ||
| 863 | |||
| 864 | NativeAssert::StringEqual(wzVersion7, pVersion7->sczVersion); | ||
| 865 | Assert::Equal<DWORD>(6, pVersion7->dwMajor); | ||
| 866 | Assert::Equal<DWORD>(0, pVersion7->dwMinor); | ||
| 867 | Assert::Equal<DWORD>(0, pVersion7->dwPatch); | ||
| 868 | Assert::Equal<DWORD>(0, pVersion7->dwRevision); | ||
| 869 | Assert::Equal<DWORD>(1, pVersion7->cReleaseLabels); | ||
| 870 | |||
| 871 | Assert::Equal<BOOL>(FALSE, pVersion7->rgReleaseLabels[0].fNumeric); | ||
| 872 | Assert::Equal<DWORD>(1, pVersion7->rgReleaseLabels[0].cchLabel); | ||
| 873 | Assert::Equal<DWORD>(2, pVersion7->rgReleaseLabels[0].cchLabelOffset); | ||
| 874 | |||
| 875 | Assert::Equal<DWORD>(4, pVersion7->cchMetadataOffset); | ||
| 876 | Assert::Equal<BOOL>(TRUE, pVersion7->fInvalid); | ||
| 877 | } | ||
| 878 | finally | ||
| 879 | { | ||
| 880 | ReleaseVerutilVersion(pVersion1); | ||
| 881 | ReleaseVerutilVersion(pVersion2); | ||
| 882 | ReleaseVerutilVersion(pVersion3); | ||
| 883 | ReleaseVerutilVersion(pVersion4); | ||
| 884 | ReleaseVerutilVersion(pVersion5); | ||
| 885 | ReleaseVerutilVersion(pVersion6); | ||
| 886 | ReleaseVerutilVersion(pVersion7); | ||
| 887 | } | ||
| 888 | } | ||
| 889 | |||
| 890 | [Fact] | ||
| 891 | void VerVersionFromQwordCreatesVersion() | ||
| 892 | { | ||
| 893 | HRESULT hr = S_OK; | ||
| 894 | VERUTIL_VERSION* pVersion1 = NULL; | ||
| 895 | |||
| 896 | try | ||
| 897 | { | ||
| 898 | hr = VerVersionFromQword(MAKEQWORDVERSION(1, 2, 3, 4), &pVersion1); | ||
| 899 | NativeAssert::Succeeded(hr, "VerVersionFromQword failed"); | ||
| 900 | |||
| 901 | NativeAssert::StringEqual(L"1.2.3.4", pVersion1->sczVersion); | ||
| 902 | Assert::Equal<DWORD>(1, pVersion1->dwMajor); | ||
| 903 | Assert::Equal<DWORD>(2, pVersion1->dwMinor); | ||
| 904 | Assert::Equal<DWORD>(3, pVersion1->dwPatch); | ||
| 905 | Assert::Equal<DWORD>(4, pVersion1->dwRevision); | ||
| 906 | Assert::Equal<DWORD>(0, pVersion1->cReleaseLabels); | ||
| 907 | Assert::Equal<DWORD>(7, pVersion1->cchMetadataOffset); | ||
| 908 | Assert::Equal<BOOL>(FALSE, pVersion1->fInvalid); | ||
| 909 | } | ||
| 910 | finally | ||
| 911 | { | ||
| 912 | ReleaseVerutilVersion(pVersion1); | ||
| 913 | } | ||
| 914 | } | ||
| 915 | |||
| 916 | private: | ||
| 917 | void TestVerutilCompareParsedVersions(VERUTIL_VERSION* pVersion1, VERUTIL_VERSION* pVersion2, int nExpectedResult) | ||
| 918 | { | ||
| 919 | HRESULT hr = S_OK; | ||
| 920 | int nResult = 0; | ||
| 921 | |||
| 922 | hr = VerCompareParsedVersions(pVersion1, pVersion2, &nResult); | ||
| 923 | NativeAssert::Succeeded(hr, "Failed to compare versions '{0}' and '{1}'", pVersion1->sczVersion, pVersion2->sczVersion); | ||
| 924 | |||
| 925 | Assert::Equal(nExpectedResult, nResult); | ||
| 926 | |||
| 927 | hr = VerCompareParsedVersions(pVersion2, pVersion1, &nResult); | ||
| 928 | NativeAssert::Succeeded(hr, "Failed to compare versions '{0}' and '{1}'", pVersion1->sczVersion, pVersion2->sczVersion); | ||
| 929 | |||
| 930 | Assert::Equal(nExpectedResult, -nResult); | ||
| 931 | } | ||
| 932 | }; | ||
| 933 | } | ||
diff --git a/src/test/DUtilUnitTest/error.cpp b/src/test/DUtilUnitTest/error.cpp deleted file mode 100644 index e51971c3..00000000 --- a/src/test/DUtilUnitTest/error.cpp +++ /dev/null | |||
| @@ -1,26 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | const int ERROR_STRING_BUFFER = 1024; | ||
| 6 | |||
| 7 | static char szMsg[ERROR_STRING_BUFFER]; | ||
| 8 | static WCHAR wzMsg[ERROR_STRING_BUFFER]; | ||
| 9 | |||
| 10 | void CALLBACK DutilTestTraceError( | ||
| 11 | __in_z LPCSTR /*szFile*/, | ||
| 12 | __in int /*iLine*/, | ||
| 13 | __in REPORT_LEVEL /*rl*/, | ||
| 14 | __in UINT source, | ||
| 15 | __in HRESULT hrError, | ||
| 16 | __in_z __format_string LPCSTR szFormat, | ||
| 17 | __in va_list args | ||
| 18 | ) | ||
| 19 | { | ||
| 20 | if (DUTIL_SOURCE_EXTERNAL == source) | ||
| 21 | { | ||
| 22 | ::StringCchPrintfA(szMsg, countof(szMsg), szFormat, args); | ||
| 23 | MultiByteToWideChar(CP_ACP, 0, szMsg, -1, wzMsg, countof(wzMsg)); | ||
| 24 | throw gcnew System::Exception(System::String::Format("hr = 0x{0:X8}, message = {1}", hrError, gcnew System::String(wzMsg))); | ||
| 25 | } | ||
| 26 | } | ||
diff --git a/src/test/DUtilUnitTest/error.h b/src/test/DUtilUnitTest/error.h deleted file mode 100644 index b973acaf..00000000 --- a/src/test/DUtilUnitTest/error.h +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | #pragma once | ||
| 2 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 3 | |||
| 4 | #define DUTIL_SOURCE_DEFAULT DUTIL_SOURCE_EXTERNAL | ||
| 5 | |||
| 6 | void CALLBACK DutilTestTraceError( | ||
| 7 | __in_z LPCSTR szFile, | ||
| 8 | __in int iLine, | ||
| 9 | __in REPORT_LEVEL rl, | ||
| 10 | __in UINT source, | ||
| 11 | __in HRESULT hrError, | ||
| 12 | __in_z __format_string LPCSTR szFormat, | ||
| 13 | __in va_list args | ||
| 14 | ); | ||
diff --git a/src/test/DUtilUnitTest/packages.config b/src/test/DUtilUnitTest/packages.config deleted file mode 100644 index a4fef2bf..00000000 --- a/src/test/DUtilUnitTest/packages.config +++ /dev/null | |||
| @@ -1,13 +0,0 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 3 | <packages> | ||
| 4 | <package id="xunit.abstractions" version="2.0.3" /> | ||
| 5 | <package id="xunit.assert" version="2.4.1" /> | ||
| 6 | <package id="xunit.core" version="2.4.1" /> | ||
| 7 | <package id="xunit.extensibility.core" version="2.4.1" /> | ||
| 8 | <package id="xunit.extensibility.execution" version="2.4.1" /> | ||
| 9 | <package id="xunit.runner.msbuild" version="2.4.1" /> | ||
| 10 | <package id="xunit.runner.visualstudio" version="2.4.1" /> | ||
| 11 | <package id="WixBuildTools.TestSupport" version="4.0.47" /> | ||
| 12 | <package id="WixBuildTools.TestSupport.Native" version="4.0.47" /> | ||
| 13 | </packages> \ No newline at end of file | ||
diff --git a/src/test/DUtilUnitTest/precomp.cpp b/src/test/DUtilUnitTest/precomp.cpp deleted file mode 100644 index 37664a1c..00000000 --- a/src/test/DUtilUnitTest/precomp.cpp +++ /dev/null | |||
| @@ -1,3 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
diff --git a/src/test/DUtilUnitTest/precomp.h b/src/test/DUtilUnitTest/precomp.h deleted file mode 100644 index e9f8770b..00000000 --- a/src/test/DUtilUnitTest/precomp.h +++ /dev/null | |||
| @@ -1,32 +0,0 @@ | |||
| 1 | #pragma once | ||
| 2 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 3 | |||
| 4 | |||
| 5 | #include <windows.h> | ||
| 6 | #include <strsafe.h> | ||
| 7 | #include <ShlObj.h> | ||
| 8 | |||
| 9 | // Include error.h before dutil.h | ||
| 10 | #include <dutilsources.h> | ||
| 11 | #include "error.h" | ||
| 12 | #include <dutil.h> | ||
| 13 | |||
| 14 | #include <verutil.h> | ||
| 15 | #include <atomutil.h> | ||
| 16 | #include <dictutil.h> | ||
| 17 | #include <dirutil.h> | ||
| 18 | #include <fileutil.h> | ||
| 19 | #include <guidutil.h> | ||
| 20 | #include <iniutil.h> | ||
| 21 | #include <memutil.h> | ||
| 22 | #include <pathutil.h> | ||
| 23 | #include <strutil.h> | ||
| 24 | #include <monutil.h> | ||
| 25 | #include <regutil.h> | ||
| 26 | #include <rssutil.h> | ||
| 27 | #include <apuputil.h> // NOTE: this must come after atomutil.h and rssutil.h since it uses them. | ||
| 28 | #include <uriutil.h> | ||
| 29 | #include <xmlutil.h> | ||
| 30 | |||
| 31 | #pragma managed | ||
| 32 | #include <vcclr.h> | ||
diff --git a/src/test/DUtilUnitTest/resource.h b/src/test/DUtilUnitTest/resource.h deleted file mode 100644 index bdf252f6..00000000 --- a/src/test/DUtilUnitTest/resource.h +++ /dev/null | |||
| @@ -1,2 +0,0 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
