OrTest.pm 4.13 KB
Newer Older
1 2 3
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
#
5 6
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.
7 8 9 10 11 12 13

# This test combines two field/operator combinations using OR in
# a single boolean chart.
package Bugzilla::Test::Search::OrTest;
use base qw(Bugzilla::Test::Search::FieldTest);

use Bugzilla::Test::Search::Constants;
14
use List::MoreUtils qw(all any uniq);
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

use constant type => 'OR';

###############
# Constructor #
###############

sub new {
    my $class = shift;
    my $self = { field_tests => [@_] };
    return bless $self, $class;
}

#############
# Accessors #
#############

sub field_tests { return @{ $_[0]->{field_tests} } }
sub search_test { ($_[0]->field_tests)[0]->search_test }

sub name {
    my ($self) = @_;
    my @names = map { $_->name } $self->field_tests;
    return join('-' . $self->type . '-', @names);
}

# In an OR test, bugs ARE supposed to be contained if they are contained
# by ANY test.
sub bug_is_contained {
    my ($self, $number) = @_;
    return any { $_->bug_is_contained($number) } $self->field_tests;
}

# Needed only for failure messages
sub debug_value {
    my ($self) = @_;
    my @values = map { $_->field . ' ' . $_->debug_value } $self->field_tests;
    return join(' ' . $self->type . ' ', @values);
}

########################
# SKIP & TODO Messages #
########################

sub field_not_yet_implemented {
    my ($self) = @_;
    return $self->_join_messages('field_not_yet_implemented');
}
sub invalid_field_operator_combination {
    my ($self) = @_;
    return $self->_join_messages('invalid_field_operator_combination');
}
sub search_known_broken {
    my ($self) = @_;
    return $self->_join_messages('search_known_broken');    
}

sub _join_messages {
    my ($self, $message_method) = @_;
    my @messages = map { $_->$message_method } $self->field_tests;
    @messages = grep { $_ } @messages;
    return join(' AND ', @messages);
}

sub _bug_will_actually_be_contained {
    my ($self, $number) = @_;
81

82
    foreach my $test ($self->field_tests) {
83 84 85 86 87
        # Some tests are broken in such a way that they actually
        # generate no criteria in the SQL. In this case, the only way
        # the test contains the bug is if *another* test contains it.
        next if $test->_known_broken->{no_criteria};
        return 1 if $test->will_actually_contain_bug($number);
88 89 90 91 92 93 94 95 96 97 98 99
    }
    return 0;
}

sub contains_known_broken {
    my ($self, $number) = @_;

    if ( ( $self->bug_is_contained($number)
           and !$self->_bug_will_actually_be_contained($number) )
        or ( !$self->bug_is_contained($number)
             and $self->_bug_will_actually_be_contained($number) ) )
    {
100 101
        my @messages = map { $_->contains_known_broken($number) } 
                           $self->field_tests;
102
        @messages = grep { $_ } @messages;
103 104 105 106 107 108 109 110 111
        # Sometimes, with things that break because of no_criteria, there won't
        # be anything in @messages even though we need to print out a message.
        if (!@messages) {
            my @no_criteria = grep { $_->_known_broken->{no_criteria} }
                                   $self->field_tests;
            @messages = map { "No criteria generated by " . $_->name }
                            @no_criteria;
        }
        die "broken test with no message" if !@messages;
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
        return join(' AND ', @messages);
    }
    return undef;
}

##############################
# Bugzilla::Search arguments #
##############################

sub search_columns {
    my ($self) = @_;
    my @columns = map { @{ $_->search_columns } } $self->field_tests;
    return [uniq @columns];
}

sub search_params {
    my ($self) = @_;
    my @all_params = map { $_->search_params } $self->field_tests;
130
    my %params;
131 132
    my $chart = 0;
    foreach my $item (@all_params) {
133 134 135
        $params{"field0-0-$chart"} = $item->{'field0-0-0'};
        $params{"type0-0-$chart"}  = $item->{'type0-0-0'};
        $params{"value0-0-$chart"} = $item->{'value0-0-0'};
136 137
        $chart++;
    }
138
    return \%params;
139 140
}

141
1;