Skip to content

Commit 7a3f7e5

Browse files
committed
Build out CliApplicationTest
- Use native line endings in `Json::prettyPrint()` and elsewhere previously overlooked
1 parent c8b4795 commit 7a3f7e5

File tree

8 files changed

+234
-174
lines changed

8 files changed

+234
-174
lines changed

lk-util/Command/Generate/Concept/GenerateCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ protected function handleOutput($lines): void
812812
*/
813813
protected function code($value): string
814814
{
815-
return Convert::valueToCode($value, ",\n", ' => ', null, self::TAB);
815+
return Convert::valueToCode($value, ',' . \PHP_EOL, ' => ', null, self::TAB);
816816
}
817817

818818
/**
@@ -834,7 +834,7 @@ protected function indent($lines, int $levels = 1)
834834
}
835835

836836
$indent = str_repeat(self::TAB, $levels);
837-
return $indent . str_replace("\n", "\n{$indent}", $lines);
837+
return $indent . str_replace(\PHP_EOL, \PHP_EOL . $indent, $lines);
838838
}
839839

840840
/**

lk-util/Command/Http/SendHttpRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,6 @@ protected function run(string ...$args)
156156
$result = $array;
157157
}
158158

159-
echo Json::prettyPrint($result) . "\n";
159+
echo Json::prettyPrint($result) . PHP_EOL;
160160
}
161161
}

src/Cli/CliApplication.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ public function run()
392392
if ($args && $args[0] === '_json_schema') {
393393
array_shift($args);
394394
$schema = $command->getJsonSchema($args[0] ?? trim($this->getProgramName() . " $name") . ' options');
395-
printf("%s\n", Json::prettyPrint($schema));
395+
echo Json::prettyPrint($schema) . PHP_EOL;
396396
return $this;
397397
}
398398

src/Sync/Command/GetSyncEntities.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,11 @@ protected function run(string ...$args)
194194
$result = array_shift($result);
195195
}
196196

197-
echo Json::prettyPrint($result) . "\n";
197+
echo Json::prettyPrint($result) . PHP_EOL;
198198
} else {
199199
$count = 0;
200200
foreach ($result as $entity) {
201-
echo Json::prettyPrint($entity->toArrayWith($rules)) . "\n";
201+
echo Json::prettyPrint($entity->toArrayWith($rules)) . PHP_EOL;
202202
$count++;
203203
}
204204
}

src/Utility/Json.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ public static function stringify($value, int $flags = 0): string
4040
*/
4141
public static function prettyPrint($value, int $flags = 0): string
4242
{
43-
return json_encode($value, self::ENCODE_FLAGS | \JSON_PRETTY_PRINT | $flags);
43+
$json = json_encode($value, self::ENCODE_FLAGS | \JSON_PRETTY_PRINT | $flags);
44+
return \PHP_EOL === "\n"
45+
? $json
46+
: str_replace("\n", \PHP_EOL, $json);
4447
}
4548

4649
/**

tests/fixtures/Cli/Command/TestOptions.php

Lines changed: 91 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -3,186 +3,120 @@
33
namespace Lkrms\Tests\Cli\Command;
44

55
use Lkrms\Cli\Catalog\CliOptionType;
6+
use Lkrms\Cli\Catalog\CliOptionValueType;
67
use Lkrms\Cli\CliCommand;
78
use Lkrms\Cli\CliOption;
8-
use Lkrms\Utility\Convert;
9+
use Lkrms\Support\Date\DateFormatter;
910
use Lkrms\Utility\Json;
11+
use DateTimeInterface;
1012

1113
class TestOptions extends CliCommand
1214
{
13-
/**
14-
* @var bool
15-
*/
16-
public $flag1;
15+
private bool $Flag = false;
1716

18-
/**
19-
* @var string
20-
*/
21-
public $valPos1;
17+
private int $RepeatableFlag = 0;
2218

23-
/**
24-
* @var string|null
25-
*/
26-
public $val1;
19+
private ?bool $NullableFlag = null;
2720

28-
/**
29-
* @var string|null
30-
*/
31-
public $valOpt1;
32-
33-
/**
34-
* @var string
35-
*/
36-
public $oneOfPos1;
37-
38-
/**
39-
* @var string|null
40-
*/
41-
public $oneOf1;
21+
private string $Value = '';
4222

4323
/**
4424
* @var string[]|null
4525
*/
46-
public $oneOfOpt3;
26+
private ?array $RepeatableValue = null;
27+
28+
private ?DateTimeInterface $RequiredValue = null;
4729

