rmb32 / port-generator
Reads captured stories/scenarios from Barnspec (rmb32/barnspec) and generates Scenario Runner (rmb32/scenario-runner) Port stub classes from them — library plus the generate/check CLI
Requires
- php: ^8.5
- ext-ds: ^2.0
- php-ds/php-ds: ^2.0
- rmb32/barn-layout: ^1.0@dev
- rmb32/barncept: ^5.0@dev
- rmb32/barnscaff: ^2.0@dev
- rmb32/barnspec: ^3.0@dev
- rmb32/filesystem: ^1.0@dev
- symfony/console: ^7.0
Requires (Dev)
- deptrac/deptrac: ^4.7
- infection/infection: ^0.35.4
- phpstan/phpstan: ^2.2
- phpunit/phpunit: ^12.0
- rmb32/typed-input: ^1.0@dev
- rmb32/typed-json: ^1.0@dev
- squizlabs/php_codesniffer: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Part of Barn.
Generates Scenario Runner Port stub classes from a captured
Barnspec area of business — one Arrange and Assert per Subject → Fact,
one Act per Action, one Authenticate per Role — ready for you to fill in
with real application logic. It can also check the generated files for drift.
It ships as a library plus the port-generator command.
Requirements
- PHP 8.5+
rmb32/barnspec, Barncept and Barnscaff- A project with captured Barnspec data (
.barnspec/) — see Barnspec CLI
Installation
composer require --dev rmb32/port-generator
Configuration
Create barnspec.json at your project root (next to .barnspec/):
{
"portStubs": {
"directory": "tests/Barnspec/Port",
"namespace": "App\\Tests\\Barnspec\\Port"
}
}
Inside a barn
In a barn (a project whose root holds .barn/barn.json), the config is
.barn/barnspec.json and the stories are in .barn/barnspec/. Commands work from
any folder inside the barn, and a relative portStubs.directory is taken from
the barn's root, not from where you run them.
Usage
vendor/bin/port-generator generate <area-of-business-slug>
vendor/bin/port-generator check <area-of-business-slug>
generatewrites stubs and never overwrites an existing file, so re-running after capturing new vocabulary is safe. Each area of business gets its own folder and namespace beneathportStubs— e.g.tests/Barnspec/Port/RoomManagement/Fact/Room/IsOnOfferArrange.php— so a Fact named the same in two areas is two Ports.checkreportsMissing,Unexpected,MisplacedandTypeMismatchfiles in the output directory — useful after renaming or deleting a Fact, Action or Role. Until its Phase is released, a Subject, Fact or Action can be reworded or deleted;generatethen writes the stub under its new name, andchecklists the old file asUnexpectedfor you to move your code from and delete.- Vocabulary that only replaced Scenarios use — every Scenario using it was
amended or retired by an elaboration in a released Phase — has nothing left to
prove:
generateno longer writes its stubs, andcheckreports any still on disk asRetired, safe to delete. Vocabulary no Scenario uses yet is still generated.
Generated stubs throw a TODO until you fill them in. Once you have, run your
scenarios with Scenario Bridge.
Ports are built with new by default. To give them constructor dependencies —
your application's handlers, say — name a Scenario Runner PortFactory that
hands them out of your container:
{
"portStubs": {
"directory": "tests/Barnspec/Port",
"namespace": "App\\Tests\\Barnspec\\Port",
"factory": "App\\Tests\\Barnspec\\ContainerPorts"
}
}
Related packages
- Barnspec CLI — capture the stories and vocabulary.
- Scenario Runner — defines the Port interfaces the stubs implement.
- Scenario Bridge — runs captured Scenarios against your filled-in Ports.
- Barnspec — where the stories and vocabulary are captured.
More docs
Internals · History · Known issues
License
Proprietary. See LICENSE. Copyright (c) Roger Barnfather.