refactor: Introduce filter.is_exactly().

This new API replaces some more specific functions that were
only recently introduced:

        is_stream_only
        is_stream_topic_only
        is_pm_with_only
        is_for_only

We use the deterministically sorted "term_type" values for
matching.  (Notably "stream" will come before "topic".)
This commit is contained in:
Steve Howell
2018-05-08 16:08:48 +00:00
committed by Tim Abbott
parent 60e399f717
commit a176380df5
3 changed files with 45 additions and 90 deletions

View File

@@ -78,7 +78,7 @@ function assert_same_operators(result, terms) {
assert(filter.is_search());
assert(! filter.can_apply_locally());
assert(! filter.is_stream_only());
assert(! filter.is_exactly('stream'));
// If our only stream operator is negated, then for all intents and purposes,
// we don't consider ourselves to have a stream operator, because we don't
@@ -134,7 +134,7 @@ function assert_same_operators(result, terms) {
var filter = new Filter(operators);
assert.deepEqual(filter.operands('stream'), ['foo']);
assert(filter.is_stream_only());
assert(filter.is_exactly('stream'));
}());
(function test_public_operators() {
@@ -146,7 +146,7 @@ function assert_same_operators(result, terms) {
var filter = new Filter(operators);
assert_same_operators(filter.public_operators(), operators);
assert(!filter.is_stream_only());
assert(!filter.is_exactly('stream'));
global.page_params.narrow_stream = 'default';
operators = [
@@ -674,74 +674,75 @@ function make_sub(name, stream_id) {
{operator: 'stream', operand: 'My Stream'},
];
var filter = new Filter(terms);
assert.equal(filter.is_stream_only(), true);
assert.equal(filter.is_stream_topic_only(), false);
assert.equal(filter.is_pm_with_only(), false);
assert.equal(filter.is_exactly('stream'), true);
assert.equal(filter.is_exactly('stream', 'topic'), false);
assert.equal(filter.is_exactly('pm-with'), false);
terms = [
{operator: 'stream', operand: 'My Stream'},
// try a non-orthodox ordering
{operator: 'topic', operand: 'My Topic'},
{operator: 'stream', operand: 'My Stream'},
];
filter = new Filter(terms);
assert.equal(filter.is_stream_only(), false);
assert.equal(filter.is_stream_topic_only(), true);
assert.equal(filter.is_pm_with_only(), false);
assert.equal(filter.is_exactly('stream'), false);
assert.equal(filter.is_exactly('stream', 'topic'), true);
assert.equal(filter.is_exactly('pm-with'), false);
terms = [
{operator: 'stream', operand: 'My Stream', negated: true},
{operator: 'topic', operand: 'My Topic'},
];
filter = new Filter(terms);
assert.equal(filter.is_stream_only(), false);
assert.equal(filter.is_stream_topic_only(), false);
assert.equal(filter.is_pm_with_only(), false);
assert.equal(filter.is_exactly('stream'), false);
assert.equal(filter.is_exactly('stream', 'topic'), false);
assert.equal(filter.is_exactly('pm-with'), false);
terms = [
{operator: 'pm-with', operand: 'foo@example.com', negated: true},
];
filter = new Filter(terms);
assert.equal(filter.is_stream_only(), false);
assert.equal(filter.is_stream_topic_only(), false);
assert.equal(filter.is_pm_with_only(), false);
assert.equal(filter.is_exactly('stream'), false);
assert.equal(filter.is_exactly('stream', 'topic'), false);
assert.equal(filter.is_exactly('pm-with'), false);
terms = [
{operator: 'pm-with', operand: 'foo@example.com,bar@example.com'},
];
filter = new Filter(terms);
assert.equal(filter.is_stream_only(), false);
assert.equal(filter.is_stream_topic_only(), false);
assert.equal(filter.is_pm_with_only(), true);
assert.equal(filter.is_for_only('mentioned'), false);
assert.equal(filter.is_for_only('private'), false);
assert.equal(filter.is_exactly('stream'), false);
assert.equal(filter.is_exactly('stream', 'topic'), false);
assert.equal(filter.is_exactly('pm-with'), true);
assert.equal(filter.is_exactly('is-mentioned'), false);
assert.equal(filter.is_exactly('is-private'), false);
terms = [
{operator: 'is', operand: 'private'},
];
filter = new Filter(terms);
assert.equal(filter.is_for_only('mentioned'), false);
assert.equal(filter.is_for_only('private'), true);
assert.equal(filter.is_exactly('is-mentioned'), false);
assert.equal(filter.is_exactly('is-private'), true);
terms = [
{operator: 'is', operand: 'mentioned'},
];
filter = new Filter(terms);
assert.equal(filter.is_for_only('mentioned'), true);
assert.equal(filter.is_for_only('private'), false);
assert.equal(filter.is_exactly('is-mentioned'), true);
assert.equal(filter.is_exactly('is-private'), false);
terms = [
{operator: 'is', operand: 'mentioned'},
{operator: 'is', operand: 'starred'},
];
filter = new Filter(terms);
assert.equal(filter.is_for_only('mentioned'), false);
assert.equal(filter.is_for_only('private'), false);
assert.equal(filter.is_exactly('is-mentioned'), false);
assert.equal(filter.is_exactly('is-private'), false);
terms = [
{operator: 'is', operand: 'mentioned', negated: true},
];
filter = new Filter(terms);
assert.equal(filter.is_for_only('mentioned'), false);
assert.equal(filter.is_for_only('private'), false);
assert.equal(filter.is_exactly('is-mentioned'), false);
assert.equal(filter.is_exactly('is-private'), false);
}());
(function test_term_type() {

View File

@@ -403,62 +403,16 @@ Filter.prototype = {
return sorted_terms;
},
is_stream_only: function () {
if (this._operators.length !== 1) {
return false;
}
is_exactly: function () {
// TODO: in ES6 use spread operator
//
// Examples calls:
// filter.is_exactly('stream', 'topic')
// filter.is_exactly('pm-with')
var wanted_term_types = [].slice.call(arguments);
var term_types = this.sorted_term_types();
var term = this._operators[0];
if (term.negated) {
return false;
}
return (term.operator === 'stream');
},
is_stream_topic_only: function () {
if (this._operators.length !== 2) {
return false;
}
return this.has_operator('stream') && this.has_operator('topic');
},
is_pm_with_only: function () {
if (this._operators.length !== 1) {
return false;
}
var term = this._operators[0];
if (term.negated) {
return false;
}
return (term.operator === 'pm-with');
},
is_for_only: function (operand) {
// Call as:
// filter.is_for_only('mentioned')
// filter.is_for_only('private')
// filter.is_for_only('starred')
if (this._operators.length !== 1) {
return false;
}
var term = this._operators[0];
if (term.negated) {
return false;
}
if (term.operator !== 'is') {
return false;
}
return (term.operand === operand);
return _.isEqual(term_types, wanted_term_types);
},
update_email: function (user_id, new_email) {

View File

@@ -203,7 +203,7 @@ exports.get_unread_ids = function () {
var topic_name;
var pm_string;
if (current_filter.is_stream_only()) {
if (current_filter.is_exactly('stream')) {
stream_id = exports.stream_id();
if (stream_id === undefined) {
return [];
@@ -211,7 +211,7 @@ exports.get_unread_ids = function () {
return unread.get_msg_ids_for_stream(stream_id);
}
if (current_filter.is_stream_topic_only()) {
if (current_filter.is_exactly('stream', 'topic')) {
stream_id = exports.stream_id();
if (stream_id === undefined) {
return [];
@@ -220,7 +220,7 @@ exports.get_unread_ids = function () {
return unread.get_msg_ids_for_topic(stream_id, topic_name);
}
if (current_filter.is_pm_with_only()) {
if (current_filter.is_exactly('pm-with')) {
pm_string = exports.pm_string();
if (pm_string === undefined) {
return [];
@@ -228,15 +228,15 @@ exports.get_unread_ids = function () {
return unread.get_msg_ids_for_person(pm_string);
}
if (current_filter.is_for_only('private')) {
if (current_filter.is_exactly('is-private')) {
return unread.get_msg_ids_for_private();
}
if (current_filter.is_for_only('mentioned')) {
if (current_filter.is_exactly('is-mentioned')) {
return unread.get_msg_ids_for_mentions();
}
if (current_filter.is_for_only('starred')) {
if (current_filter.is_exactly('is-starred')) {
return unread.get_msg_ids_for_starred();
}