Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
alcalyn committed Aug 30, 2017
2 parents 6435a2e + ab89a51 commit ebbf467
Show file tree
Hide file tree
Showing 15 changed files with 281 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@
/phpunit.xml.dist export-ignore
/phpcs.xml export-ignore
/.scrutinizer.yml export-ignore
/Makefile export-ignore
/docker export-ignore
/docker-compose.yml export-ignore
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
all: install test

install:
docker-compose up -d

docker exec -ti sandstone sh -c "composer install"

update:
docker-compose up -d

docker exec -ti sandstone sh -c "composer update"

test:
docker-compose up -d

docker exec -ti sandstone sh -c "vendor/bin/phpunit -c ."
docker exec -ti sandstone sh -c "vendor/bin/phpcs src --standard=phpcs.xml"

logs:
docker-compose logs -ft

bash:
docker exec -ti sandstone bash
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,33 @@ Sandstone extends Silex to easily mount a RestApi working together with a **Webs
[See the documentation here](https://eole-io.github.io/sandstone/).


## Testing
## Application

If you plan to start a new real-time Rest Api application based on Sandstone,
you may be interested by sandstone-edition.

It already integrates a Sandstone application with a docker environment, a database, debug tools...

Check it out: [eole/sandstone-edition](https://github.com/eole-io/sandstone-edition).


Running tests:
## Testing

``` bash
# Install dependencies
composer install

# Running tests
vendor/bin/phpunit -c .

# Checking code style
vendor/bin/phpcs src --standard=phpcs.xml
```

Checking code style:
Or using Docker, install dependencies and run all tests and codestyle checks:

``` bash
vendor/bin/phpcs src --standard=phpcs.xml
make
```


Expand Down
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: '2'

services:
php-fpm:
container_name: sandstone
build: docker/php-fpm
volumes:
- .:/var/www/html/
5 changes: 5 additions & 0 deletions docker/docker-compose.arm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
version: '2'

services:
php-fpm:
build: docker/php-fpm-rpi
23 changes: 23 additions & 0 deletions docker/php-fpm-rpi/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM alcalyn/rpi-php7-fpm-zmq

# install PHP extensions & PECL modules with dependencies
RUN apt-get update \
&& apt-get install -y \
bzip2 git wget \
zlib1g-dev \
libicu-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*

RUN docker-php-ext-install intl \
&& docker-php-ext-install pdo_mysql mysqli \
&& docker-php-ext-install zip

# install composer
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('SHA384', 'composer-setup.php') === '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php --filename=composer \
&& php -r "unlink('composer-setup.php');" \
&& mv composer /usr/local/bin/composer

WORKDIR "/var/www/html"
7 changes: 7 additions & 0 deletions docker/php-fpm/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM phpdockerio/php71-fpm

RUN apt-get update \
&& apt-get -y --no-install-recommends install php7.1-mysql php-zmq \
&& apt-get clean; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*

WORKDIR "/var/www/html"
4 changes: 1 addition & 3 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,7 @@ public function forwardEventsToPushServer(array $eventsNames)
));
}

$this->before(function () use ($eventsNames) {
$this['sandstone.push.event_forwarder']->forwardAllEvents($eventsNames);
});
$this['sandstone.push.event_forwarder']->forwardAllEvents($eventsNames);

return $this;
}
Expand Down
9 changes: 9 additions & 0 deletions src/Websocket/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Eole\Sandstone\Websocket;

use Psr\Log\LoggerAwareTrait;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface as WrongEventSubscriberInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Ratchet\ConnectionInterface;
Expand Down Expand Up @@ -120,6 +121,14 @@ private function loadTopic($topicPath)
$this->sandstoneApplication['dispatcher']->addSubscriber($topic);
}

// debug purpose only. Sometimes I use the wrong namespace (JMS one), and it's hard to debug.
if ($topic instanceof WrongEventSubscriberInterface) {
throw new \LogicException(
get_class($topic).' seems to implements the wrong EventSubscriberInterface. '.
'Use the Symfony one, not the JMS one.'
);
}

return $topic;
}

Expand Down
31 changes: 31 additions & 0 deletions tests/Integration/App/Console.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Eole\Sandstone\Tests\Integration\App;

use Symfony\Component\Console\Application as ConsoleApplication;
use Eole\Sandstone\Tests\Integration\App\App as SilexApplication;

