146 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710// UNSUPPORTED: no-localization11// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME12 13// TODO FMT This test should not require std::to_chars(floating-point)14// XFAIL: availability-fp_to_chars-missing15 16// REQUIRES: locale.fr_FR.UTF-817// REQUIRES: locale.ja_JP.UTF-818 19// <chrono>20// class month_day;21 22// template<class charT, class traits>23// basic_ostream<charT, traits>&24// operator<<(basic_ostream<charT, traits>& os, const month_day& md);25 26#include <chrono>27#include <cassert>28#include <sstream>29 30#include "make_string.h"31#include "platform_support.h" // locale name macros32#include "test_macros.h"33#include "assert_macros.h"34#include "concat_macros.h"35 36#define SV(S) MAKE_STRING_VIEW(CharT, S)37 38#define TEST_EQUAL(OUT, EXPECTED) \39 TEST_REQUIRE(OUT == EXPECTED, \40 TEST_WRITE_CONCATENATED( \41 "\nExpression ", #OUT, "\nExpected output ", EXPECTED, "\nActual output ", OUT, '\n'));42 43template <class CharT>44static std::basic_string<CharT> stream_c_locale(std::chrono::month_day md) {45 std::basic_stringstream<CharT> sstr;46 sstr << md;47 return sstr.str();48}49 50template <class CharT>51static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::month_day md) {52 std::basic_stringstream<CharT> sstr;53 const std::locale locale(LOCALE_fr_FR_UTF_8);54 sstr.imbue(locale);55 sstr << md;56 return sstr.str();57}58 59template <class CharT>60static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::month_day md) {61 std::basic_stringstream<CharT> sstr;62 const std::locale locale(LOCALE_ja_JP_UTF_8);63 sstr.imbue(locale);64 sstr << md;65 return sstr.str();66}67 68template <class CharT>69static void test() {70 using namespace std::literals::chrono_literals;71 72 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 0d}),73 SV("0 is not a valid month/00 is not a valid day"));74 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 1d}),75 SV("0 is not a valid month/01"));76 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),77 SV("Jan/255 is not a valid day"));78 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV("Jan/31"));79 // February is considered valid with 29 days; it lacks the year information80 // to do a proper validation.81 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV("Feb/29"));82 // The month_day stream operator has no validation, this means never validate83 // dates don't get84 // Jun/31 is not a valid month day85 // which is inconsistent with other stream operators.86 // TODO FMT file an issue about this.87 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV("Jun/31"));88 89 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 0d}),90 SV("0 is not a valid month/00 is not a valid day"));91 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 1d}),92 SV("0 is not a valid month/01"));93#if defined(__APPLE__)94 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),95 SV("jan/255 is not a valid day"));96 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV("jan/31"));97 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV("fév/29"));98 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV("jui/31"));99#else // defined(__APPLE__)100 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),101 SV("janv./255 is not a valid day"));102 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV("janv./31"));103 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV("févr./29"));104 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV("juin/31"));105#endif // defined(__APPLE__)106 107 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 0d}),108 SV("0 is not a valid month/00 is not a valid day"));109 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 1d}),110 SV("0 is not a valid month/01"));111#if defined(__APPLE__)112 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),113 SV(" 1/255 is not a valid day"));114 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV(" 1/31"));115 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV(" 2/29"));116 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV(" 6/31"));117#elif defined(_WIN32) // defined(__APPLE__)118 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),119 SV("1/255 is not a valid day"));120 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV("1/31"));121 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV("2/29"));122 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV("6/31"));123#elif defined(_AIX) // defined(__APPLE__)124 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),125 SV("1月/255 is not a valid day"));126 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV("1月/31"));127 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV("2月/29"));128 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV("6月/31"));129#else // defined(__APPLE__)130 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),131 SV(" 1月/255 is not a valid day"));132 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV(" 1月/31"));133 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV(" 2月/29"));134 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV(" 6月/31"));135#endif // defined(__APPLE__)136}137 138int main(int, char**) {139 test<char>();140#ifndef TEST_HAS_NO_WIDE_CHARACTERS141 test<wchar_t>();142#endif143 144 return 0;145}146