line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package YATT::Lite::Test::XHFTest; |
2
|
2
|
|
|
2
|
|
4751
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
60
|
|
3
|
2
|
|
|
2
|
|
11
|
use warnings qw(FATAL all NONFATAL misc); |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
91
|
|
4
|
2
|
|
|
2
|
|
11
|
use parent qw(YATT::Lite::Object); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
14
|
|
5
|
2
|
|
|
|
|
14
|
use YATT::Lite::MFields qw/tests numtests yatt global file_list file_dict |
6
|
|
|
|
|
|
|
cf_filename cf_ext cf_parser cf_encoding |
7
|
2
|
|
|
2
|
|
137
|
prev_item builder/; |
|
2
|
|
|
|
|
4
|
|
8
|
2
|
|
|
2
|
|
13
|
use Exporter 'import'; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
124
|
|
9
|
|
|
|
|
|
|
sub MY () {__PACKAGE__} |
10
|
2
|
|
|
2
|
|
10
|
use YATT::Lite::Util qw(default dict_sort); |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
176
|
|
11
|
10
|
|
|
10
|
0
|
34
|
sub default_ext {'yatt'} |
12
|
|
|
|
|
|
|
our @EXPORT_OK = qw(Item); |
13
|
|
|
|
|
|
|
|
14
|
2
|
|
|
2
|
|
12
|
use Encode; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
270
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
{ |
17
|
|
|
|
|
|
|
sub Item () {'YATT::Lite::Test::XHFTest::Item'} |
18
|
|
|
|
|
|
|
package YATT::Lite::Test::XHFTest::Item; |
19
|
2
|
|
|
2
|
|
16
|
use parent qw(YATT::Lite::Object); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
10
|
|
20
|
2
|
|
|
2
|
|
111
|
use YATT::Lite::Util qw(lexpand); |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
116
|
|
21
|
2
|
|
|
|
|
10
|
use YATT::Lite::MFields qw/cf_global |
22
|
|
|
|
|
|
|
cf_parser |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
num |
25
|
|
|
|
|
|
|
realfile |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
cf_FILE |
28
|
|
|
|
|
|
|
cf_TITLE |
29
|
|
|
|
|
|
|
cf_BREAK |
30
|
|
|
|
|
|
|
cf_SKIP |
31
|
|
|
|
|
|
|
cf_TODO |
32
|
|
|
|
|
|
|
cf_PERL_MINVER |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
cf_WIDGET |
35
|
|
|
|
|
|
|
cf_RANDOM |
36
|
|
|
|
|
|
|
cf_IN |
37
|
|
|
|
|
|
|
cf_PARAM |
38
|
|
|
|
|
|
|
cf_OUT |
39
|
|
|
|
|
|
|
cf_ERROR |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
cf_REQUIRE |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
cf_TAG |
44
|
2
|
|
|
2
|
|
20
|
/; |
|
2
|
|
|
|
|
4
|
|
45
|
|
|
|
|
|
|
|
46
|
165
|
|
|
165
|
|
99281
|
sub is_runnable { shift->ntests } |
47
|
|
|
|
|
|
|
sub ntests { |
48
|
339
|
|
|
339
|
|
1114
|
my __PACKAGE__ $item = shift; |
49
|
339
|
100
|
|
|
|
957
|
if ($item->{cf_OUT}) { |
|
|
100
|
|
|
|
|
|
50
|
242
|
|
|
|
|
1547
|
2; |
51
|
|
|
|
|
|
|
} elsif ($item->{cf_ERROR}) { |
52
|
87
|
|
|
|
|
565
|
1; |
53
|
|
|
|
|
|
|
} else { |
54
|
10
|
|
|
|
|
59
|
0; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
sub test_require { |
58
|
1
|
|
|
1
|
|
3
|
my ($self, $reqlist) = @_; |
59
|
1
|
|
|
|
|
5
|
grep {not eval qq{require $_}} lexpand($reqlist); |
|
1
|
|
|
|
|
74
|
|
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
require YATT::Lite::XHF; |
65
|
|
|
|
|
|
|
sub Parser () {'YATT::Lite::XHF'} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub list_files { |
68
|
1
|
|
|
1
|
0
|
406
|
my $pack = shift; |
69
|
|
|
|
|
|
|
map { |
70
|
1
|
50
|
|
|
|
3
|
! -d $_ ? $_ : dict_sort <$_/*.xhf>; |
|
10
|
|
|
|
|
266
|
|
71
|
|
|
|
|
|
|
} @_; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub after_new { |
75
|
10
|
|
|
10
|
1
|
16
|
my MY $self = shift; |
76
|
10
|
|
|
|
|
20
|
$self->{numtests} = 0; |
77
|
10
|
|
|
|
|
20
|
$self->{tests} = []; |
78
|
10
|
|
33
|
|
|
48
|
$self->{cf_ext} //= $self->default_ext; |
79
|
10
|
|
|
|
|
24
|
$self; |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
sub load { |
82
|
10
|
|
|
10
|
0
|
192
|
my $pack = shift; |
83
|
10
|
|
|
|
|
86
|
my Parser $parser = $pack->Parser->new(@_); |
84
|
10
|
|
|
|
|
40
|
my MY $self = $pack->new($parser->cf_delegate(qw(filename)) |
85
|
|
|
|
|
|
|
, parser => $parser); |
86
|
10
|
100
|
|
|
|
43
|
if (my @global = $parser->read(skip_comment => 0)) { |
87
|
3
|
|
|
|
|
14
|
$self->configure(@global); |
88
|
3
|
|
|
|
|
16
|
$parser->configure($self->cf_delegate_defined(qw(encoding))); |
89
|
|
|
|
|
|
|
} |
90
|
10
|
|
|
|
|
64
|
while (my @config = $parser->read) { |
91
|
165
|
|
|
|
|
764
|
$self->add_item($self->Item->new(@config)); |
92
|
|
|
|
|
|
|
} |
93
|
10
|
|
|
|
|
58
|
$self; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub convert_enc_array { |
97
|
2
|
|
|
2
|
0
|
17
|
my ($self, $enc, $array) = @_; |
98
|
2
|
|
|
|
|
6
|
foreach (@$array) { |
99
|
5
|
100
|
|
|
|
117
|
unless (ref $_) { |
|
|
50
|
|
|
|
|
|
100
|
4
|
|
|
|
|
32
|
$_ = decode($enc, $_) |
101
|
|
|
|
|
|
|
} elsif (ref $_ eq 'ARRAY') { |
102
|
1
|
|
|
|
|
5
|
$_ = $self->convert_enc_array($enc, $_); |
103
|
|
|
|
|
|
|
} else { |
104
|
|
|
|
|
|
|
# nop. |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
} |
107
|
2
|
|
|
|
|
36
|
$array; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub ntests { |
111
|
10
|
|
|
10
|
0
|
52
|
my MY $self = shift; $self->{numtests} |
112
|
10
|
|
|
|
|
34
|
} |
113
|
|
|
|
|
|
|
sub add_item { |
114
|
165
|
|
|
165
|
0
|
253
|
(my MY $self, my Item $item) = @_; |
115
|
165
|
50
|
|
|
|
389
|
if ($item->{cf_global}) { |
116
|
0
|
|
|
|
|
0
|
$self->{global} = $item->{cf_global}; |
117
|
0
|
|
|
|
|
0
|
next; |
118
|
|
|
|
|
|
|
} |
119
|
165
|
|
|
|
|
174
|
push @{$self->{tests}}, $self->fixup_item($item); |
|
165
|
|
|
|
|
423
|
|
120
|
165
|
|
|
|
|
412
|
$self->{numtests} += $item->ntests; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub fixup_item { |
124
|
165
|
|
|
165
|
0
|
258
|
(my MY $self, my Item $test) = @_; |
125
|
165
|
|
|
|
|
231
|
my Item $prev = $self->{prev_item}; |
126
|
165
|
|
66
|
|
|
420
|
$test->{cf_FILE} ||= do { |
127
|
159
|
100
|
100
|
|
|
783
|
if ($prev && $prev->{cf_FILE} =~ m{%d}) { |
128
|
|
|
|
|
|
|
$prev->{cf_FILE} |
129
|
148
|
|
|
|
|
485
|
} else { |
130
|
11
|
|
|
|
|
41
|
"f%d.$self->{cf_ext}" |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
}; |
133
|
|
|
|
|
|
|
|
134
|
165
|
|
|
|
|
235
|
$test->{realfile} = do { |
135
|
165
|
100
|
|
|
|
291
|
if ($test->{cf_IN}) { |
136
|
2
|
|
|
2
|
|
14
|
no if $] >= 5.021002, warnings => qw/redundant/; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
19
|
|
137
|
142
|
|
100
|
|
|
212
|
sprintf($test->{cf_FILE}, 1+@{$self->{file_list} //= []}) |
|
142
|
|
|
|
|
769
|
|
138
|
|
|
|
|
|
|
} else { |
139
|
|
|
|
|
|
|
$prev->{realfile} |
140
|
23
|
|
|
|
|
50
|
} |
141
|
|
|
|
|
|
|
}; |
142
|
|
|
|
|
|
|
|
143
|
165
|
|
33
|
|
|
448
|
$test->{cf_WIDGET} ||= do { |
144
|
165
|
|
|
|
|
268
|
my $widget = $test->{realfile}; |
145
|
165
|
|
|
|
|
603
|
$widget =~ s{\.\w+$}{}; |
146
|
165
|
|
|
|
|
272
|
$widget =~ s{/}{:}g; |
147
|
165
|
|
|
|
|
517
|
$widget; |
148
|
|
|
|
|
|
|
}; |
149
|
|
|
|
|
|
|
|
150
|
165
|
100
|
|
|
|
406
|
if ($test->{cf_IN}) { |
151
|
142
|
50
|
|
|
|
413
|
if (my $conflict = $self->{file_dict}{$test->{realfile}}) { |
152
|
0
|
|
|
|
|
0
|
die "FILE name confliction in test $test"; |
153
|
|
|
|
|
|
|
} |
154
|
142
|
|
|
|
|
362
|
$self->{file_dict}{$test->{realfile}} = $test; |
155
|
142
|
|
|
|
|
165
|
push @{$self->{file_list}}, $test->{realfile}; |
|
142
|
|
|
|
|
354
|
|
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
165
|
100
|
66
|
|
|
622
|
if ($test->{cf_OUT} || $test->{cf_ERROR}) { |
159
|
160
|
|
0
|
|
|
342
|
$test->{cf_WIDGET} ||= $prev && $prev->{cf_WIDGET}; |
|
|
|
33
|
|
|
|
|
160
|
160
|
100
|
100
|
|
|
467
|
if (not $test->{cf_TITLE} and $prev) { |
161
|
19
|
|
|
|
|
71
|
$test->{num} = default($prev->{num}, 0) + 1; |
162
|
19
|
|
|
|
|
48
|
$test->{cf_TITLE} = $prev->{cf_TITLE}; |
163
|
|
|
|
|
|
|
} |
164
|
160
|
|
|
|
|
267
|
$self->{prev_item} = $test; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
165
|
|
|
|
|
334
|
$test; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
sub as_vfs_data { |
171
|
10
|
|
|
10
|
0
|
10164
|
my MY $self = shift; |
172
|
10
|
|
|
|
|
22
|
my (%result); |
173
|
|
|
|
|
|
|
# 記述の順番どおりに作成 |
174
|
10
|
|
|
|
|
18
|
foreach my $fn (@{$self->{file_list}}) { |
|
10
|
|
|
|
|
36
|
|
175
|
142
|
|
|
|
|
317
|
my Item $item = $self->{file_dict}{$fn}; |
176
|
142
|
|
|
|
|
278
|
my @path = split m|/|, $fn; |
177
|
142
|
|
|
|
|
353
|
my $path_cursor = path_cursor(\%result, \@path); |
178
|
142
|
50
|
|
|
|
660
|
$path[0] =~ s|\.(\w+)$|| |
179
|
|
|
|
|
|
|
or die "Can't handle filename as vfs key: $fn"; |
180
|
142
|
|
|
|
|
276
|
my $ext = $1; |
181
|
142
|
50
|
|
|
|
526
|
if (my $sub = $self->can("convert_$ext")) { |
182
|
0
|
|
|
|
|
0
|
$sub->($self, $path_cursor, $item) |
183
|
|
|
|
|
|
|
} else { |
184
|
|
|
|
|
|
|
# XXX: 既に配列になってると困るよね。 rc 系を後回しにすれば大丈夫? |
185
|
142
|
50
|
|
|
|
373
|
unless (defined $item->{cf_IN}) { |
186
|
0
|
|
|
|
|
0
|
die "undef IN" |
187
|
|
|
|
|
|
|
} |
188
|
142
|
|
|
|
|
598
|
$path_cursor->[0]{$path[0]} = $item->{cf_IN}; |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
} |
191
|
10
|
|
|
|
|
38
|
\%result; |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub path_cursor { |
195
|
142
|
|
|
142
|
0
|
208
|
my ($top, $path) = @_; |
196
|
|
|
|
|
|
|
# path を一個残して、vivify する。 |
197
|
|
|
|
|
|
|
# そこにいたる経路を cursor として返す。 |
198
|
142
|
|
|
|
|
239
|
my $cursor = [$top]; |
199
|
142
|
|
|
|
|
354
|
while (@$path > 1) { |
200
|
1
|
|
|
|
|
3
|
my $nm = shift @$path; |
201
|
1
|
|
50
|
|
|
11
|
$cursor = [$cursor->[0]{$nm} ||= {}, $cursor]; |
202
|
|
|
|
|
|
|
} |
203
|
142
|
|
|
|
|
240
|
$cursor; |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
1; |