Creates a polyvalent instance.
public static instance ( array $options = [] ) : object | ||
$options | array | Array of options. Options are: - `'class'` _string_: the fully-namespaced class name. - `'extends'` _string_: the fully-namespaced parent class name. - `'args'` _array_: arguments to pass to the constructor. - `'methods'` _string_: override the method defined. |
리턴 | object | The created instance. |
$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);
$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));
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); }); }); });
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()]);
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');
<?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); }); }); });
$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); }); }); });
public function foo(\$a) {return parent::foo(\$a);} public function foo2(\$b = NULL) {return parent::foo2(\$b);} public function foo3(array \$b = array()) {return parent::foo3(\$b);} public function foo4(callable \$fct) {return parent::foo4(\$fct);} public function foo5(\\Closure \$fct) {return parent::foo5(\$fct);} public function foo6(\\Exception \$e) {return parent::foo6(\$e);} public function foo7(\\Kahlan\\Spec\\Fixture\\Plugin\\Double\\DozInterface \$instance) {return parent::foo7(\$instance);} } ?> EOD; expect($result)->toBe($expected); }); it("overrides by default all parent class method of internal classes if the layer option is not defined", function () { $double = Double::instance(['extends' => 'DateTime']); allow($double)->toReceive('getTimestamp')->andReturn(12345678); 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');
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 () { };
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);
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'); });
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'); });
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 () {
<?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);
/** * 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; }
$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'); }); }); });
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 () {