1use strict;
2use warnings;
3use Carp;
4
5use Test::More tests => 69;
6
7use RPC::ExtDirect::Test::Util;
8
9sub global_before {}
10
11sub global_after {}
12
13use RPC::ExtDirect;      # Checking case insensitiveness, too
14use RPC::ExtDirect::API  Before => \&global_before,
15                         aFtEr  => \&global_after,
16                         ;
17
18use RPC::ExtDirect::Test::Pkg::Foo;
19use RPC::ExtDirect::Test::Pkg::Bar;
20use RPC::ExtDirect::Test::Pkg::Qux;
21use RPC::ExtDirect::Test::Pkg::PollProvider;
22
23my $tests = eval do { local $/; <DATA>; }           ## no critic
24    or die "Can't eval DATA: '$@'";
25
26my %test_for = %{ $tests->{main_tests} };
27
28my @expected_classes = sort qw( Foo Bar Qux PollProvider );
29
30my @full_classes = sort eval { RPC::ExtDirect->get_action_list() };
31
32is       $@, '', "full get_action_list() eval $@";
33ok       @full_classes, "full get_action_list() not empty";
34is_deep \@full_classes, \@expected_classes, "full get_action_list() deep";
35
36my @expected_methods = sort qw(
37    Qux::bar_bar            Qux::bar_baz        Qux::bar_foo
38    Qux::foo_bar            Qux::foo_baz        Qux::foo_foo
39    Foo::foo_foo            Foo::foo_bar        Foo::foo_baz
40    Foo::foo_zero           Foo::foo_blessed
41    Bar::bar_foo            Bar::bar_bar        Bar::bar_baz
42    PollProvider::foo
43);
44
45my @full_methods = sort eval { RPC::ExtDirect->get_method_list() };
46
47is       $@, '',         "full get_method_list() eval $@";
48ok       @full_methods, "full get_method_list() not empty";
49is_deep \@full_methods, \@expected_methods, "full get_method_list() deep";
50
51my @expected_poll_handlers = ( [ 'PollProvider', 'foo' ] );
52
53my @full_poll_handlers = eval { RPC::ExtDirect->get_poll_handlers() };
54
55is      $@, '',              "full get_poll_handlers() eval $@";
56ok      @full_poll_handlers, "full get_poll_handlers() not empty";
57is_deep \@full_poll_handlers, \@expected_poll_handlers,
58                        "full get_poll_handlers() deep";
59
60# We have RPC::ExtDirect already loaded so let's go
61for my $module ( sort keys %test_for ) {
62    my $test = $test_for{ $module };
63
64    my @method_list = sort eval { RPC::ExtDirect->get_method_list($module) };
65    is $@, '', "$module get_method_list eval $@";
66
67    my @expected_list = sort @{ $test->{methods} };
68
69    is_deep \@method_list, \@expected_list, "$module get_method_list() deeply";
70
71    my %expected_parameter_for = %{ $test->{list  } };
72
73    for my $method_name ( @method_list ) {
74        my %parameters = eval {
75            RPC::ExtDirect->get_method_parameters($module, $method_name)
76        };
77
78        is $@, '', "$module get_method_parameters() list eval $@";
79
80        my $expected_ref = $expected_parameter_for{ $method_name };
81
82        # No way to compare referents (and no sense in that, too);
83        delete $parameters{referent};
84
85        is_deep \%parameters, $expected_ref,
86            "$module get_method_parameters() deeply";
87    };
88};
89
90# Check if we have hooks properly defined
91my $hook_tests = $tests->{hook_tests};
92
93for my $test ( @$hook_tests ) {
94    my $name = $test->{name};
95
96    my $code = RPC::ExtDirect->get_hook(
97        package => $test->{package},
98        method  => $test->{method},
99        type    => $test->{type},
100    );
101
102    is $code, $test->{code}, "$name code matches";
103};
104
105__DATA__
106#line 106
107{
108    main_tests => {
109        # foo is plain basic package with ExtDirect methods and hooks
110        'Foo' => {
111            methods => [ sort qw( foo_foo foo_bar foo_baz foo_zero foo_blessed ) ],
112            list    => {
113                foo_foo => { package => 'RPC::ExtDirect::Test::Pkg::Foo',
114                             method  => 'foo_foo', param_no => 1,
115                             formHandler => 0, pollHandler => 0,
116                             param_names => undef,
117                             before => \&RPC::ExtDirect::Test::Pkg::Foo::foo_before,
118                           },
119                foo_bar => { package => 'RPC::ExtDirect::Test::Pkg::Foo',
120                             method  => 'foo_bar', param_no => 2,
121                             formHandler => 0, pollHandler => 0,
122                             param_names => undef,
123                             instead => \&RPC::ExtDirect::Test::Pkg::Foo::foo_instead,
124                           },
125                foo_baz => { package => 'RPC::ExtDirect::Test::Pkg::Foo',
126                             method  => 'foo_baz', param_no => undef,
127                             formHandler => 0, pollHandler => 0,
128                             param_names => [ qw( foo bar baz ) ],
129                             before => \&RPC::ExtDirect::Test::Pkg::Foo::foo_before,
130                             after  => \&RPC::ExtDirect::Test::Pkg::Foo::foo_after,
131                           },
132                foo_zero =>{ package => 'RPC::ExtDirect::Test::Pkg::Foo',
133                             method  => 'foo_zero', param_no => 0,
134                             formHandler => 0, pollHandler => 0,
135                             param_names => undef, },
136                foo_blessed => { package => 'RPC::ExtDirect::Test::Pkg::Foo',
137                             method => 'foo_blessed', param_no => undef,
138                             formHandler => 0, pollHandler => 0,
139                             param_names => [], },
140
141            },
142        },
143        # bar package has only its own methods as we don't support inheritance
144        'Bar' => {
145            methods => [ sort qw( bar_foo bar_bar bar_baz ) ],
146            list    => {
147                bar_foo => { package => 'RPC::ExtDirect::Test::Pkg::Bar',
148                             method  => 'bar_foo', param_no => 4,
149                             formHandler => 0, pollHandler => 0,
150                             param_names => undef, },
151                bar_bar => { package => 'RPC::ExtDirect::Test::Pkg::Bar',
152                             method  => 'bar_bar', param_no => 5,
153                             formHandler => 0, pollHandler => 0,
154                             param_names => undef, },
155                bar_baz => { package => 'RPC::ExtDirect::Test::Pkg::Bar',
156                             method  => 'bar_baz', param_no => undef,
157                             formHandler => 1, pollHandler => 0,
158                             param_names => undef, },
159            },
160        },
161        # Now, qux package redefines all methods so we have 'em here
162        'Qux' => {
163            methods => [sort qw(foo_foo foo_bar foo_baz bar_foo bar_bar bar_baz)],
164            list    => {
165                foo_foo => { package => 'RPC::ExtDirect::Test::Pkg::Qux',
166                             method  => 'foo_foo', param_no => 1,
167                             formHandler => 0, pollHandler => 0,
168                             param_names => undef, },
169                foo_bar => { package => 'RPC::ExtDirect::Test::Pkg::Qux',
170                             method  => 'foo_bar', param_no => 2,
171                             formHandler => 0, pollHandler => 0,
172                             param_names => undef, },
173                foo_baz => { package => 'RPC::ExtDirect::Test::Pkg::Qux',
174                             method  => 'foo_baz', param_no => undef,
175                             formHandler => 0, pollHandler => 0,
176                             param_names => [ qw( foo bar baz ) ], },
177                bar_foo => { package => 'RPC::ExtDirect::Test::Pkg::Qux',
178                             method  => 'bar_foo', param_no => 4,
179                             formHandler => 0, pollHandler => 0,
180                             param_names => undef, },
181                bar_bar => { package => 'RPC::ExtDirect::Test::Pkg::Qux',
182                             method  => 'bar_bar', param_no => 5,
183                             formHandler => 0, pollHandler => 0,
184                             param_names => undef, },
185                bar_baz => { package => 'RPC::ExtDirect::Test::Pkg::Qux',
186                             method  => 'bar_baz', param_no => undef,
187                             formHandler => 1, pollHandler => 0,
188                             param_names => undef, },
189            },
190        },
191        # PollProvider implements Event provider for polling mechanism
192        'PollProvider' => {
193            methods => [ sort qw( foo ) ],
194            list    => {
195                foo => { package => 'RPC::ExtDirect::Test::Pkg::PollProvider',
196                         method  => 'foo', param_no => undef,
197                         formHandler => 0, pollHandler => 1,
198                         param_names => undef, },
199            },
200        },
201    },
202
203    hook_tests => [
204        {
205            name    => 'foo_foo method scope before hook',
206            package => 'RPC::ExtDirect::Test::Pkg::Foo',
207            method  => 'foo_foo',
208            type    => 'before',
209            code    => \&RPC::ExtDirect::Test::Pkg::Foo::foo_before,
210        },
211        {
212            name    => 'foo_baz method scope instead hook',
213            package => 'RPC::ExtDirect::Test::Pkg::Foo',
214            method  => 'foo_bar',
215            type    => 'instead',
216            code    => \&RPC::ExtDirect::Test::Pkg::Foo::foo_instead,
217        },
218        {
219            name    => 'foo_baz method scope before hook',
220            package => 'RPC::ExtDirect::Test::Pkg::Foo',
221            method  => 'foo_baz',
222            type    => 'before',
223            code    => \&RPC::ExtDirect::Test::Pkg::Foo::foo_before,
224        },
225        {
226            name    => 'foo_baz method scope after hook',
227            package => 'RPC::ExtDirect::Test::Pkg::Foo',
228            method  => 'foo_baz',
229            type    => 'after',
230            code    => \&RPC::ExtDirect::Test::Pkg::Foo::foo_after,
231        },
232        {
233            name    => 'bar_foo package scope before hook',
234            package => 'RPC::ExtDirect::Test::Pkg::Bar',
235            method  => 'bar_foo',
236            type    => 'before',
237            code    => \&RPC::ExtDirect::Test::Pkg::Bar::bar_before,
238        },
239        {
240            name    => 'bar_foo package scope after hook',
241            package => 'RPC::ExtDirect::Test::Pkg::Bar',
242            method  => 'bar_foo',
243            type    => 'after',
244            code    => \&RPC::ExtDirect::Test::Pkg::Bar::bar_after,
245        },
246        {
247            name    => 'bar_bar package scope before hook',
248            package => 'RPC::ExtDirect::Test::Pkg::Bar',
249            method  => 'bar_bar',
250            type    => 'before',
251            code    => \&RPC::ExtDirect::Test::Pkg::Bar::bar_before,
252        },
253        {
254            name    => 'bar_bar package scope after hook',
255            package => 'RPC::ExtDirect::Test::Pkg::Bar',
256            method  => 'bar_bar',
257            type    => 'after',
258            code    => \&RPC::ExtDirect::Test::Pkg::Bar::bar_after,
259        },
260        {
261            name    => 'bar_baz package scope before hook',
262            package => 'RPC::ExtDirect::Test::Pkg::Bar',
263            method  => 'bar_baz',
264            type    => 'before',
265            code    => \&RPC::ExtDirect::Test::Pkg::Bar::bar_before,
266        },
267        {
268            name    => 'bar_baz package scope after hook',
269            package => 'RPC::ExtDirect::Test::Pkg::Bar',
270            method  => 'bar_baz',
271            type    => 'after',
272            code    => \&RPC::ExtDirect::Test::Pkg::Bar::bar_after,
273        },
274        {
275            name    => 'Global scope Qux foo_foo before hook',
276            package => 'RPC::ExtDirect::Test::Pkg::Qux',
277            method  => 'foo_foo',
278            type    => 'before',
279            code    => \&global_before,
280        },
281        {
282            name    => 'Global scope Qux foo_foo after hook',
283            package => 'RPC::ExtDirect::Test::Pkg::Qux',
284            method  => 'foo_foo',
285            type    => 'after',
286            code    => \&global_after,
287        },
288        {
289            name    => 'Global scope Qux foo_bar before hook',
290            package => 'RPC::ExtDirect::Test::Pkg::Qux',
291            method  => 'foo_bar',
292            type    => 'before',
293            code    => \&global_before,
294        },
295        {
296            name    => 'Global scope Qux foo_bar after hook',
297            package => 'RPC::ExtDirect::Test::Pkg::Qux',
298            method  => 'foo_bar',
299            type    => 'after',
300            code    => \&global_after,
301        },
302        {
303            name    => 'Global scope Qux foo_baz before hook',
304            package => 'RPC::ExtDirect::Test::Pkg::Qux',
305            method  => 'foo_baz',
306            type    => 'before',
307            code    => \&global_before,
308        },
309        {
310            name    => 'Global scope Qux foo_baz after hook',
311            package => 'RPC::ExtDirect::Test::Pkg::Qux',
312            method  => 'foo_baz',
313            type    => 'after',
314            code    => \&global_after,
315        },
316        {
317            name    => 'Global scope Qux bar_foo before hook',
318            package => 'RPC::ExtDirect::Test::Pkg::Qux',
319            method  => 'bar_foo',
320            type    => 'before',
321            code    => \&global_before,
322        },
323        {
324            name    => 'Global scope Qux bar_foo after hook',
325            package => 'RPC::ExtDirect::Test::Pkg::Qux',
326            method  => 'bar_foo',
327            type    => 'after',
328            code    => \&global_after,
329        },
330        {
331            name    => 'Global scope Qux bar_bar before hook',
332            package => 'RPC::ExtDirect::Test::Pkg::Qux',
333            method  => 'bar_bar',
334            type    => 'before',
335            code    => \&global_before,
336        },
337        {
338            name    => 'Global scope Qux bar_bar after hook',
339            package => 'RPC::ExtDirect::Test::Pkg::Qux',
340            method  => 'bar_bar',
341            type    => 'after',
342            code    => \&global_after,
343        },
344        {
345            name    => 'Global scope Qux bar_baz before hook',
346            package => 'RPC::ExtDirect::Test::Pkg::Qux',
347            method  => 'bar_baz',
348            type    => 'before',
349            code    => \&global_before,
350        },
351        {
352            name    => 'Global scope Qux bar_baz after hook',
353            package => 'RPC::ExtDirect::Test::Pkg::Qux',
354            method  => 'bar_baz',
355            type    => 'after',
356            code    => \&global_after,
357        },
358    ],
359}
360