diff --git a/tests/auto/scripts/scripts.pro b/tests/auto/scripts/scripts.pro new file mode 100644 index 00000000..62d2997e --- /dev/null +++ b/tests/auto/scripts/scripts.pro @@ -0,0 +1,11 @@ +include(../../../nymea.pri) +include(../autotests.pri) + +TARGET = scripts +SOURCES += testscripts.cpp \ + testhelper.cpp + +QT += quick + +HEADERS += \ + testhelper.h diff --git a/tests/auto/scripts/testscripts.cpp b/tests/auto/scripts/testscripts.cpp new file mode 100644 index 00000000..52a59990 --- /dev/null +++ b/tests/auto/scripts/testscripts.cpp @@ -0,0 +1,379 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2015 Simon Stürz * + * Copyright (C) 2014 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * nymea is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + ** + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with nymea. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "nymeatestbase.h" +#include "testhelper.h" + +#include "nymeasettings.h" +#include "nymeacore.h" +#include "scriptengine/scriptengine.h" + +#include + +using namespace nymeaserver; + +static QObject* helperProvider(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + return TestHelper::instance(); +} + +class TestScripts: public NymeaTestBase +{ + Q_OBJECT +public: + TestScripts(); +private: + +private slots: + void init(); + + void testScriptEventById(); + void testScriptEventByName(); + + void testReadScriptStateById(); + void testReadScriptStateByNyme(); + + void testWriteScriptStateById(); + void testWriteScriptStateByName(); + + void testScriptActionById(); + void testScriptActionByName(); + + void testScriptAlarm_data(); + void testScriptAlarm(); +}; + + +TestScripts::TestScripts() +{ + qmlRegisterSingletonType("nymea", 1, 0, "TestHelper", &helperProvider); +} + +void TestScripts::init() +{ + // Make sure no scripts are in the engine when we start a test + foreach (const Script &script, NymeaCore::instance()->scriptEngine()->scripts()) { + NymeaCore::instance()->scriptEngine()->removeScript(script.id()); + } + + // Set initial state values of mock device + Action action(mockPowerActionTypeId, m_mockDeviceId); + action.setParams(ParamList() << Param(mockPowerActionPowerParamTypeId, false)); + NymeaCore::instance()->deviceManager()->executeAction(action); +} + +void TestScripts::testScriptEventById() +{ + QString script = QString("import QtQuick 2.0\n" + "import nymea 1.0\n" + "Item {\n" + " DeviceEvent {\n" + " deviceId: \"%1\"\n" + " eventTypeId: \"%2\"\n" + " onTriggered: {\n" + " TestHelper.logEvent(deviceId, eventTypeId, params);\n" + " }\n" + " }\n" + "}\n").arg(m_mockDeviceId.toString()).arg(mockPowerEventTypeId.toString()); + + qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script); + ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestEvent", script.toUtf8()); + QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError); + + QSignalSpy spy(TestHelper::instance(), &TestHelper::eventLogged); + + // Generate event by setting state value of powerState + Action action(mockPowerActionTypeId, m_mockDeviceId); + action.setParams(ParamList() << Param(mockPowerActionPowerParamTypeId, true)); + NymeaCore::instance()->deviceManager()->executeAction(action); + + spy.wait(1); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.first().at(0).value(), m_mockDeviceId); + QCOMPARE(EventTypeId(spy.first().at(1).toUuid()), mockPowerEventTypeId); + QVariantMap expectedParams; + expectedParams.insert(mockPowerEventTypeId.toString().remove(QRegExp("[{}]")), true); + expectedParams.insert("power", true); + QCOMPARE(spy.first().at(2).toMap(), expectedParams); +} + +void TestScripts::testScriptEventByName() +{ + QString script = QString("import QtQuick 2.0\n" + "import nymea 1.0\n" + "Item {\n" + " DeviceEvent {\n" + " deviceId: \"%1\"\n" + " eventName: \"%2\"\n" + " onTriggered: {\n" + " TestHelper.logEvent(deviceId, eventName, params);\n" + " }\n" + " }\n" + "}\n").arg(m_mockDeviceId.toString()).arg("power"); + + qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script); + ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestEvent", script.toUtf8()); + QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError); + + QSignalSpy spy(TestHelper::instance(), &TestHelper::eventLogged); + + // Generate event by setting state value of powerState + Action action(mockPowerActionTypeId, m_mockDeviceId); + action.setParams(ParamList() << Param(mockPowerActionPowerParamTypeId, true)); + NymeaCore::instance()->deviceManager()->executeAction(action); + + spy.wait(1); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.first().at(0).value(), m_mockDeviceId); + QCOMPARE(spy.first().at(1).toString(), QString("power")); + QVariantMap expectedParams; + expectedParams.insert(mockPowerEventTypeId.toString().remove(QRegExp("[{}]")), true); + expectedParams.insert("power", true); + QCOMPARE(spy.first().at(2).toMap(), expectedParams); +} + +void TestScripts::testReadScriptStateById() +{ + QString script = QString("import QtQuick 2.0\n" + "import nymea 1.0\n" + "Item {\n" + " DeviceState {\n" + " deviceId: \"%1\"\n" + " stateTypeId: \"%2\"\n" + " onValueChanged: {\n" + " TestHelper.logStateChange(deviceId, stateTypeId, value);\n" + " }\n" + " }\n" + "}\n").arg(m_mockDeviceId.toString()).arg(mockPowerStateTypeId.toString()); + + qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script); + ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestState", script.toUtf8()); + QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError); + + QSignalSpy spy(TestHelper::instance(), &TestHelper::stateChangeLogged); + + // Generate state change + Action action(mockPowerActionTypeId, m_mockDeviceId); + action.setParams(ParamList() << Param(mockPowerActionPowerParamTypeId, true)); + NymeaCore::instance()->deviceManager()->executeAction(action); + + spy.wait(1); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.first().at(0).value(), m_mockDeviceId); + QCOMPARE(StateTypeId(spy.first().at(1).toString()), mockPowerStateTypeId); + QCOMPARE(spy.first().at(2).toBool(), true); +} + +void TestScripts::testReadScriptStateByNyme() +{ + QString script = QString("import QtQuick 2.0\n" + "import nymea 1.0\n" + "Item {\n" + " DeviceState {\n" + " deviceId: \"%1\"\n" + " stateName: \"%2\"\n" + " onValueChanged: {\n" + " TestHelper.logStateChange(deviceId, stateName, value);\n" + " }\n" + " }\n" + "}\n").arg(m_mockDeviceId.toString()).arg("power"); + + qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script); + ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestState", script.toUtf8()); + QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError); + + QSignalSpy spy(TestHelper::instance(), &TestHelper::stateChangeLogged); + + // Generate state change + Action action(mockPowerActionTypeId, m_mockDeviceId); + action.setParams(ParamList() << Param(mockPowerActionPowerParamTypeId, true)); + NymeaCore::instance()->deviceManager()->executeAction(action); + + spy.wait(1); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.first().at(0).value(), m_mockDeviceId); + QCOMPARE(spy.first().at(1).toString(), QString("power")); + QCOMPARE(spy.first().at(2).toBool(), true); +} + +void TestScripts::testWriteScriptStateById() +{ + QString script = QString("import QtQuick 2.0\n" + "import nymea 1.0\n" + "Item {\n" + " DeviceState {\n" + " id: deviceState\n" + " deviceId: \"%1\"\n" + " stateTypeId: \"%2\"\n" + " }\n" + " Connections {\n" + " target: TestHelper\n" + " onSetState: {\n" + " deviceState.value = value\n" + " }\n" + " }\n" + "}\n").arg(m_mockDeviceId.toString()).arg(mockPowerStateTypeId.toString()); + + qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script); + ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestState", script.toUtf8()); + QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError); + + QSignalSpy spy(NymeaCore::instance()->deviceManager(), &DeviceManager::deviceStateChanged); + + TestHelper::instance()->setState(true); + + spy.wait(1); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.first().at(0).value()->id(), m_mockDeviceId); + QCOMPARE(spy.first().at(1).value(), mockPowerStateTypeId); + QCOMPARE(spy.first().at(2).toBool(), true); +} + +void TestScripts::testWriteScriptStateByName() +{ + QString script = QString("import QtQuick 2.0\n" + "import nymea 1.0\n" + "Item {\n" + " DeviceState {\n" + " id: deviceState\n" + " deviceId: \"%1\"\n" + " stateName: \"%2\"\n" + " }\n" + " Connections {\n" + " target: TestHelper\n" + " onSetState: {\n" + " deviceState.value = value\n" + " }\n" + " }\n" + "}\n").arg(m_mockDeviceId.toString()).arg("power"); + + qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script); + ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestState", script.toUtf8()); + QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError); + + QSignalSpy spy(NymeaCore::instance()->deviceManager(), &DeviceManager::deviceStateChanged); + + TestHelper::instance()->setState(true); + + spy.wait(1); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.first().at(0).value()->id(), m_mockDeviceId); + QCOMPARE(spy.first().at(1).value(), mockPowerStateTypeId); + QCOMPARE(spy.first().at(2).toBool(), true); +} + +void TestScripts::testScriptActionById() +{ + QString script = QString("import QtQuick 2.0\n" + "import nymea 1.0\n" + "Item {\n" + " DeviceAction {\n" + " id: deviceAction\n" + " deviceId: \"%1\"\n" + " actionTypeId: \"%2\"\n" + " }\n" + " Connections {\n" + " target: TestHelper\n" + " onExecuteAction: {\n" + " deviceAction.execute(params)\n" + " }\n" + " }\n" + "}\n").arg(m_mockDeviceId.toString()).arg(mockPowerActionTypeId.toString()); + + qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script); + ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestAction", script.toUtf8()); + QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError); + + QSignalSpy spy(NymeaCore::instance()->deviceManager(), &DeviceManager::deviceStateChanged); + + QVariantMap params; + params.insert(mockPowerActionPowerParamTypeId.toString(), true); + TestHelper::instance()->executeAction(params); + + spy.wait(1); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.first().at(0).value()->id(), m_mockDeviceId); + QCOMPARE(spy.first().at(1).value(), mockPowerStateTypeId); + QCOMPARE(spy.first().at(2).toBool(), true); +} + +void TestScripts::testScriptActionByName() +{ + QString script = QString("import QtQuick 2.0\n" + "import nymea 1.0\n" + "Item {\n" + " DeviceAction {\n" + " id: deviceAction\n" + " deviceId: \"%1\"\n" + " actionName: \"%2\"\n" + " }\n" + " Connections {\n" + " target: TestHelper\n" + " onExecuteAction: {\n" + " deviceAction.execute(params)\n" + " }\n" + " }\n" + "}\n").arg(m_mockDeviceId.toString()).arg("power"); + + qCDebug(dcTests()) << "Adding script:\n" << qUtf8Printable(script); + ScriptEngine::AddScriptReply reply = NymeaCore::instance()->scriptEngine()->addScript("TestAction", script.toUtf8()); + QCOMPARE(reply.scriptError, ScriptEngine::ScriptErrorNoError); + + QSignalSpy spy(NymeaCore::instance()->deviceManager(), &DeviceManager::deviceStateChanged); + + QVariantMap params; + params.insert("power", true); + TestHelper::instance()->executeAction(params); + + spy.wait(1); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.first().at(0).value()->id(), m_mockDeviceId); + QCOMPARE(spy.first().at(1).value(), mockPowerStateTypeId); + QCOMPARE(spy.first().at(2).toBool(), true); +} + +void TestScripts::testScriptAlarm_data() +{ + QTest::addColumn("time"); + QTest::addColumn("endTime"); + QTest::addColumn("active"); + + QTest::newRow("active, regular") << QTime(12, 05); +} + +void TestScripts::testScriptAlarm() +{ + +} + + +#include "testscripts.moc" +QTEST_MAIN(TestScripts)