annotate vendor/consolidation/output-formatters/tests/testFormatters.php @ 9:1fc0ff908d1f

Add another data file
author Chris Cannam
date Mon, 05 Feb 2018 12:34:32 +0000
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2 namespace Consolidation\OutputFormatters;
Chris@0 3
Chris@0 4 use Consolidation\TestUtils\PropertyListWithCsvCells;
Chris@0 5 use Consolidation\TestUtils\RowsOfFieldsWithAlternatives;
Chris@0 6 use Consolidation\OutputFormatters\Options\FormatterOptions;
Chris@0 7 use Consolidation\OutputFormatters\StructuredData\AssociativeList;
Chris@0 8 use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
Chris@0 9 use Consolidation\OutputFormatters\StructuredData\PropertyList;
Chris@0 10 use Consolidation\OutputFormatters\StructuredData\ListDataFromKeys;
Chris@0 11 use Symfony\Component\Console\Output\BufferedOutput;
Chris@0 12 use Symfony\Component\Console\Output\OutputInterface;
Chris@0 13 use Symfony\Component\Console\Input\InputInterface;
Chris@0 14 use Symfony\Component\Console\Input\StringInput;
Chris@0 15 use Symfony\Component\Console\Input\InputOption;
Chris@0 16 use Symfony\Component\Console\Input\InputArgument;
Chris@0 17 use Symfony\Component\Console\Input\InputDefinition;
Chris@0 18
Chris@0 19 class FormattersTests extends \PHPUnit_Framework_TestCase
Chris@0 20 {
Chris@0 21 protected $formatterManager;
Chris@0 22
Chris@0 23 function setup() {
Chris@0 24 $this->formatterManager = new FormatterManager();
Chris@0 25 }
Chris@0 26
Chris@0 27 function assertFormattedOutputMatches($expected, $format, $data, FormatterOptions $options = null, $userOptions = []) {
Chris@0 28 if (!$options) {
Chris@0 29 $options = new FormatterOptions();
Chris@0 30 }
Chris@0 31 $options->setOptions($userOptions);
Chris@0 32 $output = new BufferedOutput();
Chris@0 33 $this->formatterManager->write($output, $format, $data, $options);
Chris@0 34 $actual = preg_replace('#[ \t]*$#sm', '', $output->fetch());
Chris@0 35 $this->assertEquals(rtrim($expected), rtrim($actual));
Chris@0 36 }
Chris@0 37
Chris@0 38 function testSimpleYaml()
Chris@0 39 {
Chris@0 40 $data = [
Chris@0 41 'one' => 'a',
Chris@0 42 'two' => 'b',
Chris@0 43 'three' => 'c',
Chris@0 44 ];
Chris@0 45
Chris@0 46 $expected = <<<EOT
Chris@0 47 one: a
Chris@0 48 two: b
Chris@0 49 three: c
Chris@0 50 EOT;
Chris@0 51 $this->assertFormattedOutputMatches($expected, 'yaml', $data);
Chris@0 52
Chris@0 53 $expected = <<<EOT
Chris@0 54 a
Chris@0 55 b
Chris@0 56 c
Chris@0 57 EOT;
Chris@0 58 $this->assertFormattedOutputMatches($expected, 'list', $data);
Chris@0 59
Chris@0 60 $data = new ListDataFromKeys($data);
Chris@0 61
Chris@0 62 $expected = <<<EOT
Chris@0 63 one: a
Chris@0 64 two: b
Chris@0 65 three: c
Chris@0 66 EOT;
Chris@0 67 $this->assertFormattedOutputMatches($expected, 'yaml', $data);
Chris@0 68
Chris@0 69 $expected = <<<EOT
Chris@0 70 one
Chris@0 71 two
Chris@0 72 three
Chris@0 73 EOT;
Chris@0 74
Chris@0 75 $this->assertFormattedOutputMatches($expected, 'list', $data);
Chris@0 76 }
Chris@0 77
Chris@0 78 function testNestedYaml()
Chris@0 79 {
Chris@0 80 $data = [
Chris@0 81 'one' => [
Chris@0 82 'i' => ['a', 'b', 'c'],
Chris@0 83 ],
Chris@0 84 'two' => [
Chris@0 85 'ii' => ['q', 'r', 's'],
Chris@0 86 ],
Chris@0 87 'three' => [
Chris@0 88 'iii' => ['t', 'u', 'v'],
Chris@0 89 ],
Chris@0 90 ];
Chris@0 91
Chris@0 92 $expected = <<<EOT
Chris@0 93 one:
Chris@0 94 i:
Chris@0 95 - a
Chris@0 96 - b
Chris@0 97 - c
Chris@0 98 two:
Chris@0 99 ii:
Chris@0 100 - q
Chris@0 101 - r
Chris@0 102 - s
Chris@0 103 three:
Chris@0 104 iii:
Chris@0 105 - t
Chris@0 106 - u
Chris@0 107 - v
Chris@0 108 EOT;
Chris@0 109
Chris@0 110 $this->assertFormattedOutputMatches($expected, 'yaml', $data);
Chris@0 111 }
Chris@0 112
Chris@0 113 function testSimpleJson()
Chris@0 114 {
Chris@0 115 $data = [
Chris@0 116 'one' => 'a',
Chris@0 117 'two' => 'b',
Chris@0 118 'three' => 'c',
Chris@0 119 ];
Chris@0 120
Chris@0 121 $expected = <<<EOT
Chris@0 122 {
Chris@0 123 "one": "a",
Chris@0 124 "two": "b",
Chris@0 125 "three": "c"
Chris@0 126 }
Chris@0 127 EOT;
Chris@0 128
Chris@0 129 $this->assertFormattedOutputMatches($expected, 'json', $data);
Chris@0 130 }
Chris@0 131
Chris@0 132 function testSerializeFormat()
Chris@0 133 {
Chris@0 134 $data = [
Chris@0 135 'one' => 'a',
Chris@0 136 'two' => 'b',
Chris@0 137 'three' => 'c',
Chris@0 138 ];
Chris@0 139
Chris@0 140 $expected = 'a:3:{s:3:"one";s:1:"a";s:3:"two";s:1:"b";s:5:"three";s:1:"c";}';
Chris@0 141
Chris@0 142 $this->assertFormattedOutputMatches($expected, 'php', $data);
Chris@0 143 }
Chris@0 144
Chris@0 145 function testNestedJson()
Chris@0 146 {
Chris@0 147 $data = [
Chris@0 148 'one' => [
Chris@0 149 'i' => ['a', 'b', 'c'],
Chris@0 150 ],
Chris@0 151 'two' => [
Chris@0 152 'ii' => ['q', 'r', 's'],
Chris@0 153 ],
Chris@0 154 'three' => [
Chris@0 155 'iii' => ['t', 'u', 'v'],
Chris@0 156 ],
Chris@0 157 ];
Chris@0 158
Chris@0 159 $expected = <<<EOT
Chris@0 160 {
Chris@0 161 "one": {
Chris@0 162 "i": [
Chris@0 163 "a",
Chris@0 164 "b",
Chris@0 165 "c"
Chris@0 166 ]
Chris@0 167 },
Chris@0 168 "two": {
Chris@0 169 "ii": [
Chris@0 170 "q",
Chris@0 171 "r",
Chris@0 172 "s"
Chris@0 173 ]
Chris@0 174 },
Chris@0 175 "three": {
Chris@0 176 "iii": [
Chris@0 177 "t",
Chris@0 178 "u",
Chris@0 179 "v"
Chris@0 180 ]
Chris@0 181 }
Chris@0 182 }
Chris@0 183 EOT;
Chris@0 184
Chris@0 185 $this->assertFormattedOutputMatches($expected, 'json', $data);
Chris@0 186 }
Chris@0 187
Chris@0 188 function testSimplePrintR()
Chris@0 189 {
Chris@0 190 $data = [
Chris@0 191 'one' => 'a',
Chris@0 192 'two' => 'b',
Chris@0 193 'three' => 'c',
Chris@0 194 ];
Chris@0 195
Chris@0 196 $expected = <<<EOT
Chris@0 197 Array
Chris@0 198 (
Chris@0 199 [one] => a
Chris@0 200 [two] => b
Chris@0 201 [three] => c
Chris@0 202 )
Chris@0 203 EOT;
Chris@0 204
Chris@0 205 $this->assertFormattedOutputMatches($expected, 'print-r', $data);
Chris@0 206 }
Chris@0 207
Chris@0 208 function testNestedPrintR()
Chris@0 209 {
Chris@0 210 $data = [
Chris@0 211 'one' => [
Chris@0 212 'i' => ['a', 'b', 'c'],
Chris@0 213 ],
Chris@0 214 'two' => [
Chris@0 215 'ii' => ['q', 'r', 's'],
Chris@0 216 ],
Chris@0 217 'three' => [
Chris@0 218 'iii' => ['t', 'u', 'v'],
Chris@0 219 ],
Chris@0 220 ];
Chris@0 221
Chris@0 222 $expected = <<<EOT
Chris@0 223 Array
Chris@0 224 (
Chris@0 225 [one] => Array
Chris@0 226 (
Chris@0 227 [i] => Array
Chris@0 228 (
Chris@0 229 [0] => a
Chris@0 230 [1] => b
Chris@0 231 [2] => c
Chris@0 232 )
Chris@0 233
Chris@0 234 )
Chris@0 235
Chris@0 236 [two] => Array
Chris@0 237 (
Chris@0 238 [ii] => Array
Chris@0 239 (
Chris@0 240 [0] => q
Chris@0 241 [1] => r
Chris@0 242 [2] => s
Chris@0 243 )
Chris@0 244
Chris@0 245 )
Chris@0 246
Chris@0 247 [three] => Array
Chris@0 248 (
Chris@0 249 [iii] => Array
Chris@0 250 (
Chris@0 251 [0] => t
Chris@0 252 [1] => u
Chris@0 253 [2] => v
Chris@0 254 )
Chris@0 255
Chris@0 256 )
Chris@0 257
Chris@0 258 )
Chris@0 259 EOT;
Chris@0 260
Chris@0 261 $this->assertFormattedOutputMatches($expected, 'print-r', $data);
Chris@0 262 }
Chris@0 263
Chris@0 264 function testSimpleVarExport()
Chris@0 265 {
Chris@0 266 $data = [
Chris@0 267 'one' => 'a',
Chris@0 268 'two' => 'b',
Chris@0 269 'three' => 'c',
Chris@0 270 ];
Chris@0 271
Chris@0 272 $expected = <<<EOT
Chris@0 273 array (
Chris@0 274 'one' => 'a',
Chris@0 275 'two' => 'b',
Chris@0 276 'three' => 'c',
Chris@0 277 )
Chris@0 278 EOT;
Chris@0 279
Chris@0 280 $this->assertFormattedOutputMatches($expected, 'var_export', $data);
Chris@0 281 }
Chris@0 282
Chris@0 283 function testNestedVarExport()
Chris@0 284 {
Chris@0 285 $data = [
Chris@0 286 'one' => [
Chris@0 287 'i' => ['a', 'b', 'c'],
Chris@0 288 ],
Chris@0 289 'two' => [
Chris@0 290 'ii' => ['q', 'r', 's'],
Chris@0 291 ],
Chris@0 292 'three' => [
Chris@0 293 'iii' => ['t', 'u', 'v'],
Chris@0 294 ],
Chris@0 295 ];
Chris@0 296
Chris@0 297 $expected = <<<EOT
Chris@0 298 array (
Chris@0 299 'one' =>
Chris@0 300 array (
Chris@0 301 'i' =>
Chris@0 302 array (
Chris@0 303 0 => 'a',
Chris@0 304 1 => 'b',
Chris@0 305 2 => 'c',
Chris@0 306 ),
Chris@0 307 ),
Chris@0 308 'two' =>
Chris@0 309 array (
Chris@0 310 'ii' =>
Chris@0 311 array (
Chris@0 312 0 => 'q',
Chris@0 313 1 => 'r',
Chris@0 314 2 => 's',
Chris@0 315 ),
Chris@0 316 ),
Chris@0 317 'three' =>
Chris@0 318 array (
Chris@0 319 'iii' =>
Chris@0 320 array (
Chris@0 321 0 => 't',
Chris@0 322 1 => 'u',
Chris@0 323 2 => 'v',
Chris@0 324 ),
Chris@0 325 ),
Chris@0 326 )
Chris@0 327 EOT;
Chris@0 328
Chris@0 329 $this->assertFormattedOutputMatches($expected, 'var_export', $data);
Chris@0 330 }
Chris@0 331
Chris@0 332 function testList()
Chris@0 333 {
Chris@0 334 $data = [
Chris@0 335 'one' => 'a',
Chris@0 336 'two' => 'b',
Chris@0 337 'three' => 'c',
Chris@0 338 ];
Chris@0 339
Chris@0 340 $expected = <<<EOT
Chris@0 341 a
Chris@0 342 b
Chris@0 343 c
Chris@0 344 EOT;
Chris@0 345
Chris@0 346 $this->assertFormattedOutputMatches($expected, 'list', $data);
Chris@0 347 }
Chris@0 348
Chris@0 349 /**
Chris@0 350 * @expectedException \Consolidation\OutputFormatters\Exception\UnknownFormatException
Chris@0 351 * @expectedExceptionCode 1
Chris@0 352 * @expectedExceptionMessage The requested format, 'no-such-format', is not available.
Chris@0 353 */
Chris@0 354 function testBadFormat()
Chris@0 355 {
Chris@0 356 $this->assertFormattedOutputMatches('Will fail, not return', 'no-such-format', ['a' => 'b']);
Chris@0 357 }
Chris@0 358
Chris@0 359 /**
Chris@0 360 * @expectedException \Consolidation\OutputFormatters\Exception\IncompatibleDataException
Chris@0 361 * @expectedExceptionCode 1
Chris@0 362 * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\CsvFormatter must be one of an instance of Consolidation\OutputFormatters\StructuredData\RowsOfFields, an instance of Consolidation\OutputFormatters\StructuredData\PropertyList or an array. Instead, a string was provided.
Chris@0 363 */
Chris@0 364 function testBadDataTypeForCsv()
Chris@0 365 {
Chris@0 366 $this->assertFormattedOutputMatches('Will fail, not return', 'csv', 'String cannot be converted to csv');
Chris@0 367 }
Chris@0 368
Chris@0 369 /**
Chris@0 370 * @expectedException \Consolidation\OutputFormatters\Exception\IncompatibleDataException
Chris@0 371 * @expectedExceptionCode 1
Chris@0 372 * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\JsonFormatter must be an array. Instead, a string was provided.
Chris@0 373 */
Chris@0 374 function testBadDataTypeForJson()
Chris@0 375 {
Chris@0 376 $this->assertFormattedOutputMatches('Will fail, not return', 'json', 'String cannot be converted to json');
Chris@0 377 }
Chris@0 378
Chris@0 379 function testNoFormatterSelected()
Chris@0 380 {
Chris@0 381 $data = 'Hello';
Chris@0 382 $expected = $data;
Chris@0 383 $this->assertFormattedOutputMatches($expected, '', $data);
Chris@0 384 }
Chris@0 385
Chris@0 386 function testRenderTableAsString()
Chris@0 387 {
Chris@0 388 $data = new RowsOfFields([['f1' => 'A', 'f2' => 'B', 'f3' => 'C'], ['f1' => 'x', 'f2' => 'y', 'f3' => 'z']]);
Chris@0 389 $expected = "A\tB\tC\nx\ty\tz";
Chris@0 390
Chris@0 391 $this->assertFormattedOutputMatches($expected, 'string', $data);
Chris@0 392 }
Chris@0 393
Chris@0 394 function testRenderTableAsStringWithSingleField()
Chris@0 395 {
Chris@0 396 $data = new RowsOfFields([['f1' => 'q', 'f2' => 'r', 'f3' => 's'], ['f1' => 'x', 'f2' => 'y', 'f3' => 'z']]);
Chris@0 397 $expected = "q\nx";
Chris@0 398
Chris@0 399 $options = new FormatterOptions([FormatterOptions::DEFAULT_STRING_FIELD => 'f1']);
Chris@0 400
Chris@0 401 $this->assertFormattedOutputMatches($expected, 'string', $data, $options);
Chris@0 402 }
Chris@0 403
Chris@0 404 function testRenderTableAsStringWithSingleFieldAndUserSelectedField()
Chris@0 405 {
Chris@0 406 $data = new RowsOfFields([['f1' => 'q', 'f2' => 'r', 'f3' => 's'], ['f1' => 'x', 'f2' => 'y', 'f3' => 'z']]);
Chris@0 407 $expected = "r\ny";
Chris@0 408
Chris@0 409 $options = new FormatterOptions([FormatterOptions::DEFAULT_STRING_FIELD => 'f1']);
Chris@0 410
Chris@0 411 $this->assertFormattedOutputMatches($expected, 'string', $data, $options, ['fields' => 'f2']);
Chris@0 412 }
Chris@0 413
Chris@0 414 function testSimpleCsv()
Chris@0 415 {
Chris@0 416 $data = ['a', 'b', 'c'];
Chris@0 417 $expected = "a,b,c";
Chris@0 418
Chris@0 419 $this->assertFormattedOutputMatches($expected, 'csv', $data);
Chris@0 420 }
Chris@0 421
Chris@0 422 function testLinesOfCsv()
Chris@0 423 {
Chris@0 424 $data = [['a', 'b', 'c'], ['x', 'y', 'z']];
Chris@0 425 $expected = "a,b,c\nx,y,z";
Chris@0 426
Chris@0 427 $this->assertFormattedOutputMatches($expected, 'csv', $data);
Chris@0 428 }
Chris@0 429
Chris@0 430 function testCsvWithEscapedValues()
Chris@0 431 {
Chris@0 432 $data = ["Red apple", "Yellow lemon"];
Chris@0 433 $expected = '"Red apple","Yellow lemon"';
Chris@0 434
Chris@0 435 $this->assertFormattedOutputMatches($expected, 'csv', $data);
Chris@0 436 }
Chris@0 437
Chris@0 438 function testCsvWithEmbeddedSingleQuote()
Chris@0 439 {
Chris@0 440 $data = ["John's book", "Mary's laptop"];
Chris@0 441 $expected = <<<EOT
Chris@0 442 "John's book","Mary's laptop"
Chris@0 443 EOT;
Chris@0 444
Chris@0 445 $this->assertFormattedOutputMatches($expected, 'csv', $data);
Chris@0 446 }
Chris@0 447
Chris@0 448 function testCsvWithEmbeddedDoubleQuote()
Chris@0 449 {
Chris@0 450 $data = ['The "best" solution'];
Chris@0 451 $expected = <<<EOT
Chris@0 452 "The ""best"" solution"
Chris@0 453 EOT;
Chris@0 454
Chris@0 455 $this->assertFormattedOutputMatches($expected, 'csv', $data);
Chris@0 456 }
Chris@0 457
Chris@0 458 function testCsvBothKindsOfQuotes()
Chris@0 459 {
Chris@0 460 $data = ["John's \"new\" book", "Mary's \"modified\" laptop"];
Chris@0 461 $expected = <<<EOT
Chris@0 462 "John's ""new"" book","Mary's ""modified"" laptop"
Chris@0 463 EOT;
Chris@0 464
Chris@0 465 $this->assertFormattedOutputMatches($expected, 'csv', $data);
Chris@0 466 }
Chris@0 467
Chris@0 468 function testSimpleTsv()
Chris@0 469 {
Chris@0 470 $data = ['a', 'b', 'c'];
Chris@0 471 $expected = "a\tb\tc";
Chris@0 472
Chris@0 473 $this->assertFormattedOutputMatches($expected, 'tsv', $data);
Chris@0 474 }
Chris@0 475
Chris@0 476 function testLinesOfTsv()
Chris@0 477 {
Chris@0 478 $data = [['a', 'b', 'c'], ['x', 'y', 'z']];
Chris@0 479 $expected = "a\tb\tc\nx\ty\tz";
Chris@0 480
Chris@0 481 $this->assertFormattedOutputMatches($expected, 'tsv', $data);
Chris@0 482 }
Chris@0 483
Chris@0 484 function testTsvBothKindsOfQuotes()
Chris@0 485 {
Chris@0 486 $data = ["John's \"new\" book", "Mary's \"modified\" laptop"];
Chris@0 487 $expected = "John's \"new\" book\tMary's \"modified\" laptop";
Chris@0 488
Chris@0 489 $this->assertFormattedOutputMatches($expected, 'tsv', $data);
Chris@0 490 }
Chris@0 491
Chris@0 492 function testTsvWithEscapedValues()
Chris@0 493 {
Chris@0 494 $data = ["Red apple", "Yellow lemon", "Embedded\ttab"];
Chris@0 495 $expected = "Red apple\tYellow lemon\tEmbedded\\ttab";
Chris@0 496
Chris@0 497 $this->assertFormattedOutputMatches($expected, 'tsv', $data);
Chris@0 498 }
Chris@0 499
Chris@0 500 protected function missingCellTableExampleData()
Chris@0 501 {
Chris@0 502 $data = [
Chris@0 503 [
Chris@0 504 'one' => 'a',
Chris@0 505 'two' => 'b',
Chris@0 506 'three' => 'c',
Chris@0 507 ],
Chris@0 508 [
Chris@0 509 'one' => 'x',
Chris@0 510 'three' => 'z',
Chris@0 511 ],
Chris@0 512 ];
Chris@0 513 return new RowsOfFields($data);
Chris@0 514 }
Chris@0 515
Chris@0 516 function testTableWithMissingCell()
Chris@0 517 {
Chris@0 518 $data = $this->missingCellTableExampleData();
Chris@0 519
Chris@0 520 $expected = <<<EOT
Chris@0 521 ----- ----- -------
Chris@0 522 One Two Three
Chris@0 523 ----- ----- -------
Chris@0 524 a b c
Chris@0 525 x z
Chris@0 526 ----- ----- -------
Chris@0 527 EOT;
Chris@0 528 $this->assertFormattedOutputMatches($expected, 'table', $data);
Chris@0 529
Chris@0 530 $expectedCsv = <<<EOT
Chris@0 531 One,Two,Three
Chris@0 532 a,b,c
Chris@0 533 x,,z
Chris@0 534 EOT;
Chris@0 535 $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data);
Chris@0 536
Chris@0 537 $expectedTsv = <<<EOT
Chris@0 538 a\tb\tc
Chris@0 539 x\t\tz
Chris@0 540 EOT;
Chris@0 541 $this->assertFormattedOutputMatches($expectedTsv, 'tsv', $data);
Chris@0 542
Chris@0 543 $expectedTsvWithHeaders = <<<EOT
Chris@0 544 One\tTwo\tThree
Chris@0 545 a\tb\tc
Chris@0 546 x\t\tz
Chris@0 547 EOT;
Chris@0 548 $this->assertFormattedOutputMatches($expectedTsvWithHeaders, 'tsv', $data, new FormatterOptions(), ['include-field-labels' => true]);
Chris@0 549 }
Chris@0 550
Chris@0 551 function testTableWithWordWrapping()
Chris@0 552 {
Chris@0 553 $options = new FormatterOptions();
Chris@0 554
Chris@0 555 $data = [
Chris@0 556 [
Chris@0 557 'first' => 'This is a really long cell that contains a lot of data. When it is rendered, it should be wrapped across multiple lines.',
Chris@0 558 'second' => 'This is the second column of the same table. It is also very long, and should be wrapped across multiple lines, just like the first column.',
Chris@0 559 ]
Chris@0 560 ];
Chris@0 561 $data = new RowsOfFields($data);
Chris@0 562
Chris@0 563 $expected = <<<EOT
Chris@0 564 ------------------ --------------------
Chris@0 565 First Second
Chris@0 566 ------------------ --------------------
Chris@0 567 This is a really This is the second
Chris@0 568 long cell that column of the same
Chris@0 569 contains a lot table. It is also
Chris@0 570 of data. When it very long, and
Chris@0 571 is rendered, it should be wrapped
Chris@0 572 should be across multiple
Chris@0 573 wrapped across lines, just like
Chris@0 574 multiple lines. the first column.
Chris@0 575 ------------------ --------------------
Chris@0 576 EOT;
Chris@0 577 $options->setWidth(42);
Chris@0 578 $this->assertFormattedOutputMatches($expected, 'table', $data, $options);
Chris@0 579
Chris@0 580 $expected = <<<EOT
Chris@0 581 ----------------------------------- ---------------------------------------
Chris@0 582 First Second
Chris@0 583 ----------------------------------- ---------------------------------------
Chris@0 584 This is a really long cell that This is the second column of the same
Chris@0 585 contains a lot of data. When it table. It is also very long, and
Chris@0 586 is rendered, it should be wrapped should be wrapped across multiple
Chris@0 587 across multiple lines. lines, just like the first column.
Chris@0 588 ----------------------------------- ---------------------------------------
Chris@0 589 EOT;
Chris@0 590 $options->setWidth(78);
Chris@0 591 $this->assertFormattedOutputMatches($expected, 'table', $data, $options);
Chris@0 592 }
Chris@0 593
Chris@0 594 function testWrappingLotsOfColumns()
Chris@0 595 {
Chris@0 596 $options = new FormatterOptions();
Chris@0 597
Chris@0 598 $data = [
Chris@0 599 [
Chris@0 600 'id' => '4d87b545-b4c3-4ece-9908-20c5c5e67e81',
Chris@0 601 'name' => '123456781234567812345678123456781234567812345678',
Chris@0 602 'service_level' => 'business',
Chris@0 603 'framework' => 'wordpress-network',
Chris@0 604 'owner' => '8558a08d-8059-45f6-9c4b-908299a025ee',
Chris@0 605 'created' => '2017-05-24 19:28:45',
Chris@0 606 'memberships' => 'b3a42ba5-755d-42ca-9109-21bde32809d0: Team,9bfaaf50-ece3-4460-acb8-dc1b8dd536e8: pantheon-engineering-canary-sites',
Chris@0 607 'frozen' => 'false',
Chris@0 608 ],
Chris@0 609 [
Chris@0 610 'id' => '3d87b545-b4c3-4ece-9908-20c5c5e67e80',
Chris@0 611 'name' => 'build-tools-136',
Chris@0 612 'service_level' => 'free',
Chris@0 613 'framework' => 'drupal8',
Chris@0 614 'owner' => '7558a08d-8059-45f6-9c4b-908299a025ef',
Chris@0 615 'created' => '2017-05-24 19:28:45',
Chris@0 616 'memberships' => '5ae1fa30-8cc4-4894-8ca9-d50628dcba17: ci-for-drupal-8-composer',
Chris@0 617 'frozen' => 'false',
Chris@0 618 ]
Chris@0 619 ];
Chris@0 620 $data = new RowsOfFields($data);
Chris@0 621
Chris@0 622 $expected = <<<EOT
Chris@0 623 ------------- ---------------- --------------- ----------- ------------- --------- ------------------------------------ --------
Chris@0 624 Id Name Service_level Framework Owner Created Memberships Frozen
Chris@0 625 ------------- ---------------- --------------- ----------- ------------- --------- ------------------------------------ --------
Chris@0 626 4d87b545-b4 12345678123456 business wordp 8558a08d-80 2017-0 b3a42ba5-755d-42ca-9109-21bde32809 false
Chris@0 627 c3-4ece-990 78123456781234 ress- 59-45f6-9c4 5-24 d0:
Chris@0 628 8-20c5c5e67 56781234567812 netwo b-908299a02 19:28: Team,9bfaaf50-ece3-4460-acb8-dc1b8
Chris@0 629 e81 345678 rk 5ee 45 dd536e8:
Chris@0 630 pantheon-engineering-canary-sites
Chris@0 631 3d87b545-b4 build-tools-13 free drupa 7558a08d-80 2017-0 5ae1fa30-8cc4-4894-8ca9-d50628dcba false
Chris@0 632 c3-4ece-990 6 l8 59-45f6-9c4 5-24 17: ci-for-drupal-8-composer
Chris@0 633 8-20c5c5e67 b-908299a02 19:28:
Chris@0 634 e80 5ef 45
Chris@0 635 ------------- ---------------- --------------- ----------- ------------- --------- ------------------------------------ --------
Chris@0 636 EOT;
Chris@0 637
Chris@0 638 $options->setWidth(125);
Chris@0 639 $this->assertFormattedOutputMatches($expected, 'table', $data, $options);
Chris@0 640 }
Chris@0 641
Chris@0 642 function testTableWithWordWrapping2()
Chris@0 643 {
Chris@0 644 $options = new FormatterOptions();
Chris@0 645
Chris@0 646 $data = [
Chris@0 647 [
Chris@0 648 'id' => 42,
Chris@0 649 'vid' => 321,
Chris@0 650 'description' => 'Life, the Universe and Everything.',
Chris@0 651 ],
Chris@0 652 [
Chris@0 653 'id' => 13,
Chris@0 654 'vid' => 789,
Chris@0 655 'description' => 'Why is six afraid of seven?',
Chris@0 656 ],
Chris@0 657 ];
Chris@0 658 $data = new RowsOfFields($data);
Chris@0 659 $expected = <<<EOT
Chris@0 660 ---- ----- -----------------------------
Chris@0 661 Id Vid Description
Chris@0 662 ---- ----- -----------------------------
Chris@0 663 42 321 Life, the Universe and
Chris@0 664 Everything.
Chris@0 665 13 789 Why is six afraid of seven?
Chris@0 666 ---- ----- -----------------------------
Chris@0 667 EOT;
Chris@0 668 $options->setWidth(42);
Chris@0 669 $this->assertFormattedOutputMatches($expected, 'table', $data, $options);
Chris@0 670 }
Chris@0 671
Chris@0 672 function testTableWithWordWrapping3()
Chris@0 673 {
Chris@0 674 $options = new FormatterOptions();
Chris@0 675 $data = [
Chris@0 676 'name' => 'Rex',
Chris@0 677 'species' => 'dog',
Chris@0 678 'food' => 'kibble',
Chris@0 679 'legs' => '4',
Chris@0 680 'description' => 'Rex is a very good dog, Brett. He likes kibble, and has four legs.',
Chris@0 681 ];
Chris@0 682 $data = new PropertyList($data);
Chris@0 683
Chris@0 684 $expected = <<<EOT
Chris@0 685 ------------- -------------------------
Chris@0 686 Name Rex
Chris@0 687 Species dog
Chris@0 688 Food kibble
Chris@0 689 Legs 4
Chris@0 690 Description Rex is a very good dog,
Chris@0 691 Brett. He likes kibble,
Chris@0 692 and has four legs.
Chris@0 693 ------------- -------------------------
Chris@0 694 EOT;
Chris@0 695 $options->setWidth(42);
Chris@0 696 $this->assertFormattedOutputMatches($expected, 'table', $data, $options);
Chris@0 697 }
Chris@0 698
Chris@0 699 function testTableWithWordWrapping4()
Chris@0 700 {
Chris@0 701 $options = new FormatterOptions();
Chris@0 702
Chris@0 703 $data = [
Chris@0 704 'name' => ['label' => 'Name', 'sep' => ':', 'value' => 'Rex', ],
Chris@0 705 'species' => ['label' => 'Species', 'sep' => ':', 'value' => 'dog', ],
Chris@0 706 'food' => ['label' => 'Food', 'sep' => ':', 'value' => 'kibble', ],
Chris@0 707 'legs' => ['label' => 'Legs', 'sep' => ':', 'value' => '4', ],
Chris@0 708 'description' => ['label' => 'Description', 'sep' => ':', 'value' => 'Rex is a very good dog, Brett. He likes kibble, and has four legs.', ],
Chris@0 709 ];
Chris@0 710 $data = new RowsOfFields($data);
Chris@0 711 $expected = <<<EOT
Chris@0 712 ------------- ----- -----------------------------------------------------
Chris@0 713 Label Sep Value
Chris@0 714 ------------- ----- -----------------------------------------------------
Chris@0 715 Name : Rex
Chris@0 716 Species : dog
Chris@0 717 Food : kibble
Chris@0 718 Legs : 4
Chris@0 719 Description : Rex is a very good dog, Brett. He likes kibble, and
Chris@0 720 has four legs.
Chris@0 721 ------------- ----- -----------------------------------------------------
Chris@0 722 EOT;
Chris@0 723 $options->setWidth(78);
Chris@0 724 $this->assertFormattedOutputMatches($expected, 'table', $data, $options);
Chris@0 725 }
Chris@0 726
Chris@0 727 function testTableWithWordWrapping5()
Chris@0 728 {
Chris@0 729 $options = new FormatterOptions();
Chris@0 730 $data = [
Chris@0 731 'name' => ['Name', ':', 'Rex', ],
Chris@0 732 'species' => ['Species', ':', 'dog', ],
Chris@0 733 'food' => ['Food', ':', 'kibble', ],
Chris@0 734 'legs' => ['Legs', ':', '4', ],
Chris@0 735 'description' => ['Description', ':', 'Rex is a very good dog, Brett. He likes kibble, and has four legs.', ],
Chris@0 736 ];
Chris@0 737 $data = new RowsOfFields($data);
Chris@0 738 $expected = <<<EOT
Chris@0 739 Name : Rex
Chris@0 740 Species : dog
Chris@0 741 Food : kibble
Chris@0 742 Legs : 4
Chris@0 743 Description : Rex is a very good dog, Brett. He likes kibble, and has
Chris@0 744 four legs.
Chris@0 745 EOT;
Chris@0 746 $options->setWidth(78);
Chris@0 747 $options->setIncludeFieldLables(false);
Chris@0 748 $options->setTableStyle('compact');
Chris@0 749 $this->assertFormattedOutputMatches($expected, 'table', $data, $options);
Chris@0 750 }
Chris@0 751
Chris@0 752 protected function simpleTableExampleData()
Chris@0 753 {
Chris@0 754 $data = [
Chris@0 755 'id-123' =>
Chris@0 756 [
Chris@0 757 'one' => 'a',
Chris@0 758 'two' => 'b',
Chris@0 759 'three' => 'c',
Chris@0 760 ],
Chris@0 761 'id-456' =>
Chris@0 762 [
Chris@0 763 'one' => 'x',
Chris@0 764 'two' => 'y',
Chris@0 765 'three' => 'z',
Chris@0 766 ],
Chris@0 767 ];
Chris@0 768 return new RowsOfFields($data);
Chris@0 769 }
Chris@0 770
Chris@0 771 /**
Chris@0 772 * @expectedException \Consolidation\OutputFormatters\Exception\InvalidFormatException
Chris@0 773 * @expectedExceptionCode 1
Chris@0 774 * @expectedExceptionMessage The format table cannot be used with the data produced by this command, which was an array. Valid formats are: csv,json,list,php,print-r,string,tsv,var_export,xml,yaml
Chris@0 775 */
Chris@0 776 function testIncompatibleDataForTableFormatter()
Chris@0 777 {
Chris@0 778 $data = $this->simpleTableExampleData()->getArrayCopy();
Chris@0 779 $this->assertFormattedOutputMatches('Should throw an exception before comparing the table data', 'table', $data);
Chris@0 780 }
Chris@0 781
Chris@0 782 /**
Chris@0 783 * @expectedException \Consolidation\OutputFormatters\Exception\InvalidFormatException
Chris@0 784 * @expectedExceptionCode 1
Chris@0 785 * @expectedExceptionMessage The format sections cannot be used with the data produced by this command, which was an array. Valid formats are: csv,json,list,php,print-r,string,tsv,var_export,xml,yaml
Chris@0 786 */
Chris@0 787 function testIncompatibleDataForSectionsFormatter()
Chris@0 788 {
Chris@0 789 $data = $this->simpleTableExampleData()->getArrayCopy();
Chris@0 790 $this->assertFormattedOutputMatches('Should throw an exception before comparing the table data', 'sections', $data);
Chris@0 791 }
Chris@0 792
Chris@0 793 function testSimpleTable()
Chris@0 794 {
Chris@0 795 $data = $this->simpleTableExampleData();
Chris@0 796
Chris@0 797 $expected = <<<EOT
Chris@0 798 ----- ----- -------
Chris@0 799 One Two Three
Chris@0 800 ----- ----- -------
Chris@0 801 a b c
Chris@0 802 x y z
Chris@0 803 ----- ----- -------
Chris@0 804 EOT;
Chris@0 805 $this->assertFormattedOutputMatches($expected, 'table', $data);
Chris@0 806
Chris@0 807 $expectedBorderless = <<<EOT
Chris@0 808 ===== ===== =======
Chris@0 809 One Two Three
Chris@0 810 ===== ===== =======
Chris@0 811 a b c
Chris@0 812 x y z
Chris@0 813 ===== ===== =======
Chris@0 814 EOT;
Chris@0 815 $this->assertFormattedOutputMatches($expectedBorderless, 'table', $data, new FormatterOptions(['table-style' => 'borderless']));
Chris@0 816
Chris@0 817 $expectedJson = <<<EOT
Chris@0 818 {
Chris@0 819 "id-123": {
Chris@0 820 "one": "a",
Chris@0 821 "two": "b",
Chris@0 822 "three": "c"
Chris@0 823 },
Chris@0 824 "id-456": {
Chris@0 825 "one": "x",
Chris@0 826 "two": "y",
Chris@0 827 "three": "z"
Chris@0 828 }
Chris@0 829 }
Chris@0 830 EOT;
Chris@0 831 $this->assertFormattedOutputMatches($expectedJson, 'json', $data);
Chris@0 832
Chris@0 833 $expectedCsv = <<<EOT
Chris@0 834 One,Two,Three
Chris@0 835 a,b,c
Chris@0 836 x,y,z
Chris@0 837 EOT;
Chris@0 838 $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data);
Chris@0 839
Chris@0 840 $expectedList = <<<EOT
Chris@0 841 id-123
Chris@0 842 id-456
Chris@0 843 EOT;
Chris@0 844 $this->assertFormattedOutputMatches($expectedList, 'list', $data);
Chris@0 845 }
Chris@0 846
Chris@0 847 protected function tableWithAlternativesExampleData()
Chris@0 848 {
Chris@0 849 $data = [
Chris@0 850 'id-123' =>
Chris@0 851 [
Chris@0 852 'one' => 'a',
Chris@0 853 'two' => ['this', 'that', 'the other thing'],
Chris@0 854 'three' => 'c',
Chris@0 855 ],
Chris@0 856 'id-456' =>
Chris@0 857 [
Chris@0 858 'one' => 'x',
Chris@0 859 'two' => 'y',
Chris@0 860 'three' => ['apples', 'oranges'],
Chris@0 861 ],
Chris@0 862 ];
Chris@0 863 return new RowsOfFieldsWithAlternatives($data);
Chris@0 864 }
Chris@0 865
Chris@0 866 function testTableWithAlternatives()
Chris@0 867 {
Chris@0 868 $data = $this->tableWithAlternativesExampleData();
Chris@0 869
Chris@0 870 $expected = <<<EOT
Chris@0 871 ----- --------------------------- ----------------
Chris@0 872 One Two Three
Chris@0 873 ----- --------------------------- ----------------
Chris@0 874 a this|that|the other thing c
Chris@0 875 x y apples|oranges
Chris@0 876 ----- --------------------------- ----------------
Chris@0 877 EOT;
Chris@0 878 $this->assertFormattedOutputMatches($expected, 'table', $data);
Chris@0 879
Chris@0 880 $expectedBorderless = <<<EOT
Chris@0 881 ===== =========================== ================
Chris@0 882 One Two Three
Chris@0 883 ===== =========================== ================
Chris@0 884 a this|that|the other thing c
Chris@0 885 x y apples|oranges
Chris@0 886 ===== =========================== ================
Chris@0 887 EOT;
Chris@0 888 $this->assertFormattedOutputMatches($expectedBorderless, 'table', $data, new FormatterOptions(['table-style' => 'borderless']));
Chris@0 889
Chris@0 890 $expectedJson = <<<EOT
Chris@0 891 {
Chris@0 892 "id-123": {
Chris@0 893 "one": "a",
Chris@0 894 "two": [
Chris@0 895 "this",
Chris@0 896 "that",
Chris@0 897 "the other thing"
Chris@0 898 ],
Chris@0 899 "three": "c"
Chris@0 900 },
Chris@0 901 "id-456": {
Chris@0 902 "one": "x",
Chris@0 903 "two": "y",
Chris@0 904 "three": [
Chris@0 905 "apples",
Chris@0 906 "oranges"
Chris@0 907 ]
Chris@0 908 }
Chris@0 909 }
Chris@0 910 EOT;
Chris@0 911 $this->assertFormattedOutputMatches($expectedJson, 'json', $data);
Chris@0 912
Chris@0 913 $expectedCsv = <<<EOT
Chris@0 914 One,Two,Three
Chris@0 915 a,"this|that|the other thing",c
Chris@0 916 x,y,apples|oranges
Chris@0 917 EOT;
Chris@0 918 $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data);
Chris@0 919
Chris@0 920 $expectedList = <<<EOT
Chris@0 921 id-123
Chris@0 922 id-456
Chris@0 923 EOT;
Chris@0 924 $this->assertFormattedOutputMatches($expectedList, 'list', $data);
Chris@0 925 }
Chris@0 926
Chris@0 927 function testSimpleTableWithFieldLabels()
Chris@0 928 {
Chris@0 929 $data = $this->simpleTableExampleData();
Chris@0 930 $configurationData = new FormatterOptions(
Chris@0 931 [
Chris@0 932 'field-labels' => ['one' => 'Ichi', 'two' => 'Ni', 'three' => 'San'],
Chris@0 933 'row-labels' => ['id-123' => 'Walrus', 'id-456' => 'Carpenter'],
Chris@0 934 ]
Chris@0 935 );
Chris@0 936 $configurationDataAnnotationFormat = new FormatterOptions(
Chris@0 937 [
Chris@0 938 'field-labels' => "one: Uno\ntwo: Dos\nthree: Tres",
Chris@0 939 ]
Chris@0 940 );
Chris@0 941
Chris@0 942 $expected = <<<EOT
Chris@0 943 ------ ---- -----
Chris@0 944 Ichi Ni San
Chris@0 945 ------ ---- -----
Chris@0 946 a b c
Chris@0 947 x y z
Chris@0 948 ------ ---- -----
Chris@0 949 EOT;
Chris@0 950 $this->assertFormattedOutputMatches($expected, 'table', $data, $configurationData);
Chris@0 951
Chris@0 952 $expectedSidewaysTable = <<<EOT
Chris@0 953 ------ --- ---
Chris@0 954 Ichi a x
Chris@0 955 Ni b y
Chris@0 956 San c z
Chris@0 957 ------ --- ---
Chris@0 958 EOT;
Chris@0 959 $this->assertFormattedOutputMatches($expectedSidewaysTable, 'table', $data, $configurationData->override(['list-orientation' => true]));
Chris@0 960
Chris@0 961 $expectedAnnotationFormatConfigData = <<<EOT
Chris@0 962 ----- ----- ------
Chris@0 963 Uno Dos Tres
Chris@0 964 ----- ----- ------
Chris@0 965 a b c
Chris@0 966 x y z
Chris@0 967 ----- ----- ------
Chris@0 968 EOT;
Chris@0 969 $this->assertFormattedOutputMatches($expectedAnnotationFormatConfigData, 'table', $data, $configurationDataAnnotationFormat);
Chris@0 970
Chris@0 971 $expectedWithNoFields = <<<EOT
Chris@0 972 --- --- ---
Chris@0 973 a b c
Chris@0 974 x y z
Chris@0 975 --- --- ---
Chris@0 976 EOT;
Chris@0 977 $this->assertFormattedOutputMatches($expectedWithNoFields, 'table', $data, $configurationData, ['include-field-labels' => false]);
Chris@0 978
Chris@0 979 $expectedWithReorderedFields = <<<EOT
Chris@0 980 ----- ------
Chris@0 981 San Ichi
Chris@0 982 ----- ------
Chris@0 983 c a
Chris@0 984 z x
Chris@0 985 ----- ------
Chris@0 986 EOT;
Chris@0 987 $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['three', 'one']]);
Chris@0 988 $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['San', 'Ichi']]);
Chris@0 989 $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => 'San,Ichi']);
Chris@0 990
Chris@0 991 $expectedWithRegexField = <<<EOT
Chris@0 992 ------ -----
Chris@0 993 Ichi San
Chris@0 994 ------ -----
Chris@0 995 a c
Chris@0 996 x z
Chris@0 997 ------ -----
Chris@0 998 EOT;
Chris@0 999 $this->assertFormattedOutputMatches($expectedWithRegexField, 'table', $data, $configurationData, ['fields' => ['/e$/']]);
Chris@0 1000 $this->assertFormattedOutputMatches($expectedWithRegexField, 'table', $data, $configurationData, ['fields' => ['*e']]);
Chris@0 1001 $this->assertFormattedOutputMatches($expectedWithRegexField, 'table', $data, $configurationData, ['default-fields' => ['*e']]);
Chris@0 1002
Chris@0 1003 $expectedSections = <<<EOT
Chris@0 1004
Chris@0 1005 Walrus
Chris@0 1006 One a
Chris@0 1007 Two b
Chris@0 1008 Three c
Chris@0 1009
Chris@0 1010 Carpenter
Chris@0 1011 One x
Chris@0 1012 Two y
Chris@0 1013 Three z
Chris@0 1014 EOT;
Chris@0 1015 $this->assertFormattedOutputMatches($expectedSections, 'sections', $data, $configurationData);
Chris@0 1016
Chris@0 1017 $expectedJson = <<<EOT
Chris@0 1018 {
Chris@0 1019 "id-123": {
Chris@0 1020 "three": "c",
Chris@0 1021 "one": "a"
Chris@0 1022 },
Chris@0 1023 "id-456": {
Chris@0 1024 "three": "z",
Chris@0 1025 "one": "x"
Chris@0 1026 }
Chris@0 1027 }
Chris@0 1028 EOT;
Chris@0 1029 $this->assertFormattedOutputMatches($expectedJson, 'json', $data, $configurationData, ['fields' => ['San', 'Ichi']]);
Chris@0 1030
Chris@0 1031 $expectedSingleField = <<<EOT
Chris@0 1032 -----
Chris@0 1033 San
Chris@0 1034 -----
Chris@0 1035 c
Chris@0 1036 z
Chris@0 1037 -----
Chris@0 1038 EOT;
Chris@0 1039 $this->assertFormattedOutputMatches($expectedSingleField, 'table', $data, $configurationData, ['field' => 'San']);
Chris@0 1040
Chris@0 1041 $expectedEmptyColumn = <<<EOT
Chris@0 1042 -----
Chris@0 1043 San
Chris@0 1044 -----
Chris@0 1045 EOT;
Chris@0 1046
Chris@0 1047 $this->assertFormattedOutputMatches($expectedEmptyColumn, 'table', new RowsOfFields([]), $configurationData, ['field' => 'San']);
Chris@0 1048
Chris@0 1049 $this->assertFormattedOutputMatches('', '', new RowsOfFields([]), $configurationData, ['field' => 'San']);
Chris@0 1050 $this->assertFormattedOutputMatches('[]', 'json', new RowsOfFields([]), $configurationData, ['field' => 'San']);
Chris@0 1051 }
Chris@0 1052
Chris@0 1053 /**
Chris@0 1054 * @expectedException \Consolidation\OutputFormatters\Exception\UnknownFieldException
Chris@0 1055 * @expectedExceptionCode 1
Chris@0 1056 * @expectedExceptionMessage The requested field, 'Shi', is not defined.
Chris@0 1057 */
Chris@0 1058 function testNoSuchFieldException()
Chris@0 1059 {
Chris@0 1060 $configurationData = new FormatterOptions(
Chris@0 1061 [
Chris@0 1062 'field-labels' => ['one' => 'Ichi', 'two' => 'Ni', 'three' => 'San'],
Chris@0 1063 'row-labels' => ['id-123' => 'Walrus', 'id-456' => 'Carpenter'],
Chris@0 1064 ]
Chris@0 1065 );
Chris@0 1066 $data = $this->simpleTableExampleData();
Chris@0 1067 $this->assertFormattedOutputMatches('Will throw before comparing', 'table', $data, $configurationData, ['field' => 'Shi']);
Chris@0 1068 }
Chris@0 1069
Chris@0 1070 protected function simpleListExampleData()
Chris@0 1071 {
Chris@0 1072 $data = [
Chris@0 1073 'one' => 'apple',
Chris@0 1074 'two' => 'banana',
Chris@0 1075 'three' => 'carrot',
Chris@0 1076 ];
Chris@0 1077 return new PropertyList($data);
Chris@0 1078 }
Chris@0 1079
Chris@0 1080 // Test with the deprecated data structure
Chris@0 1081 protected function simpleListExampleDataUsingAssociativeList()
Chris@0 1082 {
Chris@0 1083 $data = [
Chris@0 1084 'one' => 'apple',
Chris@0 1085 'two' => 'banana',
Chris@0 1086 'three' => 'carrot',
Chris@0 1087 ];
Chris@0 1088 return new AssociativeList($data);
Chris@0 1089 }
Chris@0 1090
Chris@0 1091 /**
Chris@0 1092 * @expectedException \Consolidation\OutputFormatters\Exception\InvalidFormatException
Chris@0 1093 * @expectedExceptionCode 1
Chris@0 1094 * @expectedExceptionMessage The format table cannot be used with the data produced by this command, which was an array. Valid formats are: csv,json,list,php,print-r,string,tsv,var_export,xml,yaml
Chris@0 1095 */
Chris@0 1096 function testIncompatibleListDataForTableFormatter()
Chris@0 1097 {
Chris@0 1098 $data = $this->simpleListExampleData();
Chris@0 1099 $this->assertFormattedOutputMatches('Should throw an exception before comparing the table data', 'table', $data->getArrayCopy());
Chris@0 1100 }
Chris@0 1101
Chris@0 1102 function testEmptyList()
Chris@0 1103 {
Chris@0 1104 $data = new RowsOfFields([]);
Chris@0 1105
Chris@0 1106 $expected = <<<EOT
Chris@0 1107 --- ---- -----
Chris@0 1108 I II III
Chris@0 1109 --- ---- -----
Chris@0 1110 EOT;
Chris@0 1111
Chris@0 1112 // If we provide field labels, then the output will change to reflect that.
Chris@0 1113 $formatterOptionsWithFieldLables = new FormatterOptions();
Chris@0 1114 $formatterOptionsWithFieldLables
Chris@0 1115 ->setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III']);
Chris@0 1116 $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithFieldLables);
Chris@0 1117 }
Chris@0 1118
Chris@0 1119 function testSimpleList()
Chris@0 1120 {
Chris@0 1121
Chris@0 1122 $expected = <<<EOT
Chris@0 1123 ------- --------
Chris@0 1124 One apple
Chris@0 1125 Two banana
Chris@0 1126 Three carrot
Chris@0 1127 ------- --------
Chris@0 1128 EOT;
Chris@0 1129 $data = $this->simpleListExampleDataUsingAssociativeList();
Chris@0 1130
Chris@0 1131 $this->assertFormattedOutputMatches($expected, 'table', $data);
Chris@0 1132
Chris@0 1133 $data = $this->simpleListExampleData();
Chris@0 1134
Chris@0 1135 $this->assertFormattedOutputMatches($expected, 'table', $data);
Chris@0 1136
Chris@0 1137 $expected = <<<EOT
Chris@0 1138 ----- --------
Chris@0 1139 I apple
Chris@0 1140 II banana
Chris@0 1141 III carrot
Chris@0 1142 ----- --------
Chris@0 1143 EOT;
Chris@0 1144 // If we provide field labels, then the output will change to reflect that.
Chris@0 1145 $formatterOptionsWithFieldLables = new FormatterOptions();
Chris@0 1146 $formatterOptionsWithFieldLables
Chris@0 1147 ->setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III']);
Chris@0 1148 $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithFieldLables);
Chris@0 1149
Chris@0 1150 $expectedDrushStyleTable = <<<EOT
Chris@0 1151 One : apple
Chris@0 1152 Two : banana
Chris@0 1153 Three : carrot
Chris@0 1154 EOT;
Chris@0 1155
Chris@0 1156 // If we provide field labels, then the output will change to reflect that.
Chris@0 1157 $formatterOptionsWithFieldLables = new FormatterOptions();
Chris@0 1158 $formatterOptionsWithFieldLables
Chris@0 1159 ->setTableStyle('compact')
Chris@0 1160 ->setListDelimiter(':');
Chris@0 1161 $this->assertFormattedOutputMatches($expectedDrushStyleTable, 'table', $data, $formatterOptionsWithFieldLables);
Chris@0 1162
Chris@0 1163
Chris@0 1164 // Adding an extra field that does not exist in the data set should not change the output
Chris@0 1165 $formatterOptionsWithExtraFieldLables = new FormatterOptions();
Chris@0 1166 $formatterOptionsWithExtraFieldLables
Chris@0 1167 ->setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III', 'four' => 'IV']);
Chris@0 1168 $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithExtraFieldLables);
Chris@0 1169
Chris@0 1170 $expectedRotated = <<<EOT
Chris@0 1171 ------- -------- --------
Chris@0 1172 One Two Three
Chris@0 1173 ------- -------- --------
Chris@0 1174 apple banana carrot
Chris@0 1175 ------- -------- --------
Chris@0 1176 EOT;
Chris@0 1177 $this->assertFormattedOutputMatches($expectedRotated, 'table', $data, new FormatterOptions(['list-orientation' => false]));
Chris@0 1178
Chris@0 1179 $expectedList = <<< EOT
Chris@0 1180 apple
Chris@0 1181 banana
Chris@0 1182 carrot
Chris@0 1183 EOT;
Chris@0 1184 $this->assertFormattedOutputMatches($expectedList, 'list', $data);
Chris@0 1185
Chris@0 1186 $expectedReorderedList = <<< EOT
Chris@0 1187 carrot
Chris@0 1188 apple
Chris@0 1189 EOT;
Chris@0 1190 $options = new FormatterOptions([FormatterOptions::FIELDS => 'three,one']);
Chris@0 1191 $this->assertFormattedOutputMatches($expectedReorderedList, 'list', $data, $options);
Chris@0 1192
Chris@0 1193 $expectedCsv = <<< EOT
Chris@0 1194 One,Two,Three
Chris@0 1195 apple,banana,carrot
Chris@0 1196 EOT;
Chris@0 1197 $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data);
Chris@0 1198
Chris@0 1199 $expectedCsvNoHeaders = 'apple,banana,carrot';
Chris@0 1200 $this->assertFormattedOutputMatches($expectedCsvNoHeaders, 'csv', $data, new FormatterOptions(), ['include-field-labels' => false]);
Chris@0 1201
Chris@0 1202 // Next, configure the formatter options with 'include-field-labels',
Chris@0 1203 // but set --include-field-labels to turn the option back on again.
Chris@0 1204 $options = new FormatterOptions(['include-field-labels' => false]);
Chris@0 1205 $input = new StringInput('test --include-field-labels');
Chris@0 1206 $optionDefinitions = [
Chris@0 1207 new InputArgument('unused', InputArgument::REQUIRED),
Chris@0 1208 new InputOption('include-field-labels', null, InputOption::VALUE_NONE),
Chris@0 1209 ];
Chris@0 1210 $definition = new InputDefinition($optionDefinitions);
Chris@0 1211 $input->bind($definition);
Chris@0 1212 $testValue = $input->getOption('include-field-labels');
Chris@0 1213 $this->assertTrue($testValue);
Chris@0 1214 $hasFieldLabels = $input->hasOption('include-field-labels');
Chris@0 1215 $this->assertTrue($hasFieldLabels);
Chris@0 1216
Chris@0 1217 $this->assertFormattedOutputMatches($expectedCsvNoHeaders, 'csv', $data, $options);
Chris@0 1218 $options->setInput($input);
Chris@0 1219 $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data, $options);
Chris@0 1220 }
Chris@0 1221
Chris@0 1222 protected function associativeListWithRenderer()
Chris@0 1223 {
Chris@0 1224 $data = [
Chris@0 1225 'one' => 'apple',
Chris@0 1226 'two' => ['banana', 'plantain'],
Chris@0 1227 'three' => 'carrot',
Chris@0 1228 'four' => ['peaches', 'pumpkin pie'],
Chris@0 1229 ];
Chris@0 1230 $list = new PropertyList($data);
Chris@0 1231
Chris@0 1232 $list->addRendererFunction(
Chris@0 1233 function ($key, $cellData, FormatterOptions $options)
Chris@0 1234 {
Chris@0 1235 if (is_array($cellData)) {
Chris@0 1236 return implode(',', $cellData);
Chris@0 1237 }
Chris@0 1238 return $cellData;
Chris@0 1239 }
Chris@0 1240 );
Chris@0 1241
Chris@0 1242 return $list;
Chris@0 1243 }
Chris@0 1244
Chris@0 1245 protected function associativeListWithCsvCells()
Chris@0 1246 {
Chris@0 1247 $data = [
Chris@0 1248 'one' => 'apple',
Chris@0 1249 'two' => ['banana', 'plantain'],
Chris@0 1250 'three' => 'carrot',
Chris@0 1251 'four' => ['peaches', 'pumpkin pie'],
Chris@0 1252 ];
Chris@0 1253 return new PropertyListWithCsvCells($data);
Chris@0 1254 }
Chris@0 1255
Chris@0 1256 function testPropertyListWithCsvCells()
Chris@0 1257 {
Chris@0 1258 $this->doPropertyListWithCsvCells($this->associativeListWithRenderer());
Chris@0 1259 $this->doPropertyListWithCsvCells($this->associativeListWithCsvCells());
Chris@0 1260 }
Chris@0 1261
Chris@0 1262 function doPropertyListWithCsvCells($data)
Chris@0 1263 {
Chris@0 1264 $expected = <<<EOT
Chris@0 1265 ------- ---------------------
Chris@0 1266 One apple
Chris@0 1267 Two banana,plantain
Chris@0 1268 Three carrot
Chris@0 1269 Four peaches,pumpkin pie
Chris@0 1270 ------- ---------------------
Chris@0 1271 EOT;
Chris@0 1272 $this->assertFormattedOutputMatches($expected, 'table', $data);
Chris@0 1273
Chris@0 1274 $expectedList = <<< EOT
Chris@0 1275 apple
Chris@0 1276 banana,plantain
Chris@0 1277 carrot
Chris@0 1278 peaches,pumpkin pie
Chris@0 1279 EOT;
Chris@0 1280 $this->assertFormattedOutputMatches($expectedList, 'list', $data);
Chris@0 1281
Chris@0 1282 $expectedCsv = <<< EOT
Chris@0 1283 One,Two,Three,Four
Chris@0 1284 apple,"banana,plantain",carrot,"peaches,pumpkin pie"
Chris@0 1285 EOT;
Chris@0 1286 $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data);
Chris@0 1287
Chris@0 1288 $expectedCsvNoHeaders = 'apple,"banana,plantain",carrot,"peaches,pumpkin pie"';
Chris@0 1289 $this->assertFormattedOutputMatches($expectedCsvNoHeaders, 'csv', $data, new FormatterOptions(), ['include-field-labels' => false]);
Chris@0 1290
Chris@0 1291 $expectedTsv = <<< EOT
Chris@0 1292 apple\tbanana,plantain\tcarrot\tpeaches,pumpkin pie
Chris@0 1293 EOT;
Chris@0 1294 $this->assertFormattedOutputMatches($expectedTsv, 'tsv', $data);
Chris@0 1295
Chris@0 1296 }
Chris@0 1297
Chris@0 1298 function testSimpleListWithFieldLabels()
Chris@0 1299 {
Chris@0 1300 $data = $this->simpleListExampleData();
Chris@0 1301 $configurationData = new FormatterOptions(
Chris@0 1302 [
Chris@0 1303 'field-labels' => ['one' => 'Ichi', 'two' => 'Ni', 'three' => 'San'],
Chris@0 1304 ]
Chris@0 1305 );
Chris@0 1306
Chris@0 1307 $expected = <<<EOT
Chris@0 1308 ------ --------
Chris@0 1309 Ichi apple
Chris@0 1310 Ni banana
Chris@0 1311 San carrot
Chris@0 1312 ------ --------
Chris@0 1313 EOT;
Chris@0 1314 $this->assertFormattedOutputMatches($expected, 'table', $data, $configurationData);
Chris@0 1315
Chris@0 1316 $expectedWithReorderedFields = <<<EOT
Chris@0 1317 ------ --------
Chris@0 1318 San carrot
Chris@0 1319 Ichi apple
Chris@0 1320 ------ --------
Chris@0 1321 EOT;
Chris@0 1322 $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['three', 'one']]);
Chris@0 1323 $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['San', 'Ichi']]);
Chris@0 1324
Chris@0 1325 $expectedJson = <<<EOT
Chris@0 1326 {
Chris@0 1327 "three": "carrot",
Chris@0 1328 "one": "apple"
Chris@0 1329 }
Chris@0 1330 EOT;
Chris@0 1331 $this->assertFormattedOutputMatches($expectedJson, 'json', $data, $configurationData, ['fields' => ['San', 'Ichi']]);
Chris@0 1332 }
Chris@0 1333
Chris@0 1334 function testSimpleXml()
Chris@0 1335 {
Chris@0 1336 $data = [
Chris@0 1337 'name' => 'primary',
Chris@0 1338 'description' => 'The primary colors of the color wheel.',
Chris@0 1339 'colors' =>
Chris@0 1340 [
Chris@0 1341 'red',
Chris@0 1342 'yellow',
Chris@0 1343 'blue',
Chris@0 1344 ],
Chris@0 1345 ];
Chris@0 1346
Chris@0 1347 $expected = <<<EOT
Chris@0 1348 <?xml version="1.0" encoding="UTF-8"?>
Chris@0 1349 <document name="primary">
Chris@0 1350 <description>The primary colors of the color wheel.</description>
Chris@0 1351 <colors>
Chris@0 1352 <color>red</color>
Chris@0 1353 <color>yellow</color>
Chris@0 1354 <color>blue</color>
Chris@0 1355 </colors>
Chris@0 1356 </document>
Chris@0 1357 EOT;
Chris@0 1358
Chris@0 1359 $this->assertFormattedOutputMatches($expected, 'xml', $data);
Chris@0 1360 }
Chris@0 1361
Chris@0 1362 function domDocumentData()
Chris@0 1363 {
Chris@0 1364 $dom = new \DOMDocument('1.0', 'UTF-8');
Chris@0 1365
Chris@0 1366 $document = $dom->createElement('document');
Chris@0 1367 $dom->appendChild($document);
Chris@0 1368
Chris@0 1369 $document->setAttribute('name', 'primary');
Chris@0 1370 $description = $dom->createElement('description');
Chris@0 1371 $document->appendChild($description);
Chris@0 1372 $description->appendChild($dom->createTextNode('The primary colors of the color wheel.'));
Chris@0 1373
Chris@0 1374 $this->domCreateElements($dom, $document, 'color', ['red', 'yellow', 'blue']);
Chris@0 1375
Chris@0 1376 return $dom;
Chris@0 1377 }
Chris@0 1378
Chris@0 1379 function domCreateElements($dom, $element, $name, $data)
Chris@0 1380 {
Chris@0 1381 $container = $dom->createElement("{$name}s");
Chris@0 1382 $element->appendChild($container);
Chris@0 1383 foreach ($data as $value) {
Chris@0 1384 $child = $dom->createElement($name);
Chris@0 1385 $container->appendChild($child);
Chris@0 1386 $child->appendChild($dom->createTextNode($value));
Chris@0 1387 }
Chris@0 1388 }
Chris@0 1389
Chris@0 1390 function complexDomDocumentData()
Chris@0 1391 {
Chris@0 1392 $dom = new \DOMDocument('1.0', 'UTF-8');
Chris@0 1393
Chris@0 1394 $document = $dom->createElement('document');
Chris@0 1395 $dom->appendChild($document);
Chris@0 1396
Chris@0 1397 $document->setAttribute('name', 'widget-collection');
Chris@0 1398 $description = $dom->createElement('description');
Chris@0 1399 $document->appendChild($description);
Chris@0 1400 $description->appendChild($dom->createTextNode('A couple of widgets.'));
Chris@0 1401
Chris@0 1402 $widgets = $dom->createElement('widgets');
Chris@0 1403 $document->appendChild($widgets);
Chris@0 1404
Chris@0 1405 $widget = $dom->createElement('widget');
Chris@0 1406 $widgets->appendChild($widget);
Chris@0 1407 $widget->setAttribute('name', 'usual');
Chris@0 1408 $this->domCreateElements($dom, $widget, 'color', ['red', 'yellow', 'blue']);
Chris@0 1409 $this->domCreateElements($dom, $widget, 'shape', ['square', 'circle', 'triangle']);
Chris@0 1410
Chris@0 1411 $widget = $dom->createElement('widget');
Chris@0 1412 $widgets->appendChild($widget);
Chris@0 1413 $widget->setAttribute('name', 'unusual');
Chris@0 1414 $this->domCreateElements($dom, $widget, 'color', ['muave', 'puce', 'umber']);
Chris@0 1415 $this->domCreateElements($dom, $widget, 'shape', ['elipse', 'rhombus', 'trapazoid']);
Chris@0 1416
Chris@0 1417 return $dom;
Chris@0 1418 }
Chris@0 1419
Chris@0 1420 function domDocumentTestValues()
Chris@0 1421 {
Chris@0 1422
Chris@0 1423 $expectedXml = <<<EOT
Chris@0 1424 <?xml version="1.0" encoding="UTF-8"?>
Chris@0 1425 <document name="primary">
Chris@0 1426 <description>The primary colors of the color wheel.</description>
Chris@0 1427 <colors>
Chris@0 1428 <color>red</color>
Chris@0 1429 <color>yellow</color>
Chris@0 1430 <color>blue</color>
Chris@0 1431 </colors>
Chris@0 1432 </document>
Chris@0 1433 EOT;
Chris@0 1434
Chris@0 1435 $expectedJson = <<<EOT
Chris@0 1436 {
Chris@0 1437 "name": "primary",
Chris@0 1438 "description": "The primary colors of the color wheel.",
Chris@0 1439 "colors": [
Chris@0 1440 "red",
Chris@0 1441 "yellow",
Chris@0 1442 "blue"
Chris@0 1443 ]
Chris@0 1444 }
Chris@0 1445 EOT;
Chris@0 1446
Chris@0 1447 $expectedComplexXml = <<<EOT
Chris@0 1448 <?xml version="1.0" encoding="UTF-8"?>
Chris@0 1449 <document name="widget-collection">
Chris@0 1450 <description>A couple of widgets.</description>
Chris@0 1451 <widgets>
Chris@0 1452 <widget name="usual">
Chris@0 1453 <colors>
Chris@0 1454 <color>red</color>
Chris@0 1455 <color>yellow</color>
Chris@0 1456 <color>blue</color>
Chris@0 1457 </colors>
Chris@0 1458 <shapes>
Chris@0 1459 <shape>square</shape>
Chris@0 1460 <shape>circle</shape>
Chris@0 1461 <shape>triangle</shape>
Chris@0 1462 </shapes>
Chris@0 1463 </widget>
Chris@0 1464 <widget name="unusual">
Chris@0 1465 <colors>
Chris@0 1466 <color>muave</color>
Chris@0 1467 <color>puce</color>
Chris@0 1468 <color>umber</color>
Chris@0 1469 </colors>
Chris@0 1470 <shapes>
Chris@0 1471 <shape>elipse</shape>
Chris@0 1472 <shape>rhombus</shape>
Chris@0 1473 <shape>trapazoid</shape>
Chris@0 1474 </shapes>
Chris@0 1475 </widget>
Chris@0 1476 </widgets>
Chris@0 1477 </document>
Chris@0 1478 EOT;
Chris@0 1479
Chris@0 1480 $expectedComplexJson = <<<EOT
Chris@0 1481 {
Chris@0 1482 "name": "widget-collection",
Chris@0 1483 "description": "A couple of widgets.",
Chris@0 1484 "widgets": {
Chris@0 1485 "usual": {
Chris@0 1486 "name": "usual",
Chris@0 1487 "colors": [
Chris@0 1488 "red",
Chris@0 1489 "yellow",
Chris@0 1490 "blue"
Chris@0 1491 ],
Chris@0 1492 "shapes": [
Chris@0 1493 "square",
Chris@0 1494 "circle",
Chris@0 1495 "triangle"
Chris@0 1496 ]
Chris@0 1497 },
Chris@0 1498 "unusual": {
Chris@0 1499 "name": "unusual",
Chris@0 1500 "colors": [
Chris@0 1501 "muave",
Chris@0 1502 "puce",
Chris@0 1503 "umber"
Chris@0 1504 ],
Chris@0 1505 "shapes": [
Chris@0 1506 "elipse",
Chris@0 1507 "rhombus",
Chris@0 1508 "trapazoid"
Chris@0 1509 ]
Chris@0 1510 }
Chris@0 1511 }
Chris@0 1512 }
Chris@0 1513 EOT;
Chris@0 1514
Chris@0 1515 return [
Chris@0 1516 [
Chris@0 1517 $this->domDocumentData(),
Chris@0 1518 $expectedXml,
Chris@0 1519 $expectedJson,
Chris@0 1520 ],
Chris@0 1521 [
Chris@0 1522 $this->complexDomDocumentData(),
Chris@0 1523 $expectedComplexXml,
Chris@0 1524 $expectedComplexJson,
Chris@0 1525 ],
Chris@0 1526 ];
Chris@0 1527 }
Chris@0 1528
Chris@0 1529 /**
Chris@0 1530 * @dataProvider domDocumentTestValues
Chris@0 1531 */
Chris@0 1532 function testDomData($data, $expectedXml, $expectedJson)
Chris@0 1533 {
Chris@0 1534 $this->assertFormattedOutputMatches($expectedXml, 'xml', $data);
Chris@0 1535 $this->assertFormattedOutputMatches($expectedJson, 'json', $data);
Chris@0 1536
Chris@0 1537 // Check to see if we get the same xml data if we convert from
Chris@0 1538 // DOM -> array -> DOM.
Chris@0 1539 $expectedJsonAsArray = (array)json_decode($expectedJson);
Chris@0 1540 $this->assertFormattedOutputMatches($expectedXml, 'xml', $expectedJsonAsArray);
Chris@0 1541 }
Chris@0 1542
Chris@0 1543 /**
Chris@0 1544 * @expectedException \Exception
Chris@0 1545 * @expectedExceptionCode 1
Chris@0 1546 * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\XmlFormatter must be either an instance of DOMDocument or an array. Instead, a string was provided.
Chris@0 1547 */
Chris@0 1548 function testDataTypeForXmlFormatter()
Chris@0 1549 {
Chris@0 1550 $this->assertFormattedOutputMatches('Will fail, not return', 'xml', 'Strings cannot be converted to XML');
Chris@0 1551 }
Chris@0 1552 }