4830
public function description(): string
4931
{
50-
return 'Test various permutations of each CliOption type';
32+
return 'Test CliCommand options';
5133
}
5234

5335
protected function getOptionList(): array
5436
{
55-
$short = array_map(
56-
fn(int $ord): string => chr($ord),
57-
[...range(ord('a'), ord('z')), ...range(ord('A'), ord('Z'))]
58-
);
59-
natcasesort($short);
60-
61-
$options = [];
62-
$current = 1;
63-
foreach (
64-
[
65-
'FLAG' => CliOptionType::FLAG,
66-
'VALUE' => CliOptionType::VALUE,
67-
'VALUE_OPTIONAL' => CliOptionType::VALUE_OPTIONAL,
68-
'VALUE_POSITIONAL' => CliOptionType::VALUE_POSITIONAL,
69-
'ONE_OF' => CliOptionType::ONE_OF,
70-
'ONE_OF_OPTIONAL' => CliOptionType::ONE_OF_OPTIONAL,
71-
'ONE_OF_POSITIONAL' => CliOptionType::ONE_OF_POSITIONAL,
72-
] as $typeName => $type
73-
) {
74-
unset($names);
75-
$vary = [];
76-
$apply = [];
77-
78-
switch ($type) {
79-
case CliOptionType::FLAG:
80-
$names = ['flag1', 'flag2'];
81-
$vary['multipleAllowed'] = [false, true];
82-
$vary['bindTo'] = [&$this->flag1];
83-
break;
84-
85-
case CliOptionType::VALUE_POSITIONAL:
86-
$names = ['valPos1'];
87-
$vary['required'] = [true];
88-
$vary['bindTo'] = [&$this->valPos1];
89-
case CliOptionType::VALUE:
90-
$names ??= ['val1', 'val2', 'val3', 'val4'];
91-
$vary['required'] ??= [false, true, true, false];
92-
$vary['bindTo'] ??= [&$this->val1];
93-
case CliOptionType::VALUE_OPTIONAL:
94-
$names ??= ['valOpt1', 'valOpt2', 'valOpt3', 'valOpt4'];
95-
$vary['valueName'] = ['VAL', 'val', null, null];
96-
$vary['multipleAllowed'] = [false, false, true, true];
97-
$vary['delimiter'] = [',', ',', null, null];
98-
$vary['bindTo'] ??= [&$this->valOpt1];
99-
break;
100-
101-
case CliOptionType::ONE_OF_POSITIONAL:
102-
$names = ['oneOfPos1', 'oneOfPos2', 'oneOfPos3'];
103-
$vary['defaultValue'] = [];
104-
$vary['required'] = [true];
105-
$vary['bindTo'] = [&$this->oneOfPos1];
106-
case CliOptionType::ONE_OF:
107-
$names ??= ['oneOf1', 'oneOf2', 'oneOf3', 'oneOf4'];
108-
$vary['defaultValue'] ??= [null, 'value1', 'value1,value2', ['value4', 'value3']];
109-
$vary['required'] ??= [false, false, true];
110-
$vary['bindTo'] ??= [&$this->oneOf1];
111-
case CliOptionType::ONE_OF_OPTIONAL:
112-
$names ??= ['oneOfOpt1', 'oneOfOpt2', 'oneOfOpt3', 'oneOfOpt4'];
113-
$vary['valueName'] = ['ONE_OF', 'one_of', null, 'one_of'];
114-
$vary['multipleAllowed'] = [false, false, true, true];
115-
$vary['addAll'] = [false, false, true, true];
116-
$vary['defaultValue'] ??= [null, 'value2', 'value3,value4', ['value1', 'value4']];
117-
$vary['bindTo'] ??= [null, null, &$this->oneOfOpt3];
118-
119-
$apply['allowedValues'] = ['value1', 'value2', 'value3', 'value4'];
120-
break;
121-
}
122-
123-
foreach ($names ?? [$typeName . $current] as $i => $long) {
124-
$option = CliOption::build()
125-
->long($long)
126-
->short(array_shift($short))
127-
->optionType($type);
128-
$desc = [];
129-
foreach ($vary as $property => $values) {
130-
if (!array_key_exists($i, $values)) {
131-
continue;
132-
}
133-
// Preserve references, i.e. bindTo arguments
134-
$value = &$values[$i];
135-
$option = $option->{$property}($value);
136-
$desc[] = "$property=***" . Convert::valueToCode($value) . '***';
137-
unset($value);
138-
}
139-
140-
foreach ($apply as $property => $value) {
141-
$option = $option->{$property}($value);
142-
$desc[] = "~~$property=***" . Convert::valueToCode($value) . '***~~';
143-
}
144-
145-
$option = $option->description(implode(
146-
" \n",
147-
["Option $current (CliOptionType::$typeName) \n", ...$desc]
148-
));
149-
150-
$options[] = $option;
151-
$current++;
152-
}
153-
}
154-
155-
return $options;
156-
}
157-
158-
public function getLongDescription(): ?string
159-
{
160-
return <<<EOF
161-
Variations tested:
162-
163-
- Short option names that vary only by case
164-
- UPPER_CASE, lower_case and null `valueName`
165-
- Legal combinations of `multipleAllowed` and `required`
166-
- Bound to class properties, and unbound
167-
EOF;
37+
return [
38+
// CliOption::build()
39+
// ->name()
40+
// ->long()
41+
// ->short()
42+
// ->valueName()
43+
// ->description()
44+
// ->optionType()
45+
// ->valueType()
46+
// ->allowedValues()
47+
// ->unknownValuePolicy()
48+
// ->required()
49+
// ->multipleAllowed()
50+
// ->unique()
51+
// ->addAll()
52+
// ->defaultValue()
53+
// ->nullable()
54+
// ->envVariable()
55+
// ->delimiter()
56+
// ->valueCallback()
57+
// ->visibility()
58+
// ->hide()
59+
// ->bindTo(),
60+
CliOption::build()
61+
->long('flag')
62+
->short('f')
63+
->description('Flag')
64+
->bindTo($this->Flag),
65+
CliOption::build()
66+
->long('flags')
67+
->short('F')
68+
->description('Flag with multipleAllowed()')
69+
->multipleAllowed()
70+
->bindTo($this->RepeatableFlag),
71+
CliOption::build()
72+
->long('nullable')
73+
->description('Flag with nullable() and no short form')
74+
->nullable()
75+
->bindTo($this->NullableFlag),
76+
CliOption::build()
77+
->long('value')
78+
->short('v')
79+
->valueName('entity')
80+
->description('Value with defaultValue() and valueName <entity>')
81+
->optionType(CliOptionType::VALUE)
82+
->defaultValue('foo')
83+
->bindTo($this->Value),
84+
CliOption::build()
85+
->long('values')
86+
->short('V')
87+
->description('Value with multipleAllowed(), unique() and nullable()')
88+
->optionType(CliOptionType::VALUE)
89+
->multipleAllowed()
90+
->unique()
91+
->nullable()
92+
->bindTo($this->RepeatableValue),
93+
CliOption::build()
94+
->long('start')
95+
->short('s')
96+
->valueName('date')
97+
->description('Value with required(), valueType DATE and valueName <date>')
98+
->optionType(CliOptionType::VALUE)
99+
->valueType(CliOptionValueType::DATE)
100+
->required()
101+
->bindTo($this->RequiredValue),
102+
];
168103
}
169104

