Skip to content

Commit

Permalink
Add ability to use GetValue with Laravel command
Browse files Browse the repository at this point in the history
  • Loading branch information
pionl committed Oct 12, 2023
1 parent 2c00735 commit 1457180
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 0 deletions.
22 changes: 22 additions & 0 deletions docs/content/en/laravel.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ subtitle: ''
position: 4
---

## Command input

For safe access of command arguments / options you can extend `GetValueFactoryCommand` that provides `$this->inputData`
with wrapped arguments and options in `GetValue` instance.

```php
class MyCommand extends GetValueFactoryCommand {
protected $signature = 'test {argument} {--option} {--value=}';

public function handle(): void
{
// Ensures that you will get a string
$this->inputData->getRequiredString('argument');
// Get bool (option always return bool)
$this->inputData->getRequiredBool('option');
// Returns nullable string
$this->inputData->getString('value');
}
}
```

## GetValueFormRequest

Allows you access `GetValue` instance within your `FormRequest` by extending `GetValueFormRequest`.
Expand Down Expand Up @@ -36,6 +57,7 @@ We have implemented helper functions that pulls array data from Laravel requests
- `$this->getValueFactory->request($request);` - Initializes `ArrayData` with FormRequest and uses only **validated**
array data.
- `$this->getValueFactory->requestAll($request);` - Initializes `ArrayData` with **all values** from the requests
- `$this->getValueFactory->command($request);` - Initializes `ArrayData` with command arguments and options.

