Skip to content

Commit

Permalink
chore: fix caseFirst issues and improve tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ramsey committed Jul 27, 2023
1 parent 95e5acc commit a2c80c8
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 62 deletions.
42 changes: 11 additions & 31 deletions src/ecma402/locale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,23 +217,7 @@ int ecma402_getCalendar(const char *localeId, char *calendar,

int ecma402_getCaseFirst(const char *localeId, char *caseFirst,
ecma402_errorStatus *status) {
char *value;
int valueLength;

value = (char *)malloc(sizeof(char) * ULOC_KEYWORDS_CAPACITY);
valueLength =
getKeywordValue(ICU_KEYWORD_CASE_FIRST, localeId, value, status);

if (valueLength > 0 && strcmp(value, "yes") == 0) {
strcpy(caseFirst, "");
valueLength = 0;
} else if (valueLength >= 0) {
strcpy(caseFirst, value);
}

free(value);

return valueLength;
return getKeywordValue(ICU_KEYWORD_CASE_FIRST, localeId, caseFirst, status);
}

int ecma402_getCollation(const char *localeId, char *collation,
Expand Down Expand Up @@ -395,7 +379,6 @@ int getKeywordValue(const char *keyword, const char *localeId,
char *canonicalized, *icuValue;
const char *bcp47Value;
UErrorCode icuStatus = U_ZERO_ERROR;
int icuValueLength;

if (localeId == nullptr) {
return -1;
Expand All @@ -411,8 +394,8 @@ int getKeywordValue(const char *keyword, const char *localeId,
}

icuValue = (char *)malloc(sizeof(char) * ULOC_KEYWORDS_CAPACITY);
icuValueLength = uloc_getKeywordValue(canonicalized, keyword, icuValue,
ULOC_KEYWORDS_CAPACITY, &icuStatus);
uloc_getKeywordValue(canonicalized, keyword, icuValue, ULOC_KEYWORDS_CAPACITY,
&icuStatus);
free(canonicalized);

if (U_FAILURE(icuStatus) != U_ZERO_ERROR) {
Expand All @@ -423,28 +406,25 @@ int getKeywordValue(const char *keyword, const char *localeId,
return -1;
}

if (strcmp(icuValue, "true") == 0) {
strcpy(returnValue, "");
free(icuValue);
return 0;
}

if (strcmp(icuValue, "yes") == 0) {
strcpy(returnValue, icuValue);
if (strcmp(keyword, ICU_KEYWORD_NUMERIC) == 0 &&
strcmp(icuValue, "yes") == 0) {
strcpy(returnValue, "yes");
free(icuValue);
return icuValueLength;
return 3;
}

bcp47Value = uloc_toUnicodeLocaleType(keyword, icuValue);
free(icuValue);

if (bcp47Value == nullptr) {
free(icuValue);
return -1;
}

const size_t bcp47Length = strlen(bcp47Value);
strcpy(returnValue, bcp47Value);
free(icuValue);

return strlen(bcp47Value);
return bcp47Length;
}

} // namespace
13 changes: 8 additions & 5 deletions tests/criterion/ecma402/locale_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ Test(TEST_SUITE, initLocale) {
cr_expect(eq(str, locale->calendar, "gregory"));
cr_expect(eq(str, locale->canonical,
"de-Latn-DE-u-ca-gregory-co-phonebk-hc-h23-kf-kn-nu-latn"));
cr_expect(eq(str, locale->caseFirst, ""));
cr_expect(eq(str, locale->caseFirst, "yes"));
cr_expect(eq(str, locale->collation, "phonebk"));
cr_expect(eq(str, locale->hourCycle, "h23"));
cr_expect(eq(str, locale->language, "de"));
Expand Down Expand Up @@ -500,12 +500,13 @@ ParameterizedTestParameters(TEST_SUITE, getCaseFirst) {
STRING_TEST("cmn-hans-cn-u-ca-t-ca-x-t-u", "-1")
STRING_TEST("de-gregory-u-ca-gregory", "-1")
STRING_TEST(
"de-latn-de-u-ca-gregory-co-phonebk-hc-h23-kf-true-kn-false-nu-latn", "")
"de-latn-de-u-ca-gregory-co-phonebk-hc-h23-kf-true-kn-false-nu-latn",
"yes")
STRING_TEST(
"ja-jpan-jp-u-ca-japanese-co-search-hc-h24-kf-false-kn-nu-jpanfin",
"false")
STRING_TEST("fr-latn-ca-u-ca-gregory-co-standard-hc-h11-kf-kn-false-nu-latn",
"")
"yes")
END_STRING_TEST_PARAMS;
}

Expand Down Expand Up @@ -702,9 +703,11 @@ ParameterizedTest(stringTestParams *test, TEST_SUITE, isNumeric) {
cr_assert(eq(i8, ecma402_hasError(status), 0));

if (strcmp(test->expected, "false") == 0) {
cr_expect(eq(i8, result, 0));
cr_expect(eq(i8, result, 0), "Expected false numeric for \"%s\"",
test->input);
} else {
cr_expect(eq(i8, result, 1));
cr_expect(eq(i8, result, 1), "Expected true numeric for \"%s\"",
test->input);
}
}

Expand Down
30 changes: 27 additions & 3 deletions tests/phpt/Intl/Locale-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,33 @@ ecma_intl
<?php
use Ecma\Intl\Locale;

$locale = new Locale('cmn-hans-cn-u-ca-t-ca-x-t-u');
$tests = [
'en',
'en-us',
'en-latn',
'en-latn-us',
'en-US-u-ca-gregory',
'en-u-kf-false',
'en-u-co-phonebk',
'en-u-hc-h12',
'en-u-kn-false',
'en-u-nu-arab',
'en-latn-us-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-kn-true',
];

echo $locale;
foreach ($tests as $test) {
echo (new Locale($test)) . "\n";
}

--EXPECT--
zh-Hans-CN-t-ca-u-ca-x-t-u
en
en-US
en-Latn
en-Latn-US
en-US-u-ca-gregory
en-u-kf-false
en-u-co-phonebk
en-u-hc-h12
en-u-kn-false
en-u-nu-arab
en-Latn-US-u-ca-gregory-co-emoji-hc-h23-kf-upper-kn-nu-latn
4 changes: 2 additions & 2 deletions tests/phpt/Intl/Locale-002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use Ecma\Intl\Locale;

$string = new class () {
public function __toString(): string {
return 'cmn-hans-cn-u-ca-t-ca-x-t-u';
return 'en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-kn';
}
};

Expand All @@ -17,4 +17,4 @@ $locale = new Locale($string);
echo $locale;

--EXPECT--
zh-Hans-CN-t-ca-u-ca-x-t-u
en-Latn-US-u-ca-gregory-co-emoji-hc-h23-kf-upper-kn-nu-latn
22 changes: 11 additions & 11 deletions tests/phpt/Intl/Locale-003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ ecma_intl
<?php
use Ecma\Intl\Locale;

$locale = new Locale('cmn-hans-cn-u-ca-t-ca-x-t-u');
$locale = new Locale('en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-kn');

var_export($locale);

--EXPECT--
\Ecma\Intl\Locale::__set_state(array(
'baseName' => 'zh-Hans-CN',
'calendar' => 'yes',
'caseFirst' => NULL,
'collation' => NULL,
'hourCycle' => NULL,
'language' => 'zh',
'numberingSystem' => NULL,
'numeric' => false,
'region' => 'CN',
'script' => 'Hans',
'baseName' => 'en-Latn-US',
'calendar' => 'gregory',
'caseFirst' => 'upper',
'collation' => 'emoji',
'hourCycle' => 'h23',
'language' => 'en',
'numberingSystem' => 'latn',
'numeric' => true,
'region' => 'US',
'script' => 'Latn',
))
30 changes: 27 additions & 3 deletions tests/phpt/Intl/Locale-004.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,33 @@ ecma_intl
<?php
use Ecma\Intl\Locale;

$locale = new Locale('cmn-hans-cn-u-ca-t-ca-x-t-u');
$tests = [
'en',
'en-us',
'en-latn',
'en-latn-us',
'en-US-u-ca-gregory',
'en-u-kf-false',
'en-u-co-phonebk',
'en-u-hc-h12',
'en-u-kn-false',
'en-u-nu-arab',
'en-latn-us-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-kn-true',
];

echo json_encode($locale) . "\n";
foreach ($tests as $test) {
echo json_encode(new Locale($test)) . "\n";
}

--EXPECT--
{"baseName":"zh-Hans-CN","calendar":"yes","caseFirst":null,"collation":null,"hourCycle":null,"language":"zh","numberingSystem":null,"numeric":false,"region":"CN","script":"Hans"}
{"baseName":"en","calendar":null,"caseFirst":null,"collation":null,"hourCycle":null,"language":"en","numberingSystem":null,"numeric":false,"region":null,"script":null}
{"baseName":"en-US","calendar":null,"caseFirst":null,"collation":null,"hourCycle":null,"language":"en","numberingSystem":null,"numeric":false,"region":"US","script":null}
{"baseName":"en-Latn","calendar":null,"caseFirst":null,"collation":null,"hourCycle":null,"language":"en","numberingSystem":null,"numeric":false,"region":null,"script":"Latn"}
{"baseName":"en-Latn-US","calendar":null,"caseFirst":null,"collation":null,"hourCycle":null,"language":"en","numberingSystem":null,"numeric":false,"region":"US","script":"Latn"}
{"baseName":"en-US","calendar":"gregory","caseFirst":null,"collation":null,"hourCycle":null,"language":"en","numberingSystem":null,"numeric":false,"region":"US","script":null}
{"baseName":"en","calendar":null,"caseFirst":"false","collation":null,"hourCycle":null,"language":"en","numberingSystem":null,"numeric":false,"region":null,"script":null}
{"baseName":"en","calendar":null,"caseFirst":null,"collation":"phonebk","hourCycle":null,"language":"en","numberingSystem":null,"numeric":false,"region":null,"script":null}
{"baseName":"en","calendar":null,"caseFirst":null,"collation":null,"hourCycle":"h12","language":"en","numberingSystem":null,"numeric":false,"region":null,"script":null}
{"baseName":"en","calendar":null,"caseFirst":null,"collation":null,"hourCycle":null,"language":"en","numberingSystem":null,"numeric":false,"region":null,"script":null}
{"baseName":"en","calendar":null,"caseFirst":null,"collation":null,"hourCycle":null,"language":"en","numberingSystem":"arab","numeric":false,"region":null,"script":null}
{"baseName":"en-Latn-US","calendar":"gregory","caseFirst":"upper","collation":"emoji","hourCycle":"h23","language":"en","numberingSystem":"latn","numeric":true,"region":"US","script":"Latn"}
39 changes: 32 additions & 7 deletions tests/phpt/Intl/Locale-005.phpt
Original file line number Diff line number Diff line change
@@ -1,17 +1,42 @@
--TEST--
Locale::$baseName is readonly
Locale properties are readonly
--EXTENSIONS--
ecma_intl
--FILE--
<?php
use Ecma\Intl\Locale;

$locale = new Locale('cmn-hans-cn-u-ca-t-ca-x-t-u');
$properties = [
'baseName' => 'en-Latn-US',
'calendar' => 'gregory',
'caseFirst' => 'upper',
'collation' => 'emoji',
'hourCycle' => 'h23',
'language' => 'en',
'numberingSystem' => 'latn',
'numeric' => true,
'region' => 'US',
'script' => 'Latn',
];

$locale->baseName = 'foo';
$locale = new Locale('en');

foreach ($properties as $property => $value) {
try {
$locale->{$property} = $value;
} catch (Error $error) {
echo $error->getMessage() . "\n";
}
}

--EXPECTF--
Fatal error: Uncaught Error: Cannot modify readonly property Ecma\Intl\Locale::$baseName in %s/Intl/Locale-005.php:%d
Stack trace:
#0 {main}
thrown in %s/Intl/Locale-005.php on line %d
Cannot modify readonly property Ecma\Intl\Locale::$baseName
Cannot modify readonly property Ecma\Intl\Locale::$calendar
Cannot modify readonly property Ecma\Intl\Locale::$caseFirst
Cannot modify readonly property Ecma\Intl\Locale::$collation
Cannot modify readonly property Ecma\Intl\Locale::$hourCycle
Cannot modify readonly property Ecma\Intl\Locale::$language
Cannot modify readonly property Ecma\Intl\Locale::$numberingSystem
Cannot modify readonly property Ecma\Intl\Locale::$numeric
Cannot modify readonly property Ecma\Intl\Locale::$region
Cannot modify readonly property Ecma\Intl\Locale::$script
32 changes: 32 additions & 0 deletions tests/phpt/Intl/Locale-006.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--TEST--
Locale can access each property
--EXTENSIONS--
ecma_intl
--FILE--
<?php
use Ecma\Intl\Locale;

$locale = new Locale('en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-kn');

var_dump($locale->baseName);
var_dump($locale->calendar);
var_dump($locale->caseFirst);
var_dump($locale->collation);
var_dump($locale->hourCycle);
var_dump($locale->language);
var_dump($locale->numberingSystem);
var_dump($locale->numeric);
var_dump($locale->region);
var_dump($locale->script);

--EXPECT--
string(10) "en-Latn-US"
string(7) "gregory"
string(5) "upper"
string(5) "emoji"
string(3) "h23"
string(2) "en"
string(4) "latn"
bool(true)
string(2) "US"
string(4) "Latn"
59 changes: 59 additions & 0 deletions tests/phpt/Intl/Locale-007.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
--TEST--
Locale must have a valid value
--EXTENSIONS--
ecma_intl
--FILE--
<?php
use Ecma\Intl\Locale;

$tests = [
'',
'e',
'en-',
'en-Lat',
'en-Latn-',
'en-Latn-USA',
'en-Latn-US-',
'en-Latn-US-u-ca-gregoryab',
'en-Latn-US-u-ca-gregory-',
'en-Latn-US-u-ca-gregory-kf-upperabcd',
'en-Latn-US-u-ca-gregory-kf-upper-',
'en-Latn-US-u-ca-gregory-kf-upper-co-emojiabcd',
'en-Latn-US-u-ca-gregory-kf-upper-co-emoji-',
'en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23abcdef',
'en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-',
'en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latnabcde',
'en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-',
'en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-kn-falseabcd',
'en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-kn-false-',
];

foreach ($tests as $test) {
try {
$loc = new Locale($test);
echo json_encode($loc) . "\n";
} catch (ValueError $exception) {
echo $exception->getMessage() . "\n";
}
}

--EXPECT--
Invalid language tag ""
Invalid language tag "e"
Invalid language tag "en-"
Invalid language tag "en-Lat"
Invalid language tag "en-Latn-"
Invalid language tag "en-Latn-USA"
Invalid language tag "en-Latn-US-"
Invalid language tag "en-Latn-US-u-ca-gregoryab"
Invalid language tag "en-Latn-US-u-ca-gregory-"
Invalid language tag "en-Latn-US-u-ca-gregory-kf-upperabcd"
Invalid language tag "en-Latn-US-u-ca-gregory-kf-upper-"
Invalid language tag "en-Latn-US-u-ca-gregory-kf-upper-co-emojiabcd"
Invalid language tag "en-Latn-US-u-ca-gregory-kf-upper-co-emoji-"
Invalid language tag "en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23abcdef"
Invalid language tag "en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-"
Invalid language tag "en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latnabcde"
Invalid language tag "en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-"
Invalid language tag "en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-kn-falseabcd"
Invalid language tag "en-Latn-US-u-ca-gregory-kf-upper-co-emoji-hc-h23-nu-latn-kn-false-"

0 comments on commit a2c80c8

Please sign in to comment.