File Coverage

blib/lib/Test/Stream/Exporter.pm
Criterion Covered Total %
statement 93 93 100.0
branch 34 34 100.0
condition 17 18 94.4
subroutine 17 17 100.0
pod 5 5 100.0
total 166 167 99.4


line stmt bran cond sub pod time code
1             package Test::Stream::Exporter;
2 109     109   1241 use strict;
  109         200  
  109         3034  
3 109     109   535 use warnings;
  109         186  
  109         2724  
4              
5 109     109   65203 use Test::Stream::Exporter::Meta;
  109         375  
  109         3373  
6              
7 109     109   588 use Scalar::Util qw/reftype/;
  109         226  
  109         5190  
8              
9 109     109   526 use Carp qw/croak confess/;
  109         190  
  109         5601  
10              
11 109     109   477 BEGIN { Test::Stream::Exporter::Meta->new(__PACKAGE__) };
12              
13             sub import {
14 1575     1575   3326 my $class = shift;
15 1575         2936 my $caller = caller;
16              
17 1575         6305 Test::Stream::Exporter::Meta->new($caller);
18 1575         4266 export_from($class => $caller, \@_);
19             }
20              
21             sub unimport {
22 1574     1574   3929 my ($class, @list) = @_;
23 1574         3010 my $pkg = caller;
24              
25 1574 100       6631 @list = qw/export exports default_export default_exports export_from/ unless @list;
26              
27 1574         3662 for my $name (@list) {
28 7866   100     530690 my $ref = $pkg->can($name) || next;
29 109     109   555 no strict 'refs';
  109         214  
  109         70293  
30 5669 100       8064 next unless $ref == \&{$name};
  5669         19490  
31 5668         8321 local *GLOBCLONE = *{"$pkg\::$name"};
  5668         20529  
32 5668         7098 my $stash = \%{"${pkg}\::"};
  5668         17585  
33 5668         14039 delete $stash->{$name};
34 5668         10814 for my $slot (qw/HASH SCALAR ARRAY IO FORMAT/) {
35 28340 100       74353 *{"$pkg\::$name"} = *GLOBCLONE{$slot} if defined *GLOBCLONE{$slot};
  5668         28597  
36             }
37             }
38             }
39              
40             ###############
41             # Exported Methods
42             ###############
43              
44             exports(qw/export_to/);
45              
46             default_export( import => sub {
47 8123 100   8123   28680 return unless Test::Stream::Exporter::Meta::get($_[0]);
48 6119         12064 my $class = shift;
49 6119         10436 my $caller = caller;
50 6119         16058 export_from($class => $caller, \@_);
51             });
52              
53             sub export_to {
54 8636     8636 1 15631 my ($from, $dest, $args) = @_;
55              
56 8636         37893 my $meta = Test::Stream::Exporter::Meta->new($from);
57 8636         25160 my $exports = $meta->exports;
58              
59 8636         11750 my @imports;
60 8636 100 100     39660 if ($args && @$args) {
61 4331         5480 my %seen;
62 4331         5585 my $all = 0;
63 4331         5332 my $def = 0;
64 4331         8556 for my $item (@$args) {
65             # Keep track of what we have seen so that things do not get
66             # re-added by '-all'. We do not want to skip things already seen
67             # here though as people may alias a single sub to multiple names.
68 7751         15279 $seen{$item}++;
69 7751 100 100     37716 if (!ref($item) && $item =~ m/^-(all|default)$/) {
70 213         703 my $tag = $1;
71 213 100       839 $all++ if $tag eq 'all';
72 213 100       852 $def++ if $tag eq 'default';
73             }
74             else {
75 7538         16596 push @imports => $item;
76             }
77             }
78 4331 100       9548 push @imports => grep { !$seen{$_}++ } @{$meta->default} if $def;
  2         8  
  1         5  
79 4331 100       13574 push @imports => grep { !$seen{$_}++ } keys %$exports if $all;
  3480         8291  
80             }
81             else {
82 4305         5676 @imports = @{$meta->default};
  4305         12657  
83             }
84              
85 8636         67131 while (my $export = shift @imports) {
86 22341 100       57847 my $ref = $exports->{$export}
87             or croak qq{"$export" is not exported by the $from module};
88              
89 22340         28256 my $name = $export;
90 22340 100 100     82716 if (@imports && ref $imports[0]) {
91 64         123 my $options = shift @imports;
92 64 100       446 croak "import options must be specified as a hashref, got '$options'"
93             unless reftype($options) eq 'HASH';
94              
95 63   100     364 my $prefix = delete $options->{'-prefix'} || "";
96 63   100     317 my $postfix = delete $options->{'-postfix'} || "";
97 63   66     221 my $infix = delete $options->{'-as'} || $export;
98              
99             croak "'$_' is not a valid export option for export '$export'"
100 63         323 for keys %$options;
101              
102 62         196 $name = join '' => $prefix, $infix, $postfix;
103             }
104              
105 109     109   627 no strict 'refs';
  109         215  
  109         14323  
106 22338         27957 *{"$dest\::$name"} = $ref;
  22338         896784  
107             }
108             }
109              
110             ###############
111             # Exported Functions
112             ###############
113              
114             default_exports(qw/export exports default_export default_exports/);
115             exports(qw/export_from/);
116              
117             # There is no implementation difference, but different names make the purpose
118             # of each use more clear.
119 109     109   28192 BEGIN { *export_from = \&export_to }
120              
121             sub export {
122 801     801 1 1688 my $caller = caller;
123              
124 801 100       2218 my $meta = Test::Stream::Exporter::Meta::get($caller)
125             or confess "$caller is not an exporter!?";
126              
127             # Only the first 2 args are used.
128 800         2926 $meta->add(0, @_);
129             }
130              
131             sub exports {
132 1033     1033 1 2742 my $caller = caller;
133              
134 1033 100       3336 my $meta = Test::Stream::Exporter::Meta::get($caller)
135             or confess "$caller is not an exporter!?";
136              
137 1032         4542 $meta->add_bulk(0, @_);
138             }
139              
140             sub default_export {
141 346     346 1 849 my $caller = caller;
142              
143 346 100       1072 my $meta = Test::Stream::Exporter::Meta::get($caller)
144             or confess "$caller is not an exporter!?";
145              
146             # Only the first 2 args are used.
147 345         1450 $meta->add(1, @_);
148             }
149              
150             sub default_exports {
151 826     826 1 2022 my $caller = caller;
152              
153 826 100       2565 my $meta = Test::Stream::Exporter::Meta::get($caller)
154             or confess "$caller is not an exporter!?";
155              
156 825         3442 $meta->add_bulk(1, @_);
157             }
158              
159             1;
160              
161             __END__