Lawman for SaloonPHP
So SaloonPHP received a new plugin this week! The plugin is called Lawman and well, actually, it's a PestPHP plugin for SaloonPHP. Saloon and Pest are two of the PHP libraries that I used on a daily basis, and I thought it was about time they met each other!
I wanted to keep with the naming convention that Saloon uses, so it had to have a wild west name for it. I honestly didn't think too hard about the name, I was thinking about how the package "enforces" certain architectural rules and then naturally got onto the Law and then Lawman. You can think of this package as:
Your architectural enforcer for your SaloonPHP integrations
So, why did I build it?
I'm a massive fan of architecture testing with Pest and I think it's super important that your application is tested from an architectural persepctive, instead of only a feature perspective.
The application that prompted me to create this package did actually already have arch tests for my Saloon integrations, but I found them quite hard to read, they weren't consistent and I wanted a way of making them easier to write, using PestPHP as a foundation.
Lawman is pretty simple, it essentially adds a set of Saloon specific Expectations to Pest, that you can then use in your application. You can mix and match them with regular Pest Expectations too, so if you have an existing Pest test library, this will fit in seamlessly
So let's say I have a Connector
and want to test it, with PestPHP I could do:
test('connector')
->expect('App\Http\Integrations\Integration\Connector')
->toExtend('Saloon\Http\Connector')
->toUse('Saloon\Traits\Plugins\AcceptsJson')
->toUse('Saloon\Traits\Plugins\AlwaysThrowOnErrors');
So that test is ensuring our class extends the base Connector and uses the `AcceptJson` and `AlwaysThrowOnErrors` traits. Whilst that test works, we could perhaps make it quicker to write and easier to read, so with Lawman, you can do:
test('connector')
->expect('App\Http\Integrations\Integration\Connector')
->toBeSaloonConnector()
->toUseAcceptsJsonTrait()
->toUseAlwaysThrowOnErrorsTrait();
Next up, let's take a Request test that we have:
test('request')
->expect('App\Http\Integrations\Integration\Requests\Request')
->toExtend('\Saloon\Http\Request')
->toImplement('Saloon\Contracts\Body\HasBody')
->toUse('Saloon\Traits\Body\HasFormBody')
->toUse('Saloon\Traits\Plugins\AcceptsJson');
Lawman makes this test much nicer to read:
test('request')
->expect('App\Http\Integrations\Integration\Requests\Request')
->toBeSaloonRequest()
->toSendPostRequest()
->toHaveFormBody()
->toUseAcceptsJsonTrait();
What about if we want to test our Connector has an Authentication method? Lawman makes this easy to do, it even works with multi auth:
test('connector')
->expect('App\Http\Integrations\Integration\Connector')
->toBeSaloonConnector()
->toUseCertificateAuthentication()
->toUseTokenAuthentication();
Lawman also has Expectations for the Pagination, Cache and Rate Limit Plugins:
test('request')
->expect('App\Http\Integrations\Integration\Requests\Request')
->toBeSaloonRequest()
->toSendPostRequest()
->toUsePagedPagination()
->toHaveCaching()
->toHaveRateLimits()
Maybe our Connector has some Retry instructions that we want to test. Again, with Lawman, it's as simple as:
test('connector')
->expect('App\Http\Integrations\Integration\Connector')
->toBeSaloonConnector()
->toBeTriedAgainOnFailure()
->toHaveRetryInterval()
->toUseExponentialBackoff()
Lawman was built over the course of a couple of days last weekend. I was already in conversation about something else with Sam Carré on Twitter so I dropped this into the conversation. Luckily he was instantly a fan! I'm really appreciative of the support Sam gave Lawman and he even offered to have the documentation for it on the official Saloon website! You can check the documentation out here.
Lawman was the first PestPHP plugin I'd built, so whilst the need for Lawman really was to scratch my own itch with testing, it was also a good learning experience to learn about a side of Pest that I'd never really delved into before!
I've already got ideas for some updates I want to do and I shall get to them soon. Any ideas I do have, I will open an issue on the GitHub repo so if anyone else wants to tackle them, they're more than free to do so!
You can find Lawman on GitHub but if you want to quickly check it out from here, all you need to do is run the following command:
composer require jonpurvis/lawman --dev
I have a few posts about SaloonPHP, so if you'd like to check them out, you can click here to view them all!