blob: 35985c043059661511e0cc3f49daecdcaf9aad17 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include <cmath>
#include <locale>
#include <stdexcept>
#include <string>
#include <gtest/gtest.h>
#include "arrow/status.h"
#include "arrow/testing/gtest_util.h"
#include "arrow/type.h"
#include "arrow/util/formatting.h"
namespace arrow {
using internal::StringFormatter;
class StringAppender {
public:
Status operator()(util::string_view v) {
string_.append(v.data(), v.size());
return Status::OK();
}
std::string string() const { return string_; }
protected:
std::string string_;
};
template <typename FormatterType, typename C_TYPE = typename FormatterType::value_type>
void AssertFormatting(FormatterType& formatter, C_TYPE value,
const std::string& expected) {
StringAppender appender;
ASSERT_OK(formatter(value, appender));
ASSERT_EQ(appender.string(), expected) << "Formatting failed (value = " << value << ")";
}
TEST(Formatting, Boolean) {
StringFormatter<BooleanType> formatter;
AssertFormatting(formatter, true, "true");
AssertFormatting(formatter, false, "false");
}
template <typename FormatterType>
void TestAnyIntUpTo8(FormatterType& formatter) {
AssertFormatting(formatter, 0, "0");
AssertFormatting(formatter, 1, "1");
AssertFormatting(formatter, 9, "9");
AssertFormatting(formatter, 10, "10");
AssertFormatting(formatter, 99, "99");
AssertFormatting(formatter, 100, "100");
AssertFormatting(formatter, 127, "127");
}
template <typename FormatterType>
void TestAnyIntUpTo16(FormatterType& formatter) {
TestAnyIntUpTo8(formatter);
AssertFormatting(formatter, 999, "999");
AssertFormatting(formatter, 1000, "1000");
AssertFormatting(formatter, 9999, "9999");
AssertFormatting(formatter, 10000, "10000");
AssertFormatting(formatter, 32767, "32767");
}
template <typename FormatterType>
void TestAnyIntUpTo32(FormatterType& formatter) {
TestAnyIntUpTo16(formatter);
AssertFormatting(formatter, 99999, "99999");
AssertFormatting(formatter, 100000, "100000");
AssertFormatting(formatter, 999999, "999999");
AssertFormatting(formatter, 1000000, "1000000");
AssertFormatting(formatter, 9999999, "9999999");
AssertFormatting(formatter, 10000000, "10000000");
AssertFormatting(formatter, 99999999, "99999999");
AssertFormatting(formatter, 100000000, "100000000");
AssertFormatting(formatter, 999999999, "999999999");
AssertFormatting(formatter, 1000000000, "1000000000");
AssertFormatting(formatter, 1234567890, "1234567890");
AssertFormatting(formatter, 2147483647, "2147483647");
}
template <typename FormatterType>
void TestAnyIntUpTo64(FormatterType& formatter) {
TestAnyIntUpTo32(formatter);
AssertFormatting(formatter, 9999999999ULL, "9999999999");
AssertFormatting(formatter, 10000000000ULL, "10000000000");
AssertFormatting(formatter, 99999999999ULL, "99999999999");
AssertFormatting(formatter, 100000000000ULL, "100000000000");
AssertFormatting(formatter, 999999999999ULL, "999999999999");
AssertFormatting(formatter, 1000000000000ULL, "1000000000000");
AssertFormatting(formatter, 9999999999999ULL, "9999999999999");
AssertFormatting(formatter, 10000000000000ULL, "10000000000000");
AssertFormatting(formatter, 99999999999999ULL, "99999999999999");
AssertFormatting(formatter, 1000000000000000000ULL, "1000000000000000000");
AssertFormatting(formatter, 9223372036854775807ULL, "9223372036854775807");
}
template <typename FormatterType>
void TestUIntUpTo8(FormatterType& formatter) {
TestAnyIntUpTo8(formatter);
AssertFormatting(formatter, 128, "128");
AssertFormatting(formatter, 255, "255");
}
template <typename FormatterType>
void TestUIntUpTo16(FormatterType& formatter) {
TestAnyIntUpTo16(formatter);
AssertFormatting(formatter, 32768, "32768");
AssertFormatting(formatter, 65535, "65535");
}
template <typename FormatterType>
void TestUIntUpTo32(FormatterType& formatter) {
TestAnyIntUpTo32(formatter);
AssertFormatting(formatter, 2147483648U, "2147483648");
AssertFormatting(formatter, 4294967295U, "4294967295");
}
template <typename FormatterType>
void TestUIntUpTo64(FormatterType& formatter) {
TestAnyIntUpTo64(formatter);
AssertFormatting(formatter, 9999999999999999999ULL, "9999999999999999999");
AssertFormatting(formatter, 10000000000000000000ULL, "10000000000000000000");
AssertFormatting(formatter, 12345678901234567890ULL, "12345678901234567890");
AssertFormatting(formatter, 18446744073709551615ULL, "18446744073709551615");
}
TEST(Formatting, UInt8) {
StringFormatter<UInt8Type> formatter;
TestUIntUpTo8(formatter);
}
TEST(Formatting, UInt16) {
StringFormatter<UInt16Type> formatter;
TestUIntUpTo16(formatter);
}
TEST(Formatting, UInt32) {
StringFormatter<UInt32Type> formatter;
TestUIntUpTo32(formatter);
}
TEST(Formatting, UInt64) {
StringFormatter<UInt64Type> formatter;
TestUIntUpTo64(formatter);
}
template <typename FormatterType>
void TestIntUpTo8(FormatterType& formatter) {
TestAnyIntUpTo8(formatter);
AssertFormatting(formatter, -1, "-1");
AssertFormatting(formatter, -9, "-9");
AssertFormatting(formatter, -10, "-10");
AssertFormatting(formatter, -99, "-99");
AssertFormatting(formatter, -100, "-100");
AssertFormatting(formatter, -127, "-127");
AssertFormatting(formatter, -128, "-128");
}
template <typename FormatterType>
void TestIntUpTo16(FormatterType& formatter) {
TestAnyIntUpTo16(formatter);
TestIntUpTo8(formatter);
AssertFormatting(formatter, -129, "-129");
AssertFormatting(formatter, -999, "-999");
AssertFormatting(formatter, -1000, "-1000");
AssertFormatting(formatter, -9999, "-9999");
AssertFormatting(formatter, -10000, "-10000");
AssertFormatting(formatter, -32768, "-32768");
}
template <typename FormatterType>
void TestIntUpTo32(FormatterType& formatter) {
TestAnyIntUpTo32(formatter);
TestIntUpTo16(formatter);
AssertFormatting(formatter, -32769, "-32769");
AssertFormatting(formatter, -99999, "-99999");
AssertFormatting(formatter, -1000000000, "-1000000000");
AssertFormatting(formatter, -1234567890, "-1234567890");
AssertFormatting(formatter, -2147483647, "-2147483647");
AssertFormatting(formatter, -2147483647 - 1, "-2147483648");
}
template <typename FormatterType>
void TestIntUpTo64(FormatterType& formatter) {
TestAnyIntUpTo64(formatter);
TestIntUpTo32(formatter);
AssertFormatting(formatter, -2147483649LL, "-2147483649");
AssertFormatting(formatter, -9999999999LL, "-9999999999");
AssertFormatting(formatter, -1000000000000000000LL, "-1000000000000000000");
AssertFormatting(formatter, -9012345678901234567LL, "-9012345678901234567");
AssertFormatting(formatter, -9223372036854775807LL, "-9223372036854775807");
AssertFormatting(formatter, -9223372036854775807LL - 1, "-9223372036854775808");
}
TEST(Formatting, Int8) {
StringFormatter<Int8Type> formatter;
TestIntUpTo8(formatter);
}
TEST(Formatting, Int16) {
StringFormatter<Int16Type> formatter;
TestIntUpTo16(formatter);
}
TEST(Formatting, Int32) {
StringFormatter<Int32Type> formatter;
TestIntUpTo32(formatter);
}
TEST(Formatting, Int64) {
StringFormatter<Int64Type> formatter;
TestIntUpTo64(formatter);
}
TEST(Formatting, Float) {
StringFormatter<FloatType> formatter;
AssertFormatting(formatter, 0.0f, "0");
AssertFormatting(formatter, -0.0f, "-0");
AssertFormatting(formatter, 1.5f, "1.5");
AssertFormatting(formatter, 0.0001f, "0.0001");
AssertFormatting(formatter, 1234.567f, "1234.567");
AssertFormatting(formatter, 1e9f, "1000000000");
AssertFormatting(formatter, 1e10f, "1e+10");
AssertFormatting(formatter, 1e20f, "1e+20");
AssertFormatting(formatter, 1e-6f, "0.000001");
AssertFormatting(formatter, 1e-7f, "1e-7");
AssertFormatting(formatter, 1e-20f, "1e-20");
AssertFormatting(formatter, std::nanf(""), "nan");
AssertFormatting(formatter, HUGE_VALF, "inf");
AssertFormatting(formatter, -HUGE_VALF, "-inf");
}
TEST(Formatting, Double) {
StringFormatter<DoubleType> formatter;
AssertFormatting(formatter, 0.0, "0");
AssertFormatting(formatter, -0.0, "-0");
AssertFormatting(formatter, 1.5, "1.5");
AssertFormatting(formatter, 0.0001, "0.0001");
AssertFormatting(formatter, 1234.567, "1234.567");
AssertFormatting(formatter, 1e9, "1000000000");
AssertFormatting(formatter, 1e10, "1e+10");
AssertFormatting(formatter, 1e20, "1e+20");
AssertFormatting(formatter, 1e-6, "0.000001");
AssertFormatting(formatter, 1e-7, "1e-7");
AssertFormatting(formatter, 1e-20, "1e-20");
AssertFormatting(formatter, std::nan(""), "nan");
AssertFormatting(formatter, HUGE_VAL, "inf");
AssertFormatting(formatter, -HUGE_VAL, "-inf");
}
TEST(Formatting, Date32) {
StringFormatter<Date32Type> formatter;
AssertFormatting(formatter, 0, "1970-01-01");
AssertFormatting(formatter, 1, "1970-01-02");
AssertFormatting(formatter, 30, "1970-01-31");
AssertFormatting(formatter, 30 + 1, "1970-02-01");
AssertFormatting(formatter, 30 + 28, "1970-02-28");
AssertFormatting(formatter, 30 + 28 + 1, "1970-03-01");
AssertFormatting(formatter, -1, "1969-12-31");
AssertFormatting(formatter, 365, "1971-01-01");
AssertFormatting(formatter, 2 * 365, "1972-01-01");
AssertFormatting(formatter, 2 * 365 + 30 + 28 + 1, "1972-02-29");
}
TEST(Formatting, Date64) {
StringFormatter<Date64Type> formatter;
constexpr int64_t kMillisInDay = 24 * 60 * 60 * 1000;
AssertFormatting(formatter, kMillisInDay * (0), "1970-01-01");
AssertFormatting(formatter, kMillisInDay * (1), "1970-01-02");
AssertFormatting(formatter, kMillisInDay * (30), "1970-01-31");
AssertFormatting(formatter, kMillisInDay * (30 + 1), "1970-02-01");
AssertFormatting(formatter, kMillisInDay * (30 + 28), "1970-02-28");
AssertFormatting(formatter, kMillisInDay * (30 + 28 + 1), "1970-03-01");
AssertFormatting(formatter, kMillisInDay * (-1), "1969-12-31");
AssertFormatting(formatter, kMillisInDay * (365), "1971-01-01");
AssertFormatting(formatter, kMillisInDay * (2 * 365), "1972-01-01");
AssertFormatting(formatter, kMillisInDay * (2 * 365 + 30 + 28 + 1), "1972-02-29");
}
TEST(Formatting, Time32) {
{
StringFormatter<Time32Type> formatter(time32(TimeUnit::SECOND));
AssertFormatting(formatter, 0, "00:00:00");
AssertFormatting(formatter, 1, "00:00:01");
AssertFormatting(formatter, ((12) * 60 + 34) * 60 + 56, "12:34:56");
AssertFormatting(formatter, 24 * 60 * 60 - 1, "23:59:59");
}
{
StringFormatter<Time32Type> formatter(time32(TimeUnit::MILLI));
AssertFormatting(formatter, 0, "00:00:00.000");
AssertFormatting(formatter, 1, "00:00:00.001");
AssertFormatting(formatter, 1000, "00:00:01.000");
AssertFormatting(formatter, (((12) * 60 + 34) * 60 + 56) * 1000 + 789,
"12:34:56.789");
AssertFormatting(formatter, 24 * 60 * 60 * 1000 - 1, "23:59:59.999");
}
}
TEST(Formatting, Time64) {
{
StringFormatter<Time64Type> formatter(time64(TimeUnit::MICRO));
AssertFormatting(formatter, 0, "00:00:00.000000");
AssertFormatting(formatter, 1, "00:00:00.000001");
AssertFormatting(formatter, 1000000, "00:00:01.000000");
AssertFormatting(formatter, (((12) * 60 + 34) * 60 + 56) * 1000000LL + 789000,
"12:34:56.789000");
AssertFormatting(formatter, (24 * 60 * 60) * 1000000LL - 1, "23:59:59.999999");
}
{
StringFormatter<Time64Type> formatter(time64(TimeUnit::NANO));
AssertFormatting(formatter, 0, "00:00:00.000000000");
AssertFormatting(formatter, 1, "00:00:00.000000001");
AssertFormatting(formatter, 1000000000LL, "00:00:01.000000000");
AssertFormatting(formatter, (((12) * 60 + 34) * 60 + 56) * 1000000000LL + 789000000LL,
"12:34:56.789000000");
AssertFormatting(formatter, (24 * 60 * 60) * 1000000000LL - 1, "23:59:59.999999999");
}
}
TEST(Formatting, Timestamp) {
{
StringFormatter<TimestampType> formatter(timestamp(TimeUnit::SECOND));
AssertFormatting(formatter, 0, "1970-01-01 00:00:00");
AssertFormatting(formatter, 1, "1970-01-01 00:00:01");
AssertFormatting(formatter, 24 * 60 * 60, "1970-01-02 00:00:00");
AssertFormatting(formatter, 616377600, "1989-07-14 00:00:00");
AssertFormatting(formatter, 951782400, "2000-02-29 00:00:00");
AssertFormatting(formatter, 63730281600LL, "3989-07-14 00:00:00");
AssertFormatting(formatter, -2203977600LL, "1900-02-28 00:00:00");
AssertFormatting(formatter, 1542129070, "2018-11-13 17:11:10");
AssertFormatting(formatter, -2203932304LL, "1900-02-28 12:34:56");
}
{
StringFormatter<TimestampType> formatter(timestamp(TimeUnit::MILLI));
AssertFormatting(formatter, 0, "1970-01-01 00:00:00.000");
AssertFormatting(formatter, 1000L + 1, "1970-01-01 00:00:01.001");
AssertFormatting(formatter, 24 * 60 * 60 * 1000LL + 2, "1970-01-02 00:00:00.002");
AssertFormatting(formatter, 616377600 * 1000LL + 3, "1989-07-14 00:00:00.003");
AssertFormatting(formatter, 951782400 * 1000LL + 4, "2000-02-29 00:00:00.004");
AssertFormatting(formatter, 63730281600LL * 1000LL + 5, "3989-07-14 00:00:00.005");
AssertFormatting(formatter, -2203977600LL * 1000LL + 6, "1900-02-28 00:00:00.006");
AssertFormatting(formatter, 1542129070LL * 1000LL + 7, "2018-11-13 17:11:10.007");
AssertFormatting(formatter, -2203932304LL * 1000LL + 8, "1900-02-28 12:34:56.008");
}
{
StringFormatter<TimestampType> formatter(timestamp(TimeUnit::MICRO));
AssertFormatting(formatter, 0, "1970-01-01 00:00:00.000000");
AssertFormatting(formatter, 1000000LL + 1, "1970-01-01 00:00:01.000001");
AssertFormatting(formatter, 24 * 60 * 60 * 1000000LL + 2,
"1970-01-02 00:00:00.000002");
AssertFormatting(formatter, 616377600 * 1000000LL + 3, "1989-07-14 00:00:00.000003");
AssertFormatting(formatter, 951782400 * 1000000LL + 4, "2000-02-29 00:00:00.000004");
AssertFormatting(formatter, 63730281600LL * 1000000LL + 5,
"3989-07-14 00:00:00.000005");
AssertFormatting(formatter, -2203977600LL * 1000000LL + 6,
"1900-02-28 00:00:00.000006");
AssertFormatting(formatter, 1542129070 * 1000000LL + 7, "2018-11-13 17:11:10.000007");
AssertFormatting(formatter, -2203932304LL * 1000000LL + 8,
"1900-02-28 12:34:56.000008");
}
{
StringFormatter<TimestampType> formatter(timestamp(TimeUnit::NANO));
AssertFormatting(formatter, 0, "1970-01-01 00:00:00.000000000");
AssertFormatting(formatter, 1000000000LL + 1, "1970-01-01 00:00:01.000000001");
AssertFormatting(formatter, 24 * 60 * 60 * 1000000000LL + 2,
"1970-01-02 00:00:00.000000002");
AssertFormatting(formatter, 616377600 * 1000000000LL + 3,
"1989-07-14 00:00:00.000000003");
AssertFormatting(formatter, 951782400 * 1000000000LL + 4,
"2000-02-29 00:00:00.000000004");
AssertFormatting(formatter, -2203977600LL * 1000000000LL + 6,
"1900-02-28 00:00:00.000000006");
AssertFormatting(formatter, 1542129070 * 1000000000LL + 7,
"2018-11-13 17:11:10.000000007");
AssertFormatting(formatter, -2203932304LL * 1000000000LL + 8,
"1900-02-28 12:34:56.000000008");
}
}
} // namespace arrow