ICU-20602 add LocaleBuilder::copyErrorTo

Check the status after the setter and test err.

Add more check for errors.

change comments
This commit is contained in:
Frank Tang 2019-05-15 16:21:23 -07:00 committed by Frank Yung-Fong Tang
parent b7ffd7b6d0
commit bb22fc1a27
3 changed files with 78 additions and 13 deletions

View File

@ -433,4 +433,13 @@ Locale LocaleBuilder::build(UErrorCode& errorCode)
return product; return product;
} }
UBool LocaleBuilder::copyErrorTo(UErrorCode &outErrorCode) {
if (U_FAILURE(outErrorCode)) {
// Do not overwrite the older error code
return TRUE;
}
outErrorCode = status_;
return U_FAILURE(outErrorCode);
}
U_NAMESPACE_END U_NAMESPACE_END

View File

@ -279,6 +279,17 @@ public:
*/ */
Locale build(UErrorCode& status); Locale build(UErrorCode& status);
/**
* Sets the UErrorCode if an error occurred while recording sets.
* Preserves older error codes in the outErrorCode.
* @param outErrorCode Set to an error code that occurred while setting subtags.
* Unchanged if there is no such error or if outErrorCode
* already contained an error.
* @return TRUE if U_FAILURE(outErrorCode)
* @draft ICU 65
*/
UBool copyErrorTo(UErrorCode &outErrorCode);
private: private:
UErrorCode status_; UErrorCode status_;
char language_[9]; char language_[9];

View File

@ -55,10 +55,21 @@ void LocaleBuilderTest::runIndexedTest( int32_t index, UBool exec, const char* &
void LocaleBuilderTest::Verify(LocaleBuilder& bld, const char* expected, const char* msg) { void LocaleBuilderTest::Verify(LocaleBuilder& bld, const char* expected, const char* msg) {
UErrorCode status = U_ZERO_ERROR; UErrorCode status = U_ZERO_ERROR;
UErrorCode copyStatus = U_ZERO_ERROR;
UErrorCode errorStatus = U_ILLEGAL_ARGUMENT_ERROR;
if (bld.copyErrorTo(copyStatus)) {
errln(msg, u_errorName(copyStatus));
}
if (!bld.copyErrorTo(errorStatus) || errorStatus != U_ILLEGAL_ARGUMENT_ERROR) {
errln("Should always get the previous error and return FALSE");
}
Locale loc = bld.build(status); Locale loc = bld.build(status);
if (U_FAILURE(status)) { if (U_FAILURE(status)) {
errln(msg, u_errorName(status)); errln(msg, u_errorName(status));
} }
if (status != copyStatus) {
errln(msg, u_errorName(status));
}
std::string tag = loc.toLanguageTag<std::string>(status); std::string tag = loc.toLanguageTag<std::string>(status);
if (U_FAILURE(status)) { if (U_FAILURE(status)) {
errln("loc.toLanguageTag() got Error: %s\n", errln("loc.toLanguageTag() got Error: %s\n",
@ -190,39 +201,67 @@ void LocaleBuilderTest::TestLocaleBuilder() {
status = U_ZERO_ERROR; status = U_ZERO_ERROR;
bld.clear(); bld.clear();
while (true) { while (true) {
status = U_ZERO_ERROR;
UErrorCode copyStatus = U_ZERO_ERROR;
method = testCase[i++]; method = testCase[i++];
if (strcmp("L", method) == 0) { if (strcmp("L", method) == 0) {
bld.setLanguage(testCase[i++]).build(status); bld.setLanguage(testCase[i++]);
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("S", method) == 0) { } else if (strcmp("S", method) == 0) {
bld.setScript(testCase[i++]).build(status); bld.setScript(testCase[i++]);
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("R", method) == 0) { } else if (strcmp("R", method) == 0) {
bld.setRegion(testCase[i++]).build(status); bld.setRegion(testCase[i++]);
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("V", method) == 0) { } else if (strcmp("V", method) == 0) {
bld.setVariant(testCase[i++]).build(status); bld.setVariant(testCase[i++]);
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("K", method) == 0) { } else if (strcmp("K", method) == 0) {
const char* key = testCase[i++]; const char* key = testCase[i++];
const char* type = testCase[i++]; const char* type = testCase[i++];
bld.setUnicodeLocaleKeyword(key, type).build(status); bld.setUnicodeLocaleKeyword(key, type);
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("A", method) == 0) { } else if (strcmp("A", method) == 0) {
bld.addUnicodeLocaleAttribute(testCase[i++]).build(status); bld.addUnicodeLocaleAttribute(testCase[i++]);
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("E", method) == 0) { } else if (strcmp("E", method) == 0) {
const char* key = testCase[i++]; const char* key = testCase[i++];
const char* value = testCase[i++]; const char* value = testCase[i++];
bld.setExtension(key[0], value).build(status); bld.setExtension(key[0], value);
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("P", method) == 0) { } else if (strcmp("P", method) == 0) {
bld.setExtension('x', testCase[i++]).build(status); bld.setExtension('x', testCase[i++]);
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("U", method) == 0) { } else if (strcmp("U", method) == 0) {
bld.setLocale(Locale(testCase[i++])).build(status); bld.setLocale(Locale(testCase[i++]));
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("B", method) == 0) { } else if (strcmp("B", method) == 0) {
bld.setLanguageTag(testCase[i++]).build(status); bld.setLanguageTag(testCase[i++]);
bld.copyErrorTo(copyStatus);
bld.build(status);
} }
// clear / remove // clear / remove
else if (strcmp("C", method) == 0) { else if (strcmp("C", method) == 0) {
bld.clear().build(status); bld.clear();
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("N", method) == 0) { } else if (strcmp("N", method) == 0) {
bld.clearExtensions().build(status); bld.clearExtensions();
bld.copyErrorTo(copyStatus);
bld.build(status);
} else if (strcmp("D", method) == 0) { } else if (strcmp("D", method) == 0) {
bld.removeUnicodeLocaleAttribute(testCase[i++]).build(status); bld.removeUnicodeLocaleAttribute(testCase[i++]);
bld.copyErrorTo(copyStatus);
bld.build(status);
} }
// result // result
else if (strcmp("X", method) == 0) { else if (strcmp("X", method) == 0) {
@ -232,6 +271,9 @@ void LocaleBuilderTest::TestLocaleBuilder() {
} else if (strcmp("T", method) == 0) { } else if (strcmp("T", method) == 0) {
status = U_ZERO_ERROR; status = U_ZERO_ERROR;
Locale loc = bld.build(status); Locale loc = bld.build(status);
if (status != copyStatus) {
errln("copyErrorTo not matching");
}
if (U_FAILURE(status) || if (U_FAILURE(status) ||
strcmp(loc.getName(), testCase[i + 1]) != 0) { strcmp(loc.getName(), testCase[i + 1]) != 0) {
errln("FAIL: Wrong locale ID - %s %s %s", loc.getName(), errln("FAIL: Wrong locale ID - %s %s %s", loc.getName(),
@ -248,6 +290,9 @@ void LocaleBuilderTest::TestLocaleBuilder() {
errln("Unknown test case method: There is an error in the test case data."); errln("Unknown test case method: There is an error in the test case data.");
break; break;
} }
if (status != copyStatus) {
errln("copyErrorTo not matching");
}
if (U_FAILURE(status)) { if (U_FAILURE(status)) {
if (strcmp("X", testCase[i]) == 0) { if (strcmp("X", testCase[i]) == 0) {
// This failure is expected // This failure is expected