#include #include #include #include "shell_log.h" using namespace roro; void setUp() {} void tearDown() {} static void feed(ShellLog& log, const std::string& text, uint32_t now) { log.feed(text.data(), text.size(), now); } void test_lines_arrive_in_pieces() { ShellLog log; feed(log, "firmware: roro", 0); TEST_ASSERT_EQUAL(0, log.lines().size()); feed(log, "9stack\r\nuptime: 1s\n", 0); TEST_ASSERT_EQUAL(2, log.lines().size()); TEST_ASSERT_EQUAL_STRING("firmware: roro9stack", log.lines()[0].c_str()); TEST_ASSERT_EQUAL_STRING("uptime: 1s", log.lines()[1].c_str()); } void test_the_heap_line_is_never_kept() { ShellLog log; feed(log, "status: heap 105000 min 90000\nirc: connected\n", 0); TEST_ASSERT_EQUAL(1, log.lines().size()); TEST_ASSERT_EQUAL_STRING("irc: connected", log.lines()[0].c_str()); } // Q206: with background lines hidden, only what's printed in the ten seconds after a command. void test_mine_only_keeps_what_follows_a_command() { ShellLog log; log.showBackground(false); feed(log, "irc: someone joined\n", 1000); // no command yet TEST_ASSERT_EQUAL(0, log.lines().size()); log.commandRun(5000); feed(log, "ls: end of /\n", 5200); // the reply, a moment later, from another task feed(log, "tasks: ...\n", 14999); feed(log, "irc: someone left\n", 15000); // ten seconds on: background again TEST_ASSERT_EQUAL(2, log.lines().size()); log.showBackground(true); feed(log, "irc: back\n", 99000); TEST_ASSERT_EQUAL(3, log.lines().size()); } void test_mine_only_holds_across_the_clock_wrap() { ShellLog log; log.showBackground(false); log.commandRun(0xFFFFFF00u); feed(log, "reply\n", 0x00000100u); // 512 ms later, past the wrap TEST_ASSERT_EQUAL(1, log.lines().size()); } void test_the_oldest_lines_go_past_4_kb() { ShellLog log; for (int i = 0; i < 200; i++) feed(log, std::string(49, 'x') + "\n", 0); // 10 KB in all size_t bytes = 0; for (auto& l : log.lines()) bytes += l.size() + 1; TEST_ASSERT_TRUE(bytes <= ShellLog::kMaxBytes); TEST_ASSERT_TRUE(log.lines().size() >= 80); uint32_t before = log.revision(); log.add("> info"); TEST_ASSERT_EQUAL_STRING("> info", log.lines().back().c_str()); TEST_ASSERT_TRUE(log.revision() != before); log.clear(); TEST_ASSERT_EQUAL(0, log.lines().size()); } static const char* kHelp = "info firmware, uptime, memory\n" "ls [folder] | du | mkdir | rm the SD card\n" "lora probe | lora status | lora rx on|off the LoRa radio\n" "log level <0-5> ESP-IDF log level\n" "sd card | sd list | cat | log | burst\n" "get | put | screenshot (Debug Console only) binary\n"; void test_command_words_come_from_the_help_text() { auto words = commandWords(kHelp); const char* expected[] = {"info", "ls", "du", "mkdir", "rm", "lora", "log", "sd", "cat", "burst", "get", "put", "screenshot"}; TEST_ASSERT_EQUAL(sizeof expected / sizeof expected[0], words.size()); for (size_t i = 0; i < words.size(); i++) TEST_ASSERT_EQUAL_STRING(expected[i], words[i].c_str()); } void test_tab_completes_the_first_word() { auto words = commandWords(kHelp); std::vector matches; TEST_ASSERT_EQUAL_STRING("info ", completeCommand("in", words, matches).c_str()); // the only one: with its space TEST_ASSERT_EQUAL(0, matches.size()); TEST_ASSERT_EQUAL_STRING("l", completeCommand("l", words, matches).c_str()); // ls, lora, log: they agree on no more TEST_ASSERT_EQUAL(3, matches.size()); TEST_ASSERT_EQUAL_STRING("mkdir ", completeCommand("m", words, matches).c_str()); TEST_ASSERT_EQUAL_STRING("lo", completeCommand("lo", words, matches).c_str()); // lora, log TEST_ASSERT_EQUAL(2, matches.size()); TEST_ASSERT_EQUAL_STRING("zz", completeCommand("zz", words, matches).c_str()); // nothing: as it was TEST_ASSERT_EQUAL_STRING("ls /no", completeCommand("ls /no", words, matches).c_str()); // past the first word TEST_ASSERT_EQUAL_STRING("", completeCommand("", words, matches).c_str()); } int main(int, char**) { UNITY_BEGIN(); RUN_TEST(test_lines_arrive_in_pieces); RUN_TEST(test_the_heap_line_is_never_kept); RUN_TEST(test_mine_only_keeps_what_follows_a_command); RUN_TEST(test_mine_only_holds_across_the_clock_wrap); RUN_TEST(test_the_oldest_lines_go_past_4_kb); RUN_TEST(test_command_words_come_from_the_help_text); RUN_TEST(test_tab_completes_the_first_word); return UNITY_END(); }