From 8547cec1d90751499da29c8434bfed46d52080ef Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Mon, 17 Aug 2026 13:20:17 +0300 Subject: [PATCH 1/3] Unfold TestLocaleClass (and other Locale class-related tests) to test_locale_class --- tests/test_core.py | 241 ------------------------------- tests/test_locale_class.py | 280 +++++++++++++++++++++++++++++++++++++ 2 files changed, 280 insertions(+), 241 deletions(-) create mode 100644 tests/test_locale_class.py diff --git a/tests/test_core.py b/tests/test_core.py index 117f8697c..2c1e6d92e 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -16,34 +16,6 @@ from babel.core import Locale, default_locale -def test_locale_provides_access_to_cldr_locale_data(): - locale = Locale('en', 'US') - assert locale.display_name == 'English (United States)' - assert locale.number_symbols["latn"]['decimal'] == '.' - - -def test_locale_repr(): - # fmt: off - assert repr(Locale('en', 'US')) == "Locale('en', territory='US')" - assert repr(Locale('de', 'DE')) == "Locale('de', territory='DE')" - assert repr(Locale('zh', 'CN', script='Hans')) == "Locale('zh', territory='CN', script='Hans')" - # fmt: on - - -def test_locale_comparison(): - en_US = Locale('en', 'US') - en_US_2 = Locale('en', 'US') - fi_FI = Locale('fi', 'FI') - bad_en_US = Locale('en_US') - assert en_US == en_US - assert en_US == en_US_2 - assert en_US != fi_FI - assert not (en_US != en_US_2) - assert en_US is not None - assert en_US != bad_en_US - assert fi_FI != bad_en_US - - def test_can_return_default_locale(monkeypatch): monkeypatch.setenv('LC_MESSAGES', 'fr_FR.UTF-8') assert Locale('fr', 'FR') == Locale.default('LC_MESSAGES') @@ -71,206 +43,6 @@ def test_zone_aliases_and_territories(): assert aliases['Europe/Kiev'] == 'Europe/Kyiv' -def test_hash(): - locale_a = Locale('en', 'US') - locale_b = Locale('en', 'US') - locale_c = Locale('fi', 'FI') - assert hash(locale_a) == hash(locale_b) - assert hash(locale_a) != hash(locale_c) - - -class TestLocaleClass: - def test_attributes(self): - locale = Locale('en', 'US') - assert locale.language == 'en' - assert locale.territory == 'US' - - def test_default(self, monkeypatch): - for name in ['LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES']: - monkeypatch.setenv(name, '') - monkeypatch.setenv('LANG', 'fr_FR.UTF-8') - default = Locale.default('LC_MESSAGES') - assert (default.language, default.territory) == ('fr', 'FR') - - def test_negotiate(self): - de_DE = Locale.negotiate(['de_DE', 'en_US'], ['de_DE', 'de_AT']) - assert (de_DE.language, de_DE.territory) == ('de', 'DE') - de = Locale.negotiate(['de_DE', 'en_US'], ['en', 'de']) - assert (de.language, de.territory) == ('de', None) - nothing = Locale.negotiate(['de_DE', 'de'], ['en_US']) - assert nothing is None - - def test_negotiate_custom_separator(self): - de_DE = Locale.negotiate(['de-DE', 'de'], ['en-us', 'de-de'], sep='-') - assert (de_DE.language, de_DE.territory) == ('de', 'DE') - - def test_parse(self): - locale = Locale.parse('de-DE', sep='-') - assert locale.display_name == 'Deutsch (Deutschland)' - - de_DE = Locale.parse(locale) - assert (de_DE.language, de_DE.territory) == ('de', 'DE') - - def test_parse_likely_subtags(self): - locale = Locale.parse('zh-TW', sep='-') - assert locale.language == 'zh' - assert locale.territory == 'TW' - assert locale.script == 'Hant' - - locale = Locale.parse('zh_CN') - assert locale.language == 'zh' - assert locale.territory == 'CN' - assert locale.script == 'Hans' - - locale = Locale.parse('zh_SG') - assert locale.language == 'zh' - assert locale.territory == 'SG' - assert locale.script == 'Hans' - - locale = Locale.parse('und_AT') - assert locale.language == 'de' - assert locale.territory == 'AT' - - locale = Locale.parse('und_UK') - assert locale.language == 'en' - assert locale.territory == 'GB' - assert locale.script is None - - def test_get_display_name(self): - zh_CN = Locale('zh', 'CN', script='Hans') - assert zh_CN.get_display_name('en') == 'Chinese (Simplified, China)' - - def test_display_name_property(self): - assert Locale('en').display_name == 'English' - assert Locale('en', 'US').display_name == 'English (United States)' - assert Locale('sv').display_name == 'svenska' - - def test_english_name_property(self): - assert Locale('de').english_name == 'German' - assert Locale('de', 'DE').english_name == 'German (Germany)' - - def test_languages_property(self): - assert Locale('de', 'DE').languages['ja'] == 'Japanisch' - - def test_scripts_property(self): - assert Locale('en', 'US').scripts['Hira'] == 'Hiragana' - - def test_territories_property(self): - assert Locale('es', 'CO').territories['DE'] == 'Alemania' - - def test_variants_property(self): - assert Locale('de', 'DE').variants['1901'] == 'Alte deutsche Rechtschreibung' - - def test_currencies_property(self): - assert Locale('en').currencies['COP'] == 'Colombian Peso' - assert Locale('de', 'DE').currencies['COP'] == 'Kolumbianischer Peso' - - def test_currency_symbols_property(self): - assert Locale('en', 'US').currency_symbols['USD'] == '$' - assert Locale('es', 'CO').currency_symbols['USD'] == 'US$' - - def test_number_symbols_property(self): - assert Locale('fr', 'FR').number_symbols["latn"]['decimal'] == ',' - assert Locale('ar', 'IL').number_symbols["arab"]['percentSign'] == '٪\u061c' - assert Locale('ar', 'IL').number_symbols["latn"]['percentSign'] == '\u200e%\u200e' - - def test_other_numbering_systems_property(self): - assert Locale('fr', 'FR').other_numbering_systems['native'] == 'latn' - assert 'traditional' not in Locale('fr', 'FR').other_numbering_systems - - assert Locale('el', 'GR').other_numbering_systems['native'] == 'latn' - assert Locale('el', 'GR').other_numbering_systems['traditional'] == 'grek' - - def test_default_numbering_systems_property(self): - assert Locale('en', 'GB').default_numbering_system == 'latn' - assert Locale('ar', 'EG').default_numbering_system == 'arab' - - @pytest.mark.all_locales - def test_all_locales_have_default_numbering_system(self, locale): - locale = Locale.parse(locale) - assert locale.default_numbering_system - - def test_decimal_formats(self): - assert Locale('en', 'US').decimal_formats[None].pattern == '#,##0.###' - - def test_currency_formats_property(self): - en_us_currency_format = Locale('en', 'US').currency_formats - assert en_us_currency_format['standard'].pattern == '\xa4#,##0.00' - assert en_us_currency_format['accounting'].pattern == '\xa4#,##0.00;(\xa4#,##0.00)' - - def test_percent_formats_property(self): - assert Locale('en', 'US').percent_formats[None].pattern == '#,##0%' - - def test_scientific_formats_property(self): - assert Locale('en', 'US').scientific_formats[None].pattern == '#E0' - - def test_periods_property(self): - assert Locale('en', 'US').periods['am'] == 'AM' - - def test_days_property(self): - assert Locale('de', 'DE').days['format']['wide'][3] == 'Donnerstag' - - def test_months_property(self): - assert Locale('de', 'DE').months['format']['wide'][10] == 'Oktober' - - def test_quarters_property(self): - assert Locale('de', 'DE').quarters['format']['wide'][1] == '1. Quartal' - - def test_eras_property(self): - assert Locale('en', 'US').eras['wide'][1] == 'Anno Domini' - assert Locale('en', 'US').eras['abbreviated'][0] == 'BC' - - def test_time_zones_property(self): - time_zones = Locale('en', 'US').time_zones - assert time_zones['Europe/London']['long']['daylight'] == 'British Summer Time' - assert time_zones['America/St_Johns']['city'] == 'St. John\u2019s' - - def test_meta_zones_property(self): - meta_zones = Locale('en', 'US').meta_zones - assert ( - meta_zones['Europe_Central']['long']['daylight'] == 'Central European Summer Time' - ) - - def test_zone_formats_property(self): - assert Locale('en', 'US').zone_formats['fallback'] == '%(1)s (%(0)s)' - assert Locale('pt', 'BR').zone_formats['region'] == 'Hor\xe1rio %s' - - def test_first_week_day_property(self): - assert Locale('de', 'DE').first_week_day == 0 - assert Locale('en', 'US').first_week_day == 6 - - def test_weekend_start_property(self): - assert Locale('de', 'DE').weekend_start == 5 - - def test_weekend_end_property(self): - assert Locale('de', 'DE').weekend_end == 6 - - def test_min_week_days_property(self): - assert Locale('de', 'DE').min_week_days == 4 - - def test_date_formats_property(self): - assert Locale('en', 'US').date_formats['short'].pattern == 'M/d/yy' - assert Locale('fr', 'FR').date_formats['long'].pattern == 'd MMMM y' - - def test_time_formats_property(self): - assert Locale('en', 'US').time_formats['short'].pattern == 'h:mm\u202fa' - assert Locale('fr', 'FR').time_formats['long'].pattern == 'HH:mm:ss z' - - def test_datetime_formats_property(self): - assert Locale('en').datetime_formats['full'] == "{1}, {0}" - assert Locale('th').datetime_formats['medium'] == '{1} {0}' - - def test_datetime_skeleton_property(self): - assert Locale('en').datetime_skeletons['Md'].pattern == "M/d" - assert Locale('th').datetime_skeletons['Md'].pattern == 'd/M' - - def test_plural_form_property(self): - assert Locale('en').plural_form(1) == 'one' - assert Locale('en').plural_form(0) == 'other' - assert Locale('fr').plural_form(0) == 'one' - assert Locale('ru').plural_form(100) == 'many' - - def test_default_locale(monkeypatch): for name in ['LANGUAGE', 'LANG', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES']: monkeypatch.setenv(name, '') @@ -399,19 +171,6 @@ def test_issue_1112(): ) -def test_language_alt_official_not_used(): - # If there exists an official and customary language name, the customary - # name should be used. - # - # For example, here 'Muscogee' should be used instead of 'Mvskoke': - # Muscogee - # Mvskoke - - locale = Locale('mus') - assert locale.get_display_name() == 'Mvskoke' - assert locale.get_display_name(Locale('en')) == 'Muscogee' - - def test_locale_parse_empty(): with pytest.raises(ValueError, match="Empty") as ei: Locale.parse("") diff --git a/tests/test_locale_class.py b/tests/test_locale_class.py new file mode 100644 index 000000000..5ddb3e876 --- /dev/null +++ b/tests/test_locale_class.py @@ -0,0 +1,280 @@ +import pytest + +from babel import Locale + + +def test_attributes(): + locale = Locale('en', 'US') + assert locale.language == 'en' + assert locale.territory == 'US' + + +def test_default(monkeypatch): + for name in ['LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES']: + monkeypatch.setenv(name, '') + monkeypatch.setenv('LANG', 'fr_FR.UTF-8') + default = Locale.default('LC_MESSAGES') + assert (default.language, default.territory) == ('fr', 'FR') + + +def test_negotiate(): + de_DE = Locale.negotiate(['de_DE', 'en_US'], ['de_DE', 'de_AT']) + assert (de_DE.language, de_DE.territory) == ('de', 'DE') + de = Locale.negotiate(['de_DE', 'en_US'], ['en', 'de']) + assert (de.language, de.territory) == ('de', None) + nothing = Locale.negotiate(['de_DE', 'de'], ['en_US']) + assert nothing is None + + +def test_negotiate_custom_separator(): + de_DE = Locale.negotiate(['de-DE', 'de'], ['en-us', 'de-de'], sep='-') + assert (de_DE.language, de_DE.territory) == ('de', 'DE') + + +def test_parse(): + locale = Locale.parse('de-DE', sep='-') + assert locale.display_name == 'Deutsch (Deutschland)' + + de_DE = Locale.parse(locale) + assert (de_DE.language, de_DE.territory) == ('de', 'DE') + + +def test_parse_likely_subtags(): + locale = Locale.parse('zh-TW', sep='-') + assert locale.language == 'zh' + assert locale.territory == 'TW' + assert locale.script == 'Hant' + + locale = Locale.parse('zh_CN') + assert locale.language == 'zh' + assert locale.territory == 'CN' + assert locale.script == 'Hans' + + locale = Locale.parse('zh_SG') + assert locale.language == 'zh' + assert locale.territory == 'SG' + assert locale.script == 'Hans' + + locale = Locale.parse('und_AT') + assert locale.language == 'de' + assert locale.territory == 'AT' + + locale = Locale.parse('und_UK') + assert locale.language == 'en' + assert locale.territory == 'GB' + assert locale.script is None + + +def test_get_display_name(): + zh_CN = Locale('zh', 'CN', script='Hans') + assert zh_CN.get_display_name('en') == 'Chinese (Simplified, China)' + + +def test_display_name_property(): + assert Locale('en').display_name == 'English' + assert Locale('en', 'US').display_name == 'English (United States)' + assert Locale('sv').display_name == 'svenska' + + +def test_english_name_property(): + assert Locale('de').english_name == 'German' + assert Locale('de', 'DE').english_name == 'German (Germany)' + + +def test_languages_property(): + assert Locale('de', 'DE').languages['ja'] == 'Japanisch' + + +def test_scripts_property(): + assert Locale('en', 'US').scripts['Hira'] == 'Hiragana' + + +def test_territories_property(): + assert Locale('es', 'CO').territories['DE'] == 'Alemania' + + +def test_variants_property(): + assert Locale('de', 'DE').variants['1901'] == 'Alte deutsche Rechtschreibung' + + +def test_currencies_property(): + assert Locale('en').currencies['COP'] == 'Colombian Peso' + assert Locale('de', 'DE').currencies['COP'] == 'Kolumbianischer Peso' + + +def test_currency_symbols_property(): + assert Locale('en', 'US').currency_symbols['USD'] == '$' + assert Locale('es', 'CO').currency_symbols['USD'] == 'US$' + + +def test_number_symbols_property(): + assert Locale('fr', 'FR').number_symbols["latn"]['decimal'] == ',' + assert Locale('ar', 'IL').number_symbols["arab"]['percentSign'] == '٪\u061c' + assert Locale('ar', 'IL').number_symbols["latn"]['percentSign'] == '\u200e%\u200e' + + +def test_other_numbering_systems_property(): + assert Locale('fr', 'FR').other_numbering_systems['native'] == 'latn' + assert 'traditional' not in Locale('fr', 'FR').other_numbering_systems + + assert Locale('el', 'GR').other_numbering_systems['native'] == 'latn' + assert Locale('el', 'GR').other_numbering_systems['traditional'] == 'grek' + + +def test_default_numbering_systems_property(): + assert Locale('en', 'GB').default_numbering_system == 'latn' + assert Locale('ar', 'EG').default_numbering_system == 'arab' + + +@pytest.mark.all_locales +def test_all_locales_have_default_numbering_system(locale): + locale = Locale.parse(locale) + assert locale.default_numbering_system + + +def test_decimal_formats(): + assert Locale('en', 'US').decimal_formats[None].pattern == '#,##0.###' + + +def test_currency_formats_property(): + en_us_currency_format = Locale('en', 'US').currency_formats + assert en_us_currency_format['standard'].pattern == '\xa4#,##0.00' + assert en_us_currency_format['accounting'].pattern == '\xa4#,##0.00;(\xa4#,##0.00)' + + +def test_percent_formats_property(): + assert Locale('en', 'US').percent_formats[None].pattern == '#,##0%' + + +def test_scientific_formats_property(): + assert Locale('en', 'US').scientific_formats[None].pattern == '#E0' + + +def test_periods_property(): + assert Locale('en', 'US').periods['am'] == 'AM' + + +def test_days_property(): + assert Locale('de', 'DE').days['format']['wide'][3] == 'Donnerstag' + + +def test_months_property(): + assert Locale('de', 'DE').months['format']['wide'][10] == 'Oktober' + + +def test_quarters_property(): + assert Locale('de', 'DE').quarters['format']['wide'][1] == '1. Quartal' + + +def test_eras_property(): + assert Locale('en', 'US').eras['wide'][1] == 'Anno Domini' + assert Locale('en', 'US').eras['abbreviated'][0] == 'BC' + + +def test_time_zones_property(): + time_zones = Locale('en', 'US').time_zones + assert time_zones['Europe/London']['long']['daylight'] == 'British Summer Time' + assert time_zones['America/St_Johns']['city'] == 'St. John\u2019s' + + +def test_meta_zones_property(): + meta_zones = Locale('en', 'US').meta_zones + assert meta_zones['Europe_Central']['long']['daylight'] == 'Central European Summer Time' + + +def test_zone_formats_property(): + assert Locale('en', 'US').zone_formats['fallback'] == '%(1)s (%(0)s)' + assert Locale('pt', 'BR').zone_formats['region'] == 'Hor\xe1rio %s' + + +def test_first_week_day_property(): + assert Locale('de', 'DE').first_week_day == 0 + assert Locale('en', 'US').first_week_day == 6 + + +def test_weekend_start_property(): + assert Locale('de', 'DE').weekend_start == 5 + + +def test_weekend_end_property(): + assert Locale('de', 'DE').weekend_end == 6 + + +def test_min_week_days_property(): + assert Locale('de', 'DE').min_week_days == 4 + + +def test_date_formats_property(): + assert Locale('en', 'US').date_formats['short'].pattern == 'M/d/yy' + assert Locale('fr', 'FR').date_formats['long'].pattern == 'd MMMM y' + + +def test_time_formats_property(): + assert Locale('en', 'US').time_formats['short'].pattern == 'h:mm\u202fa' + assert Locale('fr', 'FR').time_formats['long'].pattern == 'HH:mm:ss z' + + +def test_datetime_formats_property(): + assert Locale('en').datetime_formats['full'] == "{1}, {0}" + assert Locale('th').datetime_formats['medium'] == '{1} {0}' + + +def test_datetime_skeleton_property(): + assert Locale('en').datetime_skeletons['Md'].pattern == "M/d" + assert Locale('th').datetime_skeletons['Md'].pattern == 'd/M' + + +def test_plural_form_property(): + assert Locale('en').plural_form(1) == 'one' + assert Locale('en').plural_form(0) == 'other' + assert Locale('fr').plural_form(0) == 'one' + assert Locale('ru').plural_form(100) == 'many' + + +def test_locale_provides_access_to_cldr_locale_data(): + locale = Locale('en', 'US') + assert locale.display_name == 'English (United States)' + assert locale.number_symbols["latn"]['decimal'] == '.' + + +def test_locale_repr(): + # fmt: off + assert repr(Locale('en', 'US')) == "Locale('en', territory='US')" + assert repr(Locale('de', 'DE')) == "Locale('de', territory='DE')" + assert repr(Locale('zh', 'CN', script='Hans')) == "Locale('zh', territory='CN', script='Hans')" + # fmt: on + + +def test_locale_comparison(): + en_US = Locale('en', 'US') + en_US_2 = Locale('en', 'US') + fi_FI = Locale('fi', 'FI') + bad_en_US = Locale('en_US') + assert en_US == en_US + assert en_US == en_US_2 + assert en_US != fi_FI + assert not (en_US != en_US_2) + assert en_US is not None + assert en_US != bad_en_US + assert fi_FI != bad_en_US + + +def test_hash(): + locale_a = Locale('en', 'US') + locale_b = Locale('en', 'US') + locale_c = Locale('fi', 'FI') + assert hash(locale_a) == hash(locale_b) + assert hash(locale_a) != hash(locale_c) + + +def test_language_alt_official_not_used(): + # If there exists an official and customary language name, the customary + # name should be used. + # + # For example, here 'Muscogee' should be used instead of 'Mvskoke': + # Muscogee + # Mvskoke + + locale = Locale('mus') + assert locale.get_display_name() == 'Mvskoke' + assert locale.get_display_name(Locale('en')) == 'Muscogee' From c7752bfa80e9ab66854fd6e395a1676b693f9392 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Mon, 17 Aug 2026 13:23:56 +0300 Subject: [PATCH 2/3] Unfold DateTimeFormat test cases into test_date_time_format.py These had been un-run since 14216ed8, accidentally. --- tests/test_date_time_format.py | 226 +++++++++++++++++++++++++++++++++ tests/test_dates.py | 221 ++------------------------------ 2 files changed, 239 insertions(+), 208 deletions(-) create mode 100644 tests/test_date_time_format.py diff --git a/tests/test_date_time_format.py b/tests/test_date_time_format.py new file mode 100644 index 000000000..5ca620879 --- /dev/null +++ b/tests/test_date_time_format.py @@ -0,0 +1,226 @@ +from datetime import date, datetime, time + +from babel.dates import DateTimeFormat, _localize + + +def test_quarter_format(): + d = date(2006, 6, 8) + fmt = DateTimeFormat(d, locale='en_US') + assert fmt['Q'] == '2' + assert fmt['QQQQ'] == '2nd quarter' + assert fmt['q'] == '2' + assert fmt['qqqq'] == '2nd quarter' + d = date(2006, 12, 31) + fmt = DateTimeFormat(d, locale='en_US') + assert fmt['qqq'] == 'Q4' + assert fmt['qqqqq'] == '4' + assert fmt['QQQ'] == 'Q4' + assert fmt['QQQQQ'] == '4' + + +def test_month_context(): + d = date(2006, 2, 8) + assert DateTimeFormat(d, locale='mt_MT')['MMMMM'] == 'F' # narrow format + assert DateTimeFormat(d, locale='mt_MT')['LLLLL'] == 'Fr' # narrow standalone + + +def test_abbreviated_month_alias(): + d = date(2006, 3, 8) + assert DateTimeFormat(d, locale='de_DE')['LLL'] == 'Mär' + + +def test_week_of_year_first(): + d = date(2006, 1, 8) + assert DateTimeFormat(d, locale='de_DE')['w'] == '1' + assert DateTimeFormat(d, locale='en_US')['ww'] == '02' + + +def test_week_of_year_first_with_year(): + d = date(2006, 1, 1) + fmt = DateTimeFormat(d, locale='de_DE') + assert fmt['w'] == '52' + assert fmt['YYYY'] == '2005' + + +def test_week_of_year_last(): + d = date(2006, 12, 26) + assert DateTimeFormat(d, locale='de_DE')['w'] == '52' + assert DateTimeFormat(d, locale='en_US')['w'] == '52' + + +def test_week_of_year_last_us_extra_week(): + d = date(2005, 12, 26) + assert DateTimeFormat(d, locale='de_DE')['w'] == '52' + assert DateTimeFormat(d, locale='en_US')['w'] == '53' + + +def test_week_of_year_de_first_us_last_with_year(): + d = date(2018, 12, 31) + fmt = DateTimeFormat(d, locale='de_DE') + assert fmt['w'] == '1' + assert fmt['YYYY'] == '2019' + fmt = DateTimeFormat(d, locale='en_US') + # See 363ad753, issue #1179 + assert fmt['w'] == '1' + assert fmt['YYYY'] == '2019' + + +def test_week_of_month_first(): + d = date(2006, 1, 8) + assert DateTimeFormat(d, locale='de_DE')['W'] == '1' + assert DateTimeFormat(d, locale='en_US')['W'] == '2' + + +def test_week_of_month_last(): + d = date(2006, 1, 29) + assert DateTimeFormat(d, locale='de_DE')['W'] == '4' + assert DateTimeFormat(d, locale='en_US')['W'] == '5' + + +def test_day_of_year(): + d = date(2007, 4, 1) + assert DateTimeFormat(d, locale='en_US')['D'] == '91' + + +def test_day_of_year_works_with_datetime(): + d = datetime(2007, 4, 1) + assert DateTimeFormat(d, locale='en_US')['D'] == '91' + + +def test_day_of_year_first(): + d = date(2007, 1, 1) + assert DateTimeFormat(d, locale='en_US')['DDD'] == '001' + + +def test_day_of_year_last(): + d = date(2007, 12, 31) + assert DateTimeFormat(d, locale='en_US')['DDD'] == '365' + + +def test_day_of_week_in_month(): + d = date(2007, 4, 15) + assert DateTimeFormat(d, locale='en_US')['F'] == '3' + + +def test_day_of_week_in_month_first(): + d = date(2007, 4, 1) + assert DateTimeFormat(d, locale='en_US')['F'] == '1' + + +def test_day_of_week_in_month_last(): + d = date(2007, 4, 29) + assert DateTimeFormat(d, locale='en_US')['F'] == '5' + + +def test_local_day_of_week(): + d = date(2007, 4, 1) # a sunday + assert DateTimeFormat(d, locale='de_DE')['e'] == '7' # monday is first day of week + assert DateTimeFormat(d, locale='en_US')['ee'] == '01' # sunday is first day of week + assert DateTimeFormat(d, locale='ar_BH')['ee'] == '02' # saturday is first day of week + + d = date(2007, 4, 2) # a monday + assert DateTimeFormat(d, locale='de_DE')['e'] == '1' # monday is first day of week + assert DateTimeFormat(d, locale='en_US')['ee'] == '02' # sunday is first day of week + assert DateTimeFormat(d, locale='ar_BH')['ee'] == '03' # saturday is first day of week + + +def test_local_day_of_week_standalone(): + d = date(2007, 4, 1) # a sunday + assert DateTimeFormat(d, locale='de_DE')['c'] == '7' # monday is first day of week + assert DateTimeFormat(d, locale='en_US')['c'] == '1' # sunday is first day of week + assert DateTimeFormat(d, locale='ar_BH')['c'] == '2' # saturday is first day of week + + d = date(2007, 4, 2) # a monday + assert DateTimeFormat(d, locale='de_DE')['c'] == '1' # monday is first day of week + assert DateTimeFormat(d, locale='en_US')['c'] == '2' # sunday is first day of week + assert DateTimeFormat(d, locale='ar_BH')['c'] == '3' # saturday is first day of week + + +def test_pattern_day_of_week(): + dt = datetime(2016, 2, 6) + fmt = DateTimeFormat(dt, locale='en_US') + assert fmt['c'] == '7' + assert fmt['ccc'] == 'Sat' + assert fmt['cccc'] == 'Saturday' + assert fmt['ccccc'] == 'S' + assert fmt['cccccc'] == 'Sa' + assert fmt['e'] == '7' + assert fmt['ee'] == '07' + assert fmt['eee'] == 'Sat' + assert fmt['eeee'] == 'Saturday' + assert fmt['eeeee'] == 'S' + assert fmt['eeeeee'] == 'Sa' + assert fmt['E'] == 'Sat' + assert fmt['EE'] == 'Sat' + assert fmt['EEE'] == 'Sat' + assert fmt['EEEE'] == 'Saturday' + assert fmt['EEEEE'] == 'S' + assert fmt['EEEEEE'] == 'Sa' + fmt = DateTimeFormat(dt, locale='uk') + assert fmt['c'] == '6' + assert fmt['e'] == '6' + assert fmt['ee'] == '06' + + +def test_fractional_seconds(): + t = time(8, 3, 9, 799) + assert DateTimeFormat(t, locale='en_US')['S'] == '0' + t = time(8, 3, 1, 799) + assert DateTimeFormat(t, locale='en_US')['SSSS'] == '0008' + t = time(8, 3, 1, 34567) + assert DateTimeFormat(t, locale='en_US')['SSSS'] == '0346' + t = time(8, 3, 1, 345678) + assert DateTimeFormat(t, locale='en_US')['SSSSSS'] == '345678' + t = time(8, 3, 1, 799) + assert DateTimeFormat(t, locale='en_US')['SSSSS'] == '00080' + + +def test_fractional_seconds_zero(): + t = time(15, 30, 0) + assert DateTimeFormat(t, locale='en_US')['SSSS'] == '0000' + + +def test_milliseconds_in_day(): + t = time(15, 30, 12, 345000) + assert DateTimeFormat(t, locale='en_US')['AAAA'] == '55812345' + + +def test_milliseconds_in_day_zero(): + d = time(0, 0, 0) + assert DateTimeFormat(d, locale='en_US')['AAAA'] == '0000' + + +def test_timezone_rfc822(timezone_getter): + tz = timezone_getter('Europe/Berlin') + t = _localize(tz, datetime(2015, 1, 1, 15, 30)) + assert DateTimeFormat(t, locale='de_DE')['Z'] == '+0100' + + +def test_timezone_gmt(timezone_getter): + tz = timezone_getter('Europe/Berlin') + t = _localize(tz, datetime(2015, 1, 1, 15, 30)) + assert DateTimeFormat(t, locale='de_DE')['ZZZZ'] == 'GMT+01:00' + + +def test_timezone_name(timezone_getter): + tz = timezone_getter('Europe/Paris') + dt = _localize(tz, datetime(2007, 4, 1, 15, 30)) + assert DateTimeFormat(dt, locale='fr_FR')['v'] == 'heure : France' + + +def test_timezone_location_format(timezone_getter): + tz = timezone_getter('Europe/Paris') + dt = _localize(tz, datetime(2007, 4, 1, 15, 30)) + assert DateTimeFormat(dt, locale='fr_FR')['VVVV'] == 'heure : France' + + +def test_timezone_walltime_short(timezone_getter): + tz = timezone_getter('Europe/Paris') + t = time(15, 30, tzinfo=tz) + assert DateTimeFormat(t, locale='fr_FR')['v'] == 'heure : France' + + +def test_timezone_walltime_long(timezone_getter): + tz = timezone_getter('Europe/Paris') + t = time(15, 30, tzinfo=tz) + assert DateTimeFormat(t, locale='fr_FR')['vvvv'] == 'heure d’Europe centrale' diff --git a/tests/test_dates.py b/tests/test_dates.py index 2eacdb312..3672bb80b 100644 --- a/tests/test_dates.py +++ b/tests/test_dates.py @@ -21,214 +21,6 @@ from babel.util import FixedOffsetTimezone -class DateTimeFormatTestCase: - - def test_quarter_format(self): - d = date(2006, 6, 8) - fmt = dates.DateTimeFormat(d, locale='en_US') - assert fmt['Q'] == '2' - assert fmt['QQQQ'] == '2nd quarter' - assert fmt['q'] == '2' - assert fmt['qqqq'] == '2nd quarter' - d = date(2006, 12, 31) - fmt = dates.DateTimeFormat(d, locale='en_US') - assert fmt['qqq'] == 'Q4' - assert fmt['qqqqq'] == '4' - assert fmt['QQQ'] == 'Q4' - assert fmt['QQQQQ'] == '4' - - def test_month_context(self): - d = date(2006, 2, 8) - assert dates.DateTimeFormat(d, locale='mt_MT')['MMMMM'] == 'F' # narrow format - assert dates.DateTimeFormat(d, locale='mt_MT')['LLLLL'] == 'Fr' # narrow standalone - - def test_abbreviated_month_alias(self): - d = date(2006, 3, 8) - assert dates.DateTimeFormat(d, locale='de_DE')['LLL'] == 'Mär' - - def test_week_of_year_first(self): - d = date(2006, 1, 8) - assert dates.DateTimeFormat(d, locale='de_DE')['w'] == '1' - assert dates.DateTimeFormat(d, locale='en_US')['ww'] == '02' - - def test_week_of_year_first_with_year(self): - d = date(2006, 1, 1) - fmt = dates.DateTimeFormat(d, locale='de_DE') - assert fmt['w'] == '52' - assert fmt['YYYY'] == '2005' - - def test_week_of_year_last(self): - d = date(2006, 12, 26) - assert dates.DateTimeFormat(d, locale='de_DE')['w'] == '52' - assert dates.DateTimeFormat(d, locale='en_US')['w'] == '52' - - def test_week_of_year_last_us_extra_week(self): - d = date(2005, 12, 26) - assert dates.DateTimeFormat(d, locale='de_DE')['w'] == '52' - assert dates.DateTimeFormat(d, locale='en_US')['w'] == '53' - - def test_week_of_year_de_first_us_last_with_year(self): - d = date(2018, 12, 31) - fmt = dates.DateTimeFormat(d, locale='de_DE') - assert fmt['w'] == '1' - assert fmt['YYYY'] == '2019' - fmt = dates.DateTimeFormat(d, locale='en_US') - assert fmt['w'] == '53' - assert fmt['yyyy'] == '2018' - - def test_week_of_month_first(self): - d = date(2006, 1, 8) - assert dates.DateTimeFormat(d, locale='de_DE')['W'] == '1' - assert dates.DateTimeFormat(d, locale='en_US')['W'] == '2' - - def test_week_of_month_last(self): - d = date(2006, 1, 29) - assert dates.DateTimeFormat(d, locale='de_DE')['W'] == '4' - assert dates.DateTimeFormat(d, locale='en_US')['W'] == '5' - - def test_day_of_year(self): - d = date(2007, 4, 1) - assert dates.DateTimeFormat(d, locale='en_US')['D'] == '91' - - def test_day_of_year_works_with_datetime(self): - d = datetime(2007, 4, 1) - assert dates.DateTimeFormat(d, locale='en_US')['D'] == '91' - - def test_day_of_year_first(self): - d = date(2007, 1, 1) - assert dates.DateTimeFormat(d, locale='en_US')['DDD'] == '001' - - def test_day_of_year_last(self): - d = date(2007, 12, 31) - assert dates.DateTimeFormat(d, locale='en_US')['DDD'] == '365' - - def test_day_of_week_in_month(self): - d = date(2007, 4, 15) - assert dates.DateTimeFormat(d, locale='en_US')['F'] == '3' - - def test_day_of_week_in_month_first(self): - d = date(2007, 4, 1) - assert dates.DateTimeFormat(d, locale='en_US')['F'] == '1' - - def test_day_of_week_in_month_last(self): - d = date(2007, 4, 29) - assert dates.DateTimeFormat(d, locale='en_US')['F'] == '5' - - def test_local_day_of_week(self): - d = date(2007, 4, 1) # a sunday - assert dates.DateTimeFormat(d, locale='de_DE')['e'] == '7' # monday is first day of week - assert dates.DateTimeFormat(d, locale='en_US')['ee'] == '01' # sunday is first day of week - assert dates.DateTimeFormat(d, locale='ar_BH')['ee'] == '02' # saturday is first day of week - - d = date(2007, 4, 2) # a monday - assert dates.DateTimeFormat(d, locale='de_DE')['e'] == '1' # monday is first day of week - assert dates.DateTimeFormat(d, locale='en_US')['ee'] == '02' # sunday is first day of week - assert dates.DateTimeFormat(d, locale='ar_BH')['ee'] == '03' # saturday is first day of week - - def test_local_day_of_week_standalone(self): - d = date(2007, 4, 1) # a sunday - assert dates.DateTimeFormat(d, locale='de_DE')['c'] == '7' # monday is first day of week - assert dates.DateTimeFormat(d, locale='en_US')['c'] == '1' # sunday is first day of week - assert dates.DateTimeFormat(d, locale='ar_BH')['c'] == '2' # saturday is first day of week - - d = date(2007, 4, 2) # a monday - assert dates.DateTimeFormat(d, locale='de_DE')['c'] == '1' # monday is first day of week - assert dates.DateTimeFormat(d, locale='en_US')['c'] == '2' # sunday is first day of week - assert dates.DateTimeFormat(d, locale='ar_BH')['c'] == '3' # saturday is first day of week - - def test_pattern_day_of_week(self): - dt = datetime(2016, 2, 6) - fmt = dates.DateTimeFormat(dt, locale='en_US') - assert fmt['c'] == '7' - assert fmt['ccc'] == 'Sat' - assert fmt['cccc'] == 'Saturday' - assert fmt['ccccc'] == 'S' - assert fmt['cccccc'] == 'Sa' - assert fmt['e'] == '7' - assert fmt['ee'] == '07' - assert fmt['eee'] == 'Sat' - assert fmt['eeee'] == 'Saturday' - assert fmt['eeeee'] == 'S' - assert fmt['eeeeee'] == 'Sa' - assert fmt['E'] == 'Sat' - assert fmt['EE'] == 'Sat' - assert fmt['EEE'] == 'Sat' - assert fmt['EEEE'] == 'Saturday' - assert fmt['EEEEE'] == 'S' - assert fmt['EEEEEE'] == 'Sa' - fmt = dates.DateTimeFormat(dt, locale='uk') - assert fmt['c'] == '6' - assert fmt['e'] == '6' - assert fmt['ee'] == '06' - - def test_fractional_seconds(self): - t = time(8, 3, 9, 799) - assert dates.DateTimeFormat(t, locale='en_US')['S'] == '0' - t = time(8, 3, 1, 799) - assert dates.DateTimeFormat(t, locale='en_US')['SSSS'] == '0008' - t = time(8, 3, 1, 34567) - assert dates.DateTimeFormat(t, locale='en_US')['SSSS'] == '0346' - t = time(8, 3, 1, 345678) - assert dates.DateTimeFormat(t, locale='en_US')['SSSSSS'] == '345678' - t = time(8, 3, 1, 799) - assert dates.DateTimeFormat(t, locale='en_US')['SSSSS'] == '00080' - - def test_fractional_seconds_zero(self): - t = time(15, 30, 0) - assert dates.DateTimeFormat(t, locale='en_US')['SSSS'] == '0000' - - def test_milliseconds_in_day(self): - t = time(15, 30, 12, 345000) - assert dates.DateTimeFormat(t, locale='en_US')['AAAA'] == '55812345' - - def test_milliseconds_in_day_zero(self): - d = time(0, 0, 0) - assert dates.DateTimeFormat(d, locale='en_US')['AAAA'] == '0000' - - def test_timezone_rfc822(self, timezone_getter): - tz = timezone_getter('Europe/Berlin') - t = _localize(tz, datetime(2015, 1, 1, 15, 30)) - assert dates.DateTimeFormat(t, locale='de_DE')['Z'] == '+0100' - - def test_timezone_gmt(self, timezone_getter): - tz = timezone_getter('Europe/Berlin') - t = _localize(tz, datetime(2015, 1, 1, 15, 30)) - assert dates.DateTimeFormat(t, locale='de_DE')['ZZZZ'] == 'GMT+01:00' - - def test_timezone_name(self, timezone_getter): - tz = timezone_getter('Europe/Paris') - dt = _localize(tz, datetime(2007, 4, 1, 15, 30)) - assert dates.DateTimeFormat(dt, locale='fr_FR')['v'] == 'heure : France' - - def test_timezone_location_format(self, timezone_getter): - tz = timezone_getter('Europe/Paris') - dt = _localize(tz, datetime(2007, 4, 1, 15, 30)) - assert dates.DateTimeFormat(dt, locale='fr_FR')['VVVV'] == 'heure : France' - - def test_timezone_walltime_short(self, timezone_getter): - tz = timezone_getter('Europe/Paris') - t = time(15, 30, tzinfo=tz) - assert dates.DateTimeFormat(t, locale='fr_FR')['v'] == 'heure : France' - - def test_timezone_walltime_long(self, timezone_getter): - tz = timezone_getter('Europe/Paris') - t = time(15, 30, tzinfo=tz) - assert dates.DateTimeFormat(t, locale='fr_FR')['vvvv'] == 'heure d’Europe centrale' - - def test_hour_formatting(self): - locale = 'en_US' - t = time(0, 0, 0) - assert dates.format_time(t, 'h a', locale=locale) == '12 AM' - assert dates.format_time(t, 'H', locale=locale) == '0' - assert dates.format_time(t, 'k', locale=locale) == '24' - assert dates.format_time(t, 'K a', locale=locale) == '0 AM' - t = time(12, 0, 0) - assert dates.format_time(t, 'h a', locale=locale) == '12 PM' - assert dates.format_time(t, 'H', locale=locale) == '12' - assert dates.format_time(t, 'k', locale=locale) == '12' - assert dates.format_time(t, 'K a', locale=locale) == '0 PM' - - class FormatDateTestCase: def test_with_time_fields_in_pattern(self): @@ -347,6 +139,19 @@ def test_with_date_fields_in_pattern_and_datetime_param(self): with pytest.raises(AttributeError): dates.format_time(datetime(2007, 4, 1, 15, 30), "yyyy-MM-dd HH:mm", locale='en_US') + def test_hour_formatting(self): + locale = 'en_US' + t = time(0, 0, 0) + assert dates.format_time(t, 'h a', locale=locale) == '12 AM' + assert dates.format_time(t, 'H', locale=locale) == '0' + assert dates.format_time(t, 'k', locale=locale) == '24' + assert dates.format_time(t, 'K a', locale=locale) == '0 AM' + t = time(12, 0, 0) + assert dates.format_time(t, 'h a', locale=locale) == '12 PM' + assert dates.format_time(t, 'H', locale=locale) == '12' + assert dates.format_time(t, 'k', locale=locale) == '12' + assert dates.format_time(t, 'K a', locale=locale) == '0 PM' + class FormatTimedeltaTestCase: From 909bbd3daaf0e94c99d069ca2591bc1284766d62 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Mon, 17 Aug 2026 13:30:05 +0300 Subject: [PATCH 3/3] Unfold test_dates test cases They had actually never been run since 14216ed8 (January 2023), since they stopped inheriting from `unittest.TestCase` there... --- tests/test_dates.py | 355 ++++++++++++++++++++++---------------------- 1 file changed, 176 insertions(+), 179 deletions(-) diff --git a/tests/test_dates.py b/tests/test_dates.py index 3672bb80b..4f8c73907 100644 --- a/tests/test_dates.py +++ b/tests/test_dates.py @@ -21,185 +21,182 @@ from babel.util import FixedOffsetTimezone -class FormatDateTestCase: - - def test_with_time_fields_in_pattern(self): - with pytest.raises(AttributeError): - dates.format_date(date(2007, 4, 1), "yyyy-MM-dd HH:mm", locale='en_US') - - def test_with_time_fields_in_pattern_and_datetime_param(self): - with pytest.raises(AttributeError): - dates.format_date(datetime(2007, 4, 1, 15, 30), "yyyy-MM-dd HH:mm", locale='en_US') - - def test_with_day_of_year_in_pattern_and_datetime_param(self): - # format_date should work on datetimes just as well (see #282) - d = datetime(2007, 4, 1) - assert dates.format_date(d, 'w', locale='en_US') == '14' - - -class FormatDatetimeTestCase: - - def test_with_float(self, timezone_getter): - UTC = timezone_getter('UTC') - d = datetime(2012, 4, 1, 15, 30, 29, tzinfo=UTC) - epoch = float(calendar.timegm(d.timetuple())) - formatted_string = dates.format_datetime(epoch, format='long', locale='en_US') - assert formatted_string == 'April 1, 2012 at 3:30:29 PM UTC' - - def test_timezone_formats_los_angeles(self, timezone_getter): - tz = timezone_getter('America/Los_Angeles') - dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35)) - assert dates.format_datetime(dt, 'z', locale='en') == 'PST' - assert dates.format_datetime(dt, 'zz', locale='en') == 'PST' - assert dates.format_datetime(dt, 'zzz', locale='en') == 'PST' - assert dates.format_datetime(dt, 'zzzz', locale='en') == 'Pacific Standard Time' - assert dates.format_datetime(dt, 'Z', locale='en') == '-0800' - assert dates.format_datetime(dt, 'ZZ', locale='en') == '-0800' - assert dates.format_datetime(dt, 'ZZZ', locale='en') == '-0800' - assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT-08:00' - assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == '-08:00' - assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT-08:00' - assert dates.format_datetime(dt, 'VV', locale='en') == 'America/Los_Angeles' - assert dates.format_datetime(dt, 'VVV', locale='en') == 'Los Angeles' - assert dates.format_datetime(dt, 'X', locale='en') == '-08' - assert dates.format_datetime(dt, 'XX', locale='en') == '-0800' - assert dates.format_datetime(dt, 'XXX', locale='en') == '-08:00' - assert dates.format_datetime(dt, 'XXXX', locale='en') == '-0800' - assert dates.format_datetime(dt, 'XXXXX', locale='en') == '-08:00' - assert dates.format_datetime(dt, 'x', locale='en') == '-08' - assert dates.format_datetime(dt, 'xx', locale='en') == '-0800' - assert dates.format_datetime(dt, 'xxx', locale='en') == '-08:00' - assert dates.format_datetime(dt, 'xxxx', locale='en') == '-0800' - assert dates.format_datetime(dt, 'xxxxx', locale='en') == '-08:00' - - def test_timezone_formats_utc(self, timezone_getter): - tz = timezone_getter('UTC') - dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35)) - assert dates.format_datetime(dt, 'Z', locale='en') == '+0000' - assert dates.format_datetime(dt, 'ZZ', locale='en') == '+0000' - assert dates.format_datetime(dt, 'ZZZ', locale='en') == '+0000' - assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT+00:00' - assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == 'Z' - assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT+00:00' - assert dates.format_datetime(dt, 'VV', locale='en') == 'Etc/UTC' - assert dates.format_datetime(dt, 'VVV', locale='en') == 'UTC' - assert dates.format_datetime(dt, 'X', locale='en') == 'Z' - assert dates.format_datetime(dt, 'XX', locale='en') == 'Z' - assert dates.format_datetime(dt, 'XXX', locale='en') == 'Z' - assert dates.format_datetime(dt, 'XXXX', locale='en') == 'Z' - assert dates.format_datetime(dt, 'XXXXX', locale='en') == 'Z' - assert dates.format_datetime(dt, 'x', locale='en') == '+00' - assert dates.format_datetime(dt, 'xx', locale='en') == '+0000' - assert dates.format_datetime(dt, 'xxx', locale='en') == '+00:00' - assert dates.format_datetime(dt, 'xxxx', locale='en') == '+0000' - assert dates.format_datetime(dt, 'xxxxx', locale='en') == '+00:00' - - def test_timezone_formats_kolkata(self, timezone_getter): - tz = timezone_getter('Asia/Kolkata') - dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35)) - assert dates.format_datetime(dt, 'zzzz', locale='en') == 'India Standard Time' - assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT+05:30' - assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == '+05:30' - assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT+05:30' - assert dates.format_datetime(dt, 'VV', locale='en') == 'Asia/Calcutta' - assert dates.format_datetime(dt, 'VVV', locale='en') == 'Kolkata' - assert dates.format_datetime(dt, 'X', locale='en') == '+0530' - assert dates.format_datetime(dt, 'XX', locale='en') == '+0530' - assert dates.format_datetime(dt, 'XXX', locale='en') == '+05:30' - assert dates.format_datetime(dt, 'XXXX', locale='en') == '+0530' - assert dates.format_datetime(dt, 'XXXXX', locale='en') == '+05:30' - assert dates.format_datetime(dt, 'x', locale='en') == '+0530' - assert dates.format_datetime(dt, 'xx', locale='en') == '+0530' - assert dates.format_datetime(dt, 'xxx', locale='en') == '+05:30' - assert dates.format_datetime(dt, 'xxxx', locale='en') == '+0530' - assert dates.format_datetime(dt, 'xxxxx', locale='en') == '+05:30' - - -class FormatTimeTestCase: - - def test_with_naive_datetime_and_tzinfo(self, timezone_getter): - assert dates.format_time( - datetime(2007, 4, 1, 15, 30), - 'long', - tzinfo=timezone_getter('US/Eastern'), - locale='en', - ) == '11:30:00 AM EDT' - - def test_with_float(self, timezone_getter): - tz = timezone_getter('UTC') - d = _localize(tz, datetime(2012, 4, 1, 15, 30, 29)) - epoch = float(calendar.timegm(d.timetuple())) - assert dates.format_time(epoch, format='long', locale='en_US') == '3:30:29 PM UTC' - - def test_with_date_fields_in_pattern(self): - with pytest.raises(AttributeError): - dates.format_time(datetime(2007, 4, 1), 'yyyy-MM-dd HH:mm', locale='en') - - def test_with_date_fields_in_pattern_and_datetime_param(self): - with pytest.raises(AttributeError): - dates.format_time(datetime(2007, 4, 1, 15, 30), "yyyy-MM-dd HH:mm", locale='en_US') - - def test_hour_formatting(self): - locale = 'en_US' - t = time(0, 0, 0) - assert dates.format_time(t, 'h a', locale=locale) == '12 AM' - assert dates.format_time(t, 'H', locale=locale) == '0' - assert dates.format_time(t, 'k', locale=locale) == '24' - assert dates.format_time(t, 'K a', locale=locale) == '0 AM' - t = time(12, 0, 0) - assert dates.format_time(t, 'h a', locale=locale) == '12 PM' - assert dates.format_time(t, 'H', locale=locale) == '12' - assert dates.format_time(t, 'k', locale=locale) == '12' - assert dates.format_time(t, 'K a', locale=locale) == '0 PM' - - -class FormatTimedeltaTestCase: - - def test_zero_seconds(self): - td = timedelta(seconds=0) - assert dates.format_timedelta(td, locale='en') == '0 seconds' - assert dates.format_timedelta(td, locale='en', format='short') == '0 sec' - assert dates.format_timedelta(td, granularity='hour', locale='en') == '0 hours' - assert dates.format_timedelta(td, granularity='hour', locale='en', format='short') == '0 hr' - - def test_small_value_with_granularity(self): - td = timedelta(seconds=42) - assert dates.format_timedelta(td, granularity='hour', locale='en') == '1 hour' - assert dates.format_timedelta(td, granularity='hour', locale='en', format='short') == '1 hr' - - def test_direction_adding(self): - td = timedelta(hours=1) - assert dates.format_timedelta(td, locale='en', add_direction=True) == 'in 1 hour' - assert dates.format_timedelta(-td, locale='en', add_direction=True) == '1 hour ago' - - def test_format_narrow(self): - assert dates.format_timedelta(timedelta(hours=1), locale='en', format='narrow') == '1h' - assert dates.format_timedelta(timedelta(hours=-2), locale='en', format='narrow') == '2h' - - def test_format_invalid(self): - for format in (None, '', 'bold italic'): - with pytest.raises(TypeError): - dates.format_timedelta(timedelta(hours=1), format=format) - - -class TimeZoneAdjustTestCase: - - def _utc(self): - class EvilFixedOffsetTimezone(FixedOffsetTimezone): - - def localize(self, dt, is_dst=False): - raise NotImplementedError() - UTC = EvilFixedOffsetTimezone(0, 'UTC') - # This is important to trigger the actual bug (#257) - assert hasattr(UTC, 'normalize') is False - return UTC - - def test_can_format_time_with_custom_timezone(self): - # regression test for #257 - utc = self._utc() - t = datetime(2007, 4, 1, 15, 30, tzinfo=utc) - formatted_time = dates.format_time(t, 'long', tzinfo=utc, locale='en') - assert formatted_time == '3:30:00 PM UTC' +def test_format_date_with_time_fields_in_pattern(): + with pytest.raises(AttributeError): + dates.format_date(date(2007, 4, 1), "yyyy-MM-dd HH:mm", locale='en_US') + + +def test_format_date_with_time_fields_in_pattern_and_datetime_param(): + d = datetime(2007, 4, 1, 15, 30) + with pytest.raises(AttributeError): + dates.format_date(d, "yyyy-MM-dd HH:mm", locale='en_US') + + +def test_format_date_with_day_of_year_in_pattern_and_datetime_param(): + # format_date should work on datetimes just as well (see #282) + d = datetime(2007, 4, 1) + assert dates.format_date(d, 'w', locale='en_US') == '14' + + +def test_format_datetime_with_float(timezone_getter): + UTC = timezone_getter('UTC') + d = datetime(2012, 4, 1, 15, 30, 29, tzinfo=UTC) + epoch = float(calendar.timegm(d.timetuple())) + formatted_string = dates.format_datetime(epoch, format='long', locale='en_US') + assert formatted_string == 'April 1, 2012, 3:30:29\u202fPM UTC' + + +def test_format_datetime_timezone_formats_los_angeles(timezone_getter): + tz = timezone_getter('America/Los_Angeles') + dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35)) + assert dates.format_datetime(dt, 'z', locale='en') == 'PST' + assert dates.format_datetime(dt, 'zz', locale='en') == 'PST' + assert dates.format_datetime(dt, 'zzz', locale='en') == 'PST' + assert dates.format_datetime(dt, 'zzzz', locale='en') == 'Pacific Standard Time' + assert dates.format_datetime(dt, 'Z', locale='en') == '-0800' + assert dates.format_datetime(dt, 'ZZ', locale='en') == '-0800' + assert dates.format_datetime(dt, 'ZZZ', locale='en') == '-0800' + assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT-08:00' + assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == '-08:00' + assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT-08:00' + assert dates.format_datetime(dt, 'VV', locale='en') == 'America/Los_Angeles' + assert dates.format_datetime(dt, 'VVV', locale='en') == 'Los Angeles' + assert dates.format_datetime(dt, 'X', locale='en') == '-08' + assert dates.format_datetime(dt, 'XX', locale='en') == '-0800' + assert dates.format_datetime(dt, 'XXX', locale='en') == '-08:00' + assert dates.format_datetime(dt, 'XXXX', locale='en') == '-0800' + assert dates.format_datetime(dt, 'XXXXX', locale='en') == '-08:00' + assert dates.format_datetime(dt, 'x', locale='en') == '-08' + assert dates.format_datetime(dt, 'xx', locale='en') == '-0800' + assert dates.format_datetime(dt, 'xxx', locale='en') == '-08:00' + assert dates.format_datetime(dt, 'xxxx', locale='en') == '-0800' + assert dates.format_datetime(dt, 'xxxxx', locale='en') == '-08:00' + + +def test_format_datetime_timezone_formats_utc(timezone_getter): + tz = timezone_getter('UTC') + dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35)) + assert dates.format_datetime(dt, 'Z', locale='en') == '+0000' + assert dates.format_datetime(dt, 'ZZ', locale='en') == '+0000' + assert dates.format_datetime(dt, 'ZZZ', locale='en') == '+0000' + assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT+00:00' + assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == 'Z' + assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT+00:00' + assert dates.format_datetime(dt, 'VV', locale='en') == 'Etc/UTC' + assert dates.format_datetime(dt, 'VVV', locale='en') == 'UTC' + assert dates.format_datetime(dt, 'X', locale='en') == 'Z' + assert dates.format_datetime(dt, 'XX', locale='en') == 'Z' + assert dates.format_datetime(dt, 'XXX', locale='en') == 'Z' + assert dates.format_datetime(dt, 'XXXX', locale='en') == 'Z' + assert dates.format_datetime(dt, 'XXXXX', locale='en') == 'Z' + assert dates.format_datetime(dt, 'x', locale='en') == '+00' + assert dates.format_datetime(dt, 'xx', locale='en') == '+0000' + assert dates.format_datetime(dt, 'xxx', locale='en') == '+00:00' + assert dates.format_datetime(dt, 'xxxx', locale='en') == '+0000' + assert dates.format_datetime(dt, 'xxxxx', locale='en') == '+00:00' + + +def test_format_datetime_timezone_formats_kolkata(timezone_getter): + tz = timezone_getter('Asia/Kolkata') + dt = _localize(tz, datetime(2016, 1, 13, 7, 8, 35)) + assert dates.format_datetime(dt, 'zzzz', locale='en') == 'GMT+05:30' + assert dates.format_datetime(dt, 'ZZZZ', locale='en') == 'GMT+05:30' + assert dates.format_datetime(dt, 'ZZZZZ', locale='en') == '+05:30' + assert dates.format_datetime(dt, 'OOOO', locale='en') == 'GMT+05:30' + assert dates.format_datetime(dt, 'VV', locale='en') == 'Asia/Kolkata' + assert dates.format_datetime(dt, 'VVV', locale='en') == 'Kolkata' + assert dates.format_datetime(dt, 'X', locale='en') == '+0530' + assert dates.format_datetime(dt, 'XX', locale='en') == '+0530' + assert dates.format_datetime(dt, 'XXX', locale='en') == '+05:30' + assert dates.format_datetime(dt, 'XXXX', locale='en') == '+0530' + assert dates.format_datetime(dt, 'XXXXX', locale='en') == '+05:30' + assert dates.format_datetime(dt, 'x', locale='en') == '+0530' + assert dates.format_datetime(dt, 'xx', locale='en') == '+0530' + assert dates.format_datetime(dt, 'xxx', locale='en') == '+05:30' + assert dates.format_datetime(dt, 'xxxx', locale='en') == '+0530' + assert dates.format_datetime(dt, 'xxxxx', locale='en') == '+05:30' + + +def test_format_time_with_naive_datetime_and_tzinfo(timezone_getter): + d = datetime(2007, 4, 1, 15, 30) + formatted = dates.format_time(d, 'long', tzinfo=timezone_getter('US/Eastern'), locale='en') + assert formatted == '11:30:00\u202fAM EDT' + + +def test_format_time_with_float(timezone_getter): + tz = timezone_getter('UTC') + d = _localize(tz, datetime(2012, 4, 1, 15, 30, 29)) + epoch = float(calendar.timegm(d.timetuple())) + assert dates.format_time(epoch, format='long', locale='en_US') == '3:30:29\u202fPM UTC' + + +def test_format_time_with_date_fields_in_pattern(): + with pytest.raises(AttributeError): + dates.format_time(datetime(2007, 4, 1), 'yyyy-MM-dd HH:mm', locale='en') + + +def test_format_time_with_date_fields_in_pattern_and_datetime_param(): + with pytest.raises(AttributeError): + dates.format_time(datetime(2007, 4, 1, 15, 30), "yyyy-MM-dd HH:mm", locale='en_US') + + +def test_format_time_hour_formatting(): + locale = 'en_US' + t = time(0, 0, 0) + assert dates.format_time(t, 'h a', locale=locale) == '12 AM' + assert dates.format_time(t, 'H', locale=locale) == '0' + assert dates.format_time(t, 'k', locale=locale) == '24' + assert dates.format_time(t, 'K a', locale=locale) == '0 AM' + t = time(12, 0, 0) + assert dates.format_time(t, 'h a', locale=locale) == '12 PM' + assert dates.format_time(t, 'H', locale=locale) == '12' + assert dates.format_time(t, 'k', locale=locale) == '12' + assert dates.format_time(t, 'K a', locale=locale) == '0 PM' + + +def test_format_timedelta_zero_seconds(): + td = timedelta(seconds=0) + assert dates.format_timedelta(td, locale='en') == '0 seconds' + assert dates.format_timedelta(td, locale='en', format='short') == '0 sec' + assert dates.format_timedelta(td, granularity='hour', locale='en') == '0 hours' + assert dates.format_timedelta(td, granularity='hour', locale='en', format='short') == '0 hr' # fmt: skip + + +def test_format_timedelta_small_value_with_granularity(): + td = timedelta(seconds=42) + assert dates.format_timedelta(td, granularity='hour', locale='en') == '1 hour' + assert dates.format_timedelta(td, granularity='hour', locale='en', format='short') == '1 hr' # fmt: skip + + +def test_format_timedelta_direction_adding(): + td = timedelta(hours=1) + assert dates.format_timedelta(td, locale='en', add_direction=True) == 'in 1 hour' + assert dates.format_timedelta(-td, locale='en', add_direction=True) == '1 hour ago' + + +def test_format_timedelta_format_narrow(): + assert dates.format_timedelta(timedelta(hours=1), locale='en', format='narrow') == '1h' + assert dates.format_timedelta(timedelta(hours=-2), locale='en', format='narrow') == '2h' + + +def test_format_timedelta_format_invalid(): + for format in (None, '', 'bold italic'): + with pytest.raises(TypeError): + dates.format_timedelta(timedelta(hours=1), format=format) + + +def test_timezone_adjust_can_format_time_with_custom_timezone(): + # regression test for #257 + class EvilFixedOffsetTimezone(FixedOffsetTimezone): + def localize(self, dt, is_dst=False): + raise NotImplementedError() + + utc = EvilFixedOffsetTimezone(0, 'UTC') + # This is important to trigger the actual bug (#257) + assert hasattr(utc, 'normalize') is False + t = datetime(2007, 4, 1, 15, 30, tzinfo=utc) + formatted_time = dates.format_time(t, 'long', tzinfo=utc, locale='en') + assert formatted_time == '3:30:00\u202fPM UTC' def test_get_period_names():