1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17
18 #include <cstdint>
19 #include <cstring>
20 #include <memory>
21 #include <sstream>
22 #include <string>
23 #include <vector>
24
25 #include <gtest/gtest.h>
26
27 #include "arrow/array.h"
28 #include "arrow/builder.h"
29 #include "arrow/pretty_print.h"
30 #include "arrow/table.h"
31 #include "arrow/testing/gtest_util.h"
32 #include "arrow/type.h"
33 #include "arrow/util/key_value_metadata.h"
34
35 namespace arrow {
36
37 class TestPrettyPrint : public ::testing::Test {
38 public:
SetUp()39 void SetUp() {}
40
Print(const Array & array)41 void Print(const Array& array) {}
42
43 private:
44 std::ostringstream sink_;
45 };
46
47 template <typename T>
CheckStream(const T & obj,const PrettyPrintOptions & options,const char * expected)48 void CheckStream(const T& obj, const PrettyPrintOptions& options, const char* expected) {
49 std::ostringstream sink;
50 ASSERT_OK(PrettyPrint(obj, options, &sink));
51 std::string result = sink.str();
52 ASSERT_EQ(std::string(expected, strlen(expected)), result);
53 }
54
CheckArray(const Array & arr,const PrettyPrintOptions & options,const char * expected,bool check_operator=true)55 void CheckArray(const Array& arr, const PrettyPrintOptions& options, const char* expected,
56 bool check_operator = true) {
57 CheckStream(arr, options, expected);
58
59 if (options.indent == 0 && check_operator) {
60 std::stringstream ss;
61 ss << arr;
62 std::string result = std::string(expected, strlen(expected));
63 ASSERT_EQ(result, ss.str());
64 }
65 }
66
67 template <typename T>
Check(const T & obj,const PrettyPrintOptions & options,const char * expected)68 void Check(const T& obj, const PrettyPrintOptions& options, const char* expected) {
69 std::string result;
70 ASSERT_OK(PrettyPrint(obj, options, &result));
71 ASSERT_EQ(std::string(expected, strlen(expected)), result);
72 }
73
74 template <typename TYPE, typename C_TYPE>
CheckPrimitive(const std::shared_ptr<DataType> & type,const PrettyPrintOptions & options,const std::vector<bool> & is_valid,const std::vector<C_TYPE> & values,const char * expected,bool check_operator=true)75 void CheckPrimitive(const std::shared_ptr<DataType>& type,
76 const PrettyPrintOptions& options, const std::vector<bool>& is_valid,
77 const std::vector<C_TYPE>& values, const char* expected,
78 bool check_operator = true) {
79 std::shared_ptr<Array> array;
80 ArrayFromVector<TYPE, C_TYPE>(type, is_valid, values, &array);
81 CheckArray(*array, options, expected, check_operator);
82 }
83
84 template <typename TYPE, typename C_TYPE>
CheckPrimitive(const PrettyPrintOptions & options,const std::vector<bool> & is_valid,const std::vector<C_TYPE> & values,const char * expected,bool check_operator=true)85 void CheckPrimitive(const PrettyPrintOptions& options, const std::vector<bool>& is_valid,
86 const std::vector<C_TYPE>& values, const char* expected,
87 bool check_operator = true) {
88 CheckPrimitive<TYPE, C_TYPE>(TypeTraits<TYPE>::type_singleton(), options, is_valid,
89 values, expected, check_operator);
90 }
91
TEST_F(TestPrettyPrint,PrimitiveType)92 TEST_F(TestPrettyPrint, PrimitiveType) {
93 std::vector<bool> is_valid = {true, true, false, true, false};
94
95 std::vector<int32_t> values = {0, 1, 2, 3, 4};
96 static const char* expected = R"expected([
97 0,
98 1,
99 null,
100 3,
101 null
102 ])expected";
103 CheckPrimitive<Int32Type, int32_t>({0, 10}, is_valid, values, expected);
104
105 static const char* expected_na = R"expected([
106 0,
107 1,
108 NA,
109 3,
110 NA
111 ])expected";
112 CheckPrimitive<Int32Type, int32_t>({0, 10, 2, "NA"}, is_valid, values, expected_na,
113 false);
114
115 static const char* ex_in2 = R"expected( [
116 0,
117 1,
118 null,
119 3,
120 null
121 ])expected";
122 CheckPrimitive<Int32Type, int32_t>({2, 10}, is_valid, values, ex_in2);
123 static const char* ex_in2_w2 = R"expected( [
124 0,
125 1,
126 ...
127 3,
128 null
129 ])expected";
130 CheckPrimitive<Int32Type, int32_t>({2, 2}, is_valid, values, ex_in2_w2);
131
132 std::vector<double> values2 = {0., 1., 2., 3., 4.};
133 static const char* ex2 = R"expected([
134 0,
135 1,
136 null,
137 3,
138 null
139 ])expected";
140 CheckPrimitive<DoubleType, double>({0, 10}, is_valid, values2, ex2);
141 static const char* ex2_in2 = R"expected( [
142 0,
143 1,
144 null,
145 3,
146 null
147 ])expected";
148 CheckPrimitive<DoubleType, double>({2, 10}, is_valid, values2, ex2_in2);
149
150 std::vector<std::string> values3 = {"foo", "bar", "", "baz", ""};
151 static const char* ex3 = R"expected([
152 "foo",
153 "bar",
154 null,
155 "baz",
156 null
157 ])expected";
158 CheckPrimitive<StringType, std::string>({0, 10}, is_valid, values3, ex3);
159 CheckPrimitive<LargeStringType, std::string>({0, 10}, is_valid, values3, ex3);
160 static const char* ex3_in2 = R"expected( [
161 "foo",
162 "bar",
163 null,
164 "baz",
165 null
166 ])expected";
167 CheckPrimitive<StringType, std::string>({2, 10}, is_valid, values3, ex3_in2);
168 CheckPrimitive<LargeStringType, std::string>({2, 10}, is_valid, values3, ex3_in2);
169 }
170
TEST_F(TestPrettyPrint,Int8)171 TEST_F(TestPrettyPrint, Int8) {
172 static const char* expected = R"expected([
173 0,
174 127,
175 -128
176 ])expected";
177 CheckPrimitive<Int8Type, int8_t>({0, 10}, {true, true, true}, {0, 127, -128}, expected);
178 }
179
TEST_F(TestPrettyPrint,UInt8)180 TEST_F(TestPrettyPrint, UInt8) {
181 static const char* expected = R"expected([
182 0,
183 255
184 ])expected";
185 CheckPrimitive<UInt8Type, uint8_t>({0, 10}, {true, true}, {0, 255}, expected);
186 }
187
TEST_F(TestPrettyPrint,Int64)188 TEST_F(TestPrettyPrint, Int64) {
189 static const char* expected = R"expected([
190 0,
191 9223372036854775807,
192 -9223372036854775808
193 ])expected";
194 CheckPrimitive<Int64Type, int64_t>(
195 {0, 10}, {true, true, true}, {0, 9223372036854775807LL, -9223372036854775807LL - 1},
196 expected);
197 }
198
TEST_F(TestPrettyPrint,UInt64)199 TEST_F(TestPrettyPrint, UInt64) {
200 static const char* expected = R"expected([
201 0,
202 9223372036854775803,
203 18446744073709551615
204 ])expected";
205 CheckPrimitive<UInt64Type, uint64_t>(
206 {0, 10}, {true, true, true}, {0, 9223372036854775803ULL, 18446744073709551615ULL},
207 expected);
208 }
209
TEST_F(TestPrettyPrint,DateTimeTypes)210 TEST_F(TestPrettyPrint, DateTimeTypes) {
211 std::vector<bool> is_valid = {true, true, false, true, false};
212
213 {
214 std::vector<int32_t> values = {0, 1, 2, 31, 4};
215 static const char* expected = R"expected([
216 1970-01-01,
217 1970-01-02,
218 null,
219 1970-02-01,
220 null
221 ])expected";
222 CheckPrimitive<Date32Type, int32_t>({0, 10}, is_valid, values, expected);
223 }
224
225 {
226 constexpr int64_t ms_per_day = 24 * 60 * 60 * 1000;
227 std::vector<int64_t> values = {0 * ms_per_day, 1 * ms_per_day, 2 * ms_per_day,
228 31 * ms_per_day, 4 * ms_per_day};
229 static const char* expected = R"expected([
230 1970-01-01,
231 1970-01-02,
232 null,
233 1970-02-01,
234 null
235 ])expected";
236 CheckPrimitive<Date64Type, int64_t>({0, 10}, is_valid, values, expected);
237 }
238
239 {
240 std::vector<int64_t> values = {
241 0, 1, 2, 678 + 1000000 * (5 + 60 * (4 + 60 * (3 + 24 * int64_t(1)))), 4};
242 static const char* expected = R"expected([
243 1970-01-01 00:00:00.000000,
244 1970-01-01 00:00:00.000001,
245 null,
246 1970-01-02 03:04:05.000678,
247 null
248 ])expected";
249 CheckPrimitive<TimestampType, int64_t>(timestamp(TimeUnit::MICRO, "Transylvania"),
250 {0, 10}, is_valid, values, expected);
251 }
252
253 {
254 std::vector<int32_t> values = {1, 62, 2, 3 + 60 * (2 + 60 * 1), 4};
255 static const char* expected = R"expected([
256 00:00:01,
257 00:01:02,
258 null,
259 01:02:03,
260 null
261 ])expected";
262 CheckPrimitive<Time32Type, int32_t>(time32(TimeUnit::SECOND), {0, 10}, is_valid,
263 values, expected);
264 }
265
266 {
267 std::vector<int64_t> values = {
268 0, 1, 2, 678 + int64_t(1000000000) * (5 + 60 * (4 + 60 * 3)), 4};
269 static const char* expected = R"expected([
270 00:00:00.000000000,
271 00:00:00.000000001,
272 null,
273 03:04:05.000000678,
274 null
275 ])expected";
276 CheckPrimitive<Time64Type, int64_t>(time64(TimeUnit::NANO), {0, 10}, is_valid, values,
277 expected);
278 }
279 }
280
TEST_F(TestPrettyPrint,StructTypeBasic)281 TEST_F(TestPrettyPrint, StructTypeBasic) {
282 auto simple_1 = field("one", int32());
283 auto simple_2 = field("two", int32());
284 auto simple_struct = struct_({simple_1, simple_2});
285
286 auto array = ArrayFromJSON(simple_struct, "[[11, 22]]");
287
288 static const char* ex = R"expected(-- is_valid: all not null
289 -- child 0 type: int32
290 [
291 11
292 ]
293 -- child 1 type: int32
294 [
295 22
296 ])expected";
297 CheckStream(*array, {0, 10}, ex);
298
299 static const char* ex_2 = R"expected( -- is_valid: all not null
300 -- child 0 type: int32
301 [
302 11
303 ]
304 -- child 1 type: int32
305 [
306 22
307 ])expected";
308 CheckStream(*array, {2, 10}, ex_2);
309 }
310
TEST_F(TestPrettyPrint,StructTypeAdvanced)311 TEST_F(TestPrettyPrint, StructTypeAdvanced) {
312 auto simple_1 = field("one", int32());
313 auto simple_2 = field("two", int32());
314 auto simple_struct = struct_({simple_1, simple_2});
315
316 auto array = ArrayFromJSON(simple_struct, "[[11, 22], null, [null, 33]]");
317
318 static const char* ex = R"expected(-- is_valid:
319 [
320 true,
321 false,
322 true
323 ]
324 -- child 0 type: int32
325 [
326 11,
327 null,
328 null
329 ]
330 -- child 1 type: int32
331 [
332 22,
333 null,
334 33
335 ])expected";
336 CheckStream(*array, {0, 10}, ex);
337 }
338
TEST_F(TestPrettyPrint,BinaryType)339 TEST_F(TestPrettyPrint, BinaryType) {
340 std::vector<bool> is_valid = {true, true, false, true, true, true};
341 std::vector<std::string> values = {"foo", "bar", "", "baz", "", "\xff"};
342 static const char* ex = "[\n 666F6F,\n 626172,\n null,\n 62617A,\n ,\n FF\n]";
343 CheckPrimitive<BinaryType, std::string>({0}, is_valid, values, ex);
344 CheckPrimitive<LargeBinaryType, std::string>({0}, is_valid, values, ex);
345 static const char* ex_in2 =
346 " [\n 666F6F,\n 626172,\n null,\n 62617A,\n ,\n FF\n ]";
347 CheckPrimitive<BinaryType, std::string>({2}, is_valid, values, ex_in2);
348 CheckPrimitive<LargeBinaryType, std::string>({2}, is_valid, values, ex_in2);
349 }
350
TEST_F(TestPrettyPrint,ListType)351 TEST_F(TestPrettyPrint, ListType) {
352 auto list_type = list(int64());
353
354 static const char* ex = R"expected([
355 [
356 null
357 ],
358 [],
359 null,
360 [
361 4,
362 6,
363 7
364 ],
365 [
366 2,
367 3
368 ]
369 ])expected";
370 static const char* ex_2 = R"expected( [
371 [
372 null
373 ],
374 [],
375 null,
376 [
377 4,
378 6,
379 7
380 ],
381 [
382 2,
383 3
384 ]
385 ])expected";
386 static const char* ex_3 = R"expected([
387 [
388 null
389 ],
390 ...
391 [
392 2,
393 3
394 ]
395 ])expected";
396
397 auto array = ArrayFromJSON(list_type, "[[null], [], null, [4, 6, 7], [2, 3]]");
398 CheckArray(*array, {0, 10}, ex);
399 CheckArray(*array, {2, 10}, ex_2);
400 CheckStream(*array, {0, 1}, ex_3);
401
402 list_type = large_list(int64());
403 array = ArrayFromJSON(list_type, "[[null], [], null, [4, 6, 7], [2, 3]]");
404 CheckArray(*array, {0, 10}, ex);
405 CheckArray(*array, {2, 10}, ex_2);
406 CheckStream(*array, {0, 1}, ex_3);
407 }
408
TEST_F(TestPrettyPrint,MapType)409 TEST_F(TestPrettyPrint, MapType) {
410 auto map_type = map(utf8(), int64());
411 auto array = ArrayFromJSON(map_type, R"([
412 [["joe", 0], ["mark", null]],
413 null,
414 [["cap", 8]],
415 []
416 ])");
417
418 static const char* ex = R"expected([
419 keys:
420 [
421 "joe",
422 "mark"
423 ]
424 values:
425 [
426 0,
427 null
428 ],
429 null,
430 keys:
431 [
432 "cap"
433 ]
434 values:
435 [
436 8
437 ],
438 keys:
439 []
440 values:
441 []
442 ])expected";
443 CheckArray(*array, {0, 10}, ex);
444 }
445
TEST_F(TestPrettyPrint,FixedSizeListType)446 TEST_F(TestPrettyPrint, FixedSizeListType) {
447 auto list_type = fixed_size_list(int32(), 3);
448 auto array = ArrayFromJSON(list_type,
449 "[[null, 0, 1], [2, 3, null], null, [4, 6, 7], [8, 9, 5]]");
450
451 CheckArray(*array, {0, 10}, R"expected([
452 [
453 null,
454 0,
455 1
456 ],
457 [
458 2,
459 3,
460 null
461 ],
462 null,
463 [
464 4,
465 6,
466 7
467 ],
468 [
469 8,
470 9,
471 5
472 ]
473 ])expected");
474 CheckStream(*array, {0, 1}, R"expected([
475 [
476 null,
477 ...
478 1
479 ],
480 ...
481 [
482 8,
483 ...
484 5
485 ]
486 ])expected");
487 }
488
TEST_F(TestPrettyPrint,FixedSizeBinaryType)489 TEST_F(TestPrettyPrint, FixedSizeBinaryType) {
490 std::vector<bool> is_valid = {true, true, false, true, false};
491
492 auto type = fixed_size_binary(3);
493 auto array = ArrayFromJSON(type, "[\"foo\", \"bar\", null, \"baz\"]");
494
495 static const char* ex = "[\n 666F6F,\n 626172,\n null,\n 62617A\n]";
496 CheckArray(*array, {0, 10}, ex);
497 static const char* ex_2 = " [\n 666F6F,\n ...\n 62617A\n ]";
498 CheckArray(*array, {2, 1}, ex_2);
499 }
500
TEST_F(TestPrettyPrint,Decimal128Type)501 TEST_F(TestPrettyPrint, Decimal128Type) {
502 int32_t p = 19;
503 int32_t s = 4;
504
505 auto type = decimal(p, s);
506 auto array = ArrayFromJSON(type, "[\"123.4567\", \"456.7891\", null]");
507
508 static const char* ex = "[\n 123.4567,\n 456.7891,\n null\n]";
509 CheckArray(*array, {0}, ex);
510 }
511
TEST_F(TestPrettyPrint,DictionaryType)512 TEST_F(TestPrettyPrint, DictionaryType) {
513 std::vector<bool> is_valid = {true, true, false, true, true, true};
514
515 std::shared_ptr<Array> dict;
516 std::vector<std::string> dict_values = {"foo", "bar", "baz"};
517 ArrayFromVector<StringType, std::string>(dict_values, &dict);
518 std::shared_ptr<DataType> dict_type = dictionary(int16(), utf8());
519
520 std::shared_ptr<Array> indices;
521 std::vector<int16_t> indices_values = {1, 2, -1, 0, 2, 0};
522 ArrayFromVector<Int16Type, int16_t>(is_valid, indices_values, &indices);
523 auto arr = std::make_shared<DictionaryArray>(dict_type, indices, dict);
524
525 static const char* expected = R"expected(
526 -- dictionary:
527 [
528 "foo",
529 "bar",
530 "baz"
531 ]
532 -- indices:
533 [
534 1,
535 2,
536 null,
537 0,
538 2,
539 0
540 ])expected";
541
542 CheckArray(*arr, {0}, expected);
543 }
544
TEST_F(TestPrettyPrint,ChunkedArrayPrimitiveType)545 TEST_F(TestPrettyPrint, ChunkedArrayPrimitiveType) {
546 auto array = ArrayFromJSON(int32(), "[0, 1, null, 3, null]");
547 ChunkedArray chunked_array(array);
548
549 static const char* expected = R"expected([
550 [
551 0,
552 1,
553 null,
554 3,
555 null
556 ]
557 ])expected";
558 CheckStream(chunked_array, {0}, expected);
559
560 ChunkedArray chunked_array_2({array, array});
561
562 static const char* expected_2 = R"expected([
563 [
564 0,
565 1,
566 null,
567 3,
568 null
569 ],
570 [
571 0,
572 1,
573 null,
574 3,
575 null
576 ]
577 ])expected";
578
579 CheckStream(chunked_array_2, {0}, expected_2);
580 }
581
TEST_F(TestPrettyPrint,TablePrimitive)582 TEST_F(TestPrettyPrint, TablePrimitive) {
583 std::shared_ptr<Field> int_field = field("column", int32());
584 auto array = ArrayFromJSON(int_field->type(), "[0, 1, null, 3, null]");
585 auto column = std::make_shared<ChunkedArray>(ArrayVector({array}));
586 std::shared_ptr<Schema> table_schema = schema({int_field});
587 std::shared_ptr<Table> table = Table::Make(table_schema, {column});
588
589 static const char* expected = R"expected(column: int32
590 ----
591 column:
592 [
593 [
594 0,
595 1,
596 null,
597 3,
598 null
599 ]
600 ]
601 )expected";
602 CheckStream(*table, {0}, expected);
603 }
604
TEST_F(TestPrettyPrint,SchemaWithDictionary)605 TEST_F(TestPrettyPrint, SchemaWithDictionary) {
606 std::vector<bool> is_valid = {true, true, false, true, true, true};
607
608 std::shared_ptr<Array> dict;
609 std::vector<std::string> dict_values = {"foo", "bar", "baz"};
610 ArrayFromVector<StringType, std::string>(dict_values, &dict);
611
612 auto simple = field("one", int32());
613 auto simple_dict = field("two", dictionary(int16(), utf8()));
614 auto list_of_dict = field("three", list(simple_dict));
615 auto struct_with_dict = field("four", struct_({simple, simple_dict}));
616
617 auto sch = schema({simple, simple_dict, list_of_dict, struct_with_dict});
618
619 static const char* expected = R"expected(one: int32
620 two: dictionary<values=string, indices=int16, ordered=0>
621 three: list<two: dictionary<values=string, indices=int16, ordered=0>>
622 child 0, two: dictionary<values=string, indices=int16, ordered=0>
623 four: struct<one: int32, two: dictionary<values=string, indices=int16, ordered=0>>
624 child 0, one: int32
625 child 1, two: dictionary<values=string, indices=int16, ordered=0>)expected";
626
627 PrettyPrintOptions options;
628 Check(*sch, options, expected);
629 }
630
TEST_F(TestPrettyPrint,SchemaWithNotNull)631 TEST_F(TestPrettyPrint, SchemaWithNotNull) {
632 auto simple = field("one", int32());
633 auto non_null = field("two", int32(), false);
634 auto list_simple = field("three", list(int32()));
635 auto list_non_null = field("four", list(int32()), false);
636 auto list_non_null2 = field("five", list(field("item", int32(), false)));
637
638 auto sch = schema({simple, non_null, list_simple, list_non_null, list_non_null2});
639
640 static const char* expected = R"expected(one: int32
641 two: int32 not null
642 three: list<item: int32>
643 child 0, item: int32
644 four: list<item: int32> not null
645 child 0, item: int32
646 five: list<item: int32 not null>
647 child 0, item: int32 not null)expected";
648
649 PrettyPrintOptions options;
650 Check(*sch, options, expected);
651 }
652
TEST_F(TestPrettyPrint,SchemaWithMetadata)653 TEST_F(TestPrettyPrint, SchemaWithMetadata) {
654 // ARROW-7063
655 auto metadata1 = key_value_metadata({"foo1"}, {"bar1"});
656 auto metadata2 = key_value_metadata({"foo2"}, {"bar2"});
657 auto metadata3 = key_value_metadata(
658 {"foo3", "lorem"},
659 {"bar3",
660 R"(Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla accumsan vel
661 turpis et mollis. Aliquam tincidunt arcu id tortor blandit blandit. Donec
662 eget leo quis lectus scelerisque varius. Class aptent taciti sociosqu ad
663 litora torquent per conubia nostra, per inceptos himenaeos. Praesent
664 faucibus, diam eu volutpat iaculis, tellus est porta ligula, a efficitur
665 turpis nulla facilisis quam. Aliquam vitae lorem erat. Proin a dolor ac libero
666 dignissim mollis vitae eu mauris. Quisque posuere tellus vitae massa
667 pellentesque sagittis. Aenean feugiat, diam ac dignissim fermentum, lorem
668 sapien commodo massa, vel volutpat orci nisi eu justo. Nulla non blandit
669 sapien. Quisque pretium vestibulum urna eu vehicula.)"});
670 auto my_schema = schema(
671 {field("one", int32(), true, metadata1), field("two", utf8(), false, metadata2)},
672 metadata3);
673
674 PrettyPrintOptions options;
675 static const char* expected = R"(one: int32
676 -- field metadata --
677 foo1: 'bar1'
678 two: string not null
679 -- field metadata --
680 foo2: 'bar2'
681 -- schema metadata --
682 foo3: 'bar3'
683 lorem: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ac' + 737)";
684 Check(*my_schema, options, expected);
685
686 static const char* expected_verbose = R"(one: int32
687 -- field metadata --
688 foo1: 'bar1'
689 two: string not null
690 -- field metadata --
691 foo2: 'bar2'
692 -- schema metadata --
693 foo3: 'bar3'
694 lorem: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla accumsan vel
695 turpis et mollis. Aliquam tincidunt arcu id tortor blandit blandit. Donec
696 eget leo quis lectus scelerisque varius. Class aptent taciti sociosqu ad
697 litora torquent per conubia nostra, per inceptos himenaeos. Praesent
698 faucibus, diam eu volutpat iaculis, tellus est porta ligula, a efficitur
699 turpis nulla facilisis quam. Aliquam vitae lorem erat. Proin a dolor ac libero
700 dignissim mollis vitae eu mauris. Quisque posuere tellus vitae massa
701 pellentesque sagittis. Aenean feugiat, diam ac dignissim fermentum, lorem
702 sapien commodo massa, vel volutpat orci nisi eu justo. Nulla non blandit
703 sapien. Quisque pretium vestibulum urna eu vehicula.')";
704 options.truncate_metadata = false;
705 Check(*my_schema, options, expected_verbose);
706
707 // Metadata that exactly fits
708 auto metadata4 =
709 key_value_metadata({"key"}, {("valuexxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
710 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")});
711 my_schema = schema({field("f0", int32())}, metadata4);
712 static const char* expected_fits = R"(f0: int32
713 -- schema metadata --
714 key: 'valuexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')";
715 options.truncate_metadata = false;
716 Check(*my_schema, options, expected_fits);
717
718 // A large key
719 auto metadata5 = key_value_metadata({"0123456789012345678901234567890123456789"},
720 {("valuexxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
721 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")});
722 my_schema = schema({field("f0", int32())}, metadata5);
723 static const char* expected_big_key = R"(f0: int32
724 -- schema metadata --
725 0123456789012345678901234567890123456789: 'valuexxxxxxxxxxxxxxxxxxxxxxxxx' + 40)";
726 options.truncate_metadata = true;
727 Check(*my_schema, options, expected_big_key);
728 }
729
TEST_F(TestPrettyPrint,SchemaIndentation)730 TEST_F(TestPrettyPrint, SchemaIndentation) {
731 // ARROW-6159
732 auto simple = field("one", int32());
733 auto non_null = field("two", int32(), false);
734 auto sch = schema({simple, non_null});
735
736 static const char* expected = R"expected( one: int32
737 two: int32 not null)expected";
738
739 PrettyPrintOptions options(/*indent=*/4);
740 Check(*sch, options, expected);
741 }
742
743 } // namespace arrow
744