示例#1
0
         $class = $this->class;
         $subclass = Double::classname(['extends' => $class]);
         allow($subclass)->toReceive('::filterable')->andRun(function () {
             return Filters::run(get_called_class(), 'filterable', func_get_args(), function ($next, $message) {
                 return "Hello {$message}";
             });
         });
         Filters::apply($class, 'filterable', $this->filter1);
         Filters::apply($subclass, 'filterable', $this->filter2);
         expect($subclass::filterable('World!'))->toBe('21Hello World!12');
         Filters::apply($subclass, 'filterable', $this->noChain);
         expect($subclass::filterable('World!'))->toBe("Hello");
     });
     it("applies filters in order", function () {
         $class = $this->class;
         $subclass = Double::classname(['extends' => $class]);
         allow($subclass)->toReceive('::filterable')->andRun(function () {
             return Filters::run(get_called_class(), 'filterable', func_get_args(), function ($next, $message) {
                 return "Hello {$message}";
             });
         });
         Filters::apply($subclass, 'filterable', $this->filter1);
         Filters::apply($subclass, 'filterable', $this->filter2);
         expect($subclass::filterable('World!'))->toBe('21Hello World!12');
     });
 });
 describe("::get()", function () {
     it("exports filters setted as a class level", function () {
         Filters::apply($this->class, 'filterable', $this->filter1);
         $filters = Filters::get();
         expect($filters)->toHaveLength(1);
示例#2
0
            expect($double->getTimestamp())->toBe(12345678);
        });
        it("adds ` = NULL` to optional parameter in PHP core method", function () {
            skipIf(defined('HHVM_VERSION'));
            $result = Double::generate(['class' => 'Kahlan\\Spec\\Plugin\\Double\\Double', 'extends' => 'LogicException', 'layer' => true]);
            $expected = <<<EOD
<?php
namespace Kahlan\\\\Spec\\\\Plugin\\\\Double;

class Double extends \\\\LogicException {

    public function __construct\\(\\\$message = NULL, \\\$code = NULL, \\\$previous = NULL\\)
EOD;
            expect($result)->toMatch('~' . $expected . '~i');
        });
        it("generates code without PHP tags", function () {
            $result = Double::generate(['class' => 'Kahlan\\Spec\\Plugin\\Double\\Double', 'magicMethods' => false, 'openTag' => false, 'closeTag' => false]);
            $expected = <<<EOD
namespace Kahlan\\Spec\\Plugin\\Double;

class Double {



}

EOD;
            expect($result)->toBe($expected);
        });
    });
});
示例#3
0
     it("formats an exception as a string message", function () {
         $message = Debugger::message(new Exception('World Destruction Error!'));
         expect($message)->toBe('`Exception` Code(0): World Destruction Error!');
     });
     it("formats a backtrace array as a string message", function () {
         $backtrace = ['message' => 'E_ERROR Error!', 'code' => E_ERROR];
         $message = Debugger::message($backtrace);
         expect($message)->toBe("`E_ERROR` Code(1): E_ERROR Error!");
         $backtrace = ['message' => 'Invalid Error!', 'code' => 404];
         $message = Debugger::message($backtrace);
         expect($message)->toBe("`<INVALID>` Code(404): Invalid Error!");
     });
 });
 describe("::loader()", function () {
     it("gets/sets a loader", function () {
         $loader = Double::instance();
         expect(Debugger::loader($loader))->toBe($loader);
     });
 });
 describe("::errorType()", function () {
     it("returns some reader-friendly error type string", function () {
         expect(Debugger::errorType(E_ERROR))->toBe('E_ERROR');
         expect(Debugger::errorType(E_WARNING))->toBe('E_WARNING');
         expect(Debugger::errorType(E_PARSE))->toBe('E_PARSE');
         expect(Debugger::errorType(E_NOTICE))->toBe('E_NOTICE');
         expect(Debugger::errorType(E_CORE_ERROR))->toBe('E_CORE_ERROR');
         expect(Debugger::errorType(E_CORE_WARNING))->toBe('E_CORE_WARNING');
         expect(Debugger::errorType(E_CORE_ERROR))->toBe('E_CORE_ERROR');
         expect(Debugger::errorType(E_COMPILE_ERROR))->toBe('E_COMPILE_ERROR');
         expect(Debugger::errorType(E_CORE_WARNING))->toBe('E_CORE_WARNING');
         expect(Debugger::errorType(E_COMPILE_WARNING))->toBe('E_COMPILE_WARNING');
示例#4
0
         $this->expect($result)->toBe('2 and 3');
         $result = Text::clean('{:a}, 2 and {:c}');
         $this->expect($result)->toBe('2');
     });
 });
 describe("::toString()", function () {
     it("exports an empty array", function () {
         $dump = Text::toString([]);
         $this->expect($dump)->toBe("[]");
     });
     it("exports an object", function () {
         $dump = Text::toString(new stdClass());
         $this->expect($dump)->toBe("`stdClass`");
     });
     it("exports an object supporting __toString()", function () {
         $stub = Double::instance();
         allow($stub)->toReceive('__toString')->andReturn('jedi');
         $dump = Text::toString($stub);
         $this->expect($dump)->toBe("jedi");
     });
     it("exports an object using a closure", function () {
         $toString = function ($instance) {
             return 'an instance of `' . get_class($instance) . '`';
         };
         $dump = Text::toString(new stdClass(), ['object' => ['method' => $toString]]);
         $this->expect($dump)->toBe("an instance of `stdClass`");
     });
     it("exports an exception", function () {
         $dump = Text::toString(new Exception());
         $this->expect($dump)->toMatch("~`Exception` Code\\(0\\) with no message in .*?" . DS . "Text.spec.php.*?\$~");
         $dump = Text::toString(new Exception('error', 500));
示例#5
0
            $cursor->rewind();
            expect($cursor->next())->toBe(1);
        });
    });
    describe("->current()", function () {
        it("returns `false` when the `PDOStatement` returns `false`", function () {
            $resource = Double::instance();
            allow($resource)->toReceive('fetch')->andRun(function () {
                return false;
            });
            $cursor = new Cursor(['resource' => $resource]);
            expect($cursor->current())->toBe(false);
        });
        it("returns `false` when the `PDOStatement` throws an exception", function () {
            $resource = Double::instance();
            allow($resource)->toReceive('fetch')->andRun(function () {
                throw new PDOException();
            });
            $cursor = new Cursor(['resource' => $resource]);
            expect($cursor->current())->toBe(false);
        });
        it("sets the resource extracted data on success", function () {
            $resource = Double::instance();
            allow($resource)->toReceive('fetch')->andRun(function () {
                return 'data';
            });
            $cursor = new Cursor(['resource' => $resource]);
            expect($cursor->current())->toBe('data');
        });
    });
});
示例#6
0
    describe("::all()", function () {
        beforeEach(function () {
            $model = $this->model;
            $schema = $model::definition();
            $this->query = $query = Double::instance();
            allow($schema)->toReceive('query')->andRun(function () use($query) {
                return $query;
            });
        });
        it("delegates to `::all`", function () {
            $model = $this->model;
            expect($model)->toReceive('::find')->with(['query' => ['field' => 'value']]);
            expect($this->query)->toReceive('all')->with(['fetch' => 'options']);
            $model::all(['query' => ['field' => 'value']], ['fetch' => 'options']);
        });
    });
    describe("::definition()", function () {
        it("returns the model", function () {
            $model = $this->model;
            $schema = $model::definition();
            expect($schema)->toBeAnInstanceOf('chaos\\Schema');
            expect($schema)->toBe($model::definition());
        });
        it("gets/sets a finders", function () {
            $schema = Double::instance();
            $model = $this->model;
            $model::definition($schema);
            expect($model::definition())->toBe($schema);
        });
    });
});
示例#7
0
         $expectation = new Expectation();
         expect($expectation->not())->toBe(false);
         expect($expectation->not)->toBe($expectation);
         expect($expectation->not())->toBe(true);
     });
     it("throws an exception with unsupported attributes", function () {
         $closure = function () {
             $expectation = new Expectation();
             $expectation->abc;
         };
         expect($closure)->toThrow(new Exception('Unsupported attribute `abc`.'));
     });
 });
 describe("->clear()", function () {
     it("clears an expectation", function () {
         $actual = Double::instance();
         $expectation = expectation($actual, 10);
         $matcher = $expectation->not->toReceive('helloWorld');
         expect($expectation->actual())->toBe($actual);
         expect($expectation->deferred())->toBe(['matcherName' => 'toReceive', 'matcher' => 'Kahlan\\Matcher\\ToReceive', 'data' => ['actual' => $actual, 'expected' => 'helloWorld'], 'instance' => $matcher, 'not' => true]);
         expect($expectation->timeout())->toBe(10);
         expect($expectation->not())->toBe(true);
         expect($expectation->passed())->toBe(true);
         expect($expectation->logs())->toHaveLength(1);
         $expectation->clear();
         expect($expectation->actual())->toBe(null);
         expect($expectation->deferred())->toBe(null);
         expect($expectation->timeout())->toBe(-1);
         expect($expectation->not())->toBe(false);
         expect($expectation->passed())->toBe(true);
         expect($expectation->logs())->toHaveLength(0);
示例#8
0
         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 = Double::instance();
         $this->class = Double::classname();
         $this->file = 'some/path/file.php';
         $this->stub1 = Double::instance();
         $this->patchers->add('patcher1', $this->stub1);
         $this->stub2 = Double::instance();
         $this->patchers->add('patcher2', $this->stub2);
         $file = $this->file;
         allow($this->stub1)->toReceive('findFile')->andRun(function () use($file) {
             return $file;
         });
         allow($this->stub2)->toReceive('findFile')->andRun(function () use($file) {
             return $file;
         });
     });
     it("runs findFile() on all patchers", function () {
         expect($this->stub1)->toReceive('findFile')->with($this->loader, $this->class, $this->file);
         expect($this->stub2)->toReceive('findFile')->with($this->loader, $this->class, $this->file);
         $actual = $this->patchers->findFile($this->loader, $this->class, $this->file);
         expect($actual)->toBe('some/path/file.php');
     });
示例#9
0
         expect($this->finders->set('myfinder', $closure))->toBe($this->finders);
         expect($this->finders->get('myfinder'))->toBe($closure);
     });
 });
 describe("->exists()", function () {
     it("checks if a finder exists", function () {
         $closure = function () {
         };
         expect($this->finders->exists('myfinder'))->toBe(false);
         $this->finders->set('myfinder', $closure);
         expect($this->finders->exists('myfinder'))->toBe(true);
     });
 });
 describe("->_call()", function () {
     it("calls a finder", function () {
         $closure = Double::instance();
         $this->finders->set('myfinder', $closure);
         expect($closure)->toReceive('__invoke')->with('a', 'b', 'c');
         $this->finders->myfinder('a', 'b', 'c');
     });
     it("throws an exception if no finder exists", function () {
         $closure = function () {
             $this->finders->myfinder('a', 'b', 'c');
         };
         expect($closure)->toThrow(new ChaosException("Unexisting finder `'myfinder'`."));
     });
 });
 describe("->remove()", function () {
     it("removes a finder", function () {
         $closure = function () {
         };
示例#10
0
namespace Chaos\Spec\Suite\Collection;

use InvalidArgumentException;
use Chaos\Model;
use Chaos\Collection\Collection;
use Chaos\Collection\Through;
use Kahlan\Plugin\Double;
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 = Double::classname(['extends' => ImageTag::class]);
        $imageTagModel::definition()->locked(false);
        $this->tagModel = $tagModel = Double::classname(['extends' => Tag::class, 'methods' => ['tagMethod']]);
        $tagModel::definition()->locked(false);
        allow($tagModel)->toReceive('tagMethod')->andRun(function ($options) {
            return $options;
        });
        for ($i = 0; $i < 5; $i++) {
            $image_tag = new $imageTagModel();
            $tag = new $tagModel();
            $tag->name = (string) $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(['schema' => $tagModel::definition(), 'parent' => $this->image, 'through' => 'images_tags', 'using' => 'tag']);
        $this->image->tags = $this->through;
    });
示例#11
0
namespace Lead\Sql\Spec\Suite;

use Lead\Sql\SqlException;
use Lead\Sql\Statement;
use Lead\Sql\Statement\Behavior\HasFlags;
use Lead\Sql\Statement\Behavior\HasWhere;
use Lead\Sql\Statement\Behavior\HasOrder;
use Lead\Sql\Statement\Behavior\HasLimit;
use Kahlan\Plugin\Double;
describe("Statement", function () {
    beforeEach(function () {
        $this->statement = Double::instance(['extends' => Statement::class, 'uses' => [HasFlags::class, HasWhere::class, HasOrder::class, HasLimit::class]]);
    });
    describe("->dialect()", function () {
        it("gets/sets a dialect", function () {
            $dialect = Double::instance();
            $this->statement->dialect($dialect);
            expect($this->statement->dialect())->toBe($dialect);
        });
        it("throws an exception if no dialect has been defined", function () {
            $closure = function () {
                $this->statement->dialect();
            };
            expect($closure)->toThrow(new SqlException("Missing SQL dialect adapter."));
        });
    });
    describe("->data()", function () {
        it("gets/sets some data", function () {
            $this->statement->data('key', 'value');
            expect($this->statement->data('key'))->toBe('value');
        });
示例#12
0
 });
 describe("->is()", function () {
     beforeEach(function () {
         $this->checker = Double::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 = Double::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();
示例#13
0
            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', Double::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', Double::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', Double::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`."));
        });
    });
});
示例#14
0
     allow($bar)->toReceive('send')->andReturn('EOF');
     allow('Kahlan\\Spec\\Fixture\\Plugin\\Pointcut\\Bar')->toBe($bar);
     $foo = new Foo();
     expect($foo->bar())->toBe('EOF');
 });
 it("monkey patches a function", function () {
     $mon = new Mon();
     allow('time')->toBe(function () {
         return 123;
     });
     expect($mon->time())->toBe(123);
 });
 it("throws an exception when trying to monkey patch an instance", function () {
     expect(function () {
         $foo = new Foo();
         allow($foo)->toBe(Double::instance());
     })->toThrow(new Exception("Error `toBe()` need to be applied on a fully-namespaced class or function name."));
 });
 it("throws an exception when trying to monkey patch an instance using a generic stub", function () {
     expect(function () {
         $foo = new Foo();
         allow($foo)->toBeOK();
     })->toThrow(new Exception("Error `toBeOK()` need to be applied on a fully-namespaced class or function name."));
 });
 context("with an instance", function () {
     it("stubs a method", function () {
         $foo = new Foo();
         allow($foo)->toReceive('message')->andReturn('Good Bye!');
         expect($foo->message())->toBe('Good Bye!');
     });
     it("stubs with multiple return value", function () {
示例#15
0
<?php

namespace Kahlan\Spec\Suite\Filter\Behavior;

use Kahlan\Plugin\Double;
use Kahlan\Filter\MethodFilters;
describe('Filterable', function () {
    beforeEach(function () {
        $this->mock = Double::instance(['uses' => ['Kahlan\\Filter\\Behavior\\Filterable']]);
        allow($this->mock)->toReceive('filterable')->andRun(function () {
            return Filter::on($this, 'filterable', func_get_args(), function ($chain, $message) {
                return "Hello {$message}";
            });
        });
    });
    describe("methodFilters", function () {
        it("gets the `MethodFilters` instance", function () {
            expect($this->mock->methodFilters())->toBeAnInstanceOf('Kahlan\\Filter\\MethodFilters');
        });
        it("sets a new `MethodFilters` instance", function () {
            $methodFilters = new MethodFilters();
            expect($this->mock->methodFilters($methodFilters))->toBeAnInstanceOf('Kahlan\\Filter\\MethodFilters');
            expect($this->mock->methodFilters())->toBe($methodFilters);
        });
    });
});
示例#16
0
use Exception;
use InvalidArgumentException;
use Lead\Text\Text;
use Kahlan\Plugin\Double;
describe("Text", function () {
    describe("::insert()", function () {
        it("inserts scalar variables in a string", function () {
            $string = 'Obi-Wan is {:adjective}.';
            $expected = 'Obi-Wan is awesome.';
            $result = Text::insert($string, ['adjective' => 'awesome']);
            expect($result)->toBe($expected);
        });
        it("inserts object variables supporting `__toString()` in a string", function () {
            $string = 'Obi-Wan is a {:noun}.';
            $expected = 'Obi-Wan is a jedi.';
            $double = Double::instance();
            allow($double)->toReceive('__toString')->andReturn('jedi');
            $result = Text::insert($string, ['noun' => $double]);
            expect($result)->toBe($expected);
        });
        it("inserts a blank for object variables which doesn't support `__toString()`", function () {
            $string = 'Obi-Wan is a {:noun}.';
            $expected = 'Obi-Wan is a .';
            $result = Text::insert($string, ['noun' => new stdClass()]);
            expect($result)->toBe($expected);
        });
        it("inserts a variable as many time as it exists a placeholder", function () {
            $string = '{:a} {:b} {:a} {:a}';
            $expected = '1 2 1 1';
            $result = Text::insert($string, ['a' => 1, 'b' => 2]);
            expect($result)->toBe($expected);
示例#17
0
     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', Double::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();
示例#18
0
                        $this->expect($closure)->not->toThrow();
                    });
                });
            });
            error_reporting(E_ALL ^ E_NOTICE);
            $this->suite->run();
            error_reporting(E_ALL);
            expect($this->suite->passed())->toBe(true);
        });
    });
    describe("->reporters()", function () {
        it("returns the reporters", function () {
            $describe = $this->suite->describe("", function () {
            });
            $reporters = Double::instance();
            $this->suite->run(['reporters' => $reporters]);
            expect($this->suite->reporters())->toBe($reporters);
        });
    });
    describe("->stop()", function () {
        it("sends the stop event", function () {
            $describe = $this->suite->describe("", function () {
            });
            $reporters = Double::instance();
            expect($reporters)->toReceive('dispatch')->with('stop', Arg::toBeAnInstanceOf('Kahlan\\Summary'));
            $this->suite->run(['reporters' => $reporters]);
            $this->suite->stop();
            expect($this->suite->reporters())->toBe($reporters);
        });
    });
});
示例#19
0
Host: localhost
Connection: Close
User-Agent: Mozilla/5.0
Transfer-Encoding: chunked
Content-Type: application/x-www-form-urlencoded

