File Coverage

blib/lib/WWW/HTMLTagAttributeCounter.pm
Criterion Covered Total %
statement 50 57 87.7
branch 15 22 68.1
condition 3 5 60.0
subroutine 11 12 91.6
pod 3 3 100.0
total 82 99 82.8


line stmt bran cond sub pod time code
1             package WWW::HTMLTagAttributeCounter;
2              
3 1     1   133935 use warnings;
  1         2  
  1         30  
4 1     1   5 use strict;
  1         2  
  1         43  
5              
6             our $VERSION = '0.0104';
7              
8 1     1   5 use LWP::UserAgent;
  1         6  
  1         20  
9 1     1   6 use HTML::TokeParser::Simple;
  1         2  
  1         43  
10 1     1   5 use overload q|""| => sub { shift->result_readable };
  1     2   9  
  1         18  
  2         92  
11              
12 1     1   55 use base 'Class::Accessor::Grouped';
  1         2  
  1         732  
13             __PACKAGE__->mk_group_accessors( simple => qw/
14             ua
15             result
16             error
17             /);
18              
19             sub new {
20 1     1 1 1108 my ( $class, %args ) = @_;
21              
22 1   33     17 $args{ua} ||= LWP::UserAgent->new(
23             timeout => 30,
24             agent => 'Opera 9.5',
25             );
26              
27 1         4154 my $self = bless {}, $class;
28 1         10 $self->ua( $args{ua} );
29              
30 1         337 return $self;
31             }
32              
33             sub count {
34 4     4 1 3862 my ( $self, $where, $what, $type, ) = @_;
35              
36             $self->$_(undef)
37 4         25 for qw/error result/;
38              
39 4 100       404 $what = [ $what ]
40             unless ref $what eq 'ARRAY';
41              
42 4 100       13 defined $type
43             or $type = 'tag';
44              
45 4         6 my $content;
46 4 50       12 if ( ref $where eq 'SCALAR' ) {
47 4         7 $content = $$where;
48             }
49             else {
50 0 0       0 $where =~ m{^https?://}
51             or $where = "http://$where";
52              
53 0         0 my $response = $self->ua->get( $where );
54              
55 0 0       0 $response->is_success
56             or return $self->_set_error( $response );
57              
58 0         0 $content = $response->decoded_content;
59             }
60              
61 4         12 return $self->result( $self->_count( $what, $type, $content ) );
62             }
63              
64             sub result_readable {
65 3     3 1 11 my $result = shift->result;
66              
67 3         4 my @out;
68 3         17 for ( sort keys %$result ) {
69 9         21 push @out, "$result->{$_} $_";
70             }
71              
72 3 50       11 return $out[0]
73             if @out == 1;
74              
75 3         38 return (join q|, |, @out[0..$#out-1]) . ' and ' . $out[-1];
76             }
77              
78             sub _count {
79 4     4   7 my ( $self, $what, $type, $content ) = @_;
80              
81 4         60 my $p = HTML::TokeParser::Simple->new( \$content );
82 4         611 my $count = {};
83 4         17 while ( my $t = $p->get_token ) {
84             next
85 52 100       2320 unless $t->is_start_tag;
86              
87 16 100       105 if ( $type eq 'tag' ) {
    50          
88 12         20 for ( @$what ) {
89 28 100       248 $t->is_start_tag($_)
90             and $count->{$_}++;
91             }
92             }
93             elsif ( $type eq 'attr') {
94 4         6 for ( @$what ) {
95 4 100       14 defined $t->get_attr($_)
96             and $count->{$_}++;
97             }
98             }
99             }
100              
101             defined $count->{$_}
102             or $count->{$_} = 0
103 4   100     97 for @$what;
104              
105 4         45 return $count;
106             }
107              
108             sub _set_error {
109 0     0     my ( $self, $response ) = @_;
110 0           $self->error('Network error: ' . $response->status_line );
111 0           return;
112             }
113              
114             1;
115             __END__