diff --git a/src/console.cpp b/src/console.cpp index 3a3642820..98c163876 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -691,11 +691,16 @@ std::string EMSESPShell::context_text() { // when in su (admin) show # as the prompt suffix std::string EMSESPShell::prompt_suffix() { +#ifndef EMSESP_UNITY if (has_flags(CommandFlags::ADMIN)) { return std::string{'#'}; } else { return std::string{'$'}; } +#else + // don't bother with prompt suffix if we're testing Unity output + return ""; +#endif } void EMSESPShell::end_of_transmission() { diff --git a/src/emsesp.cpp b/src/emsesp.cpp index b3e77fbeb..ada971520 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -1553,8 +1553,6 @@ void EMSESP::start() { #if defined(EMSESP_STANDALONE) shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when running tests #endif -#else -#warning "Shell is disabled when running Unity tests." #endif // start the file system diff --git a/src/system.cpp b/src/system.cpp index 11ca28e8f..00825a685 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1397,8 +1397,13 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output JsonObject node; // System - node = output["system"].to(); - node["version"] = EMSESP_APP_VERSION; + node = output["system"].to(); +// prevent false negataive in Unity tests everytime the version changes +#if defined(EMSESP_UNITY) + node["version"] = "dev"; +#else + node["version"] = EMSESP_APP_VERSION; +#endif node["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); node["uptimeSec"] = uuid::get_uptime_sec(); #ifndef EMSESP_STANDALONE diff --git a/src/test/test.cpp b/src/test/test.cpp index d3ac94cd8..b6cfc4e28 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -1109,6 +1109,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const Serial.println(); Serial.printf("%s**** Testing bad urls ****\n%s", COLOR_RED, COLOR_RESET); + request.method(HTTP_GET); + request.url("/api/boiler2"); EMSESP::webAPIService.webAPIService(&request); diff --git a/src/web/WebAPIService.cpp b/src/web/WebAPIService.cpp index d14c1cfaa..296f3f4e1 100644 --- a/src/web/WebAPIService.cpp +++ b/src/web/WebAPIService.cpp @@ -134,7 +134,7 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) { const char * api_data = output["api_data"]; if (api_data) { request->send(200, "text/plain; charset=utf-8", api_data); -#if defined(EMSESP_TEST) +#if defined(EMSESP_UNITY) // store the result so we can test with Unity later storeResponse(output); #endif @@ -161,7 +161,7 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) { request->send(response); api_count_++; -#if defined(EMSESP_TEST) +#if defined(EMSESP_UNITY) // store the result so we can test with Unity later storeResponse(output); #endif @@ -229,7 +229,7 @@ void WebAPIService::getEntities(AsyncWebServerRequest * request) { request->send(response); } -#if defined(EMSESP_TEST) +#if defined(EMSESP_UNITY) // store the result so we can test with Unity later static JsonDocument storeResponseDoc_; diff --git a/test/test_api/test_api.cpp b/test/test_api/test_api.cpp index a18701d0d..f62ac0c6d 100644 --- a/test/test_api/test_api.cpp +++ b/test/test_api/test_api.cpp @@ -27,15 +27,42 @@ using namespace emsesp; +// forward declarations +void run_tests(); +const char * call_url(const char * url); + AsyncWebServer * webServer; ESP8266React * esp8266React; WebAPIService * webAPIService; EMSESP application; FS dummyFS; -// forward declarations -void run_tests(); -const char * call_url(const char * url); +std::shared_ptr shell; +char output_buffer[4096]; + +class TestStream : public Stream { + public: + int available() override { + return 1; + } + int read() override { + return '\n'; + }; + int peek() override { + return '\n'; + }; + size_t write(uint8_t data __attribute__((unused))) override { + return 1; + } + size_t write(const uint8_t * buffer __attribute__((unused)), size_t size) override { + strcat(output_buffer, (const char *)buffer); // store output in our temp buffer, strings only + return size; + } + void flush() override { + output_buffer[0] = '\0'; // empty the temp buffer + } +}; +static TestStream stream; // load the tests // this is generated from this file when compiled with -DEMSESP_UNITY_CREATE @@ -248,23 +275,49 @@ void run_manual_tests() { RUN_TEST(manual_test4); } -// Main entry point -int main() { - webServer = new AsyncWebServer(80); - esp8266React = new ESP8266React(webServer, &dummyFS); - webAPIService = new WebAPIService(webServer, esp8266React->getSecurityManager()); +const char * run_console_command(const char * command) { + output_buffer[0] = '\0'; // empty the temp buffer + shell->invoke_command(command); + // remove everything before \r\n + char * p = strstr(output_buffer, "\r\n"); + if (p) { + p += 2; // skip the \r\n + } + // remove the \r\n at the end + p[strlen(p) - 2] = '\0'; - application.start(); // calls begin() + // Serial.println("Output:"); + // Serial.print(p); + // Serial.println(); - EMSESP::webCustomEntityService.test(); // custom entities - EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS - EMSESP::temperaturesensor_.test(); // add temperature sensors - EMSESP::webSchedulerService.test(); // run scheduler tests, and conditions + return p; +} - add_devices(); // add devices +void console_test1() { + auto expected_response = "Log level: DEBUG"; + TEST_ASSERT_EQUAL_STRING(expected_response, run_console_command("log")); +} -#if defined(EMSESP_UNITY_CREATE) +void console_test2() { + auto expected_response = ""; + TEST_ASSERT_EQUAL_STRING(expected_response, run_console_command("call thermostat mode auto")); +} +void console_test3() { + // test bad command + auto expected_response = "Bad syntax. Check arguments."; + TEST_ASSERT_EQUAL_STRING(expected_response, run_console_command("call thermostat mode bad")); +} + +// simulate console commands +void run_console_tests() { + RUN_TEST(console_test1); + RUN_TEST(console_test2); + RUN_TEST(console_test3); +} + +// auto-generate the tests +void create_tests() { // These tests should all pass.... capture("/api/boiler"); @@ -326,7 +379,6 @@ int main() { capture("/api/system/settings2"); capture("/api/system/settings2/locale2"); - // scheduler capture("/api/scheduler/test_scheduler2"); capture("/api/scheduler/test_scheduler/val"); @@ -349,13 +401,41 @@ int main() { // ************************************************************************************************** // Finish capture(); // always end with this, this will create the run_test() function +} + +// Main entry point +int main() { + webServer = new AsyncWebServer(80); + esp8266React = new ESP8266React(webServer, &dummyFS); + webAPIService = new WebAPIService(webServer, esp8266React->getSecurityManager()); + + // Serial console for commands + Serial.begin(115200); + shell = std::make_shared(application, stream, true); + shell->log_level(uuid::log::Level::DEBUG); + shell->add_flags(CommandFlags::ADMIN); + + application.start(); // calls begin() + + EMSESP::webCustomEntityService.test(); // custom entities + EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS + EMSESP::temperaturesensor_.test(); // add temperature sensors + EMSESP::webSchedulerService.test(); // run scheduler tests, and conditions + + add_devices(); // add devices + +#if defined(EMSESP_UNITY_CREATE) + create_tests(); #endif - // always run the tests + // + // Run the tests + // UNITY_BEGIN(); - run_tests(); // execute the generated tests - run_manual_tests(); // execute some other manual tests from this file + run_tests(); // execute the generated tests + run_manual_tests(); // execute some other manual tests from this file + run_console_tests(); // execute some console tests return UNITY_END(); } diff --git a/test/test_api/test_api.h b/test/test_api/test_api.h index 347c89ccf..21ec835b3 100644 --- a/test/test_api/test_api.h +++ b/test/test_api/test_api.h @@ -156,7 +156,7 @@ void test_18() { void test_19() { auto expected_response = - "[{\"system\":{\"version\":\"3.7.0-dev.29\",\"uptime\":\"000+00:00:00.000\",\"uptimeSec\":0,\"resetReason\":\"Unknown / " + "[{\"system\":{\"version\":\"dev\",\"uptime\":\"000+00:00:00.000\",\"uptimeSec\":0,\"resetReason\":\"Unknown / " "Unknown\"},\"network\":{\"network\":\"WiFi\",\"hostname\":\"ems-esp\",\"RSSI\":-23,\"TxPowerSetting\":0,\"staticIP\":false,\"lowBandwidth\":false," "\"disableSleep\":false,\"enableMDNS\":true,\"enableCORS\":false},\"ntp\":{},\"mqtt\":{\"MQTTStatus\":\"disconnected\",\"MQTTPublishes\":0," "\"MQTTQueued\":0,\"MQTTPublishFails\":0,\"MQTTConnects\":1,\"enabled\":true,\"clientID\":\"ems-esp\",\"keepAlive\":60,\"cleanSession\":false," @@ -179,7 +179,7 @@ void test_19() { void test_20() { auto expected_response = - "[{\"system\":{\"version\":\"3.7.0-dev.29\",\"uptime\":\"000+00:00:00.000\",\"uptimeSec\":0,\"resetReason\":\"Unknown / " + "[{\"system\":{\"version\":\"dev\",\"uptime\":\"000+00:00:00.000\",\"uptimeSec\":0,\"resetReason\":\"Unknown / " "Unknown\"},\"network\":{\"network\":\"WiFi\",\"hostname\":\"ems-esp\",\"RSSI\":-23,\"TxPowerSetting\":0,\"staticIP\":false,\"lowBandwidth\":false," "\"disableSleep\":false,\"enableMDNS\":true,\"enableCORS\":false},\"ntp\":{},\"mqtt\":{\"MQTTStatus\":\"disconnected\",\"MQTTPublishes\":0," "\"MQTTQueued\":0,\"MQTTPublishFails\":0,\"MQTTConnects\":1,\"enabled\":true,\"clientID\":\"ems-esp\",\"keepAlive\":60,\"cleanSession\":false,"