File Coverage

blib/lib/Test/MasterData/Declare.pm
Criterion Covered Total %
statement 131 151 86.7
branch 17 24 70.8
condition 13 24 54.1
subroutine 32 34 94.1
pod 7 10 70.0
total 200 243 82.3


line stmt bran cond sub pod time code
1             package Test::MasterData::Declare;
2 4     4   339614 use 5.010001;
  4         31  
3 4     4   17 use strict;
  4         7  
  4         65  
4 4     4   16 use warnings;
  4         5  
  4         98  
5 4     4   1456 use utf8;
  4         38  
  4         16  
6              
7             our $VERSION = "0.01_01";
8              
9 4     4   197 use Test2::API qw/context/;
  4         7  
  4         164  
10 4     4   1134 use Test2::V0;
  4         362935  
  4         21  
11 4     4   4518 use Test2::Compare ();
  4         9  
  4         69  
12 4     4   17 use Test2::Tools::Compare qw/number/;
  4         8  
  4         140  
13 4     4   19 use Test2::Compare::Custom;
  4         4  
  4         102  
14 4     4   20 use Scalar::Util qw/blessed/;
  4         8  
  4         207  
15              
16 4     4   22 use Carp qw/croak/;
  4         9  
  4         244  
17              
18             %Carp::Internal = (
19             %Carp::Internal,
20             "Test::MasterData::Declare" => 1,
21             "Test::MasterData::Declare::CompareRow" => 1,
22             "Test::MasterData::Declare::Row" => 1,
23             );
24              
25 4     4   23 use parent "Exporter";
  4         9  
  4         28  
26             our @EXPORT = qw/
27             master_data
28             load_csv
29             table
30             expect_row
31             relation
32              
33             like_number
34             if_column
35             json
36             /;
37              
38             our $DEFAULT_IDENTIFIER_KEY = "id";
39              
40 4     4   2030 use Test::MasterData::Declare::Runner;
  4         10  
  4         112  
41 4     4   1401 use Test::MasterData::Declare::Reader;
  4         12  
  4         122  
42 4     4   1458 use Test::MasterData::Declare::CompareRow;
  4         11  
  4         5175  
