mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 08:55:36 +00:00
Merge remote-tracking branch 'upstream/optimize-value-accuracy' into integration
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/string_ref.h"
|
||||
|
||||
namespace esphome::core::testing {
|
||||
|
||||
@@ -149,4 +150,73 @@ TEST(ValueAccuracyToBuf, ReturnsCorrectLength) {
|
||||
EXPECT_EQ(strlen(buf), len);
|
||||
}
|
||||
|
||||
// --- value_accuracy_with_uom_to_buf ---
|
||||
|
||||
static std::string va_uom_to_string(float value, int8_t accuracy_decimals, const char *uom) {
|
||||
char buf[VALUE_ACCURACY_MAX_LEN];
|
||||
std::span<char, VALUE_ACCURACY_MAX_LEN> sp(buf);
|
||||
StringRef ref(uom);
|
||||
size_t len = value_accuracy_with_uom_to_buf(sp, value, accuracy_decimals, ref);
|
||||
return std::string(buf, len);
|
||||
}
|
||||
|
||||
static std::string va_uom_reference(float value, int8_t accuracy_decimals, const char *uom) {
|
||||
char buf[VALUE_ACCURACY_MAX_LEN];
|
||||
if (!uom || *uom == '\0') {
|
||||
snprintf(buf, sizeof(buf), "%.*f", accuracy_decimals, value);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%.*f %s", accuracy_decimals, value, uom);
|
||||
}
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
TEST(ValueAccuracyWithUomToBuf, BasicWithUnit) {
|
||||
EXPECT_EQ(va_uom_to_string(23.456f, 2, "°C"), va_uom_reference(23.456f, 2, "°C"));
|
||||
EXPECT_EQ(va_uom_to_string(1013.25f, 2, "hPa"), va_uom_reference(1013.25f, 2, "hPa"));
|
||||
EXPECT_EQ(va_uom_to_string(-40.0f, 1, "°F"), va_uom_reference(-40.0f, 1, "°F"));
|
||||
EXPECT_EQ(va_uom_to_string(100.0f, 0, "%"), va_uom_reference(100.0f, 0, "%"));
|
||||
}
|
||||
|
||||
TEST(ValueAccuracyWithUomToBuf, EmptyUnit) {
|
||||
EXPECT_EQ(va_uom_to_string(23.456f, 2, ""), "23.46");
|
||||
EXPECT_EQ(va_uom_to_string(0.0f, 1, ""), "0.0");
|
||||
}
|
||||
|
||||
TEST(ValueAccuracyWithUomToBuf, ReturnsCorrectLength) {
|
||||
char buf[VALUE_ACCURACY_MAX_LEN];
|
||||
std::span<char, VALUE_ACCURACY_MAX_LEN> sp(buf);
|
||||
StringRef ref("°C");
|
||||
size_t len = value_accuracy_with_uom_to_buf(sp, 23.46f, 2, ref);
|
||||
EXPECT_EQ(strlen(buf), len);
|
||||
EXPECT_EQ(len, strlen("23.46 °C"));
|
||||
}
|
||||
|
||||
TEST(ValueAccuracyWithUomToBuf, NearBufferLimitTruncates) {
|
||||
// Build a unit long enough that value + " " + unit exceeds VALUE_ACCURACY_MAX_LEN.
|
||||
// "23.46" (5) + " " (1) + unit -> must cap at buf.size()-1 and stay null-terminated.
|
||||
std::string long_unit(VALUE_ACCURACY_MAX_LEN, 'U');
|
||||
char buf[VALUE_ACCURACY_MAX_LEN];
|
||||
std::span<char, VALUE_ACCURACY_MAX_LEN> sp(buf);
|
||||
StringRef ref(long_unit.c_str());
|
||||
size_t len = value_accuracy_with_uom_to_buf(sp, 23.46f, 2, ref);
|
||||
EXPECT_LT(len, VALUE_ACCURACY_MAX_LEN);
|
||||
EXPECT_EQ(strlen(buf), len);
|
||||
// Should begin with the formatted value and a separator.
|
||||
EXPECT_EQ(std::string(buf, 6), "23.46 ");
|
||||
}
|
||||
|
||||
TEST(ValueAccuracyWithUomToBuf, MatchesSnprintf) {
|
||||
const char *units[] = {"°C", "hPa", "%", "W", "kWh", "m/s"};
|
||||
float values[] = {0.0f, 23.456f, -40.0f, 1013.25f, 100.0f};
|
||||
int8_t accs[] = {0, 1, 2, 3};
|
||||
for (const char *u : units) {
|
||||
for (float v : values) {
|
||||
for (int8_t a : accs) {
|
||||
EXPECT_EQ(va_uom_to_string(v, a, u), va_uom_reference(v, a, u))
|
||||
<< "value=" << v << " acc=" << static_cast<int>(a) << " uom=" << u;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace esphome::core::testing
|
||||
|
||||
Reference in New Issue
Block a user