Skip to content

Commit

Permalink
Merge branch 'master' of github.com:xp-forge/web
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Sep 18, 2022
2 parents 637e404 + 5511ed9 commit 7449dd6
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 11 deletions.
23 changes: 17 additions & 6 deletions src/main/php/web/Application.class.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<?php namespace web;

use Closure;
use lang\Value;

/**
* Application is at the heart at every web project.
*
* @test xp://web.unittest.ApplicationTest
* @test web.unittest.ApplicationTest
*/
abstract class Application implements \lang\Value {
abstract class Application implements Value {
private $routing= null;
private $filters= [];
protected $environment;

/**
Expand All @@ -28,7 +32,8 @@ public function environment() { return $this->environment; }
*/
public final function routing() {
if (null === $this->routing) {
$this->routing= Routing::cast($this->routes(), true);
$routing= Routing::cast($this->routes(), true);
$this->routing= $this->filters ? new Filters($this->filters, $routing) : $routing;
}
return $this->routing;
}
Expand All @@ -46,11 +51,17 @@ public abstract function routes();
/**
* Installs global filters
*
* @param web.Filter[] $filters
* @param web.Filter|function(web.Request, web.Response, web.filters.Invocation): var|web.Filter[] $arg
* @return void
*/
public function install($filters) {
$this->routing= new Filters($filters, $this->routing());
public function install($arg) {
if ($arg instanceof Filter || $arg instanceof Closure) {
$this->filters[]= $arg;
} else {
foreach ((array)$arg as $filter) {
$this->filters[]= $filter;
}
}
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/main/php/web/Route.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Route {
* Creates a new route
*
* @param web.routing.Match|function(web.Request): web.Handler $match
* @param web.Handler|function(web.Request, web.Response): var $handler
* @param web.Handler|function(web.Request, web.Response): var|[:var] $handler
*/
public function __construct($match, $handler) {
if ($match instanceof RouteMatch) {
Expand All @@ -21,6 +21,8 @@ public function __construct($match, $handler) {

if ($handler instanceof Handler) {
$this->handler= $handler;
} else if (is_array($handler)) {
$this->handler= Routing::cast($handler);
} else {
$this->handler= new Call($handler);
}
Expand Down
51 changes: 49 additions & 2 deletions src/test/php/web/unittest/ApplicationTest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

use lang\IllegalStateException;
use unittest\{Expect, Test};
use util\Objects;
use web\io\{TestInput, TestOutput};
use web\{Application, Environment, Error, Filters, Handler, Request, Response, Routing};
use web\{Application, Environment, Error, Filter, Filters, Handler, Request, Response, Routing};

class ApplicationTest extends \unittest\TestCase {
private $environment;
Expand All @@ -13,6 +14,18 @@ public function setUp() {
$this->environment= new Environment('dev', '.', 'static', []);
}

/** @return iterable */
private function filters() {
yield [function($req, $res, $invocation) {
return $invocation->proceed($req->pass('filtered', 'true'), $res);
}];
yield [new class() implements Filter {
public function filter($req, $res, $invocation) {
return $invocation->proceed($req->pass('filtered', 'true'), $res);
}
}];
}

/**
* Handle given routes
*
Expand All @@ -22,7 +35,7 @@ public function setUp() {
private function handle($routes) {
with ($app= newinstance(Application::class, [$this->environment], ['routes' => $routes])); {
$request= new Request(new TestInput('GET', '/'));
$response= new Response();
$response= new Response(new TestOutput());
$app->service($request, $response);
return [$request, $response];
}
Expand Down Expand Up @@ -230,4 +243,38 @@ public function does_not_equal_clone() {
$app= new HelloWorld($this->environment);
$this->assertEquals(1, $app->compareTo(clone $app));
}

#[Test, Values('filters')]
public function install_filter($install) {
list($request, $response)= $this->handle(function() use($install) {
$this->install($install);

return function($req, $res) {
$res->send($req->value('filtered'), 'text/plain');
};
});
$this->assertEquals('true', $response->output()->body());
}

#[Test]
public function install_multiple_filters() {
list($request, $response)= $this->handle(function() {
$this->install([
function($req, $res, $invocation) {
return $invocation->proceed($req->pass('filtered', 'true'), $res);
},
function($req, $res, $invocation) {
return $invocation->proceed($req->pass('enhanced', 'twice'), $res);
}
]);

return function($req, $res) {
$res->send(Objects::stringOf($req->values()), 'text/plain');
};
});
$this->assertEquals(
Objects::stringOf(['filtered' => 'true', 'enhanced' => 'twice']),
$response->output()->body()
);
}
}
5 changes: 3 additions & 2 deletions src/test/php/web/unittest/RoutingTest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use unittest\{Expect, Test, TestCase, Values};
use web\io\{TestInput, TestOutput};
use web\routing\{CannotRoute, Target};
use web\{Application, Environment, Handler, Request, Response, Route, Routing};
use web\{Application, Environment, Filters, Handler, Request, Response, Route, Routing};

class RoutingTest extends TestCase {
private $handlers;
Expand All @@ -12,7 +12,8 @@ class RoutingTest extends TestCase {
public function setUp() {
$this->handlers= [
'specific' => new class() implements Handler { public $name= 'specific'; public function handle($req, $res) { }},
'default' => new class() implements Handler { public $name= 'default'; public function handle($req, $res) { }}
'default' => new class() implements Handler { public $name= 'default'; public function handle($req, $res) { }},
'error' => new class() implements Handler { public $name= 'error'; public function handle($req, $res) { }},
];
}

Expand Down

0 comments on commit 7449dd6

Please sign in to comment.