SpecGen v0.3 28/05/2015
TL;DR: SpecGen v0.3 inserts a property for each constructor argument.
SpecGen is a phpspec extension which enhance its code generator. With the latest release, v0.3, we get the following features:
- method generation:
- it inserts method at the end of the class
- it typehints object, array and callable arguments
- it names object arguments after their type
- it names scalar arguments after a generic name (
argument
) - it adds number on names that could collide (e.g.
$argument1, $argument2
)
- constructor generation, same as method except:
- it inserts constructor at the begining of the class
- it inserts properties with initialization for each constructor arguments
Here's a simple example to demonstrate how helpful it can be.
Example
First of all, we need to set up a project with Composer.
Let's write the following composer.json
:
{
"name": "vendor/project",
"autoload": {
"psr-4": {
"Vendor\\Project\\": "src/Vendor/Project"
}
},
"require": {},
"require-dev": {}
}
Then we can install phpspec with SpecGen by running those commands:
composer require --dev phpspec/phpspec:~2.2
composer require --dev memio/spec-gen:~0.3
echo 'extensions:' > phpspec.yml
echo ' - Memio\SpecGen\MemioSpecGenExtension' >> phpspec.yml
In our example, we'll specify a TextEditor
service, it should be able to
create new files by relying on Filesystem
, another service.
This can be done as follow:
phpspec describe 'Vendor\Project\TextEditor'
````
> **Tip**: make your vendor's binaries available by adding `vendor/bin` to your `$PATH`.
> `export PATH="vendor/bin:$PATH"`.
This should generate a `spec\Vendor\Project\TextEditorSpec.php` file:
```php
<?php
namespace spec\Vendor\Project;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class TextEditorSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Vendor\Project\TextEditor');
}
}
It needs to be edited to fit our needs:
<?php
namespace spec\Vendor\Project;
use Vendor\Project\Service\Filesystem;
use Vendor\Project\File;
use PhpSpec\ObjectBehavior;
class TextEditorSpec extends ObjectBehavior
{
const FILENAME = '/tmp/file.txt';
const FORCE_FILE_CREATION = true;
function let(Filesystem $filesystem)
{
$this->beConstructedWith($filesystem);
}
function it_creates_new_files(File $file, Filesystem $filesystem)
{
$filesystem->exists(self::FILENAME)->willReturn(false);
$filesystem->create(self::FILENAME)->willReturn($file);
$this->open(self::FILENAME, self::FORCE_FILE_CREATION)->shouldBe($file);
}
}
The Test Driven Development cycle advises us to run the test suite now:
phpspec run
This will bootstrap the following code:
<?php
namespace Vendor\Project;
use Vendor\Project\Service\Filesystem;
class TextEditor
{
private $filesystem;
public function __construct(Filesystem $filesystem)
{
$this->filesystem = $filesystem;
}
public function open($argument1, $argument2)
{
}
}
It created a filesystem
property to mirror the constructor arguments. Neat!
What's next?
In our example phpspec also generated the collaborators (File
and Filesystem
).
These don't beneficiate from SpecGen help yet, so the next release (v0.4) will
probably be about using it for collaborators.
Other features that could be implemented would be PHPdoc generation, or avoiding the
Interface
/ Abstract
suffix/prefix in interface and abstract object argument names.
Reference: see the phpspec reference article