Skip to content

Commit

Permalink
added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanak-michal committed Jul 20, 2021
1 parent d4d7003 commit 2c4b8b3
Show file tree
Hide file tree
Showing 33 changed files with 1,898 additions and 129 deletions.
86 changes: 3 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,87 +1,7 @@
# deepr-php

PHP API library following Deepr specification
PHP API library following [Deepr specification](https://github.com/deeprjs/deepr).

https://github.com/deeprjs/deepr
![](https://img.shields.io/badge/phpunit-passed-success) ![](https://img.shields.io/badge/coverage-98%25-green) ![](https://img.shields.io/github/stars/stefanak-michal/deepr-php) ![](https://img.shields.io/packagist/dt/stefanak-michal/deepr-php) ![](https://img.shields.io/github/v/release/stefanak-michal/deepr-php) ![](https://img.shields.io/github/commits-since/stefanak-michal/deepr-php/latest)


### Example

```php

function applyColumns(IComponent $object, array $row)
{
foreach ($row as $column => $value) {
if (property_exists($object, $column))
$object->$column = $value;
}
}

class Movies extends Collection implements ILoadable
{
public $count;

public function __construct()
{
$this->count = DB::getMoviesCount();
}

public function load(): array
{
$items = [];
foreach (DB::getMovies() as $row) {
$movie = new Movie();
applyColumns($movie, $row);
$items[] = $movie;
}
return $items;
}

public function getByTitle(string $title): Collection
{
$collection = new self();

$movie = new Movie();
$row = DB::getMovieByTitle($title);
applyColumns($movie, $row);
$collection->add($movie);

return $collection;
}
}

class Movie extends Collection
{
public $_id;
public $title;
public $released;
public $tagline;
}

class Root extends Collection
{
public $movies = Movies::class;
}

$deepr = new Deepr();
$json = '{"movies": {"count": true, "[]": [0, 2],"title": true, "released": true}}';
$collection = new Root();
$deepr->invokeQuery($collection, json_decode($j, true));
echo '<pre>' . json_encode($collection->execute(), JSON_PRETTY_PRINT) . '</pre>' . PHP_EOL;

/*
{
"movies": {
"count": 38,
"0": {
"title": "The Matrix",
"released": 1999
},
"1": {
"title": "The Matrix Reloaded",
"released": 2003
}
}
}
*/
```
Check wiki for more informations about how to use this library.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"php": ">=7.1.0"
},
"require-dev": {
"phpunit/phpunit": ">=7.5.0"
"phpunit/phpunit": ">=7.5.0",
"ext-json": "*"
},
"support": {
"issues": "https://github.com/stefanak-michal/deepr-php/issues",
Expand Down
62 changes: 29 additions & 33 deletions src/Deepr.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,27 +86,26 @@ private function recursion(IComponent $root, string $action, array $values)
} elseif ($k === '[]' && !empty($action)) {
if (self::$debug)
var_dump($action . ' []');
if (!($root instanceof ILoadable))
throw new Exception('You are trying access collection on not loadable object');

$offset = 0;
$length = null;
if (is_int($v)) {
$offset = $v;
$length = 1;
} elseif (is_array($v)) {
$offset = $v[0] ?? 0;
$length = $v[1] ?? null;
}
if ($root instanceof ILoadable) {
$offset = 0;
$length = null;
if (is_int($v)) {
$offset = $v;
$length = 1;
} elseif (is_array($v)) {
$offset = $v[0] ?? 0;
$length = $v[1] ?? null;
}

$items = $root->load();
$tmpValues = $values;
unset($tmpValues['[]']);
foreach (array_slice($items, $offset, $length) as $item) {
$this->recursion($item, $action, $tmpValues);
$root->add($item);
$tmpValues = $values;
unset($tmpValues['[]']);
foreach ($root->load($offset, $length) as $item) {
$this->recursion($item, $action, $tmpValues);
$root->add($item);
}
} else {
throw new Exception('To access collection of class it has to implement ILoadable interface');
}

return;
} elseif ($k === '()') {
continue;
Expand All @@ -115,18 +114,19 @@ private function recursion(IComponent $root, string $action, array $values)
var_dump($key . ' ()');

$data = $root->{$key}(...$v['()']);
if (!($data instanceof Collection))
throw new Exception('Method response has to be Collection');
if ($data instanceof Collection) {
$nest = $this->isNest($k);
foreach ($data->getChildren() as $child) {
$this->recursion($child, $key, $v);
if (!$nest)
$root->add($child);
}

$nest = $this->isNest($k);
foreach ($data->getChildren() as $child) {
$this->recursion($child, $key, $v);
if (!$nest)
$root->add($child);
if ($nest)
$root->add($data, $this->getKey($k));
} else {
throw new Exception('Method response has to be Collection');
}

if ($nest)
$root->add($data, $this->getKey($k));
} elseif ($v === true) {
if (self::$debug)
var_dump($action . ' ' . $k . ' true');
Expand All @@ -147,10 +147,6 @@ private function recursion(IComponent $root, string $action, array $values)
if (self::$debug)
var_dump($action . ' array unnest');
$this->recursion($root, $this->getKey($k, false), $v);
} else {
if (self::$debug)
var_dump($action . ' array iterate');
$this->recursion($root, $k, $v);
}
}
}
Expand Down
11 changes: 0 additions & 11 deletions src/components/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,6 @@ public function add(IComponent $component, string $name = '')
$this->children[] = $component;
}

/**
* Remove child from collection
* @param IComponent $component
*/
public function remove(IComponent $component)
{
$key = array_search($component, $this->children);
if ($key !== false)
unset($this->children[$key]);
}

/**
* Get list of children
* @return IComponent[]
Expand Down
2 changes: 1 addition & 1 deletion src/components/ILoadable.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
*/
interface ILoadable
{
public function load(): array;
public function load(int $offset, ?int $length): array;
}
97 changes: 97 additions & 0 deletions tests/DeeprTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace Deepr\tests;

use Deepr\Deepr;
use Deepr\tests\classes\Root;
use PHPUnit\Framework\TestCase;
use Exception;

/**
* Class DeeprTest
* @package Deepr\tests
* @author Michal Stefanak
* @link https://github.com/stefanak-michal/deepr-php
*/
class DeeprTest extends TestCase
{
/**
* @return Deepr|null
*/
public function testDeepr(): ?Deepr
{
$deepr = new Deepr();
$deepr::$debug = true;
$this->assertInstanceOf(Deepr::class, $deepr);
return $deepr;
}

/**
* @depends testDeepr
* @dataProvider jsonProvider
* @param string $input
* @param string $output
* @param Deepr $deepr
*/
public function testInvokeQueries(string $input, string $output, Deepr $deepr)
{
try {
$root = new Root();
$deepr->invokeQuery($root, json_decode($input, true));
$result = $root->execute();
$result = json_encode($result);
$this->assertJsonStringEqualsJsonString($output, $result);
} catch (Exception $e) {
$this->markTestIncomplete($e->getMessage());
}
}

/**
* @depends testDeepr
* @param Deepr $deepr
*/
public function testParallel(Deepr $deepr)
{
$root = new Root();
$this->expectException(Exception::class);
$deepr->invokeQuery($root, json_decode('{"||":[]}', true));
}

/**
* @depends testDeepr
* @param Deepr $deepr
*/
public function testMissingException(Deepr $deepr)
{
$root = new Root();
$this->expectException(Exception::class);
$deepr->invokeQuery($root, json_decode('{ "missingFunction": { "()": [] } }', true));
}

/**
* Use json files in jsons directory as sample data for requests
* @return array
*/
public function jsonProvider()
{
$data = [];
$dir = __DIR__ . DIRECTORY_SEPARATOR . 'jsons' . DIRECTORY_SEPARATOR;
if (file_exists($dir)) {
foreach (glob($dir . '*.json') as $file) {
list($i, $type) = explode('-', pathinfo($file, PATHINFO_FILENAME), 2);
$i = intval($i);
$type = $type == 'input' ? 0 : 1;

$json = file_get_contents($file);
if ($json === false)
continue;
$json = json_decode($json, true);
if (json_last_error() != JSON_ERROR_NONE)
continue;
$data[$i][$type] = json_encode($json);
}
}

return $data;
}
}
73 changes: 73 additions & 0 deletions tests/classes/Database.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

namespace Deepr\tests\classes;

/**
* Class Database
* Fake database with data stored in json files
* @package Deepr\tests\classes
* @author Michal Stefanak
* @link https://github.com/stefanak-michal/deepr-php
*/
class Database
{
private static $movies;
private static $actors;

private static function load()
{
if (!empty(self::$movies) && !empty(self::$actors))
return;

$movies = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'movies.json');
if ($movies === false)
trigger_error('Missing movies.json file', E_USER_ERROR);
$movies = json_decode($movies, true);
if (json_last_error() != JSON_ERROR_NONE)
trigger_error('File movies.json has wrong structure: ' . json_last_error_msg(), E_USER_ERROR);
self::$movies = $movies;

$actors = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'actors.json');
if ($actors === false)
trigger_error('Missing actors.json file', E_USER_ERROR);
$actors = json_decode($actors, true);
if (json_last_error() != JSON_ERROR_NONE)
trigger_error('File actors.json has wrong structure', E_USER_ERROR);
self::$actors = $actors;
}

public static function getMoviesCount(): int
{
self::load();
return count(self::$movies);
}

public static function getMovies(): array
{
self::load();
return self::$movies;
}

public static function getMovieByTitle(string $title): array
{
self::load();
foreach (self::$movies as $movie) {
if ($movie['title'] == $title)
return $movie;
}
return [];
}

public static function getMovieActors(int $idMovie): array
{
self::load();
$output = [];
foreach (self::$actors as $actor) {
if (in_array($idMovie, $actor['_movies'])) {
unset($actor['_movies']);
$output[] = $actor;
}
}
return $output;
}
}
Loading

0 comments on commit 2c4b8b3

Please sign in to comment.