Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

add Kamui::Web.

  • Loading branch information...
commit f6d4e81cb3d63e98fa11e97f0ea04186729768bc 1 parent 530753a
@nekokak authored
View
10 bench/assets/script/handler.psgi
@@ -0,0 +1,10 @@
+use MyAPP::Web::Handler;
+use Plack::Builder;
+
+my $app = MyAPP::Web::Handler->new;
+builder {
+ enable 'Debug', panels => [ qw(Memory) ];
+ $app->handler;
+};
+
+
View
9 bench/assets/script/web.psgi
@@ -0,0 +1,9 @@
+use MyAPP::Web;
+use Plack::Builder;
+
+my $app = MyAPP::Web->new;
+builder {
+ enable 'Debug', panels => [ qw(Memory) ];
+ $app->handler;
+};
+
View
6 bench/assets/tmpl/root/index.html
@@ -0,0 +1,6 @@
+<html>
+<head></head>
+<body>
+hi kamui.
+</body>
+</html>
View
12 bench/config.pl
@@ -0,0 +1,12 @@
+use Kamui;
+use MyAPP::Container;
+use Path::Class;
+
+return +{
+ view => {
+ tt => +{
+ path => container('home')->file('assets/tmpl')->stringify,
+ },
+ },
+};
+
View
5 bench/lib/MyAPP/Container.pm
@@ -0,0 +1,5 @@
+package MyAPP::Container;
+use Kamui::Container -base;
+
+1;
+
View
19 bench/lib/MyAPP/Web.pm
@@ -0,0 +1,19 @@
+package MyAPP::Web;
+use Kamui;
+use base 'Kamui::Web';
+
+use MyAPP::Web::Context;
+sub context {'MyAPP::Web::Context'}
+
+use MyAPP::Web::Dispatcher;
+sub dispatcher {'MyAPP::Web::Dispatcher'}
+
+sub view {'Kamui::View::TT'}
+sub plugins {['Encode']}
+
+use MyAPP::Container -no_export;
+sub container { MyAPP::Container->instance }
+
+
+1;
+
View
6 bench/lib/MyAPP/Web/Context.pm
@@ -0,0 +1,6 @@
+package MyAPP::Web::Context;
+use Kamui;
+use base 'Kamui::Web::Context';
+
+
+1;
View
7 bench/lib/MyAPP/Web/Controller/Root.pm
@@ -0,0 +1,7 @@
+package MyAPP::Web::Controller::Root;
+use Kamui::Web::Controller -base;
+
+sub do_index { }
+
+1;
+
View
9 bench/lib/MyAPP/Web/Dispatcher.pm
@@ -0,0 +1,9 @@
+package MyAPP::Web::Dispatcher;
+use Kamui::Web::Dispatcher;
+
+on '/' => run {
+ return 'Root', 'index', FALSE, +{};
+};
+
+1;
+
View
11 bench/lib/MyAPP/Web/Handler.pm
@@ -0,0 +1,11 @@
+package MyAPP::Web::Handler;
+use Kamui::Web::Handler;
+
+use_container 'MyAPP::Container';
+use_plugins [qw/Encode/];
+use_context 'MyAPP::Web::Context';
+use_view 'Kamui::View::TT';
+use_dispatcher 'MyAPP::Web::Dispatcher';
+
+1;
+
View
91 lib/Kamui/Web.pm
@@ -0,0 +1,91 @@
+package Kamui::Web;
+use Kamui;
+
+sub dispatcher { die 'this method is abstract: dispatch' }
+sub view { die 'this method is abstract: view' }
+sub context { die 'this method is abstract: context' }
+sub container { die 'this method is abstract: container' }
+sub plugins { [] }
+
+sub new {
+ my $class = shift;
+
+ $class->context->load_plugins( $class->plugins );
+
+ bless {}, $class;
+}
+
+sub handler {
+ my $self = shift;
+
+ sub {
+ my $env = shift;
+
+ my $context = $self->context->new(
+ env => $env,
+ dispatch_rule => +{},
+ view => $self->view,
+ conf => $self->container->get('conf'),
+ app => $self,
+ );
+ $context->initialize();
+
+ my $rule = $self->dispatcher->determine($context);
+ $context->dispatch_rule($rule);
+
+ my $response = $self->dispatch($context);
+ $context->finalize($response);
+
+ $response->finalize;
+ };
+}
+
+sub dispatch {
+ my ($self, $context) = @_;
+
+ my $controller = $context->dispatch_rule->{controller}||'';
+ ($controller && $controller->use) or do {
+ warn "[404] controller : $controller $@ (path: $context->{env}->{PATH_INFO})";
+ return $context->handle_404;
+ };
+
+ my $action = $context->dispatch_rule->{action} or do {
+ warn "[500] controller : $controller, action : $context->dispatch_rule->{action} $@ (path: $context->{env}->{PATH_INFO})";
+ return $context->handle_404;
+ };
+
+ my $method = 'do_'.$action;
+ if ($context->dispatch_rule->{is_static}) {
+ no strict 'refs'; ## no critic.
+ *{"${controller}::${method}"} = sub { "empty" };
+ }
+
+ if (my $dispatch_code = $controller->can($method)) {
+
+ my $res;
+ eval {
+
+ if (my $not_authorized = $controller->authorize($dispatch_code, $context)) {
+ $res = $not_authorized;
+ } else {
+ $controller->call_trigger('before_dispatch', $context, $context->dispatch_rule->{args});
+ $res = $controller->$method($context, $context->dispatch_rule->{args});
+ $controller->call_trigger('after_dispatch', $context, $context->dispatch_rule->{args});
+ }
+ };
+ if ( $context->is_detach($@) ) {
+ return $context->res;
+ } elsif($@) {
+ warn $@;
+ return $context->handle_500;
+ }
+ return $res if $context->is_finished;
+ return $context->render;
+ } else {
+ warn q{can not find dispatch method.};
+ return $context->handle_404;
+ }
+}
+
+1;
+
View
82 t/020_web/web/base.t
@@ -0,0 +1,82 @@
+use t::Utils;
+use Test::More;
+use Mock::Web;
+
+my $app = Mock::Web->new;
+my $psgi_handler = $app->handler;
+
+subtest 'simple handler test' => sub {
+ my $env = +{
+ REQUEST_METHOD => 'GET',
+ SERVER_PROTOCOL => 'HTTP/1.1',
+ SERVER_PORT => 80,
+ SERVER_NAME => 'example.com',
+ SCRIPT_NAME => '/handler_base_test',
+ PATH_INFO => '/handler_base_test',
+ REMOTE_ADDR => '127.0.0.1',
+ };
+ my $res = $psgi_handler->($env);
+ is_deeply $res, [
+ '200',
+ [
+ 'Content-Type',
+ 'text/html'
+ ],
+ [
+ "handler_base_test is ok\n"
+ ]
+ ];
+ done_testing;
+};
+
+subtest 'args test' => sub {
+ my $env = +{
+ REQUEST_METHOD => 'GET',
+ SERVER_PROTOCOL => 'HTTP/1.1',
+ SERVER_PORT => 80,
+ SERVER_NAME => 'example.com',
+ SCRIPT_NAME => '/args_test',
+ PATH_INFO => '/args_test',
+ REMOTE_ADDR => '127.0.0.1',
+ };
+ my $res = $psgi_handler->($env);
+ is_deeply $res, [
+ '200',
+ [
+ 'Content-Type',
+ 'text/html'
+ ],
+ [
+ "args_test is ok\n"
+ ]
+ ];
+ done_testing;
+};
+
+subtest 'query test' => sub {
+ my $env = +{
+ REQUEST_METHOD => 'GET',
+ SERVER_PROTOCOL => 'HTTP/1.1',
+ SERVER_PORT => 80,
+ SERVER_NAME => 'example.com',
+ SCRIPT_NAME => '/query_test/',
+ PATH_INFO => '/query_test/',
+ REMOTE_ADDR => '127.0.0.1',
+ QUERY_STRING => 'p=query',
+ };
+ my $res = $psgi_handler->($env);
+ is_deeply $res, [
+ '200',
+ [
+ 'Content-Type',
+ 'text/html'
+ ],
+ [
+ "query is ok\n"
+ ]
+ ];
+ done_testing;
+};
+
+done_testing;
+
View
17 t/lib/Mock/Web.pm
@@ -0,0 +1,17 @@
+package Mock::Web;
+use Kamui;
+use base 'Kamui::Web';
+
+use Kamui::Web::Context;
+sub context {'Kamui::Web::Context'}
+
+use Mock::Web::Dispatcher;
+sub dispatcher {'Mock::Web::Dispatcher'}
+
+sub view {'Kamui::View::TT'}
+sub plugins {['Encode']}
+
+use Mock::Container -no_export;
+sub container { Mock::Container->instance }
+
+1;

0 comments on commit f6d4e81

Please sign in to comment.
Something went wrong with that request. Please try again.