blob: cd96681a2d46406d86a65396d1ea3a35557b4bfd [file] [log] [blame]
Wyatt Hepler80c6ee52020-01-03 09:54:58 -08001// Copyright 2020 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15#include "pw_tokenizer/tokenize.h"
16
17#include <cinttypes>
18#include <cstdint>
19#include <cstring>
20#include <iterator>
21
22#include "gtest/gtest.h"
23#include "pw_tokenizer/pw_tokenizer_65599_fixed_length_hash.h"
24#include "pw_tokenizer_private/tokenize_test.h"
25#include "pw_varint/varint.h"
26
27namespace pw::tokenizer {
28namespace {
29
30// The hash to use for this test. This makes sure the strings are shorter than
31// the configured max length to ensure this test works with any reasonable
32// configuration.
33template <size_t kSize>
34constexpr uint32_t TestHash(const char (&string)[kSize]) {
Wyatt Hepler7e587232020-08-28 07:51:29 -070035 constexpr unsigned kTestHashLength = 64;
Wyatt Hepler80c6ee52020-01-03 09:54:58 -080036 static_assert(kTestHashLength <= PW_TOKENIZER_CFG_HASH_LENGTH);
37 static_assert(kSize <= kTestHashLength + 1);
38 return PwTokenizer65599FixedLengthHash(std::string_view(string, kSize - 1),
39 kTestHashLength);
40}
41
42// Constructs an array with the hashed string followed by the provided bytes.
43template <uint8_t... kData, size_t kSize>
44constexpr auto ExpectedData(const char (&format)[kSize]) {
45 const uint32_t value = TestHash(format);
46 return std::array<uint8_t, sizeof(uint32_t) + sizeof...(kData)>{
47 static_cast<uint8_t>(value & 0xff),
48 static_cast<uint8_t>(value >> 8 & 0xff),
49 static_cast<uint8_t>(value >> 16 & 0xff),
50 static_cast<uint8_t>(value >> 24 & 0xff),
51 kData...};
52}
53
Wyatt Hepler7e587232020-08-28 07:51:29 -070054TEST(TokenizeString, EmptyString_IsZero) {
Wyatt Hepler80c6ee52020-01-03 09:54:58 -080055 constexpr pw_TokenizerStringToken token = PW_TOKENIZE_STRING("");
56 EXPECT_EQ(0u, token);
57}
58
Wyatt Hepler7e587232020-08-28 07:51:29 -070059TEST(TokenizeString, String_MatchesHash) {
Wyatt Hepler80c6ee52020-01-03 09:54:58 -080060 constexpr uint32_t token = PW_TOKENIZE_STRING("[:-)");
61 EXPECT_EQ(TestHash("[:-)"), token);
62}
63
64constexpr uint32_t kGlobalToken = PW_TOKENIZE_STRING(">:-[]");
65
Wyatt Hepler7e587232020-08-28 07:51:29 -070066TEST(TokenizeString, GlobalVariable_MatchesHash) {
Wyatt Hepler80c6ee52020-01-03 09:54:58 -080067 EXPECT_EQ(TestHash(">:-[]"), kGlobalToken);
68}
69
Wyatt Hepler7e587232020-08-28 07:51:29 -070070struct TokenizedWithinClass {
71 static constexpr uint32_t kThisToken = PW_TOKENIZE_STRING("???");
72};
73
74static_assert(TestHash("???") == TokenizedWithinClass::kThisToken);
75
76TEST(TokenizeString, ClassMember_MatchesHash) {
77 EXPECT_EQ(TestHash("???"), TokenizedWithinClass().kThisToken);
78}
79
80// Use a function with a shorter name to test tokenizing __func__ and
81// __PRETTY_FUNCTION__.
82//
83// WARNING: This function might cause errors for compilers other than GCC and
84// clang. It relies on two GCC/clang extensions:
85//
86// 1 - The __PRETTY_FUNCTION__ C++ function name variable.
87// 2 - __func__ as a static constexpr array instead of static const. See
88// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66639 for background.
89//
90void TestName() {
91 constexpr uint32_t function_hash = PW_TOKENIZE_STRING(__func__);
92 EXPECT_EQ(pw::tokenizer::TestHash(__func__), function_hash);
93
94 // Check the non-standard __PRETTY_FUNCTION__ name.
95 constexpr uint32_t pretty_function = PW_TOKENIZE_STRING(__PRETTY_FUNCTION__);
96 EXPECT_EQ(pw::tokenizer::TestHash(__PRETTY_FUNCTION__), pretty_function);
97}
98
99TEST(TokenizeString, FunctionName) { TestName(); }
100
101TEST(TokenizeString, Array) {
102 constexpr char array[] = "won-won-won-wonderful";
103
104 const uint32_t array_hash = PW_TOKENIZE_STRING(array);
105 EXPECT_EQ(TestHash(array), array_hash);
106}
107
Keir Mierle42f41f72020-08-05 00:15:56 -0700108// Verify that we can tokenize multiple strings from one source line.
109#define THREE_FOR_ONE(first, second, third) \
110 [[maybe_unused]] constexpr uint32_t token_1 = \
111 PW_TOKENIZE_STRING_DOMAIN("ignored", first); \
112 [[maybe_unused]] constexpr uint32_t token_2 = \
113 PW_TOKENIZE_STRING_DOMAIN("ignored", second); \
114 [[maybe_unused]] constexpr uint32_t token_3 = \
115 PW_TOKENIZE_STRING_DOMAIN("ignored", third);
116
Wyatt Hepler7e587232020-08-28 07:51:29 -0700117TEST(TokenizeString, MultipleTokenizationsInOneMacroExpansion) {
Keir Mierle42f41f72020-08-05 00:15:56 -0700118 // This verifies that we can safely tokenize multiple times in a single macro
119 // expansion. This can be useful when for example a name and description are
120 // both tokenized after being passed into a macro.
121 //
122 // This test only verifies that this compiles correctly; it does not test
123 // that the tokenizations make it to the final token database.
124 THREE_FOR_ONE("hello", "yes", "something");
125}
126
Wyatt Hepler80c6ee52020-01-03 09:54:58 -0800127class TokenizeToBuffer : public ::testing::Test {
128 public:
129 TokenizeToBuffer() : buffer_{} {}
130
131 protected:
132 uint8_t buffer_[64];
133};
134
135TEST_F(TokenizeToBuffer, Integer64) {
136 size_t message_size = 14;
137 PW_TOKENIZE_TO_BUFFER(
138 buffer_,
139 &message_size,
140 "%" PRIu64,
141 static_cast<uint64_t>(0x55555555'55555555ull)); // 0xAAAAAAAA'AAAAAAAA
142
143 // Pattern becomes 10101010'11010101'10101010 ...
144 constexpr std::array<uint8_t, 14> expected =
145 ExpectedData<0xAA, 0xD5, 0xAA, 0xD5, 0xAA, 0xD5, 0xAA, 0xD5, 0xAA, 0x01>(
146 "%" PRIu64);
147 ASSERT_EQ(expected.size(), message_size);
148 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
149}
150
151TEST_F(TokenizeToBuffer, Integer64Overflow) {
152 size_t message_size;
153
154 for (size_t size = 4; size < 20; ++size) {
155 message_size = size;
156
157 PW_TOKENIZE_TO_BUFFER(
158 buffer_,
159 &message_size,
160 "%" PRIx64,
161 static_cast<uint64_t>(std::numeric_limits<int64_t>::min()));
162
163 if (size < 14) {
164 constexpr std::array<uint8_t, 4> empty = ExpectedData("%" PRIx64);
165 ASSERT_EQ(sizeof(uint32_t), message_size);
166 EXPECT_EQ(std::memcmp(empty.data(), &buffer_, empty.size()), 0);
167
168 // Make sure nothing was written past the end of the buffer.
169 EXPECT_TRUE(std::all_of(&buffer_[size], std::end(buffer_), [](uint8_t v) {
170 return v == '\0';
171 }));
172 } else {
173 constexpr std::array<uint8_t, 14> expected =
174 ExpectedData<0xff,
175 0xff,
176 0xff,
177 0xff,
178 0xff,
179 0xff,
180 0xff,
181 0xff,
182 0xff,
183 0x01>("%" PRIx64);
184 ASSERT_EQ(expected.size(), message_size);
185 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
186 }
187 }
188}
189
190TEST_F(TokenizeToBuffer, IntegerNegative) {
191 size_t message_size = 9;
192 PW_TOKENIZE_TO_BUFFER(
193 buffer_, &message_size, "%" PRId32, std::numeric_limits<int32_t>::min());
194
195 // 0x8000'0000 -zig-zag-> 0xff'ff'ff'ff'0f
196 constexpr std::array<uint8_t, 9> expected =
197 ExpectedData<0xff, 0xff, 0xff, 0xff, 0x0f>("%" PRId32);
198 ASSERT_EQ(expected.size(), message_size);
199 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
200}
201
202TEST_F(TokenizeToBuffer, IntegerMin) {
203 size_t message_size = 9;
204 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "%d", -1);
205
206 constexpr std::array<uint8_t, 5> expected = ExpectedData<0x01>("%d");
207 ASSERT_EQ(expected.size(), message_size);
208 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
209}
210
211TEST_F(TokenizeToBuffer, IntegerDoesntFit) {
212 size_t message_size = 8;
213 PW_TOKENIZE_TO_BUFFER(
214 buffer_, &message_size, "%" PRId32, std::numeric_limits<int32_t>::min());
215
216 constexpr std::array<uint8_t, 4> expected = ExpectedData<>("%" PRId32);
217 ASSERT_EQ(expected.size(), message_size);
218 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
219}
220
221TEST_F(TokenizeToBuffer, String) {
222 size_t message_size = sizeof(buffer_);
223
224 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "The answer is: %s", "5432!");
225 constexpr std::array<uint8_t, 10> expected =
226 ExpectedData<5, '5', '4', '3', '2', '!'>("The answer is: %s");
227
228 ASSERT_EQ(expected.size(), message_size);
229 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
230}
231
232TEST_F(TokenizeToBuffer, String_BufferTooSmall_TruncatesAndSetsTopStatusBit) {
233 size_t message_size = 8;
234 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "The answer is: %s", "5432!");
235
236 constexpr std::array<uint8_t, 8> truncated_1 =
237 ExpectedData<0x83, '5', '4', '3'>("The answer is: %s");
238
239 ASSERT_EQ(truncated_1.size(), message_size);
240 EXPECT_EQ(std::memcmp(truncated_1.data(), buffer_, truncated_1.size()), 0);
241}
242
243TEST_F(TokenizeToBuffer, String_TwoBytesLeft_TruncatesToOneCharacter) {
244 size_t message_size = 6;
245 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "The answer is: %s", "5432!");
246
247 constexpr std::array<uint8_t, 6> truncated_2 =
248 ExpectedData<0x81, '5'>("The answer is: %s");
249
250 ASSERT_EQ(truncated_2.size(), message_size);
251 EXPECT_EQ(std::memcmp(truncated_2.data(), buffer_, truncated_2.size()), 0);
252}
253
254TEST_F(TokenizeToBuffer, String_OneByteLeft_OnlyWritesTruncatedStatusByte) {
255 size_t message_size = 5;
256 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "The answer is: %s", "5432!");
257
258 std::array<uint8_t, 5> result = ExpectedData<0x80>("The answer is: %s");
259 ASSERT_EQ(result.size(), message_size);
260 EXPECT_EQ(std::memcmp(result.data(), buffer_, result.size()), 0);
261}
262
263TEST_F(TokenizeToBuffer, EmptyString_OneByteLeft_EncodesCorrectly) {
264 size_t message_size = 5;
265 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "The answer is: %s", "");
266
267 std::array<uint8_t, 5> result = ExpectedData<0>("The answer is: %s");
268 ASSERT_EQ(result.size(), message_size);
269 EXPECT_EQ(std::memcmp(result.data(), buffer_, result.size()), 0);
270}
271
272TEST_F(TokenizeToBuffer, String_ZeroBytesLeft_WritesNothing) {
273 size_t message_size = 4;
274 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "The answer is: %s", "5432!");
275
276 constexpr std::array<uint8_t, 4> empty = ExpectedData<>("The answer is: %s");
277 ASSERT_EQ(empty.size(), message_size);
278 EXPECT_EQ(std::memcmp(empty.data(), buffer_, empty.size()), 0);
279}
280
Wyatt Hepler7e587232020-08-28 07:51:29 -0700281TEST_F(TokenizeToBuffer, Array) {
282 static constexpr char array[] = "1234";
283 size_t message_size = 4;
284 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, array);
285
286 constexpr std::array<uint8_t, 4> result = ExpectedData<>("1234");
287 ASSERT_EQ(result.size(), message_size);
288 EXPECT_EQ(std::memcmp(result.data(), buffer_, result.size()), 0);
289}
290
Wyatt Hepler80c6ee52020-01-03 09:54:58 -0800291TEST_F(TokenizeToBuffer, NullptrString_EncodesNull) {
292 char* string = nullptr;
293 size_t message_size = 9;
294 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "The answer is: %s", string);
295
296 std::array<uint8_t, 9> result =
297 ExpectedData<4, 'N', 'U', 'L', 'L'>("The answer is: %s");
298 ASSERT_EQ(result.size(), message_size);
299 EXPECT_EQ(std::memcmp(result.data(), buffer_, result.size()), 0);
300}
301
302TEST_F(TokenizeToBuffer, NullptrString_BufferTooSmall_EncodesTruncatedNull) {
303 char* string = nullptr;
304 size_t message_size = 6;
305 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "The answer is: %s", string);
306
307 std::array<uint8_t, 6> result = ExpectedData<0x81, 'N'>("The answer is: %s");
308 ASSERT_EQ(result.size(), message_size);
309 EXPECT_EQ(std::memcmp(result.data(), buffer_, result.size()), 0);
310}
311
Wyatt Heplerd58eef92020-05-08 10:39:56 -0700312TEST_F(TokenizeToBuffer, Domain_String) {
313 size_t message_size = sizeof(buffer_);
314
315 PW_TOKENIZE_TO_BUFFER_DOMAIN(
316 "TEST_DOMAIN", buffer_, &message_size, "The answer was: %s", "5432!");
317 constexpr std::array<uint8_t, 10> expected =
318 ExpectedData<5, '5', '4', '3', '2', '!'>("The answer was: %s");
319
320 ASSERT_EQ(expected.size(), message_size);
321 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
322}
323
Wyatt Hepler80c6ee52020-01-03 09:54:58 -0800324TEST_F(TokenizeToBuffer, TruncateArgs) {
325 // Args that can't fit are dropped completely
326 size_t message_size = 6;
327 PW_TOKENIZE_TO_BUFFER(buffer_,
328 &message_size,
329 "%u %d",
330 static_cast<uint8_t>(0b0010'1010u),
331 0xffffff);
332
333 constexpr std::array<uint8_t, 5> expected =
334 ExpectedData<0b0101'0100u>("%u %d");
335 ASSERT_EQ(expected.size(), message_size);
336 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
337}
338
339TEST_F(TokenizeToBuffer, NoRoomForToken) {
340 // Nothing is written if there isn't room for the token.
341 std::memset(buffer_, '$', sizeof(buffer_));
342 auto is_untouched = [](uint8_t v) { return v == '$'; };
343
344 size_t message_size = 3;
345 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "The answer: \"%s\"", "5432!");
346 EXPECT_EQ(0u, message_size);
347 EXPECT_TRUE(std::all_of(buffer_, std::end(buffer_), is_untouched));
348
349 message_size = 2;
350 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "Jello, world!");
351 EXPECT_EQ(0u, message_size);
352 EXPECT_TRUE(std::all_of(buffer_, std::end(buffer_), is_untouched));
353
354 message_size = 1;
355 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "Jello!");
356 EXPECT_EQ(0u, message_size);
357 EXPECT_TRUE(std::all_of(buffer_, std::end(buffer_), is_untouched));
358
359 message_size = 0;
360 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "Jello?");
361 EXPECT_EQ(0u, message_size);
362 EXPECT_TRUE(std::all_of(buffer_, std::end(buffer_), is_untouched));
363}
364
365TEST_F(TokenizeToBuffer, C_StringShortFloat) {
366 size_t size = sizeof(buffer_);
367 pw_TokenizeToBufferTest_StringShortFloat(buffer_, &size);
368 constexpr std::array<uint8_t, 11> expected = // clang-format off
369 ExpectedData<1, '1', // string '1'
370 3, // -2 (zig-zag encoded)
371 0x00, 0x00, 0x40, 0x40 // 3.0 in floating point
372 >(TEST_FORMAT_STRING_SHORT_FLOAT);
373 ASSERT_EQ(expected.size(), size); // clang-format on
374 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
375}
376
377TEST_F(TokenizeToBuffer, C_SequentialZigZag) {
378 size_t size = sizeof(buffer_);
379 pw_TokenizeToBufferTest_SequentialZigZag(buffer_, &size);
380 constexpr std::array<uint8_t, 18> expected =
381 ExpectedData<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13>(
382 TEST_FORMAT_SEQUENTIAL_ZIG_ZAG);
383
384 ASSERT_EQ(expected.size(), size);
385 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
386}
387
388TEST_F(TokenizeToBuffer, C_Overflow) {
389 std::memset(buffer_, '$', sizeof(buffer_));
390
391 {
392 size_t size = 7;
393 pw_TokenizeToBufferTest_Requires8(buffer_, &size);
394 constexpr std::array<uint8_t, 7> expected =
395 ExpectedData<2, 'h', 'i'>(TEST_FORMAT_REQUIRES_8);
396 ASSERT_EQ(expected.size(), size);
397 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
398 EXPECT_EQ(buffer_[7], '$');
399 }
400
401 {
402 size_t size = 8;
403 pw_TokenizeToBufferTest_Requires8(buffer_, &size);
404 constexpr std::array<uint8_t, 8> expected =
405 ExpectedData<2, 'h', 'i', 13>(TEST_FORMAT_REQUIRES_8);
406 ASSERT_EQ(expected.size(), size);
407 EXPECT_EQ(std::memcmp(expected.data(), buffer_, expected.size()), 0);
408 EXPECT_EQ(buffer_[8], '$');
409 }
410}
411
412// Test fixture for callback and global handler. Both of these need a global
413// message buffer. To keep the message buffers separate, template this on the
414// derived class type.
415template <typename Impl>
416class GlobalMessage : public ::testing::Test {
417 public:
418 static void SetMessage(const uint8_t* message, size_t size) {
419 ASSERT_LE(size, sizeof(message_));
420 std::memcpy(message_, message, size);
421 message_size_bytes_ = size;
422 }
423
424 protected:
425 GlobalMessage() {
426 std::memset(message_, 0, sizeof(message_));
427 message_size_bytes_ = 0;
428 }
429
430 static uint8_t message_[256];
431 static size_t message_size_bytes_;
432};
433
434template <typename Impl>
435uint8_t GlobalMessage<Impl>::message_[256] = {};
436template <typename Impl>
437size_t GlobalMessage<Impl>::message_size_bytes_ = 0;
438
439class TokenizeToCallback : public GlobalMessage<TokenizeToCallback> {};
440
441TEST_F(TokenizeToCallback, Variety) {
442 PW_TOKENIZE_TO_CALLBACK(
443 SetMessage, "%s there are %x (%.2f) of them%c", "Now", 2u, 2.0f, '.');
444 const auto expected = // clang-format off
445 ExpectedData<3, 'N', 'o', 'w', // string "Now"
446 0x04, // unsigned 2 (zig-zag encoded)
447 0x00, 0x00, 0x00, 0x40, // float 2.0
448 0x5C // char '.' (0x2E, zig-zag encoded)
449 >("%s there are %x (%.2f) of them%c");
450 // clang-format on
451 ASSERT_EQ(expected.size(), message_size_bytes_);
452 EXPECT_EQ(std::memcmp(expected.data(), message_, expected.size()), 0);
453}
454
455TEST_F(TokenizeToCallback, Strings) {
456 PW_TOKENIZE_TO_CALLBACK(SetMessage, "The answer is: %s", "5432!");
457 constexpr std::array<uint8_t, 10> expected =
458 ExpectedData<5, '5', '4', '3', '2', '!'>("The answer is: %s");
459 ASSERT_EQ(expected.size(), message_size_bytes_);
460 EXPECT_EQ(std::memcmp(expected.data(), message_, expected.size()), 0);
461}
462
Wyatt Heplerd58eef92020-05-08 10:39:56 -0700463TEST_F(TokenizeToCallback, Domain_Strings) {
464 PW_TOKENIZE_TO_CALLBACK_DOMAIN(
465 "TEST_DOMAIN", SetMessage, "The answer is: %s", "5432!");
466 constexpr std::array<uint8_t, 10> expected =
467 ExpectedData<5, '5', '4', '3', '2', '!'>("The answer is: %s");
468 ASSERT_EQ(expected.size(), message_size_bytes_);
469 EXPECT_EQ(std::memcmp(expected.data(), message_, expected.size()), 0);
470}
471
Wyatt Hepler80c6ee52020-01-03 09:54:58 -0800472TEST_F(TokenizeToCallback, C_SequentialZigZag) {
473 pw_TokenizeToCallbackTest_SequentialZigZag(SetMessage);
474
475 constexpr std::array<uint8_t, 18> expected =
476 ExpectedData<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13>(
477 TEST_FORMAT_SEQUENTIAL_ZIG_ZAG);
478 ASSERT_EQ(expected.size(), message_size_bytes_);
479 EXPECT_EQ(std::memcmp(expected.data(), message_, expected.size()), 0);
480}
481
Wyatt Heplerd58eef92020-05-08 10:39:56 -0700482// Hijack the PW_TOKENIZE_STRING_DOMAIN macro to capture the domain name.
483#undef PW_TOKENIZE_STRING_DOMAIN
484#define PW_TOKENIZE_STRING_DOMAIN(domain, string) \
485 /* assigned to a variable */ PW_TOKENIZER_STRING_TOKEN(string); \
486 tokenizer_domain = domain; \
487 string_literal = string
488
489TEST_F(TokenizeToBuffer, Domain_Default) {
490 const char* tokenizer_domain = nullptr;
491 const char* string_literal = nullptr;
492
493 size_t message_size = sizeof(buffer_);
494
495 PW_TOKENIZE_TO_BUFFER(buffer_, &message_size, "The answer is: %s", "5432!");
496
497 EXPECT_STREQ(tokenizer_domain, PW_TOKENIZER_DEFAULT_DOMAIN);
498 EXPECT_STREQ(string_literal, "The answer is: %s");
499}
500
501TEST_F(TokenizeToBuffer, Domain_Specified) {
502 const char* tokenizer_domain = nullptr;
503 const char* string_literal = nullptr;
504
505 size_t message_size = sizeof(buffer_);
506
507 PW_TOKENIZE_TO_BUFFER_DOMAIN(
508 "._.", buffer_, &message_size, "The answer is: %s", "5432!");
509
510 EXPECT_STREQ(tokenizer_domain, "._.");
511 EXPECT_STREQ(string_literal, "The answer is: %s");
512}
513
514TEST_F(TokenizeToCallback, Domain_Default) {
515 const char* tokenizer_domain = nullptr;
516 const char* string_literal = nullptr;
517
518 PW_TOKENIZE_TO_CALLBACK(SetMessage, "The answer is: %s", "5432!");
519
520 EXPECT_STREQ(tokenizer_domain, PW_TOKENIZER_DEFAULT_DOMAIN);
521 EXPECT_STREQ(string_literal, "The answer is: %s");
522}
523
524TEST_F(TokenizeToCallback, Domain_Specified) {
525 const char* tokenizer_domain = nullptr;
526 const char* string_literal = nullptr;
527
528 PW_TOKENIZE_TO_CALLBACK_DOMAIN(
529 "ThisIsTheDomain", SetMessage, "The answer is: %s", "5432!");
530
531 EXPECT_STREQ(tokenizer_domain, "ThisIsTheDomain");
532 EXPECT_STREQ(string_literal, "The answer is: %s");
533}
534
Wyatt Hepler80c6ee52020-01-03 09:54:58 -0800535} // namespace
536} // namespace pw::tokenizer