class Console extends ConsoleApplication
{
/**
* @var SilexApplication
*/
private $silexApplication;

/**
* Console application constructor.
*
* @param SilexApplication $silexApplication
*/
public function __construct(SilexApplication $silexApplication)
{
parent::__construct('My Sandstone application');

$this->silexApplication = $silexApplication;
$this->silexApplication->boot();

$this->addCommands([
new PushMessageCommand($this->silexApplication['dispatcher']),
]);
}
}
53 changes: 53 additions & 0 deletions tests/Integration/App/PushMessageCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Eole\Sandstone\Tests\Integration\App;

use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command;
use Eole\Sandstone\Tests\Integration\App\ArticleCreatedEvent;

class PushMessageCommand extends Command
{
/**
* @var EventDispatcherInterface
*/
private $dispatcher;

/**
* @param EventDispatcherInterface $dispatcher
*/
public function __construct(EventDispatcherInterface $dispatcher)
{
parent::__construct('sandstone:test:push');

$this->dispatcher = $dispatcher;
}

/**
* {@InheritDoc}
*/
protected function configure()
{
parent::configure();

$this
->setDescription('Dispatch an event which should push an event.')
;
}

/**
* {@InheritDoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$id = 42;
$title = 'Unicorns spotted in Alaska';
$url = 'http://unicorn.com/articles/unicorns-spotted-alaska';

$event = new ArticleCreatedEvent($id, $title, $url);

$this->dispatcher->dispatch('article.created', $event);
}
}
43 changes: 43 additions & 0 deletions tests/Integration/PushOnConsoleCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Eole\Sandstone\Tests\Integration;

use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\HttpFoundation\Request;
use Eole\Sandstone\Push\PushServerInterface;
use Eole\Sandstone\Tests\Integration\App\ArticleCreatedEvent;

class PushOnConsoleCommandTest extends \PHPUnit_Framework_TestCase
{
public function testDispatchingEventFromConsoleCommandTriggersPushEvent()
{
$pushServerMock = $this->getMockForAbstractClass(PushServerInterface::class);

$app = new App\AppRestApi([
'debug' => true,
'sandstone.push' => function () use ($pushServerMock) {
return $pushServerMock;
},
]);

$pushServerMock
->expects($this->once())
->method('send')
->with($this->callback(function ($message) {
$decodedMessage = unserialize($message);
$serializedEvent = '{"propagation_stopped":false,"id":42,"title":"Unicorns spotted in Alaska","url":"http:\/\/unicorn.com\/articles\/unicorns-spotted-alaska"}';

return
ArticleCreatedEvent::ARTICLE_CREATED_EVENT === $decodedMessage['name'] &&
ArticleCreatedEvent::class === $decodedMessage['class'] &&
$serializedEvent === $decodedMessage['event']
;
}))
;

$console = new App\Console($app);
$input = new ArrayInput(['sandstone:test:push']);
$console->find('sandstone:test:push')->run($input, new NullOutput());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Eole\Sandstone\Tests\Unit;
namespace Eole\Sandstone\Tests\Unit\Push;

use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Eole\Sandstone\Push\PushServerInterface;
Expand Down
41 changes: 41 additions & 0 deletions tests/Unit/Websocket/ApplicationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Eole\Sandstone\Tests\Unit\Websocket;

use Eole\Sandstone\Serializer\ServiceProvider as SerializerServiceProvider;
use Eole\Sandstone\Websocket\Routing\TopicRouter;
use Eole\Sandstone\Websocket\Application as WebsocketApplication;
use Eole\Sandstone\Application;

class ApplicationTest extends \PHPUnit_Framework_TestCase
{
public function testLoadTopicThrowExceptionWhenImplementingTheWrongEventDispatcherInterface()
{
$app = new Application();
$websocketAppClass = new \ReflectionClass(WebsocketApplication::class);
$method = $websocketAppClass->getMethod('loadTopic');
$method->setAccessible(true);
$websocketApp = $websocketAppClass->newInstance($app);

$app->register(new SerializerServiceProvider());

$app['sandstone.websocket.router'] = function () {
$wrongTopic = new WrongTopic('my-topic');
$topicRouterMock = $this->getMockBuilder(TopicRouter::class)->disableOriginalConstructor()->getMock();

$topicRouterMock
->method('loadTopic')
->willReturn($wrongTopic)
;

return $topicRouterMock;
};

$this->setExpectedExceptionRegExp(
\LogicException::class,
'/WrongTopic seems to implements the wrong EventSubscriberInterface/'
);

$method->invokeArgs($websocketApp, ['my-topic']);
}
}
14 changes: 14 additions & 0 deletions tests/Unit/Websocket/WrongTopic.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Eole\Sandstone\Tests\Unit\Websocket;

use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use Eole\Sandstone\Websocket\Topic;

class WrongTopic extends Topic implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [];
}
}

0 comments on commit ebbf467

Please sign in to comment.