4624863c776619c2ab3c80daa78a52a244f111b7
[catagits/Reaction.git] / t / lib / RTest / UI / Window.pm
1 package RTest::UI::Window;
2
3 use aliased 'Reaction::UI::ViewPort';
4
5 use base qw/Reaction::Test/;
6 use Reaction::Class;
7
8 use Test::More ();
9
10 BEGIN {
11   eval q{
12     package RTest::UI::Window::_::view;
13
14     use base qw/Reaction::UI::Renderer::XHTML/;
15
16     sub render {
17       return $_[0]->{render}->(@_);
18     }
19
20     package RTest::UI::Window::_::TestViewPort;
21
22     use Reaction::Class;
23
24     extends 'Reaction::UI::ViewPort';
25
26     register_inc_entry;
27
28     sub handle_events {
29       $_[0]->{handle_events}->(@_);
30     }
31   };
32   if ($@) {
33     Test::More::plan skip_all => "Caught exception generating basic classes to test: $@";
34     exit;
35   } 
36 };
37
38 use Reaction::UI::Window;
39 use aliased 'RTest::UI::Window::_::TestViewPort';
40
41 has 'window' => (isa => 'Reaction::UI::Window', is => 'rw', lazy_build => 1);
42
43 sub _build_window {
44   my $self = shift;
45   return Reaction::UI::Window->new(
46            ctx => bless({}, 'Reaction::Test::Mock::Context'),
47            view_name => 'Test',
48            content_type => 'text/html',
49          );
50 }
51
52 sub test_window :Tests {
53   my $self = shift;
54   my $window = $self->build_window;
55   my $view = bless({}, 'RTest::UI::Window::_::view');
56   $window->ctx->{view} = sub {
57     Test::More::is($_[1], 'Test', 'View name ok');
58     return $view;
59   };
60   Test::More::is($window->view, $view, 'View retrieved from context');
61   my %param;
62   $window->ctx->{req} = sub {
63     return bless({
64              query_parameters => sub { \%param },
65              body_parameters => sub { {} },
66            }, 'Reaction::Test::Mock::Request');
67   };
68   $window->ctx->{res} = sub {
69     return bless({
70              status => sub { 200 },
71              body => sub { '' },
72            }, 'Reaction::Test::Mock::Response');
73   };
74   eval { $window->flush };
75   Test::More::like($@, qr/empty focus stack/, 'Error thrown without viewports');
76   my @vp;
77   push(@vp, $window->focus_stack
78     ->push_viewport(ViewPort, ctx => $window->ctx));
79   push(@vp, $window->focus_stack
80     ->push_viewport(ViewPort, ctx => $window->ctx));
81   my $i;
82   $view->{render} = sub {
83     my $expect_vp = $vp[$i++];
84     Test::More::is($_[1], $window->ctx, 'Context ok');
85     Test::More::is($_[2], 'component', 'Component template');
86     Test::More::is($_[3]->{self}, $expect_vp, 'Viewport');
87     $_[3]->{window}->render_viewport($expect_vp->inner);
88     return "foo";
89   };
90   my $body;
91   $window->ctx->{res} = sub {
92     return bless({
93              body => sub { shift; return '' unless @_; $body = shift; },
94              content_type => sub { },
95              status => sub { 200 },
96            }, 'Reaction::Test::Mock::Response');
97   };
98   $window->flush;
99   Test::More::is($body, 'foo', 'body set ok');
100   my $test_vp = $vp[1]->create_tangent('foo')
101                       ->push_viewport(TestViewPort,
102                                       ctx => bless({}, 'Catalyst'));
103   my $param_name = '1.foo.0:name';
104   Test::More::is($test_vp->event_id_for('name'), $param_name, 'Event id ok');
105   $param{$param_name} = 'blah';
106   $test_vp->{handle_events} = sub {
107     Test::More::is($_[1]->{name}, 'blah', 'Event delivered ok');
108   };
109   $window->flush_events;
110 }
111
112 1;