Add tests
This commit is contained in:
parent
a3a5277e5d
commit
3fd27905ee
7 changed files with 1429 additions and 0 deletions
|
|
@ -24,6 +24,12 @@ set(CMAKE_AUTOUIC ON)
|
|||
# Add src to include path for relative includes
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
|
||||
# Enable testing framework
|
||||
enable_testing()
|
||||
|
||||
# Add subdirectory for tests
|
||||
add_subdirectory(tests)
|
||||
|
||||
# Create executable
|
||||
add_executable(SHinterface
|
||||
src/sensors/mqttsensorsource.h src/sensors/mqttsensorsource.cpp)
|
||||
|
|
|
|||
140
tests/CMakeLists.txt
Normal file
140
tests/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
cmake_minimum_required(VERSION 4.0)
|
||||
|
||||
# Enable testing
|
||||
enable_testing()
|
||||
|
||||
# Find Qt packages for tests
|
||||
find_package(Qt6 COMPONENTS Core Gui Widgets Multimedia Test REQUIRED)
|
||||
|
||||
# Define common sources needed by all tests - include only what's actually needed for basic testing
|
||||
set(COMMON_TEST_SOURCES
|
||||
../src/items/item.h
|
||||
../src/items/item.cpp
|
||||
../src/sensors/sensor.h
|
||||
../src/sensors/sensor.cpp
|
||||
../src/programmode.h
|
||||
../src/programmode.cpp
|
||||
../src/microcontroller.h
|
||||
../src/microcontroller.cpp
|
||||
../src/actors/actor.h
|
||||
../src/actors/actor.cpp
|
||||
../src/actors/factoractor.h
|
||||
../src/actors/factoractor.cpp
|
||||
../src/actors/polynomalactor.h
|
||||
../src/actors/polynomalactor.cpp
|
||||
../src/actors/sensoractor.h
|
||||
../src/actors/sensoractor.cpp
|
||||
../src/actors/timeractor.h
|
||||
../src/actors/timeractor.cpp
|
||||
../src/items/relay.h
|
||||
../src/items/relay.cpp
|
||||
../src/items/messageitem.h
|
||||
../src/items/messageitem.cpp
|
||||
../src/items/systemitem.h
|
||||
../src/items/systemitem.cpp
|
||||
../src/items/auxitem.h
|
||||
../src/items/auxitem.cpp
|
||||
../src/items/poweritem.h
|
||||
../src/items/poweritem.cpp
|
||||
../src/items/rgbitem.h
|
||||
../src/items/rgbitem.cpp
|
||||
../src/actors/alarmtime.h
|
||||
../src/actors/alarmtime.cpp
|
||||
../src/actors/regulator.h
|
||||
../src/actors/regulator.cpp
|
||||
../src/items/itemsource.h
|
||||
../src/items/itemsource.cpp
|
||||
../src/items/itemstore.h
|
||||
../src/items/itemstore.cpp
|
||||
../src/items/itemloadersource.h
|
||||
../src/items/itemloadersource.cpp
|
||||
)
|
||||
|
||||
# Add test executables - compile all needed sources into each test
|
||||
add_executable(test_item unit/items/test_item.cpp ${COMMON_TEST_SOURCES})
|
||||
add_executable(test_sensor unit/sensors/test_sensor.cpp ${COMMON_TEST_SOURCES})
|
||||
add_executable(test_actor unit/actors/test_actor.cpp ${COMMON_TEST_SOURCES})
|
||||
add_executable(test_itemstore unit/items/test_itemstore.cpp ${COMMON_TEST_SOURCES})
|
||||
add_executable(test_itemloadersource unit/items/test_itemloadersource.cpp ${COMMON_TEST_SOURCES})
|
||||
|
||||
# Link libraries for test_item
|
||||
target_link_libraries(test_item
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
Qt6::Multimedia
|
||||
Qt6::Test
|
||||
)
|
||||
|
||||
# Include paths for source files
|
||||
target_include_directories(test_item PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../src
|
||||
${Qt6Gui_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
# Link libraries for test_sensor
|
||||
target_link_libraries(test_sensor
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
Qt6::Multimedia
|
||||
Qt6::Test
|
||||
)
|
||||
|
||||
# Include paths for source files
|
||||
target_include_directories(test_sensor PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../src
|
||||
${Qt6Gui_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
# Link libraries for test_actor
|
||||
target_link_libraries(test_actor
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
Qt6::Multimedia
|
||||
Qt6::Test
|
||||
)
|
||||
|
||||
# Include paths for source files
|
||||
target_include_directories(test_actor PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../src
|
||||
${Qt6Gui_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
# Link libraries for test_itemstore
|
||||
target_link_libraries(test_itemstore
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
Qt6::Multimedia
|
||||
Qt6::Test
|
||||
)
|
||||
|
||||
# Include paths for source files
|
||||
target_include_directories(test_itemstore PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../src
|
||||
${Qt6Gui_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
# Link libraries for test_itemloadersource
|
||||
target_link_libraries(test_itemloadersource
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
Qt6::Multimedia
|
||||
Qt6::Test
|
||||
)
|
||||
|
||||
# Include paths for source files
|
||||
target_include_directories(test_itemloadersource PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../src
|
||||
${Qt6Gui_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
# Add tests to CTest
|
||||
add_test(NAME test_item COMMAND test_item)
|
||||
add_test(NAME test_sensor COMMAND test_sensor)
|
||||
add_test(NAME test_actor COMMAND test_actor)
|
||||
add_test(NAME test_itemstore COMMAND test_itemstore)
|
||||
add_test(NAME test_itemloadersource COMMAND test_itemloadersource)
|
||||
333
tests/unit/actors/test_actor.cpp
Normal file
333
tests/unit/actors/test_actor.cpp
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
#include <QtTest/QtTest>
|
||||
#include "actors/actor.h"
|
||||
#include "actors/timeractor.h"
|
||||
#include "actors/sensoractor.h"
|
||||
|
||||
class TestActor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
// Setup for all tests
|
||||
}
|
||||
|
||||
void testActorCreation()
|
||||
{
|
||||
Actor actor;
|
||||
|
||||
// Actor should be active by default
|
||||
QVERIFY(actor.isActive());
|
||||
|
||||
// Actor should not be exhausted by default
|
||||
QVERIFY(!actor.isExausted());
|
||||
}
|
||||
|
||||
void testActorActivation()
|
||||
{
|
||||
Actor actor;
|
||||
|
||||
// Test makeActive/makeInactive
|
||||
actor.makeActive();
|
||||
QVERIFY(actor.isActive());
|
||||
|
||||
actor.makeInactive();
|
||||
QVERIFY(!actor.isActive());
|
||||
}
|
||||
|
||||
void testActorSetActive()
|
||||
{
|
||||
Actor actor;
|
||||
|
||||
// Test setActive
|
||||
actor.setActive(1);
|
||||
QVERIFY(actor.isActive());
|
||||
|
||||
actor.setActive(0);
|
||||
QVERIFY(!actor.isActive());
|
||||
}
|
||||
|
||||
void testActorTriggerValue()
|
||||
{
|
||||
Actor actor;
|
||||
|
||||
// Default trigger value should be 0
|
||||
QVERIFY(actor.getTriggerValue() == 0);
|
||||
|
||||
// Set trigger value
|
||||
actor.setTriggerValue(1);
|
||||
QVERIFY(actor.getTriggerValue() == 1);
|
||||
|
||||
actor.setTriggerValue(255);
|
||||
QVERIFY(actor.getTriggerValue() == 255);
|
||||
}
|
||||
|
||||
void testActorActionName()
|
||||
{
|
||||
Actor actor;
|
||||
|
||||
// Default trigger value is 0, so action name should be "off"
|
||||
QVERIFY(actor.actionName() == "off");
|
||||
|
||||
// Set trigger value to 1
|
||||
actor.setTriggerValue(1);
|
||||
QVERIFY(actor.actionName() == "on");
|
||||
|
||||
// Set trigger value to something else
|
||||
actor.setTriggerValue(5);
|
||||
QVERIFY(actor.actionName() == "value to 5");
|
||||
}
|
||||
|
||||
void testActorJsonSerialization()
|
||||
{
|
||||
Actor actor;
|
||||
actor.setTriggerValue(1);
|
||||
actor.makeInactive();
|
||||
|
||||
QJsonObject json;
|
||||
actor.store(json);
|
||||
|
||||
// Verify JSON contents
|
||||
QVERIFY(json.contains("Active"));
|
||||
QVERIFY(json.contains("Exausted"));
|
||||
QVERIFY(json.contains("TriggerValue"));
|
||||
|
||||
QVERIFY(json["Active"].toBool() == false);
|
||||
QVERIFY(json["Exausted"].toBool() == false);
|
||||
QVERIFY(json["TriggerValue"].toInt() == 1);
|
||||
}
|
||||
|
||||
void testActorJsonDeserialization()
|
||||
{
|
||||
QJsonObject json;
|
||||
json["Active"] = false;
|
||||
json["Exausted"] = true;
|
||||
json["TriggerValue"] = 5;
|
||||
|
||||
Actor actor;
|
||||
actor.load(json);
|
||||
|
||||
QVERIFY(actor.isActive() == false);
|
||||
QVERIFY(actor.isExausted() == true);
|
||||
QVERIFY(actor.getTriggerValue() == 5);
|
||||
}
|
||||
|
||||
void testActorCreateActor()
|
||||
{
|
||||
// Test creating different actor types
|
||||
std::shared_ptr<Actor> alarmActor = Actor::createActor("Alarm");
|
||||
QVERIFY(alarmActor != nullptr);
|
||||
|
||||
std::shared_ptr<Actor> sensorActor = Actor::createActor("Sensor");
|
||||
QVERIFY(sensorActor != nullptr);
|
||||
|
||||
std::shared_ptr<Actor> timerActor = Actor::createActor("Timer");
|
||||
QVERIFY(timerActor != nullptr);
|
||||
|
||||
std::shared_ptr<Actor> regulatorActor = Actor::createActor("Regulator");
|
||||
QVERIFY(regulatorActor != nullptr);
|
||||
|
||||
std::shared_ptr<Actor> polynomalActor = Actor::createActor("Polynomal");
|
||||
QVERIFY(polynomalActor != nullptr);
|
||||
|
||||
std::shared_ptr<Actor> factorActor = Actor::createActor("MultiFactor");
|
||||
QVERIFY(factorActor != nullptr);
|
||||
|
||||
std::shared_ptr<Actor> genericActor = Actor::createActor("Actor");
|
||||
QVERIFY(genericActor != nullptr);
|
||||
|
||||
// Test unknown type returns nullptr
|
||||
std::shared_ptr<Actor> unknownActor = Actor::createActor("UnknownType");
|
||||
QVERIFY(unknownActor == nullptr);
|
||||
}
|
||||
|
||||
void testActorLoadActor()
|
||||
{
|
||||
QJsonObject json;
|
||||
json["Type"] = "Timer";
|
||||
json["Active"] = true;
|
||||
json["Exausted"] = false;
|
||||
json["TriggerValue"] = 1;
|
||||
json["Timeout"] = 5000;
|
||||
|
||||
std::shared_ptr<Actor> actor = Actor::loadActor(json);
|
||||
QVERIFY(actor != nullptr);
|
||||
|
||||
// Verify the actor was loaded with correct values
|
||||
QVERIFY(actor->isActive());
|
||||
QVERIFY(!actor->isExausted());
|
||||
QVERIFY(actor->getTriggerValue() == 1);
|
||||
}
|
||||
|
||||
void testTimerActorCreation()
|
||||
{
|
||||
TimerActor actor(60);
|
||||
|
||||
// Default timeout should be 60 seconds
|
||||
QVERIFY(actor.getTimeout() == 60);
|
||||
}
|
||||
|
||||
void testTimerActorSetTimeout()
|
||||
{
|
||||
TimerActor actor(60);
|
||||
|
||||
actor.setTimeout(120);
|
||||
QVERIFY(actor.getTimeout() == 120);
|
||||
|
||||
actor.setTimeout(5);
|
||||
QVERIFY(actor.getTimeout() == 5);
|
||||
}
|
||||
|
||||
void testTimerActorJsonSerialization()
|
||||
{
|
||||
TimerActor actor(120);
|
||||
|
||||
QJsonObject json;
|
||||
actor.store(json);
|
||||
|
||||
// Verify JSON contents
|
||||
QVERIFY(json.contains("Type"));
|
||||
QVERIFY(json.contains("Timeout"));
|
||||
|
||||
QVERIFY(json["Type"].toString() == "Timer");
|
||||
QVERIFY(json["Timeout"].toInt() == 120000); // Converted to milliseconds
|
||||
}
|
||||
|
||||
void testTimerActorJsonDeserialization()
|
||||
{
|
||||
QJsonObject json;
|
||||
json["Type"] = "Timer";
|
||||
json["Timeout"] = 30000; // 30 seconds in milliseconds
|
||||
json["Active"] = true;
|
||||
json["Exausted"] = false;
|
||||
json["TriggerValue"] = 1;
|
||||
|
||||
TimerActor actor;
|
||||
actor.load(json, false);
|
||||
|
||||
// Timeout should be 30 seconds
|
||||
QVERIFY(actor.getTimeout() == 30);
|
||||
}
|
||||
|
||||
void testTimerActorGetName()
|
||||
{
|
||||
TimerActor actor(60);
|
||||
|
||||
QString name = actor.getName();
|
||||
QVERIFY(name.contains("60"));
|
||||
}
|
||||
|
||||
void testSensorActorCreation()
|
||||
{
|
||||
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0, "temp_sensor");
|
||||
SensorActor actor(sensor);
|
||||
|
||||
// Verify sensor was set correctly
|
||||
QVERIFY(actor.getSensor().type == Sensor::TYPE_TEMPERATURE);
|
||||
QVERIFY(actor.getSensor().id == 1);
|
||||
}
|
||||
|
||||
void testSensorActorDefaultCreation()
|
||||
{
|
||||
SensorActor actor;
|
||||
|
||||
// Default sensor should be dummy
|
||||
QVERIFY(actor.getSensor().type == Sensor::TYPE_DUMMY);
|
||||
}
|
||||
|
||||
void testSensorActorSetSensor()
|
||||
{
|
||||
SensorActor actor;
|
||||
|
||||
Sensor newSensor(Sensor::TYPE_HUMIDITY, 2, 60.0, "humidity_sensor");
|
||||
actor.setSensor(newSensor);
|
||||
|
||||
QVERIFY(actor.getSensor().type == Sensor::TYPE_HUMIDITY);
|
||||
QVERIFY(actor.getSensor().id == 2);
|
||||
}
|
||||
|
||||
void testSensorActorSetThreshold()
|
||||
{
|
||||
SensorActor actor;
|
||||
|
||||
actor.setThreshold(25.0);
|
||||
QVERIFY(actor.getThreshold() == 25.0);
|
||||
}
|
||||
|
||||
void testSensorActorSetSlope()
|
||||
{
|
||||
SensorActor actor;
|
||||
|
||||
actor.setSloap(SensorActor::SLOPE_UP);
|
||||
QVERIFY(actor.getSloap() == SensorActor::SLOPE_UP);
|
||||
|
||||
actor.setSloap(SensorActor::SLOPE_DOWN);
|
||||
QVERIFY(actor.getSloap() == SensorActor::SLOPE_DOWN);
|
||||
|
||||
actor.setSloap(SensorActor::SLOPE_BOTH);
|
||||
QVERIFY(actor.getSloap() == SensorActor::SLOPE_BOTH);
|
||||
}
|
||||
|
||||
void testSensorActorJsonSerialization()
|
||||
{
|
||||
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0, "temp_sensor");
|
||||
SensorActor actor(sensor);
|
||||
actor.setThreshold(30.0);
|
||||
actor.setSloap(SensorActor::SLOPE_UP);
|
||||
|
||||
QJsonObject json;
|
||||
actor.store(json);
|
||||
|
||||
// Verify JSON contents
|
||||
QVERIFY(json.contains("Type"));
|
||||
QVERIFY(json.contains("Threshold"));
|
||||
QVERIFY(json.contains("Sloap"));
|
||||
QVERIFY(json.contains("SensorType"));
|
||||
|
||||
QVERIFY(json["Type"].toString() == "Sensor");
|
||||
QVERIFY(json["Threshold"].toDouble() == 30.0);
|
||||
QVERIFY(json["Sloap"].toInt() == SensorActor::SLOPE_UP);
|
||||
}
|
||||
|
||||
void testSensorActorJsonDeserialization()
|
||||
{
|
||||
QJsonObject json;
|
||||
json["Type"] = "Sensor";
|
||||
json["Threshold"] = 25.5;
|
||||
json["Sloap"] = SensorActor::SLOPE_DOWN;
|
||||
json["SensorType"] = Sensor::TYPE_HUMIDITY;
|
||||
json["SensorId"] = 3;
|
||||
json["SensorField"] = 65.0;
|
||||
json["SensorName"] = "humidity";
|
||||
json["Active"] = true;
|
||||
json["Exausted"] = false;
|
||||
json["TriggerValue"] = 1;
|
||||
|
||||
SensorActor actor;
|
||||
actor.load(json, false);
|
||||
|
||||
QVERIFY(actor.getThreshold() == 25.5);
|
||||
QVERIFY(actor.getSloap() == SensorActor::SLOPE_DOWN);
|
||||
}
|
||||
|
||||
void testSensorActorGetName()
|
||||
{
|
||||
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0, "temp_sensor");
|
||||
SensorActor actor(sensor);
|
||||
actor.setThreshold(30.0);
|
||||
|
||||
QString name = actor.getName();
|
||||
QVERIFY(name.contains("temp_sensor"));
|
||||
QVERIFY(name.contains("30"));
|
||||
}
|
||||
|
||||
void cleanupTestCase()
|
||||
{
|
||||
// Cleanup after all tests
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_APPLESS_MAIN(TestActor)
|
||||
|
||||
#include "test_actor.moc"
|
||||
225
tests/unit/items/test_item.cpp
Normal file
225
tests/unit/items/test_item.cpp
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
#include <QtTest/QtTest>
|
||||
#include "items/item.h"
|
||||
#include "items/itemstore.h"
|
||||
#include "items/itemsource.h"
|
||||
#include "items/itemloadersource.h"
|
||||
|
||||
class TestItem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
// Setup for all tests
|
||||
}
|
||||
|
||||
void testItemCreation()
|
||||
{
|
||||
Item item(0, "test_item", 0);
|
||||
QCOMPARE(item.getName(), QString("test_item"));
|
||||
}
|
||||
|
||||
void testOverrideFunctionality()
|
||||
{
|
||||
Item item(0, "test_item", 0);
|
||||
|
||||
// Test override on/off
|
||||
item.setOverride(true);
|
||||
QVERIFY(item.getOverride());
|
||||
|
||||
item.setOverride(false);
|
||||
QVERIFY(!item.getOverride());
|
||||
}
|
||||
|
||||
void testItemValueTypes()
|
||||
{
|
||||
// Test default value type is BOOL
|
||||
Item item(1, "test_item", 0);
|
||||
QCOMPARE(item.getValueType(), ITEM_VALUE_BOOL);
|
||||
|
||||
// Test setting and getting value
|
||||
item.setValueData(1);
|
||||
QCOMPARE(item.getValue(), static_cast<uint8_t>(1));
|
||||
|
||||
item.setValueData(0);
|
||||
QCOMPARE(item.getValue(), static_cast<uint8_t>(0));
|
||||
}
|
||||
|
||||
void testItemId()
|
||||
{
|
||||
Item item(42, "test_item", 0);
|
||||
QCOMPARE(item.id(), static_cast<uint32_t>(42));
|
||||
}
|
||||
|
||||
void testItemGroupName()
|
||||
{
|
||||
Item item(1, "test_item", 0);
|
||||
QCOMPARE(item.getGroupName(), QString("All")); // Default group
|
||||
|
||||
item.setGroupName("Living Room");
|
||||
QCOMPARE(item.getGroupName(), QString("Living Room"));
|
||||
}
|
||||
|
||||
void testItemHidden()
|
||||
{
|
||||
Item item(1, "test_item", 0);
|
||||
QVERIFY(!item.isHidden());
|
||||
|
||||
item.setHidden(true);
|
||||
QVERIFY(item.isHidden());
|
||||
|
||||
item.setHidden(false);
|
||||
QVERIFY(!item.isHidden());
|
||||
}
|
||||
|
||||
void testItemLoaded()
|
||||
{
|
||||
Item item(1, "test_item", 0);
|
||||
QVERIFY(!item.getLoaded());
|
||||
|
||||
item.setLoaded(true);
|
||||
QVERIFY(item.getLoaded());
|
||||
}
|
||||
|
||||
void testItemJsonSerialization()
|
||||
{
|
||||
Item item(42, "test_item", 1);
|
||||
item.setGroupName("TestGroup");
|
||||
|
||||
QJsonObject json;
|
||||
item.store(json);
|
||||
|
||||
// Verify JSON contents
|
||||
QCOMPARE(json["ItemId"].toDouble(), 42.0);
|
||||
// Note: Name is only stored if changes.name is true
|
||||
// Value is only stored if changes.value is true
|
||||
}
|
||||
|
||||
void testItemJsonDeserialization()
|
||||
{
|
||||
QJsonObject json;
|
||||
json["ItemId"] = 100;
|
||||
json["Name"] = "loaded_item";
|
||||
json["Value"] = 1;
|
||||
json["GroupName"] = "Bedroom";
|
||||
|
||||
Item item;
|
||||
item.load(json);
|
||||
|
||||
// Note: load() uses loadWithChanges which requires preserve=false to apply changes
|
||||
// The id should be set
|
||||
// The name should be set (since preserve defaults to false)
|
||||
}
|
||||
|
||||
void testItemUpdateRequest()
|
||||
{
|
||||
Item item(1, "test_item", 0);
|
||||
|
||||
// Test creating update request
|
||||
ItemUpdateRequest request = item.createValueUpdateRequest(ITEM_UPDATE_USER, false);
|
||||
|
||||
QVERIFY(request.type == ITEM_UPDATE_USER);
|
||||
// Note: changes is not automatically set by createValueUpdateRequest
|
||||
// The caller is expected to set the changes they want
|
||||
QVERIFY(request.newActors.empty());
|
||||
}
|
||||
|
||||
void testItemUpdateRequestWithActors()
|
||||
{
|
||||
Item item(1, "test_item", 0);
|
||||
|
||||
// Test creating update request with actors
|
||||
ItemUpdateRequest request = item.createValueUpdateRequest(ITEM_UPDATE_USER, true);
|
||||
|
||||
QVERIFY(request.type == ITEM_UPDATE_USER);
|
||||
// With actors=true, newActors should be populated
|
||||
// Note: changes.actors is set by the caller, not by createValueUpdateRequest
|
||||
}
|
||||
|
||||
void testItemHasActors()
|
||||
{
|
||||
Item item(1, "test_item", 0);
|
||||
|
||||
QVERIFY(!item.hasActors());
|
||||
|
||||
// Note: Adding actors requires a valid Actor pointer
|
||||
}
|
||||
|
||||
void testItemRemoveAllActors()
|
||||
{
|
||||
Item item(1, "test_item", 0);
|
||||
|
||||
item.removeAllActors();
|
||||
QVERIFY(!item.hasActors());
|
||||
}
|
||||
|
||||
void testItemSetActorsActive()
|
||||
{
|
||||
Item item(1, "test_item", 0);
|
||||
|
||||
// Should not crash when no actors
|
||||
item.setActorsActive(true);
|
||||
item.setActorsActive(false);
|
||||
}
|
||||
|
||||
void testItemDataChangeDetection()
|
||||
{
|
||||
ItemData data1(1, "item1", 0);
|
||||
ItemData data2(1, "item1", 1);
|
||||
|
||||
// Test value change detection
|
||||
ItemFieldChanges changes(true);
|
||||
QVERIFY(data1.hasChanged(data2, changes));
|
||||
|
||||
// Test no change
|
||||
changes = ItemFieldChanges(false);
|
||||
QVERIFY(!data1.hasChanged(data2, changes));
|
||||
}
|
||||
|
||||
void testItemDataNameChange()
|
||||
{
|
||||
ItemData data1(1, "item1", 0);
|
||||
ItemData data2(1, "item2", 0);
|
||||
|
||||
ItemFieldChanges changes;
|
||||
changes.name = true;
|
||||
|
||||
QVERIFY(data1.hasChanged(data2, changes));
|
||||
}
|
||||
|
||||
void testItemDataGroupNameChange()
|
||||
{
|
||||
ItemData data1(1, "item1", 0);
|
||||
data1.setGroupName("Group1");
|
||||
|
||||
ItemData data2(1, "item1", 0);
|
||||
data2.setGroupName("Group2");
|
||||
|
||||
ItemFieldChanges changes;
|
||||
changes.groupName = true;
|
||||
|
||||
QVERIFY(data1.hasChanged(data2, changes));
|
||||
}
|
||||
|
||||
void testItemFieldChanges()
|
||||
{
|
||||
ItemFieldChanges changes(false);
|
||||
QVERIFY(changes.isNone());
|
||||
|
||||
changes.value = true;
|
||||
QVERIFY(!changes.isNone());
|
||||
|
||||
ItemFieldChanges allChanges(true);
|
||||
QVERIFY(!allChanges.isNone());
|
||||
}
|
||||
|
||||
void cleanupTestCase()
|
||||
{
|
||||
// Cleanup after all tests
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_APPLESS_MAIN(TestItem)
|
||||
|
||||
#include "test_item.moc"
|
||||
240
tests/unit/items/test_itemloadersource.cpp
Normal file
240
tests/unit/items/test_itemloadersource.cpp
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
#include <QtTest/QtTest>
|
||||
#include "items/itemloadersource.h"
|
||||
#include "items/item.h"
|
||||
|
||||
class TestItemLoaderSource : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
// Setup for all tests
|
||||
}
|
||||
|
||||
void testItemLoaderSourceCreation()
|
||||
{
|
||||
ItemLoaderSource source;
|
||||
|
||||
// Should be created with empty JSON
|
||||
QVERIFY(true); // No crash
|
||||
}
|
||||
|
||||
void testItemLoaderSourceCreationWithJson()
|
||||
{
|
||||
QJsonObject json;
|
||||
json["Items"] = QJsonArray();
|
||||
|
||||
ItemLoaderSource source(json);
|
||||
|
||||
// Should be created with JSON
|
||||
QVERIFY(true); // No crash
|
||||
}
|
||||
|
||||
void testItemLoaderSourceRefreshEmpty()
|
||||
{
|
||||
ItemLoaderSource source;
|
||||
|
||||
// Should not crash with empty JSON
|
||||
source.refresh();
|
||||
|
||||
// No items should be emitted
|
||||
QVERIFY(true);
|
||||
}
|
||||
|
||||
void testItemLoaderSourceRefreshWithItems()
|
||||
{
|
||||
QJsonObject json;
|
||||
QJsonArray itemsArray;
|
||||
|
||||
QJsonObject item1;
|
||||
item1["Type"] = "Item";
|
||||
item1["ItemId"] = 1;
|
||||
item1["Name"] = "test_item1";
|
||||
item1["Value"] = 0;
|
||||
itemsArray.append(item1);
|
||||
|
||||
QJsonObject item2;
|
||||
item2["Type"] = "Item";
|
||||
item2["ItemId"] = 2;
|
||||
item2["Name"] = "test_item2";
|
||||
item2["Value"] = 1;
|
||||
itemsArray.append(item2);
|
||||
|
||||
json["Items"] = itemsArray;
|
||||
|
||||
ItemLoaderSource source(json);
|
||||
|
||||
// Capture the gotItems signal
|
||||
std::vector<ItemAddRequest> capturedItems;
|
||||
connect(&source, &ItemLoaderSource::gotItems,
|
||||
[&capturedItems](std::vector<ItemAddRequest> items) {
|
||||
capturedItems = items;
|
||||
});
|
||||
|
||||
source.refresh();
|
||||
|
||||
// Should have 2 items
|
||||
QVERIFY(capturedItems.size() == 2);
|
||||
}
|
||||
|
||||
void testItemLoaderSourceRefreshWithRelay()
|
||||
{
|
||||
QJsonObject json;
|
||||
QJsonArray itemsArray;
|
||||
|
||||
QJsonObject relay;
|
||||
relay["Type"] = "Relay";
|
||||
relay["ItemId"] = 100;
|
||||
relay["Name"] = "test_relay";
|
||||
relay["Value"] = 0;
|
||||
relay["Id"] = 1;
|
||||
relay["Address"] = 0x2000;
|
||||
itemsArray.append(relay);
|
||||
|
||||
json["Items"] = itemsArray;
|
||||
|
||||
ItemLoaderSource source(json);
|
||||
|
||||
// Capture the gotItems signal
|
||||
std::vector<ItemAddRequest> capturedItems;
|
||||
connect(&source, &ItemLoaderSource::gotItems,
|
||||
[&capturedItems](std::vector<ItemAddRequest> items) {
|
||||
capturedItems = items;
|
||||
});
|
||||
|
||||
source.refresh();
|
||||
|
||||
// Should have 1 item
|
||||
QVERIFY(capturedItems.size() == 1);
|
||||
}
|
||||
|
||||
void testItemLoaderSourceUpdateJson()
|
||||
{
|
||||
ItemLoaderSource source;
|
||||
|
||||
// Initial JSON
|
||||
QJsonObject json1;
|
||||
QJsonArray items1;
|
||||
QJsonObject item1;
|
||||
item1["Type"] = "Item";
|
||||
item1["ItemId"] = 1;
|
||||
item1["Name"] = "item1";
|
||||
items1.append(item1);
|
||||
json1["Items"] = items1;
|
||||
|
||||
source.updateJson(json1);
|
||||
|
||||
// Update JSON
|
||||
QJsonObject json2;
|
||||
QJsonArray items2;
|
||||
QJsonObject item2;
|
||||
item2["Type"] = "Item";
|
||||
item2["ItemId"] = 2;
|
||||
item2["Name"] = "item2";
|
||||
items2.append(item2);
|
||||
json2["Items"] = items2;
|
||||
|
||||
source.updateJson(json2);
|
||||
|
||||
// Should not crash
|
||||
QVERIFY(true);
|
||||
}
|
||||
|
||||
void testItemLoaderSourceRefreshWithInvalidItems()
|
||||
{
|
||||
QJsonObject json;
|
||||
QJsonArray itemsArray;
|
||||
|
||||
// Add invalid item (no Type)
|
||||
QJsonObject item1;
|
||||
item1["ItemId"] = 1;
|
||||
itemsArray.append(item1);
|
||||
|
||||
json["Items"] = itemsArray;
|
||||
|
||||
ItemLoaderSource source(json);
|
||||
|
||||
// Capture the gotItems signal
|
||||
std::vector<ItemAddRequest> capturedItems;
|
||||
connect(&source, &ItemLoaderSource::gotItems,
|
||||
[&capturedItems](std::vector<ItemAddRequest> items) {
|
||||
capturedItems = items;
|
||||
});
|
||||
|
||||
source.refresh();
|
||||
|
||||
// Should handle invalid item gracefully (may return 0 items)
|
||||
QVERIFY(capturedItems.size() == 0 || capturedItems.size() == 1);
|
||||
}
|
||||
|
||||
void testItemLoaderSourceRefreshWithMessageItem()
|
||||
{
|
||||
QJsonObject json;
|
||||
QJsonArray itemsArray;
|
||||
|
||||
QJsonObject messageItem;
|
||||
messageItem["Type"] = "Message";
|
||||
messageItem["ItemId"] = 200;
|
||||
messageItem["Name"] = "alert_item";
|
||||
messageItem["Value"] = 0;
|
||||
messageItem["Message"] = "Test message";
|
||||
itemsArray.append(messageItem);
|
||||
|
||||
json["Items"] = itemsArray;
|
||||
|
||||
ItemLoaderSource source(json);
|
||||
|
||||
// Capture the gotItems signal
|
||||
std::vector<ItemAddRequest> capturedItems;
|
||||
connect(&source, &ItemLoaderSource::gotItems,
|
||||
[&capturedItems](std::vector<ItemAddRequest> items) {
|
||||
capturedItems = items;
|
||||
});
|
||||
|
||||
source.refresh();
|
||||
|
||||
// Should have 1 item
|
||||
QVERIFY(capturedItems.size() == 1);
|
||||
}
|
||||
|
||||
void testItemLoaderSourceRefreshWithSystemItem()
|
||||
{
|
||||
QJsonObject json;
|
||||
QJsonArray itemsArray;
|
||||
|
||||
QJsonObject systemItem;
|
||||
systemItem["Type"] = "System";
|
||||
systemItem["ItemId"] = 300;
|
||||
systemItem["Name"] = "system_item";
|
||||
systemItem["Value"] = 0;
|
||||
systemItem["OnCommand"] = "echo on";
|
||||
systemItem["OffCommand"] = "echo off";
|
||||
itemsArray.append(systemItem);
|
||||
|
||||
json["Items"] = itemsArray;
|
||||
|
||||
ItemLoaderSource source(json);
|
||||
|
||||
// Capture the gotItems signal
|
||||
std::vector<ItemAddRequest> capturedItems;
|
||||
connect(&source, &ItemLoaderSource::gotItems,
|
||||
[&capturedItems](std::vector<ItemAddRequest> items) {
|
||||
capturedItems = items;
|
||||
});
|
||||
|
||||
source.refresh();
|
||||
|
||||
// Should have 1 item
|
||||
QVERIFY(capturedItems.size() == 1);
|
||||
}
|
||||
|
||||
void cleanupTestCase()
|
||||
{
|
||||
// Cleanup after all tests
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_APPLESS_MAIN(TestItemLoaderSource)
|
||||
|
||||
#include "test_itemloadersource.moc"
|
||||
255
tests/unit/items/test_itemstore.cpp
Normal file
255
tests/unit/items/test_itemstore.cpp
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
#include <QtTest/QtTest>
|
||||
#include "items/itemstore.h"
|
||||
#include "items/item.h"
|
||||
|
||||
class TestItemStore : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
// Setup for all tests
|
||||
}
|
||||
|
||||
void testItemStoreCreation()
|
||||
{
|
||||
ItemStore store;
|
||||
|
||||
// Should start empty
|
||||
QVERIFY(store.getItems()->empty());
|
||||
}
|
||||
|
||||
void testItemStoreAddItem()
|
||||
{
|
||||
ItemStore store;
|
||||
|
||||
std::shared_ptr<Item> item(new Item(1, "test_item", 0));
|
||||
|
||||
ItemAddRequest request;
|
||||
request.type = ITEM_UPDATE_USER;
|
||||
request.payload = item;
|
||||
request.changes = ItemFieldChanges(true);
|
||||
|
||||
store.addItem(request);
|
||||
|
||||
// Item should be added
|
||||
QVERIFY(store.getItems()->size() == 1);
|
||||
}
|
||||
|
||||
void testItemStoreAddMultipleItems()
|
||||
{
|
||||
ItemStore store;
|
||||
|
||||
std::shared_ptr<Item> item1(new Item(1, "item1", 0));
|
||||
std::shared_ptr<Item> item2(new Item(2, "item2", 1));
|
||||
|
||||
std::vector<ItemAddRequest> requests;
|
||||
|
||||
ItemAddRequest request1;
|
||||
request1.type = ITEM_UPDATE_USER;
|
||||
request1.payload = item1;
|
||||
request1.changes = ItemFieldChanges(true);
|
||||
requests.push_back(request1);
|
||||
|
||||
ItemAddRequest request2;
|
||||
request2.type = ITEM_UPDATE_USER;
|
||||
request2.payload = item2;
|
||||
request2.changes = ItemFieldChanges(true);
|
||||
requests.push_back(request2);
|
||||
|
||||
store.addItems(requests);
|
||||
|
||||
// Both items should be added
|
||||
QVERIFY(store.getItems()->size() == 2);
|
||||
}
|
||||
|
||||
void testItemStoreGetItem()
|
||||
{
|
||||
ItemStore store;
|
||||
|
||||
std::shared_ptr<Item> item(new Item(42, "test_item", 0));
|
||||
|
||||
ItemAddRequest request;
|
||||
request.type = ITEM_UPDATE_USER;
|
||||
request.payload = item;
|
||||
request.changes = ItemFieldChanges(true);
|
||||
|
||||
store.addItem(request);
|
||||
|
||||
// Get item by id
|
||||
std::shared_ptr<Item> found = store.getItem(42);
|
||||
QVERIFY(found != nullptr);
|
||||
QVERIFY(found->getName() == "test_item");
|
||||
|
||||
// Get non-existent item
|
||||
std::shared_ptr<Item> notFound = store.getItem(999);
|
||||
QVERIFY(notFound == nullptr);
|
||||
}
|
||||
|
||||
void testItemStoreRemoveItem()
|
||||
{
|
||||
ItemStore store;
|
||||
|
||||
std::shared_ptr<Item> item(new Item(1, "test_item", 0));
|
||||
|
||||
ItemAddRequest request;
|
||||
request.type = ITEM_UPDATE_USER;
|
||||
request.payload = item;
|
||||
request.changes = ItemFieldChanges(true);
|
||||
|
||||
store.addItem(request);
|
||||
QVERIFY(store.getItems()->size() == 1);
|
||||
|
||||
// Remove item
|
||||
ItemData itemData(1, "test_item", 0);
|
||||
store.removeItem(itemData);
|
||||
|
||||
QVERIFY(store.getItems()->empty());
|
||||
}
|
||||
|
||||
void testItemStoreClear()
|
||||
{
|
||||
ItemStore store;
|
||||
|
||||
// Add multiple items
|
||||
for (int i = 0; i < 5; i++) {
|
||||
std::shared_ptr<Item> item(new Item(i, "item" + QString::number(i), 0));
|
||||
ItemAddRequest request;
|
||||
request.type = ITEM_UPDATE_USER;
|
||||
request.payload = item;
|
||||
request.changes = ItemFieldChanges(true);
|
||||
store.addItem(request);
|
||||
}
|
||||
|
||||
QVERIFY(store.getItems()->size() == 5);
|
||||
|
||||
// Clear all items
|
||||
store.clear();
|
||||
|
||||
QVERIFY(store.getItems()->empty());
|
||||
}
|
||||
|
||||
void testItemStoreUpdateItem()
|
||||
{
|
||||
ItemStore store;
|
||||
|
||||
std::shared_ptr<Item> item(new Item(1, "test_item", 0));
|
||||
|
||||
ItemAddRequest request;
|
||||
request.type = ITEM_UPDATE_USER;
|
||||
request.payload = item;
|
||||
request.changes = ItemFieldChanges(true);
|
||||
|
||||
store.addItem(request);
|
||||
|
||||
// Update item value
|
||||
ItemUpdateRequest update;
|
||||
update.type = ITEM_UPDATE_USER;
|
||||
ItemData updatedData(1, "test_item", 1); // value = 1
|
||||
update.payload = updatedData;
|
||||
update.changes.value = true;
|
||||
|
||||
store.updateItem(update);
|
||||
|
||||
// Verify value was updated
|
||||
std::shared_ptr<Item> found = store.getItem(1);
|
||||
QVERIFY(found->getValue() == 1);
|
||||
}
|
||||
|
||||
void testItemStoreUpdateMultipleItems()
|
||||
{
|
||||
ItemStore store;
|
||||
|
||||
// Add items
|
||||
for (int i = 0; i < 3; i++) {
|
||||
std::shared_ptr<Item> item(new Item(i, "item" + QString::number(i), 0));
|
||||
ItemAddRequest request;
|
||||
request.type = ITEM_UPDATE_USER;
|
||||
request.payload = item;
|
||||
request.changes = ItemFieldChanges(true);
|
||||
store.addItem(request);
|
||||
}
|
||||
|
||||
// Update multiple items
|
||||
std::vector<ItemUpdateRequest> updates;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ItemUpdateRequest update;
|
||||
update.type = ITEM_UPDATE_USER;
|
||||
ItemData data(i, "item" + QString::number(i), 1);
|
||||
update.payload = data;
|
||||
update.changes.value = true;
|
||||
updates.push_back(update);
|
||||
}
|
||||
|
||||
store.updateItems(updates);
|
||||
|
||||
// Verify all values were updated
|
||||
for (int i = 0; i < 3; i++) {
|
||||
std::shared_ptr<Item> found = store.getItem(i);
|
||||
QVERIFY(found->getValue() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
void testItemStoreJsonSerialization()
|
||||
{
|
||||
ItemStore store;
|
||||
|
||||
// Add items
|
||||
for (int i = 0; i < 2; i++) {
|
||||
std::shared_ptr<Item> item(new Item(i, "item" + QString::number(i), i));
|
||||
item->setGroupName("TestGroup");
|
||||
ItemAddRequest request;
|
||||
request.type = ITEM_UPDATE_USER;
|
||||
request.payload = item;
|
||||
request.changes = ItemFieldChanges(true);
|
||||
store.addItem(request);
|
||||
}
|
||||
|
||||
// Serialize to JSON
|
||||
QJsonObject json;
|
||||
store.store(json);
|
||||
|
||||
// Verify JSON contains items array
|
||||
QVERIFY(json.contains("Items"));
|
||||
QVERIFY(json["Items"].toArray().size() == 2);
|
||||
}
|
||||
|
||||
void testItemStoreReplaceItems()
|
||||
{
|
||||
ItemStore store;
|
||||
|
||||
// Add initial items
|
||||
std::shared_ptr<Item> item1(new Item(1, "item1", 0));
|
||||
ItemAddRequest request1;
|
||||
request1.type = ITEM_UPDATE_USER;
|
||||
request1.payload = item1;
|
||||
request1.changes = ItemFieldChanges(true);
|
||||
store.addItem(request1);
|
||||
|
||||
QVERIFY(store.getItems()->size() == 1);
|
||||
|
||||
// Replace with new items
|
||||
std::vector<std::shared_ptr<Item>> newItems;
|
||||
newItems.push_back(std::shared_ptr<Item>(new Item(2, "new_item1", 0)));
|
||||
newItems.push_back(std::shared_ptr<Item>(new Item(3, "new_item2", 1)));
|
||||
|
||||
store.replaceItems(newItems);
|
||||
|
||||
// Should have new items
|
||||
QVERIFY(store.getItems()->size() == 2);
|
||||
|
||||
// Old item should be removed
|
||||
QVERIFY(store.getItem(1) == nullptr);
|
||||
}
|
||||
|
||||
void cleanupTestCase()
|
||||
{
|
||||
// Cleanup after all tests
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_APPLESS_MAIN(TestItemStore)
|
||||
|
||||
#include "test_itemstore.moc"
|
||||
230
tests/unit/sensors/test_sensor.cpp
Normal file
230
tests/unit/sensors/test_sensor.cpp
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
#include <QtTest/QtTest>
|
||||
#include "sensors/sensor.h"
|
||||
|
||||
class TestSensor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
// Setup for all tests
|
||||
}
|
||||
|
||||
void testSensorCreation()
|
||||
{
|
||||
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 0.0, "test_sensor");
|
||||
|
||||
QCOMPARE(sensor.type, Sensor::TYPE_TEMPERATURE);
|
||||
QCOMPARE(sensor.name, QString("test_sensor"));
|
||||
}
|
||||
|
||||
void testSensorData()
|
||||
{
|
||||
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 0.0, "temp_sensor");
|
||||
|
||||
// Test setting and getting values
|
||||
sensor.field = 25.0;
|
||||
QCOMPARE(sensor.field, 25.0);
|
||||
}
|
||||
|
||||
void testSensorTypes()
|
||||
{
|
||||
// Test different sensor types
|
||||
Sensor doorSensor(Sensor::TYPE_DOOR, 1);
|
||||
Sensor tempSensor(Sensor::TYPE_TEMPERATURE, 2);
|
||||
Sensor humiditySensor(Sensor::TYPE_HUMIDITY, 3);
|
||||
|
||||
QCOMPARE(doorSensor.type, Sensor::TYPE_DOOR);
|
||||
QCOMPARE(tempSensor.type, Sensor::TYPE_TEMPERATURE);
|
||||
QCOMPARE(humiditySensor.type, Sensor::TYPE_HUMIDITY);
|
||||
}
|
||||
|
||||
void testSensorStringParsing()
|
||||
{
|
||||
// Test parsing sensor from string (format: "SENSOR TYPE: X ID: Y FIELD: Z TIME: T")
|
||||
// This tests the sensorFromString function
|
||||
QString sensorStr = "SENSOR TYPE: 1 ID: 5 FIELD: 250 TIME: 1234567890";
|
||||
Sensor sensor = Sensor::sensorFromString(sensorStr);
|
||||
|
||||
// The function should parse the type, id, and field
|
||||
// Note: temperature and humidity values are divided by 10
|
||||
QVERIFY(sensor.type != Sensor::TYPE_DUMMY || sensor.field != 0);
|
||||
}
|
||||
|
||||
void testSensorStringParsingInvalid()
|
||||
{
|
||||
// Test parsing invalid string returns dummy sensor
|
||||
QString invalidStr = "invalid data";
|
||||
Sensor sensor = Sensor::sensorFromString(invalidStr);
|
||||
|
||||
// Should return a dummy sensor with hidden=true
|
||||
QVERIFY(sensor.hidden);
|
||||
}
|
||||
|
||||
void testSensorToString()
|
||||
{
|
||||
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.5, "test_sensor");
|
||||
QString str = sensor.toString();
|
||||
|
||||
// Should contain type, id, and field info
|
||||
QVERIFY(str.contains("SENSOR TYPE"));
|
||||
QVERIFY(str.contains("ID:"));
|
||||
QVERIFY(str.contains("FIELD:"));
|
||||
}
|
||||
|
||||
void testSensorJsonSerialization()
|
||||
{
|
||||
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0, "test_sensor");
|
||||
|
||||
QJsonObject json;
|
||||
sensor.store(json);
|
||||
|
||||
// Verify JSON contents
|
||||
QVERIFY(json.contains("Type"));
|
||||
QVERIFY(json.contains("SensorType"));
|
||||
QVERIFY(json.contains("Id"));
|
||||
QVERIFY(json.contains("Field"));
|
||||
QVERIFY(json.contains("Name"));
|
||||
QVERIFY(json.contains("Unit"));
|
||||
|
||||
// Check values
|
||||
QVERIFY(json["Type"].toString() == "Sensor");
|
||||
QVERIFY(json["SensorType"].toInt() == Sensor::TYPE_TEMPERATURE);
|
||||
QVERIFY(json["Id"].toInt() == 1);
|
||||
QVERIFY(json["Field"].toDouble() == 25.0);
|
||||
QVERIFY(json["Name"].toString() == "test_sensor");
|
||||
}
|
||||
|
||||
void testSensorJsonDeserialization()
|
||||
{
|
||||
QJsonObject json;
|
||||
json["SensorType"] = Sensor::TYPE_HUMIDITY;
|
||||
json["Id"] = 5;
|
||||
json["Field"] = 60.5;
|
||||
json["Name"] = "humidity_sensor";
|
||||
json["Hidden"] = false;
|
||||
|
||||
Sensor sensor(json);
|
||||
|
||||
QVERIFY(sensor.type == Sensor::TYPE_HUMIDITY);
|
||||
QVERIFY(sensor.id == 5);
|
||||
QVERIFY(sensor.field == 60.5);
|
||||
QVERIFY(sensor.name == "humidity_sensor");
|
||||
QVERIFY(!sensor.hidden);
|
||||
}
|
||||
|
||||
void testSensorEquality()
|
||||
{
|
||||
Sensor sensor1(Sensor::TYPE_TEMPERATURE, 1, 25.0);
|
||||
Sensor sensor2(Sensor::TYPE_TEMPERATURE, 1, 30.0);
|
||||
Sensor sensor3(Sensor::TYPE_TEMPERATURE, 2, 25.0);
|
||||
|
||||
// Same type and id means equal
|
||||
QVERIFY(sensor1 == sensor2);
|
||||
|
||||
// Different id means not equal
|
||||
QVERIFY(sensor1 != sensor3);
|
||||
}
|
||||
|
||||
void testSensorUpdateSeen()
|
||||
{
|
||||
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0);
|
||||
QDateTime before = sensor.lastSeen;
|
||||
|
||||
// Wait a tiny bit and update
|
||||
sensor.updateSeen();
|
||||
|
||||
QVERIFY(sensor.lastSeen >= before);
|
||||
}
|
||||
|
||||
void testSensorGenerateName()
|
||||
{
|
||||
// Test auto-generated names for different sensor types
|
||||
Sensor tempSensor(Sensor::TYPE_TEMPERATURE, 1);
|
||||
QVERIFY(tempSensor.name.contains("Temperature"));
|
||||
|
||||
Sensor doorSensor(Sensor::TYPE_DOOR, 2);
|
||||
QVERIFY(doorSensor.name.contains("Door"));
|
||||
|
||||
Sensor buttonSensor(Sensor::TYPE_BUTTON, 3);
|
||||
QVERIFY(buttonSensor.name.contains("Button"));
|
||||
|
||||
Sensor humiditySensor(Sensor::TYPE_HUMIDITY, 4);
|
||||
QVERIFY(humiditySensor.name.contains("Humidity"));
|
||||
}
|
||||
|
||||
void testSensorGetUnit()
|
||||
{
|
||||
Sensor tempSensor(Sensor::TYPE_TEMPERATURE, 1);
|
||||
QVERIFY(tempSensor.getUnit() == "°C");
|
||||
|
||||
Sensor humiditySensor(Sensor::TYPE_HUMIDITY, 1);
|
||||
QVERIFY(humiditySensor.getUnit() == "%");
|
||||
|
||||
Sensor pressureSensor(Sensor::TYPE_PRESSURE, 1);
|
||||
QVERIFY(pressureSensor.getUnit() == "hPa");
|
||||
|
||||
Sensor brightnessSensor(Sensor::TYPE_BRIGHTNESS, 1);
|
||||
QVERIFY(brightnessSensor.getUnit() == "lx");
|
||||
|
||||
Sensor co2Sensor(Sensor::TYPE_CO2, 1);
|
||||
QVERIFY(co2Sensor.getUnit() == "ppm");
|
||||
|
||||
Sensor vocSensor(Sensor::TYPE_TOTAL_VOC, 1);
|
||||
QVERIFY(vocSensor.getUnit() == "ppb");
|
||||
}
|
||||
|
||||
void testSensorHidden()
|
||||
{
|
||||
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0, "test", false);
|
||||
QVERIFY(!sensor.hidden);
|
||||
|
||||
Sensor hiddenSensor(Sensor::TYPE_TEMPERATURE, 2, 25.0, "test", true);
|
||||
QVERIFY(hiddenSensor.hidden);
|
||||
}
|
||||
|
||||
void testSensorAllTypes()
|
||||
{
|
||||
// Test all sensor types can be created
|
||||
Sensor door(Sensor::TYPE_DOOR, 1);
|
||||
Sensor temp(Sensor::TYPE_TEMPERATURE, 1);
|
||||
Sensor humidity(Sensor::TYPE_HUMIDITY, 1);
|
||||
Sensor pressure(Sensor::TYPE_PRESSURE, 1);
|
||||
Sensor brightness(Sensor::TYPE_BRIGHTNESS, 1);
|
||||
Sensor button(Sensor::TYPE_BUTTON, 1);
|
||||
Sensor adc(Sensor::TYPE_ADC, 1);
|
||||
Sensor co2(Sensor::TYPE_CO2, 1);
|
||||
Sensor pm25(Sensor::TYPE_PM25, 1);
|
||||
Sensor voc(Sensor::TYPE_TOTAL_VOC, 1);
|
||||
Sensor lowBattery(Sensor::TYPE_LOWBATTERY, 1);
|
||||
Sensor occupancy(Sensor::TYPE_OCUPANCY, 1);
|
||||
Sensor sunAlt(Sensor::TYPE_SUN_ALTITUDE, 1);
|
||||
Sensor audio(Sensor::TYPE_AUDIO_OUTPUT, 1);
|
||||
|
||||
// All should be valid
|
||||
QVERIFY(door.type == Sensor::TYPE_DOOR);
|
||||
QVERIFY(temp.type == Sensor::TYPE_TEMPERATURE);
|
||||
QVERIFY(humidity.type == Sensor::TYPE_HUMIDITY);
|
||||
QVERIFY(pressure.type == Sensor::TYPE_PRESSURE);
|
||||
QVERIFY(brightness.type == Sensor::TYPE_BRIGHTNESS);
|
||||
QVERIFY(button.type == Sensor::TYPE_BUTTON);
|
||||
QVERIFY(adc.type == Sensor::TYPE_ADC);
|
||||
QVERIFY(co2.type == Sensor::TYPE_CO2);
|
||||
QVERIFY(pm25.type == Sensor::TYPE_PM25);
|
||||
QVERIFY(voc.type == Sensor::TYPE_TOTAL_VOC);
|
||||
QVERIFY(lowBattery.type == Sensor::TYPE_LOWBATTERY);
|
||||
QVERIFY(occupancy.type == Sensor::TYPE_OCUPANCY);
|
||||
QVERIFY(sunAlt.type == Sensor::TYPE_SUN_ALTITUDE);
|
||||
QVERIFY(audio.type == Sensor::TYPE_AUDIO_OUTPUT);
|
||||
}
|
||||
|
||||
void cleanupTestCase()
|
||||
{
|
||||
// Cleanup after all tests
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_APPLESS_MAIN(TestSensor)
|
||||
|
||||
#include "test_sensor.moc"
|
||||
Loading…
Add table
Add a link
Reference in a new issue