1 /*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for Int64ToString
5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8 #include "shelltest.h"
9 #include <undocshell.h>
10 #include <versionhelpers.h>
11
12 typedef struct tagTEST_RETURN
13 {
14 INT ret;
15 LPCWSTR text;
16 } TEST_RETURN, *PTEST_RETURN;
17
18 typedef struct tagTEST_ENTRY
19 {
20 INT lineno;
21 LONGLONG value;
22
23 UINT NumDigits;
24 UINT LeadingZero;
25 UINT Grouping;
26 LPCWSTR pszDecimalSep;
27 LPCWSTR pszThousandSep;
28 UINT NegativeOrder;
29
30 TEST_RETURN NonVista;
31 TEST_RETURN Vista;
32 } TEST_ENTRY, *PTEST_ENTRY;
33
34 #define DATA0 2, FALSE, 3, L".", L",", 0
35 #define DATA1 3, TRUE, 3, L"<>", L":", 1
36
37 static const TEST_ENTRY s_Entries[] =
38 {
39 { __LINE__, 0, DATA0, { 3, L".00" }, { 3, L".00" } },
40 { __LINE__, 0, DATA1, { 6, L"0<>000" }, { 6, L"0<>000" } },
41 { __LINE__, 1, DATA0, { 4, L"1.00" }, { 4, L"1.00" } },
42 { __LINE__, 1, DATA1, { 6, L"1<>000" }, { 6, L"1<>000" } },
43 { __LINE__, -999, DATA0, { 0, L"#####" }, { 8, L"(999.00)" } },
44 { __LINE__, -999, DATA1, { 0, L"#####" }, { 9, L"-999<>000" } },
45 { __LINE__, 100000, DATA0, { 10, L"100,000.00" }, { 10, L"100,000.00" } },
46 { __LINE__, 100000, DATA1, { 12, L"100:000<>000" }, { 12, L"100:000<>000" } },
47 { __LINE__, 0xE8D4A51000LL, DATA0, { 20, L"1,000,000,000,000.00" }, { 20, L"1,000,000,000,000.00" } },
48 { __LINE__, 0xE8D4A51000LL, DATA1, { 22, L"1:000:000:000:000<>000" }, { 22, L"1:000:000:000:000<>000" } },
49 { __LINE__, 0x7FFFFFFFFFFFFFFFLL, DATA0, { 28, L"9,223,372,036,854,775,807.00" }, { 28, L"9,223,372,036,854,775,807.00" } },
50 { __LINE__, 0x7FFFFFFFFFFFFFFFLL, DATA1, { 30, L"9:223:372:036:854:775:807<>000" }, { 30, L"9:223:372:036:854:775:807<>000" } },
51 };
52 static const SIZE_T s_cEntries = _countof(s_Entries);
53
DoTestEntry(BOOL bVista,const TEST_ENTRY * pEntry)54 static void DoTestEntry(BOOL bVista, const TEST_ENTRY *pEntry)
55 {
56 INT lineno = pEntry->lineno;
57
58 WCHAR szDecimalSep[10], szThousandSep[10];
59 lstrcpynW(szDecimalSep, pEntry->pszDecimalSep, _countof(szDecimalSep));
60 lstrcpynW(szThousandSep, pEntry->pszThousandSep, _countof(szThousandSep));
61
62 NUMBERFMTW format =
63 {
64 pEntry->NumDigits, pEntry->LeadingZero, pEntry->Grouping,
65 szDecimalSep, szThousandSep, pEntry->NegativeOrder
66 };
67
68 WCHAR szBuff[64];
69 lstrcpynW(szBuff, L"#####", _countof(szBuff));
70
71 INT ret = Int64ToString(pEntry->value, szBuff, _countof(szBuff), TRUE, &format, -1);
72 if (bVista)
73 {
74 ok(pEntry->Vista.ret == ret, "Line %d: %d vs %d\n", lineno, pEntry->Vista.ret, ret);
75 ok(lstrcmpW(pEntry->Vista.text, szBuff) == 0, "Line %d: %ls vs %ls\n",
76 lineno, pEntry->Vista.text, szBuff);
77 }
78 else
79 {
80 ok(pEntry->NonVista.ret == ret, "Line %d: %d vs %d\n", lineno, pEntry->NonVista.ret, ret);
81 ok(lstrcmpW(pEntry->NonVista.text, szBuff) == 0, "Line %d: %ls vs %ls\n",
82 lineno, pEntry->NonVista.text, szBuff);
83 }
84
85 lstrcpynW(szBuff, L"#####", _countof(szBuff));
86
87 LARGE_INTEGER LInt;
88 LInt.QuadPart = pEntry->value;
89 ret = LargeIntegerToString(&LInt, szBuff, _countof(szBuff), TRUE, &format, -1);
90 if (bVista)
91 {
92 ok(pEntry->Vista.ret == ret, "Line %d: %d vs %d\n", lineno, pEntry->Vista.ret, ret);
93 ok(lstrcmpW(pEntry->Vista.text, szBuff) == 0, "Line %d: %ls vs %ls\n",
94 lineno, pEntry->Vista.text, szBuff);
95 }
96 else
97 {
98 ok(pEntry->NonVista.ret == ret, "Line %d: %d vs %d\n", lineno, pEntry->NonVista.ret, ret);
99 ok(lstrcmpW(pEntry->NonVista.text, szBuff) == 0, "Line %d: %ls vs %ls\n",
100 lineno, pEntry->NonVista.text, szBuff);
101 }
102 }
103
Test_EntryTest(BOOL bVista)104 static void Test_EntryTest(BOOL bVista)
105 {
106 for (SIZE_T i = 0; i < s_cEntries; ++i)
107 {
108 DoTestEntry(bVista, &s_Entries[i]);
109 }
110 }
111
Test_Int64ToString(BOOL bVista)112 static void Test_Int64ToString(BOOL bVista)
113 {
114 WCHAR szBuff[64];
115 INT ret;
116
117 ret = Int64ToString(0, szBuff, _countof(szBuff), FALSE, NULL, 0);
118 ok_int(ret, 1);
119 ok_wstr(szBuff, L"0");
120
121 ret = Int64ToString(1, szBuff, _countof(szBuff), FALSE, NULL, 0);
122 ok_int(ret, 1);
123 ok_wstr(szBuff, L"1");
124
125 ret = Int64ToString(-9999, szBuff, _countof(szBuff), FALSE, NULL, 0);
126 if (bVista)
127 {
128 ok_int(ret, 5);
129 ok_wstr(szBuff, L"-9999");
130 }
131 else
132 {
133 ok_int(ret, 4);
134 ok_wstr(szBuff, L"''''");
135 }
136
137 ret = Int64ToString(10000, szBuff, _countof(szBuff), FALSE, NULL, 0);
138 ok_int(ret, 5);
139 ok_wstr(szBuff, L"10000");
140
141 ret = Int64ToString(0xE8D4A51000LL, szBuff, _countof(szBuff), FALSE, NULL, 0);
142 ok_int(ret, 13);
143 ok_wstr(szBuff, L"1000000000000");
144 }
145
Test_LargeIntegerToString(BOOL bVista)146 static void Test_LargeIntegerToString(BOOL bVista)
147 {
148 LARGE_INTEGER LInt;
149 WCHAR szBuff[64];
150 INT ret;
151
152 LInt.QuadPart = 0;
153 ret = LargeIntegerToString(&LInt, szBuff, _countof(szBuff), FALSE, NULL, 0);
154 ok_int(ret, 1);
155 ok_wstr(szBuff, L"0");
156
157 LInt.QuadPart = 1;
158 ret = LargeIntegerToString(&LInt, szBuff, _countof(szBuff), FALSE, NULL, 0);
159 ok_int(ret, 1);
160 ok_wstr(szBuff, L"1");
161
162 LInt.QuadPart = -9999;
163 ret = LargeIntegerToString(&LInt, szBuff, _countof(szBuff), FALSE, NULL, 0);
164 if (bVista)
165 {
166 ok_int(ret, 5);
167 ok_wstr(szBuff, L"-9999");
168 }
169 else
170 {
171 ok_int(ret, 4);
172 ok_wstr(szBuff, L"''''");
173 }
174
175 LInt.QuadPart = 10000;
176 ret = LargeIntegerToString(&LInt, szBuff, _countof(szBuff), FALSE, NULL, 0);
177 ok_int(ret, 5);
178 ok_wstr(szBuff, L"10000");
179
180 LInt.QuadPart = 0xE8D4A51000LL;
181 ret = LargeIntegerToString(&LInt, szBuff, _countof(szBuff), FALSE, NULL, 0);
182 ok_int(ret, 13);
183 ok_wstr(szBuff, L"1000000000000");
184 }
185
START_TEST(Int64ToString)186 START_TEST(Int64ToString)
187 {
188 BOOL bVista = IsWindowsVistaOrGreater();
189 trace("bVista: %d\n", bVista);
190
191 Test_EntryTest(bVista);
192 Test_Int64ToString(bVista);
193 Test_LargeIntegerToString(bVista);
194 }
195