Skip to content

Commit 23a28f0

Browse files
author
Jordan Hoff
committed
Adds tests and readme
1 parent 2c90342 commit 23a28f0

File tree

9 files changed

+479
-6
lines changed

9 files changed

+479
-6
lines changed

README.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
Laravel Blade Vue Directive
2+
==============
3+
4+
Laravel Blade Vue Directive provides a blade directive for vue.js inline components.
5+
6+
[![Latest Stable Version](https://img.shields.io/github/release/jhoff/blade-vue-directive.svg?style=flat-square)](https://packagist.org/packages/jhoff/blade-vue-directive)
7+
[![Total Downloads](https://img.shields.io/packagist/dt/jhoff/blade-vue-directive.svg?style=flat-square)](https://packagist.org/packages/jhoff/blade-vue-directive)
8+
[![MIT License](https://img.shields.io/packagist/l/jhoff/blade-vue-directive.svg?style=flat-square)](https://packagist.org/packages/jhoff/blade-vue-directive)
9+
[![Build Status](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/badges/build.png?b=master)](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/build-status/master)
10+
[![Code Coverage](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/?branch=master)
11+
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/?branch=master)
12+
13+
<!-- MarkdownTOC autolink="true" autoanchor="true" bracket="round" depth="4" -->
14+
15+
- [Installation](#installation)
16+
- [Usage](#usage)
17+
- [Basic Example](#basic-example)
18+
- [Scalars Example](#scalars-example)
19+
- [Booleans and Numbers Example](#booleans-and-numbers-example)
20+
- [Objects and Arrays Example](#objects-and-arrays-example)
21+
22+
<!-- /MarkdownTOC -->
23+
24+
<a name="installation"></a>
25+
## Installation
26+
27+
To install the Laravel Blade Vue Directive, simply run `composer require blade-vue-directive` in a terminal, or if you prefer to manually install you can the following in your `composer.json` file and then run `composer install` from the terminal:
28+
29+
```json
30+
{
31+
"require": {
32+
"jhoff/blade-vue-directive": "1.*"
33+
}
34+
}
35+
```
36+
37+
Then all you need to do is add the new provider to the providers array of `config/app.php`:
38+
39+
```php
40+
'providers' => [
41+
// ...
42+
Jhoff\BladeVue\DirectiveServiceProvider::class,
43+
// ...
44+
],
45+
```
46+
47+
<a name="usage"></a>
48+
## Usage
49+
50+
The Laravel Blade Vue Directive was written to be simple and intuitive to use. It's not opinionated about how you use your vue.js components. Simply provide a component name and (optionally) an associative array of properties.
51+
52+
<a name="basic-example"></a>
53+
### Basic Example
54+
55+
Using the vue directive with no arguments in your blade file
56+
57+
```html
58+
@vue('my-component')
59+
<div>Some content</div>
60+
@endvue
61+
```
62+
63+
Renders in html as
64+
65+
```html
66+
<component inline-template v-cloak is="my-component">
67+
<div>Some content</div>
68+
</component>
69+
```
70+
71+
<a name="scalars-example"></a>
72+
### Scalars Example
73+
74+
Using the vue directive with an associative array as the second argument will automatically translate into native properties that you can use within your vue.js components.
75+
76+
```html
77+
@vue('page-title', ['title' => 'Welcome to my page'])
78+
<h1>@{{ title }}</h1>
79+
@endvue
80+
```
81+
82+
Renders in html as
83+
84+
```html
85+
<component inline-template v-cloak is="page-title" title="Welcome to my page">
86+
<h1>{{ title }}</h1>
87+
</component>
88+
```
89+
90+
Then, to use the properties in your vue.js component, add them to `props` in your component definition. See [Component::props](https://vuejs.org/v2/guide/components.html#Props) for more information.
91+
92+
```js
93+
Vue.component('page-title', {
94+
props: ['title']
95+
});
96+
```
97+
98+
<a name="booleans-and-numbers-example"></a>
99+
### Booleans and Numbers Example
100+
101+
Properties that are booleans or numeric will be bound automatically as well
102+
103+
```html
104+
@vue('report-viewer', ['show' => true, 'report' => 8675309])
105+
<h1 v-if="show">Report #@{{ report }}</h1>
106+
@endvue
107+
```
108+
109+
Renders in html as
110+
111+
```html
112+
<component inline-template v-cloak is="report-viewer" :show="true" :report="8675309">
113+
<h1 v-if="show">Report #{{ report }}</h1>
114+
</component>
115+
```
116+
117+
<a name="objects-and-arrays-example"></a>
118+
### Objects and Arrays Example
119+
120+
The vue directive will automatically handle any objects or arrays to make sure that vue.js can interact with them without any additional effort.
121+
122+
```html
123+
@vue('welcome-header', ['user' => (object)['name' => 'Jordan Hoff']])
124+
<h2>Welcome @{{ user.name }}!</h2>
125+
@endvue
126+
```
127+
128+
Renders in html as
129+
130+
```html
131+
<component inline-template v-cloak is="welcome-header" :user="{&quot;name&quot;:&quot;Jordan Hoff&quot;}">
132+
<h2>Welcome {{ user.name }}!</h2>
133+
</component>
134+
```
135+
136+
Notice that the object is json encoded, html escaped and the property is prepended with `:` to ensure that vue will bind the value as data.
137+
138+
To use an object property in your component, make sure to make it an `Object` type:
139+
140+
```js
141+
Vue.component('welcome-header', {
142+
props: {
143+
user: {
144+
type: Object
145+
}
146+
}
147+
});
148+
```

phpunit.xml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
bootstrap="vendor/autoload.php"
5+
colors="false"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false">
11+
<testsuites>
12+
<testsuite name="Integration Tests">
13+
<directory suffix="Test.php">tests/Integration</directory>
14+
</testsuite>
15+
<testsuite name="Unit Tests">
16+
<directory suffix="Test.php">tests/Unit</directory>
17+
</testsuite>
18+
</testsuites>
19+
<logging>
20+
<log type="coverage-html"
21+
target="coverage"
22+
lowUpperBound="35"
23+
highLowerBound="70"/>
24+
<log type="coverage-clover"
25+
target="coverage/clover.xml"/>
26+
<log type="coverage-text"
27+
target="php://stdout"
28+
showOnlySummary="true"/>
29+
</logging>
30+
<filter>
31+
<whitelist processUncoveredFilesFromWhitelist="true">
32+
<directory suffix=".php">src</directory>
33+
</whitelist>
34+
</filter>
35+
<php>
36+
<env name="APP_ENV" value="testing"/>
37+
<env name="CACHE_DRIVER" value="array"/>
38+
<env name="SESSION_DRIVER" value="array"/>
39+
<env name="QUEUE_DRIVER" value="sync"/>
40+
<env name="DB_CONNECTION" value="sqlite"/>
41+
<env name="DB_DATABASE" value=":memory:"/>
42+
</php>
43+
</phpunit>

src/Component.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ protected function resolveAttributeValue(string $name, $value) : array
9393
return [":$name", $value ? 'true' : 'false'];
9494
}
9595

96+
if (is_numeric($value)) {
97+
return [":$name", $value];
98+
}
99+
96100
if (!is_scalar($value) && !is_null($value)) {
97101
return [":$name", htmlspecialchars(json_encode($value), ENT_QUOTES, 'UTF-8', false)];
98102
}

src/Element.php

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ public function getEndTag() : string
4545
*/
4646
public function getStartTag() : string
4747
{
48-
return "<{$this->name} {$this->renderAttributes()}>";
48+
$attributes = $this->renderAttributes();
49+
50+
return "<{$this->name}" . ( $attributes ? ' ' . $attributes : '' ) . '>';
4951
}
5052

5153
/**
@@ -62,6 +64,18 @@ public function setAttribute(string $name, $value)
6264
return $this;
6365
}
6466

67+
/**
68+
* Builds an attribute string
69+
*
70+
* @param string $key
71+
* @param mixed $value
72+
* @return string
73+
*/
74+
protected function buildAttribute(string $key, $value) : string
75+
{
76+
return is_null($value) ? $key : sprintf('%s="%s"', $key, $value);
77+
}
78+
6579
/**
6680
* Renders all of the attributes in the proper format
6781
*
@@ -70,11 +84,7 @@ public function setAttribute(string $name, $value)
7084
protected function renderAttributes() : string
7185
{
7286
return implode(' ', array_map(
73-
function ($key, $value) {
74-
return is_null($value) ?
75-
sprintf("%s", $key) :
76-
sprintf("%s=\"%s\"", $key, $value);
77-
},
87+
[$this, 'buildAttribute'],
7888
array_keys($this->attributes),
7989
$this->attributes
8090
));

tests/Integration/BladeTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace Jhoff\BladeVue\Testing\Integration;
4+
5+
use Jhoff\BladeVue\Testing\TestCase;
6+
7+
class BladeTest extends TestCase
8+
{
9+
/**
10+
* @test
11+
*/
12+
public function bladeRendersBasicVueDirective()
13+
{
14+
$output = $this->renderBlade('"my-component"');
15+
16+
$this->assertContains('<component', $output);
17+
$this->assertContains('is="my-component"', $output);
18+
$this->assertContains('</component>', $output);
19+
}
20+
21+
/**
22+
* @test
23+
*/
24+
public function bladeRendersAdvancedVueDirective()
25+
{
26+
$output = $this->renderBlade('"my-component", ["foo" => "bar"]');
27+
28+
$this->assertContains('<component', $output);
29+
$this->assertContains('is="my-component"', $output);
30+
$this->assertContains('foo="bar"', $output);
31+
$this->assertContains('</component>', $output);
32+
}
33+
34+
/**
35+
* Creates a vue file in the testbench views directory and renders it
36+
*
37+
* @param string $expression
38+
* @return string
39+
*/
40+
protected function renderBlade(string $expression)
41+
{
42+
@file_put_contents(
43+
resource_path('views/vue.blade.php'),
44+
"@vue($expression)\n<div>Testing</div>\n@endvue"
45+
);
46+
47+
return view()->make('vue')->render();
48+
}
49+
}

tests/TestCase.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Jhoff\BladeVue\Testing;
4+
5+
use Orchestra\Testbench\TestCase as BaseTestCase;
6+
7+
class TestCase extends BaseTestCase
8+
{
9+
/**
10+
* Get package providers.
11+
*
12+
* @param \Illuminate\Foundation\Application $app
13+
* @return array
14+
*/
15+
protected function getPackageProviders($app)
16+
{
17+
return ['Jhoff\BladeVue\DirectiveServiceProvider'];
18+
}
19+
}

0 commit comments

Comments
 (0)