mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-21584 Added code to allow regions of type "grouping" to return their children.
This commit is contained in:
parent
17d64710a2
commit
9a614752ce
6 changed files with 185 additions and 13 deletions
|
@ -166,19 +166,6 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
|
|||
continents->addElement(continentName,status);
|
||||
}
|
||||
|
||||
UResourceBundle *groupingBundle = nullptr;
|
||||
while ( ures_hasNext(groupingContainment.getAlias()) ) {
|
||||
groupingBundle = ures_getNextResource(groupingContainment.getAlias(), groupingBundle, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
break;
|
||||
}
|
||||
UnicodeString *groupingName = new UnicodeString(ures_getKey(groupingBundle), -1, US_INV);
|
||||
if (groupingName) {
|
||||
groupings->addElement(groupingName,status);
|
||||
}
|
||||
}
|
||||
ures_close(groupingBundle);
|
||||
|
||||
for ( int32_t i = 0 ; i < allRegions->size() ; i++ ) {
|
||||
LocalPointer<Region> r(new Region(), status);
|
||||
if ( U_FAILURE(status) ) {
|
||||
|
@ -203,6 +190,29 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) {
|
|||
uhash_put(newRegionIDMap.getAlias(),idStrAlias,(void *)(r.orphan()),&status); // regionIDMap takes ownership
|
||||
}
|
||||
|
||||
UResourceBundle *groupingBundle = nullptr;
|
||||
while ( ures_hasNext(groupingContainment.getAlias()) ) {
|
||||
groupingBundle = ures_getNextResource(groupingContainment.getAlias(), groupingBundle, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
break;
|
||||
}
|
||||
UnicodeString *groupingName = new UnicodeString(ures_getKey(groupingBundle), -1, US_INV);
|
||||
groupings->addElement(groupingName,status);
|
||||
Region *grouping = (Region *) uhash_get(newRegionIDMap.getAlias(),groupingName);
|
||||
if (grouping != NULL) {
|
||||
for (int32_t i = 0; i < ures_getSize(groupingBundle); i++) {
|
||||
UnicodeString child = ures_getUnicodeStringByIndex(groupingBundle, i, &status);
|
||||
if (U_SUCCESS(status)) {
|
||||
if (grouping->containedRegions == NULL) {
|
||||
grouping->containedRegions = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);
|
||||
}
|
||||
grouping->containedRegions->addElement(new UnicodeString(child), status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ures_close(groupingBundle);
|
||||
|
||||
// Process the territory aliases
|
||||
while ( ures_hasNext(territoryAlias.getAlias()) ) {
|
||||
LocalUResourceBundlePointer res(ures_getNextResource(territoryAlias.getAlias(),NULL,&status));
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
static void TestKnownRegions(void);
|
||||
static void TestGetContainedRegions(void);
|
||||
static void TestGroupingChildren(void);
|
||||
static void TestGetContainedRegionsWithType(void);
|
||||
static void TestGetContainingRegion(void);
|
||||
static void TestGetContainingRegionWithType(void);
|
||||
|
@ -38,6 +39,7 @@ void addURegionTest(TestNode** root)
|
|||
{
|
||||
TESTCASE(TestKnownRegions);
|
||||
TESTCASE(TestGetContainedRegions);
|
||||
TESTCASE(TestGroupingChildren);
|
||||
TESTCASE(TestGetContainedRegionsWithType);
|
||||
TESTCASE(TestGetContainingRegion);
|
||||
TESTCASE(TestGetContainingRegionWithType);
|
||||
|
@ -414,6 +416,58 @@ static void TestGetContainedRegions() {
|
|||
}
|
||||
}
|
||||
|
||||
static void TestGroupingChildren() {
|
||||
const char* testGroupings[] = {
|
||||
"003", "021,013,029",
|
||||
"419", "013,029,005",
|
||||
"EU", "AT,BE,CY,CZ,DE,DK,EE,ES,FI,FR,GR,HR,HU,IE,IT,LT,LU,LV,MT,NL,PL,PT,SE,SI,SK,BG,RO"
|
||||
};
|
||||
|
||||
for (int32_t i = 0; i < UPRV_LENGTHOF(testGroupings); i += 2) {
|
||||
const char* groupingCode = testGroupings[i];
|
||||
const char* expectedChildren = testGroupings[i + 1];
|
||||
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
const URegion* grouping = uregion_getRegionFromCode(groupingCode, &err);
|
||||
if (U_SUCCESS(err)) {
|
||||
UEnumeration* actualChildren = uregion_getContainedRegions(grouping, &err);
|
||||
if (U_SUCCESS(err)) {
|
||||
int32_t numActualChildren = uenum_count(actualChildren, &err);
|
||||
int32_t numExpectedChildren = 0;
|
||||
const char* expectedChildStart = expectedChildren;
|
||||
const char* expectedChildEnd = NULL;
|
||||
const char* actualChild = NULL;
|
||||
while ((actualChild = uenum_next(actualChildren, NULL, &err)) != NULL && *expectedChildStart != '\0') {
|
||||
expectedChildEnd = uprv_strchr(expectedChildStart, ',');
|
||||
if (expectedChildEnd == NULL) {
|
||||
expectedChildEnd = expectedChildStart + uprv_strlen(expectedChildStart);
|
||||
}
|
||||
if (uprv_strlen(actualChild) != (size_t)(expectedChildEnd - expectedChildStart) || uprv_strncmp(actualChild, expectedChildStart, expectedChildEnd - expectedChildStart) != 0) {
|
||||
log_err("Mismatch in child list for %s at position %d: expected %s, got %s\n", groupingCode, i, expectedChildStart, actualChild);
|
||||
}
|
||||
expectedChildStart = (*expectedChildEnd != '\0') ? expectedChildEnd + 1 : expectedChildEnd;
|
||||
++numExpectedChildren;
|
||||
}
|
||||
if (expectedChildEnd == NULL) {
|
||||
expectedChildEnd = expectedChildren;
|
||||
}
|
||||
while (expectedChildEnd != NULL && *expectedChildEnd != '\0') {
|
||||
expectedChildEnd = uprv_strchr(expectedChildEnd + 1, ',');
|
||||
++numExpectedChildren;
|
||||
}
|
||||
if (numExpectedChildren != numActualChildren) {
|
||||
log_err("Wrong number of children for %s: expected %d, got %d\n", groupingCode, numExpectedChildren, numActualChildren);
|
||||
}
|
||||
uenum_close(actualChildren);
|
||||
} else {
|
||||
log_err("Couldn't create iterator for children of %s\n", groupingCode);
|
||||
}
|
||||
} else {
|
||||
log_err("Region %s not found\n", groupingCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TestGetContainedRegionsWithType() {
|
||||
const KnownRegion * rd;
|
||||
for (rd = knownRegions; rd->code != NULL ; rd++ ) {
|
||||
|
|
|
@ -358,6 +358,7 @@ RegionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char*
|
|||
TESTCASE_AUTO(TestContains);
|
||||
TESTCASE_AUTO(TestAvailableTerritories);
|
||||
TESTCASE_AUTO(TestNoContainedRegions);
|
||||
TESTCASE_AUTO(TestGroupingChildren);
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
|
||||
|
@ -733,6 +734,55 @@ void RegionTest::TestNoContainedRegions(void) {
|
|||
delete containedRegions;
|
||||
}
|
||||
|
||||
void RegionTest::TestGroupingChildren(void) {
|
||||
const char* testGroupings[] = {
|
||||
"003", "021,013,029",
|
||||
"419", "013,029,005",
|
||||
"EU", "AT,BE,CY,CZ,DE,DK,EE,ES,FI,FR,GR,HR,HU,IE,IT,LT,LU,LV,MT,NL,PL,PT,SE,SI,SK,BG,RO"
|
||||
};
|
||||
|
||||
for (int32_t i = 0; i < UPRV_LENGTHOF(testGroupings); i += 2) {
|
||||
const char* groupingCode = testGroupings[i];
|
||||
const char* expectedChildren = testGroupings[i + 1];
|
||||
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
const Region* grouping = Region::getInstance(groupingCode, err);
|
||||
if (U_SUCCESS(err)) {
|
||||
StringEnumeration* actualChildren = grouping->getContainedRegions(err);
|
||||
if (U_SUCCESS(err)) {
|
||||
int32_t numActualChildren = actualChildren->count(err);
|
||||
int32_t numExpectedChildren = 0;
|
||||
const char* expectedChildStart = expectedChildren;
|
||||
const char* expectedChildEnd = NULL;
|
||||
const char* actualChild = NULL;
|
||||
while ((actualChild = actualChildren->next(NULL, err)) != NULL && *expectedChildStart != '\0') {
|
||||
expectedChildEnd = uprv_strchr(expectedChildStart, ',');
|
||||
if (expectedChildEnd == NULL) {
|
||||
expectedChildEnd = expectedChildStart + uprv_strlen(expectedChildStart);
|
||||
}
|
||||
if (uprv_strlen(actualChild) != size_t(expectedChildEnd - expectedChildStart) || uprv_strncmp(actualChild, expectedChildStart, expectedChildEnd - expectedChildStart) != 0) {
|
||||
errln("Mismatch in child list for %s at position %d: expected %s, got %s\n", groupingCode, numExpectedChildren, expectedChildStart, actualChild);
|
||||
}
|
||||
expectedChildStart = (*expectedChildEnd != '\0') ? expectedChildEnd + 1 : expectedChildEnd;
|
||||
++numExpectedChildren;
|
||||
}
|
||||
while (expectedChildEnd != NULL && *expectedChildEnd != '\0') {
|
||||
expectedChildEnd = uprv_strchr(expectedChildEnd + 1, ',');
|
||||
++numExpectedChildren;
|
||||
}
|
||||
if (numExpectedChildren != numActualChildren) {
|
||||
errln("Wrong number of children for %s: expected %d, got %d\n", groupingCode, numExpectedChildren, numActualChildren);
|
||||
}
|
||||
delete actualChildren;
|
||||
} else {
|
||||
errln("Couldn't create iterator for children of %s\n", groupingCode);
|
||||
}
|
||||
} else {
|
||||
errln("Region %s not found\n", groupingCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
||||
//eof
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
void TestContains(void);
|
||||
void TestAvailableTerritories(void);
|
||||
void TestNoContainedRegions(void);
|
||||
void TestGroupingChildren(void);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -348,6 +348,23 @@ public class Region implements Comparable<Region> {
|
|||
}
|
||||
}
|
||||
|
||||
// Fill in the grouping containment resource as well
|
||||
for ( int i = 0 ; i < groupingContainment.getSize(); i++ ) {
|
||||
UResourceBundle mapping = groupingContainment.get(i);
|
||||
String parent = mapping.getKey();
|
||||
Region parentRegion = regionIDMap.get(parent);
|
||||
for ( int j = 0 ; j < mapping.getSize(); j++ ) {
|
||||
String child = mapping.getString(j);
|
||||
Region childRegion = regionIDMap.get(child);
|
||||
if ( parentRegion != null && childRegion != null ) {
|
||||
// Add the child region to the set of regions contained by the parent
|
||||
parentRegion.containedRegions.add(childRegion);
|
||||
// Do NOT change the parent of the child region, since groupings are
|
||||
// never the primary parent of a region.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the availableRegions lists
|
||||
|
||||
for (int i = 0 ; i < RegionType.values().length ; i++) {
|
||||
|
|
|
@ -587,4 +587,44 @@ public class RegionTest extends TestFmwk {
|
|||
"Contained in World = " + containedInWorld.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestGroupingChildren() {
|
||||
String[][][] testGroupings = {
|
||||
{ { "003" }, { "013", "021", "029" } },
|
||||
{ { "419" }, { "005", "013", "029" } },
|
||||
{ { "EU" }, { "AT", "BE", "BG", "CY", "CZ", "DE", "DK", "EE", "ES", "FI", "FR",
|
||||
"GR", "HR", "HU", "IE", "IT", "LT", "LU", "LV", "MT", "NL", "PL",
|
||||
"PT", "RO", "SE", "SI", "SK" } }
|
||||
};
|
||||
|
||||
for (String[][] testCase : testGroupings) {
|
||||
String groupingCode = testCase[0][0];
|
||||
String[] expectedChildren = testCase[1];
|
||||
|
||||
try {
|
||||
Region grouping = Region.getInstance(groupingCode);
|
||||
Set<Region> actualChildren = grouping.getContainedRegions();
|
||||
List<String> actualChildIDs = new java.util.ArrayList();
|
||||
for (Region childRegion : actualChildren) {
|
||||
actualChildIDs.add(childRegion.toString());
|
||||
}
|
||||
actualChildIDs.sort(null);
|
||||
|
||||
for (int i = 0; i < actualChildIDs.size() && i < expectedChildren.length; i++) {
|
||||
if (!expectedChildren[i].equals(actualChildIDs.get(i))) {
|
||||
errln("Mismatch in child list for " + groupingCode + " at position "
|
||||
+ i + ": expected " + expectedChildren[i] + ", got " + actualChildIDs.get(i));
|
||||
}
|
||||
}
|
||||
if (expectedChildren.length != actualChildIDs.size()) {
|
||||
errln("Wrong number of children for " + groupingCode + ": expected "
|
||||
+ expectedChildren.length + ", got " + actualChildIDs.size());
|
||||
}
|
||||
|
||||
} catch (IllegalArgumentException ex) {
|
||||
errln("Known region " + groupingCode + " was not recognized");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue