Files
anvil/templates/weather/test/test_unit.cpp.tmpl
2026-02-21 20:52:48 -06:00

133 lines
3.6 KiB
Cheetah

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "hal.h"
#include "mock_hal.h"
#include "tmp36_mock.h"
#include "{{PROJECT_NAME}}_app.h"
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Return;
using ::testing::HasSubstr;
// ============================================================================
// Unit Tests -- verify WeatherApp behavior with mock sensor
// ============================================================================
class WeatherUnitTest : public ::testing::Test {
protected:
void SetUp() override {
ON_CALL(mock_, millis()).WillByDefault(Return(0));
EXPECT_CALL(mock_, serialBegin(_)).Times(AnyNumber());
EXPECT_CALL(mock_, serialPrint(_)).Times(AnyNumber());
EXPECT_CALL(mock_, serialPrintln(_)).Times(AnyNumber());
EXPECT_CALL(mock_, millis()).Times(AnyNumber());
}
::testing::NiceMock<MockHal> mock_;
Tmp36Mock sensor_;
};
TEST_F(WeatherUnitTest, BeginPrintsStartupMessage) {
WeatherApp app(&mock_, &sensor_);
EXPECT_CALL(mock_, serialBegin(115200)).Times(1);
EXPECT_CALL(mock_, serialPrintln(HasSubstr("WeatherApp started"))).Times(1);
app.begin();
}
TEST_F(WeatherUnitTest, BeginTakesInitialReading) {
sensor_.setTemperature(25.0f);
WeatherApp app(&mock_, &sensor_);
app.begin();
EXPECT_EQ(app.readCount(), 1);
EXPECT_NEAR(app.lastCelsius(), 25.0f, 0.1f);
}
TEST_F(WeatherUnitTest, ReadsAfterInterval) {
sensor_.setTemperature(20.0f);
WeatherApp app(&mock_, &sensor_);
ON_CALL(mock_, millis()).WillByDefault(Return(0));
app.begin();
EXPECT_EQ(app.readCount(), 1);
// Not enough time yet
ON_CALL(mock_, millis()).WillByDefault(Return(1999));
app.update();
EXPECT_EQ(app.readCount(), 1);
// Now 2 seconds have passed
ON_CALL(mock_, millis()).WillByDefault(Return(2000));
app.update();
EXPECT_EQ(app.readCount(), 2);
}
TEST_F(WeatherUnitTest, DoesNotReadTooEarly) {
sensor_.setTemperature(22.0f);
WeatherApp app(&mock_, &sensor_);
ON_CALL(mock_, millis()).WillByDefault(Return(0));
app.begin();
ON_CALL(mock_, millis()).WillByDefault(Return(1500));
app.update();
EXPECT_EQ(app.readCount(), 1);
}
TEST_F(WeatherUnitTest, CelsiusToFahrenheitConversion) {
sensor_.setTemperature(0.0f);
WeatherApp app(&mock_, &sensor_);
app.begin();
EXPECT_NEAR(app.lastCelsius(), 0.0f, 0.1f);
EXPECT_NEAR(app.lastFahrenheit(), 32.0f, 0.1f);
}
TEST_F(WeatherUnitTest, BoilingPoint) {
sensor_.setTemperature(100.0f);
WeatherApp app(&mock_, &sensor_);
app.begin();
EXPECT_NEAR(app.lastCelsius(), 100.0f, 0.1f);
EXPECT_NEAR(app.lastFahrenheit(), 212.0f, 0.1f);
}
TEST_F(WeatherUnitTest, NegativeTemperature) {
sensor_.setTemperature(-10.0f);
WeatherApp app(&mock_, &sensor_);
app.begin();
EXPECT_NEAR(app.lastCelsius(), -10.0f, 0.1f);
EXPECT_NEAR(app.lastFahrenheit(), 14.0f, 0.1f);
}
TEST_F(WeatherUnitTest, PrintsTemperatureOnRead) {
sensor_.setTemperature(25.0f);
WeatherApp app(&mock_, &sensor_);
EXPECT_CALL(mock_, serialPrint(HasSubstr("Temperature: "))).Times(1);
EXPECT_CALL(mock_, serialPrintln(HasSubstr(" F)"))).Times(1);
app.begin();
}
TEST_F(WeatherUnitTest, MultipleReadingsTrackNewTemperature) {
WeatherApp app(&mock_, &sensor_);
sensor_.setTemperature(20.0f);
ON_CALL(mock_, millis()).WillByDefault(Return(0));
app.begin();
EXPECT_NEAR(app.lastCelsius(), 20.0f, 0.1f);
sensor_.setTemperature(30.0f);
ON_CALL(mock_, millis()).WillByDefault(Return(2000));
app.update();
EXPECT_NEAR(app.lastCelsius(), 30.0f, 0.1f);
EXPECT_EQ(app.readCount(), 2);
}