Skip to content

Commit 28f733a

Browse files
committed
[UNITTESTS][PATHCCH] Add unit compilation-tests for the pathcch library (reactos#8085)
CORE-12686 Test the following compilation scenarii: - using the `pathcch_static` library (function implementations statically linked into the test); - using the `pathcch_kernelbase` library (linking directly to kernelbase.dll); - using the `pathcch` MS PSDK-compatible library (linking to the api-ms-win-core-path-l1-1-0.dll APISET dll).
1 parent db96138 commit 28f733a

File tree

7 files changed

+306
-0
lines changed

7 files changed

+306
-0
lines changed

modules/rostests/unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ add_subdirectory(interop)
33
if(ISAPNP_ENABLE)
44
add_subdirectory(isapnp)
55
endif()
6+
add_subdirectory(pathcch)
67
add_subdirectory(setuplib)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
include_directories(
3+
${REACTOS_SOURCE_DIR}/modules/rostests/apitests/include)
4+
5+
list(APPEND SOURCE
6+
pathcch_compile.c
7+
pathcch_compile.cpp
8+
precomp.h)
9+
10+
list(APPEND PCH_SKIP_SOURCE
11+
testlist.c)
12+
13+
add_executable(pathcch_static_unittest ${SOURCE} ${PCH_SKIP_SOURCE})
14+
add_pch(pathcch_static_unittest precomp.h ${PCH_SKIP_SOURCE})
15+
target_compile_definitions(pathcch_static_unittest PRIVATE STATIC_PATHCCH)
16+
set_module_type(pathcch_static_unittest win32cui)
17+
add_dependencies(pathcch_static_unittest psdk)
18+
target_link_libraries(pathcch_static_unittest pathcch_static)
19+
add_importlibs(pathcch_static_unittest msvcrt kernel32 ntdll)
20+
add_rostests_file(TARGET pathcch_static_unittest)
21+
22+
add_executable(pathcch_dyn1_unittest ${SOURCE} ${PCH_SKIP_SOURCE})
23+
add_pch(pathcch_dyn1_unittest precomp.h ${PCH_SKIP_SOURCE})
24+
set_module_type(pathcch_dyn1_unittest win32cui)
25+
add_dependencies(pathcch_dyn1_unittest psdk)
26+
target_link_libraries(pathcch_dyn1_unittest pathcch_kernelbase)
27+
add_importlibs(pathcch_dyn1_unittest msvcrt kernel32 ntdll)
28+
## add_rostests_file(TARGET pathcch_dyn1_unittest) ## TODO: Requires kernelbase.dll to be compiled
29+
30+
add_executable(pathcch_dyn2_unittest ${SOURCE} ${PCH_SKIP_SOURCE})
31+
add_pch(pathcch_dyn2_unittest precomp.h ${PCH_SKIP_SOURCE})
32+
set_module_type(pathcch_dyn2_unittest win32cui)
33+
add_dependencies(pathcch_dyn2_unittest psdk)
34+
target_link_libraries(pathcch_dyn2_unittest pathcch)
35+
add_importlibs(pathcch_dyn2_unittest msvcrt kernel32 ntdll)
36+
## add_rostests_file(TARGET pathcch_dyn2_unittest) ## TODO: Requires api-ms-win-core-path-l1-1-0.dll
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* PROJECT: ReactOS PathCch Library - Unit-tests
3+
* LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4+
* PURPOSE: C compilation tests
5+
* COPYRIGHT: Copyright 2025 Hermès Bélusca-Maïto <[email protected]>
6+
*/
7+
8+
#include "precomp.h"
9+
10+
#include "pathcch_compile.inc"
11+
12+
// See pathcch_compile.cpp
13+
extern void test_CPP_PathCch(void);
14+
15+
START_TEST(PathCchCompileTest)
16+
{
17+
test_C_PathCch();
18+
test_CPP_PathCch();
19+
}
20+
21+
/* EOF */
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* PROJECT: ReactOS PathCch Library - Unit-tests
3+
* LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4+
* PURPOSE: C++ compilation tests
5+
* COPYRIGHT: Copyright 2025 Hermès Bélusca-Maïto <[email protected]>
6+
*/
7+
8+
#include "precomp.h"
9+
10+
#include "pathcch_compile.inc"
11+
12+
/* EOF */
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
* PROJECT: ReactOS PathCch Library - Unit-tests
3+
* LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4+
* PURPOSE: C/C++ compilation tests
5+
* COPYRIGHT: Copyright 2025 Hermès Bélusca-Maïto <[email protected]>
6+
*
7+
* REMARKS:
8+
* The purpose of these tests is to verify that the PathCch* functions can
9+
* be used either via static linking, or dynamic linking, in both C and C++
10+
* languages. Thus, only minimal testing of functionality is done here.
11+
*/
12+
13+
#ifdef __cplusplus
14+
extern "C"
15+
void test_CPP_PathCch(void)
16+
#else
17+
void test_C_PathCch(void)
18+
#endif
19+
{
20+
const WCHAR szTestPath[] = L"C:\\ReactOS\\System32\\dllcache\\..\\..\\..\\freeldr.ini";
21+
const WCHAR szCanonPath[] = L"C:\\freeldr.ini";
22+
const WCHAR szExtraPath0[] = L"C:\\ReactOS\\System32";
23+
const WCHAR szExtraPath1[] = L"C:\\ReactOS\\System32\\";
24+
const WCHAR szExtraPath2[] = L"\\dllcache\\..\\..\\..\\freeldr.ini";
25+
const WCHAR szUNCPath[] = L"\\\\?\\UNC\\ReactOS_Server\\Root\\freeldr.ini";
26+
27+
HRESULT hr;
28+
BOOL res;
29+
#ifdef __cplusplus
30+
PWSTR psz;
31+
#endif
32+
PCWSTR pcsz;
33+
PWSTR pszPathOut;
34+
WCHAR szPathOut[MAX_PATH];
35+
36+
pszPathOut = NULL;
37+
hr = PathAllocCanonicalize(szTestPath, PATHCCH_NONE, &pszPathOut);
38+
ok_hr(hr, S_OK);
39+
ok(pszPathOut != NULL, "pszPathOut is NULL\n");
40+
ok_wstr(pszPathOut, szCanonPath);
41+
LocalFree(pszPathOut);
42+
43+
*szPathOut = UNICODE_NULL;
44+
hr = PathCchCanonicalize(szPathOut, _countof(szPathOut), szTestPath);
45+
ok_hr(hr, S_OK);
46+
ok_wstr(szPathOut, szCanonPath);
47+
48+
*szPathOut = UNICODE_NULL;
49+
hr = PathCchCanonicalizeEx(szPathOut, _countof(szPathOut), szTestPath, PATHCCH_NONE);
50+
ok_hr(hr, S_OK);
51+
ok_wstr(szPathOut, szCanonPath);
52+
53+
pszPathOut = NULL;
54+
hr = PathAllocCombine(szExtraPath1, szExtraPath2, PATHCCH_NONE, &pszPathOut);
55+
ok_hr(hr, S_OK);
56+
ok(pszPathOut != NULL, "pszPathOut is NULL\n");
57+
ok_wstr(pszPathOut, szCanonPath);
58+
LocalFree(pszPathOut);
59+
60+
*szPathOut = UNICODE_NULL;
61+
hr = PathCchCombine(szPathOut, _countof(szPathOut), szExtraPath1, szExtraPath2);
62+
ok_hr(hr, S_OK);
63+
ok_wstr(szPathOut, szCanonPath);
64+
65+
*szPathOut = UNICODE_NULL;
66+
hr = PathCchCombineEx(szPathOut, _countof(szPathOut), szExtraPath1, szExtraPath2, PATHCCH_NONE);
67+
ok_hr(hr, S_OK);
68+
ok_wstr(szPathOut, szCanonPath);
69+
70+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), szExtraPath0);
71+
ok_hr(hr, S_OK);
72+
hr = PathCchAddBackslash(szPathOut, _countof(szPathOut));
73+
ok_hr(hr, S_OK);
74+
ok_wstr(szPathOut, szExtraPath1);
75+
76+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), szExtraPath0);
77+
ok_hr(hr, S_OK);
78+
hr = PathCchAddBackslashEx(szPathOut, _countof(szPathOut), NULL, NULL);
79+
ok_hr(hr, S_OK);
80+
ok_wstr(szPathOut, szExtraPath1);
81+
82+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), L"C:\\freeldr");
83+
ok_hr(hr, S_OK);
84+
hr = PathCchAddExtension(szPathOut, _countof(szPathOut), L"ini"); // The extension period is added if needed.
85+
ok_hr(hr, S_OK);
86+
ok_wstr(szPathOut, szCanonPath);
87+
88+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), szExtraPath1);
89+
ok_hr(hr, S_OK);
90+
hr = PathCchAppend(szPathOut, _countof(szPathOut), szExtraPath2);
91+
ok_hr(hr, S_OK);
92+
ok_wstr(szPathOut, szCanonPath);
93+
94+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), szExtraPath1);
95+
ok_hr(hr, S_OK);
96+
hr = PathCchAppendEx(szPathOut, _countof(szPathOut), szExtraPath2, PATHCCH_NONE);
97+
ok_hr(hr, S_OK);
98+
ok_wstr(szPathOut, szCanonPath);
99+
100+
#ifdef __cplusplus // Won't compile in C; is OK in C++
101+
psz = NULL;
102+
hr = PathCchFindExtension(const_cast<PWSTR>(szCanonPath), _countof(szCanonPath), &psz);
103+
ok_hr(hr, S_OK);
104+
ok_ptr(psz, &szCanonPath[10]);
105+
#endif
106+
pcsz = NULL;
107+
hr = PathCchFindExtension(szCanonPath, _countof(szCanonPath), &pcsz);
108+
ok_hr(hr, S_OK);
109+
ok_ptr(pcsz, &szCanonPath[10]);
110+
111+
res = PathCchIsRoot(szCanonPath);
112+
ok_bool_false(res, "PathCchIsRoot returned");
113+
res = PathCchIsRoot(L"C:\\");
114+
ok_bool_true(res, "PathCchIsRoot returned");
115+
116+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), szExtraPath1);
117+
ok_hr(hr, S_OK);
118+
hr = PathCchRemoveBackslash(szPathOut, _countof(szPathOut));
119+
ok_hr(hr, S_OK);
120+
ok_wstr(szPathOut, szExtraPath0);
121+
122+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), szExtraPath1);
123+
ok_hr(hr, S_OK);
124+
hr = PathCchRemoveBackslashEx(szPathOut, _countof(szPathOut), NULL, NULL);
125+
ok_hr(hr, S_OK);
126+
ok_wstr(szPathOut, szExtraPath0);
127+
128+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), szCanonPath);
129+
ok_hr(hr, S_OK);
130+
hr = PathCchRemoveExtension(szPathOut, _countof(szPathOut));
131+
ok_hr(hr, S_OK);
132+
ok_wstr(szPathOut, L"C:\\freeldr");
133+
134+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), szCanonPath);
135+
ok_hr(hr, S_OK);
136+
hr = PathCchRemoveFileSpec(szPathOut, _countof(szPathOut));
137+
ok_hr(hr, S_OK);
138+
ok_wstr(szPathOut, L"C:\\");
139+
140+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), szCanonPath);
141+
ok_hr(hr, S_OK);
142+
hr = PathCchRenameExtension(szPathOut, _countof(szPathOut), L"txt"); // The extension period is added if needed.
143+
ok_hr(hr, S_OK);
144+
ok_wstr(szPathOut, L"C:\\freeldr.txt");
145+
146+
#ifdef __cplusplus // Won't compile in C; is OK in C++
147+
psz = NULL;
148+
hr = PathCchSkipRoot(const_cast<PWSTR>(szCanonPath), &psz);
149+
ok_hr(hr, S_OK);
150+
ok_ptr(psz, &szCanonPath[3]);
151+
#endif
152+
pcsz = NULL;
153+
hr = PathCchSkipRoot(szCanonPath, &pcsz);
154+
ok_hr(hr, S_OK);
155+
ok_ptr(pcsz, &szCanonPath[3]);
156+
157+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), L"\\\\?\\"); // Prefix to test its removal.
158+
ok_hr(hr, S_OK);
159+
hr = StringCchCatW(szPathOut, _countof(szPathOut), szCanonPath);
160+
ok_hr(hr, S_OK);
161+
hr = PathCchStripPrefix(szPathOut, _countof(szPathOut));
162+
ok_hr(hr, S_OK);
163+
ok_wstr(szPathOut, szCanonPath);
164+
165+
hr = StringCchCopyW(szPathOut, _countof(szPathOut), szTestPath);
166+
ok_hr(hr, S_OK);
167+
hr = PathCchStripToRoot(szPathOut, _countof(szPathOut));
168+
ok_hr(hr, S_OK);
169+
ok_wstr(szPathOut, L"C:\\");
170+
171+
#ifdef __cplusplus // Won't compile in C; is OK in C++
172+
psz = NULL;
173+
res = PathIsUNCEx(const_cast<PWSTR>(szCanonPath), &psz);
174+
ok_bool_false(res, "PathIsUNCEx returned");
175+
ok_ptr(psz, NULL);
176+
177+
psz = NULL;
178+
res = PathIsUNCEx(const_cast<PWSTR>(szUNCPath), &psz);
179+
ok_bool_true(res, "PathIsUNCEx returned");
180+
ok_ptr(psz, &szUNCPath[8]);
181+
#endif
182+
pcsz = NULL;
183+
res = PathIsUNCEx(szCanonPath, &pcsz);
184+
ok_bool_false(res, "PathIsUNCEx returned");
185+
ok_ptr(pcsz, NULL);
186+
187+
pcsz = NULL;
188+
res = PathIsUNCEx(szUNCPath, &pcsz);
189+
ok_bool_true(res, "PathIsUNCEx returned");
190+
ok_ptr(pcsz, &szUNCPath[8]);
191+
}
192+
193+
/* EOF */
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* PROJECT: ReactOS PathCch Library - Unit-tests
3+
* LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4+
* PURPOSE: Precompiled header
5+
* COPYRIGHT: Copyright 2025 Hermès Bélusca-Maïto <[email protected]>
6+
*/
7+
8+
#pragma once
9+
10+
#include <apitest.h>
11+
12+
/* C Headers */
13+
#include <stdio.h>
14+
15+
/* PSDK Headers */
16+
#define WIN32_NO_STATUS
17+
#define _INC_WINDOWS
18+
#define COM_NO_WINDOWS_H
19+
20+
#include <windef.h>
21+
#include <winbase.h>
22+
23+
#include <strsafe.h>
24+
#include <pathcch.h>
25+
26+
/* EOF */
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* PROJECT: ReactOS PathCch Library - Unit-tests
3+
* LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4+
* PURPOSE: List of tests
5+
* COPYRIGHT: Copyright 2025 Hermès Bélusca-Maïto <[email protected]>
6+
*/
7+
8+
#define STANDALONE
9+
#include <apitest.h>
10+
11+
extern void func_PathCchCompileTest(void);
12+
13+
const struct test winetest_testlist[] =
14+
{
15+
{ "PathCchCompileTest", func_PathCchCompileTest },
16+
{ 0, 0 }
17+
};

0 commit comments

Comments
 (0)