Skip to content

Commit 4b1fbf4

Browse files
committed
Implement --serialize option.
Adjusts tests to maintain full coverage with new feature.
1 parent 36ccdc5 commit 4b1fbf4

2 files changed

Lines changed: 174 additions & 6 deletions

File tree

src/Shell/ConfigReadShell.php

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
namespace ConfigRead\Shell;
88

9+
use Cake\Console\ConsoleOutput;
910
use Cake\Console\Shell;
1011
use Cake\Core\Configure;
1112

@@ -30,6 +31,15 @@ class ConfigReadShell extends Shell {
3031
*/
3132
public $formatBash = false;
3233

34+
/**
35+
* Stores command line switch value for whether to serialize all output.
36+
*
37+
* When present, it always overrides the --bash option.
38+
*
39+
* @var bool
40+
*/
41+
public $formatSerialize = false;
42+
3343
/**
3444
* Overrides the defaul welcome function in order to supporess the
3545
* normal "Welcome to CakePHP" Cake banner.
@@ -48,6 +58,8 @@ public function _welcome() {
4858
public function startup() {
4959
parent::startup();
5060

61+
$this->_io->outputAs(ConsoleOutput::RAW);
62+
5163
if (isset($this->params['h'])) {
5264
return $this->help();
5365
}
@@ -61,6 +73,12 @@ public function startup() {
6173
if (count($this->args) > 1) {
6274
$this->formatBash = true;
6375
}
76+
77+
if (isset($this->params['s'])) {
78+
$this->formatSerialize = true;
79+
// Make up for Cake snagging the next arg as the value for `-s`.
80+
array_unshift($this->args, $this->params['s']);
81+
}
6482
}
6583

6684
/**
@@ -71,6 +89,21 @@ public function startup() {
7189
* @return void
7290
*/
7391
public function main() {
92+
if ($this->formatSerialize) {
93+
$this->serializedFetchAndPrint();
94+
} else {
95+
$this->simpleFetchAndPrint();
96+
}
97+
}
98+
99+
/**
100+
* Iterate over provided args, printing them to the console as we go.
101+
*
102+
* Used to handle single scalar values and all --bash formatted output.
103+
*
104+
* @return void
105+
*/
106+
protected function simpleFetchAndPrint() {
74107
foreach ($this->args as $key) {
75108
$val = $this->fetchVal($key);
76109

@@ -82,6 +115,29 @@ public function main() {
82115
}
83116
}
84117

118+
/**
119+
* Iterate over provided args, collecting them for serialization.
120+
*
121+
* Used to --serialize formatted output. Returns a single requested
122+
* value as a directly-serialized string. If multiple keys were
123+
* provided on the command line, they are collected into an
124+
* associative array, which is serialized and echoed.
125+
*
126+
* @return void
127+
*/
128+
protected function serializedFetchAndPrint() {
129+
$unserialized = [];
130+
foreach ($this->args as $key) {
131+
$unserialized[$key] = $this->fetchVal($key);
132+
}
133+
134+
if (count($unserialized) === 1) {
135+
$unserialized = array_shift($unserialized);
136+
}
137+
138+
$this->out(serialize($unserialized), 0, Shell::QUIET);
139+
}
140+
85141
/**
86142
* Value fetcher.
87143
*
@@ -147,7 +203,7 @@ protected function printVal($key, $val) {
147203
$format = '%1$s=%2$s';
148204
}
149205

150-
$this->out(sprintf($format, $key, $val));
206+
$this->out(sprintf($format, $key, $val), 1, Shell::QUIET);
151207
}
152208

153209
/**
@@ -172,6 +228,12 @@ public function getOptionParser() {
172228
'default' => false,
173229
'help' => __('Always use bash variable deinfition formatting. When enabled, output will be formatted as `KEY_NAME=\'value\'`. This option is auto-enabled if multiple keys are provided on the command line, or if the value for the requested key is itself an array. When multiple values are returned, each will be output on its own line.')
174230
))
231+
->addOption('serialize', array(
232+
'short' => 's',
233+
'boolean' => true,
234+
'default' => false,
235+
'help' => __('Encode all output using PHP\'s `serialize()` method. Makes the Shell\'s output suitable for consumption by other PHP console scripts. Always overrides the --bash option. A single requested key will be serialized directly. Multiple requested keys will be combined into an associative array and then serialized.')
236+
))
175237
->description(__('Provides CLI access to variables defined in the Configure class of the host
176238
CakePHP application. Will output the value of any keys passed as arguments.
177239
Equivelant to `Configure::read(\'Key.Name\')`.'));

tests/TestCase/Shell/ConfigReadShellTest.php

Lines changed: 111 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@
1616
* Exposes protected methods for direct testing.
1717
*/
1818
class TestConfigReadShell extends ConfigReadShell {
19+
public function simpleFetchAndPrint() {
20+
return parent::simpleFetchAndPrint();
21+
}
22+
23+
public function serializedFetchAndPrint() {
24+
return parent::serializedFetchAndPrint();
25+
}
26+
1927
public function fetchVal($key) {
2028
return parent::fetchVal($key);
2129
}
@@ -82,7 +90,7 @@ public function tearDown() {
8290
* @param string $s The output string being printed.
8391
* @see ::initSUT()
8492
*/
85-
public function outputCollector($s) {
93+
public function outputCollector($s, $newlines = 1, $level = Shell::NORMAL) {
8694
$this->output[] = $s;
8795
}
8896

@@ -233,11 +241,32 @@ public function testStartupBashModeMultiArgs() {
233241
}
234242

235243
/**
236-
* test main().
244+
* Confirm that startup() engages serialized output mode when -s flag is present.
245+
*
246+
* @return void
247+
*/
248+
public function testStartupSerializeModeFlag() {
249+
$this->Shell->params = ['s' => 'canary'];
250+
251+
$this->Shell->startup();
252+
253+
$this->assertEquals(
254+
['canary'],
255+
$this->Shell->args,
256+
'Shell args should contain the value mistakenly captured by the -s option.'
257+
);
258+
$this->assertTrue(
259+
$this->Shell->formatSerialize,
260+
'Serialized output formatting should be enabled by the presence of the -s option.'
261+
);
262+
}
263+
264+
/**
265+
* test main() using simple (bash) output.
237266
*
238267
* @return void
239268
*/
240-
public function testMain() {
269+
public function testMainSimple() {
241270
$expected = [
242271
'key' => 'val',
243272
'debug' => true,
@@ -261,6 +290,9 @@ public function testMain() {
261290
->with($k, $v);
262291
}
263292

293+
// Can't use runCommand() because it requires a host Cake app.
294+
//$shell->runCommand(array_keys($expected));
295+
// So simulate startup and execution directly:
264296
$shell->startup();
265297
$shell->main();
266298

@@ -271,11 +303,11 @@ public function testMain() {
271303
}
272304

273305
/**
274-
* test main(), including associated protected methods.
306+
* test main(), including associated protected methods, using simple output.
275307
*
276308
* @return void
277309
*/
278-
public function testMainIntegrationStyle() {
310+
public function testMainSimpleIntegration() {
279311
$configure = [
280312
'key' => 'val',
281313
'debug' => true,
@@ -306,4 +338,78 @@ public function testMainIntegrationStyle() {
306338
'Bash output should be engaged automatically by presence of multiple command line args.'
307339
);
308340
}
341+
342+
/**
343+
* test main(), including associated protected methods, using simple output.
344+
*
345+
* @param array $params Array of params to seed the Shell->params with.
346+
* @param array $args Array of arguments to seed the Shell->args with.
347+
* @param array $expected Array of generated output lines to compare to ::$output.
348+
* @param string $msg Optional PHPUnit assertion failure message.
349+
* @return void
350+
* @dataProvider provideSerializedArgs
351+
*/
352+
public function testMainSerializedIntegration($params, $args, $expected, $msg = '') {
353+
$configure = [
354+
'key' => 'val',
355+
'debug' => true,
356+
'ary' => [
357+
'one' => 1,
358+
'two' => '2',
359+
3 => 'three',
360+
'stdClass' => (new \StdClass()),
361+
],
362+
];
363+
364+
Configure::write($configure);
365+
$this->Shell->params = $params;
366+
$this->Shell->args = $args;
367+
368+
$this->Shell->startup();
369+
$this->Shell->main();
370+
371+
$this->assertEquals(
372+
$expected,
373+
$this->output,
374+
$msg
375+
);
376+
$this->assertTrue(
377+
$this->Shell->formatSerialize,
378+
'Serialized output should be engaged from the provided param.'
379+
);
380+
}
381+
382+
/**
383+
* Provides input arguments to testMainSerializedIntegration().
384+
*
385+
* All keys named in the [params] and [args] elements must exist in
386+
* $configure as defined in testMainSerializedIntegration() above.
387+
*
388+
* @return void
389+
* @dataProvider provideSerializedArgs
390+
*/
391+
public function provideSerializedArgs() {
392+
return [
393+
[
394+
['s' => ''], // Params to load in the Shell.
395+
[], // Args to load in the Shell.
396+
['N;'], // Expected lines of output.
397+
'Empty input should produce a serialized `null` string.', // PHPUnit assertion failure message.
398+
],
399+
400+
[
401+
['s' => 'key'],
402+
[],
403+
['s:3:"val";'],
404+
'Single scalar value should be serialized directly.',
405+
],
406+
407+
[
408+
['s' => 'key'],
409+
['ary.stdClass'],
410+
['a:2:{s:3:"key";s:3:"val";s:12:"ary.stdClass";O:8:"stdClass":0:{}}'],
411+
'Multiple requested keys should be combined into a (serialized) associative array.',
412+
],
413+
];
414+
}
309415
}

0 commit comments

Comments
 (0)