File Coverage

blib/lib/Perl/Critic/PolicyParameter/Behavior/Enumeration.pm
Criterion Covered Total %
statement 57 57 100.0
branch 15 16 93.7
condition 12 12 100.0
subroutine 10 10 100.0
pod 2 2 100.0
total 96 97 98.9


line stmt bran cond sub pod time code
1             package Perl::Critic::PolicyParameter::Behavior::Enumeration;
2              
3 40     40   542 use 5.010001;
  40         119  
4 40     40   169 use strict;
  40         60  
  40         725  
5 40     40   128 use warnings;
  40         58  
  40         1725  
6              
7             use Perl::Critic::Exception::Fatal::PolicyDefinition
8 40     40   290 qw( throw_policy_definition );
  40         67  
  40         2304  
9 40     40   202 use Perl::Critic::Utils qw( :characters words_from_string hashify );
  40         56  
  40         2020  
10              
11 40     40   7991 use parent qw{ Perl::Critic::PolicyParameter::Behavior };
  40         87  
  40         245  
12              
13             our $VERSION = '1.156';
14              
15             #-----------------------------------------------------------------------------
16              
17             sub initialize_parameter {
18 746     746 1 1943 my (undef, $parameter, $specification) = @_;
19              
20             my $valid_values = $specification->{enumeration_values}
21 746 100       2257 or throw_policy_definition
22             'No enumeration_values given for '
23             . $parameter->get_name()
24             . $PERIOD;
25 745 100       2237 ref $valid_values eq 'ARRAY'
26             or throw_policy_definition
27             'The value given for enumeration_values for '
28             . $parameter->get_name()
29             . ' is not an array reference.';
30 744 100       1178 scalar @{$valid_values} > 1
  744         2187  
31             or throw_policy_definition
32             'There were not at least two valid values given for'
33             . ' enumeration_values for '
34             . $parameter->get_name()
35             . $PERIOD;
36              
37             # Unfortunately, this has to be a reference, rather than a regular hash,
38             # due to a problem in Devel::Cycle
39             # (http://rt.cpan.org/Ticket/Display.html?id=25360) which causes
40             # t/92_memory_leaks.t to fall over.
41 742         1206 my $value_lookup = { hashify( @{$valid_values} ) };
  742         2376  
42 742         2345 $parameter->_get_behavior_values()->{enumeration_values} = $value_lookup;
43              
44             my $allow_multiple_values =
45 742         1309 $specification->{enumeration_allow_multiple_values};
46              
47 742 100       1581 if ($allow_multiple_values) {
48             $parameter->_set_parser(
49             sub {
50             # Normally bad thing, obscuring a variable in an outer scope
51             # with a variable with the same name is being done here in
52             # order to remain consistent with the parser function interface.
53 462     462   960 my ($policy, $parameter, $config_string) = @_; ## no critic(Variables::ProhibitReusedNames)
54              
55 462         865 my @potential_values;
56 462   100     1821 my $value_string = $config_string // $parameter->get_default_string();
57              
58 462 100       1051 if ( defined $value_string ) {
59 461         1386 @potential_values = words_from_string($value_string);
60              
61             my @bad_values =
62 461         922 grep { not exists $value_lookup->{$_} } @potential_values;
  467         1045  
63 461 100       992 if (@bad_values) {
64             $policy->throw_parameter_value_exception(
65             $parameter->get_name(),
66             $value_string,
67             undef,
68             q{contains invalid values: }
69             . join (q{, }, @bad_values)
70             . q{. Allowed values are: }
71 1         5 . join (q{, }, sort keys %{$value_lookup})
  1         29  
72             . qq{.\n},
73             );
74             }
75             }
76              
77 461         1062 my %actual_values = hashify(@potential_values);
78              
79 461         1763 $policy->__set_parameter_value($parameter, \%actual_values);
80              
81 461         915 return;
82             }
83 462         2489 );
84             } else {
85             $parameter->_set_parser(
86             sub {
87             # Normally bad thing, obscuring a variable in an outer scope
88             # with a variable with the same name is being done here in
89             # order to remain consistent with the parser function interface.
90 280     280   620 my ($policy, $parameter, $config_string) = @_; ## no critic(Variables::ProhibitReusedNames)
91              
92 280   100     996 my $value_string = $config_string // $parameter->get_default_string();
93              
94 280 100 100     1765 if (
      100        
95             defined $value_string
96             and $EMPTY ne $value_string
97             and not defined $value_lookup->{$value_string}
98             ) {
99             $policy->throw_parameter_value_exception(
100             $parameter->get_name(),
101             $value_string,
102             undef,
103             q{is not one of the allowed values: }
104 2         7 . join (q{, }, sort keys %{$value_lookup})
  2         31  
105             . qq{.\n},
106             );
107             }
108              
109 278         1019 $policy->__set_parameter_value($parameter, $value_string);
110              
111 278         471 return;
112             }
113 280         1460 );
114             }
115              
116 742         1494 return;
117             }
118              
119             #-----------------------------------------------------------------------------
120              
121             sub generate_parameter_description {
122 72     72 1 158 my (undef, $parameter) = @_;
123              
124 72         178 my $description = $parameter->_get_description_with_trailing_period();
125 72 50       141 if ( $description ) {
126 72         129 $description .= qq{\n};
127             }
128              
129 72         122 my %values = %{$parameter->_get_behavior_values()->{enumeration_values}};
  72         167  
130             return
131 72         579 $description
132             . 'Valid values: '
133             . join (', ', sort keys %values)
134             . $PERIOD;
135             }
136              
137             #-----------------------------------------------------------------------------
138              
139             1;
140              
141             __END__
142              
143             #-----------------------------------------------------------------------------
144              
145             =pod
146              
147             =for stopwords
148              
149             =head1 NAME
150              
151             Perl::Critic::PolicyParameter::Behavior::Enumeration - Actions appropriate for an enumerated value.
152              
153              
154             =head1 DESCRIPTION
155              
156             Provides a standard set of functionality for an enumerated
157             L<Perl::Critic::PolicyParameter|Perl::Critic::PolicyParameter> so that
158             the developer of a policy does not have to provide it her/himself.
159              
160             NOTE: Do not instantiate this class. Use the singleton instance held
161             onto by
162             L<Perl::Critic::PolicyParameter|Perl::Critic::PolicyParameter>.
163              
164              
165             =head1 INTERFACE SUPPORT
166              
167             This is considered to be a non-public class. Its interface is subject
168             to change without notice.
169              
170              
171             =head1 METHODS
172              
173             =over
174              
175             =item C<initialize_parameter( $parameter, $specification )>
176              
177             Plug in the functionality this behavior provides into the parameter,
178             based upon the configuration provided by the specification.
179              
180             This behavior looks for two configuration items:
181              
182             =over
183              
184             =item enumeration_values
185              
186             Mandatory. The set of valid values for the parameter, as an array
187             reference.
188              
189              
190             =item enumeration_allow_multiple_values
191              
192             Optional, defaults to false. Should the parameter support a single
193             value or accept multiple?
194              
195              
196             =back
197              
198              
199             =item C<generate_parameter_description( $parameter )>
200              
201             Create a description of the parameter, based upon the description on
202             the parameter itself, but enhancing it with information from this
203             behavior.
204              
205             In this specific case, the universe of values is added at the end.
206              
207              
208             =back
209              
210              
211             =head1 AUTHOR
212              
213             Elliot Shank <perl@galumph.com>
214              
215              
216             =head1 COPYRIGHT
217              
218             Copyright (c) 2006-2023 Elliot Shank.
219              
220             This program is free software; you can redistribute it and/or modify
221             it under the same terms as Perl itself. The full text of this license
222             can be found in the LICENSE file included with this module.
223              
224             =cut
225              
226             # Local Variables:
227             # mode: cperl
228             # cperl-indent-level: 4
229             # fill-column: 78
230             # indent-tabs-mode: nil
231             # c-indentation-style: bsd
232             # End:
233             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :