This adds unit tests for these four functions: GetUserGeoID(); SetUserGeoID(); GetUserDefaultGeoName(); SetUserGeoName().
These are all functions I intend to improve and/or implement in the short future.
Signed-off-by: João Diogo Craveiro Ferreira devilj@outlook.pt --- dlls/kernel32/tests/locale.c | 319 +++++++++++++++++++++++++++++++++++ 1 file changed, 319 insertions(+)
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 81e74531ea..e3e46bfb53 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -108,6 +108,8 @@ static LANGID (WINAPI *pSetThreadUILanguage)(LANGID); static LANGID (WINAPI *pGetThreadUILanguage)(VOID); static INT (WINAPI *pNormalizeString)(NORM_FORM, LPCWSTR, INT, LPWSTR, INT); static INT (WINAPI *pFindStringOrdinal)(DWORD, LPCWSTR lpStringSource, INT, LPCWSTR, INT, BOOL); +static int (WINAPI *pGetUserDefaultGeoName)(LPWSTR, int); +static BOOL (WINAPI *pSetUserGeoName)(PWSTR);
static void InitFunctionPointers(void) { @@ -145,6 +147,8 @@ static void InitFunctionPointers(void) X(GetThreadUILanguage); X(NormalizeString); X(FindStringOrdinal); + X(GetUserDefaultGeoName); + X(SetUserGeoName);
mod = GetModuleHandleA("ntdll"); X(RtlUpcaseUnicodeChar); @@ -4745,6 +4749,317 @@ static void test_CompareStringOrdinal(void) } }
+static void test_GetUserGeoID(void) +{ + GEOID id; + todo_wine { + if (pGetUserDefaultGeoName && pSetUserGeoName) + { + ok(GEOID_NOT_AVAILABLE != GetUserGeoID(GEOCLASS_NATION), + "GEOCLASS_NATION: should never return GEOID_NOT_AVAILABLE when GeoName API is available.\n"); + ok(GEOID_NOT_AVAILABLE != GetUserGeoID(GEOCLASS_REGION), + "GEOCLASS_REGION: should never return GEOID_NOT_AVAILABLE when GeoName API is available.\n"); + } + else + win_skip("This platform allows GEOID_NOT_AVAILABLE to be returned.\n"); + } + + id = GetUserGeoID(GEOCLASS_ALL); + ok(id == GEOID_NOT_AVAILABLE, + "GEOCLASS_ALL: Expected GEOID_NOT_AVAILABLE, got %d.\n", id); + id = GetUserGeoID(12345); + ok(id == GEOID_NOT_AVAILABLE, + "Gibberish argument: Expected GEOID_NOT_AVAILABLE, got %d.\n", id); +} + +static void test_GetUserDefaultGeoName(void) +{ + todo_wine { + if (pGetUserDefaultGeoName && pSetUserGeoName) + { + WCHAR *name = malloc(sizeof(WCHAR) * 10); + int count = 0; + + if (!name) + { + trace("Couldn't allocate 20 bytes to store geo name. Aborting test!\n"); + return; + } + + SetLastError(ERROR_SUCCESS); + count = pGetUserDefaultGeoName(NULL, 10); + ok(count == 0 && (GetLastError() == ERROR_INVALID_PARAMETER), + "Expected count == 0, got %d; and expected last error = ERROR_INVALID_PARAMETER (87), got %d\n", + count, GetLastError()); + + count = pGetUserDefaultGeoName(NULL, -1); + ok(count == 0 && (GetLastError() == ERROR_INVALID_PARAMETER), + "Expected count == 0, got %d; and expected last error = ERROR_INVALID_PARAMETER (87), got %d\n", + count, GetLastError()); + + SetLastError(ERROR_SUCCESS); + count = pGetUserDefaultGeoName(name, 0); + ok(count > 0, "Expected character count > 0, got %d; last error was %d.\n", count, GetLastError()); + + count = pGetUserDefaultGeoName(name, 1); + ok(count == 0 && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), + "Expected count == 0, got %d; and expected last error = ERROR_INSUFFICIENT_BUFFER (122), got %d\n", + count, GetLastError()); + + count = pGetUserDefaultGeoName(name, -1); + ok(count == 0 && (GetLastError() == ERROR_INVALID_PARAMETER), + "Expected count == 0, got %d; and expected last error = ERROR_INVALID_PARAMETER (87), got %d\n", + count, GetLastError()); + + free(name); + + SetLastError(ERROR_SUCCESS); + count = pGetUserDefaultGeoName(NULL, 0); + ok(count > 0, "Expected character count > 0, got %d; last error was %d.\n", count, GetLastError()); + if (count) + { + name = malloc(count * sizeof(WCHAR)); + if (name) + { + int result = pGetUserDefaultGeoName(name, count); + ok(result, + "Expected character count == %d, got %d; last error was %d.\n", + count, result, GetLastError()); + free(name); + } + else + trace("Couldn't allocate %d bytes to store geo name.\n", count); + } + } + else win_skip("GetUserDefaultGeoName: procedure not implemented on this platform.\n"); + } +} + +static void test_SetUserGeoID(void) +{ + BOOL status; + const int geoname_supported = (pGetUserDefaultGeoName && pSetUserGeoName); + + const GEOID original_nation = GetUserGeoID(GEOCLASS_NATION); + const GEOID original_region = GetUserGeoID(GEOCLASS_REGION); + int original_name_count = 0; /* We only need the char count. */ + + struct geopair { + GEOID id; + WCHAR name[4]; + }; + + struct testsuit { + const char *const stage; + struct geopair geo, geo_backup; + GEOCLASS geoclass; + }; + + struct testsuit const tests[] = { + {"GEOCLASS_NATION", {193, {'P','T',0}}, {56, {'C','U',0}}, GEOCLASS_NATION}, + {"GEOCLASS_REGION", {21206, {'0','5','7',0}}, {10039880, {'0','2','9',0}}, GEOCLASS_REGION} + }; + + struct testsuit const bad_args[] = { + {"invalid GEOID -1", {GEOID_NOT_AVAILABLE}}, + {"invalid GEOID 1", {1}} + }; + + if (geoname_supported) + original_name_count = pGetUserDefaultGeoName(NULL, 0); + + /* Invalid args */ + for (int i = 0; i < ARRAY_SIZE(bad_args); i++) + { + BOOL status; + + SetLastError(ERROR_SUCCESS); + + status = SetUserGeoID(bad_args[i].geo.id); + ok(!status && + (GetLastError() == ERROR_INVALID_PARAMETER || /* Vista+ */ + broken(GetLastError() == ERROR_SUCCESS)), /* WinXP */ + "Setting %s: got ret=%d (expected 0), error=%d (expected 87=ERROR_INVALID_PARAMETER)\n", + bad_args[i].stage, status, GetLastError()); + } + + for (int i = 0; i < ARRAY_SIZE(tests); i++) + { + const struct geopair *geo; + + if (original_nation != tests[i].geo.id) + geo = &tests[i].geo; + else + geo = &tests[i].geo_backup; + + SetLastError(ERROR_SUCCESS); + ok(status = SetUserGeoID(geo->id), + "%s: Setting to %d failed with last error: %d\n", tests[i].stage, geo->id, GetLastError()); + if (status) + { + const GEOID id = GetUserGeoID(tests[i].geoclass); + const int status = (id == geo->id); + ok(status, "%s: we just set it to %d but retrieved %d instead \n", tests[i].stage, geo->id, id); + + if (status) + { + todo_wine { + if (geoname_supported) + { + const int count = pGetUserDefaultGeoName(NULL, 0); + WCHAR *const name = malloc(count * sizeof(WCHAR)); + + if (name) + { + const int written = pGetUserDefaultGeoName(name, count); + const int status = (count == written); + + ok(status, + "%s: Failed to get geoname after setting ID to %d: got %d characters, expected %d\n", + tests[i].stage, id, written, count); + ok(!winetest_strcmpW(name, geo->name), + "%s: wrong geoname for ID %d: got %s, expected %s\n", + tests[i].stage, geo->id, wine_dbgstr_w(name), wine_dbgstr_w(geo->name)); + free(name); + } + else if (count > 0) + trace("Couldn't allocate memory to store geoname string! (Size = %lu bytes)\n", + count * sizeof(WCHAR)); + } + else + win_skip("%s: Can't check geoname: unsupported platform.\n", tests[i].stage); + } + } + } + } + + /* Best attempt at restoring original values */ + if (geoname_supported) + { + if (original_name_count <= 3) + { + SetUserGeoID(original_region); + SetUserGeoID(original_nation); + } + else + { + SetUserGeoID(original_nation); + SetUserGeoID(original_region); + } + } + else + { + const GEOID neutral = 39070; /* World */ + original_region != GEOID_NOT_AVAILABLE ? SetUserGeoID(original_region) : SetUserGeoID(neutral); + original_nation != GEOID_NOT_AVAILABLE ? SetUserGeoID(original_nation) : SetUserGeoID(neutral); + } +} + +static void test_SetUserGeoName(void) +{ + todo_wine + { + if (pGetUserDefaultGeoName && pSetUserGeoName) + { + struct geopair { + WCHAR *name; + GEOID id; + }; + + struct testsuit { + const char *stage; + BOOL exp_return; + int exp_error; + struct geopair geo, geo_backup; + GEOCLASS geoclass; + }; + + /* Known valid test nations and regions */ + struct geopair vietnam = {(WCHAR[]){'V','N',0}, 251}; + struct geopair brasil = {(WCHAR[]){'B','R',0}, 32}; + struct geopair west_europe = {(WCHAR[]){'1','5','5',0}, 10210824}; + struct geopair east_asia = {(WCHAR[]){'0','3','0',0}, 47600}; + + /* Invalid arguments */ + WCHAR too_long[] = {'w','e',' ','t','o','o',' ','l','o','n','g',0}; /* Names must have less than 3 chars */ + WCHAR too_short[] = {'P',0}; /* Names must be at least two characters */ + WCHAR wrong_un_m49[] = {'A','A','A',0}; /* UN M49 codes use numbers only */ + WCHAR wrong_iso_3166a2[] = {'1','2',0}; /* ISO 3166-1 alpha-2 country codes use the latin alphabet only */ + + const struct testsuit good_args[] = { + {"nation geoname", TRUE, ERROR_SUCCESS, vietnam, brasil, GEOCLASS_NATION}, + {"region geoname", TRUE, ERROR_SUCCESS, west_europe, east_asia, GEOCLASS_REGION} + }; + + const struct testsuit bad_args[] = { + {"too long geoname", FALSE, ERROR_INVALID_PARAMETER, {too_long}}, + {"too short geoname", FALSE, ERROR_INVALID_PARAMETER, {too_short}}, + {"invalid UN M49 code", FALSE, ERROR_INVALID_PARAMETER, {wrong_un_m49}}, + {"invalid ISO 3166 code", FALSE, ERROR_INVALID_PARAMETER, {wrong_iso_3166a2}} + }; + + const int original_count = pGetUserDefaultGeoName(NULL, 0); + WCHAR *const original_name = malloc(original_count * sizeof(WCHAR)); + const GEOID original_nation = GetUserGeoID(GEOCLASS_NATION); + const GEOID original_region = GetUserGeoID(GEOCLASS_REGION); + + /* Get current values before testing */ + if (original_name) + { + if (original_count != pGetUserDefaultGeoName(original_name, original_count)) + trace("Couldn't get original geo name; restoring is not possible.\n"); + } + else if (original_count) + trace("Couldn't allocate %lu bytes to store original name.\n", sizeof(WCHAR) * original_count); + + + for (int i = 0; i < ARRAY_SIZE(bad_args); i++) + { + BOOL status; + SetLastError(ERROR_SUCCESS); + + status = pSetUserGeoName(bad_args[i].geo.name); + ok((status == bad_args[i].exp_return) && (GetLastError() == bad_args[i].exp_error), + "Setting %s: Got ret=%d (expected %d) and lasterror=%d (expected %d).\n", + bad_args[i].stage, status, bad_args[i].exp_return, GetLastError(), bad_args[i].exp_error); + }; + + + for (int i = 0; i < ARRAY_SIZE(good_args); i++) + { + BOOL status; + const struct geopair *geo; + + if (winetest_strcmpW(original_name, good_args[i].geo.name)) + geo = &good_args[i].geo; + else + geo = &good_args[i].geo_backup; + + SetLastError(ERROR_SUCCESS); + + status = pSetUserGeoName(geo->name); + ok((status == good_args[i].exp_return) && (GetLastError() == good_args[i].exp_error), + "Setting geoname to %s: failed with ret=%d (expected %d) and lasterror=%d (expected %d).\n", + wine_dbgstr_w(geo->name), status, good_args[i].exp_return, GetLastError(), good_args[i].exp_error); + + if (status == good_args[i].exp_return) + { + const GEOID geoid = GetUserGeoID(good_args[i].geoclass); + + ok(geoid == geo->id, "%s (geoclass %d): Wrong GeoID for geoname %s: got %d (expected %d).\n", + good_args[i].stage, good_args[i].geoclass, wine_dbgstr_w(geo->name), geoid, geo->id); + } + } + + /* Best attempt at restoring original values */ + SetUserGeoID(original_region); + SetUserGeoID(original_nation); + pSetUserGeoName(original_name); + } + else win_skip("SetUserGeoName: procedure not implemented on this platform.\n"); + } +} + static void test_GetGeoInfo(void) { char buffA[20]; @@ -6058,6 +6373,10 @@ START_TEST(locale) test_SetThreadUILanguage(); test_NormalizeString(); test_SpecialCasing(); + test_GetUserGeoID(); + test_GetUserDefaultGeoName(); + test_SetUserGeoID(); + test_SetUserGeoName(); /* this requires collation table patch to make it MS compatible */ if (0) test_sorting(); }
On 10/3/19 7:40 AM, João Diogo Ferreira wrote:
This adds unit tests for these four functions: GetUserGeoID(); SetUserGeoID(); GetUserDefaultGeoName(); SetUserGeoName().
These are all functions I intend to improve and/or implement in the short future.
Signed-off-by: João Diogo Craveiro Ferreira devilj@outlook.pt
dlls/kernel32/tests/locale.c | 319 +++++++++++++++++++++++++++++++++++ 1 file changed, 319 insertions(+)
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 81e74531ea..e3e46bfb53 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -108,6 +108,8 @@ static LANGID (WINAPI *pSetThreadUILanguage)(LANGID); static LANGID (WINAPI *pGetThreadUILanguage)(VOID); static INT (WINAPI *pNormalizeString)(NORM_FORM, LPCWSTR, INT, LPWSTR, INT); static INT (WINAPI *pFindStringOrdinal)(DWORD, LPCWSTR lpStringSource, INT, LPCWSTR, INT, BOOL); +static int (WINAPI *pGetUserDefaultGeoName)(LPWSTR, int); +static BOOL (WINAPI *pSetUserGeoName)(PWSTR);
static void InitFunctionPointers(void) { @@ -145,6 +147,8 @@ static void InitFunctionPointers(void) X(GetThreadUILanguage); X(NormalizeString); X(FindStringOrdinal);
X(GetUserDefaultGeoName);
X(SetUserGeoName);
mod = GetModuleHandleA("ntdll"); X(RtlUpcaseUnicodeChar);
@@ -4745,6 +4749,317 @@ static void test_CompareStringOrdinal(void) } }
+static void test_GetUserGeoID(void) +{
- GEOID id;
- todo_wine {
if (pGetUserDefaultGeoName && pSetUserGeoName)
{
ok(GEOID_NOT_AVAILABLE != GetUserGeoID(GEOCLASS_NATION),
"GEOCLASS_NATION: should never return GEOID_NOT_AVAILABLE when GeoName API is available.\n");
ok(GEOID_NOT_AVAILABLE != GetUserGeoID(GEOCLASS_REGION),
"GEOCLASS_REGION: should never return GEOID_NOT_AVAILABLE when GeoName API is available.\n");
}
else
win_skip("This platform allows GEOID_NOT_AVAILABLE to be returned.\n");
- }
- id = GetUserGeoID(GEOCLASS_ALL);
- ok(id == GEOID_NOT_AVAILABLE,
"GEOCLASS_ALL: Expected GEOID_NOT_AVAILABLE, got %d.\n", id);
- id = GetUserGeoID(12345);
- ok(id == GEOID_NOT_AVAILABLE,
"Gibberish argument: Expected GEOID_NOT_AVAILABLE, got %d.\n", id);
+}
+static void test_GetUserDefaultGeoName(void) +{
- todo_wine {
if (pGetUserDefaultGeoName && pSetUserGeoName)
{
WCHAR *name = malloc(sizeof(WCHAR) * 10);
int count = 0;
if (!name)
{
trace("Couldn't allocate 20 bytes to store geo name. Aborting test!\n");
return;
}
SetLastError(ERROR_SUCCESS);
count = pGetUserDefaultGeoName(NULL, 10);
ok(count == 0 && (GetLastError() == ERROR_INVALID_PARAMETER),
"Expected count == 0, got %d; and expected last error = ERROR_INVALID_PARAMETER (87), got %d\n",
count, GetLastError());
count = pGetUserDefaultGeoName(NULL, -1);
ok(count == 0 && (GetLastError() == ERROR_INVALID_PARAMETER),
"Expected count == 0, got %d; and expected last error = ERROR_INVALID_PARAMETER (87), got %d\n",
count, GetLastError());
SetLastError(ERROR_SUCCESS);
count = pGetUserDefaultGeoName(name, 0);
ok(count > 0, "Expected character count > 0, got %d; last error was %d.\n", count, GetLastError());
count = pGetUserDefaultGeoName(name, 1);
ok(count == 0 && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
"Expected count == 0, got %d; and expected last error = ERROR_INSUFFICIENT_BUFFER (122), got %d\n",
count, GetLastError());
count = pGetUserDefaultGeoName(name, -1);
ok(count == 0 && (GetLastError() == ERROR_INVALID_PARAMETER),
"Expected count == 0, got %d; and expected last error = ERROR_INVALID_PARAMETER (87), got %d\n",
count, GetLastError());
free(name);
SetLastError(ERROR_SUCCESS);
count = pGetUserDefaultGeoName(NULL, 0);
ok(count > 0, "Expected character count > 0, got %d; last error was %d.\n", count, GetLastError());
if (count)
{
name = malloc(count * sizeof(WCHAR));
if (name)
{
int result = pGetUserDefaultGeoName(name, count);
ok(result,
"Expected character count == %d, got %d; last error was %d.\n",
count, result, GetLastError());
free(name);
}
else
trace("Couldn't allocate %d bytes to store geo name.\n", count);
}
}
else win_skip("GetUserDefaultGeoName: procedure not implemented on this platform.\n");
- }
+}
Please check function pointer first and return if it's unavailable, instead of creating large outer nesting block.
Regarding string buffers, for this test it should be enough to use fixed size local buffer, but if you must allocate, please use kernel32 heap functions.
+static void test_SetUserGeoID(void) +{
- BOOL status;
- const int geoname_supported = (pGetUserDefaultGeoName && pSetUserGeoName);
- const GEOID original_nation = GetUserGeoID(GEOCLASS_NATION);
- const GEOID original_region = GetUserGeoID(GEOCLASS_REGION);
- int original_name_count = 0; /* We only need the char count. */
- struct geopair {
GEOID id;
WCHAR name[4];
- };
- struct testsuit {
const char *const stage;
struct geopair geo, geo_backup;
GEOCLASS geoclass;
- };
- struct testsuit const tests[] = {
{"GEOCLASS_NATION", {193, {'P','T',0}}, {56, {'C','U',0}}, GEOCLASS_NATION},
{"GEOCLASS_REGION", {21206, {'0','5','7',0}}, {10039880, {'0','2','9',0}}, GEOCLASS_REGION}
- };
- struct testsuit const bad_args[] = {
{"invalid GEOID -1", {GEOID_NOT_AVAILABLE}},
{"invalid GEOID 1", {1}}
- };
- if (geoname_supported)
original_name_count = pGetUserDefaultGeoName(NULL, 0);
- /* Invalid args */
- for (int i = 0; i < ARRAY_SIZE(bad_args); i++)
- {
BOOL status;
SetLastError(ERROR_SUCCESS);
status = SetUserGeoID(bad_args[i].geo.id);
ok(!status &&
(GetLastError() == ERROR_INVALID_PARAMETER || /* Vista+ */
broken(GetLastError() == ERROR_SUCCESS)), /* WinXP */
"Setting %s: got ret=%d (expected 0), error=%d (expected 87=ERROR_INVALID_PARAMETER)\n",
bad_args[i].stage, status, GetLastError());
- }
- for (int i = 0; i < ARRAY_SIZE(tests); i++)
- {
const struct geopair *geo;
if (original_nation != tests[i].geo.id)
geo = &tests[i].geo;
else
geo = &tests[i].geo_backup;
SetLastError(ERROR_SUCCESS);
ok(status = SetUserGeoID(geo->id),
"%s: Setting to %d failed with last error: %d\n", tests[i].stage, geo->id, GetLastError());
if (status)
{
const GEOID id = GetUserGeoID(tests[i].geoclass);
const int status = (id == geo->id);
ok(status, "%s: we just set it to %d but retrieved %d instead \n", tests[i].stage, geo->id, id);
if (status)
{
todo_wine {
if (geoname_supported)
{
const int count = pGetUserDefaultGeoName(NULL, 0);
WCHAR *const name = malloc(count * sizeof(WCHAR));
if (name)
{
const int written = pGetUserDefaultGeoName(name, count);
const int status = (count == written);
ok(status,
"%s: Failed to get geoname after setting ID to %d: got %d characters, expected %d\n",
tests[i].stage, id, written, count);
ok(!winetest_strcmpW(name, geo->name),
"%s: wrong geoname for ID %d: got %s, expected %s\n",
tests[i].stage, geo->id, wine_dbgstr_w(name), wine_dbgstr_w(geo->name));
free(name);
}
else if (count > 0)
trace("Couldn't allocate memory to store geoname string! (Size = %lu bytes)\n",
count * sizeof(WCHAR));
}
else
win_skip("%s: Can't check geoname: unsupported platform.\n", tests[i].stage);
}
}
}
- }
- /* Best attempt at restoring original values */
- if (geoname_supported)
- {
if (original_name_count <= 3)
{
SetUserGeoID(original_region);
SetUserGeoID(original_nation);
}
else
{
SetUserGeoID(original_nation);
SetUserGeoID(original_region);
}
- }
- else
- {
const GEOID neutral = 39070; /* World */
original_region != GEOID_NOT_AVAILABLE ? SetUserGeoID(original_region) : SetUserGeoID(neutral);
original_nation != GEOID_NOT_AVAILABLE ? SetUserGeoID(original_nation) : SetUserGeoID(neutral);
- }
My understanding is that setting geoid is not something regular application would do.
+}
+static void test_SetUserGeoName(void) +{
- todo_wine
- {
if (pGetUserDefaultGeoName && pSetUserGeoName)
{
struct geopair {
WCHAR *name;
GEOID id;
};
struct testsuit {
const char *stage;
BOOL exp_return;
int exp_error;
struct geopair geo, geo_backup;
GEOCLASS geoclass;
};
/* Known valid test nations and regions */
struct geopair vietnam = {(WCHAR[]){'V','N',0}, 251};
struct geopair brasil = {(WCHAR[]){'B','R',0}, 32};
struct geopair west_europe = {(WCHAR[]){'1','5','5',0}, 10210824};
struct geopair east_asia = {(WCHAR[]){'0','3','0',0}, 47600};
/* Invalid arguments */
WCHAR too_long[] = {'w','e',' ','t','o','o',' ','l','o','n','g',0}; /* Names must have less than 3 chars */
WCHAR too_short[] = {'P',0}; /* Names must be at least two characters */
WCHAR wrong_un_m49[] = {'A','A','A',0}; /* UN M49 codes use numbers only */
WCHAR wrong_iso_3166a2[] = {'1','2',0}; /* ISO 3166-1 alpha-2 country codes use the latin alphabet only */
const struct testsuit good_args[] = {
{"nation geoname", TRUE, ERROR_SUCCESS, vietnam, brasil, GEOCLASS_NATION},
{"region geoname", TRUE, ERROR_SUCCESS, west_europe, east_asia, GEOCLASS_REGION}
};
const struct testsuit bad_args[] = {
{"too long geoname", FALSE, ERROR_INVALID_PARAMETER, {too_long}},
{"too short geoname", FALSE, ERROR_INVALID_PARAMETER, {too_short}},
{"invalid UN M49 code", FALSE, ERROR_INVALID_PARAMETER, {wrong_un_m49}},
{"invalid ISO 3166 code", FALSE, ERROR_INVALID_PARAMETER, {wrong_iso_3166a2}}
};
const int original_count = pGetUserDefaultGeoName(NULL, 0);
WCHAR *const original_name = malloc(original_count * sizeof(WCHAR));
const GEOID original_nation = GetUserGeoID(GEOCLASS_NATION);
const GEOID original_region = GetUserGeoID(GEOCLASS_REGION);
/* Get current values before testing */
if (original_name)
{
if (original_count != pGetUserDefaultGeoName(original_name, original_count))
trace("Couldn't get original geo name; restoring is not possible.\n");
}
else if (original_count)
trace("Couldn't allocate %lu bytes to store original name.\n", sizeof(WCHAR) * original_count);
for (int i = 0; i < ARRAY_SIZE(bad_args); i++)
{
BOOL status;
SetLastError(ERROR_SUCCESS);
status = pSetUserGeoName(bad_args[i].geo.name);
ok((status == bad_args[i].exp_return) && (GetLastError() == bad_args[i].exp_error),
"Setting %s: Got ret=%d (expected %d) and lasterror=%d (expected %d).\n",
bad_args[i].stage, status, bad_args[i].exp_return, GetLastError(), bad_args[i].exp_error);
};
for (int i = 0; i < ARRAY_SIZE(good_args); i++)
{
BOOL status;
const struct geopair *geo;
if (winetest_strcmpW(original_name, good_args[i].geo.name))
geo = &good_args[i].geo;
else
geo = &good_args[i].geo_backup;
SetLastError(ERROR_SUCCESS);
status = pSetUserGeoName(geo->name);
ok((status == good_args[i].exp_return) && (GetLastError() == good_args[i].exp_error),
"Setting geoname to %s: failed with ret=%d (expected %d) and lasterror=%d (expected %d).\n",
wine_dbgstr_w(geo->name), status, good_args[i].exp_return, GetLastError(), good_args[i].exp_error);
if (status == good_args[i].exp_return)
{
const GEOID geoid = GetUserGeoID(good_args[i].geoclass);
ok(geoid == geo->id, "%s (geoclass %d): Wrong GeoID for geoname %s: got %d (expected %d).\n",
good_args[i].stage, good_args[i].geoclass, wine_dbgstr_w(geo->name), geoid, geo->id);
}
}
/* Best attempt at restoring original values */
SetUserGeoID(original_region);
SetUserGeoID(original_nation);
pSetUserGeoName(original_name);
}
else win_skip("SetUserGeoName: procedure not implemented on this platform.\n");
- }
+}
- static void test_GetGeoInfo(void) { char buffA[20];
@@ -6058,6 +6373,10 @@ START_TEST(locale) test_SetThreadUILanguage(); test_NormalizeString(); test_SpecialCasing();
- test_GetUserGeoID();
- test_GetUserDefaultGeoName();
- test_SetUserGeoID();
- test_SetUserGeoName(); /* this requires collation table patch to make it MS compatible */ if (0) test_sorting(); }
A quinta-feira, 3 de outubro de 2019 06:37:56 WEST Nikolay Sivov escreveu:
Please check function pointer first and return if it's unavailable, instead of creating large outer nesting block.
Regarding string buffers, for this test it should be enough to use fixed size local buffer, but if you must allocate, please use kernel32 heap functions.
There is no reason to do the first alloc (other than tiredness :)). The second alloc is only there to make sure we succeed in the unlikely case that the implementation allows unbounded name strings, but I'll "hide" it behind an if block in case the local buffer isn't enough.
My understanding is that setting geoid is not something regular application would do.
Yes, general applications shouldn't do it, and it's not entirely reversible as we can only make a best guess at what the values were before testing; and even then, this relies heavily on undocumented behavior (such as which ID to set last to restore the proper geo name, or that it writes a name at all).
I only wrote those because I intend to write some Wine-internal functions that made use of that behavior (and it is useful behavior). In honesty, we don't even need to guarantee Windows behaves the same way; it's only there so Wine behaves the same unless we need to change it.
If you think it's best, these tests can be removed.
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=57322
Your paranoid android.
=== wxppro (32 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== w2003std (32 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== wvistau64 (32 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== wvistau64_zh_CN (32 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== wvistau64_fr (32 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== wvistau64_he (32 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== w2008s64 (32 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== w7u (32 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== w7pro64 (32 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== wvistau64 (64 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== w2008s64 (64 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== w7pro64 (64 bit report) ===
kernel32: locale.c:4896: Test failed: GEOCLASS_REGION: Setting to 21206 failed with last error: 0
=== debian10 (32 bit report) ===
kernel32: locale.c:4879: Test failed: Setting invalid GEOID -1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4879: Test failed: Setting invalid GEOID 1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4902: Test failed: GEOCLASS_REGION: we just set it to 21206 but retrieved -1 instead
=== debian10 (32 bit French report) ===
kernel32: locale.c:4879: Test failed: Setting invalid GEOID -1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4879: Test failed: Setting invalid GEOID 1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4902: Test failed: GEOCLASS_REGION: we just set it to 21206 but retrieved -1 instead
=== debian10 (32 bit Japanese:Japan report) ===
kernel32: locale.c:4879: Test failed: Setting invalid GEOID -1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4879: Test failed: Setting invalid GEOID 1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4902: Test failed: GEOCLASS_REGION: we just set it to 21206 but retrieved -1 instead
=== debian10 (32 bit Chinese:China report) ===
kernel32: locale.c:4879: Test failed: Setting invalid GEOID -1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4879: Test failed: Setting invalid GEOID 1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4902: Test failed: GEOCLASS_REGION: we just set it to 21206 but retrieved -1 instead
=== debian10 (32 bit WoW report) ===
kernel32: locale.c:4879: Test failed: Setting invalid GEOID -1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4879: Test failed: Setting invalid GEOID 1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4902: Test failed: GEOCLASS_REGION: we just set it to 21206 but retrieved -1 instead
=== debian10 (64 bit WoW report) ===
kernel32: locale.c:4879: Test failed: Setting invalid GEOID -1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4879: Test failed: Setting invalid GEOID 1: got ret=1 (expected 0), error=0 (expected 87=ERROR_INVALID_PARAMETER) locale.c:4902: Test failed: GEOCLASS_REGION: we just set it to 21206 but retrieved -1 instead