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   1112 use strict;
  109         202  
  109         2784  
3 109     109   577 use warnings;
  109         181  
  109         2707  
4              
5 109     109   60708 use Test::Stream::Exporter::Meta;
  109         342  
  109         3298  
6              
7 109     109   551 use Scalar::Util qw/reftype/;
  109         180  
  109         4982  
8              
9 109     109   529 use Carp qw/croak confess/;
  109         188  
  109         5457  
10              
11 109     109   473 BEGIN { Test::Stream::Exporter::Meta->new(__PACKAGE__) };
12              
13             sub import {
14 1575     1575   3145 my $class = shift;
15 1575         2917 my $caller = caller;
16              
17 1575         6510 Test::Stream::Exporter::Meta->new($caller);
18 1575         4185 export_from($class => $caller, \@_);
19             }
20              
21             sub unimport {
22 1574     1574   3965 my ($class, @list) = @_;
23 1574         2960 my $pkg = caller;
24              
25 1574 100       6733 @list = qw/export exports default_export default_exports export_from/ unless @list;
26              
27 1574         3739 for my $name (@list) {
28 7866   100     528399 my $ref = $pkg->can($name) || next;
29 109     109   565 no strict 'refs';
  109         242  
  109         70461  
30 5669 100       7734 next unless $ref == \&{$name};
  5669         19574  
31 5668         8182 local *GLOBCLONE = *{"$pkg\::$name"};
  5668         20134  
32 5668         7114 my $stash = \%{"${pkg}\::"};
  5668         14569  
33 5668         15979 delete $stash->{$name};
34 5668         11917 for my $slot (qw/HASH SCALAR ARRAY IO FORMAT/) {
35 28340 100       74236 *{"$pkg\::$name"} = *GLOBCLONE{$slot} if defined *GLOBCLONE{$slot};
  5668         29505  
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   28576 return unless Test::Stream::Exporter::Meta::get($_[0]);
48 6119         12308 my $class = shift;
49 6119         10824 my $caller = caller;
50 6119         15639 export_from($class => $caller, \@_);
51             });
52              
53             sub export_to {
54 8636     8636 1 15595 my ($from, $dest, $args) = @_;
55              
56 8636         38058 my $meta = Test::Stream::Exporter::Meta->new($from);
57 8636         25292 my $exports = $meta->exports;
58              
59 8636         11906 my @imports;
60 8636 100 100     39491 if ($args && @$args) {
61 4331         5588 my %seen;
62 4331         5605 my $all = 0;
63 4331         5501 my $def = 0;
64 4331         8400 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         15597 $seen{$item}++;
69 7751 100 100     33658 if (!ref($item) && $item =~ m/^-(all|default)$/) {
70 213         674 my $tag = $1;
71 213 100       815 $all++ if $tag eq 'all';
72 213 100       862 $def++ if $tag eq 'default';
73             }
74             else {
75 7538         16674 push @imports => $item;
76             }
77             }
78 4331 100       9602 push @imports => grep { !$seen{$_}++ } @{$meta->default} if $def;
  2         7  
  1         4  
79 4331 100       13480 push @imports => grep { !$seen{$_}++ } keys %$exports if $all;
  3480         8303  
80             }
81             else {
82 4305         5780 @imports = @{$meta->default};
  4305         11836  
83             }
84              
85 8636         67786 while (my $export = shift @imports) {
86 22341 100       57511 my $ref = $exports->{$export}
87             or croak qq{"$export" is not exported by the $from module};
88              
89 22340         28387 my $name = $export;
90 22340 100 100     82455 if (@imports && ref $imports[0]) {
91 64         116 my $options = shift @imports;
92 64 100       424 croak "import options must be specified as a hashref, got '$options'"
93             unless reftype($options) eq 'HASH';
94              
95 63   100     357 my $prefix = delete $options->{'-prefix'} || "";
96 63   100     313 my $postfix = delete $options->{'-postfix'} || "";
97 63   66     236 my $infix = delete $options->{'-as'} || $export;
98              
99             croak "'$_' is not a valid export option for export '$export'"
100 63         315 for keys %$options;
101              
102 62         195 $name = join '' => $prefix, $infix, $postfix;
103             }
104              
105 109     109   643 no strict 'refs';
  109         212  
  109         14425  
106 22338         27868 *{"$dest\::$name"} = $ref;
  22338         891700  
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   29106 BEGIN { *export_from = \&export_to }
120              
121             sub export {
122 801     801 1 1806 my $caller = caller;
123              
124 801 100       2179 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         2903 $meta->add(0, @_);
129             }
130              
131             sub exports {
132 1033     1033 1 2770 my $caller = caller;
133              
134 1033 100       3483 my $meta = Test::Stream::Exporter::Meta::get($caller)
135             or confess "$caller is not an exporter!?";
136              
137 1032         4623 $meta->add_bulk(0, @_);
138             }
139              
140             sub default_export {
141 346     346 1 814 my $caller = caller;
142              
143 346 100       1029 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         1443 $meta->add(1, @_);
148             }
149              
150             sub default_exports {
151 826     826 1 2082 my $caller = caller;
152              
153 826 100       2460 my $meta = Test::Stream::Exporter::Meta::get($caller)
154             or confess "$caller is not an exporter!?";
155              
156 825         3506 $meta->add_bulk(1, @_);
157             }
158              
159             1;
160              
161             __END__