mirror of
https://github.com/esphome/esphome.git
synced 2026-10-18 12:12:48 +00:00
[core] Construct App once in the C++ unit test main (#21001)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
co-authored by
J. Nick Koston
parent
4324b7d084
commit
e110613ef1
@@ -4,7 +4,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <new>
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/components/daikin/daikin.h"
|
||||
@@ -124,8 +123,6 @@ struct Rig {
|
||||
// A second fixture in the same test would otherwise restore what the first saved
|
||||
if (global_preferences != nullptr)
|
||||
global_preferences->reset();
|
||||
static const bool APP_CONSTRUCTED = (new (&App) Application(), true);
|
||||
(void) APP_CONSTRUCTED;
|
||||
static char name[] = "test_daikin_regression";
|
||||
static char friendly_name[] = "";
|
||||
App.pre_setup(name, sizeof(name) - 1, friendly_name, 0);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -146,9 +145,6 @@ struct Fixture {
|
||||
// A second fixture in the same test would otherwise restore what the first saved
|
||||
if (!keep_preferences && global_preferences != nullptr)
|
||||
global_preferences->reset();
|
||||
// The test main does not construct App as generated code does; the boost timer needs its scheduler
|
||||
static const bool APP_CONSTRUCTED = (new (&App) Application(), true);
|
||||
(void) APP_CONSTRUCTED;
|
||||
static char name[] = "test_daikin";
|
||||
static char friendly_name[] = "";
|
||||
App.pre_setup(name, sizeof(name) - 1, friendly_name, 0);
|
||||
|
||||
@@ -31,11 +31,6 @@ class TestCardDisplay : public Display {
|
||||
namespace {
|
||||
class TestCard : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// test_card() stops the poller, which needs the scheduler; the test main does not construct App.
|
||||
static const bool APP_CONSTRUCTED = (new (&App) Application(), true);
|
||||
(void) APP_CONSTRUCTED;
|
||||
}
|
||||
int writer_calls_{0};
|
||||
display_writer_t count_writer_() {
|
||||
return [this](Display &) { this->writer_calls_++; };
|
||||
|
||||
@@ -44,12 +44,6 @@ class MockUARTComponent : public uart::UARTComponent {
|
||||
#endif // defined(USE_ESP8266) || defined(USE_ESP32)
|
||||
};
|
||||
|
||||
// The test main does not construct App as generated code does
|
||||
inline void construct_app() {
|
||||
static const bool APP_CONSTRUCTED = (new (&App) Application(), true);
|
||||
(void) APP_CONSTRUCTED;
|
||||
}
|
||||
|
||||
inline void cancel_timers(EmonTx *emontx) {
|
||||
for (uint32_t id = 0; id < 3; id++)
|
||||
App.scheduler.cancel_timeout(emontx, id);
|
||||
|
||||
@@ -14,7 +14,6 @@ namespace {
|
||||
class EmonTxTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
construct_app();
|
||||
this->sut_.set_uart_parent(&this->uart_);
|
||||
this->sut_.add_on_data_callback([this](StringRef line) { this->lines_.emplace_back(line.c_str(), line.size()); });
|
||||
this->sut_.add_on_json_callback([this](JsonObject, StringRef) { this->json_count_++; });
|
||||
|
||||
@@ -12,7 +12,6 @@ namespace {
|
||||
class EmonTxVersionTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
construct_app();
|
||||
this->sut_.set_uart_parent(&this->uart_);
|
||||
this->sut_.set_version_text_sensor(&this->version_);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,9 @@ class FilterLifetimeTest : public ::testing::Test {
|
||||
unsigned publications_{0};
|
||||
|
||||
void SetUp() override {
|
||||
new (&App) Application;
|
||||
// The test main keeps App alive; this test replaces it with a fresh one it owns
|
||||
App.~Application();
|
||||
new (&App) Application();
|
||||
App.pre_setup("filter-lifetime-tests", 21, "Filter lifetime tests", 21);
|
||||
host::setup_preferences();
|
||||
host::host_preferences->reset();
|
||||
@@ -55,6 +57,7 @@ class FilterLifetimeTest : public ::testing::Test {
|
||||
void TearDown() override {
|
||||
host::host_preferences->reset();
|
||||
App.~Application();
|
||||
new (&App) Application(); // later tests and the test listener use App
|
||||
}
|
||||
|
||||
void attach(FilterLifetime &filter) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <array>
|
||||
#include <deque>
|
||||
#include <new>
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/components/haier_water_heater/hon_water_heater.h"
|
||||
@@ -53,9 +52,6 @@ class TestableHeater : public HonWaterHeater {
|
||||
class HonControllerTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// The test runner skips generated setup(), which normally constructs App and its scheduler.
|
||||
static const bool APP_CONSTRUCTED = (new (&App) Application(), true);
|
||||
(void) APP_CONSTRUCTED;
|
||||
this->heater_.set_uart_parent(&this->uart_);
|
||||
this->heater_.set_network_pending(false);
|
||||
this->set_clock_(100);
|
||||
|
||||
@@ -33,7 +33,9 @@ class ChipDevice : public Component, public I2CDevice {};
|
||||
class I2CChipIdTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
new (&App) Application;
|
||||
// The test main keeps App alive; this test replaces it with a fresh one it owns
|
||||
App.~Application();
|
||||
new (&App) Application();
|
||||
static char name[] = "i2c-chip-id-tests";
|
||||
static char friendly_name[] = "I2C chip ID tests";
|
||||
App.pre_setup(name, sizeof(name) - 1, friendly_name, sizeof(friendly_name) - 1);
|
||||
|
||||
@@ -32,6 +32,11 @@ class ResetAppListener : public ::testing::EmptyTestEventListener {
|
||||
};
|
||||
|
||||
void setup() {
|
||||
// Construct App once, as generated code does, before the logger, the listener or any test touches it.
|
||||
// A fixture that destroys App must construct it again before returning.
|
||||
// Placement new needs <new>, which the generated include block already provides
|
||||
new (&esphome::App) esphome::Application;
|
||||
|
||||
// Log functions call global_logger->log_vprintf_() without a null check,
|
||||
// so we must set up a Logger before any test that triggers logging.
|
||||
static esphome::logger::Logger test_logger(0);
|
||||
|
||||
@@ -84,9 +84,6 @@ struct Fixture {
|
||||
// A second fixture in the same test would otherwise restore what the first saved
|
||||
if (global_preferences != nullptr)
|
||||
global_preferences->reset();
|
||||
// The test main does not construct App as generated code does
|
||||
static const bool APP_CONSTRUCTED = (new (&App) Application(), true);
|
||||
(void) APP_CONSTRUCTED;
|
||||
static char name[] = "test_mistral_ir";
|
||||
static char friendly_name[] = "";
|
||||
App.pre_setup(name, sizeof(name) - 1, friendly_name, 0);
|
||||
|
||||
@@ -72,9 +72,6 @@ struct Fixture {
|
||||
// A second fixture in the same test would otherwise restore what the first saved
|
||||
if (global_preferences != nullptr)
|
||||
global_preferences->reset();
|
||||
// The test main does not construct App as generated code does
|
||||
static const bool APP_CONSTRUCTED = (new (&App) Application(), true);
|
||||
(void) APP_CONSTRUCTED;
|
||||
static char name[] = "test_pd_pioneer_ir";
|
||||
static char friendly_name[] = "";
|
||||
App.pre_setup(name, sizeof(name) - 1, friendly_name, 0);
|
||||
|
||||
@@ -46,9 +46,6 @@ class SnapshotAnimationTest : public ::testing::Test {
|
||||
fs::remove_all(this->dir_);
|
||||
fs::create_directories(this->dir_);
|
||||
setenv("ESPHOME_SNAPSHOT_DIR", this->dir_.c_str(), 1);
|
||||
// The test main does not construct App as generated code does, and recording needs its scheduler.
|
||||
static const bool app_constructed = (new (&App) Application(), true);
|
||||
(void) app_constructed;
|
||||
App.pre_setup("test_snapshot", 10, "", 0);
|
||||
}
|
||||
void TearDown() override {
|
||||
|
||||
@@ -71,7 +71,9 @@ class TMP102Test : public ::testing::Test {
|
||||
unsigned publications_{0};
|
||||
|
||||
void SetUp() override {
|
||||
new (&App) Application;
|
||||
// The test main keeps App alive; this test replaces it with a fresh one it owns
|
||||
App.~Application();
|
||||
new (&App) Application();
|
||||
App.pre_setup("tmp102-regression-tests", 23, "TMP102 tests", 12);
|
||||
host::setup_preferences();
|
||||
host::host_preferences->reset();
|
||||
@@ -93,6 +95,7 @@ class TMP102Test : public ::testing::Test {
|
||||
App.scheduler.call(millis());
|
||||
host::host_preferences->reset();
|
||||
App.~Application();
|
||||
new (&App) Application(); // later tests and the test listener use App
|
||||
}
|
||||
|
||||
static void run_timers(uint32_t duration) {
|
||||
|
||||
@@ -52,9 +52,6 @@ inline ble_device_base::ESPBTDevice advert(uint64_t address, const Frame &frame)
|
||||
|
||||
struct Harness {
|
||||
Harness(uint64_t address, const char *key) : scale(address, key) {
|
||||
// The test main does not construct App as generated code does; the stabilized reset needs its scheduler
|
||||
static const bool app_constructed = (new (&App) Application(), true);
|
||||
(void) app_constructed;
|
||||
App.pre_setup("test_scale", 10, "", 0);
|
||||
this->scale.set_weight(&this->weight);
|
||||
this->scale.set_impedance_low(&this->impedance_low);
|
||||
|
||||
Reference in New Issue
Block a user