namespace App\Spec; use App\AnotherInterface; use App\DependencyInterface; use App\Dependency; use App\Foo; use App\ProcessTrait; use Kahlan\QuitException; use Kahlan\Plugin\Double; use Kahlan\Plugin\Quit; describe('Foo', function () { given('dependency', function () { return Double::instance(['extends' => Dependency::class, 'methods' => ['__construct'], 'implements' => [DependencyInterface::class, AnotherInterface::class], 'uses' => [ProcessTrait::class]]); }); given('foo', function () { return new Foo($this->dependency); }); describe('instance of check', function () { it('return "Foo" instance', function () { expect($this->foo)->toBeAnInstanceOf(Foo::class); }); }); describe('->process', function () { it('return "$param processed" string', function () { $param = 'foo'; $expected = $param . ' processed'; allow($this->dependency)->toReceive('process')->with($param)->andReturn($expected); $result = $this->foo->process($param); expect($result)->toBe($expected); }); });
<?php use kahlan\Arg; use kahlan\plugin\Stub; use Sofa\Searchable\Query; use Sofa\Searchable\Parser; use Sofa\Searchable\Searchable; use Illuminate\Database\Connection; use Illuminate\Database\Query\Builder; describe('Searchable Query Builder', function () { before(function () { (new Searchable(new Parser()))->boot(); }); given('query', function () { $connection = Stub::create(['extends' => Connection::class, 'methods' => ['__construct']]); $grammar = new Illuminate\Database\Query\Grammars\MySqlGrammar(); $processor = new Illuminate\Database\Query\Processors\MySqlProcessor(); return (new Builder($connection, $grammar, $processor))->from('users'); }); it('replaces query with custom implementation on call', function () { expect($this->query)->toBeAnInstanceOf(Builder::class); expect($this->query->search('word', ['column']))->toBeAnInstanceOf(Query::class); }); it('adds basic SELECT, WHERE and GROUP BY clauses', function () { $sql = 'select * from (select `users`.*, max(case when `users`.`name` = ? then 15 else 0 end) as relevance ' . 'from `users` where (`users`.`name` like ?) group by `users`.`id`) as `users` ' . 'where `relevance` >= 1 order by `relevance` desc'; $query = $this->query->search('Jarek', ['name'], false, 1); expect($query->toSql())->toBe($sql); expect($query->toBase()->getBindings())->toBe(['Jarek', 'Jarek']); }); it('splits string into separate keywords and adds valid clauses for multiple columns', function () { $sql = 'select * from (select `users`.*, max(case when `users`.`first_name` = ? or `users`.`first_name` = ? then 15 else 0 end ' . '+ case when `users`.`last_name` = ? or `users`.`last_name` = ? then 30 else 0 end) as relevance from `users` ' . 'where (`users`.`first_name` like ? or `users`.`first_name` like ? or `users`.`last_name` like ? or `users`.`last_name` like ?) ' . 'group by `users`.`id`) as `users` where `relevance` >= 0.75 order by `relevance` desc'; $bindings = ['jarek', 'tkaczyk', 'jarek', 'tkaczyk', 'jarek', 'tkaczyk', 'jarek', 'tkaczyk'];
<?php use kahlan\plugin\Stub; use Sofa\Searchable\Subquery; use Illuminate\Database\Query\Builder; describe('Subquery - working with subqueries in Laravel made easy', function () { given('builder', function () { return Stub::create(['extends' => Builder::class, 'methods' => ['__construct']]); }); given('subquery', function () { return new Subquery($this->builder, 'alias'); }); it('handles query alias', function () { expect($this->subquery->getAlias())->toBe('alias'); expect($this->subquery->setAlias('different')->getAlias())->toBe('different'); }); it('provides fluent interface and evaluates to valid sql', function () { $grammar = Stub::create(); Stub::on($grammar)->method('wrapTable', function ($value) { return '`' . $value . '`'; }); $builder = $this->builder; Stub::on($builder)->methods(['from' => [$builder], 'getGrammar' => [$grammar], 'toSql' => ['select * from `users`']]); expect($this->subquery->setQuery($builder)->from('users')->getValue())->toBe('(select * from `users`) as `alias`'); }); it('Proxies methods calls to the builder', function () { expect($this->builder)->toReceive('where')->with('column', 'value'); $this->subquery->where('column', 'value'); }); it('Proxies property calls to the builder', function () { $this->subquery->prop = 'value';
then(function ($callback) { return $callback() === 'foo'; }); }); context('using a real context', function () { given('given_php', m::mock()->shouldReceive('get_value')->andReturn('foo')->getMock()); given('callback', new EnhancedCallback(function ($foo_var) { return $foo_var; })); then(function ($callback, $given_php) { $result = $callback($given_php) === 'foo'; m::close(); return $result; }); }); context('parameters', function () { given('given_php', m::mock()->shouldReceive('get_value')->twice()->andReturn(1)->getMock()); given('callback', new EnhancedCallback(function ($param_1, $param_2) { return $param_1 + $param_2; })); when('parameters', function ($given_php, EnhancedCallback $callback) { return $callback->parameters($given_php); }); then(function ($parameters) { return count($parameters) === 4; }); then(function ($parameters) { return isset($parameters[0], $parameters[1], $parameters['param_1'], $parameters['param_2']); }); }); });
<?php require 'Stack.php'; describe('Stack', function () { Given('stack', function ($initial_contents) { return new Stack($initial_contents); }); context('with no items', function () { given('initial_contents', function () { return []; }); when(function (Stack $stack) { $stack->push(3); }); then(function (Stack $stack) { return $stack->size() === 1; }); }); context('with one item', function () { given('initial_contents', function () { return ['an item']; }); when(function (Stack $stack) { $stack->push('another item'); }); then(function (Stack $stack) { return $stack->size() === 2; }); }); });
<?php namespace App\Spec; use App\Baz; describe('Baz', function () { given('baz', function () { return new Baz(); }); describe('->getRandomFromRange', function () { it('passed if value is part of array', function () { $expected = [1, 2, 3]; $actual = $this->baz->getRandomFromRange(1, 3); expect($actual)->toBeOneOf($expected); // strict expect($actual)->toEqualOneOf($expected); // loose }); it('fails if value is not part of array', function () { $expected = [10, 11, 12]; $actual = $this->baz->getRandomFromRange(1, 3); expect($actual)->not->toBeOneOf($expected); }); }); describe('->getStringOfInteger', function () { it('passed if value is part of array', function () { $expected = [1, 2, 3]; $actual = $this->baz->getStringOfInteger(1); expect($actual)->toEqualOneOf($expected); // loose expect($actual)->not->toBeOneOf($expected);
<?php namespace App\Spec; use App\Dependency; use App\DependencyInterface; describe('Dependency', function () { given('dependency', function () { return new Dependency(1); }); describe('injected parameter in __construct filled the $a property', function () { it('should return 1', function () { $r = new \ReflectionProperty($this->dependency, 'a'); $r->setAccessible(true); expect($r->getValue($this->dependency))->toBe(1); }); }); describe('DependencyInterface instance', function () { it('instanceof DependencyInterface', function () { expect($this->dependency)->toBeAnInstanceOf(DependencyInterface::class); expect($this->dependency)->toImplement(DependencyInterface::class); }); }); describe('->process', function () { it('return "$param processed" string', function () { $param = 'foo'; $expected = $param . ' processed'; $result = $this->dependency->process($param); expect($result)->toBe($expected); }); });
}); }); describe('calling #reportEnd', function () { given('errors', array()); given('labels', array()); given('results', array()); given('an instance of the tap reporter', 'reporter', new TapReporter()); context('no tests were executed', function () { given('total', 0); when('reporter #reportEnd is called', 'result', function ($reporter, $total, $errors, $labels, $results) { ob_start(); $reporter->reportEnd($total, $errors, $labels, $results); return ob_get_clean(); }); then('result should be a valid string', function ($result) { return empty($result); }); }); context('11 tests with no errors was executed', function () { given('total', 11); when('reporter #reportEnd is called', 'result', function ($reporter, $total, $errors, $labels, $results) { ob_start(); $reporter->reportEnd($total, $errors, $labels, $results); return ob_get_clean(); }); then('result should be a valid string', function ($result) { return !(false === strpos($result, '1..11')); }); }); }); });
}); it("makes lazy loadable variables loaded", function () { expect($this->value)->toBe('some_state'); }); }); it("throw an exception when the second parameter is not a closure", function () { $closure = function () { given('some_name', 'some value'); }; expect($closure)->toThrow(new Exception("A closure is required by `Given` constructor.")); }); it("throw an exception for reserved keywords", function () { foreach (Scope::$blacklist as $keyword => $bool) { $closure = function () use($keyword) { given($keyword, function () { return 'some value'; }); }; expect($closure)->toThrow(new Exception("Sorry `{$keyword}` is a reserved keyword, it can't be used as a scope variable.")); } }); }); describe("->__get()", function () { it("throw an new exception when trying to access an undefined variable through a given definition", function () { $closure = function () { $given = new Given(function () { return $this->undefinedVariable; }); $given(); }; expect($closure)->toThrow(new Exception("Undefined variable `undefinedVariable`."));
<?php namespace App\Spec; use App\Dependency; use App\Bar; describe('Bar', function () { given('bar', function () { return new Bar(); }); describe('instance', function () { it('return "Bar" instance', function () { expect($this->bar)->toBeAnInstanceOf(Bar::class); }); }); describe('->process', function () { it('return "$param processed" string', function () { $param = 'foo'; $expected = $param . ' processed'; allow(Dependency::class)->toReceive('process')->with($param)->andReturn($expected); $result = $this->bar->process($param); expect($result)->toBe($expected); }); }); });
<?php use BeMyGuest\SdkClient\Client; use BeMyGuest\SdkClient\Response; use Illuminate\Support\Collection; use BeMyGuestAPIV1Lib\Configuration; describe('BeMyGuest API Client package - integration', function () { given('client', function () { Configuration::$BASEURI = 'https://apidemo.bemyguest.com.sg'; return new Client('2c9971eac77c0b7b1a43b5263c3eff15aae58284'); }); after(function () { foreach ($this->bookings as $uuid) { $this->client->cancelBooking($uuid); } }); $this->bookings = []; describe('Client', function () { it('filters bookings by status', function () { $first = $this->client->createBooking(sampleBookingData()); $this->client->confirmBooking($first->uuid); $second = $this->client->createBooking(sampleBookingData()); $this->client->confirmBooking($second->uuid); $response = $this->client->getWaitingBookings(['per_page' => 1000])->keyBy('uuid'); expect($response->has($first->uuid))->toBeTruthy(); expect($response->has($second->uuid))->toBeTruthy(); $this->bookings[] = $first->uuid; $this->bookings[] = $second->uuid; }); it('confirms a booking given uuid and sets its state to "waiting for approval"', function () { $booking = $this->client->createBooking(sampleBookingData());
}); }); context('isolated', function () { then(function ($empty) { return empty($empty); }); }); }); describe('Natural failing assertions', function () { given('foo', 1); given('expected', 2); then(function ($foo, $expected) { return $foo + $foo + 2 * $foo === $expected; }); then(function () { return null == "HI" && true && 1; }); then(function ($foo) { return $foo != 1; }); context('with labels', function () { given('the number of offers', 'offers', 3); given('the price of each offer', 'price', 4); when('I multiply the number with the price', 'total', function ($offers, $price) { return $offers * $price; }); then('I should get 15', function ($total) { return $total === 15; }); }); });
}); then('result should be a valid string', function ($result) { return !(false === strpos($result, '10 examples, 1 failures')); }); then('errors should have been rendered', function ($result) { return !(false === strpos($result, 'rendered error: 1')); }); then('error summaries should have been rendered', function ($result) { return !(false === strpos($result, 'Failed examples:')) && !(false === strpos($result, 'error summary')); }); }); context('5 tests with 2 errors and labels were executed', function () { given('total', 5); given('errors', array(new MockError(), new MockError())); given('labels', array('Error number 1', 'Error number 2')); given('results', array()); when('reporter #reportEnd is called', 'result', function ($reporter, $total, $errors, $labels, $results) { ob_start(); $reporter->reportEnd($total, $errors, $labels, $results); return ob_get_clean(); }); then('result should be a valid string', function ($result) { return !(false === strpos($result, '5 examples, 2 failures')); }); then('errors should have been rendered', function ($result) { return !(false === strpos($result, 'rendered error: 1')) && !(false === strpos($result, 'rendered error: 2')); }); then('labels should have been rendered', function ($result) { return !(false === strpos($result, 'Error number 1')) && !(false === strpos($result, 'Error number 2')); }); then('error summaries should have been rendered', function ($result) {