```php
class TestAction {
Expand Down
15 changes: 15 additions & 0 deletions src/GetValueFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Wrkflow\GetValue;

use Illuminate\Console\Command;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
use SimpleXMLElement;
Expand All @@ -23,11 +24,17 @@ public function __construct(
) {
}

/**
* Wraps all request data.
*/
public function requestAll(Request $request, string $parentKey = ''): GetValue
{
return $this->array($request->all(), $parentKey);
}

/**
* Wraps validated request data.
*/
public function request(FormRequest $request, string $parentKey = ''): GetValue
{
return $this->array($request->validated(), $parentKey);
Expand All @@ -43,6 +50,14 @@ public function array(array $array, string $parentKey = ''): GetValue
return $this->make(new ArrayData($array, $parentKey));
}

/**
* Wraps and merges command arguments and options.
*/
public function command(Command $command): GetValue
{
return $this->array(array_merge($command->arguments(), $command->options()));
}

protected function make(AbstractData $data): GetValue
{
return new GetValue(
Expand Down
29 changes: 29 additions & 0 deletions src/Laravel/GetValueFactoryCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Wrkflow\GetValue\Laravel;

use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Wrkflow\GetValue\GetValue;
use Wrkflow\GetValue\GetValueFactory;

class GetValueFactoryCommand extends Command
{
protected GetValue $inputData;

public function __construct(
private readonly GetValueFactory $getValueFactory,
) {
parent::__construct();
}

protected function initialize(InputInterface $input, OutputInterface $output): void
{
parent::initialize($input, $output);

$this->inputData = $this->getValueFactory->command($this);
}
}
94 changes: 94 additions & 0 deletions tests/Laravel/GetValueFactoryCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

namespace Wrkflow\GetValueTests\Laravel;

use Closure;
use PHPUnit\Framework\Assert;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;
use Wrkflow\GetValue\GetValueFactory;
use Wrkflow\GetValue\Laravel\GetValueFactoryCommand;

class GetValueFactoryCommandTest extends AbstractLaravelTestCase
{
/**
* @return array<string|int, array{0: Closure(static):void}>
*/
public function dataCommand(): array
{
return [
'argument only' => [
fn (self $self) => $self->assertCommand(
input: 'test',
expectedArgument: 'test',
expectedBoolOption: false,
expectedValueOption: null,
),
],
'argument, option' => [
fn (self $self) => $self->assertCommand(
input: 'test --option',
expectedArgument: 'test',
expectedBoolOption: true,
expectedValueOption: null,
),
],
'argument, option, value' => [
fn (self $self) => $self->assertCommand(
input: 'test --option --value=test22',
expectedArgument: 'test',
expectedBoolOption: true,
expectedValueOption: 'test22',
),
],
];
}

/**
* @param Closure(static):void $assert
*
* @dataProvider dataCommand
*/
public function testCommand(Closure $assert): void
{
$assert($this);
}

public function assertCommand(
string $input,
?string $expectedArgument,
bool $expectedBoolOption,
?string $expectedValueOption,
): void {
$command = new class(
new GetValueFactory(),
$expectedArgument,
$expectedBoolOption,
$expectedValueOption,
) extends GetValueFactoryCommand {
protected $signature = 'test {argument} {--option} {--value=}';

public function __construct(
private readonly GetValueFactory $getValueFactory,
private readonly ?string $expectedArgument,
private readonly ?bool $expectedBoolOption,
private readonly ?string $expectedValueOption,
) {
parent::__construct($this->getValueFactory);
}

public function handle(): void
{
Assert::assertSame($this->expectedArgument, $this->inputData->getString('argument'));
Assert::assertSame($this->expectedBoolOption, $this->inputData->getBool('option'));
Assert::assertSame($this->expectedValueOption, $this->inputData->getString('value'));
}
};

$command->setLaravel($this->app());

$command->run(new StringInput($input), new NullOutput());
}
}
105 changes: 105 additions & 0 deletions tests/Laravel/GetValueFactoryLaravelCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

declare(strict_types=1);

namespace Wrkflow\GetValueTests\Laravel;

use Closure;
use Illuminate\Console\Command;
use PHPUnit\Framework\Assert;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;
use Wrkflow\GetValue\GetValueFactory;

class GetValueFactoryLaravelCommandTest extends AbstractLaravelTestCase
{
private GetValueFactory $factory;

protected function setUp(): void
{
parent::setUp();

$this->factory = new GetValueFactory();
}

/**
* @return array<string|int, array{0: Closure(static):void}>
*/
public function dataCommand(): array
{
return [
'argument only' => [
fn (self $self) => $self->assertCommand(
input: 'test',
expectedArgument: 'test',
expectedBoolOption: false,
expectedValueOption: null,
),
],
'argument, option' => [
fn (self $self) => $self->assertCommand(
input: 'test --option',
expectedArgument: 'test',
expectedBoolOption: true,
expectedValueOption: null,
),
],
'argument, option, value' => [
fn (self $self) => $self->assertCommand(
input: 'test --option --value=test22',
expectedArgument: 'test',
expectedBoolOption: true,
expectedValueOption: 'test22',
),
],
];
}

/**
* @param Closure(static):void $assert
*
* @dataProvider dataCommand
*/
public function testCommand(Closure $assert): void
{
$assert($this);
}

public function assertCommand(
string $input,
?string $expectedArgument,
bool $expectedBoolOption,
?string $expectedValueOption,
): void {
$command = new class(
$this->factory,
$expectedArgument,
$expectedBoolOption,
$expectedValueOption,
) extends Command {
protected $signature = 'test {argument} {--option} {--value=}';

public function __construct(
private readonly GetValueFactory $getValueFactory,
private readonly ?string $expectedArgument,
private readonly ?bool $expectedBoolOption,
private readonly ?string $expectedValueOption,
) {
parent::__construct();
}

public function handle(): void
{
$data = $this->getValueFactory->command($this);

Assert::assertSame($this->expectedArgument, $data->getString('argument'));
Assert::assertSame($this->expectedBoolOption, $data->getBool('option'));
Assert::assertSame($this->expectedValueOption, $data->getString('value'));
}
};

$command->setLaravel($this->app());

$command->run(new StringInput($input), new NullOutput());
}
}

0 comments on commit 1457180

Please sign in to comment.