diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000..f5ca933
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,31 @@
+name: Run Tests
+
+on: ['push', 'pull_request']
+
+jobs:
+ test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: true
+ matrix:
+ os: [ubuntu-latest]
+ php: [8.3, 8.2, 8.1, 8.0, 7.4]
+
+ name: PHP ${{ matrix.php }} – ${{ matrix.os }}
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ tools: composer:v2
+ coverage: xdebug
+
+ - name: Install dependencies
+ run: composer update --prefer-stable --no-interaction
+
+ - name: All tests
+ run: php vendor/bin/pest --colors=always --coverage
diff --git a/.gitignore b/.gitignore
index fc7ea17..1373acf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
/vendor
composer.lock
.DS_Store
+.idea
+.phpunit.result.cache
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 799e576..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-language: php
-
-php:
- - 7.0
- - 7.1
- - 7.2
- - 7.3
-
-sudo: false
-
-before_script:
- - travis_retry composer self-update
- - travis_retry composer install --dev --no-interaction
-
-script:
- - mkdir -p build/logs
- - ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml
-
-after_success:
- - php vendor/bin/coveralls -v
diff --git a/composer.json b/composer.json
index 5789057..413244a 100644
--- a/composer.json
+++ b/composer.json
@@ -13,12 +13,11 @@
}
],
"require": {
- "php": ">=7.0",
- "illuminate/view": "^5.5|^6.0|^7.0|^8.0"
+ "php": ">=7.3|^8.0",
+ "illuminate/view": "^8.0|^9.0|^10.0"
},
"require-dev": {
- "phpunit/phpunit": "^6.0|^7.0",
- "satooshi/php-coveralls": "^1.0"
+ "pestphp/pest": "^1.0|^2.25"
},
"autoload": {
"psr-4": {
@@ -26,5 +25,10 @@
}
},
"minimum-stability": "dev",
- "prefer-stable": true
+ "prefer-stable": true,
+ "config": {
+ "allow-plugins": {
+ "pestphp/pest-plugin": true
+ }
+ }
}
diff --git a/phpunit.xml b/phpunit.xml
index f062023..7d0904f 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -1,21 +1,18 @@
-
+>
-
- ./tests/
+
+ ./tests
-
-
- src/
-
-
+
diff --git a/src/Blade.php b/src/Blade.php
index 256e5ec..7e30007 100644
--- a/src/Blade.php
+++ b/src/Blade.php
@@ -2,9 +2,7 @@
namespace Leaf;
-use Illuminate\Container\Container;
use Illuminate\Contracts\Container\Container as ContainerInterface;
-use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory as FactoryContract;
use Illuminate\Contracts\View\View;
use Illuminate\Events\Dispatcher;
@@ -17,7 +15,7 @@
class Blade implements FactoryContract
{
/**
- * @var Application
+ * @var BladeContainer
*/
protected $container;
@@ -33,7 +31,7 @@ class Blade implements FactoryContract
public function __construct($viewPaths = null, string $cachePath = null, ContainerInterface $container = null)
{
- $this->container = $container ?: new Container;
+ $this->container = $container ?: new \Leaf\BladeContainer();
if ($viewPaths != null && $cachePath != null) {
$this->configure($viewPaths, $cachePath);
@@ -54,8 +52,8 @@ public function configure($viewPaths, $cachePath)
/**
* Render your blade template,
- *
- * A shorter version of the original `make` command.
+ *
+ * A shorter version of the original `make` command.
* You can optionally pass data into the view as a second parameter
*/
public function render(string $view, array $data = [], array $mergeData = []): string
@@ -65,7 +63,7 @@ public function render(string $view, array $data = [], array $mergeData = []): s
/**
* Render your blade template,
- *
+ *
* You can optionally pass data into the view as a second parameter.
* Don't forget to chain the `render` method
*/
@@ -147,10 +145,10 @@ protected function setupContainer(array $viewPaths, string $cachePath)
}, true);
$this->container->bindIf('config', function () use ($viewPaths, $cachePath) {
- return [
+ return new Config([
'view.paths' => $viewPaths,
'view.compiled' => $cachePath,
- ];
+ ]);
}, true);
Facade::setFacadeApplication($this->container);
diff --git a/src/BladeContainer.php b/src/BladeContainer.php
new file mode 100755
index 0000000..b34a905
--- /dev/null
+++ b/src/BladeContainer.php
@@ -0,0 +1,372 @@
+terminatingCallbacks[] = $callback;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function version()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $path
+ *
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function basePath($path = '')
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $path
+ *
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function bootstrapPath($path = '')
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $path
+ *
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function configPath($path = '')
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $path
+ *
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function databasePath($path = '')
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $path
+ *
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function langPath($path = '')
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $path
+ *
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function publicPath($path = '')
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $path
+ *
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function resourcePath($path = '')
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $path
+ *
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function storagePath($path = '')
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param ...$environments
+ *
+ * @return bool|string
+ *
+ * @throws \Exception
+ */
+ public function environment(...$environments)
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return bool
+ *
+ * @throws \Exception
+ */
+ public function runningInConsole()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return bool
+ *
+ * @throws \Exception
+ */
+ public function runningUnitTests()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return bool
+ *
+ * @throws \Exception
+ */
+ public function hasDebugModeEnabled()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return \Illuminate\Contracts\Foundation\MaintenanceMode
+ *
+ * @throws \Exception
+ */
+ public function maintenanceMode()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return bool
+ *
+ * @throws \Exception
+ */
+ public function isDownForMaintenance()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function registerConfiguredProviders()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $provider
+ * @param $force
+ *
+ * @return \Illuminate\Support\ServiceProvider
+ *
+ * @throws \Exception
+ */
+ public function register($provider, $force = false)
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $provider
+ * @param $service
+ *
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function registerDeferredProvider($provider, $service = null)
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $provider
+ *
+ * @return \Illuminate\Support\ServiceProvider
+ *
+ * @throws \Exception
+ */
+ public function resolveProvider($provider)
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function boot()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $callback
+ *
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function booting($callback)
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $callback
+ *
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function booted($callback)
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param array $bootstrappers
+ *
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function bootstrapWith(array $bootstrappers)
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function getLocale()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return string
+ *
+ * @throws \Exception
+ */
+ public function getNamespace()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $provider
+ *
+ * @return array
+ *
+ * @throws \Exception
+ */
+ public function getProviders($provider)
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return bool
+ *
+ * @throws \Exception
+ */
+ public function hasBeenBootstrapped()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function loadDeferredProviders()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @param $locale
+ *
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function setLocale($locale)
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return bool
+ *
+ * @throws \Exception
+ */
+ public function shouldSkipMiddleware()
+ {
+ throw new \Exception("Not implemented");
+ }
+
+ /**
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function terminate()
+ {
+ throw new \Exception("Not implemented");
+ }
+}
diff --git a/src/Config.php b/src/Config.php
new file mode 100644
index 0000000..4268464
--- /dev/null
+++ b/src/Config.php
@@ -0,0 +1,154 @@
+items = $items;
+ }
+
+ /**
+ * @param string $key
+ *
+ * @return bool
+ */
+ public function has($key)
+ {
+ return Arr::has($this->items, $key);
+ }
+
+ /**
+ * @param array|string $key
+ * @param mixed $default
+ *
+ * @return mixed
+ */
+ public function get($key, $default = null)
+ {
+ if (is_array($key)) {
+ return $this->getMany($key);
+ }
+
+ return Arr::get($this->items, $key, $default);
+ }
+
+ /**
+ * @param array $keys
+ *
+ * @return array
+ */
+ public function getMany($keys)
+ {
+ $config = [];
+
+ foreach ($keys as $key => $default) {
+ if (is_numeric($key)) {
+ [$key, $default] = [$default, null];
+ }
+
+ $config[$key] = Arr::get($this->items, $key, $default);
+ }
+
+ return $config;
+ }
+
+ /**
+ * @param array|string $key
+ * @param mixed $value
+ *
+ * @return void
+ */
+ public function set($key, $value = null): void
+ {
+ $keys = is_array($key) ? $key : [$key => $value];
+
+ foreach ($keys as $key => $value) {
+ Arr::set($this->items, $key, $value);
+ }
+ }
+
+ /**
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return void
+ */
+ public function push($key, $value)
+ {
+ $array = $this->get($key, []);
+
+ $array[] = $value;
+
+ $this->set($key, $array);
+ }
+
+ /**
+ * @return array
+ */
+ public function all(): array
+ {
+ return $this->items;
+ }
+
+ /**
+ * @param string $key
+ *
+ * @return bool
+ */
+ public function offsetExists($key): bool
+ {
+ return $this->has($key);
+ }
+
+ /**
+ * @param string $key
+ *
+ * @return mixed
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($key)
+ {
+ return $this->get($key);
+ }
+
+ /**
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return void
+ */
+ public function offsetSet($key, $value): void
+ {
+ $this->set($key, $value);
+ }
+
+ /**
+ * @param string $key
+ *
+ * @return void
+ */
+ public function offsetUnset($key): void
+ {
+ $this->set($key, null);
+ }
+}
diff --git a/tests/BladeTest.php b/tests/BladeTest.php
index 946f512..de9a688 100644
--- a/tests/BladeTest.php
+++ b/tests/BladeTest.php
@@ -1,105 +1,82 @@
make('basic');
+ expect(trim($output))->toBe('hello world');
+});
+
+test('variables', function () use (&$blade) {
+ $output = $blade->make('variables', ['name' => 'John Doe']);
+ expect(trim($output))->toBe('hello John Doe');
+});
+
+test('non-blade', function () use (&$blade) {
+ $output = $blade->make('plain');
+ expect(trim($output))->toBe('this is plain php');
+});
+
+test('render alias', function () use (&$blade) {
+ $output = $blade->make('basic');
+ expect(trim($output))->toBe('hello world');
+});
+
+test('directive', function () use (&$blade) {
+ $blade->directive('datetime', function ($expression) {
+ return "format('F d, Y g:i a'); ?>";
+ });
+
+ $output = $blade->make('directive', ['birthday' => new DateTime('1989/08/19')]);
+ expect(trim($output))->toBe('Your birthday is August 19, 1989 12:00 am');
+});
+
+test('other', function () use (&$blade) {
+ $users = [
+ [
+ 'id' => 1,
+ 'name' => 'John Doe',
+ 'email' => 'john.doe@doe.com',
+ ],
+ [
+ 'id' => 2,
+ 'name' => 'Jen Doe',
+ 'email' => 'jen.doe@example.com',
+ ],
+ [
+ 'id' => 3,
+ 'name' => 'Jerry Doe',
+ 'email' => 'jerry.doe@doe.com',
+ ],
+ ];
+
+ $output = $blade->make('other', [
+ 'users' => $users,
+ 'name' => 'John',
+ 'authenticated' => false,
+ ]);
+
+ write($output, 'other');
+
+ expect((string)$output)->toBe(expected('other'));
+});
+
+function write(string $output, string $file)
+{
+ $file_path = __DIR__ . '/expected/' . $file . '.html';
+
+ file_put_contents($file_path, $output);
+}
-class BladeTest extends TestCase
+function expected(string $file): string
{
- /**
- * @var Blade
- */
- private $blade;
-
- public function setUp()
- {
- $this->blade = new Blade('tests/views', 'tests/cache');
-
- $this->blade->directive('datetime', function ($expression) {
- return "format('F d, Y g:i a'); ?>";
- });
- }
-
- public function testBasic()
- {
- $output = $this->blade->make('basic');
- $this->assertEquals('hello world', trim($output));
- }
-
- public function testVariables()
- {
- $output = $this->blade->make('variables', ['name' => 'John Doe']);
- $this->assertEquals('hello John Doe', trim($output));
- }
-
- public function testNonBlade()
- {
- $output = $this->blade->make('plain');
- $this->assertEquals('this is plain php', trim($output));
- }
-
- public function testRenderAlias()
- {
- $output = $this->blade->make('basic');
- $this->assertEquals('hello world', trim($output));
- }
-
- public function testDirective()
- {
- $output = $this->blade->make('directive', ['birthday' => new DateTime('1989/08/19')]);
- $this->assertEquals('Your birthday is August 19, 1989 12:00 am', trim($output));
- }
-
- public function testOther()
- {
- $users = [
- [
- 'id' => 1,
- 'name' => 'John Doe',
- 'email' => 'john.doe@doe.com',
- ],
- [
- 'id' => 2,
- 'name' => 'Jen Doe',
- 'email' => 'jen.doe@example.com',
- ],
- [
- 'id' => 3,
- 'name' => 'Jerry Doe',
- 'email' => 'jerry.doe@doe.com',
- ],
- ];
-
- $output = $this->blade->make('other', [
- 'users' => $users,
- 'name' => 'John',
- 'authenticated' => false,
- ]);
-
- $this->write($output, 'other');
-
- $this->assertEquals($output, $this->expected('other'));
- }
-
- public function testExtends()
- {
- $output = $this->blade->make('extends');
-
- $this->write($output, 'extends');
-
- $this->assertEquals($output, $this->expected('extends'));
- }
-
- private function write(string $output, string $file)
- {
- $file_path = __DIR__ . '/expected/' . $file . '.html';
-
- file_put_contents($file_path, $output);
- }
-
- private function expected(string $file): string
- {
- $file_path = __DIR__ . '/expected/' . $file . '.html';
-
- return file_get_contents($file_path);
- }
+ $file_path = __DIR__ . '/expected/' . $file . '.html';
+
+ return file_get_contents($file_path);
}
diff --git a/tests/Pest.php b/tests/Pest.php
new file mode 100644
index 0000000..5949c61
--- /dev/null
+++ b/tests/Pest.php
@@ -0,0 +1,45 @@
+in('Feature');
+
+/*
+|--------------------------------------------------------------------------
+| Expectations
+|--------------------------------------------------------------------------
+|
+| When you're writing tests, you often need to check that values meet certain conditions. The
+| "expect()" function gives you access to a set of "expectations" methods that you can use
+| to assert different things. Of course, you may extend the Expectation API at any time.
+|
+*/
+
+expect()->extend('toBeOne', function () {
+ return $this->toBe(1);
+});
+
+/*
+|--------------------------------------------------------------------------
+| Functions
+|--------------------------------------------------------------------------
+|
+| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
+| project that you don't want to repeat in every file. Here you can also expose helpers as
+| global functions to help you to reduce the number of lines of code in your test files.
+|
+*/
+
+function something()
+{
+ // ..
+}