File Coverage

blib/lib/PRANG/Graph/Quantity.pm
Criterion Covered Total %
statement 40 46 86.9
branch 13 20 65.0
condition 13 17 76.4
subroutine 7 7 100.0
pod 0 5 0.0
total 73 95 76.8


line stmt bran cond sub pod time code
1              
2             package PRANG::Graph::Quantity;
3             $PRANG::Graph::Quantity::VERSION = '0.21';
4 11     11   1769 use Moose;
  11         29  
  11         108  
5 11     11   76499 use MooseX::Params::Validate;
  11         37  
  11         94  
6              
7             has 'min' =>
8             is => "ro",
9             isa => "Int",
10             predicate => "has_min",
11             ;
12              
13             has 'max' =>
14             is => "ro",
15             isa => "Int",
16             predicate => "has_max",
17             ;
18              
19             has 'child' =>
20             is => "ro",
21             isa => "PRANG::Graph::Node",
22             required => 1,
23             ;
24              
25             has 'attrName' =>
26             is => "ro",
27             isa => "Str",
28             required => 1,
29             ;
30              
31 136     136 0 639 sub accept_many {1}
32              
33             sub accept {
34 562     562 0 908 my $self = shift;
35 562         2790 my ( $node, $ctx, $lax ) = pos_validated_list(
36             \@_,
37             { isa => 'XML::LibXML::Node' },
38             { isa => 'PRANG::Graph::Context' },
39             { isa => 'Bool', optional => 1 },
40             );
41            
42 562         177655 my $found = $ctx->quant_found;
43 562         14469 my $ok = defined $self->child->node_ok($node, $ctx);
44 562 100       1816 return if not $ok;
45 277 50       6970 my ($key, $value, $x, $ns) = $self->child->accept($node, $ctx, $lax)
46             or $ctx->exception(
47             "internal error: node ok, but then not accepted?",
48             $node,
49             );
50 258         583 $found++;
51 258         6709 $ctx->quant_found($found);
52 258 50 66     7240 if ( $self->has_max and $found > $self->max ) {
53 0         0 $ctx->exception("node appears too many times", $node);
54             }
55 258         1405 ($key, $value, $x, $ns);
56             }
57              
58             sub complete {
59 488     488 0 799 my $self = shift;
60 488         1829 my ( $ctx ) = pos_validated_list(
61             \@_,
62             { isa => 'PRANG::Graph::Context' },
63             );
64            
65 488         80247 my $found = $ctx->quant_found;
66 488   66     13799 return !( $self->has_min and $found < $self->min );
67             }
68              
69             sub expected {
70 2     2 0 7 my $self = shift;
71 2         9 my ( $ctx ) = pos_validated_list(
72             \@_,
73             { isa => 'PRANG::Graph::Context' },
74             );
75            
76 2         583 my $desc;
77 2 50       64 if ( $self->has_min ) {
78 0 0       0 if ( $self->has_max ) {
79 0         0 $desc = "between ".$self->min." and ".$self->max;
80             }
81             else {
82 0         0 $desc = "at least ".$self->min;
83             }
84             }
85             else {
86 2 50       71 if ( $self->has_max ) {
87 2         66 $desc = "optionally up to ".$self->max;
88             }
89             else {
90 0         0 $desc = "zero or more";
91             }
92             }
93 2         50 my @expected = $self->child->expected($ctx);
94 2         17 return("($desc of: ", @expected, ")");
95             }
96              
97             sub output {
98 401     401 0 684 my $self = shift;
99 401         1874 my ( $item, $node, $ctx ) = pos_validated_list(
100             \@_,
101             { isa => 'Object' },
102             { isa => 'XML::LibXML::Element' },
103             { isa => 'PRANG::Graph::Context' },
104             );
105            
106 401         124565 my $attrName = $self->attrName;
107 401         2839 my $val = $item->$attrName;
108 401 100 100     12730 if ( $self->has_max and $self->max == 1 ) {
109              
110             # this is an 'optional'-type thingy
111 346 100       1537 if ( defined $val ) {
112 64         1590 $self->child->output($item,$node,$ctx,value => $val);
113             }
114             }
115             else {
116              
117             # this is an arrayref-type thingy
118 55 100 100     730 if ( !$val and !$self->has_min ) {
    50 50        
      66        
119              
120             # ok, that's fine
121             }
122             elsif ( $val and (ref($val)||"") ne "ARRAY" ) {
123              
124             # that's not
125 0         0 die "item $item / slot $attrName is $val, not"
126             ."an ArrayRef";
127             }
128             else {
129 54         248 for ( my $i = 0; $i <= $#$val; $i++) {
130 103         7168 $ctx->quant_found($i+1);
131 103         2587 $self->child->output(
132             $item,$node,$ctx,
133             value => $val->[$i],
134             slot => $i,
135             );
136             }
137             }
138             }
139             }
140              
141             with 'PRANG::Graph::Node';
142              
143             1;
144              
145             __END__
146              
147             =head1 NAME
148              
149             PRANG::Graph::Quantity - a bounded quantity of graph nodes
150              
151             =head1 SYNOPSIS
152              
153             See L<PRANG::Graph::Meta::Element> source and
154             L<PRANG::Graph::Node> for examples and information.
155              
156             =head1 DESCRIPTION
157              
158             This graph node specifies that the XML graph at this point has a
159             quantity of text nodes, elements or element choices depending on the
160             type of entries in the B<child> property.
161              
162             If the quantity is always 1, that is, the element is required and may
163             only appear one, then the element does not have one of these objects
164             in their graph.
165              
166             =head1 ATTRIBUTES
167              
168             =over
169              
170             =item B<PRANG::Graph::Node child>
171              
172             The B<child> property provides the next portion of the XML Graph.
173             Depending on the type of entry, it will accept and emit nodes in a
174             particular way.
175              
176             Entries must be one of L<PRANG::Graph::Choice>,
177             L<PRANG::Graph::Element>, or L<PRANG::Graph::Text>.
178              
179             =item B<Int min>
180              
181             =item B<Int max>
182              
183             Bounds on the number of times this graph node will match.
184              
185             =item B<attrName>
186              
187             Used when emitting; specifies the method to call to retrieve the item
188             to be output.
189              
190             =back
191              
192             =head1 SEE ALSO
193              
194             L<PRANG::Graph::Meta::Class>, L<PRANG::Graph::Meta::Element>,
195             L<PRANG::Graph::Context>, L<PRANG::Graph::Node>
196              
197             Lower order L<PRANG::Graph::Node> types:
198              
199             L<PRANG::Graph::Choice>, L<PRANG::Graph::Element>,
200             L<PRANG::Graph::Text>
201              
202             =head1 AUTHOR AND LICENCE
203              
204             Development commissioned by NZ Registry Services, and carried out by
205             Catalyst IT - L<http://www.catalyst.net.nz/>
206              
207             Copyright 2009, 2010, NZ Registry Services. This module is licensed
208             under the Artistic License v2.0, which permits relicensing under other
209             Free Software licenses.
210              
211             =cut
212