first commit
This commit is contained in:
commit
5893b00dd2
1669 changed files with 1982740 additions and 0 deletions
333
libraries/M5Utility/test/utility_test.cpp
Normal file
333
libraries/M5Utility/test/utility_test.cpp
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
/*
|
||||
UnitTest for M5Utility
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
#include <M5Utility.hpp>
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
using namespace m5::utility::log;
|
||||
|
||||
namespace {
|
||||
using pf_t = std::pair<const char* /* full path */, const char* /* filename */>;
|
||||
|
||||
pf_t table[] = {
|
||||
{"", ""}, {nullptr, ""},
|
||||
{"aaa", "aaa"}, {"ソソソソ", "ソソソソ"},
|
||||
{"a/b.c", "b.c"}, {"c:/aaa/bbb/ccc/ddd.eee", "ddd.eee"},
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(Utility, pathToFilename)
|
||||
{
|
||||
{
|
||||
constexpr auto fn0 = pathToFilename("");
|
||||
EXPECT_STREQ(fn0, "");
|
||||
constexpr auto fn1 = pathToFilename("ABC");
|
||||
EXPECT_STREQ(fn1, "ABC");
|
||||
constexpr auto fn2 = pathToFilename("a:/bb/ccc/dddd/eee.f");
|
||||
EXPECT_STREQ(fn2, "eee.f");
|
||||
}
|
||||
|
||||
for (auto&& e : table) {
|
||||
EXPECT_STREQ(pathToFilename(e.first), e.second) << e.first;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(Utility, log) {
|
||||
M5_LIB_LOGE("Error");
|
||||
M5_LIB_LOGW("Warn");
|
||||
M5_LIB_LOGI("Info");
|
||||
M5_LIB_LOGD("Debug");
|
||||
M5_LIB_LOGV("Verbose");
|
||||
|
||||
constexpr uint8_t test[] = {
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23,
|
||||
0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB,
|
||||
0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
|
||||
};
|
||||
M5_DUMPE(test + 0, sizeof(test) - 0);
|
||||
M5_DUMPE(test + 1, sizeof(test) - 1);
|
||||
M5_DUMPE(test + 7, sizeof(test) - 07;
|
||||
M5_DUMPE(test + 11, sizeof(test) - 11);
|
||||
M5_DUMPE(test + 19, sizeof(test) - 19);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
auto rng = std::default_random_engine{};
|
||||
}
|
||||
|
||||
TEST(Utility, BitSegment)
|
||||
{
|
||||
// static_assert
|
||||
#if 0
|
||||
{
|
||||
m5::utility::BitSegment<11, int8_t> compile_error1; // 11 > 8
|
||||
m5::utility::BitSegment<0, int8_t> copile_error2; // 0
|
||||
}
|
||||
#endif
|
||||
|
||||
// Constructor/Assignemt
|
||||
{
|
||||
using bs_t = m5::utility::BitSegment<6, uint8_t>;
|
||||
bs_t v0{0x84}; // base_type constructor
|
||||
bs_t v1 = v0; // same type constructor
|
||||
|
||||
EXPECT_EQ(v0.raw(), 0x84);
|
||||
EXPECT_EQ(v0.upper(), v1.upper());
|
||||
EXPECT_EQ(v0.lower(), v1.lower());
|
||||
EXPECT_EQ(v0.raw(), v1.raw());
|
||||
|
||||
bs_t v2, v3;
|
||||
EXPECT_EQ(v2.raw(), 0);
|
||||
EXPECT_EQ(v2.raw(), v3.raw());
|
||||
|
||||
v2 = -1; // base_type assignment
|
||||
EXPECT_NE(v2.raw(), v3.raw());
|
||||
|
||||
v3 = v2; // same type assignment
|
||||
EXPECT_EQ(v2.raw(), v3.raw());
|
||||
|
||||
bs_t v4 = 0xC0; // base_type constructor
|
||||
EXPECT_EQ(v4.raw(), 0xC0);
|
||||
}
|
||||
|
||||
// Getter/Setter using signed
|
||||
{
|
||||
using bs1_t = m5::utility::BitSegment<12, int16_t>;
|
||||
|
||||
auto t = std::is_same<int16_t, bs1_t::base_type>::value;
|
||||
EXPECT_TRUE(t);
|
||||
t = std::is_same<uint16_t, bs1_t::unsigned_type>::value;
|
||||
EXPECT_TRUE(t);
|
||||
|
||||
EXPECT_TRUE(bs1_t::SIGNED);
|
||||
EXPECT_EQ(+bs1_t::UPPER_BITS, 3);
|
||||
EXPECT_EQ(+bs1_t::LOWER_BITS, 12);
|
||||
EXPECT_EQ(+bs1_t::UPPER_SHIFT, 12);
|
||||
EXPECT_EQ(+bs1_t::UPPER_MASK, 0x07);
|
||||
EXPECT_EQ(+bs1_t::LOWER_MASK, 0xFFF);
|
||||
|
||||
bs1_t value0;
|
||||
EXPECT_EQ(value0.upper(), 0U);
|
||||
EXPECT_EQ(value0.lower(), 0U);
|
||||
EXPECT_EQ(value0.raw(), 0);
|
||||
|
||||
value0.lower(123);
|
||||
EXPECT_EQ(value0.upper(), 0U);
|
||||
EXPECT_EQ(value0.lower(), 123U);
|
||||
EXPECT_EQ(value0.raw(), 123);
|
||||
|
||||
value0.lower(0x7FFF);
|
||||
EXPECT_EQ(value0.upper(), 0U);
|
||||
EXPECT_EQ(value0.lower(), 0x0FFFU);
|
||||
EXPECT_EQ(value0.raw(), 0x0FFF);
|
||||
|
||||
value0.upper(5);
|
||||
EXPECT_EQ(value0.upper(), 5U);
|
||||
EXPECT_EQ(value0.lower(), 0xFFFU);
|
||||
EXPECT_EQ(value0.raw(), 0x5FFF);
|
||||
|
||||
value0.upper(0xFF);
|
||||
EXPECT_EQ(value0.upper(), 0x0007U);
|
||||
EXPECT_EQ(value0.lower(), 0x0FFFU);
|
||||
EXPECT_EQ(value0.raw(), 0x7FFF);
|
||||
|
||||
value0.raw(-1);
|
||||
EXPECT_EQ(value0.upper(), 0x0007U);
|
||||
EXPECT_EQ(value0.lower(), 0x0FFFU);
|
||||
EXPECT_EQ(value0.raw(), -1);
|
||||
|
||||
// Keep signed bit
|
||||
value0.lower(234);
|
||||
EXPECT_EQ(value0.upper(), 0x0007U);
|
||||
EXPECT_EQ(value0.lower(), 234U);
|
||||
EXPECT_EQ(value0.raw(), -3862); // 0xF0EA
|
||||
}
|
||||
|
||||
// Getter/Setter using unsigned
|
||||
{
|
||||
using bs2_t = m5::utility::BitSegment<12, const uint32_t&>;
|
||||
auto t = std::is_same<uint32_t, bs2_t::base_type>::value;
|
||||
EXPECT_TRUE(t);
|
||||
t = std::is_same<uint32_t, bs2_t::unsigned_type>::value;
|
||||
EXPECT_TRUE(t);
|
||||
|
||||
EXPECT_FALSE(bs2_t::SIGNED);
|
||||
EXPECT_EQ(+bs2_t::UPPER_BITS, 20U);
|
||||
EXPECT_EQ(+bs2_t::LOWER_BITS, 12U);
|
||||
EXPECT_EQ(+bs2_t::UPPER_SHIFT, 12U);
|
||||
EXPECT_EQ(+bs2_t::UPPER_MASK, 0xFFFFFU);
|
||||
EXPECT_EQ(+bs2_t::LOWER_MASK, 0xFFFU);
|
||||
|
||||
bs2_t value0;
|
||||
EXPECT_EQ(value0.upper(), 0U);
|
||||
EXPECT_EQ(value0.lower(), 0U);
|
||||
EXPECT_EQ(value0.raw(), 0U);
|
||||
|
||||
value0.lower(123);
|
||||
EXPECT_EQ(value0.upper(), 0U);
|
||||
EXPECT_EQ(value0.lower(), 123U);
|
||||
EXPECT_EQ(value0.raw(), 123U);
|
||||
|
||||
value0.lower(0x00003FFF);
|
||||
EXPECT_EQ(value0.upper(), 0U);
|
||||
EXPECT_EQ(value0.lower(), 0x00000FFFU);
|
||||
EXPECT_EQ(value0.raw(), 0x00000FFFU);
|
||||
|
||||
value0.upper(5);
|
||||
EXPECT_EQ(value0.upper(), 5U);
|
||||
EXPECT_EQ(value0.lower(), 0x00000FFFU);
|
||||
EXPECT_EQ(value0.raw(), 0x00005FFFU);
|
||||
|
||||
value0.upper(0x84218421);
|
||||
EXPECT_EQ(value0.upper(), 0x00018421U);
|
||||
EXPECT_EQ(value0.lower(), 0x00000FFFU);
|
||||
EXPECT_EQ(value0.raw(), 0x18421FFFU);
|
||||
|
||||
value0.raw(-1);
|
||||
EXPECT_EQ(value0.upper(), 0x000FFFFFU);
|
||||
EXPECT_EQ(value0.lower(), 0x00000FFFU);
|
||||
EXPECT_EQ(value0.raw(), 0xFFFFFFFFU);
|
||||
|
||||
// Not include signed bit
|
||||
value0.lower(234);
|
||||
EXPECT_EQ(value0.upper(), 0x000FFFFFU);
|
||||
EXPECT_EQ(value0.lower(), 234U);
|
||||
EXPECT_EQ(value0.raw(), 4294963434U); // 0xFFFFF0EA
|
||||
}
|
||||
|
||||
// Compare
|
||||
{
|
||||
using bs_t = m5::utility::BitSegment<14, int64_t>;
|
||||
|
||||
bs_t v0, v1;
|
||||
EXPECT_TRUE(v0 == v1);
|
||||
EXPECT_FALSE(v0 != v1);
|
||||
EXPECT_FALSE(v0 < v1);
|
||||
EXPECT_FALSE(v0 > v1);
|
||||
EXPECT_TRUE(v0 <= v1);
|
||||
EXPECT_TRUE(v0 >= v1);
|
||||
|
||||
EXPECT_TRUE(v0 == 0);
|
||||
EXPECT_FALSE(v0 != 0);
|
||||
EXPECT_FALSE(v0 < 0);
|
||||
EXPECT_FALSE(v0 > 0);
|
||||
EXPECT_TRUE(v0 <= 0);
|
||||
EXPECT_TRUE(v0 >= 0);
|
||||
|
||||
EXPECT_TRUE(0 == v0);
|
||||
EXPECT_FALSE(0 != v0);
|
||||
EXPECT_FALSE(0 < v0);
|
||||
EXPECT_FALSE(0 > v0);
|
||||
EXPECT_TRUE(0 <= v0);
|
||||
|
||||
v1.lower(123);
|
||||
EXPECT_FALSE(v0 == v1);
|
||||
EXPECT_TRUE(v0 != v1);
|
||||
EXPECT_TRUE(v0 < v1);
|
||||
EXPECT_FALSE(v0 > v1);
|
||||
EXPECT_TRUE(v0 <= v1);
|
||||
EXPECT_FALSE(v0 >= v1);
|
||||
|
||||
v0.lower(987);
|
||||
EXPECT_FALSE(v0 == v1);
|
||||
EXPECT_TRUE(v0 != v1);
|
||||
EXPECT_FALSE(v0 < v1);
|
||||
EXPECT_TRUE(v0 > v1);
|
||||
EXPECT_FALSE(v0 <= v1);
|
||||
EXPECT_TRUE(v0 >= v1);
|
||||
|
||||
v0 = v1;
|
||||
v1.upper(654321);
|
||||
EXPECT_FALSE(v0 == v1);
|
||||
EXPECT_TRUE(v0 != v1);
|
||||
EXPECT_TRUE(v0 < v1);
|
||||
EXPECT_FALSE(v0 > v1);
|
||||
EXPECT_TRUE(v0 <= v1);
|
||||
EXPECT_FALSE(v0 >= v1);
|
||||
|
||||
v0.upper(99999999);
|
||||
EXPECT_FALSE(v0 == v1);
|
||||
EXPECT_TRUE(v0 != v1);
|
||||
EXPECT_FALSE(v0 < v1);
|
||||
EXPECT_TRUE(v0 > v1);
|
||||
EXPECT_FALSE(v0 <= v1);
|
||||
EXPECT_TRUE(v0 >= v1);
|
||||
|
||||
v0 = v1 = 0;
|
||||
|
||||
v0 = -123;
|
||||
v1 = -12;
|
||||
EXPECT_FALSE(v0 == v1);
|
||||
EXPECT_TRUE(v0 != v1);
|
||||
EXPECT_TRUE(v0 < v1);
|
||||
EXPECT_FALSE(v0 > v1);
|
||||
EXPECT_TRUE(v0 <= v1);
|
||||
EXPECT_FALSE(v0 >= v1);
|
||||
|
||||
v1 = -876543;
|
||||
EXPECT_FALSE(v0 == v1);
|
||||
EXPECT_TRUE(v0 != v1);
|
||||
EXPECT_FALSE(v0 < v1);
|
||||
EXPECT_TRUE(v0 > v1);
|
||||
EXPECT_FALSE(v0 <= v1);
|
||||
EXPECT_TRUE(v0 >= v1);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
using clock = std::chrono::high_resolution_clock;
|
||||
}
|
||||
|
||||
TEST(Utility, comatibility)
|
||||
{
|
||||
// millis
|
||||
{
|
||||
auto ms = m5::utility::millis();
|
||||
auto ams = clock::now() + std::chrono::milliseconds(1);
|
||||
std::this_thread::sleep_until(ams);
|
||||
EXPECT_GT(m5::utility::millis(), ms);
|
||||
}
|
||||
// micros
|
||||
{
|
||||
auto us = m5::utility::micros();
|
||||
auto aus = clock::now() + std::chrono::microseconds(1);
|
||||
std::this_thread::sleep_until(aus);
|
||||
EXPECT_GT(m5::utility::micros(), us);
|
||||
}
|
||||
|
||||
// delay
|
||||
{
|
||||
constexpr unsigned long wait{20};
|
||||
auto start = clock::now();
|
||||
m5::utility::delay(wait);
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() - start).count();
|
||||
auto elapsed2 = std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - start).count();
|
||||
// printf("-----> %lld %lld\n", elapsed, elapsed2);
|
||||
#if defined(ARDUINO)
|
||||
EXPECT_GE(elapsed,
|
||||
wait - 1); // Arduino delay may return before the specified time.
|
||||
#else
|
||||
EXPECT_GE(elapsed, wait);
|
||||
#endif
|
||||
}
|
||||
|
||||
// delayMicroseconds
|
||||
{
|
||||
auto start = clock::now();
|
||||
m5::utility::delayMicroseconds(1);
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - start).count();
|
||||
EXPECT_GE(elapsed, 1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue