#include "tile/base/internal/format.h"

#include "tile/base/random.h"

#include "gtest/gtest.h"

#include <chrono>

template<typename T>
static std::string
ChronoFormat(const T &val)
{
    return fmt::format("{}", val);
}

TEST(Format, Chrono)
{
    EXPECT_EQ(ChronoFormat(std::chrono::nanoseconds(1)), "1ns");
    EXPECT_EQ(ChronoFormat(std::chrono::microseconds(1)), "1us");
    EXPECT_EQ(ChronoFormat(std::chrono::milliseconds(1)), "1ms");
    EXPECT_EQ(ChronoFormat(std::chrono::seconds(1)), "1s");
    EXPECT_EQ(ChronoFormat(std::chrono::minutes(1)), "1m");
    EXPECT_EQ(ChronoFormat(std::chrono::hours(1)), "1h");
}

TEST(Format, ChronoRandom)
{
    for (int i = 0; i < 1000; ++i) {
        int n = tile::Random(0, 1000000);

        EXPECT_EQ(ChronoFormat(std::chrono::nanoseconds(n)), fmt::format("{}ns", n));
        EXPECT_EQ(ChronoFormat(std::chrono::microseconds(n)), fmt::format("{}us", n));
        EXPECT_EQ(ChronoFormat(std::chrono::milliseconds(n)), fmt::format("{}ms", n));
        EXPECT_EQ(ChronoFormat(std::chrono::seconds(n)), fmt::format("{}s", n));
        EXPECT_EQ(ChronoFormat(std::chrono::minutes(n)), fmt::format("{}m", n));
        EXPECT_EQ(ChronoFormat(std::chrono::hours(n)), fmt::format("{}h", n));
    }
}

TEST(Format, HasToString)
{
    struct Foo {
        std::string ToString() const { return "Foo"; }
    };

    EXPECT_EQ(fmt::format("{}", Foo()), "Foo");
}
