$collection->data(); }); }); describe("::toArray()", function () { it("converts a collection to an array", function () { $collection = new Collection(['data' => [1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5]]); expect(Collection::toArray($collection))->toBe([1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5]); }); it("converts objects which support __toString", function () { $stringable = Stub::classname(); Stub::on($stringable)->method('__toString')->andReturn('hello'); $collection = new Collection(['data' => [new $stringable()]]); expect(Collection::toArray($collection))->toBe(['hello']); }); it("converts objects using handlers", function () { $handlable = Stub::classname(); $handlers = [$handlable => function ($value) { return 'world'; }]; $collection = new Collection(['data' => [new $handlable()]]); expect(Collection::toArray($collection, compact('handlers')))->toBe(['world']); }); it("doesn't convert unsupported objects", function () { $collection = new Collection(['data' => [(object) 'an object']]); expect(Collection::toArray($collection))->toEqual([(object) 'an object']); }); it("converts nested collections", function () { $collection = new Collection(['data' => [1, 2, 3, new Collection(['data' => [4, 5, 6]])]]); expect(Collection::toArray($collection))->toBe([1, 2, 3, [4, 5, 6]]); }); it("converts mixed nested collections & arrays", function () {
$stub3 = new $classname(); expect($stub->bar())->toBe('Hello Bar!'); }); it("stubs static methods on a stub class", function () { $classname = Stub::classname(); Stub::on($classname)->methods(['::magicCallStatic' => ['Good Evening World!', 'Good Bye World!']]); expect($classname::magicCallStatic())->toBe('Good Evening World!'); expect($classname::magicCallStatic())->toBe('Good Bye World!'); }); it("produces unique classname", function () { $stub = Stub::classname(); $stub2 = Stub::classname(); expect($stub)->not->toBe($stub2); }); it("stubs classes with `construct()` if no parent defined", function () { $class = Stub::classname(); expect($class)->toReceive('__construct'); $stub = new $class(); }); }); describe("::generate()", function () { it("throws an exception with an unexisting trait", function () { expect(function () { Stub::generate(['uses' => ['an\\unexisting\\Trait']]); })->toThrow(new IncompleteException('Unexisting trait `an\\unexisting\\Trait`')); }); it("throws an exception with an unexisting interface", function () { expect(function () { Stub::generate(['implements' => ['an\\unexisting\\Interface']]); })->toThrow(new IncompleteException('Unexisting interface `an\\unexisting\\Interface`')); });
Matcher::reset(); foreach ($this->matchers as $name => $value) { foreach ($value as $for => $class) { Matcher::register($name, $class, $for); } } }); describe("->__call()", function () { it("throws an exception when using an undefined matcher name", function () { $closure = function () { $result = Expectation::expect(true)->toHelloWorld(true); }; expect($closure)->toThrow(new Exception("Unexisting matcher attached to `'toHelloWorld'`.")); }); it("throws an exception when a specific class matcher doesn't match", function () { Matcher::register('toEqualCustom', Stub::classname(['extends' => 'Kahlan\\Matcher\\ToEqual']), 'stdClass'); $closure = function () { $result = Expectation::expect([])->toEqualCustom(new stdClass()); }; expect($closure)->toThrow(new Exception("Unexisting matcher attached to `'toEqualCustom'` for `stdClass`.")); }); it("doesn't wait when the spec passes", function () { $start = microtime(true); $result = Expectation::expect(true, 1)->toBe(true); $end = microtime(true); expect($end - $start)->toBeLessThan(1); }); it("loops until the timeout is reached on failure", function () { $start = microtime(true); $result = Expectation::expect(true, 0.1)->toBe(false); $end = microtime(true);
$backtrace = Debugger::trace(['trace' => new Exception('World Destruction Error!')]); expect($backtrace)->toBeA('string'); $backtrace = explode("\n", $backtrace); expect(empty($backtrace))->toBe(false); }); it("returns a trace from eval'd code", function () { $trace = debug_backtrace(); $trace[1]['file'] = "eval()'d code"; $backtrace = Debugger::trace(['trace' => $trace]); expect($backtrace)->toBeA('string'); $trace = current(explode("\n", $backtrace)); expect($trace)->toMatch('~kahlan[/|\\\\]src[/|\\\\]Specification.php~'); }); describe("::_line()", function () { beforeEach(function () { $this->debugger = Stub::classname(['extends' => 'Kahlan\\Analysis\\Debugger', 'methods' => ['::line']]); Stub::on($this->debugger)->method('::line', function ($trace) { return static::_line($trace); }); }); it("returns `null` with non-existing files", function () { $debugger = $this->debugger; $trace = ['file' => DS . 'some' . DS . 'none' . DS . 'existant' . DS . 'path' . DS . 'file.php', 'line' => null]; expect($debugger::line($trace))->toBe(null); }); it("returns `null` when a line can't be found", function () { $debugger = $this->debugger; $nbline = count(file('spec' . DS . 'Suite' . DS . 'Analysis' . DS . 'DebuggerSpec.php')) + 1; $trace = ['file' => 'spec' . DS . 'Suite' . DS . 'Analysis' . DS . 'DebuggerSpec.php', 'line' => $nbline + 1]; expect($debugger::line($trace))->toBe(null); });
it("throws an exception when using an undefined matcher name", function () { $closure = function () { Matcher::get('toHelloWorld'); }; expect($closure)->toThrow(new Exception("Unexisting default matcher attached to `'toHelloWorld'`.")); }); it("throws an exception when using an undefined matcher name for a specific class", function () { $closure = function () { Matcher::get('toHelloWorld', 'stdClass'); }; expect($closure)->toThrow(new Exception("Unexisting matcher attached to `'toHelloWorld'` for `stdClass`.")); }); }); describe("::unregister()", function () { it("unregisters a matcher", function () { Matcher::register('toBeOrNotToBe', Stub::classname(['extends' => 'kahlan\\matcher\\ToBe'])); expect(Matcher::exists('toBeOrNotToBe'))->toBe(true); Matcher::unregister('toBeOrNotToBe'); expect(Matcher::exists('toBeOrNotToBe'))->toBe(false); }); it("unregisters all matchers", function () { expect(Matcher::get())->toBeGreaterThan(1); Matcher::unregister(true); Matcher::register('toHaveLength', 'kahlan\\matcher\\ToHaveLength'); expect(Matcher::get())->toHaveLength(1); }); }); describe("::reset()", function () { it("unregisters all matchers", function () { expect(Matcher::get())->toBeGreaterThan(1); Matcher::reset();
<?php namespace chaos\spec\suite; use stdClass; use DateTime; use InvalidArgumentException; use chaos\Model; use chaos\Schema; use chaos\collection\Collection; use kahlan\plugin\Stub; describe("Model", function () { before(function () { $this->model = Stub::classname(['extends' => Model::class]); }); afterEach(function () { $model = $this->model; $model::reset(); }); describe("::config()", function () { it("configures the model", function () { $model = $this->model; $model::config(['schema' => $schema = Stub::create(), 'validator' => $validator = Stub::create(), 'finders' => $finders = Stub::create(), 'query' => $query = ['option' => 'value'], 'connection' => $connection = Stub::create(), 'conventions' => $conventions = Stub::create()]); expect($model::schema())->toBe($schema); expect($model::validator())->toBe($validator); expect($model::finders())->toBe($finders); expect($model::query())->toBe($query); expect($model::connection())->toBe($connection); expect($model::conventions())->toBe($conventions); $model::reset(); expect($model::schema())->not->toBe($schema);
expect($arg->match(true))->not->toBe(true); expect($arg->match(true))->toBe(false); }); it("registers a matcher for a specific class", function () { Matcher::register('toEqualCustom', Stub::classname(['extends' => 'kahlan\\matcher\\ToEqual']), 'stdClass'); $arg = Arg::toEqualCustom(new stdClass()); expect($arg->match(new stdClass()))->toBe(true); $arg = Arg::toEqualCustom(new DateTime()); expect($arg->match(new stdClass()))->not->toBe(true); }); it("makes registered matchers for a specific class available for sub classes", function () { Matcher::register('toEqualCustom', Stub::classname(['extends' => 'kahlan\\matcher\\ToEqual']), 'SplHeap'); $arg = Arg::toEqualCustom(new SplMaxHeap()); expect($arg->match(new SplMaxHeap()))->toBe(true); }); it("throws an exception using an undefined matcher name", function () { $closure = function () { $arg = Arg::toHelloWorld(true); }; expect($closure)->toThrow(new Exception("Unexisting matchers attached to `'toHelloWorld'`.")); }); it("throws an exception using an matcher name which doesn't match actual", function () { Matcher::register('toEqualCustom', Stub::classname(['extends' => 'kahlan\\matcher\\ToEqual']), 'SplHeap'); $closure = function () { $arg = Arg::toEqualCustom(new SplMaxHeap()); $arg->match(true); }; expect($closure)->toThrow(new Exception("Unexisting matcher attached to `'toEqualCustom'` for `SplHeap`.")); }); }); });
it("applies parent classes's filters using cached filters", function () { $class = $this->class; $subclass = Stub::classname(['extends' => $class]); Stub::on($subclass)->method('::filterable', function () { return Filter::on(get_called_class(), 'filterable', func_get_args(), function ($chain, $message) { return "Hello {$message}"; }); }); Filter::apply($class, 'filterable', 'spec.be_prefix'); Filter::apply($subclass, 'filterable', 'spec.my_prefix'); expect($subclass::filterable('World!'))->toBe('Hello Be My World!'); expect($subclass::filterable('World!'))->toBe('Hello Be My World!'); }); it("invalidates parent cached filters", function () { $class = $this->class; $subclass = Stub::classname(['extends' => $class]); Stub::on($subclass)->method('::filterable', function () { return Filter::on(get_called_class(), 'filterable', func_get_args(), function ($chain, $message) { return "Hello {$message}"; }); }); Filter::apply($class, 'filterable', 'spec.be_prefix'); Filter::apply($subclass, 'filterable', 'spec.my_prefix'); expect($subclass::filterable('World!'))->toBe('Hello Be My World!'); Filter::apply($subclass, 'filterable', 'spec.no_chain'); expect($subclass::filterable('World!'))->toBe("No Man's My World!"); }); it("throws an Exception when trying to apply a filter using an unexisting closure", function () { $class = $this->class; $closure = function () use($class) { Filter::apply($class, 'filterable', 'spec.unexisting_closure');
describe('Sofa\\Hookable\\Hookable', function () { it('resolves hooks in instance scope', function () { $parent = Stub::classname(); Stub::on($parent)->method('getAttribute', function () { return 'value'; }); $hookableClass = Stub::classname(['uses' => Hookable::class, 'extends' => $parent]); $hookableClass::hook('getAttribute', function ($next, $value, $args) { $this->instanceMethod(); }); $hookable = new $hookableClass(); expect($hookable)->toReceive('instanceMethod'); $hookable->getAttribute('attribute'); }); it('flushes all hooks with the flushHooks method', function () { $parent = Stub::classname(); $hookableClass = Stub::classname(['uses' => Hookable::class, 'extends' => $parent]); $hookableClass::hook('method1', function ($next, $value, $args) { }); $hookableClass::hook('method2', function ($next, $value, $args) { }); $reflectedClass = new ReflectionClass($hookableClass); $reflectedProperty = $reflectedClass->getProperty('hooks'); $reflectedProperty->setAccessible(true); $hooks = $reflectedProperty->getValue(); expect($hooks)->toHaveLength(2); $hookableClass::flushHooks(); $hooks = $reflectedProperty->getValue(); expect($hooks)->toHaveLength(0); }); });
namespace chaos\spec\suite\model\collection; use InvalidArgumentException; use chaos\Model; use chaos\collection\Collection; use chaos\collection\Through; use kahlan\plugin\Stub; use chaos\spec\fixture\model\Image; use chaos\spec\fixture\model\Tag; use chaos\spec\fixture\model\ImageTag; describe("Through", function () { beforeEach(function () { $this->images_tags = []; $this->imageTagModel = $imageTagModel = Stub::classname(['extends' => ImageTag::class]); $this->tagModel = $tagModel = Stub::classname(['extends' => Tag::class, 'methods' => ['tagMethod']]); Stub::on($tagModel)->method('tagMethod', function ($options) { return $options; }); for ($i = 0; $i < 5; $i++) { $image_tag = new $imageTagModel(); $tag = new $tagModel(); $tag->name = $i; $image_tag->tag = $tag; $this->images_tags[] = $image_tag; } $this->image = new Image(['data' => ['id' => 1, 'name' => 'amiga_1200.jpg', 'title' => 'Amiga 1200', 'images_tags' => $this->images_tags]]); $this->through = new Through(['parent' => $this->image, 'model' => $this->tagModel, 'through' => 'images_tags', 'using' => 'tag']); }); describe("->parent()", function () { it("gets the parent", function () {
}); describe("->is()", function () { beforeEach(function () { $this->checker = Stub::classname(['extends' => Checker::class]); $this->validator = new Validator(['classes' => ['checker' => $this->checker]]); }); it("delegates to the checker", function () { $checker = $this->checker; $handler = $checker::get('alphaNumeric'); expect($checker)->toReceive('::check')->with('frferrf', [$handler], ['hello' => 'world']); $this->validator->is('alphaNumeric', 'frferrf', ['hello' => 'world']); }); }); describe("->__call()", function () { beforeEach(function () { $this->checker = Stub::classname(['extends' => Checker::class]); $this->validator = new Validator(['classes' => ['checker' => $this->checker]]); }); it("delegates to the checker", function () { $checker = $this->checker; $handler = $checker::get('alphaNumeric'); expect($checker)->toReceive('::check')->with('frferrf', [$handler], ['hello' => 'world']); $this->validator->isAlphaNumeric('frferrf', ['hello' => 'world']); }); it("bails out with no passed parameters", function () { expect($this->validator->isAlphaNumeric())->toBe(false); }); }); describe("->validates()", function () { beforeEach(function () { $this->validator = new Validator();
<?php use kahlan\plugin\Stub; use Sofa\Hookable\Builder; describe('Sofa\\Hookable\\Builder', function () { beforeEach(function () { $query = Stub::create(['class' => 'Illuminate\\Database\\Query\\Builder']); $this->eloquent = Stub::classname(['class' => 'Illuminate\\Database\\Eloquent\\Builder']); $this->builder = new Builder(new $query()); }); it('fallbacks to base builder for prefixed columns', function () { Stub::on($this->eloquent)->method('where', function () { return 'query'; }); expect($this->builder->where('prefixed.column', 'value'))->toBe('query'); }); it('calls hook defined on the model', function () { $model = Stub::create(); expect($model)->toReceive('queryHook'); Stub::on($this->builder)->method('getModel', function () use($model) { return $model; }); $this->builder->select('column', 'value'); }); });
$code = "<?php\necho 'Hello World!';\n"; $matcher = function ($actual) use($code) { return $code === (string) $actual; }; expect($stub1)->toReceive('process')->with(Arg::toMatch($matcher), $path); expect($stub2)->toReceive('process')->with(Arg::toMatch($matcher), $path); $this->patchers->process($code, $path); }); it("bails out if code to process is an empty string", function () { expect($this->patchers->process(''))->toBe(''); }); }); describe("->findFile()", function () { beforeEach(function () { $this->loader = Stub::create(); $this->class = Stub::classname(); $this->file = 'some/path/file.php'; $this->stub1 = Stub::create(); $this->patchers->add('patcher1', $this->stub1); $this->stub2 = Stub::create(); $this->patchers->add('patcher2', $this->stub2); $file = $this->file; Stub::on($this->stub1)->method('findFile', function () use($file) { return $file; }); Stub::on($this->stub2)->method('findFile', function () use($file) { return $file; }); }); it("runs findFile() on all patchers", function () { expect($this->stub1)->toReceive('findFile')->with($this->loader, $this->class, $this->file);