File Coverage

blib/lib/Test/Stream/Exporter.pm
Criterion Covered Total %
statement 95 95 100.0
branch 37 38 97.3
condition 17 18 94.4
subroutine 17 17 100.0
pod 5 5 100.0
total 171 173 98.8


line stmt bran cond sub pod time code
1             package Test::Stream::Exporter;
2 109     109   758 use strict;
  109         120  
  109         2735  
3 109     109   338 use warnings;
  109         112  
  109         2087  
4              
5 109     109   37399 use Test::Stream::Exporter::Meta();
  109         224  
  109         1831  
6              
7 109     109   375 use Scalar::Util qw/reftype/;
  109         98  
  109         3977  
8              
9 109     109   336 use Carp qw/croak confess/;
  109         114  
  109         4080  
10              
11 109     109   487 BEGIN { Test::Stream::Exporter::Meta->new(__PACKAGE__) };
12              
13             sub import {
14 1575     1575   2144 my $class = shift;
15 1575         2082 my $caller = caller;
16              
17 1575         4012 Test::Stream::Exporter::Meta->new($caller);
18 1575         2902 export_from($class => $caller, \@_);
19             }
20              
21             sub unimport {
22 1574     1574   2709 my ($class, @list) = @_;
23 1574         2111 my $pkg = caller;
24              
25 1574 100       4984 @list = qw/export exports default_export default_exports export_from/ unless @list;
26              
27 1574         5215 for my $name (@list) {
28 7866   100     357980 my $ref = $pkg->can($name) || next;
29 109     109   426 no strict 'refs';
  109         122  
  109         50776  
30 2072 100       2579 next unless $ref == \&{$name};
  2072         7445  
31 2071         2633 local *GLOBCLONE = *{"$pkg\::$name"};
  2071         6323  
32 2071         1656 my $stash = \%{"${pkg}\::"};
  2071         3396  
33 2071         3827 delete $stash->{$name};
34 2071         3162 for my $slot (qw/HASH SCALAR ARRAY IO FORMAT/) {
35 10355 100       18031 *{"$pkg\::$name"} = *GLOBCLONE{$slot} if defined *GLOBCLONE{$slot};
  2071         8018  
36             }
37             }
38             }
39              
40             ###############
41             # Exported Methods
42             ###############
43              
44             exports(qw/export_to/);
45              
46             default_export( import => sub {
47 4619 50   4619   12217 return unless Test::Stream::Exporter::Meta::get($_[0]);
48 4619         5455 my $class = shift;
49 4619         5325 my $caller = caller;
50 4619         8383 export_from($class => $caller, \@_);
51             });
52              
53             sub export_to {
54 7142     7142 1 8073 my ($from, $dest, $args) = @_;
55              
56 7142         18663 my $meta = Test::Stream::Exporter::Meta->new($from);
57 7142         12793 my $exports = $meta->exports;
58              
59 7142         5817 my @imports;
60             my %exclude;
61 7142 100 100     23525 if ($args && @$args) {
62 6301         5085 my %seen;
63 6301         4888 my $all = 0;
64 6301         4466 my $def = 0;
65 6301         8605 for my $item (@$args) {
66             # Keep track of what we have seen so that things do not get
67             # re-added by '-all'. We do not want to skip things already seen
68             # here though as people may alias a single sub to multiple names.
69 11858         13337 $seen{$item}++;
70 11858 100 100     40899 if (!ref($item) && $item =~ m/^-(all|default)$/) {
    100          
71 111         259 my $tag = $1;
72 111 100       302 $all++ if $tag eq 'all';
73 111 100       321 $def++ if $tag eq 'default';
74             }
75             elsif ($item =~ m/^!(.*)$/) {
76 2         4 $exclude{$1}++;
77             }
78             else {
79 11745         15759 push @imports => $item;
80             }
81             }
82 6301 100       9315 push @imports => grep { !$seen{$_}++ } @{$meta->default} if $def;
  2         4  
  1         3  
83 6301 100       13037 push @imports => grep { !$seen{$_}++ } keys %$exports if $all;
  2910         3512  
84             }
85             else {
86 841         729 @imports = @{$meta->default};
  841         1560  
87             }
88              
89 7142         13517 while (my $export = shift @imports) {
90 18681 100       29821 my $ref = $exports->{$export}
91             or croak qq{"$export" is not exported by the $from module};
92              
93 18680         12778 my $name = $export;
94 18680 100 100     42766 if (@imports && ref $imports[0]) {
95 64         75 my $options = shift @imports;
96 64 100       319 croak "import options must be specified as a hashref, got '$options'"
97             unless reftype($options) eq 'HASH';
98              
99 63   100     282 my $prefix = delete $options->{'-prefix'} || "";
100 63   100     212 my $postfix = delete $options->{'-postfix'} || "";
101 63   66     151 my $infix = delete $options->{'-as'} || $export;
102              
103             croak "'$_' is not a valid export option for export '$export'"
104 63         227 for keys %$options;
105              
106 62         145 $name = join '' => $prefix, $infix, $postfix;
107             }
108              
109 18678 100       23737 next if $exclude{$export};
110              
111 109     109   465 no strict 'refs';
  109         136  
  109         11010  
112 18676         11631 *{"$dest\::$name"} = $ref;
  18676         602877  
113             }
114             }
115              
116             ###############
117             # Exported Functions
118             ###############
119              
120             default_exports(qw/export exports default_export default_exports/);
121             exports(qw/export_from/);
122              
123             # There is no implementation difference, but different names make the purpose
124             # of each use more clear.
125 109     109   19576 BEGIN { *export_from = \&export_to }
126              
127             sub export {
128 801     801 1 1106 my $caller = caller;
129              
130 801 100       1511 my $meta = Test::Stream::Exporter::Meta::get($caller)
131             or confess "$caller is not an exporter!?";
132              
133             # Only the first 2 args are used.
134 800         1948 $meta->add(0, @_);
135             }
136              
137             sub exports {
138 1033     1033 1 1940 my $caller = caller;
139              
140 1033 100       2289 my $meta = Test::Stream::Exporter::Meta::get($caller)
141             or confess "$caller is not an exporter!?";
142              
143 1032         3181 $meta->add_bulk(0, @_);
144             }
145              
146             sub default_export {
147 346     346 1 644 my $caller = caller;
148              
149 346 100       735 my $meta = Test::Stream::Exporter::Meta::get($caller)
150             or confess "$caller is not an exporter!?";
151              
152             # Only the first 2 args are used.
153 345         1091 $meta->add(1, @_);
154             }
155              
156             sub default_exports {
157 826     826 1 1444 my $caller = caller;
158              
159 826 100       1732 my $meta = Test::Stream::Exporter::Meta::get($caller)
160             or confess "$caller is not an exporter!?";
161              
162 825         2408 $meta->add_bulk(1, @_);
163             }
164              
165             1;
166              
167             __END__