diff --git a/tests/_files/assets/foo.css b/tests/_files/assets/foo.css
new file mode 100644
index 0000000..e69de29
diff --git a/tests/_files/assets/foo.jpg b/tests/_files/assets/foo.jpg
new file mode 100644
index 0000000..e69de29
diff --git a/tests/_files/assets/foo.js b/tests/_files/assets/foo.js
new file mode 100644
index 0000000..e69de29
diff --git a/tests/_files/bar/foo.php b/tests/_files/bar/foo.php
new file mode 100644
index 0000000..e69de29
diff --git a/tests/_files/bar/second.php b/tests/_files/bar/second.php
new file mode 100644
index 0000000..88dc436
--- /dev/null
+++ b/tests/_files/bar/second.php
@@ -0,0 +1,16 @@
+layout('main', ['foo' => 'Bar!']) ?>
+
+section('one') ?>
+World = $this->foo ?>
+stop() ?>
+
+section('two') ?>
+I Win
+replace() ?>
+
+Buffalo Bill
+
+section('three') ?>
+MAN
+stop();
diff --git a/tests/_files/foo/alias.php b/tests/_files/foo/alias.php
new file mode 100644
index 0000000..8251678
--- /dev/null
+++ b/tests/_files/foo/alias.php
@@ -0,0 +1 @@
+= $T->foo ?>
\ No newline at end of file
diff --git a/tests/_files/foo/bar.inc b/tests/_files/foo/bar.inc
new file mode 100644
index 0000000..3d6365d
--- /dev/null
+++ b/tests/_files/foo/bar.inc
@@ -0,0 +1,2 @@
+data());
diff --git a/tests/_files/foo/blocks.php b/tests/_files/foo/blocks.php
new file mode 100644
index 0000000..d822e67
--- /dev/null
+++ b/tests/_files/foo/blocks.php
@@ -0,0 +1,11 @@
+block('spaceless') ?>
+ block('wrap', '
', '
') ?>
+ block('spaceless') ?>
+
+ block('repeat', 3) ?>
+ - a
+ endblock('repeat'); ?>
+
+ endblock('spaceless') ?>
+ endblock('wrap') ?>
+endblock('spaceless') ?>
diff --git a/tests/_files/foo/double.tpl.php b/tests/_files/foo/double.tpl.php
new file mode 100644
index 0000000..8a41cc6
--- /dev/null
+++ b/tests/_files/foo/double.tpl.php
@@ -0,0 +1 @@
+I have 2 extensions
diff --git a/tests/_files/foo/foo.php b/tests/_files/foo/foo.php
new file mode 100644
index 0000000..b8be172
--- /dev/null
+++ b/tests/_files/foo/foo.php
@@ -0,0 +1,2 @@
+data());
diff --git a/tests/_files/foo/main.php b/tests/_files/foo/main.php
new file mode 100644
index 0000000..a3c7316
--- /dev/null
+++ b/tests/_files/foo/main.php
@@ -0,0 +1,14 @@
+section('one') ?>
+Hello = $this->foo.' ' ?>
+stop() ?>
+
+Alone
+
+section('two') ?>
+NO
+stop() ?>
+
+section('three') ?>
+YES
+stop();
diff --git a/tests/_files/stubs.php b/tests/_files/stubs.php
new file mode 100644
index 0000000..78f0919
--- /dev/null
+++ b/tests/_files/stubs.php
@@ -0,0 +1,49 @@
+value = $value;
+ }
+}
+
+class ToArray extends Value
+{
+ public function toArray()
+ {
+ return ['toarray' => (array) $this->value];
+ }
+}
+
+class AsArray extends Value
+{
+ public function asArray()
+ {
+ return ['asarray' => (array) $this->value];
+ }
+}
+
+class Json implements JsonSerializable
+{
+ public function jsonSerialize()
+ {
+ return 'I am JSON';
+ }
+}
+
+class Target extends Value
+{
+}
+
+class Transformer
+{
+ public function transform($object)
+ {
+ return is_object($object) ? ['transformed' => get_object_vars($object)] : false;
+ }
+}
diff --git a/tests/_files/templates/expected.html b/tests/_files/templates/expected.html
new file mode 100644
index 0000000..e7939fd
--- /dev/null
+++ b/tests/_files/templates/expected.html
@@ -0,0 +1,113 @@
+
+
+
+
+ Foil is Awesome!
+
+
+
+
+
+
+
+
+
+
Deep var test: Lorem Ipsum Dolor
+
+
Default test: I am a default.
+
+
__get test: TEST ME!
+
+
Raw test: This is a strong tag html content
+
+
Autoescape test: <strong>This is a strong tag html content</strong>
+
+
Filter test: I AM LOWERCASE
+
+
Advanced test: HELLO WORLD!
+
+
+
+
+ Here something for you.
+
+
+
+
OVERRIDE a section defined in a PARTIAL
+
+
+ I am a partial. And this: "TEST ME!" is a var I share with template, but
+ this "I am a partial var!" is a specific partial var.
+
+
+
+
+
+
+ I am another partial.
+ This: "I am a partial var too." is a specific partial var.
+ This: "TEST ME!" is a var I share with template.
+ A shared var skipped: "Foil is Awesome!".
+
+
+
+
+
Should BE SUPPLYED by layout.
+
+
+
+ I am here.
+
+
+
+
+
MAIN LAYOUT, first section
+
+
+
+
Should REPLACE layout first-child layout section.
+
+
+
+
MAIN LAYOUT, first section after child
+
+
Should BE APPENDED to layout first section.
+
+
+
+
+
+
Should REPLACE layout second section.
+
+
+
Extended layout third section.
+
Should BE APPENDED to extended layout third section.
+
+
+
+
+
+
+
EXTENDED LAYOUT, Out of any section, output a deep var Another deep var.
+
+
+
+
+ I am another partial.
+ This: "!!!" is a specific partial var.
+ This: "TEST ME!" is a var I share with template.
+ A shared var skipped: "".
+
+
+
FINAL TEMPLATE, Out of any section, ouput a var TEST ME!
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/_files/templates/extended.php b/tests/_files/templates/extended.php
new file mode 100644
index 0000000..391c8fd
--- /dev/null
+++ b/tests/_files/templates/extended.php
@@ -0,0 +1,33 @@
+layout('layout') ?>
+
+EXTENDED LAYOUT, Out of any section, output a deep var = $this->v('a.var.in.extended') ?>
+
+section('first') ?>
+
+Should BE APPENDED to layout first section.
+
+append() // first ?>
+
+section('first-child') ?>
+
+Should REPLACE layout first-child layout section.
+
+replace() // first-child ?>
+
+section('second') ?>
+
+Should REPLACE layout second section.
+
+
+
+ section('third') ?>
+
Extended layout third section.
+ append() // third ?>
+
+
+
+replace(); // second ?>
+
+
+ = $this->buffer() ?>
+
diff --git a/tests/_files/templates/final-template.php b/tests/_files/templates/final-template.php
new file mode 100644
index 0000000..4a7049d
--- /dev/null
+++ b/tests/_files/templates/final-template.php
@@ -0,0 +1,25 @@
+layout('extended') ?>
+
+section('a-section') ?>
+
+Should BE SUPPLYED by layout.
+
+stop() ?>
+
+
+section('third') ?>
+
+Should BE APPENDED to extended layout third section.
+
+append() // third ?>
+
+
+section('another-section') ?>
+
+OVERRIDE a section defined in a PARTIAL
+
+replace() // another-section ?>
+
+= $this->insert('partials/partial-2', ['a_partial_var' => '"!!!"'], ['test_me']) ?>
+
+FINAL TEMPLATE, Out of any section, ouput a var = $this->v('test_me') ?>
diff --git a/tests/_files/templates/layout.php b/tests/_files/templates/layout.php
new file mode 100644
index 0000000..7150a08
--- /dev/null
+++ b/tests/_files/templates/layout.php
@@ -0,0 +1,90 @@
+
+
+
+
+ = $this->v('title', 'Default Title') ?>
+
+
+
+
+
+ = $this->ww('menu', '', '%s') ?>
+
+ = $this->wwif('menu', false, '%s
', '%s') ?>
+
+
+
+
Deep var test: = $this->v('a.pretty.deep.var') ?>
+
+
Default test: = $this->v('i_do_not_exist', 'I am a default.') ?>
+
+
__get test: = $this->test_me ?>
+
+
Raw test: = $this->raw('html_content') ?>
+
+
Autoescape test: = $this->html_content ?>
+
+
Filter test: = $this->f('uppercase|reverse', 'lowercase') ?>
+
+
Advanced test: = $this->v('a.var.0|uppercase|reverse') ?>
+
+
+
+
+ = $this->returnSomething() ?>
+
+
+
+ = $this->insert('partials/partial', ['a_partial_var' => '"I am a partial var!"']) ?>
+
+
+
+ = $this->raw('i_do_not_exist', $this->insert('partials/partial-2', ['a_partial_var' => '"I am a partial var too."'])) ?>
+
+
+
+ = $this->supply('a-section') ?>
+
+
+
+ = $this->supply('a-non-existent-section', 'I am here.') ?>
+
+
+
+
+ section('first') ?>
+
+
MAIN LAYOUT, first section
+
+
+
+ section('first-child') ?>
+
+
MAIN LAYOUT, first child section
+
+ stop() // first-child ?>
+
+
+
+
MAIN LAYOUT, first section after child
+
+ stop() // first ?>
+
+
+
+
+
+ section('second') ?>
+
+
MAIN LAYOUT, second section
+
+ stop() // second ?>
+
+
+
+
+ = $this->buffer() ?>
+
+
+
+
diff --git a/tests/_files/templates/partials/partial-2.php b/tests/_files/templates/partials/partial-2.php
new file mode 100644
index 0000000..6fcd717
--- /dev/null
+++ b/tests/_files/templates/partials/partial-2.php
@@ -0,0 +1,6 @@
+
+ I am another partial.
+ This: = $this->v('a_partial_var') ?> is a specific partial var.
+ This: "= $this->test_me ?>" is a var I share with template.
+ A shared var skipped: "= $this->v('title') ?>".
+
diff --git a/tests/_files/templates/partials/partial.php b/tests/_files/templates/partials/partial.php
new file mode 100644
index 0000000..b788c1e
--- /dev/null
+++ b/tests/_files/templates/partials/partial.php
@@ -0,0 +1,10 @@
+section('another-section') ?>
+
+A SECTION defined in a PARTIAL
+
+stop() ?>
+
+
+ I am a partial. And this: "= $this->test_me ?>" is a var I share with template, but
+ this = $this->v('a_partial_var') ?> is a specific partial var.
+
diff --git a/tests/boot.php b/tests/boot.php
new file mode 100644
index 0000000..1edf178
--- /dev/null
+++ b/tests/boot.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+$vendor = dirname(dirname(__FILE__)).'/vendor/';
+
+if (! realpath($vendor)) {
+ die('Please install via Composer before running tests.');
+}
+
+require_once $vendor.'antecedent/patchwork/Patchwork.php';
+require_once $vendor.'autoload.php';
+require_once $vendor.'phpunit/phpunit/src/Framework/Assert/Functions.php';
+
+putenv('FOIL_TESTS_BASEPATH='.__DIR__);
+
+unset($vendor);
diff --git a/tests/src/TestCase.php b/tests/src/TestCase.php
new file mode 100644
index 0000000..4fd229b
--- /dev/null
+++ b/tests/src/TestCase.php
@@ -0,0 +1,94 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Foil\Tests;
+
+use PHPUnit_Framework_TestCase;
+use Brain\Monkey;
+use Closure;
+use InvalidArgumentException;
+use LogicException;
+
+/**
+ * @author Giuseppe Mazzapica
+ * @package foil\foil
+ * @license http://opensource.org/licenses/MIT MIT
+ */
+class TestCase extends PHPUnit_Framework_TestCase
+{
+ protected function setUp()
+ {
+ parent::setUp();
+ Monkey::setUp();
+ }
+
+ protected function tearDown()
+ {
+ Monkey::tearDown();
+ parent::tearDown();
+ }
+
+ /**
+ * @param callable $closure
+ * @param object $object
+ * @param array $args
+ * @return mixed
+ */
+ protected function bindClosure(Closure $closure, $object, array $args = [])
+ {
+ /** @var \Closure $closure */
+ /** @noinspection PhpUndefinedMethodInspection */
+ $closure = Closure::bind($closure, $object, get_class($object));
+
+ return call_user_func_array($closure, $args);
+ }
+
+ /**
+ * @param string $property
+ * @param $object
+ * @return mixed
+ */
+ protected function accessPrivateProperty($property, $object)
+ {
+ if (! is_string($property) || ! is_object($object)) {
+ throw new InvalidArgumentException(
+ __METHOD__.' needs a valid property name and a valid object.'
+ );
+ }
+
+ return $this->bindClosure(function ($property) {
+ if (! isset($this->$property)) {
+ throw new LogicException(
+ "{$property} is not a set on the object."
+ );
+ }
+
+ return $this->$property;
+ }, $object, [$property]);
+ }
+
+ /**
+ * @param string $property
+ * @param mixed $value
+ * @param object $object
+ * @return mixed
+ */
+ protected function setPrivateProperty($property, $value, $object)
+ {
+ if (! is_string($property) || ! is_object($object)) {
+ throw new InvalidArgumentException(
+ __METHOD__.' needs a valid property name and a valid object.'
+ );
+ }
+
+ return $this->bindClosure(function ($property, $value) {
+ $this->$property = $value;
+ }, $object, [$property, $value]);
+ }
+}
diff --git a/tests/src/TestCaseFunctional.php b/tests/src/TestCaseFunctional.php
new file mode 100644
index 0000000..53e3281
--- /dev/null
+++ b/tests/src/TestCaseFunctional.php
@@ -0,0 +1,50 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace Foil\Tests;
+
+use Foil\Foil;
+
+/**
+ * @author Giuseppe Mazzapica
+ * @package foil\foil
+ * @license http://opensource.org/licenses/MIT MIT
+ */
+class TestCaseFunctional extends TestCase
+{
+ /**
+ * @var \Foil\Engine
+ */
+ protected $engine;
+
+ /**
+ * @var \Pimple\Container
+ */
+ protected $container;
+
+ /**
+ * @param array $options
+ */
+ public function initFoil(array $options = [])
+ {
+ $base = realpath(getenv('FOIL_TESTS_BASEPATH')).DIRECTORY_SEPARATOR;
+ $options = array_merge(
+ [
+ 'folders' => [
+ 'foo' => $base.implode(DIRECTORY_SEPARATOR, ['_files', 'foo']),
+ 'bar' => $base.implode(DIRECTORY_SEPARATOR, ['_files', 'bar']),
+ ],
+ ],
+ $options
+ );
+ $app = Foil::boot($options);
+ $this->container = $this->accessPrivateProperty('container', $app);
+ $this->engine = $app->engine();
+ }
+}
diff --git a/tests/src/Unit/EngineTest.php b/tests/src/Unit/EngineTest.php
new file mode 100644
index 0000000..8cfddd4
--- /dev/null
+++ b/tests/src/Unit/EngineTest.php
@@ -0,0 +1,361 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Foil\Tests\Unit;
+
+use Foil\Engine;
+use Foil\Template\Finder;
+use Foil\Tests\TestCase;
+use Foil\Kernel\Events;
+use Mockery;
+
+/**
+ * @author Giuseppe Mazzapica
+ * @license http://opensource.org/licenses/MIT MIT
+ * @package Foil
+ */
+class EngineTest extends TestCase
+{
+ /**
+ * @param \Foil\Kernel\Events $events
+ * @param \Foil\Template\Finder $finder
+ * @param string $render
+ * @return \Foil\Engine
+ */
+ private function getEngine(Events $events = null, Finder $finder = null, $render = '')
+ {
+ /** @var \Foil\Template\Stack|\Mockery\MockInterface $stack */
+ $stack = Mockery::mock('Foil\Template\Stack');
+
+ /** @var \Foil\Template\Finder|\Mockery\MockInterface $finder */
+ $finder = $finder ?: Mockery::mock('Foil\Template\Finder');
+ if (is_null($events)) {
+ /** @var \Foil\Kernel\Events|\Mockery\MockInterface $events */
+ $events = Mockery::mock('Foil\Kernel\Events');
+ $events
+ ->shouldReceive('fire')
+ ->with(Mockery::type('string'), Mockery::type('array'))
+ ->andReturnNull();
+ $events
+ ->shouldReceive('on')
+ ->with(Mockery::type('string'), Mockery::type('Closure'))
+ ->andReturnNull();
+ }
+
+ $engine = new Engine($stack, $finder, $events);
+
+ if ($render) {
+ /** @var \Foil\Template\Stack|\Mockery\MockInterface $template */
+ $template = Mockery::mock('Foil\Template\Template');
+ $template
+ ->shouldReceive('render')
+ ->with(Mockery::type('array'))
+ ->andReturn($render);
+ $stack
+ ->shouldReceive('factory')
+ ->with(__FILE__, $engine, Mockery::any())
+ ->andReturn($template);
+
+ $events
+ ->shouldReceive('fire')
+ ->once()
+ ->with('f.template.render', $template, Mockery::type('array'))
+ ->andReturnNull();
+ $events
+ ->shouldReceive('fire')
+ ->once()
+ ->with('f.template.renderered', $template, $render)
+ ->andReturnNull();
+ }
+
+ return $engine;
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testCallFailsIfUnsafeFunction()
+ {
+ $engine = $this->getEngine();
+ $engine->foo();
+ }
+
+ public function testCall()
+ {
+ /** @var \Foil\Kernel\Events|\Mockery\MockInterface $events */
+ $events = Mockery::mock('Foil\Kernel\Events');
+ $events
+ ->shouldReceive('fire')
+ ->once()
+ ->with('f.engine.call', 'useData', [['foo' => 'foo']]);
+ $engine = $this->getEngine($events);
+
+ assertSame($engine, $engine->useData(['foo' => 'foo']));
+ }
+
+ public function testFireCallOnEvents()
+ {
+ /** @var \Foil\Kernel\Events|\Mockery\MockInterface $events */
+ $events = Mockery::mock('Foil\Kernel\Events');
+ $events
+ ->shouldReceive('fire')
+ ->once()
+ ->with('foo', 'bar', 'baz');
+ $engine = $this->getEngine($events);
+ $engine->fire('foo', 'bar', 'baz');
+ }
+
+ public function testStatusIdleOnStart()
+ {
+ $engine = $this->getEngine();
+ assertSame(Engine::STATUS_IDLE, $engine->status());
+ }
+
+ public function testLoadExtension()
+ {
+ /** @var \Foil\Contracts\ExtensionInterface $extension */
+ $extension = Mockery::mock('Foil\Contracts\ExtensionInterface');
+ /** @var \Foil\Kernel\Events|\Mockery\MockInterface $events */
+ $events = Mockery::mock('Foil\Kernel\Events');
+ $events
+ ->shouldReceive('fire')
+ ->once()
+ ->with('f.extension.load', $extension, ['foo' => 'foo'], false);
+ $engine = $this->getEngine($events);
+
+ assertSame($engine, $engine->loadExtension($extension, ['foo' => 'foo']));
+ }
+
+ public function testRegisterFilter()
+ {
+ $filter = function () {
+ return true;
+ };
+ /** @var \Foil\Kernel\Events|\Mockery\MockInterface $events */
+ $events = Mockery::mock('Foil\Kernel\Events');
+ $events
+ ->shouldReceive('fire')
+ ->once()
+ ->with('f.filter.register', 'foo', $filter);
+ $engine = $this->getEngine($events);
+
+ assertSame($engine, $engine->registerFilter('foo', $filter));
+ }
+
+ public function testRegisterFunction()
+ {
+ $function = function () {
+ return true;
+ };
+ /** @var \Foil\Kernel\Events|\Mockery\MockInterface $events */
+ $events = Mockery::mock('Foil\Kernel\Events');
+ $events
+ ->shouldReceive('fire')
+ ->once()
+ ->with('f.function.register', 'foo', $function, true);
+ $engine = $this->getEngine($events);
+
+ assertSame($engine, $engine->registerFunction('foo', $function, true));
+ }
+
+ public function testRegisterBlock()
+ {
+ $block = function () {
+ return true;
+ };
+ /** @var \Foil\Kernel\Events|\Mockery\MockInterface $events */
+ $events = Mockery::mock('Foil\Kernel\Events');
+ $events
+ ->shouldReceive('fire')
+ ->once()
+ ->with('f.block.register', 'foo', $block);
+ $engine = $this->getEngine($events);
+
+ assertSame($engine, $engine->registerBlock('foo', $block));
+ }
+
+ public function testSetFolders()
+ {
+ /** @var \Foil\Template\Finder|\Mockery\MockInterface $finder */
+ $finder = Mockery::mock('Foil\Template\Finder');
+ $finder
+ ->shouldReceive('in')
+ ->once()
+ ->with(['foo', 'bar'], true)
+ ->andReturnNull();
+ $engine = $this->getEngine(null, $finder);
+
+ assertSame($engine, $engine->setFolders(['foo', 'bar']));
+ }
+
+ public function testAddFolderNoName()
+ {
+ /** @var \Foil\Template\Finder|\Mockery\MockInterface $finder */
+ $finder = Mockery::mock('Foil\Template\Finder');
+ $finder
+ ->shouldReceive('in')
+ ->once()
+ ->with(['foo'])
+ ->andReturnNull();
+ $engine = $this->getEngine(null, $finder);
+
+ assertSame($engine, $engine->addFolder('foo'));
+ }
+
+ public function testAddFolderName()
+ {
+ /** @var \Foil\Template\Finder|\Mockery\MockInterface $finder */
+ $finder = Mockery::mock('Foil\Template\Finder');
+ $finder
+ ->shouldReceive('in')
+ ->once()
+ ->with(['name' => 'foo'])
+ ->andReturnNull();
+ $engine = $this->getEngine(null, $finder);
+
+ assertSame($engine, $engine->addFolder('foo', 'name'));
+ }
+
+ public function testFindCallOnFinder()
+ {
+ /** @var \Foil\Template\Finder|\Mockery\MockInterface $finder */
+ $finder = Mockery::mock('Foil\Template\Finder');
+ $finder
+ ->shouldReceive('find')
+ ->once()
+ ->with('foo')
+ ->andReturn('/foo.php');
+ $engine = $this->getEngine(null, $finder);
+
+ assertSame('/foo.php', $engine->find('foo', 'meh'));
+ }
+
+ public function testRenderFile()
+ {
+ $engine = $this->getEngine(null, null, 'Rendered!');
+ assertSame('Rendered!', $engine->render(__FILE__));
+ }
+
+ public function testRender()
+ {
+ /** @var \Foil\Template\Finder|\Mockery\MockInterface $finder */
+ $finder = Mockery::mock('Foil\Template\Finder');
+ $finder
+ ->shouldReceive('find')
+ ->once()
+ ->with('foo')
+ ->andReturn(__FILE__);
+ $engine = $this->getEngine(null, $finder, 'Rendered!');
+ assertSame('Rendered!', $engine->render('foo'));
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testRenderFailsIfTemplateNotFound()
+ {
+ /** @var \Foil\Template\Finder|\Mockery\MockInterface $finder */
+ $finder = Mockery::mock('Foil\Template\Finder');
+ $finder
+ ->shouldReceive('find')
+ ->once()
+ ->with('foo')
+ ->andReturn(false);
+ $engine = $this->getEngine(null, $finder);
+ $engine->render('foo');
+ }
+
+ public function testRenderTemplate()
+ {
+ $engine = $this->getEngine(null, null, 'Rendered!');
+ assertSame('Rendered!', $engine->renderTemplate(__FILE__));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testRenderSectionFailsIfBadSection()
+ {
+ $engine = $this->getEngine();
+ $engine->renderSection('foo', true);
+ }
+
+ public function testRenderSectionSingle()
+ {
+ /** @var \Foil\Kernel\Events|\Mockery\MockInterface $events */
+ $events = Mockery::mock('Foil\Kernel\Events');
+ $events
+ ->shouldReceive('on')
+ ->once()
+ ->with('f.sections.content', Mockery::type('Closure'))
+ ->andReturnNull();
+ $events
+ ->shouldReceive('on')
+ ->with(Mockery::type('string'), Mockery::type('Closure'))
+ ->andReturnNull();
+ $events
+ ->shouldReceive('removeListener')
+ ->once()
+ ->with('f.sections.content', Mockery::type('Closure'))
+ ->andReturnNull();
+
+ $engine = $this->getEngine($events, null, 'foo');
+
+ assertSame('', $engine->renderSection(__FILE__, 'foo'));
+ }
+
+ public function testRenderSectionMulti()
+ {
+ /** @var \Foil\Kernel\Events|\Mockery\MockInterface $events */
+ $events = Mockery::mock('Foil\Kernel\Events');
+ $events
+ ->shouldReceive('on')
+ ->once()
+ ->with('f.sections.content', Mockery::type('Closure'))
+ ->andReturnNull();
+ $events
+ ->shouldReceive('on')
+ ->with(Mockery::type('string'), Mockery::type('Closure'))
+ ->andReturnNull();
+ $events
+ ->shouldReceive('removeListener')
+ ->once()
+ ->with('f.sections.content', Mockery::type('Closure'))
+ ->andReturnNull();
+
+ $engine = $this->getEngine($events, null, 'foo');
+
+ assertSame(['foo' => '', 'bar' => ''], $engine->renderSection(__FILE__, ['foo', 'bar']));
+ }
+
+ public function testRenderSections()
+ {
+ /** @var \Foil\Kernel\Events|\Mockery\MockInterface $events */
+ $events = Mockery::mock('Foil\Kernel\Events');
+ $events
+ ->shouldReceive('on')
+ ->once()
+ ->with('f.sections.content', Mockery::type('Closure'))
+ ->andReturnNull();
+ $events
+ ->shouldReceive('on')
+ ->with(Mockery::type('string'), Mockery::type('Closure'))
+ ->andReturnNull();
+ $events
+ ->shouldReceive('removeListener')
+ ->once()
+ ->with('f.sections.content', Mockery::type('Closure'))
+ ->andReturnNull();
+
+ $engine = $this->getEngine($events, null, 'foo');
+
+ assertSame([], $engine->renderSections(__FILE__));
+ }
+}