summaryrefslogtreecommitdiffstats
path: root/xt/lib/Bugzilla/Test/Search/Constants.pm
diff options
context:
space:
mode:
Diffstat (limited to 'xt/lib/Bugzilla/Test/Search/Constants.pm')
-rw-r--r--xt/lib/Bugzilla/Test/Search/Constants.pm1857
1 files changed, 951 insertions, 906 deletions
diff --git a/xt/lib/Bugzilla/Test/Search/Constants.pm b/xt/lib/Bugzilla/Test/Search/Constants.pm
index 53f8851fb..34953d697 100644
--- a/xt/lib/Bugzilla/Test/Search/Constants.pm
+++ b/xt/lib/Bugzilla/Test/Search/Constants.pm
@@ -31,28 +31,28 @@ use Bugzilla::Constants;
use Bugzilla::Util qw(generate_random_password);
our @EXPORT = qw(
- ATTACHMENT_FIELDS
- BROKEN_NOT
- COLUMN_TRANSLATION
- COMMENT_FIELDS
- CUSTOM_FIELDS
- CUSTOM_SEARCH_TESTS
- FIELD_SIZE
- FIELD_SUBSTR_SIZE
- FLAG_FIELDS
- INJECTION_BROKEN_FIELD
- INJECTION_BROKEN_OPERATOR
- INJECTION_TESTS
- KNOWN_BROKEN
- NUM_BUGS
- NUM_SEARCH_TESTS
- SKIP_FIELDS
- SPECIAL_PARAM_TESTS
- SUBSTR_NO_FIELD_ADD
- SUBSTR_SIZE
- TESTS
- TESTS_PER_RUN
- USER_FIELDS
+ ATTACHMENT_FIELDS
+ BROKEN_NOT
+ COLUMN_TRANSLATION
+ COMMENT_FIELDS
+ CUSTOM_FIELDS
+ CUSTOM_SEARCH_TESTS
+ FIELD_SIZE
+ FIELD_SUBSTR_SIZE
+ FLAG_FIELDS
+ INJECTION_BROKEN_FIELD
+ INJECTION_BROKEN_OPERATOR
+ INJECTION_TESTS
+ KNOWN_BROKEN
+ NUM_BUGS
+ NUM_SEARCH_TESTS
+ SKIP_FIELDS
+ SPECIAL_PARAM_TESTS
+ SUBSTR_NO_FIELD_ADD
+ SUBSTR_SIZE
+ TESTS
+ TESTS_PER_RUN
+ USER_FIELDS
);
# Bug 1 is designed to be found by all the "equals" tests. It has
@@ -77,6 +77,7 @@ use constant NUM_BUGS => 6;
# How many tests there are for each operator/field combination other
# than the "contains" tests.
use constant NUM_SEARCH_TESTS => 3;
+
# This is how many tests get run for each field/operator.
use constant TESTS_PER_RUN => NUM_SEARCH_TESTS + NUM_BUGS;
@@ -88,40 +89,37 @@ use constant FIELD_SIZE => 30;
# These are the custom fields that are created if the BZ_MODIFY_DATABASE_TESTS
# environment variable is set.
use constant CUSTOM_FIELDS => {
- FIELD_TYPE_FREETEXT, 'cf_freetext',
- FIELD_TYPE_SINGLE_SELECT, 'cf_single_select',
- FIELD_TYPE_MULTI_SELECT, 'cf_multi_select',
- FIELD_TYPE_TEXTAREA, 'cf_textarea',
- FIELD_TYPE_DATETIME, 'cf_datetime',
- FIELD_TYPE_BUG_ID, 'cf_bugid',
+ FIELD_TYPE_FREETEXT, 'cf_freetext',
+ FIELD_TYPE_SINGLE_SELECT, 'cf_single_select',
+ FIELD_TYPE_MULTI_SELECT, 'cf_multi_select',
+ FIELD_TYPE_TEXTAREA, 'cf_textarea',
+ FIELD_TYPE_DATETIME, 'cf_datetime',
+ FIELD_TYPE_BUG_ID, 'cf_bugid',
};
# This translates fielddefs names into Search column names.
use constant COLUMN_TRANSLATION => {
- creation_ts => 'opendate',
- delta_ts => 'changeddate',
- work_time => 'actual_time',
+ creation_ts => 'opendate',
+ delta_ts => 'changeddate',
+ work_time => 'actual_time',
};
# Make comment field names to their Bugzilla::Comment accessor.
use constant COMMENT_FIELDS => {
- longdesc => 'body',
- commenter => 'author',
- 'longdescs.isprivate' => 'is_private',
+ longdesc => 'body',
+ commenter => 'author',
+ 'longdescs.isprivate' => 'is_private',
};
# Same as above, for Bugzilla::Attachment.
-use constant ATTACHMENT_FIELDS => {
- mimetype => 'contenttype',
- submitter => 'attacher',
- thedata => 'data',
-};
+use constant ATTACHMENT_FIELDS =>
+ {mimetype => 'contenttype', submitter => 'attacher', thedata => 'data',};
# Same, for Bugzilla::Flag.
use constant FLAG_FIELDS => {
- 'flagtypes.name' => 'name',
- 'setters.login_name' => 'setter',
- 'requestees.login_name' => 'requestee',
+ 'flagtypes.name' => 'name',
+ 'setters.login_name' => 'setter',
+ 'requestees.login_name' => 'requestee',
};
# These are fields that we don't test. Test::More will mark these
@@ -129,40 +127,43 @@ use constant FLAG_FIELDS => {
#
# We don't support days_elapsed or owner_idle_time yet.
use constant SKIP_FIELDS => qw(
- owner_idle_time
- days_elapsed
+ owner_idle_time
+ days_elapsed
);
# All the fields that represent users.
use constant USER_FIELDS => qw(
- assigned_to
- cc
- reporter
- qa_contact
- commenter
- attachments.submitter
- setters.login_name
- requestees.login_name
+ assigned_to
+ cc
+ reporter
+ qa_contact
+ commenter
+ attachments.submitter
+ setters.login_name
+ requestees.login_name
);
# For the "substr"-type searches, how short of a substring should
# we use? The goal is to be shorter than the full string, but
# long enough to still be globally unique.
use constant SUBSTR_SIZE => 20;
+
# However, for some fields, we use a different size.
use constant FIELD_SUBSTR_SIZE => {
- alias => 11,
- # Just the month and day.
- deadline => -5,
- creation_ts => -8,
- delta_ts => -8,
- percentage_complete => 1,
- work_time => 3,
- remaining_time => 3,
- target_milestone => 15,
- longdesc => 25,
- # Just the hour and minute.
- FIELD_TYPE_DATETIME, -5,
+ alias => 11,
+
+ # Just the month and day.
+ deadline => -5,
+ creation_ts => -8,
+ delta_ts => -8,
+ percentage_complete => 1,
+ work_time => 3,
+ remaining_time => 3,
+ target_milestone => 15,
+ longdesc => 25,
+
+ # Just the hour and minute.
+ FIELD_TYPE_DATETIME, -5,
};
# For most fields, we add the length of the name of the field plus
@@ -170,9 +171,9 @@ use constant FIELD_SUBSTR_SIZE => {
# we're going to use. However, for some fields, it doesn't make sense to
# add in their field name this way.
use constant SUBSTR_NO_FIELD_ADD => FIELD_TYPE_DATETIME, qw(
- target_milestone remaining_time percentage_complete work_time
- attachments.mimetype attachments.submitter attachments.filename
- attachments.description flagtypes.name
+ target_milestone remaining_time percentage_complete work_time
+ attachments.mimetype attachments.submitter attachments.filename
+ attachments.description flagtypes.name
);
################
@@ -192,42 +193,42 @@ use constant SUBSTR_NO_FIELD_ADD => FIELD_TYPE_DATETIME, qw(
# lessthaneq. What we're really saying here by marking these broken
# is that there ought to be some way of searching "all ccs" vs "any cc"
# (and same for the other fields).
-use constant GREATERTHAN_BROKEN => (
- cc => { contains => [1] },
-);
+use constant GREATERTHAN_BROKEN => (cc => {contains => [1]},);
# allwords and allwordssubstr have these broken tests in common.
use constant ALLWORDS_BROKEN => (
- # allwordssubstr on cc fields matches against a single cc,
- # instead of matching against all ccs on a bug.
- cc => { contains => [1] },
- # bug 828344 changed how these searches operate to revert back to the 4.0
- # behavour, so these tests need to be updated (bug 849117).
- 'flagtypes.name' => { contains => [1] },
- longdesc => { contains => [1] },
+
+ # allwordssubstr on cc fields matches against a single cc,
+ # instead of matching against all ccs on a bug.
+ cc => {contains => [1]},
+
+ # bug 828344 changed how these searches operate to revert back to the 4.0
+ # behavour, so these tests need to be updated (bug 849117).
+ 'flagtypes.name' => {contains => [1]},
+ longdesc => {contains => [1]},
);
# Fields that don't generally work at all with changed* searches, but
# probably should.
use constant CHANGED_BROKEN => (
- classification => { contains => [1] },
- commenter => { contains => [1] },
- percentage_complete => { contains => [1] },
- 'requestees.login_name' => { contains => [1] },
- 'setters.login_name' => { contains => [1] },
- delta_ts => { contains => [1] },
+ classification => {contains => [1]},
+ commenter => {contains => [1]},
+ percentage_complete => {contains => [1]},
+ 'requestees.login_name' => {contains => [1]},
+ 'setters.login_name' => {contains => [1]},
+ delta_ts => {contains => [1]},
);
# These are additional broken tests that changedfrom and changedto
# have in common.
use constant CHANGED_VALUE_BROKEN => (
- bug_group => { contains => [1] },
- cc => { contains => [1] },
- estimated_time => { contains => [1] },
- 'flagtypes.name' => { contains => [1] },
- keywords => { contains => [1] },
- 'longdescs.count' => { search => 1 },
- FIELD_TYPE_MULTI_SELECT, { contains => [1] },
+ bug_group => {contains => [1]},
+ cc => {contains => [1]},
+ estimated_time => {contains => [1]},
+ 'flagtypes.name' => {contains => [1]},
+ keywords => {contains => [1]},
+ 'longdescs.count' => {search => 1},
+ FIELD_TYPE_MULTI_SELECT, {contains => [1]},
);
@@ -252,114 +253,94 @@ use constant CHANGED_VALUE_BROKEN => (
# while the other fails. In this case, we have a special override for
# "operator-value", which uniquely identifies tests.
use constant KNOWN_BROKEN => {
- "equals-%group.<1-bug_group>%" => {
- commenter => { contains => [1,2,3,4,5] },
- },
-
- greaterthan => { GREATERTHAN_BROKEN },
- greaterthaneq => { GREATERTHAN_BROKEN },
-
- 'allwordssubstr-<1>' => { ALLWORDS_BROKEN },
- 'allwords-<1>' => {
- ALLWORDS_BROKEN,
- },
- 'anywords-<1>' => {
- 'flagtypes.name' => { contains => [1,2,3,4,5] },
- },
- 'anywords-<1> <2>' => {
- 'flagtypes.name' => { contains => [3,4,5] },
- },
- 'anywordssubstr-<1> <2>' => {
- 'flagtypes.name' => { contains => [3,4,5] },
- },
-
- # setters.login_name and requestees.login name aren't tracked individually
- # in bugs_activity, so can't be searched using this method.
- #
- # percentage_complete isn't tracked in bugs_activity (and it would be
- # really hard to track). However, it adds a 0=0 term instead of using
- # the changed* charts or simply denying them.
- #
- # delta_ts changedbefore/after should probably search for bugs based
- # on their delta_ts.
- #
- # creation_ts changedbefore/after should search for bug creation dates.
- #
- # The commenter field changedbefore/after should search for comment
- # creation dates.
- #
- # classification isn't being tracked properly in bugs_activity, I think.
- #
- # attach_data.thedata should search when attachments were created and
- # who they were created by.
- 'changedbefore' => {
- CHANGED_BROKEN,
- 'attach_data.thedata' => { contains => [1] },
- },
- 'changedafter' => {
- 'attach_data.thedata' => { contains => [2,3,4] },
- classification => { contains => [2,3,4] },
- commenter => { contains => [2,3,4] },
- delta_ts => { contains => [2,3,4] },
- percentage_complete => { contains => [2,3,4] },
- 'requestees.login_name' => { contains => [2,3,4] },
- 'setters.login_name' => { contains => [2,3,4] },
- },
- changedfrom => {
- CHANGED_BROKEN,
- CHANGED_VALUE_BROKEN,
- # All fields should have a way to search for "changing
- # from a blank value" probably.
- blocked => { contains => [3,4,5], no_criteria => 1 },
- dependson => { contains => [2,4,5], no_criteria => 1 },
- work_time => { contains => [1] },
- FIELD_TYPE_BUG_ID, { contains => [5], no_criteria => 1 },
- },
- # changeto doesn't find remaining_time changes (possibly due to us not
- # tracking that data properly).
- #
- # multi-valued fields are stored as comma-separated strings, so you
- # can't do changedfrom/to on them.
- #
- # Perhaps commenter can either tell you who the last commenter was,
- # or if somebody commented at a given time (combined with other
- # charts).
- #
- # longdesc changedto/from doesn't do anything; maybe it should.
- # Same for attach_data.thedata.
- changedto => {
- CHANGED_BROKEN,
- CHANGED_VALUE_BROKEN,
- 'attach_data.thedata' => { contains => [1] },
- longdesc => { contains => [1] },
- remaining_time => { contains => [1] },
- },
- changedby => {
- CHANGED_BROKEN,
- # This should probably search the attacher or anybody who changed
- # anything about an attachment at all.
- 'attach_data.thedata' => { contains => [1] },
- # This should probably search the reporter.
- creation_ts => { contains => [1] },
- },
- notequals => {
- 'flagtypes.name' => { contains => [1, 5] },
- longdesc => { contains => [1] },
- },
- notregexp => {
- 'flagtypes.name' => { contains => [1, 5] },
- longdesc => { contains => [1] },
- },
- notsubstring => {
- 'flagtypes.name' => { contains => [5] },
- longdesc => { contains => [1] },
- },
- nowords => {
- 'flagtypes.name' => { contains => [1, 5] },
- },
- nowordssubstr => {
- 'flagtypes.name' => { contains => [5] },
- },
+ "equals-%group.<1-bug_group>%" => {commenter => {contains => [1, 2, 3, 4, 5]},},
+
+ greaterthan => {GREATERTHAN_BROKEN},
+ greaterthaneq => {GREATERTHAN_BROKEN},
+
+ 'allwordssubstr-<1>' => {ALLWORDS_BROKEN},
+ 'allwords-<1>' => {ALLWORDS_BROKEN,},
+ 'anywords-<1>' => {'flagtypes.name' => {contains => [1, 2, 3, 4, 5]},},
+ 'anywords-<1> <2>' => {'flagtypes.name' => {contains => [3, 4, 5]},},
+ 'anywordssubstr-<1> <2>' => {'flagtypes.name' => {contains => [3, 4, 5]},},
+
+ # setters.login_name and requestees.login name aren't tracked individually
+ # in bugs_activity, so can't be searched using this method.
+ #
+ # percentage_complete isn't tracked in bugs_activity (and it would be
+ # really hard to track). However, it adds a 0=0 term instead of using
+ # the changed* charts or simply denying them.
+ #
+ # delta_ts changedbefore/after should probably search for bugs based
+ # on their delta_ts.
+ #
+ # creation_ts changedbefore/after should search for bug creation dates.
+ #
+ # The commenter field changedbefore/after should search for comment
+ # creation dates.
+ #
+ # classification isn't being tracked properly in bugs_activity, I think.
+ #
+ # attach_data.thedata should search when attachments were created and
+ # who they were created by.
+ 'changedbefore' =>
+ {CHANGED_BROKEN, 'attach_data.thedata' => {contains => [1]},},
+ 'changedafter' => {
+ 'attach_data.thedata' => {contains => [2, 3, 4]},
+ classification => {contains => [2, 3, 4]},
+ commenter => {contains => [2, 3, 4]},
+ delta_ts => {contains => [2, 3, 4]},
+ percentage_complete => {contains => [2, 3, 4]},
+ 'requestees.login_name' => {contains => [2, 3, 4]},
+ 'setters.login_name' => {contains => [2, 3, 4]},
+ },
+ changedfrom => {
+ CHANGED_BROKEN, CHANGED_VALUE_BROKEN,
+
+ # All fields should have a way to search for "changing
+ # from a blank value" probably.
+ blocked => {contains => [3, 4, 5], no_criteria => 1},
+ dependson => {contains => [2, 4, 5], no_criteria => 1},
+ work_time => {contains => [1]},
+ FIELD_TYPE_BUG_ID, {contains => [5], no_criteria => 1},
+ },
+
+ # changeto doesn't find remaining_time changes (possibly due to us not
+ # tracking that data properly).
+ #
+ # multi-valued fields are stored as comma-separated strings, so you
+ # can't do changedfrom/to on them.
+ #
+ # Perhaps commenter can either tell you who the last commenter was,
+ # or if somebody commented at a given time (combined with other
+ # charts).
+ #
+ # longdesc changedto/from doesn't do anything; maybe it should.
+ # Same for attach_data.thedata.
+ changedto => {
+ CHANGED_BROKEN, CHANGED_VALUE_BROKEN,
+ 'attach_data.thedata' => {contains => [1]},
+ longdesc => {contains => [1]},
+ remaining_time => {contains => [1]},
+ },
+ changedby => {
+ CHANGED_BROKEN,
+
+ # This should probably search the attacher or anybody who changed
+ # anything about an attachment at all.
+ 'attach_data.thedata' => {contains => [1]},
+
+ # This should probably search the reporter.
+ creation_ts => {contains => [1]},
+ },
+ notequals =>
+ {'flagtypes.name' => {contains => [1, 5]}, longdesc => {contains => [1]},},
+ notregexp =>
+ {'flagtypes.name' => {contains => [1, 5]}, longdesc => {contains => [1]},},
+ notsubstring =>
+ {'flagtypes.name' => {contains => [5]}, longdesc => {contains => [1]},},
+ nowords => {'flagtypes.name' => {contains => [1, 5]},},
+ nowordssubstr => {'flagtypes.name' => {contains => [5]},},
};
###################
@@ -368,135 +349,90 @@ use constant KNOWN_BROKEN => {
# Common BROKEN_NOT values for the changed* fields.
use constant CHANGED_BROKEN_NOT => (
- "attach_data.thedata" => { contains => [1] },
- "classification" => { contains => [1] },
- "commenter" => { contains => [1] },
- "delta_ts" => { contains => [1] },
- percentage_complete => { contains => [1] },
- "requestees.login_name" => { contains => [1] },
- "setters.login_name" => { contains => [1] },
+ "attach_data.thedata" => {contains => [1]},
+ "classification" => {contains => [1]},
+ "commenter" => {contains => [1]},
+ "delta_ts" => {contains => [1]},
+ percentage_complete => {contains => [1]},
+ "requestees.login_name" => {contains => [1]},
+ "setters.login_name" => {contains => [1]},
);
# For changedfrom and changedto.
use constant CHANGED_FROM_TO_BROKEN_NOT => (
- 'longdescs.count' => { search => 1 },
- "bug_group" => { contains => [1] },
- "cc" => { contains => [1] },
- "estimated_time" => { contains => [1] },
- "flagtypes.name" => { contains => [1] },
- "keywords" => { contains => [1] },
- FIELD_TYPE_MULTI_SELECT, { contains => [1] },
+ 'longdescs.count' => {search => 1},
+ "bug_group" => {contains => [1]},
+ "cc" => {contains => [1]},
+ "estimated_time" => {contains => [1]},
+ "flagtypes.name" => {contains => [1]},
+ "keywords" => {contains => [1]},
+ FIELD_TYPE_MULTI_SELECT, {contains => [1]},
);
# These are field/operator combinations that are broken when run under NOT().
use constant BROKEN_NOT => {
- allwords => {
- cc => { contains => [1] },
- 'flagtypes.name' => { contains => [1, 5] },
- longdesc => { contains => [1] },
- },
- 'allwords-<1> <2>' => {
- cc => { },
- },
- allwordssubstr => {
- cc => { contains => [1] },
- 'flagtypes.name' => { contains => [5, 6] },
- longdesc => { contains => [1] },
- },
- 'allwordssubstr-<1>,<2>' => {
- cc => { },
- longdesc => { contains => [1] },
- },
- anyexact => {
- 'flagtypes.name' => { contains => [1, 2, 5] },
- },
- 'anywords-<1>' => {
- 'flagtypes.name' => { contains => [1, 2, 3, 4, 5] },
- },
- 'anywords-<1> <2>' => {
- 'flagtypes.name' => { contains => [3, 4, 5] },
- },
- anywordssubstr => {
- 'flagtypes.name' => { contains => [5] },
- },
- 'anywordssubstr-<1> <2>' => {
- 'flagtypes.name' => { contains => [3,4,5] },
- },
- casesubstring => {
- 'flagtypes.name' => { contains => [5] },
- },
- changedafter => {
- "attach_data.thedata" => { contains => [2, 3, 4] },
- "classification" => { contains => [2, 3, 4] },
- "commenter" => { contains => [2, 3, 4] },
- percentage_complete => { contains => [2, 3, 4] },
- "delta_ts" => { contains => [2, 3, 4] },
- "requestees.login_name" => { contains => [2, 3, 4] },
- "setters.login_name" => { contains => [2, 3, 4] },
- },
- changedbefore => {
- CHANGED_BROKEN_NOT,
- },
- changedby => {
- CHANGED_BROKEN_NOT,
- creation_ts => { contains => [1] },
- work_time => { contains => [1] },
- },
- changedfrom => {
- CHANGED_BROKEN_NOT,
- CHANGED_FROM_TO_BROKEN_NOT,
- 'attach_data.thedata' => { },
- blocked => { contains => [1, 2] },
- dependson => { contains => [1, 3] },
- work_time => { contains => [1] },
- FIELD_TYPE_BUG_ID, { contains => [1 .. 4] },
- },
- changedto => {
- CHANGED_BROKEN_NOT,
- CHANGED_FROM_TO_BROKEN_NOT,
- longdesc => { contains => [1] },
- "remaining_time" => { contains => [1] },
- },
- greaterthan => {
- cc => { contains => [1] },
- 'flagtypes.name' => { contains => [5] },
- },
- greaterthaneq => {
- cc => { contains => [1] },
- 'flagtypes.name' => { contains => [2, 5] },
- },
- equals => {
- 'flagtypes.name' => { contains => [1, 5] },
- },
- notequals => {
- longdesc => { contains => [1] },
- },
- notregexp => {
- longdesc => { contains => [1] },
- },
- notsubstring => {
- longdesc => { contains => [1] },
- },
- 'nowords-<1>' => {
- 'flagtypes.name' => { contains => [5] },
- },
- 'nowordssubstr-<1>' => {
- 'flagtypes.name' => { contains => [5] },
- },
- lessthan => {
- 'flagtypes.name' => { contains => [5] },
- },
- lessthaneq => {
- 'flagtypes.name' => { contains => [1, 5] },
- },
- regexp => {
- 'flagtypes.name' => { contains => [1, 5] },
- longdesc => { contains => [1] },
- },
- substring => {
- 'flagtypes.name' => { contains => [5] },
- longdesc => { contains => [1] },
- },
+ allwords => {
+ cc => {contains => [1]},
+ 'flagtypes.name' => {contains => [1, 5]},
+ longdesc => {contains => [1]},
+ },
+ 'allwords-<1> <2>' => {cc => {},},
+ allwordssubstr => {
+ cc => {contains => [1]},
+ 'flagtypes.name' => {contains => [5, 6]},
+ longdesc => {contains => [1]},
+ },
+ 'allwordssubstr-<1>,<2>' => {cc => {}, longdesc => {contains => [1]},},
+ anyexact => {'flagtypes.name' => {contains => [1, 2, 5]},},
+ 'anywords-<1>' => {'flagtypes.name' => {contains => [1, 2, 3, 4, 5]},},
+ 'anywords-<1> <2>' => {'flagtypes.name' => {contains => [3, 4, 5]},},
+ anywordssubstr => {'flagtypes.name' => {contains => [5]},},
+ 'anywordssubstr-<1> <2>' => {'flagtypes.name' => {contains => [3, 4, 5]},},
+ casesubstring => {'flagtypes.name' => {contains => [5]},},
+ changedafter => {
+ "attach_data.thedata" => {contains => [2, 3, 4]},
+ "classification" => {contains => [2, 3, 4]},
+ "commenter" => {contains => [2, 3, 4]},
+ percentage_complete => {contains => [2, 3, 4]},
+ "delta_ts" => {contains => [2, 3, 4]},
+ "requestees.login_name" => {contains => [2, 3, 4]},
+ "setters.login_name" => {contains => [2, 3, 4]},
+ },
+ changedbefore => {CHANGED_BROKEN_NOT,},
+ changedby => {
+ CHANGED_BROKEN_NOT,
+ creation_ts => {contains => [1]},
+ work_time => {contains => [1]},
+ },
+ changedfrom => {
+ CHANGED_BROKEN_NOT, CHANGED_FROM_TO_BROKEN_NOT,
+ 'attach_data.thedata' => {},
+ blocked => {contains => [1, 2]},
+ dependson => {contains => [1, 3]},
+ work_time => {contains => [1]},
+ FIELD_TYPE_BUG_ID, {contains => [1 .. 4]},
+ },
+ changedto => {
+ CHANGED_BROKEN_NOT, CHANGED_FROM_TO_BROKEN_NOT,
+ longdesc => {contains => [1]},
+ "remaining_time" => {contains => [1]},
+ },
+ greaterthan =>
+ {cc => {contains => [1]}, 'flagtypes.name' => {contains => [5]},},
+ greaterthaneq =>
+ {cc => {contains => [1]}, 'flagtypes.name' => {contains => [2, 5]},},
+ equals => {'flagtypes.name' => {contains => [1, 5]},},
+ notequals => {longdesc => {contains => [1]},},
+ notregexp => {longdesc => {contains => [1]},},
+ notsubstring => {longdesc => {contains => [1]},},
+ 'nowords-<1>' => {'flagtypes.name' => {contains => [5]},},
+ 'nowordssubstr-<1>' => {'flagtypes.name' => {contains => [5]},},
+ lessthan => {'flagtypes.name' => {contains => [5]},},
+ lessthaneq => {'flagtypes.name' => {contains => [1, 5]},},
+ regexp =>
+ {'flagtypes.name' => {contains => [1, 5]}, longdesc => {contains => [1]},},
+ substring =>
+ {'flagtypes.name' => {contains => [5]}, longdesc => {contains => [1]},},
};
#############
@@ -507,113 +443,117 @@ use constant BROKEN_NOT => {
# Regex tests need unique test values for certain fields.
use constant REGEX_OVERRIDE => {
- 'attachments.mimetype' => { value => '^text/x-1-' },
- bug_file_loc => { value => '^http://1-' },
- see_also => { value => '^http://1-' },
- blocked => { value => '^<1>$' },
- dependson => { value => '^<1>$' },
- bug_id => { value => '^<1>$' },
- 'attachments.isobsolete' => { value => '^1'},
- 'attachments.ispatch' => { value => '^1'},
- 'attachments.isprivate' => { value => '^1' },
- cclist_accessible => { value => '^1' },
- reporter_accessible => { value => '^1' },
- everconfirmed => { value => '^1' },
- 'longdescs.count' => { value => '^3' },
- 'longdescs.isprivate' => { value => '^1' },
- creation_ts => { value => '^2037-01-01' },
- delta_ts => { value => '^2037-01-01' },
- deadline => { value => '^2037-02-01' },
- estimated_time => { value => '^1.0' },
- remaining_time => { value => '^9.0' },
- work_time => { value => '^1.0' },
- longdesc => { value => '^1-' },
- percentage_complete => { value => '^10' },
- FIELD_TYPE_BUG_ID, { value => '^<1>$' },
- FIELD_TYPE_DATETIME, { value => '^2037-03-01' }
+ 'attachments.mimetype' => {value => '^text/x-1-'},
+ bug_file_loc => {value => '^http://1-'},
+ see_also => {value => '^http://1-'},
+ blocked => {value => '^<1>$'},
+ dependson => {value => '^<1>$'},
+ bug_id => {value => '^<1>$'},
+ 'attachments.isobsolete' => {value => '^1'},
+ 'attachments.ispatch' => {value => '^1'},
+ 'attachments.isprivate' => {value => '^1'},
+ cclist_accessible => {value => '^1'},
+ reporter_accessible => {value => '^1'},
+ everconfirmed => {value => '^1'},
+ 'longdescs.count' => {value => '^3'},
+ 'longdescs.isprivate' => {value => '^1'},
+ creation_ts => {value => '^2037-01-01'},
+ delta_ts => {value => '^2037-01-01'},
+ deadline => {value => '^2037-02-01'},
+ estimated_time => {value => '^1.0'},
+ remaining_time => {value => '^9.0'},
+ work_time => {value => '^1.0'},
+ longdesc => {value => '^1-'},
+ percentage_complete => {value => '^10'},
+ FIELD_TYPE_BUG_ID, {value => '^<1>$'}, FIELD_TYPE_DATETIME,
+ {value => '^2037-03-01'}
};
# Common overrides between lessthan and lessthaneq.
use constant LESSTHAN_OVERRIDE => (
- alias => { contains => [1,5] },
- estimated_time => { contains => [1,5] },
- qa_contact => { contains => [1,5] },
- resolution => { contains => [1,5] },
- status_whiteboard => { contains => [1,5] },
- FIELD_TYPE_TEXTAREA, { contains => [1,5] },
- FIELD_TYPE_FREETEXT, { contains => [1,5] },
+ alias => {contains => [1, 5]},
+ estimated_time => {contains => [1, 5]},
+ qa_contact => {contains => [1, 5]},
+ resolution => {contains => [1, 5]},
+ status_whiteboard => {contains => [1, 5]},
+ FIELD_TYPE_TEXTAREA, {contains => [1, 5]}, FIELD_TYPE_FREETEXT,
+ {contains => [1, 5]},
);
# The mandatorily-set fields have values higher than <1>,
# so bug 5 shows up.
use constant GREATERTHAN_OVERRIDE => (
- classification => { contains => [2,3,4,5] },
- assigned_to => { contains => [2,3,4,5] },
- bug_id => { contains => [2,3,4,5] },
- bug_group => { contains => [1,2,3,4] },
- bug_severity => { contains => [2,3,4,5] },
- bug_status => { contains => [2,3,4,5] },
- component => { contains => [2,3,4,5] },
- commenter => { contains => [2,3,4,5] },
- # keywords matches if *any* keyword matches
- keywords => { contains => [1,2,3,4] },
- longdesc => { contains => [1,2,3,4] },
- op_sys => { contains => [2,3,4,5] },
- priority => { contains => [2,3,4,5] },
- product => { contains => [2,3,4,5] },
- reporter => { contains => [2,3,4,5] },
- rep_platform => { contains => [2,3,4,5] },
- short_desc => { contains => [2,3,4,5] },
- version => { contains => [2,3,4,5] },
- tag => { contains => [1,2,3,4] },
- target_milestone => { contains => [2,3,4,5] },
- # Bug 2 is the only bug besides 1 that has a Requestee set.
- 'requestees.login_name' => { contains => [2] },
- FIELD_TYPE_SINGLE_SELECT, { contains => [2,3,4,5] },
- # Override SINGLE_SELECT for resolution.
- resolution => { contains => [2,3,4] },
- # MULTI_SELECTs match if *any* value matches
- FIELD_TYPE_MULTI_SELECT, { contains => [1,2,3,4] },
+ classification => {contains => [2, 3, 4, 5]},
+ assigned_to => {contains => [2, 3, 4, 5]},
+ bug_id => {contains => [2, 3, 4, 5]},
+ bug_group => {contains => [1, 2, 3, 4]},
+ bug_severity => {contains => [2, 3, 4, 5]},
+ bug_status => {contains => [2, 3, 4, 5]},
+ component => {contains => [2, 3, 4, 5]},
+ commenter => {contains => [2, 3, 4, 5]},
+
+ # keywords matches if *any* keyword matches
+ keywords => {contains => [1, 2, 3, 4]},
+ longdesc => {contains => [1, 2, 3, 4]},
+ op_sys => {contains => [2, 3, 4, 5]},
+ priority => {contains => [2, 3, 4, 5]},
+ product => {contains => [2, 3, 4, 5]},
+ reporter => {contains => [2, 3, 4, 5]},
+ rep_platform => {contains => [2, 3, 4, 5]},
+ short_desc => {contains => [2, 3, 4, 5]},
+ version => {contains => [2, 3, 4, 5]},
+ tag => {contains => [1, 2, 3, 4]},
+ target_milestone => {contains => [2, 3, 4, 5]},
+
+ # Bug 2 is the only bug besides 1 that has a Requestee set.
+ 'requestees.login_name' => {contains => [2]},
+ FIELD_TYPE_SINGLE_SELECT, {contains => [2, 3, 4, 5]},
+
+ # Override SINGLE_SELECT for resolution.
+ resolution => {contains => [2, 3, 4]},
+
+ # MULTI_SELECTs match if *any* value matches
+ FIELD_TYPE_MULTI_SELECT, {contains => [1, 2, 3, 4]},
);
# For all positive multi-value types.
use constant MULTI_BOOLEAN_OVERRIDE => (
- 'attachments.ispatch' => { value => '1,1', contains => [1] },
- 'attachments.isobsolete' => { value => '1,1', contains => [1] },
- 'attachments.isprivate' => { value => '1,1', contains => [1] },
- cclist_accessible => { value => '1,1', contains => [1] },
- reporter_accessible => { value => '1,1', contains => [1] },
- 'longdescs.isprivate' => { value => '1,1', contains => [1] },
- everconfirmed => { value => '1,1', contains => [1] },
+ 'attachments.ispatch' => {value => '1,1', contains => [1]},
+ 'attachments.isobsolete' => {value => '1,1', contains => [1]},
+ 'attachments.isprivate' => {value => '1,1', contains => [1]},
+ cclist_accessible => {value => '1,1', contains => [1]},
+ reporter_accessible => {value => '1,1', contains => [1]},
+ 'longdescs.isprivate' => {value => '1,1', contains => [1]},
+ everconfirmed => {value => '1,1', contains => [1]},
);
# Same as above, for negative multi-value types.
use constant NEGATIVE_MULTI_BOOLEAN_OVERRIDE => (
- 'attachments.ispatch' => { value => '1,1', contains => [2,3,4,5] },
- 'attachments.isobsolete' => { value => '1,1', contains => [2,3,4,5] },
- 'attachments.isprivate' => { value => '1,1', contains => [2,3,4,5] },
- cclist_accessible => { value => '1,1', contains => [2,3,4,5] },
- reporter_accessible => { value => '1,1', contains => [2,3,4,5] },
- 'longdescs.isprivate' => { value => '1,1', contains => [2,3,4,5] },
- everconfirmed => { value => '1,1', contains => [2,3,4,5] },
+ 'attachments.ispatch' => {value => '1,1', contains => [2, 3, 4, 5]},
+ 'attachments.isobsolete' => {value => '1,1', contains => [2, 3, 4, 5]},
+ 'attachments.isprivate' => {value => '1,1', contains => [2, 3, 4, 5]},
+ cclist_accessible => {value => '1,1', contains => [2, 3, 4, 5]},
+ reporter_accessible => {value => '1,1', contains => [2, 3, 4, 5]},
+ 'longdescs.isprivate' => {value => '1,1', contains => [2, 3, 4, 5]},
+ everconfirmed => {value => '1,1', contains => [2, 3, 4, 5]},
);
# For anyexact and anywordssubstr
use constant ANY_OVERRIDE => (
- 'longdescs.count' => { contains => [1,2,3,4] },
- 'work_time' => { value => '1.0,2.0' },
- dependson => { value => '<1>,<3>', contains => [1,3] },
- MULTI_BOOLEAN_OVERRIDE,
+ 'longdescs.count' => {contains => [1, 2, 3, 4]},
+ 'work_time' => {value => '1.0,2.0'},
+ dependson => {value => '<1>,<3>', contains => [1, 3]},
+ MULTI_BOOLEAN_OVERRIDE,
);
# For all the changed* searches. The ones that have empty contains
# are fields that never change in value, or will never be rationally
# tracked in bugs_activity.
use constant CHANGED_OVERRIDE => (
- 'attachments.submitter' => { contains => [] },
- bug_id => { contains => [] },
- reporter => { contains => [] },
- tag => { contains => [] },
+ 'attachments.submitter' => {contains => []},
+ bug_id => {contains => []},
+ reporter => {contains => []},
+ tag => {contains => []},
);
#########
@@ -673,298 +613,326 @@ use constant CHANGED_OVERRIDE => (
# override: This allows you to override "contains" and "values" for
# certain fields.
use constant TESTS => {
- equals => [
- { contains => [1], value => '<1>' },
- ],
- notequals => [
- { contains => [2,3,4,5], value => '<1>' },
- ],
- substring => [
- { contains => [1], value => '<1>',
- override => {
- percentage_complete => { contains => [1,2,3] },
- }
- },
- ],
- casesubstring => [
- { contains => [1], value => '<1>',
- override => {
- percentage_complete => { contains => [1,2,3] },
- }
- },
- { contains => [], value => '<1>', transform => sub { lc($_[0]) },
- extra_name => 'lc', if_equal => { contains => [1] },
- override => {
- percentage_complete => { contains => [1,2,3] },
- }
- },
- ],
- notsubstring => [
- { contains => [2,3,4,5], value => '<1>',
- override => {
- percentage_complete => { contains => [4,5] },
- },
- }
- ],
- regexp => [
- { contains => [1], value => '<1>', escape => 1,
- override => {
- percentage_complete => { value => '^10' },
- }
- },
- { contains => [1], value => '^1-', override => REGEX_OVERRIDE },
- ],
- notregexp => [
- { contains => [2,3,4,5], value => '<1>', escape => 1,
- override => {
- percentage_complete => { value => '^10' },
- }
- },
- { contains => [2,3,4,5], value => '^1-', override => REGEX_OVERRIDE },
- ],
- lessthan => [
- { contains => [1], value => 2,
- override => {
- # A lot of these contain bug 5 because an empty value is validly
- # less than the specified value.
- bug_file_loc => { value => 'http://2-', contains => [1,5] },
- see_also => { value => 'http://2-' },
- 'attachments.mimetype' => { value => 'text/x-2-' },
- blocked => { value => '<4-id>', contains => [1,2] },
- dependson => { value => '<3-id>', contains => [1,3] },
- bug_id => { value => '<2-id>' },
- 'attachments.isprivate' => { value => 1, contains => [2,3,4] },
- 'attachments.isobsolete' => { value => 1, contains => [2,3,4] },
- 'attachments.ispatch' => { value => 1, contains => [2,3,4] },
- cclist_accessible => { value => 1, contains => [2,3,4,5] },
- reporter_accessible => { value => 1, contains => [2,3,4,5] },
- 'longdescs.count' => { value => 3, contains => [2,3,4,5] },
- 'longdescs.isprivate' => { value => 1, contains => [1,2,3,4,5] },
- everconfirmed => { value => 1, contains => [2,3,4,5] },
- creation_ts => { value => '2037-01-02', contains => [1,5] },
- delta_ts => { value => '2037-01-02', contains => [1,5] },
- deadline => { value => '2037-02-02', contains => [1,5] },
- remaining_time => { value => 10, contains => [1,5] },
- percentage_complete => { value => 11, contains => [1,5] },
- longdesc => { value => '2-', contains => [1,5] },
- work_time => { value => 1, contains => [5] },
- FIELD_TYPE_BUG_ID, { value => '<2>', contains => [1,5] },
- FIELD_TYPE_DATETIME, { value => '2037-03-02', contains => [1,5] },
- LESSTHAN_OVERRIDE,
- }
- },
- ],
- lessthaneq => [
- { contains => [1], value => '<1>',
- override => {
- 'attachments.isobsolete' => { value => 0, contains => [2,3,4] },
- 'attachments.ispatch' => { value => 0, contains => [2,3,4] },
- 'attachments.isprivate' => { value => 0, contains => [2,3,4] },
- cclist_accessible => { value => 0, contains => [2,3,4,5] },
- reporter_accessible => { value => 0, contains => [2,3,4,5] },
- 'longdescs.count' => { value => 2, contains => [2,3,4,5] },
- 'longdescs.isprivate' => { value => -1, contains => [] },
- everconfirmed => { value => 0, contains => [2,3,4,5] },
- bug_file_loc => { contains => [1,5] },
- blocked => { contains => [1,2] },
- deadline => { contains => [1,5] },
- dependson => { contains => [1,3] },
- creation_ts => { contains => [1,5] },
- delta_ts => { contains => [1,5] },
- remaining_time => { contains => [1,5] },
- longdesc => { contains => [1,5] },
- percentage_complete => { contains => [1,5] },
- work_time => { value => 1, contains => [1,5] },
- FIELD_TYPE_BUG_ID, { contains => [1,5] },
- FIELD_TYPE_DATETIME, { contains => [1,5] },
- LESSTHAN_OVERRIDE,
- },
- },
- ],
- greaterthan => [
- { contains => [2,3,4], value => '<1>',
- override => {
- dependson => { contains => [3] },
- blocked => { contains => [2] },
- 'attachments.ispatch' => { value => 0, contains => [1] },
- 'attachments.isobsolete' => { value => 0, contains => [1] },
- 'attachments.isprivate' => { value => 0, contains => [1] },
- cclist_accessible => { value => 0, contains => [1] },
- reporter_accessible => { value => 0, contains => [1] },
- 'longdescs.count' => { value => 2, contains => [1] },
- 'longdescs.isprivate' => { value => 0, contains => [1] },
- everconfirmed => { value => 0, contains => [1] },
- 'flagtypes.name' => { value => 2, contains => [2,3,4] },
- GREATERTHAN_OVERRIDE,
- },
- },
- ],
- greaterthaneq => [
- { contains => [2,3,4], value => '<2>',
- override => {
- 'attachments.ispatch' => { value => 1, contains => [1] },
- 'attachments.isobsolete' => { value => 1, contains => [1] },
- 'attachments.isprivate' => { value => 1, contains => [1] },
- cclist_accessible => { value => 1, contains => [1] },
- reporter_accessible => { value => 1, contains => [1] },
- 'longdescs.count' => { value => 3, contains => [1] },
- 'longdescs.isprivate' => { value => 1, contains => [1] },
- everconfirmed => { value => 1, contains => [1] },
- dependson => { value => '<3>', contains => [1,3] },
- blocked => { contains => [1,2] },
- GREATERTHAN_OVERRIDE,
- }
- },
- ],
- matches => [
- { contains => [1], value => '<1>' },
- ],
- notmatches => [
- { contains => [2,3,4,5], value => '<1>' },
- ],
- anyexact => [
- { contains => [1,2], value => '<1>, <2>',
- override => { ANY_OVERRIDE } },
- ],
- anywordssubstr => [
- { contains => [1,2], value => '<1> <2>',
- override => {
- ANY_OVERRIDE,
- percentage_complete => { contains => [1,2,3] },
- }
- },
- ],
- allwordssubstr => [
- { contains => [1], value => '<1>',
- override => {
- MULTI_BOOLEAN_OVERRIDE,
- # We search just the number "1" for percentage_complete,
- # which matches a lot of bugs.
- percentage_complete => { contains => [1,2,3] },
- },
- },
- { contains => [], value => '<1>,<2>',
- override => {
- dependson => { value => '<1-id> <3-id>', contains => [] },
- # bug 3 has the value "21" here, so matches "2,1"
- percentage_complete => { value => '<2>,<3>', contains => [3] },
- # 1 0 matches bug 1, which has both public and private comments.
- 'longdescs.isprivate' => { contains => [1] },
- }
- },
- ],
- nowordssubstr => [
- { contains => [2,3,4,5], value => '<1>',
- override => {
- # longdescs.isprivate translates to "1 0", so no bugs should
- # show up.
- 'longdescs.isprivate' => { contains => [] },
- percentage_complete => { contains => [4,5] },
- work_time => { contains => [2,3,4,5] },
- }
- },
- ],
- anywords => [
- { contains => [1], value => '<1>',
- override => {
- MULTI_BOOLEAN_OVERRIDE,
- }
- },
- { contains => [1,2], value => '<1> <2>',
- override => {
- MULTI_BOOLEAN_OVERRIDE,
- dependson => { value => '<1> <3>', contains => [1,3] },
- 'longdescs.count' => { contains => [1,2,3,4] },
- },
- },
- ],
- allwords => [
- { contains => [1], value => '<1>',
- override => { MULTI_BOOLEAN_OVERRIDE } },
- { contains => [], value => '<1> <2>',
- override => {
- dependson => { contains => [], value => '<2-id> <3-id>' },
- # 1 0 matches bug 1, which has both public and private comments.
- 'longdescs.isprivate' => { contains => [1] },
- }
- },
- ],
- nowords => [
- { contains => [2,3,4,5], value => '<1>',
- override => {
- # longdescs.isprivate translates to "1 0", so no bugs should
- # show up.
- 'longdescs.isprivate' => { contains => [] },
- work_time => { contains => [2,3,4,5] },
- }
- },
- ],
-
- changedbefore => [
- { contains => [1], value => '<1-delta>',
- override => {
- CHANGED_OVERRIDE,
- creation_ts => { contains => [1,5] },
- blocked => { contains => [1,2] },
- dependson => { contains => [1,3] },
- longdesc => { contains => [1,5] },
- 'longdescs.count' => { contains => [1,5] },
- }
- },
- ],
- changedafter => [
- { contains => [2,3,4], value => '<2-delta>',
- override => {
- CHANGED_OVERRIDE,
- creation_ts => { contains => [3,4] },
- # We only change this for one bug, and it doesn't match.
- 'longdescs.isprivate' => { contains => [] },
- # Same for everconfirmed.
- 'everconfirmed' => { contains => [] },
- # For blocked and dependson, they have the delta_ts of bug1
- # in the bugs_activity table, so they won't ever match.
- blocked => { contains => [] },
- dependson => { contains => [] },
- }
- },
- ],
- changedfrom => [
- { contains => [1], value => '<1>',
- override => {
- CHANGED_OVERRIDE,
- # The test never changes an already-set dependency field, but
- # we *can* attempt to test searching against an empty value,
- # which should get us some bugs.
- blocked => { value => '', contains => [1,2] },
- dependson => { value => '', contains => [1,3] },
- FIELD_TYPE_BUG_ID, { value => '', contains => [1,2,3,4] },
- # longdesc changedfrom doesn't make any sense.
- longdesc => { contains => [] },
- # Nor does creation_ts changedfrom.
- creation_ts => { contains => [] },
- 'attach_data.thedata' => { contains => [] },
- bug_id => { value => '<1-id>', contains => [] },
- },
- },
- ],
- changedto => [
- { contains => [1], value => '<1>',
- override => {
- CHANGED_OVERRIDE,
- # I can't imagine any use for creation_ts changedto.
- creation_ts => { contains => [] },
- }
- },
- ],
- changedby => [
- { contains => [1], value => '<1-reporter>',
- override => {
- CHANGED_OVERRIDE,
- blocked => { contains => [1,2] },
- dependson => { contains => [1,3] },
- },
- },
- ],
+ equals => [{contains => [1], value => '<1>'},],
+ notequals => [{contains => [2, 3, 4, 5], value => '<1>'},],
+ substring => [
+ {
+ contains => [1],
+ value => '<1>',
+ override => {percentage_complete => {contains => [1, 2, 3]},}
+ },
+ ],
+ casesubstring => [
+ {
+ contains => [1],
+ value => '<1>',
+ override => {percentage_complete => {contains => [1, 2, 3]},}
+ },
+ {
+ contains => [],
+ value => '<1>',
+ transform => sub { lc($_[0]) },
+ extra_name => 'lc',
+ if_equal => {contains => [1]},
+ override => {percentage_complete => {contains => [1, 2, 3]},}
+ },
+ ],
+ notsubstring => [{
+ contains => [2, 3, 4, 5],
+ value => '<1>',
+ override => {percentage_complete => {contains => [4, 5]},},
+ }],
+ regexp => [
+ {
+ contains => [1],
+ value => '<1>',
+ escape => 1,
+ override => {percentage_complete => {value => '^10'},}
+ },
+ {contains => [1], value => '^1-', override => REGEX_OVERRIDE},
+ ],
+ notregexp => [
+ {
+ contains => [2, 3, 4, 5],
+ value => '<1>',
+ escape => 1,
+ override => {percentage_complete => {value => '^10'},}
+ },
+ {contains => [2, 3, 4, 5], value => '^1-', override => REGEX_OVERRIDE},
+ ],
+ lessthan => [
+ {
+ contains => [1],
+ value => 2,
+ override => {
+
+ # A lot of these contain bug 5 because an empty value is validly
+ # less than the specified value.
+ bug_file_loc => {value => 'http://2-', contains => [1, 5]},
+ see_also => {value => 'http://2-'},
+ 'attachments.mimetype' => {value => 'text/x-2-'},
+ blocked => {value => '<4-id>', contains => [1, 2]},
+ dependson => {value => '<3-id>', contains => [1, 3]},
+ bug_id => {value => '<2-id>'},
+ 'attachments.isprivate' => {value => 1, contains => [2, 3, 4]},
+ 'attachments.isobsolete' => {value => 1, contains => [2, 3, 4]},
+ 'attachments.ispatch' => {value => 1, contains => [2, 3, 4]},
+ cclist_accessible => {value => 1, contains => [2, 3, 4, 5]},
+ reporter_accessible => {value => 1, contains => [2, 3, 4, 5]},
+ 'longdescs.count' => {value => 3, contains => [2, 3, 4, 5]},
+ 'longdescs.isprivate' => {value => 1, contains => [1, 2, 3, 4, 5]},
+ everconfirmed => {value => 1, contains => [2, 3, 4, 5]},
+ creation_ts => {value => '2037-01-02', contains => [1, 5]},
+ delta_ts => {value => '2037-01-02', contains => [1, 5]},
+ deadline => {value => '2037-02-02', contains => [1, 5]},
+ remaining_time => {value => 10, contains => [1, 5]},
+ percentage_complete => {value => 11, contains => [1, 5]},
+ longdesc => {value => '2-', contains => [1, 5]},
+ work_time => {value => 1, contains => [5]},
+ FIELD_TYPE_BUG_ID, {value => '<2>', contains => [1, 5]}, FIELD_TYPE_DATETIME,
+ {value => '2037-03-02', contains => [1, 5]}, LESSTHAN_OVERRIDE,
+ }
+ },
+ ],
+ lessthaneq => [
+ {
+ contains => [1],
+ value => '<1>',
+ override => {
+ 'attachments.isobsolete' => {value => 0, contains => [2, 3, 4]},
+ 'attachments.ispatch' => {value => 0, contains => [2, 3, 4]},
+ 'attachments.isprivate' => {value => 0, contains => [2, 3, 4]},
+ cclist_accessible => {value => 0, contains => [2, 3, 4, 5]},
+ reporter_accessible => {value => 0, contains => [2, 3, 4, 5]},
+ 'longdescs.count' => {value => 2, contains => [2, 3, 4, 5]},
+ 'longdescs.isprivate' => {value => -1, contains => []},
+ everconfirmed => {value => 0, contains => [2, 3, 4, 5]},
+ bug_file_loc => {contains => [1, 5]},
+ blocked => {contains => [1, 2]},
+ deadline => {contains => [1, 5]},
+ dependson => {contains => [1, 3]},
+ creation_ts => {contains => [1, 5]},
+ delta_ts => {contains => [1, 5]},
+ remaining_time => {contains => [1, 5]},
+ longdesc => {contains => [1, 5]},
+ percentage_complete => {contains => [1, 5]},
+ work_time => {value => 1, contains => [1, 5]},
+ FIELD_TYPE_BUG_ID, {contains => [1, 5]}, FIELD_TYPE_DATETIME,
+ {contains => [1, 5]}, LESSTHAN_OVERRIDE,
+ },
+ },
+ ],
+ greaterthan => [
+ {
+ contains => [2, 3, 4],
+ value => '<1>',
+ override => {
+ dependson => {contains => [3]},
+ blocked => {contains => [2]},
+ 'attachments.ispatch' => {value => 0, contains => [1]},
+ 'attachments.isobsolete' => {value => 0, contains => [1]},
+ 'attachments.isprivate' => {value => 0, contains => [1]},
+ cclist_accessible => {value => 0, contains => [1]},
+ reporter_accessible => {value => 0, contains => [1]},
+ 'longdescs.count' => {value => 2, contains => [1]},
+ 'longdescs.isprivate' => {value => 0, contains => [1]},
+ everconfirmed => {value => 0, contains => [1]},
+ 'flagtypes.name' => {value => 2, contains => [2, 3, 4]},
+ GREATERTHAN_OVERRIDE,
+ },
+ },
+ ],
+ greaterthaneq => [
+ {
+ contains => [2, 3, 4],
+ value => '<2>',
+ override => {
+ 'attachments.ispatch' => {value => 1, contains => [1]},
+ 'attachments.isobsolete' => {value => 1, contains => [1]},
+ 'attachments.isprivate' => {value => 1, contains => [1]},
+ cclist_accessible => {value => 1, contains => [1]},
+ reporter_accessible => {value => 1, contains => [1]},
+ 'longdescs.count' => {value => 3, contains => [1]},
+ 'longdescs.isprivate' => {value => 1, contains => [1]},
+ everconfirmed => {value => 1, contains => [1]},
+ dependson => {value => '<3>', contains => [1, 3]},
+ blocked => {contains => [1, 2]},
+ GREATERTHAN_OVERRIDE,
+ }
+ },
+ ],
+ matches => [{contains => [1], value => '<1>'},],
+ notmatches => [{contains => [2, 3, 4, 5], value => '<1>'},],
+ anyexact =>
+ [{contains => [1, 2], value => '<1>, <2>', override => {ANY_OVERRIDE}},],
+ anywordssubstr => [
+ {
+ contains => [1, 2],
+ value => '<1> <2>',
+ override => {ANY_OVERRIDE, percentage_complete => {contains => [1, 2, 3]},}
+ },
+ ],
+ allwordssubstr => [
+ {
+ contains => [1],
+ value => '<1>',
+ override => {
+ MULTI_BOOLEAN_OVERRIDE,
+
+ # We search just the number "1" for percentage_complete,
+ # which matches a lot of bugs.
+ percentage_complete => {contains => [1, 2, 3]},
+ },
+ },
+ {
+ contains => [],
+ value => '<1>,<2>',
+ override => {
+ dependson => {value => '<1-id> <3-id>', contains => []},
+
+ # bug 3 has the value "21" here, so matches "2,1"
+ percentage_complete => {value => '<2>,<3>', contains => [3]},
+
+ # 1 0 matches bug 1, which has both public and private comments.
+ 'longdescs.isprivate' => {contains => [1]},
+ }
+ },
+ ],
+ nowordssubstr => [
+ {
+ contains => [2, 3, 4, 5],
+ value => '<1>',
+ override => {
+
+ # longdescs.isprivate translates to "1 0", so no bugs should
+ # show up.
+ 'longdescs.isprivate' => {contains => []},
+ percentage_complete => {contains => [4, 5]},
+ work_time => {contains => [2, 3, 4, 5]},
+ }
+ },
+ ],
+ anywords => [
+ {contains => [1], value => '<1>', override => {MULTI_BOOLEAN_OVERRIDE,}},
+ {
+ contains => [1, 2],
+ value => '<1> <2>',
+ override => {
+ MULTI_BOOLEAN_OVERRIDE,
+ dependson => {value => '<1> <3>', contains => [1, 3]},
+ 'longdescs.count' => {contains => [1, 2, 3, 4]},
+ },
+ },
+ ],
+ allwords => [
+ {contains => [1], value => '<1>', override => {MULTI_BOOLEAN_OVERRIDE}},
+ {
+ contains => [],
+ value => '<1> <2>',
+ override => {
+ dependson => {contains => [], value => '<2-id> <3-id>'},
+
+ # 1 0 matches bug 1, which has both public and private comments.
+ 'longdescs.isprivate' => {contains => [1]},
+ }
+ },
+ ],
+ nowords => [
+ {
+ contains => [2, 3, 4, 5],
+ value => '<1>',
+ override => {
+
+ # longdescs.isprivate translates to "1 0", so no bugs should
+ # show up.
+ 'longdescs.isprivate' => {contains => []},
+ work_time => {contains => [2, 3, 4, 5]},
+ }
+ },
+ ],
+
+ changedbefore => [
+ {
+ contains => [1],
+ value => '<1-delta>',
+ override => {
+ CHANGED_OVERRIDE,
+ creation_ts => {contains => [1, 5]},
+ blocked => {contains => [1, 2]},
+ dependson => {contains => [1, 3]},
+ longdesc => {contains => [1, 5]},
+ 'longdescs.count' => {contains => [1, 5]},
+ }
+ },
+ ],
+ changedafter => [
+ {
+ contains => [2, 3, 4],
+ value => '<2-delta>',
+ override => {
+ CHANGED_OVERRIDE,
+ creation_ts => {contains => [3, 4]},
+
+ # We only change this for one bug, and it doesn't match.
+ 'longdescs.isprivate' => {contains => []},
+
+ # Same for everconfirmed.
+ 'everconfirmed' => {contains => []},
+
+ # For blocked and dependson, they have the delta_ts of bug1
+ # in the bugs_activity table, so they won't ever match.
+ blocked => {contains => []},
+ dependson => {contains => []},
+ }
+ },
+ ],
+ changedfrom => [
+ {
+ contains => [1],
+ value => '<1>',
+ override => {
+ CHANGED_OVERRIDE,
+
+ # The test never changes an already-set dependency field, but
+ # we *can* attempt to test searching against an empty value,
+ # which should get us some bugs.
+ blocked => {value => '', contains => [1, 2]},
+ dependson => {value => '', contains => [1, 3]},
+ FIELD_TYPE_BUG_ID, {value => '', contains => [1, 2, 3, 4]},
+
+ # longdesc changedfrom doesn't make any sense.
+ longdesc => {contains => []},
+
+ # Nor does creation_ts changedfrom.
+ creation_ts => {contains => []},
+ 'attach_data.thedata' => {contains => []},
+ bug_id => {value => '<1-id>', contains => []},
+ },
+ },
+ ],
+ changedto => [
+ {
+ contains => [1],
+ value => '<1>',
+ override => {
+ CHANGED_OVERRIDE,
+
+ # I can't imagine any use for creation_ts changedto.
+ creation_ts => {contains => []},
+ }
+ },
+ ],
+ changedby => [
+ {
+ contains => [1],
+ value => '<1-reporter>',
+ override => {
+ CHANGED_OVERRIDE,
+ blocked => {contains => [1, 2]},
+ dependson => {contains => [1, 3]},
+ },
+ },
+ ],
};
# Fields that do not behave as we expect, for InjectionTest.
@@ -973,57 +941,62 @@ use constant TESTS => {
# operator_ok overrides the "brokenness" of certain operators, so that they
# are always OK for that field/operator combination.
use constant INJECTION_BROKEN_FIELD => {
- # Pg can't run injection tests against integer or date fields. See bug 577557.
- 'attachments.isobsolete' => { db_skip => ['Pg'] },
- 'attachments.ispatch' => { db_skip => ['Pg'] },
- 'attachments.isprivate' => { db_skip => ['Pg'] },
- blocked => { db_skip => ['Pg'] },
- bug_id => { db_skip => ['Pg'] },
- cclist_accessible => { db_skip => ['Pg'] },
- creation_ts => { db_skip => ['Pg'] },
- days_elapsed => { db_skip => ['Pg'] },
- dependson => { db_skip => ['Pg'] },
- deadline => { db_skip => ['Pg'] },
- delta_ts => { db_skip => ['Pg'] },
- estimated_time => { db_skip => ['Pg'] },
- everconfirmed => { db_skip => ['Pg'] },
- 'longdescs.isprivate' => { db_skip => ['Pg'] },
- percentage_complete => { db_skip => ['Pg'] },
- remaining_time => { db_skip => ['Pg'] },
- reporter_accessible => { db_skip => ['Pg'] },
- work_time => { db_skip => ['Pg'] },
- FIELD_TYPE_BUG_ID, { db_skip => ['Pg'] },
- FIELD_TYPE_DATETIME, { db_skip => ['Pg'] },
- owner_idle_time => { search => 1 },
- 'longdescs.count' => {
- search => 1,
- db_skip => ['Pg'],
- operator_ok => [qw(allwords allwordssubstr anywordssubstr casesubstring
- changedbefore changedafter greaterthan greaterthaneq
- lessthan lessthaneq notregexp notsubstring
- nowordssubstr regexp substring anywords
- notequals nowords equals anyexact)],
- },
+
+ # Pg can't run injection tests against integer or date fields. See bug 577557.
+ 'attachments.isobsolete' => {db_skip => ['Pg']},
+ 'attachments.ispatch' => {db_skip => ['Pg']},
+ 'attachments.isprivate' => {db_skip => ['Pg']},
+ blocked => {db_skip => ['Pg']},
+ bug_id => {db_skip => ['Pg']},
+ cclist_accessible => {db_skip => ['Pg']},
+ creation_ts => {db_skip => ['Pg']},
+ days_elapsed => {db_skip => ['Pg']},
+ dependson => {db_skip => ['Pg']},
+ deadline => {db_skip => ['Pg']},
+ delta_ts => {db_skip => ['Pg']},
+ estimated_time => {db_skip => ['Pg']},
+ everconfirmed => {db_skip => ['Pg']},
+ 'longdescs.isprivate' => {db_skip => ['Pg']},
+ percentage_complete => {db_skip => ['Pg']},
+ remaining_time => {db_skip => ['Pg']},
+ reporter_accessible => {db_skip => ['Pg']},
+ work_time => {db_skip => ['Pg']},
+ FIELD_TYPE_BUG_ID,
+ {db_skip => ['Pg']},
+ FIELD_TYPE_DATETIME,
+ {db_skip => ['Pg']},
+ owner_idle_time => {search => 1},
+ 'longdescs.count' => {
+ search => 1,
+ db_skip => ['Pg'],
+ operator_ok => [
+ qw(allwords allwordssubstr anywordssubstr casesubstring
+ changedbefore changedafter greaterthan greaterthaneq
+ lessthan lessthaneq notregexp notsubstring
+ nowordssubstr regexp substring anywords
+ notequals nowords equals anyexact)
+ ],
+ },
};
# Operators that do not behave as we expect, for InjectionTest.
# search => 1 means the Bugzilla::Search creation fails, but
# field_ok contains fields that it does actually succeed for.
use constant INJECTION_BROKEN_OPERATOR => {
- changedafter => { search => 1, field_ok => ['creation_ts'] },
- changedbefore => { search => 1, field_ok => ['creation_ts'] },
- changedby => { search => 1 },
+ changedafter => {search => 1, field_ok => ['creation_ts']},
+ changedbefore => {search => 1, field_ok => ['creation_ts']},
+ changedby => {search => 1},
};
# Tests run by Bugzilla::Test::Search::InjectionTest.
# We have to make sure the values are all one word or they'll be split
# up by the multi-word tests.
use constant INJECTION_TESTS => (
- { value => ';SEMICOLON_TEST' },
- { value => '--COMMENT_TEST' },
- { value => "'QUOTE_TEST" },
- { value => "';QUOTE_SEMICOLON_TEST" },
- { value => '/*STAR_COMMENT_TEST' }
+ {value => ';SEMICOLON_TEST'},
+ {value => '--COMMENT_TEST'},
+ {value => "'QUOTE_TEST"},
+ {value => "';QUOTE_SEMICOLON_TEST"},
+ {value => '/*STAR_COMMENT_TEST'}
);
#################
@@ -1031,185 +1004,257 @@ use constant INJECTION_TESTS => (
#################
use constant SPECIAL_PARAM_TESTS => (
- { field => 'bug_status', operator => 'anyexact', value => '__open__',
- contains => [5] },
- { field => 'bug_status', operator => 'anyexact', value => '__closed__',
- contains => [1,2,3,4] },
- { field => 'bug_status', operator => 'anyexact', value => '__all__',
- contains => [1,2,3,4,5] },
-
- { field => 'resolution', operator => 'anyexact', value => '---',
- contains => [5] },
-
- # email* query parameters.
- { field => 'assigned_to', operator => 'anyexact',
- value => '<1>, <2-reporter>', contains => [1,2],
- extra_params => { emailreporter1 => 1 } },
- { field => 'assigned_to', operator => 'equals',
- value => '<1>', extra_name => 'email2', contains => [],
- extra_params => {
- email2 => generate_random_password(100), emaillongdesc2 => 1,
- },
- },
-
- # standard pronouns
- { field => 'assigned_to', operator => 'equals', value => '%assignee%',
- contains => [1,2,3,4,5] },
- { field => 'reporter', operator => 'equals', value => '%reporter%',
- contains => [1,2,3,4,5] },
- { field => 'qa_contact', operator => 'equals', value => '%qacontact%',
- contains => [1,2,3,4,5] },
- { field => 'cc', operator => 'equals', value => '%user%',
- contains => [1] },
- # group pronouns
- { field => 'reporter', operator => 'equals',
- value => '%group.<1-bug_group>%', contains => [1,2,3,4,5] },
- { field => 'assigned_to', operator => 'equals',
- value => '%group.<1-bug_group>%', contains => [1,2,3,4,5] },
- { field => 'qa_contact', operator => 'equals',
- value => '%group.<1-bug_group>%', contains => [1,2,3,4] },
- { field => 'cc', operator => 'equals',
- value => '%group.<1-bug_group>%', contains => [1,2,3,4] },
- { field => 'commenter', operator => 'equals',
- value => '%group.<1-bug_group>%', contains => [1,2,3,4,5] },
+ {
+ field => 'bug_status',
+ operator => 'anyexact',
+ value => '__open__',
+ contains => [5]
+ },
+ {
+ field => 'bug_status',
+ operator => 'anyexact',
+ value => '__closed__',
+ contains => [1, 2, 3, 4]
+ },
+ {
+ field => 'bug_status',
+ operator => 'anyexact',
+ value => '__all__',
+ contains => [1, 2, 3, 4, 5]
+ },
+
+ {
+ field => 'resolution',
+ operator => 'anyexact',
+ value => '---',
+ contains => [5]
+ },
+
+ # email* query parameters.
+ {
+ field => 'assigned_to',
+ operator => 'anyexact',
+ value => '<1>, <2-reporter>',
+ contains => [1, 2],
+ extra_params => {emailreporter1 => 1}
+ },
+ {
+ field => 'assigned_to',
+ operator => 'equals',
+ value => '<1>',
+ extra_name => 'email2',
+ contains => [],
+ extra_params => {email2 => generate_random_password(100), emaillongdesc2 => 1,},
+ },
+
+ # standard pronouns
+ {
+ field => 'assigned_to',
+ operator => 'equals',
+ value => '%assignee%',
+ contains => [1, 2, 3, 4, 5]
+ },
+ {
+ field => 'reporter',
+ operator => 'equals',
+ value => '%reporter%',
+ contains => [1, 2, 3, 4, 5]
+ },
+ {
+ field => 'qa_contact',
+ operator => 'equals',
+ value => '%qacontact%',
+ contains => [1, 2, 3, 4, 5]
+ },
+ {field => 'cc', operator => 'equals', value => '%user%', contains => [1]},
+
+ # group pronouns
+ {
+ field => 'reporter',
+ operator => 'equals',
+ value => '%group.<1-bug_group>%',
+ contains => [1, 2, 3, 4, 5]
+ },
+ {
+ field => 'assigned_to',
+ operator => 'equals',
+ value => '%group.<1-bug_group>%',
+ contains => [1, 2, 3, 4, 5]
+ },
+ {
+ field => 'qa_contact',
+ operator => 'equals',
+ value => '%group.<1-bug_group>%',
+ contains => [1, 2, 3, 4]
+ },
+ {
+ field => 'cc',
+ operator => 'equals',
+ value => '%group.<1-bug_group>%',
+ contains => [1, 2, 3, 4]
+ },
+ {
+ field => 'commenter',
+ operator => 'equals',
+ value => '%group.<1-bug_group>%',
+ contains => [1, 2, 3, 4, 5]
+ },
);
use constant CUSTOM_SEARCH_TESTS => (
- { name => 'OP without CP', contains => [1],
- params => [
- { f => 'OP' },
- { f => 'bug_id', o => 'equals', v => '<1>' },
- ]
- },
-
- { name => 'Empty OP/CP pair before criteria', contains => [1],
- params => [
- { f => 'OP' }, { f => 'CP' },
- { f => 'bug_id', o => 'equals', v => '<1>' },
- ]
- },
-
- { name => 'Empty OP/CP pair after criteria', contains => [1],
- params => [
- { f => 'bug_id', o => 'equals', v => '<1>' },
- { f => 'OP' }, { f => 'CP' },
- ]
- },
-
- { name => 'empty OP/CP mid criteria', contains => [1],
- columns => ['assigned_to'],
- params => [
- { f => 'bug_id', o => 'equals', v => '<1>' },
- { f => 'OP' }, { f => 'CP' },
- { f => 'assigned_to', o => 'substr', v => '@' },
- ]
- },
-
- { name => 'bug_id = 1 AND assigned_to contains @', contains => [1],
- columns => ['assigned_to'],
- params => [
- { f => 'bug_id', o => 'equals', v => '<1>' },
- { f => 'assigned_to', o => 'substr', v => '@' },
- ]
- },
-
- { name => 'NOT(bug_id = 1) AND NOT(assigned_to = 2)',
- contains => [3,4,5],
- columns => ['assigned_to'],
- params => [
- { n => 1, f => 'bug_id', o => 'equals', v => '<1>' },
- { n => 1, f => 'assigned_to', o => 'equals', v => '<2>' },
- ]
- },
-
- { name => 'bug_id = 1 OR assigned_to = 2', contains => [1,2],
- columns => ['assigned_to'], top_params => { j_top => 'OR' },
- params => [
- { f => 'bug_id', o => 'equals', v => '<1>' },
- { f => 'assigned_to', o => 'equals', v => '<2>' },
- ]
- },
-
- { name => 'NOT(bug_id = 1 AND assigned_to = 1)', contains => [2,3,4,5],
- columns => ['assigned_to'],
- params => [
- { f => 'OP', n => 1 },
- { f => 'bug_id', o => 'equals', v => '<1>' },
- { f => 'assigned_to', o => 'equals', v => '<1>' },
- { f => 'CP' },
- ]
- },
-
-
- { name => '(bug_id = 1 AND assigned_to contains @) '
- . ' OR (bug_id = 2 AND assigned_to contains @)',
- contains => [1,2], columns => ['assigned_to'],
- top_params => { j_top => 'OR' },
- params => [
- { f => 'OP' },
- { f => 'bug_id', o => 'equals', v => '<1>' },
- { f => 'assigned_to', o => 'substr', v => '@' },
- { f => 'CP' },
- { f => 'OP' },
- { f => 'bug_id', o => 'equals', v => '<2>' },
- { f => 'assigned_to', o => 'substr', v => '@' },
- { f => 'CP' },
- ]
- },
-
- { name => '(bug_id = 1 OR assigned_to = 2) '
- . ' AND (bug_id = 2 OR assigned_to = 1)',
- contains => [1,2], columns => ['assigned_to'],
- params => [
- { f => 'OP', j => 'OR' },
- { f => 'bug_id', o => 'equals', v => '<1>' },
- { f => 'assigned_to', o => 'equals', v => '<2>' },
- { f => 'CP' },
- { f => 'OP', j => 'OR' },
- { f => 'bug_id', o => 'equals', v => '<2>' },
- { f => 'assigned_to', o => 'equals', v => '<1>' },
- { f => 'CP' },
- ]
- },
-
- { name => 'bug_id = 3 OR ( (bug_id = 1 OR assigned_to = 2) '
- . ' AND (bug_id = 2 OR assigned_to = 1) )',
- contains => [1,2,3], columns => ['assigned_to'],
- top_params => { j_top => 'OR' },
- params => [
- { f => 'bug_id', o => 'equals', v => '<3>' },
- { f => 'OP' },
- { f => 'OP', j => 'OR' },
- { f => 'bug_id', o => 'equals', v => '<1>' },
- { f => 'assigned_to', o => 'equals', v => '<2>' },
- { f => 'CP' },
- { f => 'OP', j => 'OR' },
- { f => 'bug_id', o => 'equals', v => '<2>' },
- { f => 'assigned_to', o => 'equals', v => '<1>' },
- { f => 'CP' },
- { f => 'CP' },
- ]
- },
-
- { name => 'bug_id = 3 OR ( (bug_id = 1 OR assigned_to = 2) '
- . ' AND (bug_id = 2 OR assigned_to = 1) ) OR bug_id = 4',
- contains => [1,2,3,4], columns => ['assigned_to'],
- top_params => { j_top => 'OR' },
- params => [
- { f => 'bug_id', o => 'equals', v => '<3>' },
- { f => 'OP' },
- { f => 'OP', j => 'OR' },
- { f => 'bug_id', o => 'equals', v => '<1>' },
- { f => 'assigned_to', o => 'equals', v => '<2>' },
- { f => 'CP' },
- { f => 'OP', j => 'OR' },
- { f => 'bug_id', o => 'equals', v => '<2>' },
- { f => 'assigned_to', o => 'equals', v => '<1>' },
- { f => 'CP' },
- { f => 'CP' },
- { f => 'bug_id', o => 'equals', v => '<4>' },
- ]
- },
+ {
+ name => 'OP without CP',
+ contains => [1],
+ params => [{f => 'OP'}, {f => 'bug_id', o => 'equals', v => '<1>'},]
+ },
+
+ {
+ name => 'Empty OP/CP pair before criteria',
+ contains => [1],
+ params =>
+ [{f => 'OP'}, {f => 'CP'}, {f => 'bug_id', o => 'equals', v => '<1>'},]
+ },
+
+ {
+ name => 'Empty OP/CP pair after criteria',
+ contains => [1],
+ params =>
+ [{f => 'bug_id', o => 'equals', v => '<1>'}, {f => 'OP'}, {f => 'CP'},]
+ },
+
+ {
+ name => 'empty OP/CP mid criteria',
+ contains => [1],
+ columns => ['assigned_to'],
+ params => [
+ {f => 'bug_id', o => 'equals', v => '<1>'},
+ {f => 'OP'},
+ {f => 'CP'},
+ {f => 'assigned_to', o => 'substr', v => '@'},
+ ]
+ },
+
+ {
+ name => 'bug_id = 1 AND assigned_to contains @',
+ contains => [1],
+ columns => ['assigned_to'],
+ params => [
+ {f => 'bug_id', o => 'equals', v => '<1>'},
+ {f => 'assigned_to', o => 'substr', v => '@'},
+ ]
+ },
+
+ {
+ name => 'NOT(bug_id = 1) AND NOT(assigned_to = 2)',
+ contains => [3, 4, 5],
+ columns => ['assigned_to'],
+ params => [
+ {n => 1, f => 'bug_id', o => 'equals', v => '<1>'},
+ {n => 1, f => 'assigned_to', o => 'equals', v => '<2>'},
+ ]
+ },
+
+ {
+ name => 'bug_id = 1 OR assigned_to = 2',
+ contains => [1, 2],
+ columns => ['assigned_to'],
+ top_params => {j_top => 'OR'},
+ params => [
+ {f => 'bug_id', o => 'equals', v => '<1>'},
+ {f => 'assigned_to', o => 'equals', v => '<2>'},
+ ]
+ },
+
+ {
+ name => 'NOT(bug_id = 1 AND assigned_to = 1)',
+ contains => [2, 3, 4, 5],
+ columns => ['assigned_to'],
+ params => [
+ {f => 'OP', n => 1},
+ {f => 'bug_id', o => 'equals', v => '<1>'},
+ {f => 'assigned_to', o => 'equals', v => '<1>'},
+ {f => 'CP'},
+ ]
+ },
+
+
+ {
+ name => '(bug_id = 1 AND assigned_to contains @) '
+ . ' OR (bug_id = 2 AND assigned_to contains @)',
+ contains => [1, 2],
+ columns => ['assigned_to'],
+ top_params => {j_top => 'OR'},
+ params => [
+ {f => 'OP'},
+ {f => 'bug_id', o => 'equals', v => '<1>'},
+ {f => 'assigned_to', o => 'substr', v => '@'},
+ {f => 'CP'},
+ {f => 'OP'},
+ {f => 'bug_id', o => 'equals', v => '<2>'},
+ {f => 'assigned_to', o => 'substr', v => '@'},
+ {f => 'CP'},
+ ]
+ },
+
+ {
+ name => '(bug_id = 1 OR assigned_to = 2) '
+ . ' AND (bug_id = 2 OR assigned_to = 1)',
+ contains => [1, 2],
+ columns => ['assigned_to'],
+ params => [
+ {f => 'OP', j => 'OR'},
+ {f => 'bug_id', o => 'equals', v => '<1>'},
+ {f => 'assigned_to', o => 'equals', v => '<2>'},
+ {f => 'CP'},
+ {f => 'OP', j => 'OR'},
+ {f => 'bug_id', o => 'equals', v => '<2>'},
+ {f => 'assigned_to', o => 'equals', v => '<1>'},
+ {f => 'CP'},
+ ]
+ },
+
+ {
+ name => 'bug_id = 3 OR ( (bug_id = 1 OR assigned_to = 2) '
+ . ' AND (bug_id = 2 OR assigned_to = 1) )',
+ contains => [1, 2, 3],
+ columns => ['assigned_to'],
+ top_params => {j_top => 'OR'},
+ params => [
+ {f => 'bug_id', o => 'equals', v => '<3>'},
+ {f => 'OP'},
+ {f => 'OP', j => 'OR'},
+ {f => 'bug_id', o => 'equals', v => '<1>'},
+ {f => 'assigned_to', o => 'equals', v => '<2>'},
+ {f => 'CP'},
+ {f => 'OP', j => 'OR'},
+ {f => 'bug_id', o => 'equals', v => '<2>'},
+ {f => 'assigned_to', o => 'equals', v => '<1>'},
+ {f => 'CP'},
+ {f => 'CP'},
+ ]
+ },
+
+ {
+ name => 'bug_id = 3 OR ( (bug_id = 1 OR assigned_to = 2) '
+ . ' AND (bug_id = 2 OR assigned_to = 1) ) OR bug_id = 4',
+ contains => [1, 2, 3, 4],
+ columns => ['assigned_to'],
+ top_params => {j_top => 'OR'},
+ params => [
+ {f => 'bug_id', o => 'equals', v => '<3>'},
+ {f => 'OP'},
+ {f => 'OP', j => 'OR'},
+ {f => 'bug_id', o => 'equals', v => '<1>'},
+ {f => 'assigned_to', o => 'equals', v => '<2>'},
+ {f => 'CP'},
+ {f => 'OP', j => 'OR'},
+ {f => 'bug_id', o => 'equals', v => '<2>'},
+ {f => 'assigned_to', o => 'equals', v => '<1>'},
+ {f => 'CP'},
+ {f => 'CP'},
+ {f => 'bug_id', o => 'equals', v => '<4>'},
+ ]
+ },
);