line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
############################################################################## |
2
|
|
|
|
|
|
|
# $URL: http://perlcritic.tigris.org/svn/perlcritic/tags/Test-Perl-Critic-Progressive-0.03/lib/Test/Perl/Critic/Progressive.pm $ |
3
|
|
|
|
|
|
|
# $Date: 2008-07-27 16:01:56 -0700 (Sun, 27 Jul 2008) $ |
4
|
|
|
|
|
|
|
# $Author: thaljef $ |
5
|
|
|
|
|
|
|
# $Revision: 2620 $ |
6
|
|
|
|
|
|
|
############################################################################## |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
package Test::Perl::Critic::Progressive; |
9
|
|
|
|
|
|
|
|
10
|
2
|
|
|
2
|
|
27546
|
use 5.006001; |
|
2
|
|
|
|
|
9
|
|
|
2
|
|
|
|
|
93
|
|
11
|
|
|
|
|
|
|
|
12
|
2
|
|
|
2
|
|
13
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
73
|
|
13
|
2
|
|
|
2
|
|
30
|
use warnings; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
85
|
|
14
|
|
|
|
|
|
|
|
15
|
2
|
|
|
2
|
|
11
|
use Carp qw(croak confess); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
192
|
|
16
|
2
|
|
|
2
|
|
2531
|
use Data::Dumper qw(Dumper); |
|
2
|
|
|
|
|
19569
|
|
|
2
|
|
|
|
|
201
|
|
17
|
2
|
|
|
2
|
|
2000
|
use English qw(-no_match_vars); |
|
2
|
|
|
|
|
7284
|
|
|
2
|
|
|
|
|
15
|
|
18
|
2
|
|
|
2
|
|
872
|
use File::Spec qw(); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
42
|
|
19
|
2
|
|
|
2
|
|
2161
|
use FindBin qw($Bin); |
|
2
|
|
|
|
|
11421
|
|
|
2
|
|
|
|
|
290
|
|
20
|
|
|
|
|
|
|
|
21
|
2
|
|
|
2
|
|
2270
|
use Perl::Critic qw(); |
|
2
|
|
|
|
|
4064604
|
|
|
2
|
|
|
|
|
60
|
|
22
|
2
|
|
|
2
|
|
37
|
use Perl::Critic::Utils qw(policy_short_name policy_long_name); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
120
|
|
23
|
|
|
|
|
|
|
|
24
|
2
|
|
|
2
|
|
12
|
use Test::Builder qw(); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
36
|
|
25
|
|
|
|
|
|
|
|
26
|
2
|
|
|
2
|
|
12
|
use base 'Exporter'; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
3008
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
our $VERSION = '0.03'; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
our @EXPORT_OK = qw( |
35
|
|
|
|
|
|
|
get_critic_args |
36
|
|
|
|
|
|
|
get_history_file |
37
|
|
|
|
|
|
|
get_total_step_size |
38
|
|
|
|
|
|
|
get_step_size_per_policy |
39
|
|
|
|
|
|
|
progressive_critic_ok |
40
|
|
|
|
|
|
|
set_critic_args |
41
|
|
|
|
|
|
|
set_history_file |
42
|
|
|
|
|
|
|
set_total_step_size |
43
|
|
|
|
|
|
|
set_step_size_per_policy |
44
|
|
|
|
|
|
|
); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( all => \@EXPORT_OK ); |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
my $TOTAL_STEP_SIZE = undef; |
51
|
|
|
|
|
|
|
my $DEFAULT_STEP_SIZE = 0; |
52
|
|
|
|
|
|
|
my %STEP_SIZE_PER_POLICY = (); |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
my $HISTORY_FILE = undef; |
55
|
|
|
|
|
|
|
my $DEFAULT_HISTORY_FILE = File::Spec->catfile($Bin, '.perlcritic-history'); |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
my $CRITIC = undef; |
58
|
|
|
|
|
|
|
my %CRITIC_ARGS = (); |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
my $TEST = Test::Builder->new(); |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
63
|
|
|
|
|
|
|
# Public functions |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub progressive_critic_ok { |
66
|
|
|
|
|
|
|
|
67
|
1
|
|
|
1
|
1
|
685
|
my @dirs = @_; |
68
|
1
|
50
|
|
|
|
6
|
if (not @dirs) { |
69
|
0
|
|
|
|
|
0
|
@dirs = _starting_points(); |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
1
|
|
|
|
|
5
|
my @files = _all_code_files( @dirs ); |
73
|
1
|
50
|
|
|
|
251
|
croak qq{No perl files found\n} if not @files; |
74
|
|
|
|
|
|
|
|
75
|
0
|
|
|
|
|
0
|
my $caller = caller; |
76
|
0
|
|
|
|
|
0
|
$TEST->exported_to($caller); |
77
|
0
|
|
|
|
|
0
|
$TEST->plan( tests => 1 ); |
78
|
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
0
|
$CRITIC = Perl::Critic->new( get_critic_args() ); |
80
|
0
|
|
|
|
|
0
|
my @violations = map { $CRITIC->critique($_) } @files; |
|
0
|
|
|
|
|
0
|
|
81
|
|
|
|
|
|
|
|
82
|
0
|
|
|
|
|
0
|
my $ok = _evaluate_test( @violations ); |
83
|
0
|
|
|
|
|
0
|
$TEST->ok($ok, __PACKAGE__); |
84
|
0
|
|
|
|
|
0
|
return $ok; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
88
|
|
|
|
|
|
|
# Pulbic accessor functions |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
sub get_history_file { |
91
|
1
|
50
|
|
1
|
1
|
8
|
return defined $HISTORY_FILE ? |
92
|
|
|
|
|
|
|
$HISTORY_FILE : $DEFAULT_HISTORY_FILE; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub set_history_file { |
98
|
1
|
|
|
1
|
1
|
1000
|
$HISTORY_FILE = shift; |
99
|
1
|
|
|
|
|
3
|
return 1; |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub get_critic_args { |
105
|
0
|
|
|
0
|
1
|
0
|
return %CRITIC_ARGS; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub set_critic_args { |
111
|
0
|
|
|
0
|
1
|
0
|
%CRITIC_ARGS = @_; |
112
|
0
|
|
|
|
|
0
|
return 1; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub get_total_step_size { |
118
|
1
|
50
|
|
1
|
1
|
10
|
return defined $TOTAL_STEP_SIZE ? |
119
|
|
|
|
|
|
|
$TOTAL_STEP_SIZE : $DEFAULT_STEP_SIZE; |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub set_total_step_size { |
126
|
1
|
|
|
1
|
1
|
10
|
$TOTAL_STEP_SIZE = shift; |
127
|
1
|
|
|
|
|
3
|
return 1; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub get_step_size_per_policy { |
133
|
1
|
|
|
1
|
1
|
7
|
return %STEP_SIZE_PER_POLICY; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub set_step_size_per_policy { |
139
|
|
|
|
|
|
|
|
140
|
1
|
|
|
1
|
1
|
515
|
my %args = @_; |
141
|
1
|
|
|
|
|
3
|
my %step_sizes = (); |
142
|
1
|
|
|
|
|
4
|
for my $policy_name ( keys %args ) { |
143
|
1
|
|
|
|
|
9
|
$step_sizes{policy_long_name($policy_name)} = $args{$policy_name}; |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
1
|
|
|
|
|
56
|
%STEP_SIZE_PER_POLICY = %step_sizes; |
147
|
1
|
|
|
|
|
4
|
return 1; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
151
|
|
|
|
|
|
|
# Private functions |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
sub _evaluate_test { |
154
|
|
|
|
|
|
|
|
155
|
0
|
|
|
0
|
|
0
|
my (@viols) = @_; |
156
|
|
|
|
|
|
|
|
157
|
0
|
|
|
|
|
0
|
my $ok = 1; |
158
|
0
|
|
|
|
|
0
|
my $results = {}; |
159
|
|
|
|
|
|
|
|
160
|
0
|
|
|
|
|
0
|
my $history_data = _read_history( get_history_file() ); |
161
|
0
|
|
|
|
|
0
|
my $last_critique = $history_data->[-1]; |
162
|
0
|
|
|
|
|
0
|
my $has_run_before = defined $last_critique; |
163
|
0
|
|
|
|
|
0
|
my $last_total_violations = 0; |
164
|
0
|
|
|
|
|
0
|
my $current_total_violations = 0; |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
|
167
|
0
|
|
|
|
|
0
|
for my $policy ( $CRITIC->policies() ) { |
168
|
|
|
|
|
|
|
|
169
|
0
|
|
|
|
|
0
|
my $policy_name = ref $policy; |
170
|
0
|
|
|
|
|
0
|
my $policy_violations = grep {$_->policy() eq $policy_name} @viols; |
|
0
|
|
|
|
|
0
|
|
171
|
0
|
|
|
|
|
0
|
$results->{$policy_name} = $policy_violations; |
172
|
|
|
|
|
|
|
|
173
|
0
|
|
|
|
|
0
|
my $last_policy_violations = $last_critique->{$policy_name}; |
174
|
0
|
0
|
|
|
|
0
|
next if not defined $last_policy_violations; |
175
|
|
|
|
|
|
|
|
176
|
0
|
|
|
|
|
0
|
$last_total_violations += $last_policy_violations; |
177
|
0
|
|
|
|
|
0
|
$current_total_violations += $policy_violations; |
178
|
|
|
|
|
|
|
|
179
|
0
|
0
|
|
|
|
0
|
my $policy_step_size = defined $STEP_SIZE_PER_POLICY{$policy_name} ? |
180
|
|
|
|
|
|
|
$STEP_SIZE_PER_POLICY{$policy_name} : $DEFAULT_STEP_SIZE; |
181
|
|
|
|
|
|
|
|
182
|
0
|
0
|
|
|
|
0
|
my $target = $policy_step_size > $last_policy_violations ? |
183
|
|
|
|
|
|
|
0 : $last_policy_violations - $policy_step_size; |
184
|
|
|
|
|
|
|
|
185
|
0
|
0
|
|
|
|
0
|
if ( $policy_violations > $target ) { |
186
|
0
|
|
|
|
|
0
|
my $short_name = policy_short_name($policy_name); |
187
|
0
|
|
|
|
|
0
|
my $diagf = '%s: Got %i violation(s). Expected no more than %i.'; |
188
|
0
|
|
|
|
|
0
|
$TEST->diag( sprintf $diagf, $short_name, $policy_violations, $target ); |
189
|
0
|
|
|
|
|
0
|
$ok = 0; # Failed the test! |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
|
195
|
0
|
0
|
|
|
|
0
|
if ( $has_run_before ) { |
196
|
|
|
|
|
|
|
|
197
|
0
|
0
|
|
|
|
0
|
my $target = get_total_step_size() > $last_total_violations ? |
198
|
|
|
|
|
|
|
0 : $last_total_violations - get_total_step_size(); |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
201
|
0
|
0
|
|
|
|
0
|
if ( $current_total_violations > $target ) { |
202
|
0
|
|
|
|
|
0
|
my $got = $current_total_violations; |
203
|
0
|
|
|
|
|
0
|
$TEST->diag('Too many Perl::Critic violations...'); |
204
|
0
|
|
|
|
|
0
|
$TEST->diag("Got a total of $got. Expected no more than $target."); |
205
|
0
|
|
|
|
|
0
|
$ok = 0; |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
|
212
|
0
|
0
|
0
|
|
|
0
|
if ( !$has_run_before || ($ok && $last_total_violations > 0) ) { |
|
|
|
0
|
|
|
|
|
213
|
0
|
|
|
|
|
0
|
push @{$history_data}, $results; |
|
0
|
|
|
|
|
0
|
|
214
|
0
|
|
|
|
|
0
|
_write_history_file( get_history_file(), $history_data); |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
|
218
|
0
|
|
|
|
|
0
|
return $ok; |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub _all_code_files { |
224
|
1
|
|
|
1
|
|
3
|
my @dirs = @_; |
225
|
1
|
50
|
|
|
|
3
|
if (not @dirs) { |
226
|
0
|
|
|
|
|
0
|
@dirs = _starting_points(); |
227
|
|
|
|
|
|
|
} |
228
|
1
|
|
|
|
|
6
|
return Perl::Critic::Utils::all_perl_files(@dirs); |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
sub _starting_points { |
234
|
0
|
0
|
|
0
|
|
0
|
return -e 'blib' ? 'blib' : grep { -e $_ } qw(lib bin script scripts); |
|
0
|
|
|
|
|
0
|
|
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub _read_history { |
240
|
|
|
|
|
|
|
|
241
|
1
|
|
|
1
|
|
586
|
my ($history_file) = @_; |
242
|
|
|
|
|
|
|
|
243
|
1
|
50
|
|
|
|
16
|
return [] if not -e $history_file; |
244
|
|
|
|
|
|
|
|
245
|
0
|
|
|
|
|
0
|
my $history_data = eval { do $history_file }; |
|
0
|
|
|
|
|
0
|
|
246
|
0
|
0
|
|
|
|
0
|
croak qq{Can't read history from "$history_file": $EVAL_ERROR} |
247
|
|
|
|
|
|
|
if $EVAL_ERROR; |
248
|
|
|
|
|
|
|
|
249
|
0
|
|
|
|
|
0
|
return $history_data; |
250
|
|
|
|
|
|
|
} |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub _open_history_file { |
255
|
|
|
|
|
|
|
|
256
|
1
|
|
|
1
|
|
420
|
my ($history_file) = @_; |
257
|
|
|
|
|
|
|
|
258
|
1
|
50
|
|
|
|
268
|
open my $history_fh, '>', $history_file |
259
|
|
|
|
|
|
|
or confess qq{Can't open "$history_file": $OS_ERROR}; |
260
|
|
|
|
|
|
|
|
261
|
0
|
|
|
|
|
|
return $history_fh; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
sub _write_history_file { |
267
|
|
|
|
|
|
|
|
268
|
0
|
|
|
0
|
|
|
my ($history_file, $history_data) = @_; |
269
|
|
|
|
|
|
|
|
270
|
0
|
|
|
|
|
|
my $history_fh = _open_history_file($history_file); |
271
|
|
|
|
|
|
|
|
272
|
0
|
0
|
|
|
|
|
print {$history_fh} Dumper($history_data) |
|
0
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
or confess qq{Can't write to "$history_file": $OS_ERROR}; |
274
|
|
|
|
|
|
|
|
275
|
0
|
0
|
|
|
|
|
close $history_fh |
276
|
|
|
|
|
|
|
or confess qq{Can't close "$history_file": $OS_ERROR}; |
277
|
|
|
|
|
|
|
|
278
|
0
|
|
|
|
|
|
return 1; |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
#--------------------------------------------------------------------------- |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
1; |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
__END__ |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=pod |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=for stopwords AntHill CruiseControl |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=head1 NAME |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
Test::Perl::Critic::Progressive - Gradually enforce coding standards. |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=head1 SYNOPSIS |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
To test one or more files, and/or all files in one or more directories: |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
use Test::Perl::Critic::Progressive qw( progressive_critic_ok ); |
302
|
|
|
|
|
|
|
progressive_critic_ok($file1, $file2, $dir1, $dir2); |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
To test all Perl files in a distribution: |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
use Test::Perl::Critic::Progressive qw( progressive_critic_ok ); |
307
|
|
|
|
|
|
|
progressive_critic_ok(); |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
Recommended usage for public CPAN distributions: |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
use strict; |
312
|
|
|
|
|
|
|
use warnings; |
313
|
|
|
|
|
|
|
use Test::More; |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
eval { require Test::Perl::Critic::Progressive }; |
316
|
|
|
|
|
|
|
plan skip_all => 'T::P::C::Progressive required for this test' if $@; |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
Test::Perl::Critic::Progressive::progressive_critic_ok(); |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=head1 DESCRIPTION |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
Applying coding standards to large amounts of legacy code is a daunting task. |
324
|
|
|
|
|
|
|
Often times, legacy code is so non-compliant that it seems downright |
325
|
|
|
|
|
|
|
impossible. But, if you consistently chip away at the problem, you will |
326
|
|
|
|
|
|
|
eventually succeed! Test::Perl::Critic::Progressive uses the L<Perl::Critic> |
327
|
|
|
|
|
|
|
engine to prevent further deterioration of your code and |
328
|
|
|
|
|
|
|
B<gradually> steer it towards conforming with your chosen coding standards. |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
The most effective way to use Test::Perl::Critic::Progressive is as a unit |
331
|
|
|
|
|
|
|
test that is run under a continuous-integration system like CruiseControl or |
332
|
|
|
|
|
|
|
AntHill. Each time a developer commits changes to the code, this test will |
333
|
|
|
|
|
|
|
fail and the build will break unless it has the same (or fewer) Perl::Critic |
334
|
|
|
|
|
|
|
violations than the last successful test. |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
See the L<"NOTES"> for more details about how this test works. |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=head1 SUBROUTINES |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
All of the following subroutines can be exported upon request. Or you |
341
|
|
|
|
|
|
|
can export all of them at once using the C<':all'> tag. |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
=over |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=item C< progressive_critic_ok(@FILES [, @DIRECTORIES ]) > |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=item C< progressive_critic_ok() > |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
Uses Perl::Critic to analyze each of the given @FILES, and/or all Perl files |
350
|
|
|
|
|
|
|
beneath the given list of C<@DIRECTORIES>. If no arguments are given, it |
351
|
|
|
|
|
|
|
analyzes all the Perl files in the F<blib/> directory. If the F<blib/> |
352
|
|
|
|
|
|
|
directory does not exist, then it tries the F<lib/>, F<bin/>, F<script/>, and |
353
|
|
|
|
|
|
|
F<scripts/> directory. The results of the analysis will be stored as |
354
|
|
|
|
|
|
|
F<.perlcritic-history> in the same directory where your test script is |
355
|
|
|
|
|
|
|
located. |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
The first time you run this test, it will always pass. But on each subsequent |
358
|
|
|
|
|
|
|
run, the test will pass only if the number of violations found B<is less than |
359
|
|
|
|
|
|
|
or equal to> the number of violations found during the last passing test. If |
360
|
|
|
|
|
|
|
it does pass, then the history file will be updated with the new analysis |
361
|
|
|
|
|
|
|
results. Once all the violations are removed from the code, this test will |
362
|
|
|
|
|
|
|
always pass, unless a new violation is introduced. |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
This subroutine emits its own L<Test::More> plan, so you do not need to |
365
|
|
|
|
|
|
|
specify an expected number of tests yourself. |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=item C< get_history_file() > |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
=item C< set_history_file($FILE) > |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
These functions get or set the full path to the history file. This is |
373
|
|
|
|
|
|
|
where Test::Perl::Critic::Progressive will store the results of each passing |
374
|
|
|
|
|
|
|
analysis. If the C<$FILE> does not exist, it will be created anew. The |
375
|
|
|
|
|
|
|
default is C<$Bin/.perlcritic-history> where C<$Bin> is the directory that |
376
|
|
|
|
|
|
|
the calling test script is located in. |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
=item C< get_total_step_size() > |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=item C< set_total_step_size($INTEGER) > |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
These functions get or set the minimum acceptable decrease in the B<total> |
383
|
|
|
|
|
|
|
number of violations between each test. The default value is zero, which |
384
|
|
|
|
|
|
|
means that you are not required to remove any violations, but you are also not |
385
|
|
|
|
|
|
|
allowed to add any. If you set the step size to a positive number, the test |
386
|
|
|
|
|
|
|
will require you to remove C<$INTEGER> violations each time the test is run. |
387
|
|
|
|
|
|
|
In this case, the particular type of violation that you eliminate doesn't |
388
|
|
|
|
|
|
|
matter. The larger the step size, the faster you'll have to eliminate |
389
|
|
|
|
|
|
|
violations. |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=item C< get_step_size_per_policy() > |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=item C< set_step_size_per_policy(%ARGS) > |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
These functions get or set the minimum acceptable decrease in the number of |
397
|
|
|
|
|
|
|
violations of a B<specific policy> between each test. The C<%ARGS> should be |
398
|
|
|
|
|
|
|
C<< $POLICY_NAME => $INTEGER >> pairs, like this: |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
my %step_sizes = ( |
401
|
|
|
|
|
|
|
'ValuesAndExpressions::ProhibitLeadingZeros' => 2, |
402
|
|
|
|
|
|
|
'Variables::ProhibitConditionalDeclarations' => 1, |
403
|
|
|
|
|
|
|
'InputOutput::ProhibitTwoArgOpen' => 3, |
404
|
|
|
|
|
|
|
); |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
set_step_size_per_policy( %step_sizes ); |
407
|
|
|
|
|
|
|
progressive_critic_ok(); |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
The default step size for any given Policy is zero, which means that you are |
410
|
|
|
|
|
|
|
not required to remove any violations, but you are also not allowed to add |
411
|
|
|
|
|
|
|
any. But if you wish to focus on eliminating certain types of violations, |
412
|
|
|
|
|
|
|
then increasing the per-policy step size will force you to B<decrease> the |
413
|
|
|
|
|
|
|
number of violations of that particular Policy, while ignoring other types of |
414
|
|
|
|
|
|
|
violations. The larger the step size, the faster you'll have to eliminate |
415
|
|
|
|
|
|
|
violations. |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
=item C< get_critic_args() > |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
=item C< set_critic_args(%ARGS) > |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
These functions get or set the arguments given to L<Perl::Critic>. By |
422
|
|
|
|
|
|
|
default, Test::Perl::Critic::Progressive invokes Perl::Critic with its default |
423
|
|
|
|
|
|
|
configuration. But if you have developed your code against a custom |
424
|
|
|
|
|
|
|
Perl::Critic configuration, you will want to configure this test to do the |
425
|
|
|
|
|
|
|
same. |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
Any C<%ARGS> given to C<set_critic_args> will be passed directly into the |
428
|
|
|
|
|
|
|
L<Perl::Critic> constructor. So if you have developed your code using a |
429
|
|
|
|
|
|
|
custom F<.perlcriticrc> file, you can direct Test::Perl::Critic::Progressive |
430
|
|
|
|
|
|
|
to use a custom file too. |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
use Test::Perl::Critic::Progressive ( ':all' ); |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
set_critic_args(-profile => 't/perlcriticrc); |
435
|
|
|
|
|
|
|
progressive_critic_ok(); |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
Now place a copy of your own F<.perlcriticrc> file in the distribution as |
438
|
|
|
|
|
|
|
F<t/perlcriticrc>. Now, C<progressive_critic_ok> will use this same |
439
|
|
|
|
|
|
|
Perl::Critic configuration. See the L<Perl::Critic> documentation for details |
440
|
|
|
|
|
|
|
on the F<.perlcriticrc> file format. |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
Any argument that is supported by the L<Perl::Critic> constructor can be |
443
|
|
|
|
|
|
|
passed through this interface. For example, you can also set the minimum |
444
|
|
|
|
|
|
|
severity level, or include & exclude specific policies like this: |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
use Test::Perl::Critic::Progressive ( ':all' ); |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
set_critic_args( -severity => 2, -exclude => ['MixedCaseVars'] ); |
449
|
|
|
|
|
|
|
progressive_critic_ok(); |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
See the L<Perl::Critic> documentation for complete details on its options and |
452
|
|
|
|
|
|
|
arguments. |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=back |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
=head1 NOTES |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
The test is evaluated in two ways. First, the number of violations for each |
460
|
|
|
|
|
|
|
Policy must be B<less than or equal to> the number of the violations found |
461
|
|
|
|
|
|
|
during the last passing test, minus the step size B<for that Policy>. Second, |
462
|
|
|
|
|
|
|
the total number of violations must be B<less than or equal> the total number |
463
|
|
|
|
|
|
|
of violations found during the last passing test, minus the B<total> step |
464
|
|
|
|
|
|
|
size. This prevents you from simply substituting one kind of violation for |
465
|
|
|
|
|
|
|
another. |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
You can use the total step size and the per-policy step size at the same time. |
468
|
|
|
|
|
|
|
For example, you can set the total step size to 5, and set the per-policy step |
469
|
|
|
|
|
|
|
size for the C<TestingAndDebugging::RequireStrictures> Policy to 3. In which |
470
|
|
|
|
|
|
|
case, you'll have to remove 5 violations between each test, but 3 of them must |
471
|
|
|
|
|
|
|
be violations of C<TestingAndDebugging::RequireStrictures>. |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
Over time, you'll probably add new Policies to your L<Perl::Critic> setup. |
474
|
|
|
|
|
|
|
When Test::Perl::Critic::Progressive uses a Policy for the first time, any |
475
|
|
|
|
|
|
|
newly discovered violations of that Policy will not be considered in the test. |
476
|
|
|
|
|
|
|
However, they will be considered in subsequent tests. |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
If you are building a CPAN distribution, you'll want to add |
479
|
|
|
|
|
|
|
F<^t/.perlcritic-history$> to the F<MANIFEST.SKIP> file. And if you are using |
480
|
|
|
|
|
|
|
a revision control system like CVS or Subversion, you'll probably want to |
481
|
|
|
|
|
|
|
configure it to ignore the F<t/.perlcritic-history> file as well. |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
=head1 BUGS |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
If you find any bugs, please submit them to |
487
|
|
|
|
|
|
|
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-Perl-Critic-Progressive>. |
488
|
|
|
|
|
|
|
Thanks. |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=head1 SEE ALSO |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
L<criticism> |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
L<Perl::Critic> |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
L<Test::Perl::Critic> |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
L<http://www.perlcritic.com> |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=head1 AUTHOR |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
Jeffrey Ryan Thalhammer <thaljef@cpan.org> |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
=head1 COPYRIGHT |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
Copyright (c) 2007-2008 Jeffrey Ryan Thalhammer. All rights reserved. |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify |
512
|
|
|
|
|
|
|
it under the same terms as Perl itself. The full text of this license |
513
|
|
|
|
|
|
|
can be found in the LICENSE file included with this module. |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
=cut |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
############################################################################## |
518
|
|
|
|
|
|
|
# Local Variables: |
519
|
|
|
|
|
|
|
# mode: cperl |
520
|
|
|
|
|
|
|
# cperl-indent-level: 4 |
521
|
|
|
|
|
|
|
# fill-column: 78 |
522
|
|
|
|
|
|
|
# indent-tabs-mode: nil |
523
|
|
|
|
|
|
|
# c-indentation-style: bsd |
524
|
|
|
|
|
|
|
# End: |
525
|
|
|
|
|
|
|
# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab : |