mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-06-10 11:59:19 +03:00
first
This commit is contained in:
137
lib/ArduinoStreamUtils/extras/test/BufferingPrintTest.cpp
Normal file
137
lib/ArduinoStreamUtils/extras/test/BufferingPrintTest.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Prints/BufferingPrint.hpp"
|
||||
#include "StreamUtils/Prints/SpyingPrint.hpp"
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("BufferingPrint") {
|
||||
StringPrint target;
|
||||
|
||||
StringPrint log;
|
||||
SpyingPrint spy{target, log};
|
||||
|
||||
GIVEN("capacity is 4") {
|
||||
BufferingPrint bufferingPrint{spy, 4};
|
||||
|
||||
SUBCASE("flush() calls write()") {
|
||||
bufferingPrint.write("ABC", 3);
|
||||
bufferingPrint.flush();
|
||||
|
||||
#if STREAMUTILS_PRINT_FLUSH_EXISTS
|
||||
CHECK(log.str() ==
|
||||
"write('ABC', 3) -> 3"
|
||||
"flush()");
|
||||
#else
|
||||
CHECK(log.str() == "write('ABC', 3) -> 3");
|
||||
#endif
|
||||
}
|
||||
|
||||
GIVEN("the buffer is empty") {
|
||||
SUBCASE("write(uint8_t)") {
|
||||
int n = bufferingPrint.write('A');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("write(uint8_t) should flush") {
|
||||
bufferingPrint.write('A');
|
||||
bufferingPrint.write('B');
|
||||
bufferingPrint.write('C');
|
||||
bufferingPrint.write('D');
|
||||
bufferingPrint.write('E');
|
||||
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,3) goes in buffer") {
|
||||
size_t n = bufferingPrint.write("ABC", 3);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,4) bypasses buffer") {
|
||||
size_t n = bufferingPrint.write("ABCD", 4);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
SUBCASE("write(char*,2) bypasses buffer") {
|
||||
size_t n = bufferingPrint.write("ABCD", 4);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("one byte in the buffer") {
|
||||
bufferingPrint.write('A');
|
||||
|
||||
SUBCASE("write(char*,3) goes in buffer and flush") {
|
||||
size_t n = bufferingPrint.write("BCD", 3);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,7) bypasses") {
|
||||
size_t n = bufferingPrint.write("BCDEFGH", 7);
|
||||
|
||||
CHECK(n == 7);
|
||||
CHECK(log.str() ==
|
||||
"write('ABCD', 4) -> 4"
|
||||
"write('EFGH', 4) -> 4");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("capacity is 0") {
|
||||
BufferingPrint bufferingPrint{spy, 0};
|
||||
|
||||
// SUBCASE("capacity()") {
|
||||
// CHECK(bufferingPrint.capacity() == 0);
|
||||
// }
|
||||
|
||||
SUBCASE("write(uint8_t) forwards to target") {
|
||||
int n = bufferingPrint.write('X');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('X') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,1) forwards to target") {
|
||||
int n = bufferingPrint.write("A", 1);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('A', 1) -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("flush()") {
|
||||
bufferingPrint.flush();
|
||||
|
||||
#if STREAMUTILS_PRINT_FLUSH_EXISTS
|
||||
CHECK(log.str() == "flush()");
|
||||
#else
|
||||
CHECK(log.str() == "");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Destructor should flush") {
|
||||
{
|
||||
BufferingPrint bufferingPrint{spy, 10};
|
||||
bufferingPrint.write("ABC", 3);
|
||||
}
|
||||
|
||||
CHECK(log.str() == "write('ABC', 3) -> 3");
|
||||
}
|
||||
}
|
||||
104
lib/ArduinoStreamUtils/extras/test/CMakeLists.txt
Normal file
104
lib/ArduinoStreamUtils/extras/test/CMakeLists.txt
Normal file
@@ -0,0 +1,104 @@
|
||||
# StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
# Copyright Benoit Blanchon 2019-2021
|
||||
# MIT License
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
|
||||
add_compile_options(-Wall -Wextra -Werror -Wundef)
|
||||
endif()
|
||||
|
||||
set(SOURCES
|
||||
BufferingPrintTest.cpp
|
||||
EepromStreamTest.cpp
|
||||
FailingAllocator.hpp
|
||||
HammingClientTest.cpp
|
||||
HammingDecodingClientTest.cpp
|
||||
HammingDecodingStreamTest.cpp
|
||||
HammingEncodingClientTest.cpp
|
||||
HammingEncodingStreamTest.cpp
|
||||
HammingPrintTest.cpp
|
||||
HammingStreamTest.cpp
|
||||
LoggingClientTest.cpp
|
||||
LoggingPrintTest.cpp
|
||||
LoggingStreamTest.cpp
|
||||
MemoryStreamTest.cpp
|
||||
ReadBufferingClientTest.cpp
|
||||
ReadBufferingStreamTest.cpp
|
||||
ReadLoggingClientTest.cpp
|
||||
ReadLoggingStreamTest.cpp
|
||||
ReadThrottlingStreamTest.cpp
|
||||
StringPrintTest.cpp
|
||||
StringStreamTest.cpp
|
||||
WaitingPrintTest.cpp
|
||||
WriteBufferingClientTest.cpp
|
||||
WriteBufferingStreamTest.cpp
|
||||
WriteLoggingClientTest.cpp
|
||||
WriteLoggingStreamTest.cpp
|
||||
WriteWaitingClientTest.cpp
|
||||
WriteWaitingStreamTest.cpp
|
||||
|
||||
doctest.h
|
||||
main.cpp
|
||||
)
|
||||
|
||||
########## AVR ##########
|
||||
|
||||
add_subdirectory(cores/avr)
|
||||
|
||||
add_executable(StreamUtilsTestAvr ${SOURCES})
|
||||
target_link_libraries(StreamUtilsTestAvr AvrCore)
|
||||
|
||||
add_test(Avr StreamUtilsTestAvr)
|
||||
|
||||
########## ESP32 ##########
|
||||
|
||||
add_subdirectory(cores/esp32)
|
||||
|
||||
add_executable(StreamUtilsTestEsp32 ${SOURCES})
|
||||
target_link_libraries(StreamUtilsTestEsp32 Esp32Core)
|
||||
|
||||
add_test(Esp32 StreamUtilsTestEsp32)
|
||||
|
||||
########## ESP8266 ##########
|
||||
|
||||
add_subdirectory(cores/esp8266)
|
||||
|
||||
add_executable(StreamUtilsTestEsp8266 ${SOURCES})
|
||||
target_link_libraries(StreamUtilsTestEsp8266 Esp8266Core)
|
||||
|
||||
add_test(Esp8266 StreamUtilsTestEsp8266)
|
||||
|
||||
########## NRF52 ##########
|
||||
|
||||
add_subdirectory(cores/nrf52)
|
||||
|
||||
add_executable(StreamUtilsTestNrf52 ${SOURCES})
|
||||
target_link_libraries(StreamUtilsTestNrf52 Nrf52Core)
|
||||
|
||||
add_test(Nrf52 StreamUtilsTestNrf52)
|
||||
|
||||
########## SAMD ##########
|
||||
|
||||
add_subdirectory(cores/samd)
|
||||
|
||||
add_executable(StreamUtilsTestSamd ${SOURCES})
|
||||
target_link_libraries(StreamUtilsTestSamd SamdCore)
|
||||
|
||||
add_test(Samd StreamUtilsTestSamd)
|
||||
|
||||
########## STM32 ##########
|
||||
|
||||
add_subdirectory(cores/stm32)
|
||||
|
||||
add_executable(StreamUtilsTestStm32 ${SOURCES})
|
||||
target_link_libraries(StreamUtilsTestStm32 Stm32Core)
|
||||
|
||||
add_test(Stm32 StreamUtilsTestStm32)
|
||||
|
||||
########## Teensy ##########
|
||||
|
||||
add_subdirectory(cores/teensy)
|
||||
|
||||
add_executable(StreamUtilsTestTeensy ${SOURCES})
|
||||
target_link_libraries(StreamUtilsTestTeensy TeensyCore)
|
||||
|
||||
add_test(Teensy StreamUtilsTestTeensy)
|
||||
57
lib/ArduinoStreamUtils/extras/test/EepromStreamTest.cpp
Normal file
57
lib/ArduinoStreamUtils/extras/test/EepromStreamTest.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "StreamUtils/Streams/EepromStream.hpp"
|
||||
|
||||
#if STREAMUTILS_ENABLE_EEPROM
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("EepromStream") {
|
||||
SUBCASE("available()") {
|
||||
EepromStream s(42, 84);
|
||||
CHECK(s.available() == 84);
|
||||
}
|
||||
|
||||
SUBCASE("write(uint8_t)") {
|
||||
EepromStream s(0, 2);
|
||||
CHECK(s.write('a') == 1);
|
||||
CHECK(s.write('b') == 1);
|
||||
CHECK(s.write('c') == 0);
|
||||
CHECK(s.write('d') == 0);
|
||||
s.flush();
|
||||
CHECK(s.readString() == "ab");
|
||||
}
|
||||
|
||||
SUBCASE("write(const uint8_t *, size_t)") {
|
||||
EepromStream s(0, 5);
|
||||
CHECK(s.write("abc", 3) == 3);
|
||||
CHECK(s.write("def", 3) == 2);
|
||||
CHECK(s.write("ghi", 3) == 0);
|
||||
s.flush();
|
||||
CHECK(s.readString() == "abcde");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
EepromStream s(0, 2);
|
||||
s.write("ab", 2);
|
||||
CHECK(s.read() == 'a');
|
||||
CHECK(s.read() == 'b');
|
||||
CHECK(s.read() == -1);
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
EepromStream s(0, 2);
|
||||
s.write("ab", 2);
|
||||
CHECK(s.peek() == 'a');
|
||||
CHECK(s.peek() == 'a');
|
||||
s.read();
|
||||
CHECK(s.peek() == 'b');
|
||||
s.read();
|
||||
CHECK(s.peek() == -1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
14
lib/ArduinoStreamUtils/extras/test/FailingAllocator.hpp
Normal file
14
lib/ArduinoStreamUtils/extras/test/FailingAllocator.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h> // size_t
|
||||
|
||||
struct FailingAllocator {
|
||||
void* allocate(size_t) {
|
||||
return nullptr;
|
||||
}
|
||||
void deallocate(void*) {}
|
||||
};
|
||||
30
lib/ArduinoStreamUtils/extras/test/HammingClientTest.cpp
Normal file
30
lib/ArduinoStreamUtils/extras/test/HammingClientTest.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "SpyingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Clients/HammingClient.hpp"
|
||||
#include "StreamUtils/Clients/MemoryClient.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("HammingClient") {
|
||||
MemoryClient upstream(64);
|
||||
|
||||
HammingClient<7, 4> client{upstream};
|
||||
|
||||
SUBCASE("read() decodes") {
|
||||
upstream.print("Tq");
|
||||
|
||||
CHECK(client.read() == 'A');
|
||||
}
|
||||
|
||||
SUBCASE("write() encodes") {
|
||||
client.write('A');
|
||||
|
||||
CHECK(upstream.readString() == "Tq");
|
||||
}
|
||||
}
|
||||
137
lib/ArduinoStreamUtils/extras/test/HammingDecodingClientTest.cpp
Normal file
137
lib/ArduinoStreamUtils/extras/test/HammingDecodingClientTest.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "SpyingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Clients/HammingDecodingClient.hpp"
|
||||
#include "StreamUtils/Clients/MemoryClient.hpp"
|
||||
#include "StreamUtils/Clients/SpyingClient.hpp"
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("HammingDecodingClient") {
|
||||
MemoryClient upstream(64);
|
||||
StringPrint log;
|
||||
SpyingClient spy{upstream, log};
|
||||
SpyingAllocator allocator{log};
|
||||
|
||||
BasicHammingDecodingClient<7, 4, SpyingAllocator&> client{spy, allocator};
|
||||
|
||||
SUBCASE("read() with small buffer") {
|
||||
uint8_t buffer[8];
|
||||
|
||||
SUBCASE("empty input") {
|
||||
size_t result = client.read(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 0);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "read(16) -> 0 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("decodes input") {
|
||||
upstream.print("TqTb");
|
||||
|
||||
size_t result = client.read(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 2);
|
||||
CHECK(std::string((char*)buffer, result) == "AB");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "read(16) -> 4 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("includes byte loaded by peek()") {
|
||||
upstream.print("TqTb");
|
||||
client.peek();
|
||||
log.clear();
|
||||
|
||||
size_t result = client.read(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 2);
|
||||
CHECK(std::string((char*)buffer, result) == "AB");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "read(15) -> 3 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("stores dangling byte") {
|
||||
upstream.print("TqT");
|
||||
|
||||
size_t result = client.read(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 1);
|
||||
CHECK(std::string((char*)buffer, result) == "A");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "read(16) -> 3 [timeout]");
|
||||
#endif
|
||||
|
||||
log.clear();
|
||||
upstream.print("b");
|
||||
CHECK(client.peek() == 'B');
|
||||
CHECK(log.str() == "peek() -> 98");
|
||||
}
|
||||
|
||||
SUBCASE("clears the byte loaded by peek") {
|
||||
upstream.print("TqTb");
|
||||
client.peek();
|
||||
client.read(buffer, sizeof(buffer));
|
||||
client.peek();
|
||||
CHECK(log.str() ==
|
||||
"read() -> 84"
|
||||
"peek() -> 113"
|
||||
"read(15) -> 3 [timeout]"
|
||||
"read() -> -1");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("read() with large buffer") {
|
||||
uint8_t buffer[32];
|
||||
|
||||
SUBCASE("empty input") {
|
||||
size_t result = client.read(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 0);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"allocate(64) -> ptr"
|
||||
"read(64) -> 0 [timeout]"
|
||||
"deallocate(ptr)");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("decodes input") {
|
||||
upstream.print("TqTb");
|
||||
|
||||
size_t result = client.read(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 2);
|
||||
CHECK(std::string((char*)buffer, result) == "AB");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"allocate(64) -> ptr"
|
||||
"read(64) -> 4 [timeout]"
|
||||
"deallocate(ptr)");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("uses input buffer if allocation fails") {
|
||||
upstream.print("TqTb");
|
||||
allocator.forceFail = true;
|
||||
|
||||
size_t result = client.read(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 2);
|
||||
CHECK(std::string((char*)buffer, result) == "AB");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"allocate(64) -> null"
|
||||
"read(32) -> 4 [timeout]");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
290
lib/ArduinoStreamUtils/extras/test/HammingDecodingStreamTest.cpp
Normal file
290
lib/ArduinoStreamUtils/extras/test/HammingDecodingStreamTest.cpp
Normal file
@@ -0,0 +1,290 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "SpyingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
#include "StreamUtils/Streams/HammingDecodingStream.hpp"
|
||||
#include "StreamUtils/Streams/SpyingStream.hpp"
|
||||
#include "StreamUtils/Streams/StringStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("HammingDecodingStream") {
|
||||
StringStream upstream;
|
||||
StringPrint log;
|
||||
SpyingStream spy{upstream, log};
|
||||
SpyingAllocator allocator{log};
|
||||
|
||||
BasicHammingDecodingStream<7, 4, SpyingAllocator&> stream{spy, allocator};
|
||||
|
||||
SUBCASE("available()") {
|
||||
SUBCASE("empty input") {
|
||||
CHECK(stream.available() == 0);
|
||||
CHECK(log.str() == "available() -> 0");
|
||||
}
|
||||
|
||||
SUBCASE("even number of bytes") {
|
||||
upstream.print("ABCDEFGH");
|
||||
|
||||
CHECK(stream.available() == 4);
|
||||
CHECK(log.str() == "available() -> 8");
|
||||
}
|
||||
|
||||
SUBCASE("odd number of bytes") {
|
||||
upstream.print("ABCDEFGHI");
|
||||
|
||||
CHECK(stream.available() == 4);
|
||||
CHECK(log.str() == "available() -> 9");
|
||||
}
|
||||
|
||||
SUBCASE("even number of bytes after peek") {
|
||||
upstream.print("ABCDEFGH");
|
||||
stream.peek();
|
||||
log.clear();
|
||||
CHECK(stream.available() == 4);
|
||||
CHECK(log.str() == "available() -> 7");
|
||||
}
|
||||
|
||||
SUBCASE("odd number of bytes after peek") {
|
||||
upstream.print("ABCDEFGHI");
|
||||
stream.peek();
|
||||
log.clear();
|
||||
CHECK(stream.available() == 4);
|
||||
CHECK(log.str() == "available() -> 8");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
SUBCASE("returns -1 when empty") {
|
||||
int result = stream.peek();
|
||||
|
||||
CHECK(result == -1);
|
||||
CHECK(log.str() == "read() -> -1");
|
||||
}
|
||||
|
||||
SUBCASE("returns -1 when only one byte in input") {
|
||||
upstream.print("A");
|
||||
|
||||
int result = stream.peek();
|
||||
|
||||
CHECK(result == -1);
|
||||
CHECK(log.str() ==
|
||||
"read() -> 65"
|
||||
"peek() -> -1");
|
||||
}
|
||||
|
||||
SUBCASE("returns decoded value") {
|
||||
upstream.print("Tq");
|
||||
|
||||
int result = stream.peek();
|
||||
|
||||
CHECK(result == 'A');
|
||||
CHECK(log.str() ==
|
||||
"read() -> 84"
|
||||
"peek() -> 113");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't call read() the second time") {
|
||||
upstream.print("A");
|
||||
stream.peek();
|
||||
log.clear();
|
||||
|
||||
int result = stream.peek();
|
||||
|
||||
CHECK(result == -1);
|
||||
CHECK(log.str() == "peek() -> -1");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
SUBCASE("returns -1 if empty") {
|
||||
int result = stream.read();
|
||||
|
||||
CHECK(result == -1);
|
||||
CHECK(log.str() == "read() -> -1");
|
||||
}
|
||||
|
||||
SUBCASE("returns -1 if only one byte in input") {
|
||||
upstream.print("A");
|
||||
|
||||
int result = stream.read();
|
||||
|
||||
CHECK(result == -1);
|
||||
CHECK(log.str() ==
|
||||
"read() -> 65"
|
||||
"read() -> -1");
|
||||
}
|
||||
|
||||
SUBCASE("returns decoded value if two bytes in input") {
|
||||
upstream.print("Tq");
|
||||
|
||||
int result = stream.read();
|
||||
|
||||
CHECK(result == 'A');
|
||||
CHECK(log.str() ==
|
||||
"read() -> 84"
|
||||
"read() -> 113");
|
||||
}
|
||||
|
||||
SUBCASE("reuses the byte read by peek()") {
|
||||
upstream.print("Tq");
|
||||
stream.peek();
|
||||
log.clear();
|
||||
|
||||
int result = stream.read();
|
||||
|
||||
CHECK(result == 'A');
|
||||
CHECK(log.str() == "read() -> 113");
|
||||
}
|
||||
|
||||
SUBCASE("reuses the byte read by previous call") {
|
||||
upstream.print("T");
|
||||
stream.read();
|
||||
upstream.print("q");
|
||||
log.clear();
|
||||
|
||||
int result = stream.read();
|
||||
|
||||
CHECK(result == 'A');
|
||||
CHECK(log.str() == "read() -> 113");
|
||||
}
|
||||
|
||||
SUBCASE("flushes the buffered byte") {
|
||||
upstream.print("TqTb");
|
||||
|
||||
CHECK(stream.read() == 'A');
|
||||
CHECK(stream.read() == 'B');
|
||||
|
||||
CHECK(log.str() ==
|
||||
"read() -> 84"
|
||||
"read() -> 113"
|
||||
"read() -> 84"
|
||||
"read() -> 98");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("readBytes() with small buffer") {
|
||||
char buffer[8];
|
||||
|
||||
SUBCASE("empty input") {
|
||||
size_t result = stream.readBytes(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 0);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(16) -> 0 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("decodes input") {
|
||||
upstream.print("TqTb");
|
||||
|
||||
size_t result = stream.readBytes(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 2);
|
||||
CHECK(std::string(buffer, result) == "AB");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(16) -> 4 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("includes byte loaded by peek()") {
|
||||
upstream.print("TqTb");
|
||||
stream.peek();
|
||||
log.clear();
|
||||
|
||||
size_t result = stream.readBytes(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 2);
|
||||
CHECK(std::string(buffer, result) == "AB");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(15) -> 3 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("stores dangling byte") {
|
||||
upstream.print("TqT");
|
||||
|
||||
size_t result = stream.readBytes(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 1);
|
||||
CHECK(std::string(buffer, result) == "A");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(16) -> 3 [timeout]");
|
||||
#endif
|
||||
|
||||
log.clear();
|
||||
upstream.print("b");
|
||||
CHECK(stream.peek() == 'B');
|
||||
CHECK(log.str() == "peek() -> 98");
|
||||
}
|
||||
|
||||
SUBCASE("clears the byte loaded by peek") {
|
||||
upstream.print("TqTb");
|
||||
stream.peek();
|
||||
stream.readBytes(buffer, sizeof(buffer));
|
||||
CHECK(stream.peek() == -1);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"read() -> 84"
|
||||
"peek() -> 113"
|
||||
"readBytes(15) -> 3 [timeout]"
|
||||
"read() -> -1");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("readBytes() with large buffer") {
|
||||
char buffer[32];
|
||||
|
||||
SUBCASE("empty input") {
|
||||
size_t result = stream.readBytes(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 0);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"allocate(64) -> ptr"
|
||||
"readBytes(64) -> 0 [timeout]"
|
||||
"deallocate(ptr)");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("decodes input") {
|
||||
upstream.print("TqTb");
|
||||
|
||||
size_t result = stream.readBytes(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 2);
|
||||
CHECK(std::string(buffer, result) == "AB");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"allocate(64) -> ptr"
|
||||
"readBytes(64) -> 4 [timeout]"
|
||||
"deallocate(ptr)");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("uses input buffer if allocation fails") {
|
||||
upstream.print("TqTb");
|
||||
allocator.forceFail = true;
|
||||
|
||||
size_t result = stream.readBytes(buffer, sizeof(buffer));
|
||||
|
||||
CHECK(result == 2);
|
||||
CHECK(std::string(buffer, result) == "AB");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"allocate(64) -> null"
|
||||
"readBytes(32) -> 4 [timeout]");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("flush()") {
|
||||
stream.flush();
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "SpyingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Clients/HammingEncodingClient.hpp"
|
||||
#include "StreamUtils/Clients/MemoryClient.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("HammingEncodingClient") {
|
||||
MemoryClient upstream(64);
|
||||
|
||||
HammingEncodingClient<7, 4> client{upstream};
|
||||
|
||||
SUBCASE("read() forwards upstream data") {
|
||||
upstream.print("A");
|
||||
|
||||
CHECK(client.read() == 'A');
|
||||
}
|
||||
|
||||
SUBCASE("write() encodes") {
|
||||
client.write('A');
|
||||
|
||||
CHECK(upstream.readString() == "Tq");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "SpyingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Streams/HammingEncodingStream.hpp"
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("HammingEncodingStream") {
|
||||
MemoryStream upstream(64);
|
||||
|
||||
HammingEncodingStream<7, 4> stream{upstream};
|
||||
|
||||
SUBCASE("read() forwards upstream data") {
|
||||
upstream.print("A");
|
||||
|
||||
CHECK(stream.read() == 'A');
|
||||
}
|
||||
|
||||
SUBCASE("write() encodes") {
|
||||
stream.write('A');
|
||||
|
||||
CHECK(upstream.readString() == "Tq");
|
||||
}
|
||||
}
|
||||
202
lib/ArduinoStreamUtils/extras/test/HammingPrintTest.cpp
Normal file
202
lib/ArduinoStreamUtils/extras/test/HammingPrintTest.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "SpyingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Prints/HammingPrint.hpp"
|
||||
#include "StreamUtils/Prints/SpyingPrint.hpp"
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("HammingPrint") {
|
||||
MemoryStream upstream(4);
|
||||
|
||||
StringPrint log;
|
||||
SpyingPrint spy{upstream, log};
|
||||
SpyingAllocator allocator{log};
|
||||
|
||||
BasicHammingPrint<7, 4, SpyingAllocator&> print{spy, allocator};
|
||||
|
||||
SUBCASE("write(char*, size_t)") {
|
||||
SUBCASE("stops if even byte fails") {
|
||||
CHECK(print.print("ABA") == 2);
|
||||
print.write('A'); // try to flush remainder
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('TqTbTq', 6) -> 4"
|
||||
"write('T') -> 0" // no remainder
|
||||
);
|
||||
}
|
||||
|
||||
SUBCASE("saves remainder if odd byte fails") {
|
||||
upstream.print("?");
|
||||
|
||||
CHECK(print.print("ABA") == 2);
|
||||
print.write('A'); // try to flush remainder
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('TqTbTq', 6) -> 3"
|
||||
"write('b') -> 0" // remainder!!
|
||||
);
|
||||
}
|
||||
|
||||
SUBCASE("writes remainder first") {
|
||||
upstream.print("???");
|
||||
print.write('A'); // add remainder
|
||||
log.clear();
|
||||
upstream.readString();
|
||||
|
||||
CHECK(print.print("ABA") == 2);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('q') -> 1"
|
||||
"write('TqTbTq', 6) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("stops if remainder fails") {
|
||||
upstream.print("???");
|
||||
print.write('A'); // add remainder
|
||||
log.clear();
|
||||
|
||||
CHECK(print.print("ABA") == 0);
|
||||
|
||||
CHECK(log.str() == "write('q') -> 0");
|
||||
}
|
||||
|
||||
SUBCASE("allocates in stack when buffer is small") {
|
||||
print.write("ABABABABABABABAB", 16);
|
||||
|
||||
CHECK(log.str() == "write('TqTbTqTbTqTbTqTbTqTbTqTbTqTbTqTb', 32) -> 4");
|
||||
}
|
||||
|
||||
SUBCASE("allocates in heap when buffer is large") {
|
||||
print.write("ABABABABABABABABA", 17);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"allocate(34) -> ptr"
|
||||
"write('TqTbTqTbTqTbTqTbTqTbTqTbTqTbTqTbTq', 34) -> 4"
|
||||
"deallocate(ptr)");
|
||||
}
|
||||
|
||||
SUBCASE("falls back to stack if heap fails") {
|
||||
allocator.forceFail = true;
|
||||
print.write("ABABABABABABABABA", 17);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"allocate(34) -> null"
|
||||
"write('TqTbTqTbTqTbTqTbTqTbTqTbTqTbTqTb', 32) -> 4");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
SUBCASE("writes both bytes") {
|
||||
CHECK(print.write('A') == 1);
|
||||
|
||||
CHECK(upstream.readString() == "Tq");
|
||||
CHECK(log.str() ==
|
||||
"write('T') -> 1"
|
||||
"write('q') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("stops if first by fails") {
|
||||
upstream.print("????");
|
||||
|
||||
CHECK(print.write('A') == 0);
|
||||
print.write('A'); // try to flush remainder
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('T') -> 0"
|
||||
"write('T') -> 0" // no remainder
|
||||
);
|
||||
}
|
||||
|
||||
SUBCASE("saves remainder if second by fails") {
|
||||
upstream.print("???");
|
||||
|
||||
CHECK(print.write('A') == 1);
|
||||
print.write('A'); // try to flush remainder
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('T') -> 1"
|
||||
"write('q') -> 0"
|
||||
"write('q') -> 0" // remainder!!
|
||||
);
|
||||
}
|
||||
|
||||
SUBCASE("writes remainder first") {
|
||||
upstream.print("???");
|
||||
print.write('A'); // add remainder
|
||||
log.clear();
|
||||
upstream.readString();
|
||||
|
||||
CHECK(print.write('A') == 1);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('q') -> 1"
|
||||
"write('T') -> 1"
|
||||
"write('q') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("stops if remainder fails") {
|
||||
upstream.print("???");
|
||||
print.write('A'); // add remainder
|
||||
log.clear();
|
||||
|
||||
CHECK(print.write('A') == 0);
|
||||
print.write('A'); // try to flush remainder
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('q') -> 0"
|
||||
"write('q') -> 0" // remainder!!
|
||||
);
|
||||
}
|
||||
|
||||
SUBCASE("resets remainder") {
|
||||
upstream.print("???");
|
||||
print.write('A'); // add remainder
|
||||
log.clear();
|
||||
upstream.read();
|
||||
|
||||
CHECK(print.write('A') == 0);
|
||||
print.write('A'); // try to flush remainder
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('q') -> 1"
|
||||
"write('T') -> 0"
|
||||
"write('T') -> 0" // no remainder
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#if STREAMUTILS_PRINT_FLUSH_EXISTS
|
||||
SUBCASE("flush() writes remainder") {
|
||||
upstream.print("???");
|
||||
print.write('A'); // add remainder
|
||||
log.clear();
|
||||
upstream.read();
|
||||
|
||||
print.flush();
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('q') -> 1"
|
||||
"flush()" // no remainder
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
SUBCASE("destructor flushes remainder") {
|
||||
{
|
||||
BasicHammingPrint<7, 4, SpyingAllocator&> print{spy, allocator};
|
||||
upstream.print("???");
|
||||
print.write('A'); // add remainder
|
||||
log.clear();
|
||||
}
|
||||
|
||||
CHECK(log.str() == "write('q') -> 0");
|
||||
}
|
||||
}
|
||||
30
lib/ArduinoStreamUtils/extras/test/HammingStreamTest.cpp
Normal file
30
lib/ArduinoStreamUtils/extras/test/HammingStreamTest.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "SpyingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Streams/HammingStream.hpp"
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("HammingStream") {
|
||||
MemoryStream upstream(64);
|
||||
|
||||
HammingStream<7, 4> stream{upstream};
|
||||
|
||||
SUBCASE("read() decodes") {
|
||||
upstream.print("Tq");
|
||||
|
||||
CHECK(stream.read() == 'A');
|
||||
}
|
||||
|
||||
SUBCASE("write() encodes") {
|
||||
stream.write('A');
|
||||
|
||||
CHECK(upstream.readString() == "Tq");
|
||||
}
|
||||
}
|
||||
138
lib/ArduinoStreamUtils/extras/test/LoggingClientTest.cpp
Normal file
138
lib/ArduinoStreamUtils/extras/test/LoggingClientTest.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "StreamUtils/Clients/LoggingClient.hpp"
|
||||
#include "StreamUtils/Clients/MemoryClient.hpp"
|
||||
#include "StreamUtils/Clients/SpyingClient.hpp"
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("LoggingClient") {
|
||||
MemoryClient target(4);
|
||||
|
||||
StringPrint log;
|
||||
SpyingClient spy{target, log};
|
||||
|
||||
StringPrint output;
|
||||
LoggingClient loggingClient{spy, output};
|
||||
|
||||
SUBCASE("available()") {
|
||||
target.print("ABC");
|
||||
|
||||
size_t n = loggingClient.available();
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "available() -> 3");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("connect(IPAddress)") {
|
||||
int n = loggingClient.connect(IPAddress("1.2.3.4"), 80);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "connect('1.2.3.4', 80) -> 1");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("connect(const char*)") {
|
||||
int n = loggingClient.connect("1.2.3.4", 80);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "connect('1.2.3.4', 80) -> 1");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("connected()") {
|
||||
uint8_t n = loggingClient.connected();
|
||||
|
||||
CHECK(n == false);
|
||||
CHECK(log.str() == "connected() -> 0");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("stop()") {
|
||||
loggingClient.stop();
|
||||
|
||||
CHECK(log.str() == "stop()");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("operator bool()") {
|
||||
bool n = loggingClient.operator bool();
|
||||
|
||||
CHECK(n == true);
|
||||
CHECK(log.str() == "operator bool() -> true");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
target.print("ABC");
|
||||
|
||||
int n = loggingClient.peek();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
target.print("ABC");
|
||||
|
||||
int n = loggingClient.read();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "read() -> 65");
|
||||
CHECK(output.str() == "A");
|
||||
}
|
||||
|
||||
SUBCASE("read(uint8_t*,size_t)") {
|
||||
target.print("ABC");
|
||||
|
||||
uint8_t s[4] = {0};
|
||||
size_t n = loggingClient.read(s, 4);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "read(4) -> 3 [timeout]");
|
||||
CHECK(output.str() == "ABC");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
target.print("ABC");
|
||||
|
||||
char s[4] = {0};
|
||||
size_t n = loggingClient.readBytes(s, 4);
|
||||
|
||||
CHECK(n == 3);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(4) -> 3 [timeout]");
|
||||
#endif
|
||||
CHECK(output.str() == "ABC");
|
||||
}
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
int n = loggingClient.write('A');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('A') -> 1");
|
||||
CHECK(output.str() == "A");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,size_t)") {
|
||||
int n = loggingClient.write("ABCDEF", 6);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCDEF', 6) -> 4");
|
||||
CHECK(output.str() == "ABCD");
|
||||
}
|
||||
|
||||
SUBCASE("flush()") {
|
||||
loggingClient.flush();
|
||||
|
||||
CHECK(output.str() == "");
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
}
|
||||
41
lib/ArduinoStreamUtils/extras/test/LoggingPrintTest.cpp
Normal file
41
lib/ArduinoStreamUtils/extras/test/LoggingPrintTest.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "StreamUtils/Prints/LoggingPrint.hpp"
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("LoggingPrint") {
|
||||
MemoryStream primary(4);
|
||||
MemoryStream secondary(64);
|
||||
LoggingPrint loggingPrint{primary, secondary};
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
int n = loggingPrint.write('A');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(primary.readString() == "A");
|
||||
CHECK(secondary.readString() == "A");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,size_t)") {
|
||||
int n = loggingPrint.write("ABCDEF", 6);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(primary.readString() == "ABCD");
|
||||
CHECK(secondary.readString() == "ABCD");
|
||||
}
|
||||
|
||||
#if STREAMUTILS_PRINT_FLUSH_EXISTS
|
||||
SUBCASE("flush()") {
|
||||
loggingPrint.write("AB", 2);
|
||||
REQUIRE(primary.available() == 2);
|
||||
loggingPrint.flush();
|
||||
REQUIRE(primary.available() == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
93
lib/ArduinoStreamUtils/extras/test/LoggingStreamTest.cpp
Normal file
93
lib/ArduinoStreamUtils/extras/test/LoggingStreamTest.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
#include "StreamUtils/Streams/LoggingStream.hpp"
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
#include "StreamUtils/Streams/SpyingStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("LoggingStream") {
|
||||
MemoryStream upstream{4};
|
||||
StringPrint output;
|
||||
|
||||
StringPrint log;
|
||||
SpyingStream upstreamSpy{upstream, log};
|
||||
|
||||
LoggingStream loggingStream{upstreamSpy, output};
|
||||
|
||||
// upstream -> upstreamSpy -> loggingStream -> output
|
||||
// |
|
||||
// v
|
||||
// log
|
||||
|
||||
SUBCASE("available()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
size_t n = loggingStream.available();
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "available() -> 3");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
int n = loggingStream.peek();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
int n = loggingStream.read();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "read() -> 65");
|
||||
CHECK(output.str() == "A");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
char s[4] = {0};
|
||||
size_t n = loggingStream.readBytes(s, 4);
|
||||
|
||||
CHECK(n == 3);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(4) -> 3 [timeout]");
|
||||
#endif
|
||||
CHECK(output.str() == "ABC");
|
||||
}
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
int n = loggingStream.write('A');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('A') -> 1");
|
||||
CHECK(output.str() == "A");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,size_t)") {
|
||||
int n = loggingStream.write("ABCDEF", 6);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCDEF', 6) -> 4");
|
||||
CHECK(output.str() == "ABCD");
|
||||
}
|
||||
|
||||
SUBCASE("flush()") {
|
||||
loggingStream.flush();
|
||||
|
||||
CHECK(log.str() == "flush()");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
}
|
||||
116
lib/ArduinoStreamUtils/extras/test/MemoryStreamTest.cpp
Normal file
116
lib/ArduinoStreamUtils/extras/test/MemoryStreamTest.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
#include "StreamUtils/Streams/SpyingStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("MemoryStream") {
|
||||
MemoryStream stream(4);
|
||||
|
||||
WHEN("stream is empty") {
|
||||
THEN("available() return 0") {
|
||||
CHECK(stream.available() == 0);
|
||||
}
|
||||
|
||||
THEN("write(uint8) returns 1") {
|
||||
CHECK(stream.write('A') == 1);
|
||||
}
|
||||
|
||||
THEN("write(\"ABCD\",4) returns 4") {
|
||||
CHECK(stream.write("ABCD", 4) == 4);
|
||||
}
|
||||
|
||||
THEN("write(uint8*,8) returns 4") {
|
||||
CHECK(stream.write("ABCDEFGH", 8) == 4);
|
||||
}
|
||||
|
||||
THEN("read() return -1") {
|
||||
CHECK(stream.read() == -1);
|
||||
}
|
||||
|
||||
THEN("peek() return -1") {
|
||||
CHECK(stream.peek() == -1);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("stream is full") {
|
||||
stream.print("ABCD");
|
||||
|
||||
THEN("available() return 4") {
|
||||
CHECK(stream.available() == 4);
|
||||
}
|
||||
|
||||
THEN("write(uint8) returns 0") {
|
||||
CHECK(stream.write('A') == 0);
|
||||
}
|
||||
|
||||
THEN("write(\"ABCD\",4) returns 0") {
|
||||
CHECK(stream.write("ABCD", 4) == 0);
|
||||
}
|
||||
|
||||
THEN("read() returns the next value") {
|
||||
CHECK(stream.read() == 'A');
|
||||
CHECK(stream.read() == 'B');
|
||||
}
|
||||
|
||||
THEN("read(uint8_t*,size_t) extracts the next bytes") {
|
||||
char data[5] = {0};
|
||||
CHECK(stream.readBytes(data, 4) == 4);
|
||||
CHECK(data == std::string("ABCD"));
|
||||
}
|
||||
|
||||
THEN("peek() returns the first value") {
|
||||
CHECK(stream.peek() == 'A');
|
||||
CHECK(stream.peek() == 'A');
|
||||
}
|
||||
|
||||
SUBCASE("read() makes room for one byte") {
|
||||
stream.read(); // make room
|
||||
REQUIRE(stream.available() == 3);
|
||||
|
||||
stream.write('E'); // write at the beginning
|
||||
REQUIRE(stream.available() == 4);
|
||||
|
||||
char data[5] = {0};
|
||||
stream.readBytes(data, 4);
|
||||
CHECK(data == std::string("BCDE"));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("lower half is filled") {
|
||||
stream.print("AB");
|
||||
|
||||
THEN("available() return 2") {
|
||||
CHECK(stream.available() == 2);
|
||||
}
|
||||
|
||||
THEN("write(uint8) returns 1") {
|
||||
CHECK(stream.write('C') == 1);
|
||||
}
|
||||
|
||||
THEN("write(\"ABCD\",4) returns 2") {
|
||||
CHECK(stream.write("ABCD", 4) == 2);
|
||||
}
|
||||
|
||||
THEN("read() returns the next value") {
|
||||
CHECK(stream.read() == 'A');
|
||||
CHECK(stream.read() == 'B');
|
||||
}
|
||||
|
||||
THEN("read(uint8_t*,size_t) extracts the next bytes") {
|
||||
char data[5] = {0};
|
||||
CHECK(stream.readBytes(data, 4) == 2);
|
||||
CHECK(data == std::string("AB"));
|
||||
}
|
||||
|
||||
THEN("peek() returns the first value") {
|
||||
CHECK(stream.peek() == 'A');
|
||||
CHECK(stream.peek() == 'A');
|
||||
}
|
||||
}
|
||||
}
|
||||
337
lib/ArduinoStreamUtils/extras/test/ReadBufferingClientTest.cpp
Normal file
337
lib/ArduinoStreamUtils/extras/test/ReadBufferingClientTest.cpp
Normal file
@@ -0,0 +1,337 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Clients/MemoryClient.hpp"
|
||||
#include "StreamUtils/Clients/ReadBufferingClient.hpp"
|
||||
#include "StreamUtils/Clients/SpyingClient.hpp"
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("ReadBufferingClient") {
|
||||
MemoryClient target(64);
|
||||
StringPrint log;
|
||||
SpyingClient spy{target, log};
|
||||
|
||||
SUBCASE("capacity = 4") {
|
||||
ReadBufferingClient bufferedClient{spy, 4};
|
||||
Client& client = bufferedClient;
|
||||
|
||||
SUBCASE("available()") {
|
||||
target.print("ABCDEFGH");
|
||||
|
||||
SUBCASE("empty input") {
|
||||
target.flush();
|
||||
CHECK(client.available() == 0);
|
||||
CHECK(log.str() == "available() -> 0");
|
||||
}
|
||||
|
||||
SUBCASE("read empty input") {
|
||||
target.flush();
|
||||
|
||||
client.read();
|
||||
|
||||
CHECK(client.available() == 0);
|
||||
CHECK(log.str() ==
|
||||
"available() -> 0"
|
||||
"read() -> -1"
|
||||
"available() -> 0");
|
||||
}
|
||||
|
||||
SUBCASE("same a target") {
|
||||
CHECK(client.available() == 8);
|
||||
CHECK(log.str() == "available() -> 8");
|
||||
}
|
||||
|
||||
SUBCASE("target + in buffer") {
|
||||
client.read();
|
||||
|
||||
CHECK(client.available() == 7);
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"read(4) -> 4"
|
||||
"available() -> 4");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
SUBCASE("returns -1 when empty") {
|
||||
target.flush();
|
||||
|
||||
int result = client.peek();
|
||||
|
||||
CHECK(result == -1);
|
||||
CHECK(log.str() == "peek() -> -1");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't call readBytes() when buffer is empty") {
|
||||
target.print("A");
|
||||
|
||||
int result = client.peek();
|
||||
|
||||
CHECK(result == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't call peek() when buffer is full") {
|
||||
target.print("AB");
|
||||
|
||||
client.read();
|
||||
int result = client.peek();
|
||||
|
||||
CHECK(result == 'B');
|
||||
CHECK(log.str() ==
|
||||
"available() -> 2"
|
||||
"read(2) -> 2");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
SUBCASE("reads 4 bytes at a time") {
|
||||
target.print("ABCDEFG");
|
||||
std::string result;
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
result += (char)client.read();
|
||||
}
|
||||
|
||||
CHECK(result == "ABCDEFG");
|
||||
CHECK(log.str() ==
|
||||
"available() -> 7"
|
||||
"read(4) -> 4"
|
||||
"available() -> 3"
|
||||
"read(3) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("returns -1 when empty") {
|
||||
target.flush();
|
||||
|
||||
int result = client.read();
|
||||
|
||||
CHECK(result == -1);
|
||||
CHECK(log.str() ==
|
||||
"available() -> 0"
|
||||
"read() -> -1");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
SUBCASE("empty input") {
|
||||
target.flush();
|
||||
|
||||
char c;
|
||||
size_t result = client.readBytes(&c, 1);
|
||||
|
||||
CHECK(result == 0);
|
||||
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 0"
|
||||
"readBytes(1) -> 0 [timeout]");
|
||||
#else
|
||||
CHECK(log.str() ==
|
||||
"available() -> 0"
|
||||
"read() -> -1"); // [timeout] from timedRead()
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("reads 4 bytes when requested one") {
|
||||
target.print("ABCDEFG");
|
||||
|
||||
char c;
|
||||
size_t result = client.readBytes(&c, 1);
|
||||
|
||||
CHECK(c == 'A');
|
||||
CHECK(result == 1);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 7"
|
||||
"readBytes(4) -> 4");
|
||||
#else
|
||||
CHECK(log.str() ==
|
||||
"available() -> 7"
|
||||
"read(4) -> 4");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("copy one byte from buffer") {
|
||||
target.print("ABCDEFGH");
|
||||
client.read(); // load buffer
|
||||
|
||||
char c;
|
||||
size_t result = client.readBytes(&c, 1);
|
||||
|
||||
CHECK(c == 'B');
|
||||
CHECK(result == 1);
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"read(4) -> 4");
|
||||
}
|
||||
|
||||
SUBCASE("copy content from buffer then bypass buffer") {
|
||||
target.print("ABCDEFGH");
|
||||
client.read(); // load buffer
|
||||
|
||||
char c[8] = {0};
|
||||
size_t result = client.readBytes(c, 7);
|
||||
|
||||
CHECK(c == std::string("BCDEFGH"));
|
||||
CHECK(result == 7);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"read(4) -> 4"
|
||||
"available() -> 4"
|
||||
"readBytes(4) -> 4");
|
||||
#else
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"read(4) -> 4"
|
||||
"available() -> 4"
|
||||
"read(4) -> 4");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("copy content from buffer twice") {
|
||||
target.print("ABCDEFGH");
|
||||
client.read(); // load buffer
|
||||
|
||||
char c[8] = {0};
|
||||
size_t result = client.readBytes(c, 4);
|
||||
|
||||
CHECK(c == std::string("BCDE"));
|
||||
CHECK(result == 4);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"read(4) -> 4"
|
||||
"available() -> 4"
|
||||
"readBytes(4) -> 4");
|
||||
#else
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"read(4) -> 4"
|
||||
"available() -> 4"
|
||||
"read(4) -> 4");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("read past the end") {
|
||||
target.print("A");
|
||||
|
||||
char c;
|
||||
client.readBytes(&c, 1);
|
||||
size_t result = client.readBytes(&c, 1);
|
||||
|
||||
CHECK(result == 0);
|
||||
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 1"
|
||||
"readBytes(1) -> 1"
|
||||
"available() -> 0"
|
||||
"readBytes(1) -> 0 [timeout]");
|
||||
#else
|
||||
CHECK(log.str() ==
|
||||
"available() -> 1"
|
||||
"read() -> 65"
|
||||
"available() -> 0"
|
||||
"read() -> -1"); // [timeout] from timedRead()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("flush()") {
|
||||
client.flush();
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
|
||||
SUBCASE("copy constructor") {
|
||||
target.print("ABCDEFGH");
|
||||
bufferedClient.read();
|
||||
|
||||
auto dup = bufferedClient;
|
||||
|
||||
int result = dup.read();
|
||||
|
||||
CHECK(result == 'B');
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"read(4) -> 4");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("No memory") {
|
||||
BasicReadBufferingClient<FailingAllocator> client(spy, 4);
|
||||
|
||||
SUBCASE("available()") {
|
||||
target.print("ABC");
|
||||
|
||||
CHECK(client.available() == 3);
|
||||
}
|
||||
|
||||
// SUBCASE("capacity()") {
|
||||
// CHECK(client.capacity() == 0);
|
||||
// }
|
||||
|
||||
SUBCASE("peek()") {
|
||||
target.print("ABC");
|
||||
|
||||
int c = client.peek();
|
||||
|
||||
CHECK(c == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
target.print("ABC");
|
||||
|
||||
int c = client.read();
|
||||
|
||||
CHECK(c == 'A');
|
||||
CHECK(log.str() == "read() -> 65");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
target.print("ABC");
|
||||
|
||||
char s[4] = {0};
|
||||
int n = client.readBytes(s, 3);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(s == std::string("ABC"));
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(3) -> 3");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Real example") {
|
||||
ReadBufferingClient bufferedClient{spy, 64};
|
||||
Client& client = bufferedClient;
|
||||
|
||||
target.print("{\"helloWorld\":\"Hello World\"}");
|
||||
|
||||
char c[] = "ABCDEFGH";
|
||||
CHECK(client.readBytes(&c[0], 1) == 1);
|
||||
CHECK(client.readBytes(&c[1], 1) == 1);
|
||||
CHECK(client.readBytes(&c[2], 1) == 1);
|
||||
CHECK(client.readBytes(&c[3], 1) == 1);
|
||||
|
||||
CHECK(c == std::string("{\"heEFGH"));
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 28"
|
||||
"readBytes(28) -> 28");
|
||||
#else
|
||||
CHECK(log.str() ==
|
||||
"available() -> 28"
|
||||
"read(28) -> 28");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
318
lib/ArduinoStreamUtils/extras/test/ReadBufferingStreamTest.cpp
Normal file
318
lib/ArduinoStreamUtils/extras/test/ReadBufferingStreamTest.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
#include "StreamUtils/Streams/ReadBufferingStream.hpp"
|
||||
#include "StreamUtils/Streams/SpyingStream.hpp"
|
||||
#include "StreamUtils/Streams/StringStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("ReadBufferingStream") {
|
||||
StringStream upstream;
|
||||
StringPrint log;
|
||||
SpyingStream spy{upstream, log};
|
||||
|
||||
SUBCASE("capacity = 4") {
|
||||
ReadBufferingStream bufferedStream{spy, 4};
|
||||
Stream& stream = bufferedStream;
|
||||
|
||||
SUBCASE("available()") {
|
||||
SUBCASE("empty input") {
|
||||
CHECK(stream.available() == 0);
|
||||
CHECK(log.str() == "available() -> 0");
|
||||
}
|
||||
|
||||
SUBCASE("read empty input") {
|
||||
int n = stream.read();
|
||||
|
||||
CHECK(n == -1);
|
||||
CHECK(stream.available() == 0);
|
||||
CHECK(log.str() ==
|
||||
"available() -> 0"
|
||||
"read() -> -1"
|
||||
"available() -> 0");
|
||||
}
|
||||
|
||||
SUBCASE("same a upstream") {
|
||||
upstream.print("ABCDEFGH");
|
||||
|
||||
CHECK(stream.available() == 8);
|
||||
CHECK(log.str() == "available() -> 8");
|
||||
}
|
||||
|
||||
SUBCASE("upstream + in buffer") {
|
||||
upstream.print("ABCDEFGH");
|
||||
|
||||
int n = stream.read();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(stream.available() == 7);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"readBytes(4) -> 4"
|
||||
"available() -> 4");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
SUBCASE("returns -1 when empty") {
|
||||
upstream.flush();
|
||||
|
||||
int result = stream.peek();
|
||||
|
||||
CHECK(result == -1);
|
||||
CHECK(log.str() == "peek() -> -1");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't call readBytes() when buffer is empty") {
|
||||
upstream.print("A");
|
||||
|
||||
int result = stream.peek();
|
||||
|
||||
CHECK(result == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't call peek() when buffer is full") {
|
||||
upstream.print("AB");
|
||||
|
||||
stream.read();
|
||||
int result = stream.peek();
|
||||
|
||||
CHECK(result == 'B');
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 2"
|
||||
"readBytes(2) -> 2");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
SUBCASE("reads 4 bytes at a time") {
|
||||
upstream.print("ABCDEFG");
|
||||
std::string result;
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
result += (char)stream.read();
|
||||
}
|
||||
|
||||
CHECK(result == "ABCDEFG");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 7"
|
||||
"readBytes(4) -> 4"
|
||||
"available() -> 3"
|
||||
"readBytes(3) -> 3");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("returns -1 when empty") {
|
||||
upstream.flush();
|
||||
|
||||
int result = stream.read();
|
||||
|
||||
CHECK(result == -1);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 0"
|
||||
"read() -> -1");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
SUBCASE("empty input") {
|
||||
upstream.flush();
|
||||
|
||||
char c;
|
||||
size_t result = stream.readBytes(&c, 1);
|
||||
|
||||
CHECK(result == 0);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 0"
|
||||
"readBytes(1) -> 0 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("reads 4 bytes when requested one") {
|
||||
upstream.print("ABCDEFG");
|
||||
|
||||
char c;
|
||||
size_t result = stream.readBytes(&c, 1);
|
||||
|
||||
CHECK(c == 'A');
|
||||
CHECK(result == 1);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 7"
|
||||
"readBytes(4) -> 4");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("copy one byte from buffer") {
|
||||
upstream.print("ABCDEFGH");
|
||||
stream.read(); // load buffer
|
||||
|
||||
char c;
|
||||
size_t result = stream.readBytes(&c, 1);
|
||||
|
||||
CHECK(c == 'B');
|
||||
CHECK(result == 1);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"readBytes(4) -> 4");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("copy content from buffer then bypass buffer") {
|
||||
upstream.print("ABCDEFGH");
|
||||
stream.read(); // load buffer
|
||||
|
||||
char c[8] = {0};
|
||||
size_t result = stream.readBytes(c, 7);
|
||||
|
||||
CHECK(c == std::string("BCDEFGH"));
|
||||
CHECK(result == 7);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"readBytes(4) -> 4"
|
||||
"available() -> 4"
|
||||
"readBytes(4) -> 4");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("copy content from buffer twice") {
|
||||
upstream.print("ABCDEFGH");
|
||||
stream.read(); // load buffer
|
||||
|
||||
char c[8] = {0};
|
||||
size_t result = stream.readBytes(c, 4);
|
||||
|
||||
CHECK(c == std::string("BCDE"));
|
||||
CHECK(result == 4);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"readBytes(4) -> 4"
|
||||
"available() -> 4"
|
||||
"readBytes(4) -> 4");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("read past the end") {
|
||||
upstream.print("A");
|
||||
|
||||
char c;
|
||||
stream.readBytes(&c, 1);
|
||||
size_t result = stream.readBytes(&c, 1);
|
||||
|
||||
CHECK(result == 0);
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 1"
|
||||
"readBytes(1) -> 1"
|
||||
"available() -> 0"
|
||||
"readBytes(1) -> 0 [timeout]");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("flush()") {
|
||||
stream.flush();
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
|
||||
SUBCASE("copy constructor") {
|
||||
upstream.print("ABCDEFGH");
|
||||
bufferedStream.read();
|
||||
|
||||
auto dup = bufferedStream;
|
||||
|
||||
int result = dup.read();
|
||||
|
||||
CHECK(result == 'B');
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 8"
|
||||
"readBytes(4) -> 4");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("No memory") {
|
||||
BasicReadBufferingStream<FailingAllocator> stream(spy, 4);
|
||||
|
||||
SUBCASE("available()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
CHECK(stream.available() == 3);
|
||||
}
|
||||
|
||||
// SUBCASE("capacity()") {
|
||||
// CHECK(stream.capacity() == 0);
|
||||
// }
|
||||
|
||||
SUBCASE("peek()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
int c = stream.peek();
|
||||
|
||||
CHECK(c == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
int c = stream.read();
|
||||
|
||||
CHECK(c == 'A');
|
||||
CHECK(log.str() == "read() -> 65");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
char s[4] = {0};
|
||||
int n = stream.readBytes(s, 3);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(s == std::string("ABC"));
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(3) -> 3");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Real example") {
|
||||
ReadBufferingStream bufferedStream{spy, 64};
|
||||
Stream& stream = bufferedStream;
|
||||
|
||||
upstream.print("{\"helloWorld\":\"Hello World\"}");
|
||||
|
||||
char c[] = "ABCDEFGH";
|
||||
CHECK(stream.readBytes(&c[0], 1) == 1);
|
||||
CHECK(stream.readBytes(&c[1], 1) == 1);
|
||||
CHECK(stream.readBytes(&c[2], 1) == 1);
|
||||
CHECK(stream.readBytes(&c[3], 1) == 1);
|
||||
|
||||
CHECK(c == std::string("{\"heEFGH"));
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() ==
|
||||
"available() -> 28"
|
||||
"readBytes(28) -> 28");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
139
lib/ArduinoStreamUtils/extras/test/ReadLoggingClientTest.cpp
Normal file
139
lib/ArduinoStreamUtils/extras/test/ReadLoggingClientTest.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Clients/MemoryClient.hpp"
|
||||
#include "StreamUtils/Clients/ReadLoggingClient.hpp"
|
||||
#include "StreamUtils/Clients/SpyingClient.hpp"
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("ReadLoggingClient") {
|
||||
MemoryClient target(4);
|
||||
|
||||
StringPrint log;
|
||||
SpyingClient upstreamSpy{target, log};
|
||||
|
||||
StringPrint output;
|
||||
ReadLoggingClient loggingClient{upstreamSpy, output};
|
||||
|
||||
SUBCASE("available()") {
|
||||
target.print("ABC");
|
||||
|
||||
size_t n = loggingClient.available();
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "available() -> 3");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("connect(IPAddress)") {
|
||||
int n = loggingClient.connect(IPAddress("1.2.3.4"), 80);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "connect('1.2.3.4', 80) -> 1");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("connect(const char*)") {
|
||||
int n = loggingClient.connect("1.2.3.4", 80);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "connect('1.2.3.4', 80) -> 1");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("connected()") {
|
||||
uint8_t n = loggingClient.connected();
|
||||
|
||||
CHECK(n == false);
|
||||
CHECK(log.str() == "connected() -> 0");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("stop()") {
|
||||
loggingClient.stop();
|
||||
|
||||
CHECK(log.str() == "stop()");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("operator bool()") {
|
||||
bool n = loggingClient.operator bool();
|
||||
|
||||
CHECK(n == true);
|
||||
CHECK(log.str() == "operator bool() -> true");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
target.print("ABC");
|
||||
|
||||
int n = loggingClient.peek();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
target.print("ABC");
|
||||
|
||||
int n = loggingClient.read();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "read() -> 65");
|
||||
CHECK(output.str() == "A");
|
||||
}
|
||||
|
||||
SUBCASE("read(uint8_t*,size_t)") {
|
||||
target.print("ABC");
|
||||
|
||||
uint8_t s[4] = {0};
|
||||
size_t n = loggingClient.read(s, 4);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "read(4) -> 3 [timeout]");
|
||||
CHECK(output.str() == "ABC");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
target.print("ABC");
|
||||
|
||||
char s[4] = {0};
|
||||
size_t n = loggingClient.readBytes(s, 4);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(output.str() == "ABC");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(4) -> 3 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
int n = loggingClient.write('A');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('A') -> 1");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,size_t)") {
|
||||
int n = loggingClient.write("ABCDEF", 6);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCDEF', 6) -> 4");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("flush()") {
|
||||
loggingClient.flush();
|
||||
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
}
|
||||
89
lib/ArduinoStreamUtils/extras/test/ReadLoggingStreamTest.cpp
Normal file
89
lib/ArduinoStreamUtils/extras/test/ReadLoggingStreamTest.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
#include "StreamUtils/Streams/ReadLoggingStream.hpp"
|
||||
#include "StreamUtils/Streams/SpyingStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("ReadLoggingStream") {
|
||||
MemoryStream upstream(4);
|
||||
|
||||
StringPrint log;
|
||||
SpyingStream upstreamSpy{upstream, log};
|
||||
|
||||
StringPrint output;
|
||||
ReadLoggingStream loggingStream{upstreamSpy, output};
|
||||
|
||||
SUBCASE("available()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
size_t n = loggingStream.available();
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "available() -> 3");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
int n = loggingStream.peek();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
int n = loggingStream.read();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "read() -> 65");
|
||||
CHECK(output.str() == "A");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
char s[4] = {0};
|
||||
size_t n = loggingStream.readBytes(s, 4);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(output.str() == "ABC");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(4) -> 3 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
int n = loggingStream.write('A');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('A') -> 1");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,size_t)") {
|
||||
int n = loggingStream.write("ABCDEF", 6);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCDEF', 6) -> 4");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("flush()") {
|
||||
loggingStream.flush();
|
||||
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Streams/ReadThrottlingStream.hpp"
|
||||
#include "StreamUtils/Streams/StringStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
class SpyingThrottler {
|
||||
public:
|
||||
SpyingThrottler(uint32_t rate) {
|
||||
_log << "C(" << rate << ")";
|
||||
}
|
||||
|
||||
SpyingThrottler(const SpyingThrottler& src) {
|
||||
_log << src._log.str();
|
||||
}
|
||||
|
||||
void throttle() {
|
||||
_log << "T";
|
||||
}
|
||||
|
||||
std::string log() const {
|
||||
return _log.str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::stringstream _log;
|
||||
};
|
||||
|
||||
using ReadThrottlingStream = BasicReadThrottlingStream<SpyingThrottler>;
|
||||
|
||||
TEST_CASE("ReadThrottlingStream") {
|
||||
StringStream upstream;
|
||||
|
||||
ReadThrottlingStream throttledStream{upstream, 4};
|
||||
Stream& stream = throttledStream;
|
||||
const SpyingThrottler& throttler = throttledStream.throttler();
|
||||
|
||||
SUBCASE("available()") {
|
||||
upstream.print("ABCD");
|
||||
CHECK(stream.available() == 4);
|
||||
CHECK(throttler.log() == "C(4)");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
upstream.print("ABCD");
|
||||
int n = stream.read();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(throttler.log() == "C(4)T");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
upstream.print("ABCD");
|
||||
char output[8] = {0};
|
||||
|
||||
SUBCASE("read more than available") {
|
||||
size_t n = stream.readBytes(output, sizeof(output));
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(strcmp("ABCD", output) == 0);
|
||||
CHECK(throttler.log() == "C(4)TTTTT");
|
||||
}
|
||||
|
||||
SUBCASE("read less than available") {
|
||||
size_t n = stream.readBytes(output, 2);
|
||||
|
||||
CHECK(n == 2);
|
||||
CHECK(strcmp("AB", output) == 0);
|
||||
CHECK(throttler.log() == "C(4)TT");
|
||||
}
|
||||
|
||||
SUBCASE("read as many as available") {
|
||||
size_t n = stream.readBytes(output, 4);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(strcmp("ABCD", output) == 0);
|
||||
CHECK(throttler.log() == "C(4)TTTT");
|
||||
}
|
||||
}
|
||||
}
|
||||
36
lib/ArduinoStreamUtils/extras/test/SpyingAllocator.hpp
Normal file
36
lib/ArduinoStreamUtils/extras/test/SpyingAllocator.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "StreamUtils/Ports/DefaultAllocator.hpp"
|
||||
|
||||
class SpyingAllocator {
|
||||
public:
|
||||
SpyingAllocator(Print& log) : _log(&log) {}
|
||||
|
||||
bool forceFail = false;
|
||||
|
||||
void* allocate(size_t n) {
|
||||
void* ptr = forceFail ? 0 : _allocator.allocate(n);
|
||||
_log->print("allocate(");
|
||||
_log->print(n);
|
||||
_log->print(") -> ");
|
||||
_log->print(ptr ? "ptr" : "null");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void deallocate(void* ptr) {
|
||||
_log->print("deallocate(");
|
||||
_log->print(ptr ? "ptr" : "null");
|
||||
_log->print(")");
|
||||
_allocator.deallocate(ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
Print* _log;
|
||||
StreamUtils::DefaultAllocator _allocator;
|
||||
};
|
||||
77
lib/ArduinoStreamUtils/extras/test/StringPrintTest.cpp
Normal file
77
lib/ArduinoStreamUtils/extras/test/StringPrintTest.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("StringPrint") {
|
||||
WHEN("Constructed with no argument") {
|
||||
StringPrint s;
|
||||
|
||||
THEN("str() return an empty String") {
|
||||
CHECK(s.str() == "");
|
||||
}
|
||||
|
||||
THEN("write(uint8_t) appends the string") {
|
||||
s.write('A');
|
||||
s.write('B');
|
||||
CHECK(s.str() == "AB");
|
||||
}
|
||||
|
||||
THEN("write(uint8_t) return 1") {
|
||||
CHECK(s.write('A') == 1);
|
||||
CHECK(s.write('B') == 1);
|
||||
}
|
||||
|
||||
THEN("write(0) return 0") {
|
||||
CHECK(s.write(0) == 0);
|
||||
}
|
||||
|
||||
THEN("write(uint8_t*, size_t) appends the string") {
|
||||
s.write(reinterpret_cast<const uint8_t*>("ABXXX"), 2);
|
||||
s.write(reinterpret_cast<const uint8_t*>("CDEXX"), 3);
|
||||
CHECK(s.str() == "ABCDE");
|
||||
}
|
||||
|
||||
THEN("write(uint8_t*, size_t) return number of chars written") {
|
||||
uint8_t dummy[32] = {1, 2, 3, 0, 5, 6};
|
||||
CHECK(s.write(dummy, 2) == 2);
|
||||
CHECK(s.write(dummy, 3) == 3);
|
||||
CHECK(s.write(dummy, 4) == 3);
|
||||
}
|
||||
|
||||
THEN("str(String) sets the string") {
|
||||
s.str("world!");
|
||||
CHECK(s.str() == "world!");
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("Constructed with string") {
|
||||
StringPrint s("hello");
|
||||
|
||||
THEN("str() return the stirng passed to contructor") {
|
||||
CHECK(s.str() == "hello");
|
||||
}
|
||||
|
||||
THEN("write(uint8_t) appends the string") {
|
||||
s.write('A');
|
||||
s.write('B');
|
||||
CHECK(s.str() == "helloAB");
|
||||
}
|
||||
|
||||
THEN("write(uint8_t*, size_t) appends the string") {
|
||||
s.write(reinterpret_cast<const uint8_t*>("ABXXX"), 2);
|
||||
s.write(reinterpret_cast<const uint8_t*>("CDEXX"), 3);
|
||||
CHECK(s.str() == "helloABCDE");
|
||||
}
|
||||
|
||||
THEN("str(String) replaces the string") {
|
||||
s.str("world!");
|
||||
CHECK(s.str() == "world!");
|
||||
}
|
||||
}
|
||||
}
|
||||
116
lib/ArduinoStreamUtils/extras/test/StringStreamTest.cpp
Normal file
116
lib/ArduinoStreamUtils/extras/test/StringStreamTest.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "StreamUtils/Streams/StringStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("StringStream") {
|
||||
WHEN("Constructed with no argument") {
|
||||
StringStream s;
|
||||
|
||||
THEN("str() return an empty String") {
|
||||
CHECK(s.str() == "");
|
||||
}
|
||||
|
||||
THEN("write(uint8_t) appends the string") {
|
||||
s.write('A');
|
||||
s.write('B');
|
||||
CHECK(s.str() == "AB");
|
||||
}
|
||||
|
||||
THEN("write(uint8_t) return 1") {
|
||||
CHECK(s.write('A') == 1);
|
||||
CHECK(s.write('B') == 1);
|
||||
}
|
||||
|
||||
THEN("write(0) return 0") {
|
||||
CHECK(s.write(0) == 0);
|
||||
}
|
||||
|
||||
THEN("write(uint8_t*, size_t) appends the string") {
|
||||
s.write(reinterpret_cast<const uint8_t*>("ABXXX"), 2);
|
||||
s.write(reinterpret_cast<const uint8_t*>("CDEXX"), 3);
|
||||
CHECK(s.str() == "ABCDE");
|
||||
}
|
||||
|
||||
THEN("write(uint8_t*, size_t) return number of chars written") {
|
||||
uint8_t dummy[32] = {1, 2, 3, 0, 5, 6};
|
||||
CHECK(s.write(dummy, 2) == 2);
|
||||
CHECK(s.write(dummy, 3) == 3);
|
||||
CHECK(s.write(dummy, 4) == 3);
|
||||
}
|
||||
|
||||
THEN("str(String) sets the string") {
|
||||
s.str("world!");
|
||||
CHECK(s.str() == "world!");
|
||||
}
|
||||
|
||||
THEN("available() returns 0") {
|
||||
CHECK(s.available() == 0);
|
||||
}
|
||||
|
||||
THEN("peek() return -1") {
|
||||
CHECK(s.peek() == -1);
|
||||
}
|
||||
|
||||
THEN("peek() return -1") {
|
||||
CHECK(s.read() == -1);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("Constructed with string") {
|
||||
StringStream s("hello");
|
||||
|
||||
THEN("str() returns the string passed to contructor") {
|
||||
CHECK(s.str() == "hello");
|
||||
}
|
||||
|
||||
THEN("available() returns the length passed to the constructor") {
|
||||
CHECK(s.available() == 5);
|
||||
}
|
||||
|
||||
THEN("write(uint8_t) appends the string") {
|
||||
s.write('A');
|
||||
s.write('B');
|
||||
CHECK(s.str() == "helloAB");
|
||||
}
|
||||
|
||||
THEN("write(uint8_t*, size_t) appends the string") {
|
||||
s.write(reinterpret_cast<const uint8_t*>("ABXXX"), 2);
|
||||
s.write(reinterpret_cast<const uint8_t*>("CDEXX"), 3);
|
||||
CHECK(s.str() == "helloABCDE");
|
||||
}
|
||||
|
||||
THEN("str(String) replaces the string") {
|
||||
s.str("world!");
|
||||
CHECK(s.str() == "world!");
|
||||
}
|
||||
|
||||
THEN("peek() return the first char") {
|
||||
CHECK(s.peek() == 'h');
|
||||
}
|
||||
|
||||
THEN("peek() return the next char") {
|
||||
CHECK(s.read() == 'h');
|
||||
CHECK(s.read() == 'e');
|
||||
}
|
||||
|
||||
THEN("readBytes() can return the begining of the string") {
|
||||
char buffer[32] = {0};
|
||||
CHECK(s.readBytes(buffer, 3) == 3);
|
||||
CHECK(buffer == std::string("hel"));
|
||||
CHECK(s.available() == 2);
|
||||
}
|
||||
|
||||
THEN("readBytes() can return the whole string") {
|
||||
char buffer[32] = {0};
|
||||
CHECK(s.readBytes(buffer, 32) == 5);
|
||||
CHECK(buffer == std::string("hello"));
|
||||
CHECK(s.available() == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
104
lib/ArduinoStreamUtils/extras/test/WaitingPrintTest.cpp
Normal file
104
lib/ArduinoStreamUtils/extras/test/WaitingPrintTest.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
#include "StreamUtils/Prints/WaitingPrint.hpp"
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
#include "StreamUtils/Streams/SpyingStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("WaitingPrint") {
|
||||
MemoryStream upstream(4);
|
||||
|
||||
StringPrint log;
|
||||
SpyingStream spy{upstream, log};
|
||||
WaitingPrint stream{static_cast<Print&>(spy), [&spy]() { spy.flush(); }};
|
||||
|
||||
SUBCASE("write(char*, size_t)") {
|
||||
SUBCASE("no need to wait") {
|
||||
CHECK(stream.print("ABC") == 3);
|
||||
|
||||
CHECK(log.str() == "write('ABC', 3) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("need to wait") {
|
||||
CHECK(stream.print("ABCDEFG") == 7);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('ABCDEFG', 7) -> 4"
|
||||
"flush()"
|
||||
"write('EFG', 3) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("need to wait twice") {
|
||||
CHECK(stream.print("ABCDEFGIJKL") == 11);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('ABCDEFGIJKL', 11) -> 4"
|
||||
"flush()"
|
||||
"write('EFGIJKL', 7) -> 4"
|
||||
"flush()"
|
||||
"write('JKL', 3) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't wait when timeout is 0") {
|
||||
stream.setTimeout(0);
|
||||
|
||||
CHECK(stream.print("ABCDEFG") == 4);
|
||||
|
||||
CHECK(log.str() == "write('ABCDEFG', 7) -> 4");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
SUBCASE("no need to wait") {
|
||||
CHECK(stream.write('A') == 1);
|
||||
CHECK(stream.write('B') == 1);
|
||||
CHECK(stream.write('C') == 1);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('A') -> 1"
|
||||
"write('B') -> 1"
|
||||
"write('C') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("need to wait") {
|
||||
for (int i = 0; i < 7; i++)
|
||||
CHECK(stream.write("ABCDEFG"[i]) == 1);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('A') -> 1"
|
||||
"write('B') -> 1"
|
||||
"write('C') -> 1"
|
||||
"write('D') -> 1"
|
||||
"write('E') -> 0"
|
||||
"flush()"
|
||||
"write('E') -> 1"
|
||||
"write('F') -> 1"
|
||||
"write('G') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't wait when timeout is 0") {
|
||||
stream.setTimeout(0);
|
||||
|
||||
CHECK(stream.write('A') == 1);
|
||||
CHECK(stream.write('B') == 1);
|
||||
CHECK(stream.write('C') == 1);
|
||||
CHECK(stream.write('D') == 1);
|
||||
CHECK(stream.write('E') == 0);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('A') -> 1"
|
||||
"write('B') -> 1"
|
||||
"write('C') -> 1"
|
||||
"write('D') -> 1"
|
||||
"write('E') -> 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
203
lib/ArduinoStreamUtils/extras/test/WriteBufferingClientTest.cpp
Normal file
203
lib/ArduinoStreamUtils/extras/test/WriteBufferingClientTest.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Clients/MemoryClient.hpp"
|
||||
#include "StreamUtils/Clients/SpyingClient.hpp"
|
||||
#include "StreamUtils/Clients/WriteBufferingClient.hpp"
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("WriteBufferingClient") {
|
||||
MemoryClient target(64);
|
||||
|
||||
StringPrint log;
|
||||
SpyingClient spy{target, log};
|
||||
|
||||
GIVEN("capacity is 4") {
|
||||
WriteBufferingClient bufferingClient{spy, 4};
|
||||
|
||||
SUBCASE("available()") {
|
||||
target.print("ABC");
|
||||
|
||||
CHECK(bufferingClient.available() == 3);
|
||||
CHECK(log.str() == "available() -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("connect(IPAddress)") {
|
||||
int n = bufferingClient.connect(IPAddress("1.2.3.4"), 80);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "connect('1.2.3.4', 80) -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("connect(const char*)") {
|
||||
int n = bufferingClient.connect("1.2.3.4", 80);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "connect('1.2.3.4', 80) -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("connected()") {
|
||||
uint8_t n = bufferingClient.connected();
|
||||
|
||||
CHECK(n == false);
|
||||
CHECK(log.str() == "connected() -> 0");
|
||||
}
|
||||
|
||||
SUBCASE("stop()") {
|
||||
bufferingClient.write("ABC", 3);
|
||||
bufferingClient.stop();
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('ABC', 3) -> 3"
|
||||
"stop()");
|
||||
}
|
||||
|
||||
SUBCASE("operator bool()") {
|
||||
bool n = bufferingClient.operator bool();
|
||||
|
||||
CHECK(n == true);
|
||||
CHECK(log.str() == "operator bool() -> true");
|
||||
}
|
||||
|
||||
SUBCASE("flush() forwards to target)") {
|
||||
bufferingClient.flush();
|
||||
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
|
||||
SUBCASE("flush() calls write() and flush()") {
|
||||
bufferingClient.write("ABC", 3);
|
||||
bufferingClient.flush();
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('ABC', 3) -> 3"
|
||||
"flush()");
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
target.print("ABC");
|
||||
|
||||
CHECK(bufferingClient.peek() == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
target.print("ABC");
|
||||
|
||||
CHECK(bufferingClient.read() == 'A');
|
||||
CHECK(log.str() == "read() -> 65");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
target.print("ABC");
|
||||
|
||||
char s[4] = {0};
|
||||
int n = bufferingClient.readBytes(s, 3);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(s == std::string("ABC"));
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(3) -> 3");
|
||||
#endif
|
||||
}
|
||||
|
||||
GIVEN("the buffer is empty") {
|
||||
SUBCASE("write(uint8_t)") {
|
||||
int n = bufferingClient.write('A');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("write(uint8_t) should flush") {
|
||||
bufferingClient.write('A');
|
||||
bufferingClient.write('B');
|
||||
bufferingClient.write('C');
|
||||
bufferingClient.write('D');
|
||||
bufferingClient.write('E');
|
||||
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,3) goes in buffer") {
|
||||
size_t n = bufferingClient.write("ABC", 3);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,4) bypasses buffer") {
|
||||
size_t n = bufferingClient.write("ABCD", 4);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
SUBCASE("write(char*,2) bypasses buffer") {
|
||||
size_t n = bufferingClient.write("ABCD", 4);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("one byte in the buffer") {
|
||||
bufferingClient.write('A');
|
||||
|
||||
SUBCASE("write(char*,3) goes in buffer and flush") {
|
||||
size_t n = bufferingClient.write("BCD", 3);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,7) bypasses") {
|
||||
size_t n = bufferingClient.write("BCDEFGH", 7);
|
||||
|
||||
CHECK(n == 7);
|
||||
CHECK(log.str() ==
|
||||
"write('ABCD', 4) -> 4"
|
||||
"write('EFGH', 4) -> 4");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("capacity is 0") {
|
||||
WriteBufferingClient bufferingClient{spy, 0};
|
||||
|
||||
SUBCASE("write(uint8_t) forwards to target") {
|
||||
int n = bufferingClient.write('X');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('X') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,1) forwards to target") {
|
||||
int n = bufferingClient.write("A", 1);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('A', 1) -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("flush() forwards to target") {
|
||||
bufferingClient.flush();
|
||||
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Destructor should flush") {
|
||||
{
|
||||
WriteBufferingClient bufferingClient{spy, 10};
|
||||
bufferingClient.write("ABC", 3);
|
||||
}
|
||||
|
||||
CHECK(log.str() == "write('ABC', 3) -> 3");
|
||||
}
|
||||
}
|
||||
166
lib/ArduinoStreamUtils/extras/test/WriteBufferingStreamTest.cpp
Normal file
166
lib/ArduinoStreamUtils/extras/test/WriteBufferingStreamTest.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
#include "StreamUtils/Streams/SpyingStream.hpp"
|
||||
#include "StreamUtils/Streams/WriteBufferingStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("WriteBufferingStream") {
|
||||
MemoryStream upstream(64);
|
||||
|
||||
StringPrint log;
|
||||
SpyingStream spy{upstream, log};
|
||||
|
||||
GIVEN("capacity is 4") {
|
||||
WriteBufferingStream stream{spy, 4};
|
||||
|
||||
SUBCASE("available()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
CHECK(stream.available() == 3);
|
||||
CHECK(log.str() == "available() -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("flush() forwards to upstream)") {
|
||||
stream.flush();
|
||||
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
|
||||
SUBCASE("flush() calls write() and flush()") {
|
||||
stream.write("ABC", 3);
|
||||
stream.flush();
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('ABC', 3) -> 3"
|
||||
"flush()");
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
CHECK(stream.peek() == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
CHECK(stream.read() == 'A');
|
||||
CHECK(log.str() == "read() -> 65");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
char s[4] = {0};
|
||||
int n = stream.readBytes(s, 3);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(s == std::string("ABC"));
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(3) -> 3");
|
||||
#endif
|
||||
}
|
||||
|
||||
GIVEN("the buffer is empty") {
|
||||
SUBCASE("write(uint8_t)") {
|
||||
int n = stream.write('A');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("write(uint8_t) should flush") {
|
||||
stream.write('A');
|
||||
stream.write('B');
|
||||
stream.write('C');
|
||||
stream.write('D');
|
||||
stream.write('E');
|
||||
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,3) goes in buffer") {
|
||||
size_t n = stream.write("ABC", 3);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,4) bypasses buffer") {
|
||||
size_t n = stream.write("ABCD", 4);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
SUBCASE("write(char*,2) bypasses buffer") {
|
||||
size_t n = stream.write("ABCD", 4);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("one byte in the buffer") {
|
||||
stream.write('A');
|
||||
|
||||
SUBCASE("write(char*,3) goes in buffer and flush") {
|
||||
size_t n = stream.write("BCD", 3);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "write('ABCD', 4) -> 4");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,7) bypasses") {
|
||||
size_t n = stream.write("BCDEFGH", 7);
|
||||
|
||||
CHECK(n == 7);
|
||||
CHECK(log.str() ==
|
||||
"write('ABCD', 4) -> 4"
|
||||
"write('EFGH', 4) -> 4");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("capacity is 0") {
|
||||
WriteBufferingStream stream{spy, 0};
|
||||
|
||||
SUBCASE("write(uint8_t) forwards to upstream") {
|
||||
int n = stream.write('X');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('X') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,1) forwards to upstream") {
|
||||
int n = stream.write("A", 1);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('A', 1) -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("flush() forwards to upstream") {
|
||||
stream.flush();
|
||||
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("Destructor should flush") {
|
||||
{
|
||||
WriteBufferingStream stream{spy, 10};
|
||||
stream.write("ABC", 3);
|
||||
}
|
||||
|
||||
CHECK(log.str() == "write('ABC', 3) -> 3");
|
||||
}
|
||||
}
|
||||
140
lib/ArduinoStreamUtils/extras/test/WriteLoggingClientTest.cpp
Normal file
140
lib/ArduinoStreamUtils/extras/test/WriteLoggingClientTest.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Clients/MemoryClient.hpp"
|
||||
#include "StreamUtils/Clients/SpyingClient.hpp"
|
||||
#include "StreamUtils/Clients/WriteLoggingClient.hpp"
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("WriteLoggingClient") {
|
||||
MemoryClient target(4);
|
||||
|
||||
StringPrint log;
|
||||
SpyingClient spy{target, log};
|
||||
|
||||
StringPrint output;
|
||||
WriteLoggingClient loggingClient{spy, output};
|
||||
|
||||
SUBCASE("available()") {
|
||||
target.print("ABC");
|
||||
|
||||
size_t n = loggingClient.available();
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "available() -> 3");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("connect(IPAddress)") {
|
||||
int n = loggingClient.connect(IPAddress("1.2.3.4"), 80);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "connect('1.2.3.4', 80) -> 1");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("connect(const char*)") {
|
||||
int n = loggingClient.connect("1.2.3.4", 80);
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "connect('1.2.3.4', 80) -> 1");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("connected()") {
|
||||
uint8_t n = loggingClient.connected();
|
||||
|
||||
CHECK(n == false);
|
||||
CHECK(log.str() == "connected() -> 0");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("stop()") {
|
||||
loggingClient.stop();
|
||||
|
||||
CHECK(log.str() == "stop()");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("operator bool()") {
|
||||
bool n = loggingClient.operator bool();
|
||||
|
||||
CHECK(n == true);
|
||||
CHECK(log.str() == "operator bool() -> true");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
target.print("ABC");
|
||||
|
||||
int n = loggingClient.peek();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
target.print("ABC");
|
||||
|
||||
int n = loggingClient.read();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "read() -> 65");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("read(uint8_t*,size_t)") {
|
||||
target.print("ABC");
|
||||
|
||||
uint8_t s[4] = {0};
|
||||
size_t n = loggingClient.read(s, 4);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "read(4) -> 3 [timeout]");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
target.print("ABC");
|
||||
|
||||
char s[4] = {0};
|
||||
size_t n = loggingClient.readBytes(s, 4);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(output.str() == "");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(4) -> 3 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
int n = loggingClient.write('A');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('A') -> 1");
|
||||
CHECK(output.str() == "A");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,size_t)") {
|
||||
int n = loggingClient.write("ABCDEF", 6);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCDEF', 6) -> 4");
|
||||
CHECK(output.str() == "ABCD");
|
||||
}
|
||||
|
||||
SUBCASE("flush()") {
|
||||
loggingClient.flush();
|
||||
|
||||
CHECK(output.str() == "");
|
||||
CHECK(log.str() == "flush()");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
#include "StreamUtils/Streams/SpyingStream.hpp"
|
||||
#include "StreamUtils/Streams/WriteLoggingStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("WriteLoggingStream") {
|
||||
MemoryStream upstream(4);
|
||||
|
||||
StringPrint log;
|
||||
SpyingStream upstreamSpy{upstream, log};
|
||||
|
||||
StringPrint output;
|
||||
WriteLoggingStream loggingStream{upstreamSpy, output};
|
||||
|
||||
SUBCASE("available()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
size_t n = loggingStream.available();
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(log.str() == "available() -> 3");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("peek()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
int n = loggingStream.peek();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "peek() -> 65");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("read()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
int n = loggingStream.read();
|
||||
|
||||
CHECK(n == 'A');
|
||||
CHECK(log.str() == "read() -> 65");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
|
||||
SUBCASE("readBytes()") {
|
||||
upstream.print("ABC");
|
||||
|
||||
char s[4] = {0};
|
||||
size_t n = loggingStream.readBytes(s, 4);
|
||||
|
||||
CHECK(n == 3);
|
||||
CHECK(output.str() == "");
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
CHECK(log.str() == "readBytes(4) -> 3 [timeout]");
|
||||
#endif
|
||||
}
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
int n = loggingStream.write('A');
|
||||
|
||||
CHECK(n == 1);
|
||||
CHECK(log.str() == "write('A') -> 1");
|
||||
CHECK(output.str() == "A");
|
||||
}
|
||||
|
||||
SUBCASE("write(char*,size_t)") {
|
||||
int n = loggingStream.write("ABCDEF", 6);
|
||||
|
||||
CHECK(n == 4);
|
||||
CHECK(log.str() == "write('ABCDEF', 6) -> 4");
|
||||
CHECK(output.str() == "ABCD");
|
||||
}
|
||||
|
||||
SUBCASE("flush()") {
|
||||
loggingStream.flush();
|
||||
|
||||
CHECK(log.str() == "flush()");
|
||||
CHECK(output.str() == "");
|
||||
}
|
||||
}
|
||||
104
lib/ArduinoStreamUtils/extras/test/WriteWaitingClientTest.cpp
Normal file
104
lib/ArduinoStreamUtils/extras/test/WriteWaitingClientTest.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Clients/MemoryClient.hpp"
|
||||
#include "StreamUtils/Clients/SpyingClient.hpp"
|
||||
#include "StreamUtils/Clients/WriteWaitingClient.hpp"
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("WriteWaitingClient") {
|
||||
MemoryClient upstream(4);
|
||||
|
||||
StringPrint log;
|
||||
SpyingClient spy{upstream, log};
|
||||
WriteWaitingClient client{spy, [&spy]() { spy.flush(); }};
|
||||
|
||||
SUBCASE("write(char*, size_t)") {
|
||||
SUBCASE("no need to wait") {
|
||||
CHECK(client.print("ABC") == 3);
|
||||
|
||||
CHECK(log.str() == "write('ABC', 3) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("need to wait") {
|
||||
CHECK(client.print("ABCDEFG") == 7);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('ABCDEFG', 7) -> 4"
|
||||
"flush()"
|
||||
"write('EFG', 3) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("need to wait twice") {
|
||||
CHECK(client.print("ABCDEFGIJKL") == 11);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('ABCDEFGIJKL', 11) -> 4"
|
||||
"flush()"
|
||||
"write('EFGIJKL', 7) -> 4"
|
||||
"flush()"
|
||||
"write('JKL', 3) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't wait when timeout is 0") {
|
||||
client.setTimeout(0);
|
||||
|
||||
CHECK(client.print("ABCDEFG") == 4);
|
||||
|
||||
CHECK(log.str() == "write('ABCDEFG', 7) -> 4");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
SUBCASE("no need to wait") {
|
||||
CHECK(client.write('A') == 1);
|
||||
CHECK(client.write('B') == 1);
|
||||
CHECK(client.write('C') == 1);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('A') -> 1"
|
||||
"write('B') -> 1"
|
||||
"write('C') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("need to wait") {
|
||||
for (int i = 0; i < 7; i++)
|
||||
CHECK(client.write("ABCDEFG"[i]) == 1);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('A') -> 1"
|
||||
"write('B') -> 1"
|
||||
"write('C') -> 1"
|
||||
"write('D') -> 1"
|
||||
"write('E') -> 0"
|
||||
"flush()"
|
||||
"write('E') -> 1"
|
||||
"write('F') -> 1"
|
||||
"write('G') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't wait when timeout is 0") {
|
||||
client.setTimeout(0);
|
||||
|
||||
CHECK(client.write('A') == 1);
|
||||
CHECK(client.write('B') == 1);
|
||||
CHECK(client.write('C') == 1);
|
||||
CHECK(client.write('D') == 1);
|
||||
CHECK(client.write('E') == 0);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('A') -> 1"
|
||||
"write('B') -> 1"
|
||||
"write('C') -> 1"
|
||||
"write('D') -> 1"
|
||||
"write('E') -> 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
104
lib/ArduinoStreamUtils/extras/test/WriteWaitingStreamTest.cpp
Normal file
104
lib/ArduinoStreamUtils/extras/test/WriteWaitingStreamTest.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "FailingAllocator.hpp"
|
||||
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
#include "StreamUtils/Streams/MemoryStream.hpp"
|
||||
#include "StreamUtils/Streams/SpyingStream.hpp"
|
||||
#include "StreamUtils/Streams/WriteWaitingStream.hpp"
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
using namespace StreamUtils;
|
||||
|
||||
TEST_CASE("WriteWaitingStream") {
|
||||
MemoryStream upstream(4);
|
||||
|
||||
StringPrint log;
|
||||
SpyingStream spy{upstream, log};
|
||||
WriteWaitingStream stream{spy, [&spy]() { spy.flush(); }};
|
||||
|
||||
SUBCASE("write(char*, size_t)") {
|
||||
SUBCASE("no need to wait") {
|
||||
CHECK(stream.print("ABC") == 3);
|
||||
|
||||
CHECK(log.str() == "write('ABC', 3) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("need to wait") {
|
||||
CHECK(stream.print("ABCDEFG") == 7);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('ABCDEFG', 7) -> 4"
|
||||
"flush()"
|
||||
"write('EFG', 3) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("need to wait twice") {
|
||||
CHECK(stream.print("ABCDEFGIJKL") == 11);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('ABCDEFGIJKL', 11) -> 4"
|
||||
"flush()"
|
||||
"write('EFGIJKL', 7) -> 4"
|
||||
"flush()"
|
||||
"write('JKL', 3) -> 3");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't wait when timeout is 0") {
|
||||
stream.setTimeout(0);
|
||||
|
||||
CHECK(stream.print("ABCDEFG") == 4);
|
||||
|
||||
CHECK(log.str() == "write('ABCDEFG', 7) -> 4");
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("write(char)") {
|
||||
SUBCASE("no need to wait") {
|
||||
CHECK(stream.write('A') == 1);
|
||||
CHECK(stream.write('B') == 1);
|
||||
CHECK(stream.write('C') == 1);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('A') -> 1"
|
||||
"write('B') -> 1"
|
||||
"write('C') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("need to wait") {
|
||||
for (int i = 0; i < 7; i++)
|
||||
CHECK(stream.write("ABCDEFG"[i]) == 1);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('A') -> 1"
|
||||
"write('B') -> 1"
|
||||
"write('C') -> 1"
|
||||
"write('D') -> 1"
|
||||
"write('E') -> 0"
|
||||
"flush()"
|
||||
"write('E') -> 1"
|
||||
"write('F') -> 1"
|
||||
"write('G') -> 1");
|
||||
}
|
||||
|
||||
SUBCASE("doesn't wait when timeout is 0") {
|
||||
stream.setTimeout(0);
|
||||
|
||||
CHECK(stream.write('A') == 1);
|
||||
CHECK(stream.write('B') == 1);
|
||||
CHECK(stream.write('C') == 1);
|
||||
CHECK(stream.write('D') == 1);
|
||||
CHECK(stream.write('E') == 0);
|
||||
|
||||
CHECK(log.str() ==
|
||||
"write('A') -> 1"
|
||||
"write('B') -> 1"
|
||||
"write('C') -> 1"
|
||||
"write('D') -> 1"
|
||||
"write('E') -> 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
18
lib/ArduinoStreamUtils/extras/test/cores/avr/Arduino.h
Normal file
18
lib/ArduinoStreamUtils/extras/test/cores/avr/Arduino.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
#include <Print.h>
|
||||
#include <Stream.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
inline unsigned long millis() {
|
||||
return static_cast<unsigned long>(time(NULL));
|
||||
}
|
||||
|
||||
inline void yield() {}
|
||||
22
lib/ArduinoStreamUtils/extras/test/cores/avr/CMakeLists.txt
Normal file
22
lib/ArduinoStreamUtils/extras/test/cores/avr/CMakeLists.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
# StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
# Copyright Benoit Blanchon 2019-2021
|
||||
# MIT License
|
||||
|
||||
add_library(AvrCore
|
||||
Client.h
|
||||
EEPROM.cpp
|
||||
EEPROM.h
|
||||
Print.h
|
||||
Stream.h
|
||||
WString.h
|
||||
)
|
||||
|
||||
target_include_directories(AvrCore
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(AvrCore
|
||||
PUBLIC
|
||||
ARDUINO_ARCH_AVR
|
||||
)
|
||||
27
lib/ArduinoStreamUtils/extras/test/cores/avr/Client.h
Normal file
27
lib/ArduinoStreamUtils/extras/test/cores/avr/Client.h
Normal file
@@ -0,0 +1,27 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "WString.h"
|
||||
|
||||
using IPAddress = String;
|
||||
|
||||
struct Client : Stream {
|
||||
virtual int connect(IPAddress ip, uint16_t port) = 0;
|
||||
virtual int connect(const char *host, uint16_t port) = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual operator bool() = 0;
|
||||
|
||||
// Already in Stream
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) = 0;
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
|
||||
// Curiously not in Stream
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
};
|
||||
12
lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.cpp
Normal file
12
lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "EEPROM.h"
|
||||
|
||||
EEPROMClass EEPROM;
|
||||
static uint8_t data[512];
|
||||
|
||||
uint8_t EEPROMClass::read(int address) {
|
||||
return data[address];
|
||||
}
|
||||
|
||||
void EEPROMClass::update(int address, uint8_t value) {
|
||||
data[address] = value;
|
||||
}
|
||||
12
lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.h
Normal file
12
lib/ArduinoStreamUtils/extras/test/cores/avr/EEPROM.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class EEPROMClass {
|
||||
public:
|
||||
uint8_t read(int);
|
||||
void update(int, uint8_t);
|
||||
// void write(int, uint8_t); <- it exists but we want to use update() instead
|
||||
};
|
||||
|
||||
extern EEPROMClass EEPROM;
|
||||
42
lib/ArduinoStreamUtils/extras/test/cores/avr/Print.h
Normal file
42
lib/ArduinoStreamUtils/extras/test/cores/avr/Print.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
struct Print {
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
|
||||
virtual size_t write(uint8_t data) = 0;
|
||||
virtual void flush() {}
|
||||
|
||||
size_t write(const char *buffer, size_t size) {
|
||||
return write((const uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
size_t print(const String &s) {
|
||||
return write(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
size_t print(const char *s) {
|
||||
return write(s, std::strlen(s));
|
||||
}
|
||||
|
||||
size_t println() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t print(const T &value) {
|
||||
return print(String(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t println(const T &value) {
|
||||
return print(value);
|
||||
}
|
||||
};
|
||||
41
lib/ArduinoStreamUtils/extras/test/cores/avr/Stream.h
Normal file
41
lib/ArduinoStreamUtils/extras/test/cores/avr/Stream.h
Normal file
@@ -0,0 +1,41 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
struct Stream : Print {
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
|
||||
size_t readBytes(char *buffer, size_t length) {
|
||||
size_t count = 0;
|
||||
while (count < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0)
|
||||
break;
|
||||
*buffer++ = (char)c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
String readString() {
|
||||
String result;
|
||||
int c;
|
||||
while ((c = timedRead()) >= 0) {
|
||||
result += static_cast<char>(c);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void setTimeout(unsigned long) {}
|
||||
|
||||
protected:
|
||||
int timedRead() {
|
||||
return read();
|
||||
}
|
||||
};
|
||||
43
lib/ArduinoStreamUtils/extras/test/cores/avr/WString.h
Normal file
43
lib/ArduinoStreamUtils/extras/test/cores/avr/WString.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class String : private std::string {
|
||||
public:
|
||||
String() {}
|
||||
String(const String& s) : std::string(s) {}
|
||||
String(String&& s) : std::string(std::move(s)) {}
|
||||
String(const char* s) : std::string(s) {}
|
||||
String(int n) : std::string(std::to_string(n)) {}
|
||||
|
||||
String& operator=(const String& rhs) {
|
||||
std::string::operator=(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
using std::string::c_str;
|
||||
using std::string::length;
|
||||
using std::string::operator+=;
|
||||
using std::string::operator[];
|
||||
|
||||
void remove(unsigned int index, unsigned int count) {
|
||||
erase(begin() + index, begin() + index + count);
|
||||
}
|
||||
|
||||
void toCharArray(char* buf, unsigned int bufsize,
|
||||
unsigned int index = 0) const {
|
||||
copy(buf, bufsize, index);
|
||||
}
|
||||
|
||||
friend bool operator==(const String& lhs, const char* rhs) {
|
||||
return static_cast<const std::string&>(lhs) == rhs;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const String& rhs) {
|
||||
return lhs << static_cast<const std::string&>(rhs);
|
||||
}
|
||||
};
|
||||
18
lib/ArduinoStreamUtils/extras/test/cores/esp32/Arduino.h
Normal file
18
lib/ArduinoStreamUtils/extras/test/cores/esp32/Arduino.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
#include <Print.h>
|
||||
#include <Stream.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
inline unsigned long millis() {
|
||||
return static_cast<unsigned long>(time(NULL));
|
||||
}
|
||||
|
||||
inline void yield() {}
|
||||
@@ -0,0 +1,22 @@
|
||||
# StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
# Copyright Benoit Blanchon 2019-2021
|
||||
# MIT License
|
||||
|
||||
add_library(Esp32Core
|
||||
Client.h
|
||||
EEPROM.cpp
|
||||
EEPROM.h
|
||||
Print.h
|
||||
Stream.h
|
||||
WString.h
|
||||
)
|
||||
|
||||
target_include_directories(Esp32Core
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(Esp32Core
|
||||
PUBLIC
|
||||
ARDUINO_ARCH_ESP32
|
||||
)
|
||||
26
lib/ArduinoStreamUtils/extras/test/cores/esp32/Client.h
Normal file
26
lib/ArduinoStreamUtils/extras/test/cores/esp32/Client.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "WString.h"
|
||||
|
||||
using IPAddress = String;
|
||||
|
||||
class Client : public Stream {
|
||||
public:
|
||||
virtual int connect(IPAddress ip, uint16_t port) = 0;
|
||||
virtual int connect(const char *host, uint16_t port) = 0;
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) = 0;
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual operator bool() = 0;
|
||||
};
|
||||
20
lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.cpp
Normal file
20
lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "EEPROM.h"
|
||||
|
||||
#include <string.h> // memcpy
|
||||
|
||||
EEPROMClass EEPROM;
|
||||
static uint8_t commitedData[512];
|
||||
static uint8_t pendingData[512];
|
||||
|
||||
uint8_t EEPROMClass::read(int address) {
|
||||
return commitedData[address];
|
||||
}
|
||||
|
||||
void EEPROMClass::write(int address, uint8_t value) {
|
||||
pendingData[address] = value;
|
||||
}
|
||||
|
||||
bool EEPROMClass::commit() {
|
||||
memcpy(commitedData, pendingData, 512);
|
||||
return true;
|
||||
}
|
||||
12
lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.h
Normal file
12
lib/ArduinoStreamUtils/extras/test/cores/esp32/EEPROM.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class EEPROMClass {
|
||||
public:
|
||||
uint8_t read(int);
|
||||
void write(int, uint8_t);
|
||||
bool commit();
|
||||
};
|
||||
|
||||
extern EEPROMClass EEPROM;
|
||||
42
lib/ArduinoStreamUtils/extras/test/cores/esp32/Print.h
Normal file
42
lib/ArduinoStreamUtils/extras/test/cores/esp32/Print.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
|
||||
struct Print {
|
||||
virtual ~Print() {}
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
|
||||
virtual size_t write(uint8_t data) = 0;
|
||||
|
||||
size_t write(const char *buffer, size_t size) {
|
||||
return write((const uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
size_t print(const String &s) {
|
||||
return write(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
size_t print(const char *s) {
|
||||
return write(s, std::strlen(s));
|
||||
}
|
||||
|
||||
size_t println() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t print(const T &value) {
|
||||
return print(String(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t println(const T &value) {
|
||||
return print(value);
|
||||
}
|
||||
};
|
||||
48
lib/ArduinoStreamUtils/extras/test/cores/esp32/Stream.h
Normal file
48
lib/ArduinoStreamUtils/extras/test/cores/esp32/Stream.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
struct Stream : Print {
|
||||
virtual ~Stream() {}
|
||||
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
virtual size_t readBytes(char *buffer, size_t length) {
|
||||
size_t count = 0;
|
||||
while (count < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0)
|
||||
break;
|
||||
*buffer++ = (char)c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
virtual size_t readBytes(uint8_t *buffer, size_t length) {
|
||||
return readBytes((char *)buffer, length);
|
||||
}
|
||||
|
||||
virtual String readString() {
|
||||
String result;
|
||||
int c;
|
||||
while ((c = timedRead()) >= 0) {
|
||||
result += c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void setTimeout(unsigned long) {}
|
||||
|
||||
protected:
|
||||
int timedRead() {
|
||||
return read();
|
||||
}
|
||||
};
|
||||
5
lib/ArduinoStreamUtils/extras/test/cores/esp32/WString.h
Normal file
5
lib/ArduinoStreamUtils/extras/test/cores/esp32/WString.h
Normal file
@@ -0,0 +1,5 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "../avr/WString.h"
|
||||
18
lib/ArduinoStreamUtils/extras/test/cores/esp8266/Arduino.h
Normal file
18
lib/ArduinoStreamUtils/extras/test/cores/esp8266/Arduino.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
#include <Print.h>
|
||||
#include <Stream.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
inline unsigned long millis() {
|
||||
return static_cast<unsigned long>(time(NULL));
|
||||
}
|
||||
|
||||
inline void yield() {}
|
||||
@@ -0,0 +1,22 @@
|
||||
# StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
# Copyright Benoit Blanchon 2019-2021
|
||||
# MIT License
|
||||
|
||||
add_library(Esp8266Core
|
||||
Client.h
|
||||
EEPROM.cpp
|
||||
EEPROM.h
|
||||
Print.h
|
||||
Stream.h
|
||||
WString.h
|
||||
)
|
||||
|
||||
target_include_directories(Esp8266Core
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(Esp8266Core
|
||||
PUBLIC
|
||||
ARDUINO_ARCH_ESP8266
|
||||
)
|
||||
26
lib/ArduinoStreamUtils/extras/test/cores/esp8266/Client.h
Normal file
26
lib/ArduinoStreamUtils/extras/test/cores/esp8266/Client.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "WString.h"
|
||||
|
||||
using IPAddress = String;
|
||||
|
||||
class Client : public Stream {
|
||||
public:
|
||||
virtual int connect(IPAddress ip, uint16_t port) = 0;
|
||||
virtual int connect(const char *host, uint16_t port) = 0;
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) = 0;
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual operator bool() = 0;
|
||||
};
|
||||
19
lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.cpp
Normal file
19
lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "EEPROM.h"
|
||||
|
||||
#include <string.h> // memcpy
|
||||
|
||||
EEPROMClass EEPROM;
|
||||
static uint8_t commitedData[512];
|
||||
static uint8_t pendingData[512];
|
||||
|
||||
uint8_t EEPROMClass::read(int address) {
|
||||
return commitedData[address];
|
||||
}
|
||||
|
||||
void EEPROMClass::write(int address, uint8_t value) {
|
||||
pendingData[address] = value;
|
||||
}
|
||||
|
||||
void EEPROMClass::commit() {
|
||||
memcpy(commitedData, pendingData, 512);
|
||||
}
|
||||
12
lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.h
Normal file
12
lib/ArduinoStreamUtils/extras/test/cores/esp8266/EEPROM.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class EEPROMClass {
|
||||
public:
|
||||
uint8_t read(int);
|
||||
void write(int, uint8_t);
|
||||
void commit();
|
||||
};
|
||||
|
||||
extern EEPROMClass EEPROM;
|
||||
43
lib/ArduinoStreamUtils/extras/test/cores/esp8266/Print.h
Normal file
43
lib/ArduinoStreamUtils/extras/test/cores/esp8266/Print.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
|
||||
struct Print {
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
|
||||
virtual size_t write(uint8_t data) = 0;
|
||||
|
||||
size_t write(const char *buffer, size_t size) {
|
||||
return write((const uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
size_t print(const String &s) {
|
||||
return write(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
size_t print(const char *s) {
|
||||
return write(s, std::strlen(s));
|
||||
}
|
||||
|
||||
size_t println() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t print(const T &value) {
|
||||
return print(String(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t println(const T &value) {
|
||||
return print(value);
|
||||
}
|
||||
|
||||
virtual void flush() {}
|
||||
};
|
||||
45
lib/ArduinoStreamUtils/extras/test/cores/esp8266/Stream.h
Normal file
45
lib/ArduinoStreamUtils/extras/test/cores/esp8266/Stream.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
struct Stream : Print {
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
|
||||
virtual size_t readBytes(char *buffer, size_t length) {
|
||||
size_t count = 0;
|
||||
while (count < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0)
|
||||
break;
|
||||
*buffer++ = (char)c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
virtual size_t readBytes(uint8_t *buffer, size_t length) {
|
||||
return readBytes((char *)buffer, length);
|
||||
}
|
||||
|
||||
virtual String readString() {
|
||||
String result;
|
||||
int c;
|
||||
while ((c = timedRead()) >= 0) {
|
||||
result += c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void setTimeout(unsigned long) {}
|
||||
|
||||
protected:
|
||||
int timedRead() {
|
||||
return read();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "../avr/WString.h"
|
||||
18
lib/ArduinoStreamUtils/extras/test/cores/nrf52/Arduino.h
Normal file
18
lib/ArduinoStreamUtils/extras/test/cores/nrf52/Arduino.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
#include <Print.h>
|
||||
#include <Stream.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
inline unsigned long millis() {
|
||||
return static_cast<unsigned long>(time(NULL));
|
||||
}
|
||||
|
||||
inline void yield() {}
|
||||
@@ -0,0 +1,15 @@
|
||||
# StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
# Copyright Benoit Blanchon 2019-2021
|
||||
# MIT License
|
||||
|
||||
add_library(Nrf52Core INTERFACE)
|
||||
|
||||
target_include_directories(Nrf52Core
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(Nrf52Core
|
||||
INTERFACE
|
||||
ARDUINO_ARCH_NRF52
|
||||
)
|
||||
26
lib/ArduinoStreamUtils/extras/test/cores/nrf52/Client.h
Normal file
26
lib/ArduinoStreamUtils/extras/test/cores/nrf52/Client.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "WString.h"
|
||||
|
||||
using IPAddress = String;
|
||||
|
||||
class Client : public Stream {
|
||||
public:
|
||||
virtual int connect(IPAddress ip, uint16_t port) = 0;
|
||||
virtual int connect(const char *host, uint16_t port) = 0;
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) = 0;
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual operator bool() = 0;
|
||||
};
|
||||
45
lib/ArduinoStreamUtils/extras/test/cores/nrf52/Print.h
Normal file
45
lib/ArduinoStreamUtils/extras/test/cores/nrf52/Print.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
|
||||
struct Print {
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
|
||||
virtual size_t write(uint8_t data) = 0;
|
||||
|
||||
virtual int availableForWrite() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t write(const char *buffer, size_t size) {
|
||||
return write((const uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
size_t print(const String &s) {
|
||||
return write(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
size_t print(const char *s) {
|
||||
return write(s, std::strlen(s));
|
||||
}
|
||||
|
||||
size_t println() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t print(const T &value) {
|
||||
return print(String(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t println(const T &value) {
|
||||
return print(value);
|
||||
}
|
||||
};
|
||||
45
lib/ArduinoStreamUtils/extras/test/cores/nrf52/Stream.h
Normal file
45
lib/ArduinoStreamUtils/extras/test/cores/nrf52/Stream.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
struct Stream : Print {
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() {}
|
||||
|
||||
size_t readBytes(char *buffer, size_t length) {
|
||||
size_t count = 0;
|
||||
while (count < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0)
|
||||
break;
|
||||
*buffer++ = (char)c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t readBytes(uint8_t *buffer, size_t length) {
|
||||
return readBytes((char *)buffer, length);
|
||||
}
|
||||
|
||||
String readString() {
|
||||
String result;
|
||||
int c;
|
||||
while ((c = timedRead()) >= 0)
|
||||
result += c;
|
||||
return result;
|
||||
}
|
||||
|
||||
void setTimeout(unsigned long) {}
|
||||
|
||||
protected:
|
||||
int timedRead() {
|
||||
return read();
|
||||
}
|
||||
};
|
||||
5
lib/ArduinoStreamUtils/extras/test/cores/nrf52/WString.h
Normal file
5
lib/ArduinoStreamUtils/extras/test/cores/nrf52/WString.h
Normal file
@@ -0,0 +1,5 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "../avr/WString.h"
|
||||
18
lib/ArduinoStreamUtils/extras/test/cores/samd/Arduino.h
Normal file
18
lib/ArduinoStreamUtils/extras/test/cores/samd/Arduino.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
#include <Print.h>
|
||||
#include <Stream.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
inline unsigned long millis() {
|
||||
return static_cast<unsigned long>(time(NULL));
|
||||
}
|
||||
|
||||
inline void yield() {}
|
||||
15
lib/ArduinoStreamUtils/extras/test/cores/samd/CMakeLists.txt
Normal file
15
lib/ArduinoStreamUtils/extras/test/cores/samd/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
# StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
# Copyright Benoit Blanchon 2019-2021
|
||||
# MIT License
|
||||
|
||||
add_library(SamdCore INTERFACE)
|
||||
|
||||
target_include_directories(SamdCore
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(SamdCore
|
||||
INTERFACE
|
||||
ARDUINO_ARCH_SAMD
|
||||
)
|
||||
26
lib/ArduinoStreamUtils/extras/test/cores/samd/Client.h
Normal file
26
lib/ArduinoStreamUtils/extras/test/cores/samd/Client.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "WString.h"
|
||||
|
||||
using IPAddress = String;
|
||||
|
||||
class Client : public Stream {
|
||||
public:
|
||||
virtual int connect(IPAddress ip, uint16_t port) = 0;
|
||||
virtual int connect(const char *host, uint16_t port) = 0;
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) = 0;
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual operator bool() = 0;
|
||||
};
|
||||
46
lib/ArduinoStreamUtils/extras/test/cores/samd/Print.h
Normal file
46
lib/ArduinoStreamUtils/extras/test/cores/samd/Print.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
|
||||
struct Print {
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
|
||||
virtual size_t write(uint8_t data) = 0;
|
||||
virtual void flush() {}
|
||||
|
||||
virtual int availableForWrite() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t write(const char *buffer, size_t size) {
|
||||
return write((const uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
size_t print(const String &s) {
|
||||
return write(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
size_t print(const char *s) {
|
||||
return write(s, std::strlen(s));
|
||||
}
|
||||
|
||||
size_t println() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t print(const T &value) {
|
||||
return print(String(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t println(const T &value) {
|
||||
return print(value);
|
||||
}
|
||||
};
|
||||
44
lib/ArduinoStreamUtils/extras/test/cores/samd/Stream.h
Normal file
44
lib/ArduinoStreamUtils/extras/test/cores/samd/Stream.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
struct Stream : Print {
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
|
||||
size_t readBytes(char *buffer, size_t length) {
|
||||
size_t count = 0;
|
||||
while (count < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0)
|
||||
break;
|
||||
*buffer++ = (char)c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t readBytes(uint8_t *buffer, size_t length) {
|
||||
return readBytes((char *)buffer, length);
|
||||
}
|
||||
|
||||
String readString() {
|
||||
String result;
|
||||
int c;
|
||||
while ((c = timedRead()) >= 0)
|
||||
result += c;
|
||||
return result;
|
||||
}
|
||||
|
||||
void setTimeout(unsigned long) {}
|
||||
|
||||
protected:
|
||||
int timedRead() {
|
||||
return read();
|
||||
}
|
||||
};
|
||||
5
lib/ArduinoStreamUtils/extras/test/cores/samd/WString.h
Normal file
5
lib/ArduinoStreamUtils/extras/test/cores/samd/WString.h
Normal file
@@ -0,0 +1,5 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "../avr/WString.h"
|
||||
18
lib/ArduinoStreamUtils/extras/test/cores/stm32/Arduino.h
Normal file
18
lib/ArduinoStreamUtils/extras/test/cores/stm32/Arduino.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
#include <Print.h>
|
||||
#include <Stream.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
inline unsigned long millis() {
|
||||
return static_cast<unsigned long>(time(NULL));
|
||||
}
|
||||
|
||||
inline void yield() {}
|
||||
@@ -0,0 +1,22 @@
|
||||
# StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
# Copyright Benoit Blanchon 2019-2021
|
||||
# MIT License
|
||||
|
||||
add_library(Stm32Core
|
||||
Client.h
|
||||
EEPROM.cpp
|
||||
EEPROM.h
|
||||
Print.h
|
||||
Stream.h
|
||||
WString.h
|
||||
)
|
||||
|
||||
target_include_directories(Stm32Core
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(Stm32Core
|
||||
PUBLIC
|
||||
ARDUINO_ARCH_STM32
|
||||
)
|
||||
28
lib/ArduinoStreamUtils/extras/test/cores/stm32/Client.h
Normal file
28
lib/ArduinoStreamUtils/extras/test/cores/stm32/Client.h
Normal file
@@ -0,0 +1,28 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "WString.h"
|
||||
|
||||
using IPAddress = String;
|
||||
|
||||
struct Client : Stream {
|
||||
// Print
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) = 0;
|
||||
|
||||
// Stream
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
virtual int connect(IPAddress ip, uint16_t port) = 0;
|
||||
virtual int connect(const char *host, uint16_t port) = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual operator bool() = 0;
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
};
|
||||
12
lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.cpp
Normal file
12
lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "EEPROM.h"
|
||||
|
||||
EEPROMClass EEPROM;
|
||||
static uint8_t data[512];
|
||||
|
||||
uint8_t EEPROMClass::read(int address) {
|
||||
return data[address];
|
||||
}
|
||||
|
||||
void EEPROMClass::write(int address, uint8_t value) {
|
||||
data[address] = value;
|
||||
}
|
||||
11
lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.h
Normal file
11
lib/ArduinoStreamUtils/extras/test/cores/stm32/EEPROM.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class EEPROMClass {
|
||||
public:
|
||||
uint8_t read(int);
|
||||
void write(int, uint8_t);
|
||||
};
|
||||
|
||||
extern EEPROMClass EEPROM;
|
||||
41
lib/ArduinoStreamUtils/extras/test/cores/stm32/Print.h
Normal file
41
lib/ArduinoStreamUtils/extras/test/cores/stm32/Print.h
Normal file
@@ -0,0 +1,41 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
struct Print {
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
|
||||
virtual size_t write(uint8_t data) = 0;
|
||||
|
||||
size_t write(const char *buffer, size_t size) {
|
||||
return write((const uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
size_t print(const String &s) {
|
||||
return write(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
size_t print(const char *s) {
|
||||
return write(s, std::strlen(s));
|
||||
}
|
||||
|
||||
size_t println() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t print(const T &value) {
|
||||
return print(String(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t println(const T &value) {
|
||||
return print(value);
|
||||
}
|
||||
};
|
||||
42
lib/ArduinoStreamUtils/extras/test/cores/stm32/Stream.h
Normal file
42
lib/ArduinoStreamUtils/extras/test/cores/stm32/Stream.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
struct Stream : Print {
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
virtual size_t readBytes(char *buffer, size_t length) {
|
||||
size_t count = 0;
|
||||
while (count < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0)
|
||||
break;
|
||||
*buffer++ = (char)c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
String readString() {
|
||||
String result;
|
||||
int c;
|
||||
while ((c = timedRead()) >= 0) {
|
||||
result += static_cast<char>(c);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void setTimeout(unsigned long) {}
|
||||
|
||||
protected:
|
||||
int timedRead() {
|
||||
return read();
|
||||
}
|
||||
};
|
||||
43
lib/ArduinoStreamUtils/extras/test/cores/stm32/WString.h
Normal file
43
lib/ArduinoStreamUtils/extras/test/cores/stm32/WString.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class String : private std::string {
|
||||
public:
|
||||
String() {}
|
||||
String(const String& s) : std::string(s) {}
|
||||
String(String&& s) : std::string(std::move(s)) {}
|
||||
String(const char* s) : std::string(s) {}
|
||||
String(int n) : std::string(std::to_string(n)) {}
|
||||
|
||||
String& operator=(const String& rhs) {
|
||||
std::string::operator=(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
using std::string::c_str;
|
||||
using std::string::length;
|
||||
using std::string::operator+=;
|
||||
using std::string::operator[];
|
||||
|
||||
void remove(unsigned int index, unsigned int count) {
|
||||
erase(begin() + index, begin() + index + count);
|
||||
}
|
||||
|
||||
void toCharArray(char* buf, unsigned int bufsize,
|
||||
unsigned int index = 0) const {
|
||||
copy(buf, bufsize, index);
|
||||
}
|
||||
|
||||
friend bool operator==(const String& lhs, const char* rhs) {
|
||||
return static_cast<const std::string&>(lhs) == rhs;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& lhs, const String& rhs) {
|
||||
return lhs << static_cast<const std::string&>(rhs);
|
||||
}
|
||||
};
|
||||
18
lib/ArduinoStreamUtils/extras/test/cores/teensy/Arduino.h
Normal file
18
lib/ArduinoStreamUtils/extras/test/cores/teensy/Arduino.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
#include <Print.h>
|
||||
#include <Stream.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
inline unsigned long millis() {
|
||||
return static_cast<unsigned long>(time(NULL));
|
||||
}
|
||||
|
||||
inline void yield() {}
|
||||
@@ -0,0 +1,22 @@
|
||||
# StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
# Copyright Benoit Blanchon 2019-2021
|
||||
# MIT License
|
||||
|
||||
add_library(TeensyCore
|
||||
Client.h
|
||||
EEPROM.cpp
|
||||
EEPROM.h
|
||||
Print.h
|
||||
Stream.h
|
||||
WString.h
|
||||
)
|
||||
|
||||
target_include_directories(TeensyCore
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(TeensyCore
|
||||
PUBLIC
|
||||
CORE_TEENSY
|
||||
)
|
||||
31
lib/ArduinoStreamUtils/extras/test/cores/teensy/Client.h
Normal file
31
lib/ArduinoStreamUtils/extras/test/cores/teensy/Client.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "WString.h"
|
||||
|
||||
using IPAddress = String;
|
||||
|
||||
struct Client : Stream {
|
||||
virtual int connect(IPAddress ip, uint16_t port) = 0;
|
||||
virtual int connect(const char *host, uint16_t port) = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual operator bool() = 0;
|
||||
|
||||
// Already in Print
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
// Already in Stream
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
|
||||
// Curiously not in Stream
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
};
|
||||
12
lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.cpp
Normal file
12
lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "EEPROM.h"
|
||||
|
||||
EEPROMClass EEPROM;
|
||||
static uint8_t data[512];
|
||||
|
||||
uint8_t EEPROMClass::read(int address) {
|
||||
return data[address];
|
||||
}
|
||||
|
||||
void EEPROMClass::update(int address, uint8_t value) {
|
||||
data[address] = value;
|
||||
}
|
||||
12
lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.h
Normal file
12
lib/ArduinoStreamUtils/extras/test/cores/teensy/EEPROM.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class EEPROMClass {
|
||||
public:
|
||||
uint8_t read(int);
|
||||
void update(int, uint8_t);
|
||||
// void write(int, uint8_t); <- it exists but we want to use update() instead
|
||||
};
|
||||
|
||||
extern EEPROMClass EEPROM;
|
||||
46
lib/ArduinoStreamUtils/extras/test/cores/teensy/Print.h
Normal file
46
lib/ArduinoStreamUtils/extras/test/cores/teensy/Print.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
|
||||
struct Print {
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
|
||||
virtual size_t write(uint8_t data) = 0;
|
||||
virtual void flush() {}
|
||||
|
||||
virtual int availableForWrite() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t write(const char *buffer, size_t size) {
|
||||
return write((const uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
size_t print(const String &s) {
|
||||
return write(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
size_t print(const char *s) {
|
||||
return write(s, std::strlen(s));
|
||||
}
|
||||
|
||||
size_t println() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t print(const T &value) {
|
||||
return print(String(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t println(const T &value) {
|
||||
return print(value);
|
||||
}
|
||||
};
|
||||
42
lib/ArduinoStreamUtils/extras/test/cores/teensy/Stream.h
Normal file
42
lib/ArduinoStreamUtils/extras/test/cores/teensy/Stream.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
struct Stream : Print {
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
size_t readBytes(char *buffer, size_t length) {
|
||||
size_t count = 0;
|
||||
while (count < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0)
|
||||
break;
|
||||
*buffer++ = (char)c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
String readString() {
|
||||
String result;
|
||||
int c;
|
||||
while ((c = timedRead()) >= 0) {
|
||||
result += static_cast<char>(c);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void setTimeout(unsigned long) {}
|
||||
|
||||
private:
|
||||
int timedRead() {
|
||||
return read();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../avr/WString.h"
|
||||
6000
lib/ArduinoStreamUtils/extras/test/doctest.h
Normal file
6000
lib/ArduinoStreamUtils/extras/test/doctest.h
Normal file
File diff suppressed because it is too large
Load Diff
6
lib/ArduinoStreamUtils/extras/test/main.cpp
Normal file
6
lib/ArduinoStreamUtils/extras/test/main.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||
#include "doctest.h"
|
||||
Reference in New Issue
Block a user