1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Test for CString 5 * COPYRIGHT: Copyright 2016-2017 Mark Jansen (mark.jansen@reactos.org) 6 * Copyright 2017 Katayama Hirofumi MZ 7 */ 8 9 #include <atlstr.h> 10 #include "resource.h" 11 12 #ifdef __REACTOS__ 13 #include <apitest.h> 14 #else 15 #include <stdlib.h> 16 #include <stdio.h> 17 #include <stdarg.h> 18 #include <windows.h> 19 int g_tests_executed = 0; 20 int g_tests_failed = 0; 21 int g_tests_skipped = 0; 22 const char *g_file = NULL; 23 int g_line = 0; 24 void set_location(const char *file, int line) 25 { 26 g_file = file; 27 g_line = line; 28 } 29 void ok_func(int value, const char *fmt, ...) 30 { 31 va_list va; 32 va_start(va, fmt); 33 if (!value) 34 { 35 printf("%s (%d): ", g_file, g_line); 36 vprintf(fmt, va); 37 g_tests_failed++; 38 } 39 g_tests_executed++; 40 va_end(va); 41 } 42 void skip_func(const char *fmt, ...) 43 { 44 va_list va; 45 va_start(va, fmt); 46 printf("%s (%d): test skipped: ", g_file, g_line); 47 vprintf(fmt, va); 48 g_tests_skipped++; 49 va_end(va); 50 } 51 #undef ok 52 #define ok(value, ...) do { \ 53 set_location(__FILE__, __LINE__); \ 54 ok_func(value, __VA_ARGS__); \ 55 } while (0) 56 #define ok_(x1,x2) set_location(x1,x2); ok_func 57 #define skip(...) do { \ 58 set_location(__FILE__, __LINE__); \ 59 skip_func(__VA_ARGS__); \ 60 } while (0) 61 #define START_TEST(x) int main(void) 62 char *wine_dbgstr_w(const wchar_t *wstr) 63 { 64 static char buf[512]; 65 WideCharToMultiByte(CP_ACP, 0, wstr, -1, buf, _countof(buf), NULL, NULL); 66 return buf; 67 } 68 #endif 69 70 struct traits_test 71 { 72 const char* strA; 73 const wchar_t* strW; 74 int str_len; 75 int exp_1, exp_2, exp_3, exp_4; 76 }; 77 78 traits_test g_Tests[] = { 79 // inputs outputs 80 { NULL, NULL, 0, 0, 0, -1, 0 }, 81 { NULL, NULL, -1, 0, -1, -1, 0 }, 82 { NULL, NULL, 1, 0, 1, -1, 0 }, 83 84 { "", L"", 0, 0, 0, 0, 0 }, 85 { "", L"", -1, 0, -1, 0, 1 }, 86 { "", L"", 1, 0, 1, 0, 1 }, 87 88 { "AAABBB", L"AAABBB", 0, 6, 0, 6, 0 }, 89 { "AAABBB", L"AAABBB", 3, 6, 3, 6, 3 }, 90 { "AAABBB", L"AAABBB", -1, 6, -1, 6, 7 }, 91 }; 92 93 static void test_basetypes() 94 { 95 int len; 96 char bufA[10]; 97 wchar_t bufW[10]; 98 99 for (size_t n = 0; n < _countof(g_Tests); ++n) 100 { 101 len = ChTraitsCRT<char>::GetBaseTypeLength(g_Tests[n].strA); 102 ok(len == g_Tests[n].exp_1, "Expected len to be %i, was %i for %u (A)\n", g_Tests[n].exp_1, len, n); 103 104 len = ChTraitsCRT<char>::GetBaseTypeLength(g_Tests[n].strA, g_Tests[n].str_len); 105 ok(len == g_Tests[n].exp_2, "Expected len to be %i, was %i for %u (A,len)\n", g_Tests[n].exp_2, len, n); 106 107 len = ChTraitsCRT<char>::GetBaseTypeLength(g_Tests[n].strW); 108 ok(len == g_Tests[n].exp_3, "Expected len to be %i, was %i for %u (W)\n", g_Tests[n].exp_3, len, n); 109 110 len = ChTraitsCRT<char>::GetBaseTypeLength(g_Tests[n].strW, g_Tests[n].str_len); 111 ok(len == g_Tests[n].exp_4, "Expected len to be %i, was %i for %u (W,len)\n", g_Tests[n].exp_4, len, n); 112 113 if (g_Tests[n].strA && g_Tests[n].strW) 114 { 115 memset(bufA, 'x', sizeof(bufA)); 116 ChTraitsCRT<char>::ConvertToBaseType(bufA, g_Tests[n].exp_1+1, g_Tests[n].strA); 117 char ch = bufA[g_Tests[n].exp_1]; 118 ok(ch == '\0', "Expected %i to be \\0, was: %c (%i) for %u\n", g_Tests[n].exp_1, ch, (int)ch, n); 119 ok(!strcmp(bufA, g_Tests[n].strA), "Expected bufA to be %s, was: %s for %u\n", g_Tests[n].strA, bufA, n); 120 ch = bufA[g_Tests[n].exp_1+1]; 121 ok(ch == 'x', "Expected %i to be 'x', was: %c (%i) for %u\n", g_Tests[n].exp_1+1, ch, (int)ch, n); 122 } 123 124 if (g_Tests[n].strA && g_Tests[n].strW) 125 { 126 memset(bufA, 'x', sizeof(bufA)); 127 ChTraitsCRT<char>::ConvertToBaseType(bufA, g_Tests[n].exp_1+1, g_Tests[n].strW); 128 char ch = bufA[g_Tests[n].exp_1]; 129 ok(ch == '\0', "Expected %i to be \\0, was: %c (%i) for %u\n", g_Tests[n].exp_1, ch, (int)ch, n); 130 ok(!strcmp(bufA, g_Tests[n].strA), "Expected bufA to be %s, was: %s for %u\n", g_Tests[n].strA, bufA, n); 131 ch = bufA[g_Tests[n].exp_1+1]; 132 ok(ch == 'x', "Expected %i to be 'x', was: %c (%i) for %u\n", g_Tests[n].exp_1+1, ch, (int)ch, n); 133 } 134 135 // wchar_t --> please note, swapped the expectations from 2 and 4 ! 136 len = ChTraitsCRT<wchar_t>::GetBaseTypeLength(g_Tests[n].strA); 137 ok(len == g_Tests[n].exp_1, "Expected len to be %i, was %i for %u (A)\n", g_Tests[n].exp_1, len, n); 138 139 len = ChTraitsCRT<wchar_t>::GetBaseTypeLength(g_Tests[n].strA, g_Tests[n].str_len); 140 ok(len == g_Tests[n].exp_4, "Expected len to be %i, was %i for %u (A,len)\n", g_Tests[n].exp_4, len, n); 141 142 len = ChTraitsCRT<wchar_t>::GetBaseTypeLength(g_Tests[n].strW); 143 ok(len == g_Tests[n].exp_3, "Expected len to be %i, was %i for %u (W)\n", g_Tests[n].exp_3, len, n); 144 145 len = ChTraitsCRT<wchar_t>::GetBaseTypeLength(g_Tests[n].strW, g_Tests[n].str_len); 146 ok(len == g_Tests[n].exp_2, "Expected len to be %i, was %i for %u (W,len)\n", g_Tests[n].exp_2, len, n); 147 148 if (g_Tests[n].strA && g_Tests[n].strW) 149 { 150 memset(bufW, 'x', sizeof(bufW)); 151 ChTraitsCRT<wchar_t>::ConvertToBaseType(bufW, g_Tests[n].exp_1+1, g_Tests[n].strA); 152 wchar_t ch = bufW[g_Tests[n].exp_1]; 153 ok(ch == L'\0', "Expected %i to be \\0, was: %c (%i) for %u\n", g_Tests[n].exp_1, ch, (int)ch, n); 154 ok(!wcscmp(bufW, g_Tests[n].strW), "Expected bufW to be %s, was: %s for %u\n", wine_dbgstr_w(g_Tests[n].strW), wine_dbgstr_w(bufW), n); 155 ch = bufW[g_Tests[n].exp_1+1]; 156 ok(ch == 30840, "Expected %i to be %i for %u\n", g_Tests[n].exp_1+1, (int)ch, n); 157 } 158 159 if (g_Tests[n].strA && g_Tests[n].strW) 160 { 161 memset(bufW, 'x', sizeof(bufW)); 162 ChTraitsCRT<wchar_t>::ConvertToBaseType(bufW, g_Tests[n].exp_1+1, g_Tests[n].strW); 163 wchar_t ch = bufW[g_Tests[n].exp_1]; 164 ok(ch == '\0', "Expected %i to be \\0, was: %c (%i) for %u\n", g_Tests[n].exp_1, ch, (int)ch, n); 165 ok(!wcscmp(bufW, g_Tests[n].strW), "Expected bufW to be %s, was: %s for %u\n", wine_dbgstr_w(g_Tests[n].strW), wine_dbgstr_w(bufW), n); 166 ch = bufW[g_Tests[n].exp_1+1]; 167 ok(ch == 30840, "Expected %i to be %i for %u\n", g_Tests[n].exp_1+1, (int)ch, n); 168 } 169 } 170 } 171 172 // Allocation strategy seems to differ a bit between us and MS's atl. 173 // if someone cares enough to find out why, feel free to change the macro below. 174 #ifdef __REACTOS__ 175 #define ALLOC_EXPECT(a, b) b 176 #else 177 #define ALLOC_EXPECT(a, b) a 178 #endif 179 180 181 #undef ok 182 #undef _T 183 184 #define TEST_NAMEX(name) void test_##name##W() 185 #define CStringX CStringW 186 #define _X(x) L ## x 187 #define XCHAR WCHAR 188 #define YCHAR CHAR 189 #define dbgstrx(x) wine_dbgstr_w(x) 190 #define ok ok_("CStringW:\n" __FILE__, __LINE__) 191 #define GetWindowsDirectoryX GetWindowsDirectoryW 192 #define MAKEINTRESOURCEX(x) MAKEINTRESOURCEW(x) 193 #define MAKEINTRESOURCEY(x) MAKEINTRESOURCEA(x) 194 #include "CString.inl" 195 196 197 #undef CStringX 198 #undef TEST_NAMEX 199 #undef _X 200 #undef XCHAR 201 #undef YCHAR 202 #undef dbgstrx 203 #undef ok 204 #undef GetWindowsDirectoryX 205 #undef MAKEINTRESOURCEX 206 #undef MAKEINTRESOURCEY 207 208 #define TEST_NAMEX(name) void test_##name##A() 209 #define CStringX CStringA 210 #define _X(x) x 211 #define XCHAR CHAR 212 #define YCHAR WCHAR 213 #define dbgstrx(x) (const char*)x 214 #define ok ok_("CStringA:\n" __FILE__, __LINE__) 215 #define GetWindowsDirectoryX GetWindowsDirectoryA 216 #define MAKEINTRESOURCEX(x) MAKEINTRESOURCEA(x) 217 #define MAKEINTRESOURCEY(x) MAKEINTRESOURCEW(x) 218 #include "CString.inl" 219 220 221 START_TEST(CString) 222 { 223 test_basetypes(); 224 225 if ((ALLOC_EXPECT(1, 2)) == 2) 226 { 227 skip("Ignoring real GetAllocLength() lenght\n"); 228 } 229 230 test_operators_initW(); 231 test_operators_initA(); 232 233 test_compareW(); 234 test_compareA(); 235 236 test_findW(); 237 test_findA(); 238 239 test_formatW(); 240 test_formatA(); 241 242 test_substrW(); 243 test_substrA(); 244 245 test_replaceW(); 246 test_replaceA(); 247 248 test_trimW(); 249 test_trimA(); 250 251 test_envW(); 252 test_envA(); 253 254 test_load_strW(); 255 test_load_strA(); 256 257 test_bstrW(); 258 test_bstrA(); 259 260 #ifndef __REACTOS__ 261 printf("CString: %i tests executed (0 marked as todo, %i failures), %i skipped.\n", g_tests_executed, g_tests_failed, g_tests_skipped); 262 return g_tests_failed; 263 #endif 264 } 265