mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-29 05:21:37 +03:00
Migrate from astyle to clang-format (#8464)
This commit is contained in:
committed by
Max Prokhorov
parent
46190b61f1
commit
19b7a29720
@ -2,245 +2,239 @@
|
||||
#include "PolledTimeout.h"
|
||||
|
||||
#define mockverbose printf
|
||||
#include "common/MockEsp.cpp" // getCycleCount
|
||||
#include "common/MockEsp.cpp" // getCycleCount
|
||||
|
||||
//This won't work for
|
||||
// This won't work for
|
||||
template<typename argT>
|
||||
inline bool
|
||||
fuzzycomp(argT a, argT b)
|
||||
inline bool fuzzycomp(argT a, argT b)
|
||||
{
|
||||
const argT epsilon = 10;
|
||||
return (std::max(a,b) - std::min(a,b) <= epsilon);
|
||||
const argT epsilon = 10;
|
||||
return (std::max(a, b) - std::min(a, b) <= epsilon);
|
||||
}
|
||||
|
||||
TEST_CASE("OneShot Timeout 500000000ns (0.5s)", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::oneShotFastNs;
|
||||
using timeType = oneShotFastNs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::oneShotFastNs;
|
||||
using timeType = oneShotFastNs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("OneShot Timeout 500000000ns (0.5s)");
|
||||
Serial.println("OneShot Timeout 500000000ns (0.5s)");
|
||||
|
||||
oneShotFastNs timeout(500000000);
|
||||
before = micros();
|
||||
while(!timeout.expired())
|
||||
yield();
|
||||
after = micros();
|
||||
oneShotFastNs timeout(500000000);
|
||||
before = micros();
|
||||
while (!timeout.expired())
|
||||
yield();
|
||||
after = micros();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta/1000, (timeType)500));
|
||||
REQUIRE(fuzzycomp(delta / 1000, (timeType)500));
|
||||
|
||||
Serial.print("reset\n");
|
||||
|
||||
Serial.print("reset\n");
|
||||
timeout.reset();
|
||||
before = micros();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = micros();
|
||||
|
||||
timeout.reset();
|
||||
before = micros();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = micros();
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta/1000, (timeType)500));
|
||||
REQUIRE(fuzzycomp(delta / 1000, (timeType)500));
|
||||
}
|
||||
|
||||
TEST_CASE("OneShot Timeout 3000000us", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::oneShotFastUs;
|
||||
using timeType = oneShotFastUs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::oneShotFastUs;
|
||||
using timeType = oneShotFastUs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("OneShot Timeout 3000000us");
|
||||
Serial.println("OneShot Timeout 3000000us");
|
||||
|
||||
oneShotFastUs timeout(3000000);
|
||||
before = micros();
|
||||
while(!timeout.expired())
|
||||
yield();
|
||||
after = micros();
|
||||
oneShotFastUs timeout(3000000);
|
||||
before = micros();
|
||||
while (!timeout.expired())
|
||||
yield();
|
||||
after = micros();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta/1000, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta / 1000, (timeType)3000));
|
||||
|
||||
Serial.print("reset\n");
|
||||
|
||||
Serial.print("reset\n");
|
||||
timeout.reset();
|
||||
before = micros();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = micros();
|
||||
|
||||
timeout.reset();
|
||||
before = micros();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = micros();
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta/1000, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta / 1000, (timeType)3000));
|
||||
}
|
||||
|
||||
TEST_CASE("OneShot Timeout 3000ms", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::oneShotMs;
|
||||
using timeType = oneShotMs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::oneShotMs;
|
||||
using timeType = oneShotMs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
|
||||
oneShotMs timeout(3000);
|
||||
before = millis();
|
||||
while(!timeout.expired())
|
||||
yield();
|
||||
after = millis();
|
||||
oneShotMs timeout(3000);
|
||||
before = millis();
|
||||
while (!timeout.expired())
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
|
||||
Serial.print("reset\n");
|
||||
|
||||
Serial.print("reset\n");
|
||||
timeout.reset();
|
||||
before = millis();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
timeout.reset();
|
||||
before = millis();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
}
|
||||
|
||||
TEST_CASE("OneShot Timeout 3000ms reset to 1000ms", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::oneShotMs;
|
||||
using timeType = oneShotMs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::oneShotMs;
|
||||
using timeType = oneShotMs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
|
||||
oneShotMs timeout(3000);
|
||||
before = millis();
|
||||
while(!timeout.expired())
|
||||
yield();
|
||||
after = millis();
|
||||
oneShotMs timeout(3000);
|
||||
before = millis();
|
||||
while (!timeout.expired())
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
|
||||
Serial.print("reset\n");
|
||||
|
||||
Serial.print("reset\n");
|
||||
timeout.reset(1000);
|
||||
before = millis();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
timeout.reset(1000);
|
||||
before = millis();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)1000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)1000));
|
||||
}
|
||||
|
||||
TEST_CASE("Periodic Timeout 1T 3000ms", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::periodicMs;
|
||||
using timeType = periodicMs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::periodicMs;
|
||||
using timeType = periodicMs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("Periodic Timeout 1T 3000ms");
|
||||
Serial.println("Periodic Timeout 1T 3000ms");
|
||||
|
||||
periodicMs timeout(3000);
|
||||
before = millis();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
periodicMs timeout(3000);
|
||||
before = millis();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
|
||||
Serial.print("no reset needed\n");
|
||||
Serial.print("no reset needed\n");
|
||||
|
||||
before = millis();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
before = millis();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
}
|
||||
|
||||
TEST_CASE("Periodic Timeout 10T 1000ms", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::periodicMs;
|
||||
using timeType = periodicMs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::periodicMs;
|
||||
using timeType = periodicMs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("Periodic 10T Timeout 1000ms");
|
||||
Serial.println("Periodic 10T Timeout 1000ms");
|
||||
|
||||
int counter = 10;
|
||||
int counter = 10;
|
||||
|
||||
periodicMs timeout(1000);
|
||||
before = millis();
|
||||
while(1)
|
||||
{
|
||||
if(timeout)
|
||||
periodicMs timeout(1000);
|
||||
before = millis();
|
||||
while (1)
|
||||
{
|
||||
Serial.print("*");
|
||||
if(!--counter)
|
||||
break;
|
||||
yield();
|
||||
if (timeout)
|
||||
{
|
||||
Serial.print("*");
|
||||
if (!--counter)
|
||||
break;
|
||||
yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
after = millis();
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("\ndelta = %lu\n", delta);
|
||||
REQUIRE(fuzzycomp(delta, (timeType)10000));
|
||||
delta = after - before;
|
||||
Serial.printf("\ndelta = %lu\n", delta);
|
||||
REQUIRE(fuzzycomp(delta, (timeType)10000));
|
||||
}
|
||||
|
||||
TEST_CASE("OneShot Timeout 3000ms reset to 1000ms custom yield", "[polledTimeout]")
|
||||
{
|
||||
using YieldOrSkipPolicy = esp8266::polledTimeout::YieldPolicy::YieldOrSkip;
|
||||
using oneShotMsYield = esp8266::polledTimeout::timeoutTemplate<false, YieldOrSkipPolicy>;
|
||||
using timeType = oneShotMsYield::timeType;
|
||||
timeType before, after, delta;
|
||||
using YieldOrSkipPolicy = esp8266::polledTimeout::YieldPolicy::YieldOrSkip;
|
||||
using oneShotMsYield = esp8266::polledTimeout::timeoutTemplate<false, YieldOrSkipPolicy>;
|
||||
using timeType = oneShotMsYield::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
|
||||
oneShotMsYield timeout(3000);
|
||||
before = millis();
|
||||
while (!timeout.expired())
|
||||
;
|
||||
after = millis();
|
||||
|
||||
oneShotMsYield timeout(3000);
|
||||
before = millis();
|
||||
while(!timeout.expired());
|
||||
after = millis();
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
Serial.print("reset\n");
|
||||
|
||||
timeout.reset(1000);
|
||||
before = millis();
|
||||
while (!timeout)
|
||||
;
|
||||
after = millis();
|
||||
|
||||
Serial.print("reset\n");
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
timeout.reset(1000);
|
||||
before = millis();
|
||||
while(!timeout);
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)1000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)1000));
|
||||
}
|
||||
|
||||
|
@ -27,19 +27,19 @@ TEST_CASE("Print::write overrides all compile properly", "[core][Print]")
|
||||
REQUIRE(LittleFS.begin());
|
||||
auto p = LittleFS.open("test.bin", "w");
|
||||
REQUIRE(p);
|
||||
uint8_t uint8 = 1;
|
||||
uint16_t uint16 = 2;
|
||||
uint32_t uint32 = 3;
|
||||
size_t size = 4;
|
||||
int8_t int8 = 1;
|
||||
int16_t int16 = 2;
|
||||
int32_t int32 = 3;
|
||||
char c = 'h';
|
||||
int i = 10;
|
||||
long l = 11;
|
||||
unsigned char uc = 20;
|
||||
unsigned int ui = 21;
|
||||
unsigned long ul = 22;
|
||||
uint8_t uint8 = 1;
|
||||
uint16_t uint16 = 2;
|
||||
uint32_t uint32 = 3;
|
||||
size_t size = 4;
|
||||
int8_t int8 = 1;
|
||||
int16_t int16 = 2;
|
||||
int32_t int32 = 3;
|
||||
char c = 'h';
|
||||
int i = 10;
|
||||
long l = 11;
|
||||
unsigned char uc = 20;
|
||||
unsigned int ui = 21;
|
||||
unsigned long ul = 22;
|
||||
p.write(uint8);
|
||||
p.write(uint16);
|
||||
p.write(uint32);
|
||||
@ -60,7 +60,7 @@ TEST_CASE("Print::write overrides all compile properly", "[core][Print]")
|
||||
p = LittleFS.open("test.bin", "r");
|
||||
REQUIRE(p);
|
||||
uint8_t buff[16];
|
||||
int len = p.read(buff, 16);
|
||||
int len = p.read(buff, 16);
|
||||
p.close();
|
||||
REQUIRE(len == 15);
|
||||
REQUIRE(buff[0] == 1);
|
||||
|
@ -16,12 +16,11 @@
|
||||
#include <catch.hpp>
|
||||
#include <Updater.h>
|
||||
|
||||
|
||||
// Use a SPIFFS file because we can't instantiate a virtual class like Print
|
||||
TEST_CASE("Updater fails when writes overflow requested size", "[core][Updater]")
|
||||
{
|
||||
UpdaterClass *u;
|
||||
uint8_t buff[6000];
|
||||
UpdaterClass* u;
|
||||
uint8_t buff[6000];
|
||||
memset(buff, 0, sizeof(buff));
|
||||
u = new UpdaterClass();
|
||||
REQUIRE(u->begin(6000));
|
||||
|
@ -32,30 +32,35 @@ TEST_CASE("MD5Builder::add works as expected", "[core][MD5Builder]")
|
||||
REQUIRE(builder.toString() == "9edb67f2b22c604fab13e2fd1d6056d7");
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("MD5Builder::addHexString works as expected", "[core][MD5Builder]")
|
||||
{
|
||||
WHEN("A char array is parsed"){
|
||||
MD5Builder builder;
|
||||
builder.begin();
|
||||
const char * myPayload = "1234567890abcdeffedcba98765432106469676974616c7369676e61747572656170706c69636174696F6e73";
|
||||
builder.addHexString(myPayload);
|
||||
builder.calculate();
|
||||
REQUIRE(builder.toString() == "47b937a6f9f12a4c389fa5854e023efb");
|
||||
WHEN("A char array is parsed")
|
||||
{
|
||||
MD5Builder builder;
|
||||
builder.begin();
|
||||
const char* myPayload = "1234567890abcdeffedcba98765432106469676974616c7369676e617475726561"
|
||||
"70706c69636174696F6e73";
|
||||
builder.addHexString(myPayload);
|
||||
builder.calculate();
|
||||
REQUIRE(builder.toString() == "47b937a6f9f12a4c389fa5854e023efb");
|
||||
}
|
||||
|
||||
WHEN("A Arduino String is parsed"){
|
||||
MD5Builder builder;
|
||||
builder.begin();
|
||||
builder.addHexString(String("1234567890abcdeffedcba98765432106469676974616c7369676e61747572656170706c69636174696f6e73"));
|
||||
builder.calculate();
|
||||
REQUIRE(builder.toString() == "47b937a6f9f12a4c389fa5854e023efb");
|
||||
WHEN("A Arduino String is parsed")
|
||||
{
|
||||
MD5Builder builder;
|
||||
builder.begin();
|
||||
builder.addHexString(String("1234567890abcdeffedcba98765432106469676974616c7369676e61747572"
|
||||
"656170706c69636174696f6e73"));
|
||||
builder.calculate();
|
||||
REQUIRE(builder.toString() == "47b937a6f9f12a4c389fa5854e023efb");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MD5Builder::addStream works", "[core][MD5Builder]"){
|
||||
MD5Builder builder;
|
||||
const char* str = "MD5Builder::addStream_works_longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong";
|
||||
TEST_CASE("MD5Builder::addStream works", "[core][MD5Builder]")
|
||||
{
|
||||
MD5Builder builder;
|
||||
const char* str = "MD5Builder::addStream_works_"
|
||||
"longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong";
|
||||
{
|
||||
StreamString stream;
|
||||
stream.print(str);
|
||||
|
@ -19,15 +19,16 @@
|
||||
|
||||
TEST_CASE("strstr_P works as strstr", "[core][pgmspace]")
|
||||
{
|
||||
auto t = [](const char* h, const char* n) {
|
||||
auto t = [](const char* h, const char* n)
|
||||
{
|
||||
const char* strstr_P_result = strstr_P(h, n);
|
||||
const char* strstr_result = strstr(h, n);
|
||||
const char* strstr_result = strstr(h, n);
|
||||
REQUIRE(strstr_P_result == strstr_result);
|
||||
};
|
||||
|
||||
// Test case data is from avr-libc, original copyright (c) 2007 Dmitry Xmelkov
|
||||
// See avr-libc/tests/simulate/pmstring/strstr_P.c
|
||||
t ("", "");
|
||||
t("", "");
|
||||
t("12345", "");
|
||||
t("ababac", "abac");
|
||||
t("", "a");
|
||||
|
@ -43,8 +43,8 @@ TEST_CASE("String::trim", "[core][String]")
|
||||
TEST_CASE("String::replace", "[core][String]")
|
||||
{
|
||||
String str;
|
||||
str = "The quick brown fox jumped over the lazy dog.";
|
||||
String find = "fox";
|
||||
str = "The quick brown fox jumped over the lazy dog.";
|
||||
String find = "fox";
|
||||
String replace = "vulpes vulpes";
|
||||
str.replace(find, replace);
|
||||
REQUIRE(str == "The quick brown vulpes vulpes jumped over the lazy dog.");
|
||||
@ -52,10 +52,10 @@ TEST_CASE("String::replace", "[core][String]")
|
||||
|
||||
TEST_CASE("String(value, base)", "[core][String]")
|
||||
{
|
||||
String strbase2(9999,2);
|
||||
String strbase8(9999,8);
|
||||
String strbase10(9999,10);
|
||||
String strbase16(9999,16);
|
||||
String strbase2(9999, 2);
|
||||
String strbase8(9999, 8);
|
||||
String strbase10(9999, 10);
|
||||
String strbase16(9999, 16);
|
||||
REQUIRE(strbase2 == "10011100001111");
|
||||
REQUIRE(strbase8 == "23417");
|
||||
REQUIRE(strbase10 == "9999");
|
||||
@ -64,7 +64,7 @@ TEST_CASE("String(value, base)", "[core][String]")
|
||||
String strnegf(-2.123, 3);
|
||||
REQUIRE(strnegi == "-9999");
|
||||
REQUIRE(strnegf == "-2.123");
|
||||
String strbase16l((long)999999,16);
|
||||
String strbase16l((long)999999, 16);
|
||||
REQUIRE(strbase16l == "f423f");
|
||||
}
|
||||
|
||||
@ -83,8 +83,8 @@ TEST_CASE("String constructors", "[core][String]")
|
||||
String s1("abcd");
|
||||
String s2(s1);
|
||||
REQUIRE(s1 == s2);
|
||||
String *s3 = new String("manos");
|
||||
s2 = *s3;
|
||||
String* s3 = new String("manos");
|
||||
s2 = *s3;
|
||||
delete s3;
|
||||
REQUIRE(s2 == "manos");
|
||||
s3 = new String("thisismuchlongerthantheother");
|
||||
@ -97,8 +97,8 @@ TEST_CASE("String constructors", "[core][String]")
|
||||
REQUIRE(ssh == "3.14159_abcd");
|
||||
String flash = (F("hello from flash"));
|
||||
REQUIRE(flash == "hello from flash");
|
||||
const char textarray[6] = {'h', 'e', 'l', 'l', 'o', 0};
|
||||
String hello(textarray);
|
||||
const char textarray[6] = { 'h', 'e', 'l', 'l', 'o', 0 };
|
||||
String hello(textarray);
|
||||
REQUIRE(hello == "hello");
|
||||
String hello2;
|
||||
hello2 = textarray;
|
||||
@ -135,13 +135,21 @@ TEST_CASE("String concantenation", "[core][String]")
|
||||
str += LLONG_MIN;
|
||||
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808");
|
||||
str += String(LLONG_MIN, 10);
|
||||
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808");
|
||||
REQUIRE(str
|
||||
== "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-"
|
||||
"9223372036854775808");
|
||||
str += LLONG_MAX;
|
||||
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-92233720368547758089223372036854775807");
|
||||
REQUIRE(str
|
||||
== "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-"
|
||||
"92233720368547758089223372036854775807");
|
||||
str += ULLONG_MAX;
|
||||
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808922337203685477580718446744073709551615");
|
||||
REQUIRE(str
|
||||
== "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-"
|
||||
"9223372036854775808922337203685477580718446744073709551615");
|
||||
str += String(ULLONG_MAX, 16);
|
||||
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808922337203685477580718446744073709551615ffffffffffffffff");
|
||||
REQUIRE(str
|
||||
== "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-"
|
||||
"9223372036854775808922337203685477580718446744073709551615ffffffffffffffff");
|
||||
str = "clean";
|
||||
REQUIRE(str.concat(str) == true);
|
||||
REQUIRE(str == "cleanclean");
|
||||
@ -156,19 +164,19 @@ TEST_CASE("String concantenation", "[core][String]")
|
||||
REQUIRE(str == "-100");
|
||||
// Non-zero-terminated array concatenation
|
||||
const char buff[] = "abcdefg";
|
||||
String n;
|
||||
n = "1234567890"; // Make it a SSO string, fill with non-0 data
|
||||
n = "1"; // Overwrite [1] with 0, but leave old junk in SSO space still
|
||||
String n;
|
||||
n = "1234567890"; // Make it a SSO string, fill with non-0 data
|
||||
n = "1"; // Overwrite [1] with 0, but leave old junk in SSO space still
|
||||
n.concat(buff, 3);
|
||||
REQUIRE(n == "1abc"); // Ensure the trailing 0 is always present even w/this funky concat
|
||||
for (int i=0; i<20; i++)
|
||||
n.concat(buff, 1); // Add 20 'a's to go from SSO to normal string
|
||||
REQUIRE(n == "1abc"); // Ensure the trailing 0 is always present even w/this funky concat
|
||||
for (int i = 0; i < 20; i++)
|
||||
n.concat(buff, 1); // Add 20 'a's to go from SSO to normal string
|
||||
REQUIRE(n == "1abcaaaaaaaaaaaaaaaaaaaa");
|
||||
n = "";
|
||||
for (int i=0; i<=5; i++)
|
||||
for (int i = 0; i <= 5; i++)
|
||||
n.concat(buff, i);
|
||||
REQUIRE(n == "aababcabcdabcde");
|
||||
n.concat(buff, 0); // And check no add'n
|
||||
n.concat(buff, 0); // And check no add'n
|
||||
REQUIRE(n == "aababcabcdabcde");
|
||||
}
|
||||
|
||||
@ -211,7 +219,7 @@ TEST_CASE("String byte access", "[core][String]")
|
||||
TEST_CASE("String conversion", "[core][String]")
|
||||
{
|
||||
String s = "12345";
|
||||
long l = s.toInt();
|
||||
long l = s.toInt();
|
||||
REQUIRE(l == 12345);
|
||||
s = "2147483647";
|
||||
l = s.toInt();
|
||||
@ -222,9 +230,9 @@ TEST_CASE("String conversion", "[core][String]")
|
||||
s = "-2147483648";
|
||||
l = s.toInt();
|
||||
REQUIRE(l == INT_MIN);
|
||||
s = "3.14159";
|
||||
s = "3.14159";
|
||||
float f = s.toFloat();
|
||||
REQUIRE( fabs(f - 3.14159) < 0.0001 );
|
||||
REQUIRE(fabs(f - 3.14159) < 0.0001);
|
||||
}
|
||||
|
||||
TEST_CASE("String case", "[core][String]")
|
||||
@ -246,7 +254,7 @@ TEST_CASE("String nulls", "[core][String]")
|
||||
s.trim();
|
||||
s.toUpperCase();
|
||||
s.toLowerCase();
|
||||
s.remove(1,1);
|
||||
s.remove(1, 1);
|
||||
s.remove(10);
|
||||
s.replace("taco", "burrito");
|
||||
s.replace('a', 'b');
|
||||
@ -268,7 +276,7 @@ TEST_CASE("String nulls", "[core][String]")
|
||||
REQUIRE(s == "");
|
||||
REQUIRE(s.length() == 0);
|
||||
s.setCharAt(1, 't');
|
||||
REQUIRE(s.startsWith("abc",0) == false);
|
||||
REQUIRE(s.startsWith("abc", 0) == false);
|
||||
REQUIRE(s.startsWith("def") == false);
|
||||
REQUIRE(s.equalsConstantTime("def") == false);
|
||||
REQUIRE(s.equalsConstantTime("") == true);
|
||||
@ -299,125 +307,128 @@ TEST_CASE("String sizes near 8b", "[core][String]")
|
||||
String s15("12345678901234");
|
||||
String s16("123456789012345");
|
||||
String s17("1234567890123456");
|
||||
REQUIRE(!strcmp(s7.c_str(),"123456"));
|
||||
REQUIRE(!strcmp(s8.c_str(),"1234567"));
|
||||
REQUIRE(!strcmp(s9.c_str(),"12345678"));
|
||||
REQUIRE(!strcmp(s15.c_str(),"12345678901234"));
|
||||
REQUIRE(!strcmp(s16.c_str(),"123456789012345"));
|
||||
REQUIRE(!strcmp(s17.c_str(),"1234567890123456"));
|
||||
REQUIRE(!strcmp(s7.c_str(), "123456"));
|
||||
REQUIRE(!strcmp(s8.c_str(), "1234567"));
|
||||
REQUIRE(!strcmp(s9.c_str(), "12345678"));
|
||||
REQUIRE(!strcmp(s15.c_str(), "12345678901234"));
|
||||
REQUIRE(!strcmp(s16.c_str(), "123456789012345"));
|
||||
REQUIRE(!strcmp(s17.c_str(), "1234567890123456"));
|
||||
s7 += '_';
|
||||
s8 += '_';
|
||||
s9 += '_';
|
||||
s15 += '_';
|
||||
s16 += '_';
|
||||
s17 += '_';
|
||||
REQUIRE(!strcmp(s7.c_str(),"123456_"));
|
||||
REQUIRE(!strcmp(s8.c_str(),"1234567_"));
|
||||
REQUIRE(!strcmp(s9.c_str(),"12345678_"));
|
||||
REQUIRE(!strcmp(s15.c_str(),"12345678901234_"));
|
||||
REQUIRE(!strcmp(s16.c_str(),"123456789012345_"));
|
||||
REQUIRE(!strcmp(s17.c_str(),"1234567890123456_"));
|
||||
REQUIRE(!strcmp(s7.c_str(), "123456_"));
|
||||
REQUIRE(!strcmp(s8.c_str(), "1234567_"));
|
||||
REQUIRE(!strcmp(s9.c_str(), "12345678_"));
|
||||
REQUIRE(!strcmp(s15.c_str(), "12345678901234_"));
|
||||
REQUIRE(!strcmp(s16.c_str(), "123456789012345_"));
|
||||
REQUIRE(!strcmp(s17.c_str(), "1234567890123456_"));
|
||||
}
|
||||
|
||||
TEST_CASE("String SSO works", "[core][String]")
|
||||
{
|
||||
// This test assumes that SSO_SIZE==8, if that changes the test must as well
|
||||
String s;
|
||||
s += "0";
|
||||
REQUIRE(s == "0");
|
||||
REQUIRE(s.length() == 1);
|
||||
const char *savesso = s.c_str();
|
||||
s += 1;
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01");
|
||||
REQUIRE(s.length() == 2);
|
||||
s += "2";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012");
|
||||
REQUIRE(s.length() == 3);
|
||||
s += 3;
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123");
|
||||
REQUIRE(s.length() == 4);
|
||||
s += "4";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01234");
|
||||
REQUIRE(s.length() == 5);
|
||||
s += "5";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012345");
|
||||
REQUIRE(s.length() == 6);
|
||||
s += "6";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456");
|
||||
REQUIRE(s.length() == 7);
|
||||
s += "7";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01234567");
|
||||
REQUIRE(s.length() == 8);
|
||||
s += "8";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012345678");
|
||||
REQUIRE(s.length() == 9);
|
||||
s += "9";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789");
|
||||
REQUIRE(s.length() == 10);
|
||||
if (sizeof(savesso) == 4) {
|
||||
s += "a";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789a");
|
||||
REQUIRE(s.length() == 11);
|
||||
s += "b";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789ab");
|
||||
REQUIRE(s.length() == 12);
|
||||
s += "c";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abc");
|
||||
REQUIRE(s.length() == 13);
|
||||
} else {
|
||||
s += "a";
|
||||
// This test assumes that SSO_SIZE==8, if that changes the test must as well
|
||||
String s;
|
||||
s += "0";
|
||||
REQUIRE(s == "0");
|
||||
REQUIRE(s.length() == 1);
|
||||
const char* savesso = s.c_str();
|
||||
s += 1;
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789a");
|
||||
REQUIRE(s.length() == 11);
|
||||
s += "bcde";
|
||||
REQUIRE(s == "01");
|
||||
REQUIRE(s.length() == 2);
|
||||
s += "2";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789abcde");
|
||||
REQUIRE(s.length() == 15);
|
||||
s += "fghi";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghi");
|
||||
REQUIRE(s.length() == 19);
|
||||
s += "j";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghij");
|
||||
REQUIRE(s.length() == 20);
|
||||
s += "k";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijk");
|
||||
REQUIRE(s.length() == 21);
|
||||
s += "l";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijkl");
|
||||
REQUIRE(s.length() == 22);
|
||||
s += "m";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklm");
|
||||
REQUIRE(s.length() == 23);
|
||||
s += "nopq";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklmnopq");
|
||||
REQUIRE(s.length() == 27);
|
||||
s += "rstu";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklmnopqrstu");
|
||||
REQUIRE(s.length() == 31);
|
||||
}
|
||||
s = "0123456789abcde";
|
||||
s = s.substring(s.indexOf('a'));
|
||||
REQUIRE(s == "abcde");
|
||||
REQUIRE(s.length() == 5);
|
||||
REQUIRE(s == "012");
|
||||
REQUIRE(s.length() == 3);
|
||||
s += 3;
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123");
|
||||
REQUIRE(s.length() == 4);
|
||||
s += "4";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01234");
|
||||
REQUIRE(s.length() == 5);
|
||||
s += "5";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012345");
|
||||
REQUIRE(s.length() == 6);
|
||||
s += "6";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456");
|
||||
REQUIRE(s.length() == 7);
|
||||
s += "7";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01234567");
|
||||
REQUIRE(s.length() == 8);
|
||||
s += "8";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012345678");
|
||||
REQUIRE(s.length() == 9);
|
||||
s += "9";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789");
|
||||
REQUIRE(s.length() == 10);
|
||||
if (sizeof(savesso) == 4)
|
||||
{
|
||||
s += "a";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789a");
|
||||
REQUIRE(s.length() == 11);
|
||||
s += "b";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789ab");
|
||||
REQUIRE(s.length() == 12);
|
||||
s += "c";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abc");
|
||||
REQUIRE(s.length() == 13);
|
||||
}
|
||||
else
|
||||
{
|
||||
s += "a";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789a");
|
||||
REQUIRE(s.length() == 11);
|
||||
s += "bcde";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789abcde");
|
||||
REQUIRE(s.length() == 15);
|
||||
s += "fghi";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghi");
|
||||
REQUIRE(s.length() == 19);
|
||||
s += "j";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghij");
|
||||
REQUIRE(s.length() == 20);
|
||||
s += "k";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijk");
|
||||
REQUIRE(s.length() == 21);
|
||||
s += "l";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijkl");
|
||||
REQUIRE(s.length() == 22);
|
||||
s += "m";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklm");
|
||||
REQUIRE(s.length() == 23);
|
||||
s += "nopq";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklmnopq");
|
||||
REQUIRE(s.length() == 27);
|
||||
s += "rstu";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklmnopqrstu");
|
||||
REQUIRE(s.length() == 31);
|
||||
}
|
||||
s = "0123456789abcde";
|
||||
s = s.substring(s.indexOf('a'));
|
||||
REQUIRE(s == "abcde");
|
||||
REQUIRE(s.length() == 5);
|
||||
}
|
||||
|
||||
#include <new>
|
||||
@ -426,70 +437,67 @@ void repl(const String& key, const String& val, String& s, boolean useURLencode)
|
||||
s.replace(key, val);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("String SSO handles junk in memory", "[core][String]")
|
||||
{
|
||||
// We fill the SSO space with garbage then construct an object in it and check consistency
|
||||
// This is NOT how you want to use Strings outside of this testing!
|
||||
unsigned char space[64];
|
||||
String *s = (String*)space;
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String;
|
||||
REQUIRE(*s == "");
|
||||
s->~String();
|
||||
// We fill the SSO space with garbage then construct an object in it and check consistency
|
||||
// This is NOT how you want to use Strings outside of this testing!
|
||||
unsigned char space[64];
|
||||
String* s = (String*)space;
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String;
|
||||
REQUIRE(*s == "");
|
||||
s->~String();
|
||||
|
||||
// Tests from #5883
|
||||
bool useURLencode = false;
|
||||
const char euro[4] = {(char)0xe2, (char)0x82, (char)0xac, 0}; // Unicode euro symbol
|
||||
const char yen[3] = {(char)0xc2, (char)0xa5, 0}; // Unicode yen symbol
|
||||
// Tests from #5883
|
||||
bool useURLencode = false;
|
||||
const char euro[4] = { (char)0xe2, (char)0x82, (char)0xac, 0 }; // Unicode euro symbol
|
||||
const char yen[3] = { (char)0xc2, (char)0xa5, 0 }; // Unicode yen symbol
|
||||
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("%ssid%");
|
||||
repl(("%ssid%"), "MikroTik", *s, useURLencode);
|
||||
REQUIRE(*s == "MikroTik");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("%ssid%");
|
||||
repl(("%ssid%"), "MikroTik", *s, useURLencode);
|
||||
REQUIRE(*s == "MikroTik");
|
||||
s->~String();
|
||||
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("{E}");
|
||||
repl(("{E}"), euro, *s, useURLencode);
|
||||
REQUIRE(*s == "€");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("€");
|
||||
repl(("€"), euro, *s, useURLencode);
|
||||
REQUIRE(*s == "€");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("{Y}");
|
||||
repl(("{Y}"), yen, *s, useURLencode);
|
||||
REQUIRE(*s == "¥");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("¥");
|
||||
repl(("¥"), yen, *s, useURLencode);
|
||||
REQUIRE(*s == "¥");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("{E}");
|
||||
repl(("{E}"), euro, *s, useURLencode);
|
||||
REQUIRE(*s == "€");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("€");
|
||||
repl(("€"), euro, *s, useURLencode);
|
||||
REQUIRE(*s == "€");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("{Y}");
|
||||
repl(("{Y}"), yen, *s, useURLencode);
|
||||
REQUIRE(*s == "¥");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("¥");
|
||||
repl(("¥"), yen, *s, useURLencode);
|
||||
REQUIRE(*s == "¥");
|
||||
s->~String();
|
||||
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("%sysname%");
|
||||
repl(("%sysname%"), "CO2_defect", *s, useURLencode);
|
||||
REQUIRE(*s == "CO2_defect");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("%sysname%");
|
||||
repl(("%sysname%"), "CO2_defect", *s, useURLencode);
|
||||
REQUIRE(*s == "CO2_defect");
|
||||
s->~String();
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Issue #5949 - Overlapping src/dest in replace", "[core][String]")
|
||||
{
|
||||
String blah = "blah";
|
||||
blah.replace("xx", "y");
|
||||
REQUIRE(blah == "blah");
|
||||
blah.replace("x", "yy");
|
||||
REQUIRE(blah == "blah");
|
||||
blah.replace(blah, blah);
|
||||
REQUIRE(blah == "blah");
|
||||
String blah = "blah";
|
||||
blah.replace("xx", "y");
|
||||
REQUIRE(blah == "blah");
|
||||
blah.replace("x", "yy");
|
||||
REQUIRE(blah == "blah");
|
||||
blah.replace(blah, blah);
|
||||
REQUIRE(blah == "blah");
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Issue #2736 - StreamString SSO fix", "[core][StreamString]")
|
||||
{
|
||||
StreamString s;
|
||||
@ -502,102 +510,101 @@ TEST_CASE("Issue #2736 - StreamString SSO fix", "[core][StreamString]")
|
||||
|
||||
TEST_CASE("Strings with NULs", "[core][String]")
|
||||
{
|
||||
// The following should never be done in a real app! This is only to inject 0s in the middle of a string.
|
||||
// Fits in SSO...
|
||||
String str("01234567");
|
||||
REQUIRE(str.length() == 8);
|
||||
char *ptr = (char *)str.c_str();
|
||||
ptr[3] = 0;
|
||||
String str2;
|
||||
str2 = str;
|
||||
REQUIRE(str2.length() == 8);
|
||||
// Needs a buffer pointer
|
||||
str = "0123456789012345678901234567890123456789";
|
||||
ptr = (char *)str.c_str();
|
||||
ptr[3] = 0;
|
||||
str2 = str;
|
||||
REQUIRE(str2.length() == 40);
|
||||
String str3("a");
|
||||
ptr = (char *)str3.c_str();
|
||||
*ptr = 0;
|
||||
REQUIRE(str3.length() == 1);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 2);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 4);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 8);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 16);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 32);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 64);
|
||||
static char zeros[64] = {0};
|
||||
const char *p = str3.c_str();
|
||||
REQUIRE(!memcmp(p, zeros, 64));
|
||||
// The following should never be done in a real app! This is only to inject 0s in the middle of
|
||||
// a string. Fits in SSO...
|
||||
String str("01234567");
|
||||
REQUIRE(str.length() == 8);
|
||||
char* ptr = (char*)str.c_str();
|
||||
ptr[3] = 0;
|
||||
String str2;
|
||||
str2 = str;
|
||||
REQUIRE(str2.length() == 8);
|
||||
// Needs a buffer pointer
|
||||
str = "0123456789012345678901234567890123456789";
|
||||
ptr = (char*)str.c_str();
|
||||
ptr[3] = 0;
|
||||
str2 = str;
|
||||
REQUIRE(str2.length() == 40);
|
||||
String str3("a");
|
||||
ptr = (char*)str3.c_str();
|
||||
*ptr = 0;
|
||||
REQUIRE(str3.length() == 1);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 2);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 4);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 8);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 16);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 32);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 64);
|
||||
static char zeros[64] = { 0 };
|
||||
const char* p = str3.c_str();
|
||||
REQUIRE(!memcmp(p, zeros, 64));
|
||||
}
|
||||
|
||||
TEST_CASE("Replace and string expansion", "[core][String]")
|
||||
{
|
||||
String s, l;
|
||||
// Make these large enough to span SSO and non SSO
|
||||
String whole = "#123456789012345678901234567890";
|
||||
const char *res = "abcde123456789012345678901234567890";
|
||||
for (size_t i=1; i < whole.length(); i++) {
|
||||
s = whole.substring(0, i);
|
||||
l = s;
|
||||
l.replace("#", "abcde");
|
||||
char buff[64];
|
||||
strcpy(buff, res);
|
||||
buff[5 + i-1] = 0;
|
||||
REQUIRE(!strcmp(l.c_str(), buff));
|
||||
REQUIRE(l.length() == strlen(buff));
|
||||
}
|
||||
String s, l;
|
||||
// Make these large enough to span SSO and non SSO
|
||||
String whole = "#123456789012345678901234567890";
|
||||
const char* res = "abcde123456789012345678901234567890";
|
||||
for (size_t i = 1; i < whole.length(); i++)
|
||||
{
|
||||
s = whole.substring(0, i);
|
||||
l = s;
|
||||
l.replace("#", "abcde");
|
||||
char buff[64];
|
||||
strcpy(buff, res);
|
||||
buff[5 + i - 1] = 0;
|
||||
REQUIRE(!strcmp(l.c_str(), buff));
|
||||
REQUIRE(l.length() == strlen(buff));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("String chaining", "[core][String]")
|
||||
{
|
||||
const char* chunks[] {
|
||||
"~12345",
|
||||
"67890",
|
||||
"qwertyuiopasdfghjkl",
|
||||
"zxcvbnm"
|
||||
};
|
||||
const char* chunks[] { "~12345", "67890", "qwertyuiopasdfghjkl", "zxcvbnm" };
|
||||
|
||||
String all;
|
||||
for (auto* chunk : chunks) {
|
||||
all += chunk;
|
||||
}
|
||||
String all;
|
||||
for (auto* chunk : chunks)
|
||||
{
|
||||
all += chunk;
|
||||
}
|
||||
|
||||
// make sure we can chain a combination of things to form a String
|
||||
REQUIRE((String(chunks[0]) + String(chunks[1]) + String(chunks[2]) + String(chunks[3])) == all);
|
||||
REQUIRE((chunks[0] + String(chunks[1]) + F(chunks[2]) + chunks[3]) == all);
|
||||
REQUIRE((String(chunks[0]) + F(chunks[1]) + F(chunks[2]) + String(chunks[3])) == all);
|
||||
REQUIRE(('~' + String(&chunks[0][0] + 1) + chunks[1] + String(chunks[2]) + F(chunks[3])) == all);
|
||||
REQUIRE((String(chunks[0]) + '6' + (&chunks[1][0] + 1) + String(chunks[2]) + F(chunks[3])) == all);
|
||||
// make sure we can chain a combination of things to form a String
|
||||
REQUIRE((String(chunks[0]) + String(chunks[1]) + String(chunks[2]) + String(chunks[3])) == all);
|
||||
REQUIRE((chunks[0] + String(chunks[1]) + F(chunks[2]) + chunks[3]) == all);
|
||||
REQUIRE((String(chunks[0]) + F(chunks[1]) + F(chunks[2]) + String(chunks[3])) == all);
|
||||
REQUIRE(('~' + String(&chunks[0][0] + 1) + chunks[1] + String(chunks[2]) + F(chunks[3]))
|
||||
== all);
|
||||
REQUIRE((String(chunks[0]) + '6' + (&chunks[1][0] + 1) + String(chunks[2]) + F(chunks[3]))
|
||||
== all);
|
||||
|
||||
// these are still invalid (and also cannot compile at all):
|
||||
// - `F(...)` + `F(...)`
|
||||
// - `F(...)` + `const char*`
|
||||
// - `const char*` + `F(...)`
|
||||
// we need `String()` as either rhs or lhs
|
||||
// these are still invalid (and also cannot compile at all):
|
||||
// - `F(...)` + `F(...)`
|
||||
// - `F(...)` + `const char*`
|
||||
// - `const char*` + `F(...)`
|
||||
// we need `String()` as either rhs or lhs
|
||||
|
||||
// ensure chaining reuses the buffer
|
||||
// (internal details...)
|
||||
{
|
||||
String tmp(chunks[3]);
|
||||
tmp.reserve(2 * all.length());
|
||||
auto* ptr = tmp.c_str();
|
||||
String result("~1" + String(&chunks[0][0] + 2) + F(chunks[1]) + chunks[2] + std::move(tmp));
|
||||
REQUIRE(result == all);
|
||||
REQUIRE(static_cast<const void*>(result.c_str()) == static_cast<const void*>(ptr));
|
||||
}
|
||||
// ensure chaining reuses the buffer
|
||||
// (internal details...)
|
||||
{
|
||||
String tmp(chunks[3]);
|
||||
tmp.reserve(2 * all.length());
|
||||
auto* ptr = tmp.c_str();
|
||||
String result("~1" + String(&chunks[0][0] + 2) + F(chunks[1]) + chunks[2] + std::move(tmp));
|
||||
REQUIRE(result == all);
|
||||
REQUIRE(static_cast<const void*>(result.c_str()) == static_cast<const void*>(ptr));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("String concat OOB #8198", "[core][String]")
|
||||
{
|
||||
char *p = (char*)malloc(16);
|
||||
char* p = (char*)malloc(16);
|
||||
memset(p, 'x', 16);
|
||||
String s = "abcd";
|
||||
s.concat(p, 16);
|
||||
|
Reference in New Issue
Block a user