19
name1=value1&name2=value2
0

EOD;
            expect($request->toMessage())->toBe($expected);
        });
        it("throws an exception when Content-Length is required but not be determined", function () {
            $closure = function () {
                $stream = Double::instance(['extends' => 'Lead\\Storage\\Stream\\Stream']);
                allow($stream)->toReceive('length')->andReturn(null);
                $request = new Request(['method' => 'POST', 'type' => 'application/x-www-form-urlencoded', 'body' => $stream]);
                $request->toMessage();
            };
            expect($closure)->toThrow(new NetException('A Content-Length header is required but the request stream has a `null` length.'));
        });
    });
    describe("->export()", function () {
        it("exports default values", function () {
            $request = new Request();
            expect($request->export())->toEqual(['method' => 'GET', 'scheme' => 'http', 'version' => '1.1', 'host' => 'localhost', 'port' => 80, 'path' => '/', 'query' => '', 'fragment' => '', 'username' => null, 'password' => null, 'url' => 'http://localhost/', 'stream' => $request->stream()]);
        });
        it("exports a request", function () {
            $request = new Request(['scheme' => 'http', 'host' => 'www.domain.com', 'port' => 80, 'username' => 'username', 'password' => 'password', 'path' => 'index.php']);
            expect($request->export())->toEqual(['method' => 'GET', 'scheme' => 'http', 'version' => '1.1', 'host' => 'www.domain.com', 'port' => 80, 'path' => '/index.php', 'query' => '', 'fragment' => '', 'username' => 'username', 'password' => 'password', 'url' => 'http://www.domain.com/index.php', 'stream' => $request->stream()]);
示例#20
0
     it("gets a value using a virtual field", function () {
         $model = $this->model;
         $schema = $model::definition();
         $schema->column('hello_boy', ['getter' => function ($entity, $data, $name) {
             return 'Hi Boy!';
         }]);
         $entity = $model::create();
         expect($entity->hello_boy)->toBe('Hi Boy!');
     });
     context("when a model is defined", function () {
         beforeEach(function () {
             $this->model = Double::classname(['extends' => $this->model]);
         });
         it("autoboxes setted data", function () {
             $model = $this->model;
             $childEntity = Double::classname(['extends' => $this->model]);
             $childEntity::definition()->locked(false);
             $schema = new Schema(['model' => $model]);
             $schema->column('child', ['type' => 'object', 'model' => $childEntity]);
             $model::definition($schema);
             $entity = $model::create();
             $entity['child'] = ['id' => 1, 'title' => 'child record', 'enabled' => true];
             $child = $entity['child'];
             expect($child)->toBeAnInstanceOf($childEntity);
             expect($child->parents()->get($entity))->toBe('child');
             expect($child->basePath())->toBe('child');
         });
     });
 });
 describe("->validates()", function () {
     beforeEach(function () {
示例#21
0
 /**
  * Helper for `Layer::process()`.
  *
  * @param array $parent The node instance tor process.
  */
 protected function _processTree($parent)
 {
     foreach ($parent->tree as $node) {
         if ($node->processable && $node->type === 'class' && $node->extends) {
             $namespace = $node->namespace->name . '\\';
             $parent = $node->extends;
             $extends = ltrim($parent[0] === '\\' ? $parent : $namespace . $parent, '\\');
             if (!isset($this->_override[$extends])) {
                 continue;
             }
             $layerClass = $node->name . $this->_suffix;
             $node->extends = $layerClass;
             $pattern = preg_quote($parent);
             $node->body = preg_replace("~(extends\\s+){$pattern}~", "\\1{$layerClass}", $node->body);
             $code = Double::generate(['class' => $layerClass, 'extends' => $extends, 'openTag' => false, 'closeTag' => false, 'layer' => true]);
             $parser = $this->_classes['parser'];
             $root = $parser::parse($code, ['php' => true]);
             $node->close .= str_replace("\n", '', $parser::unparse($this->_pointcut->process($root)));
         } elseif (count($node->tree)) {
             $this->_processTree($node);
         }
     }
 }
示例#22
0
文件: Stub.php 项目: crysalead/kahlan
 /**
  * Stubs a method.
  *
  * @param  string   $path    Method name or array of stubs where key are method names and
  *                           values the stubs.
  * @param  string   $closure The stub implementation.
  * @return Method[]          The created array of method instances.
  * @return Method            The stubbed method instance.
  */
 public function method($path, $closure = null)
 {
     if ($this->_needToBePatched) {
         $layer = Double::classname();
         Monkey::patch($this->_reference, $layer);
         $this->_needToBePatched = false;
         $this->_reference = $layer;
     }
     $reference = $this->_reference;
     if (!$path) {
         throw new InvalidArgumentException("Method name can't be empty.");
     }
     $names = is_array($path) ? $path : [$path];
     $this->_chain = [];
     $total = count($names);
     foreach ($names as $index => $name) {
         if (preg_match('/^::.*/', $name)) {
             $reference = is_object($reference) ? get_class($reference) : $reference;
         }
         $hash = Suite::hash($reference);
         if (!isset(static::$_registered[$hash])) {
             static::$_registered[$hash] = new static($reference);
         }
         $instance = static::$_registered[$hash];
         if (is_object($reference)) {
             Suite::register(get_class($reference));
         } else {
             Suite::register($reference);
         }
         if (!isset($instance->_methods[$name])) {
             $instance->_methods[$name] = [];
             $instance->_stubs[$name] = Double::instance();
         }
         $method = new Method(['parent' => $this, 'reference' => $reference, 'name' => $name]);
         $this->_chain[$name] = $method;
         array_unshift($instance->_methods[$name], $method);
         if ($index < $total - 1) {
             $reference = $instance->_stubs[$name];
             $method->andReturn($instance->_stubs[$name]);
         }
     }
     $method = end($this->_chain);
     if ($closure) {
         $method->andRun($closure);
     }
     return $method;
 }
示例#23
0
<?php

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);
示例#24
0
         $collection->data([]);
     });
 });
 describe("::toArray()", function () {
     it("converts a collection to an array", function () {
         $collection = new Collection(['data' => [1, 2, 3, 4, 5]]);
         expect(Collection::toArray($collection))->toBe([1, 2, 3, 4, 5]);
     });
     it("converts objects which support __toString", function () {
         $stringable = Double::classname();
         allow($stringable)->toReceive('__toString')->andReturn('hello');
         $collection = new Collection(['data' => [new $stringable()]]);
         expect(Collection::toArray($collection))->toBe(['hello']);
     });
     it("converts objects using handlers", function () {
         $handlable = Double::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 () {
示例#25
0
 /**
  * Sets the stub logic.
  *
  * @param mixed $substitute The logic.
  */
 public function toBeOK()
 {
     if (!is_string($this->_actual)) {
         throw new Exception("Error `toBeOK()` need to be applied on a fully-namespaced class or function name.");
     }
     if ($this->_isClass) {
         Monkey::patch($this->_actual, Double::classname());
     } else {
         Monkey::patch($this->_actual, function () {
         });
     }
 }
示例#26
0
     it("returns all relation names", function () {
         $relations = $this->schema->relations();
         sort($relations);
         expect($relations)->toBe(['gallery', 'images_tags', 'tags']);
     });
     it("includes embedded relations using `true` as first parameter", function () {
         $model = Double::classname(['extends' => Model::class]);
         $schema = new Schema(['model' => $model]);
         $schema->column('embedded', ['type' => 'object', 'model' => $model]);
         expect($schema->relations())->toBe([]);
         expect($schema->relations(true))->toBe(['embedded']);
     });
 });
 describe("->conventions()", function () {
     it("gets/sets the conventions", function () {
         $conventions = Double::instance();
         $schema = new Schema();
         expect($schema->conventions($conventions))->toBe($schema);
         expect($schema->conventions())->toBe($conventions);
     });
 });
 describe("->expand()", function () {
     it("expands schema paths", function () {
         expect($this->schema->expand(['gallery', 'tags']))->toBe(['gallery' => null, 'tags' => null, 'images_tags.tag' => null]);
     });
     it("perserves values", function () {
         $actual = $this->schema->expand(['gallery' => ['conditions' => ['name' => 'My Gallery']], 'tags' => ['conditions' => ['name' => 'landscape']]]);
         expect($actual)->toBe(['gallery' => ['conditions' => ['name' => 'My Gallery']], 'tags' => ['conditions' => ['name' => 'landscape']], 'images_tags.tag' => ['conditions' => ['name' => 'landscape']]]);
     });
 });
 describe("->treeify()", function () {