170105
protected function run(string ...$args)
171106
{
172-
if ($this->App->getRunningCommand() === $this) {
173-
echo Json::prettyPrint([
174-
'args' => $args,
175-
'options' => $this->getOptionValues(),
176-
'bound' => [
177-
'flag1' => $this->flag1,
178-
'valPos1' => $this->valPos1,
179-
'val1' => $this->val1,
180-
'valOpt1' => $this->valOpt1,
181-
'oneOfPos1' => $this->oneOfPos1,
182-
'oneOf1' => $this->oneOf1,
183-
'oneOfOpt3' => $this->oneOfOpt3,
184-
],
185-
]);
186-
}
107+
$dateFormatter = new DateFormatter();
108+
109+
echo Json::prettyPrint([
110+
'args' => $args,
111+
'options' => $this->getOptionValues(true),
112+
'bound' => [
113+
'Flag' => $this->Flag,
114+
'RepeatableFlag' => $this->RepeatableFlag,
115+
'NullableFlag' => $this->NullableFlag,
116+
'Value' => $this->Value,
117+
'RepeatableValue' => $this->RepeatableValue,
118+
'RequiredValue' => $this->RequiredValue,
119+
],
120+
]) . PHP_EOL;
187121
}
188122
}

0 commit comments

Comments
 (0)