Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add all_items support in Bag #183

Merged
merged 1 commit into from
Apr 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 30 additions & 2 deletions lib/Test2/Compare/Bag.pm
Expand Up @@ -6,15 +6,16 @@ use base 'Test2::Compare::Base';

our $VERSION = '0.000120';

use Test2::Util::HashBase qw/ending meta items/;
use Test2::Util::HashBase qw/ending meta items for_each/;

use Carp qw/croak confess/;
use Scalar::Util qw/reftype looks_like_number/;

sub init {
my $self = shift;

$self->{+ITEMS} ||= [];
$self->{+ITEMS} ||= [];
$self->{+FOR_EACH} ||= [];

$self->SUPER::init();
}
Expand Down Expand Up @@ -48,6 +49,11 @@ sub add_item {
push @{$self->{+ITEMS}}, $check;
}

sub add_for_each {
my $self = shift;
push @{$self->{+FOR_EACH}} => @_;
}

sub deltas {
my $self = shift;
my %params = @_;
Expand All @@ -56,6 +62,7 @@ sub deltas {
my @deltas;
my $state = 0;
my @items = @{$self->{+ITEMS}};
my @for_each = @{$self->{+FOR_EACH}};

# Make a copy that we can munge as needed.
my @list = @$got;
Expand Down Expand Up @@ -98,6 +105,27 @@ sub deltas {
}
}

if (@for_each) {
my @checks = map { $convert->($_) } @for_each;

for my $idx (0..$#list) {
# All items are matched if we have conditions for all items
delete $unmatched{$idx};

my $val = $list[$idx];

for my $check (@checks) {
push @deltas => $check->run(
id => [ARRAY => $idx],
convert => $convert,
seen => $seen,
exists => 1,
got => $val,
);
}
}
}

# if elements are left over, and ending is true, we have a problem!
if($self->{+ENDING} && keys %unmatched) {
for my $idx (sort keys %unmatched) {
Expand Down
5 changes: 5 additions & 0 deletions lib/Test2/Tools/Compare.pm
Expand Up @@ -1332,6 +1332,11 @@ check object.
B<Note:> This function can only be used inside an array, bag or subset
builder sub, and must be called in void context.

=item all_items($CHECK1, $CHECK2, ...)

Add checks that apply to all items. You can put this anywhere in the bag
block, and can call it any number of times with any number of arguments.

=item end()

Enforce that there are no more items after the last one specified.
Expand Down
51 changes: 50 additions & 1 deletion t/modules/Tools/Compare.t
Expand Up @@ -1644,7 +1644,7 @@ subtest unlike => sub {
ok(!$_->{pass}, "Event was a failure") for @$events
};

subtest all_items => sub {
subtest all_items_on_array => sub {
like(
[qw/a aa aaa/],
array {
Expand Down Expand Up @@ -1693,6 +1693,55 @@ subtest all_items => sub {
);
};

subtest all_items_on_bag => sub {
like(
[qw/a aa aaa/],
bag {
all_items match qr/^a+$/;
item 'a';
item 'aa';
},
"All items match regex"
);

my @lines;
my $array = [qw/a aa aaa/];
my $regx = qr/^b+$/;
my $events = intercept {
is(
$array,
bag {
all_items match $regx; push @lines => __LINE__;
item 'b'; push @lines => __LINE__;
item 'aa'; push @lines => __LINE__;
end;
},
"items do not all match, and diag reflects all issues, and in order"
);
};

like(
$events,
array {
fail_events Ok => {pass => 0};
event Diag => {
message => table(
header => [qw/PATH GOT OP CHECK LNs/],
rows => [
['', "$array", '', "<BAG>", ($lines[0] - 1) . ", " . ($lines[-1] + 2)],
['[*]', '<DOES NOT EXIST>', '', 'b', $lines[1]],
['[0]', 'a', '=~', $regx, $lines[0]],
['[1]', 'aa', '=~', $regx, $lines[0]],
['[2]', 'aaa', '=~', $regx, $lines[0]],
],
),
};

},
"items do not all match, and diag reflects all issues, and in order"
);
};

subtest all_keys_and_vals => sub {
is(
{a => 'a', 'aa' => 'aa', 'aaa' => 'aaa'},
Expand Down