43              
44             my $runner;
45              
46             sub master_data (&) {
47 3     3 1 257 my $code = shift;
48              
49 3         20 $runner = Test::MasterData::Declare::Runner->new(
50             code => $code,
51             );
52              
53 3         32 $runner->run;
54              
55 3         163 $runner = undef;
56             }
57              
58             sub load_csv {
59 3     3 1 38 my %paths = @_;
60 3   33     16 my $identifier_key = delete $paths{_identifier_key} || $DEFAULT_IDENTIFIER_KEY;
61              
62 3         13 for my $table_name (keys %paths) {
63 5         30 my $filepath = $paths{$table_name};
64 5         23 my $reader = Test::MasterData::Declare::Reader->read_csv_from(
65             table_name => $table_name,
66             filepath => $filepath,
67             identifier_key => $identifier_key,
68             );
69              
70 5         217 $runner->add_reader_to_bucket($reader);
71             }
72             }
73              
74             sub row_hash (&) {
75 6     6 0 23 Test2::Compare::build("Test::MasterData::Declare::CompareRow", @_)
76             }
77              
78             sub row_json {
79 2     2 0 39 my ($column, @keys) = @_;
80 2         13 my $check = pop @keys;
81              
82 2         5 my $build = Test2::Compare::get_build();
83 2 50       12 croak "row_json must be with-in Test::MasterData::Declare::CompareRow"
84             unless $build->isa("Test::MasterData::Declare::CompareRow");
85              
86 2         6 $build->add_json_field($column, @keys, $check);
87             }
88              
89             sub table {
90 4     4 1 10 my ($table_name, $column, @filters_or_expects) = @_;
91 4         10 my $ctx = context();
92              
93 4         281 my $rows = $runner->rows($table_name);
94             like $rows, array {
95 4     4   277 for my $fe (@filters_or_expects) {
96 6 100 66     50 if (blessed $fe && $fe->isa("Test2::Compare::Base")) {
    50          
97             all_items
98             row_hash {
99 3         181 field $column => $fe;
100 3         10 };
101             }
102             elsif (ref $fe eq "CODE") {
103 3         6 $fe->($column);
104             }
105             }
106 4         19 };
107              
108 4         6466 $ctx->release;
109             }
110              
111             sub like_number {
112 4     4 1 9205 my ($begin, @funcs) = @_;
113              
114 4 100 66     16 my $end = $funcs[0] && number($funcs[0]) ? shift @funcs : $begin;
115              
116              
117 4         182 my $operator = "$begin <= ... <= $end";
118 4         9 my $name = "Between";
119 4 100       16 if ($begin == $end) {
120 1         2 $operator = "$begin == ...";
121 1         1 $name = "Equal";
122             }
123              
124             my $cus = Test2::Compare::Custom->new(
125             name => $name,,
126             operator => $operator,
127             code => sub {
128 10     10   392 my %args = @_;
129 10 50       26 return 0 unless number($args{got});
130              
131 10 100 66     412 return $begin <= $args{got} && $args{got} <= $end ? 1 : 0;
132             },
133 4         24 );
134              
135 4         109 return $cus, @funcs;
136             }
137              
138             sub if_column {
139 2     2 1 5 my ($column, $cond, @funcs) = @_;
140              
141 2         3 my $filter;
142 2 50       5 if (ref $column eq "CODE") {
143             $filter = sub {
144 0     0   0 my @rows = @_;
145 0         0 my @filtered;
146 0         0 for my $row (@rows) {
147 0 0       0 push @filtered, $row if $column->($row->row);
148             }
149 0         0 return @filtered;
150 0         0 };
151             }
152             else {
153             $filter = sub {
154 2     2   375 my @rows = @_;
155 2         3 my @filtered;
156 2         4 for my $row (@rows) {
157             my $delta = Test2::Compare::compare(
158 6         16 $row->row->{$column},
159             $cond,
160             \&Test2::Compare::relaxed_convert,
161             );
162 6 100       636 push @filtered, $row unless $delta;
163             }
164 2         7 return @filtered;
165 2         7 };
166             }
167              
168             return sub {
169 2     2   5 my $array = Test2::Compare::get_build();
170 2         9 $array->add_filter($filter);
171 2         7 }, @funcs;
172             }
173              
174             sub json {
175 1     1 1 3 my ($key, @funcs) = @_;
176              
177 1         2 my @keys = ($key);
178 1   33     9 while (scalar(@funcs) > 0 && !blessed $funcs[0] && ref $funcs[0] ne "CODE") {
      33        
179 0         0 push @keys, shift @funcs;
180             }
181              
182             return sub {
183 1     1   2 my $column = shift;
184 1         3 my $ctx = context();
185             all_items
186             row_hash {
187 1         65 for my $f (@funcs) {
188 2 100 66     15 if (blessed $f && $f->isa("Test2::Compare::Base")) {
    50          
189 1         3 row_json $column, @keys => $f;
190             }
191             elsif (ref $f eq "CODE") {
192             row_json $column, @keys => validator(sub {
193 3         80 my %args = @_;
194 3         6 my $got = $args{got};
195 3         9 $f->($got);
196 1         8 });
197             }
198             }
199 1         52 };
200 1         40 $ctx->release;
201 1         6 };
202             }
203              
204             sub expect_row {
205 1     1 0 20 my ($table_name, $func) = @_;
206              
207 1         3 my $ctx = context();
208              
209 1         107 my $rows = $runner->rows($table_name);
210             like $rows, array {
211             all_items
212             row_hash {
213             validator(sub {
214 0         0 my %args = @_;
215 0         0 my $got = $args{got};
216 0         0 $func->($got);
217 1         87 });
218 1     1   90 };
219 1         7 };
220              
221 1         272 $ctx->release;
222             }
223              
224             sub relation {
225 1     1 1 15 my ($from_table, $to_table, @opts) = @_;
226              
227 1         2 my %conds;
228 1   66     9 while (!ref $opts[0] && scalar(@opts) >= 2) {
229 1         3 my $from_table_column = shift @opts;
230 1         2 my $to_table_column = shift @opts;
231 1         4 $conds{$from_table_column} = $to_table_column;
232             }
233              
234 1         5 my $from_rows = $runner->rows($from_table);
235 1         3 my $to_rows = $runner->rows($to_table);
236             my $to_rows_selector = sub {
237 0     0   0 my %from_row_values = @_;
238              
239             my @matched_rows = grep {
240 0         0 my $row = $_->row;
  0         0  
241 0         0 grep { $from_row_values{$_} == $row->{$conds{$_}} } keys %conds;
  0         0  
242             } @$to_rows;
243              
244 0         0 return @matched_rows;
245 1         5 };
246              
247 1         4 my $ctx = context();
248             like $from_rows, array {
249             all_items
250             row_hash {
251             validator(sub {
252 0         0 my %args = @_;
253 0         0 my $from_row = $args{got};
254 0         0 my @relations = $to_rows_selector->(%$from_row);
255              
256 0         0 my $ok = is scalar(@relations), scalar(keys %conds);
257 1         75 });
258 1     1   104 };
259 1         119 };
260 1         298 $ctx->release;
261             }
262              
263             1;
264             __END__