Skip to content

Commit 5365a5d

Browse files
committed
Merge pull request #99 from neomerx/develop
v0.6.3
2 parents da050d2 + 37f4500 commit 5365a5d

24 files changed

+1109
-233
lines changed

.gitignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/vendor/
2-
/build/
1+
vendor/
2+
build/
33
.idea/
4-
composer.lock
4+
composer.lock

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ This framework agnostic package implements [JSON API](http://jsonapi.org/) speci
2222
* Sparse fieldsets and customized included paths
2323
* Errors
2424

25-
High code quality and **100% test coverage** with **180+ tests**. Production ready.
25+
High code quality and **100% test coverage** with **200+ tests**. Production ready.
2626

2727
**To find out more, please check out the [Wiki](https://github.com/neomerx/json-api/wiki) and [Sample App](/sample)**.
2828

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"php": ">=5.5.0"
2525
},
2626
"require-dev": {
27-
"phpunit/phpunit": "~4.6",
27+
"phpunit/phpunit": "~4.6 || ^5.0",
2828
"mockery/mockery": "~0.9.4",
2929
"scrutinizer/ocular": "~1.1",
3030
"squizlabs/php_codesniffer": "2.*",
@@ -38,7 +38,8 @@
3838
},
3939
"autoload-dev": {
4040
"psr-4": {
41-
"Neomerx\\Tests\\JsonApi\\": "tests/"
41+
"Neomerx\\Tests\\JsonApi\\": "tests/",
42+
"Neomerx\\Samples\\JsonApi\\": "sample/"
4243
}
4344
},
4445
"scripts": {

sample/Application/EncodeSamples.php

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
<?php namespace Neomerx\Samples\JsonApi\Application;
2+
3+
/**
4+
* Copyright 2015 [email protected] (www.neomerx.com)
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
use \Closure;
20+
use \Neomerx\JsonApi\Schema\Link;
21+
use \Neomerx\JsonApi\Encoder\Encoder;
22+
use \Neomerx\Samples\JsonApi\Models\Post;
23+
use \Neomerx\Samples\JsonApi\Models\Site;
24+
use \Neomerx\Samples\JsonApi\Models\Author;
25+
use \Neomerx\Samples\JsonApi\Models\Comment;
26+
use \Neomerx\JsonApi\Encoder\EncoderOptions;
27+
use \Neomerx\Samples\JsonApi\Schemas\PostSchema;
28+
use \Neomerx\Samples\JsonApi\Schemas\SiteSchema;
29+
use \Neomerx\Samples\JsonApi\Schemas\AuthorSchema;
30+
use \Neomerx\JsonApi\Parameters\EncodingParameters;
31+
use \Neomerx\Samples\JsonApi\Schemas\CommentSchema;
32+
33+
/**
34+
* @package Neomerx\Samples\JsonApi
35+
*/
36+
class EncodeSamples
37+
{
38+
/**
39+
* Get basic usage.
40+
*
41+
* @return string
42+
*/
43+
public function getBasicExample()
44+
{
45+
$author = Author::instance('123', 'John', 'Dow');
46+
47+
$encoder = Encoder::instance([
48+
Author::class => AuthorSchema::class,
49+
], new EncoderOptions(JSON_PRETTY_PRINT, 'http://example.com/api/v1'));
50+
51+
$result = $encoder->encodeData($author);
52+
53+
return $result;
54+
}
55+
56+
/**
57+
* Get how objects are put to 'included'.
58+
*
59+
* @return string
60+
*/
61+
public function getIncludedObjectsExample()
62+
{
63+
$author = Author::instance('123', 'John', 'Dow');
64+
$comments = [
65+
Comment::instance('456', 'Included objects work as easy as basic ones', $author),
66+
Comment::instance('789', 'Let\'s try!', $author),
67+
];
68+
$post = Post::instance('321', 'Included objects', 'Yes, it is supported', $author, $comments);
69+
$site = Site::instance('1', 'JSON API Samples', [$post]);
70+
71+
$encoder = Encoder::instance([
72+
Author::class => AuthorSchema::class,
73+
Comment::class => CommentSchema::class,
74+
Post::class => PostSchema::class,
75+
Site::class => SiteSchema::class
76+
], new EncoderOptions(JSON_PRETTY_PRINT, 'http://example.com'));
77+
78+
$result = $encoder->encodeData($site);
79+
80+
return $result;
81+
}
82+
83+
/**
84+
* Get sparse and field set filters.
85+
*
86+
* @return string
87+
*/
88+
public function getSparseAndFieldSetsExample()
89+
{
90+
$author = Author::instance('123', 'John', 'Dow');
91+
$comments = [
92+
Comment::instance('456', 'Included objects work as easy as basic ones', $author),
93+
Comment::instance('789', 'Let\'s try!', $author),
94+
];
95+
$post = Post::instance('321', 'Included objects', 'Yes, it is supported', $author, $comments);
96+
$site = Site::instance('1', 'JSON API Samples', [$post]);
97+
98+
$options = new EncodingParameters([
99+
// Paths to be included. Note 'posts.comments' will not be shown.
100+
'posts.author'
101+
], [
102+
// Attributes and relationships that should be shown
103+
'sites' => ['name', 'posts'],
104+
'posts' => ['author'],
105+
'people' => ['first_name'],
106+
]);
107+
108+
SiteSchema::$isShowCustomLinks = false;
109+
$encoder = Encoder::instance([
110+
Author::class => AuthorSchema::class,
111+
Comment::class => CommentSchema::class,
112+
Post::class => PostSchema::class,
113+
Site::class => SiteSchema::class
114+
], new EncoderOptions(JSON_PRETTY_PRINT));
115+
116+
$result = $encoder->encodeData($site, $options);
117+
118+
return $result;
119+
}
120+
121+
/**
122+
* Get sparse and field set filters.
123+
*
124+
* @return string
125+
*/
126+
public function getTopLevelMetaAndLinksExample()
127+
{
128+
$author = Author::instance('123', 'John', 'Dow');
129+
$meta = [
130+
"copyright" => "Copyright 2015 Example Corp.",
131+
"authors" => [
132+
"Yehuda Katz",
133+
"Steve Klabnik",
134+
"Dan Gebhardt"
135+
]
136+
];
137+
$links = [
138+
Link::FIRST => new Link('http://example.com/people?first', null, true),
139+
Link::LAST => new Link('http://example.com/people?last', null, true),
140+
Link::PREV => new Link('http://example.com/people?prev', null, true),
141+
Link::NEXT => new Link('http://example.com/people?next', null, true),
142+
];
143+
144+
$encoder = Encoder::instance([
145+
Author::class => AuthorSchema::class,
146+
Comment::class => CommentSchema::class,
147+
Post::class => PostSchema::class,
148+
Site::class => SiteSchema::class
149+
], new EncoderOptions(JSON_PRETTY_PRINT, 'http://example.com'));
150+
151+
$result = $encoder->withLinks($links)->withMeta($meta)->encodeData($author);
152+
153+
return $result;
154+
}
155+
156+
/**
157+
* Get how schema could change dynamically.
158+
*
159+
* @return array
160+
*/
161+
public function getDynamicSchemaExample()
162+
{
163+
$site = Site::instance('1', 'JSON API Samples', []);
164+
165+
$encoder = Encoder::instance([
166+
Site::class => SiteSchema::class,
167+
], new EncoderOptions(JSON_PRETTY_PRINT));
168+
169+
SiteSchema::$isShowCustomLinks = false;
170+
$noLinksResult = $encoder->encodeData($site);
171+
172+
SiteSchema::$isShowCustomLinks = true;
173+
$withLinksResult = $encoder->encodeData($site);
174+
175+
return [
176+
$noLinksResult,
177+
$withLinksResult,
178+
];
179+
}
180+
181+
/**
182+
* Run performance test for many times for small nested resources.
183+
*
184+
* @param int $iterations
185+
*
186+
* @return mixed
187+
*/
188+
public function runPerformanceTestForSmallNestedResources($iterations)
189+
{
190+
$closure = function () use ($iterations) {
191+
$options = new EncodingParameters(
192+
['posts.author'],
193+
['sites' => ['name'], 'people' => ['first_name']]
194+
);
195+
$encoder = Encoder::instance([
196+
Author::class => AuthorSchema::class,
197+
Comment::class => CommentSchema::class,
198+
Post::class => PostSchema::class,
199+
Site::class => SiteSchema::class
200+
]);
201+
202+
for ($index = 0; $index < $iterations; ++$index) {
203+
$rand = rand();
204+
205+
$author = Author::instance('123', 'John' . $rand, 'Dow' . $rand);
206+
$comments = [
207+
Comment::instance('456', 'Included objects work as easy as basic ones' . $rand, $author),
208+
Comment::instance('789', 'Let\'s try!' . $rand, $author),
209+
];
210+
$post = Post::instance('321', 'Included objects' . $rand, 'Yes, it is supported', $author, $comments);
211+
$site = Site::instance('1', 'JSON API Samples' . $rand, [$post]);
212+
213+
$encoder
214+
->withLinks([Link::SELF => new Link('http://example.com/sites/1?' . $rand, null, true)])
215+
->withMeta(['some' => ['meta' => 'information' . $rand]])
216+
->encodeData($site, $options);
217+
}
218+
};
219+
220+
$timeSpent = null;
221+
$this->getTime($closure, $timeSpent);
222+
223+
return $timeSpent;
224+
}
225+
226+
/**
227+
* Run performance test one time for big collection of resources.
228+
*
229+
* @param int $numberOfItems
230+
*
231+
* @return mixed
232+
*/
233+
public function runPerformanceTestForBigCollection($numberOfItems)
234+
{
235+
$closure = function() use ($numberOfItems) {
236+
$sites = [];
237+
for ($index = 0; $index < $numberOfItems; ++$index) {
238+
$rand = rand();
239+
240+
$author = Author::instance('123', 'John' . $rand, 'Dow' . $rand);
241+
$comments = [
242+
Comment::instance('456', 'Included objects work as easy as basic ones' . $rand, $author),
243+
Comment::instance('789', 'Let\'s try!' . $rand, $author),
244+
];
245+
$post = Post::instance('321', 'Included objects' . $rand, 'Yes, it is supported', $author, $comments);
246+
$site = Site::instance('1', 'JSON API Samples' . $rand, [$post]);
247+
248+
$sites[] = $site;
249+
}
250+
251+
$options = new EncodingParameters(
252+
['posts.author', 'posts.comments'],
253+
['sites' => ['name'], 'people' => ['first_name']]
254+
);
255+
$encoder = Encoder::instance([
256+
Author::class => AuthorSchema::class,
257+
Comment::class => CommentSchema::class,
258+
Post::class => PostSchema::class,
259+
Site::class => SiteSchema::class
260+
]);
261+
262+
$encoder->encodeData($sites, $options);
263+
};
264+
265+
$timeSpent = null;
266+
$this->getTime($closure, $timeSpent);
267+
268+
return $timeSpent;
269+
}
270+
271+
/**
272+
* @param Closure $closure
273+
* @param float &$time
274+
*
275+
* @return mixed
276+
*/
277+
private function getTime(Closure $closure, &$time)
278+
{
279+
$time_start = microtime(true);
280+
try {
281+
return $closure();
282+
} finally {
283+
$time_end = microtime(true);
284+
$time = $time_end - $time_start;
285+
}
286+
}
287+
}

sample/models/Author.php renamed to sample/Models/Author.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php
1+
<?php namespace Neomerx\Samples\JsonApi\Models;
22

33
/**
44
* Copyright 2015 [email protected] (www.neomerx.com)
@@ -23,7 +23,7 @@
2323
* @property string firstName
2424
* @property string lastName
2525
*/
26-
class Author extends stdClass
26+
class Author extends \stdClass
2727
{
2828
/**
2929
* @param string $authorId

sample/models/Comment.php renamed to sample/Models/Comment.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php
1+
<?php namespace Neomerx\Samples\JsonApi\Models;
22

33
/**
44
* Copyright 2015 [email protected] (www.neomerx.com)
@@ -23,7 +23,7 @@
2323
* @property string body
2424
* @property Author author
2525
*/
26-
class Comment extends stdClass
26+
class Comment extends \stdClass
2727
{
2828
/**
2929
* @param string $commentId

sample/models/Post.php renamed to sample/Models/Post.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php
1+
<?php namespace Neomerx\Samples\JsonApi\Models;
22

33
/**
44
* Copyright 2015 [email protected] (www.neomerx.com)
@@ -25,7 +25,7 @@
2525
* @property Author author
2626
* @property Comment[] comments
2727
*/
28-
class Post extends stdClass
28+
class Post extends \stdClass
2929
{
3030
/**
3131
* @param string $postId

sample/models/Site.php renamed to sample/Models/Site.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php
1+
<?php namespace Neomerx\Samples\JsonApi\Models;
22

33
/**
44
* Copyright 2015 [email protected] (www.neomerx.com)
@@ -23,7 +23,7 @@
2323
* @property string name
2424
* @property Post[] posts
2525
*/
26-
class Site extends stdClass
26+
class Site extends \stdClass
2727
{
2828
/**
2929
* @param string $siteId

sample/README.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,3 @@ or with execution time measurement and specified number of iterations
3636
```
3737
$ time php sample.php -t=10000
3838
```
39-
40-
If your system has debug assertions enabled it is recommended to turn them off. Just to give you an idea that debug assert are not free here is the execution time comparison
41-
42-
|Debug asserts mode |Command |Execution time|
43-
|---------------------|--------------------------------------------------|--------------|
44-
|Enabled |```$ php -d assert.active=1 sample.php -t=10000```|7.589s |
45-
|Disabled |```$ php -d assert.active=0 sample.php -t=10000```|2.884s |

0 commit comments

Comments
 (0)