66#include < catch.hpp>
77
88#include " Allocators.hpp"
9+ #include " Literals.hpp"
910
1011using namespace ArduinoJson ::detail;
1112
@@ -16,9 +17,10 @@ TEST_CASE("StringBuilder") {
1617
1718 SECTION (" Empty string" ) {
1819 StringBuilder str (&resources);
20+ VariantData data;
1921
2022 str.startString ();
21- str.save ();
23+ str.save (&data );
2224
2325 REQUIRE (resources.size () == sizeofString (" " ));
2426 REQUIRE (resources.overflowed () == false );
@@ -96,48 +98,69 @@ TEST_CASE("StringBuilder") {
9698 }
9799}
98100
99- static StringNode* addStringToPool (ResourceManager& resources, const char * s) {
100- StringBuilder str (&resources);
101- str.startString ();
102- str.append (s);
103- return str.save ();
101+ static const char * saveString (StringBuilder& builder, const char * s) {
102+ VariantData data;
103+ builder.startString ();
104+ builder.append (s);
105+ builder.save (&data);
106+ return data.asString ().c_str ();
104107}
105108
106109TEST_CASE (" StringBuilder::save() deduplicates strings" ) {
107- ResourceManager resources;
110+ SpyingAllocator spy;
111+ ResourceManager resources (&spy);
112+ StringBuilder builder (&resources);
108113
109114 SECTION (" Basic" ) {
110- auto s1 = addStringToPool (resources, " hello" );
111- auto s2 = addStringToPool (resources, " world" );
112- auto s3 = addStringToPool (resources, " hello" );
113-
114- REQUIRE (s1 == s3);
115- REQUIRE (s2 != s3);
116- REQUIRE (s1->references == 2 );
117- REQUIRE (s2->references == 1 );
118- REQUIRE (s3->references == 2 );
119- REQUIRE (resources.size () == sizeofString (" hello" ) + sizeofString (" world" ));
115+ auto s1 = saveString (builder, " hello" );
116+ auto s2 = saveString (builder, " world" );
117+ auto s3 = saveString (builder, " hello" );
118+
119+ REQUIRE (s1 == " hello" _s);
120+ REQUIRE (s2 == " world" _s);
121+ REQUIRE (+s1 == +s3); // same address
122+
123+ REQUIRE (spy.log () ==
124+ AllocatorLog{
125+ Allocate (sizeofStringBuffer ()),
126+ Reallocate (sizeofStringBuffer (), sizeofString (" hello" )),
127+ Allocate (sizeofStringBuffer ()),
128+ Reallocate (sizeofStringBuffer (), sizeofString (" world" )),
129+ Allocate (sizeofStringBuffer ()),
130+ });
120131 }
121132
122133 SECTION (" Requires terminator" ) {
123- auto s1 = addStringToPool (resources , " hello world" );
124- auto s2 = addStringToPool (resources , " hello" );
134+ auto s1 = saveString (builder , " hello world" );
135+ auto s2 = saveString (builder , " hello" );
125136
126- REQUIRE (s2 != s1);
127- REQUIRE (s1->references == 1 );
128- REQUIRE (s2->references == 1 );
129- REQUIRE (resources.size () ==
130- sizeofString (" hello world" ) + sizeofString (" hello" ));
137+ REQUIRE (s1 == " hello world" _s);
138+ REQUIRE (s2 == " hello" _s);
139+ REQUIRE (+s2 != +s1); // different address
140+
141+ REQUIRE (spy.log () ==
142+ AllocatorLog{
143+ Allocate (sizeofStringBuffer ()),
144+ Reallocate (sizeofStringBuffer (), sizeofString (" hello world" )),
145+ Allocate (sizeofStringBuffer ()),
146+ Reallocate (sizeofStringBuffer (), sizeofString (" hello" )),
147+ });
131148 }
132149
133150 SECTION (" Don't overrun" ) {
134- auto s1 = addStringToPool (resources , " hello world" );
135- auto s2 = addStringToPool (resources , " wor" );
151+ auto s1 = saveString (builder , " hello world" );
152+ auto s2 = saveString (builder , " wor" );
136153
154+ REQUIRE (s1 == " hello world" _s);
155+ REQUIRE (s2 == " wor" _s);
137156 REQUIRE (s2 != s1);
138- REQUIRE (s1->references == 1 );
139- REQUIRE (s2->references == 1 );
140- REQUIRE (resources.size () ==
141- sizeofString (" hello world" ) + sizeofString (" wor" ));
157+
158+ REQUIRE (spy.log () ==
159+ AllocatorLog{
160+ Allocate (sizeofStringBuffer ()),
161+ Reallocate (sizeofStringBuffer (), sizeofString (" hello world" )),
162+ Allocate (sizeofStringBuffer ()),
163+ Reallocate (sizeofStringBuffer (), sizeofString (" wor" )),
164+ });
142165 }
143166}
0 commit comments