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.is_search());
assert(! filter.can_apply_locally()); 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, // 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 // 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); var filter = new Filter(operators);
assert.deepEqual(filter.operands('stream'), ['foo']); assert.deepEqual(filter.operands('stream'), ['foo']);
assert(filter.is_stream_only()); assert(filter.is_exactly('stream'));
}()); }());
(function test_public_operators() { (function test_public_operators() {
@@ -146,7 +146,7 @@ function assert_same_operators(result, terms) {
var filter = new Filter(operators); var filter = new Filter(operators);
assert_same_operators(filter.public_operators(), operators); assert_same_operators(filter.public_operators(), operators);
assert(!filter.is_stream_only()); assert(!filter.is_exactly('stream'));
global.page_params.narrow_stream = 'default'; global.page_params.narrow_stream = 'default';
operators = [ operators = [
@@ -674,74 +674,75 @@ function make_sub(name, stream_id) {
{operator: 'stream', operand: 'My Stream'}, {operator: 'stream', operand: 'My Stream'},
]; ];
var filter = new Filter(terms); var filter = new Filter(terms);
assert.equal(filter.is_stream_only(), true); assert.equal(filter.is_exactly('stream'), true);
assert.equal(filter.is_stream_topic_only(), false); assert.equal(filter.is_exactly('stream', 'topic'), false);
assert.equal(filter.is_pm_with_only(), false); assert.equal(filter.is_exactly('pm-with'), false);
terms = [ terms = [
{operator: 'stream', operand: 'My Stream'}, // try a non-orthodox ordering
{operator: 'topic', operand: 'My Topic'}, {operator: 'topic', operand: 'My Topic'},
{operator: 'stream', operand: 'My Stream'},
]; ];
filter = new Filter(terms); filter = new Filter(terms);
assert.equal(filter.is_stream_only(), false); assert.equal(filter.is_exactly('stream'), false);
assert.equal(filter.is_stream_topic_only(), true); assert.equal(filter.is_exactly('stream', 'topic'), true);
assert.equal(filter.is_pm_with_only(), false); assert.equal(filter.is_exactly('pm-with'), false);
terms = [ terms = [
{operator: 'stream', operand: 'My Stream', negated: true}, {operator: 'stream', operand: 'My Stream', negated: true},
{operator: 'topic', operand: 'My Topic'}, {operator: 'topic', operand: 'My Topic'},
]; ];
filter = new Filter(terms); filter = new Filter(terms);
assert.equal(filter.is_stream_only(), false); assert.equal(filter.is_exactly('stream'), false);
assert.equal(filter.is_stream_topic_only(), false); assert.equal(filter.is_exactly('stream', 'topic'), false);
assert.equal(filter.is_pm_with_only(), false); assert.equal(filter.is_exactly('pm-with'), false);
terms = [ terms = [
{operator: 'pm-with', operand: 'foo@example.com', negated: true}, {operator: 'pm-with', operand: 'foo@example.com', negated: true},
]; ];
filter = new Filter(terms); filter = new Filter(terms);
assert.equal(filter.is_stream_only(), false); assert.equal(filter.is_exactly('stream'), false);
assert.equal(filter.is_stream_topic_only(), false); assert.equal(filter.is_exactly('stream', 'topic'), false);
assert.equal(filter.is_pm_with_only(), false); assert.equal(filter.is_exactly('pm-with'), false);
terms = [ terms = [
{operator: 'pm-with', operand: 'foo@example.com,bar@example.com'}, {operator: 'pm-with', operand: 'foo@example.com,bar@example.com'},
]; ];
filter = new Filter(terms); filter = new Filter(terms);
assert.equal(filter.is_stream_only(), false); assert.equal(filter.is_exactly('stream'), false);
assert.equal(filter.is_stream_topic_only(), false); assert.equal(filter.is_exactly('stream', 'topic'), false);
assert.equal(filter.is_pm_with_only(), true); assert.equal(filter.is_exactly('pm-with'), true);
assert.equal(filter.is_for_only('mentioned'), false); assert.equal(filter.is_exactly('is-mentioned'), false);
assert.equal(filter.is_for_only('private'), false); assert.equal(filter.is_exactly('is-private'), false);
terms = [ terms = [
{operator: 'is', operand: 'private'}, {operator: 'is', operand: 'private'},
]; ];
filter = new Filter(terms); filter = new Filter(terms);
assert.equal(filter.is_for_only('mentioned'), false); assert.equal(filter.is_exactly('is-mentioned'), false);
assert.equal(filter.is_for_only('private'), true); assert.equal(filter.is_exactly('is-private'), true);
terms = [ terms = [
{operator: 'is', operand: 'mentioned'}, {operator: 'is', operand: 'mentioned'},
]; ];
filter = new Filter(terms); filter = new Filter(terms);
assert.equal(filter.is_for_only('mentioned'), true); assert.equal(filter.is_exactly('is-mentioned'), true);
assert.equal(filter.is_for_only('private'), false); assert.equal(filter.is_exactly('is-private'), false);
terms = [ terms = [
{operator: 'is', operand: 'mentioned'}, {operator: 'is', operand: 'mentioned'},
{operator: 'is', operand: 'starred'}, {operator: 'is', operand: 'starred'},
]; ];
filter = new Filter(terms); filter = new Filter(terms);
assert.equal(filter.is_for_only('mentioned'), false); assert.equal(filter.is_exactly('is-mentioned'), false);
assert.equal(filter.is_for_only('private'), false); assert.equal(filter.is_exactly('is-private'), false);
terms = [ terms = [
{operator: 'is', operand: 'mentioned', negated: true}, {operator: 'is', operand: 'mentioned', negated: true},
]; ];
filter = new Filter(terms); filter = new Filter(terms);
assert.equal(filter.is_for_only('mentioned'), false); assert.equal(filter.is_exactly('is-mentioned'), false);
assert.equal(filter.is_for_only('private'), false); assert.equal(filter.is_exactly('is-private'), false);
}()); }());
(function test_term_type() { (function test_term_type() {

View File

@@ -403,62 +403,16 @@ Filter.prototype = {
return sorted_terms; return sorted_terms;
}, },
is_stream_only: function () { is_exactly: function () {
if (this._operators.length !== 1) { // TODO: in ES6 use spread operator
return false; //
} // 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]; return _.isEqual(term_types, wanted_term_types);
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);
}, },
update_email: function (user_id, new_email) { update_email: function (user_id, new_email) {

View File

@@ -203,7 +203,7 @@ exports.get_unread_ids = function () {
var topic_name; var topic_name;
var pm_string; var pm_string;
if (current_filter.is_stream_only()) { if (current_filter.is_exactly('stream')) {
stream_id = exports.stream_id(); stream_id = exports.stream_id();
if (stream_id === undefined) { if (stream_id === undefined) {
return []; return [];
@@ -211,7 +211,7 @@ exports.get_unread_ids = function () {
return unread.get_msg_ids_for_stream(stream_id); 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(); stream_id = exports.stream_id();
if (stream_id === undefined) { if (stream_id === undefined) {
return []; return [];
@@ -220,7 +220,7 @@ exports.get_unread_ids = function () {
return unread.get_msg_ids_for_topic(stream_id, topic_name); 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(); pm_string = exports.pm_string();
if (pm_string === undefined) { if (pm_string === undefined) {
return []; return [];
@@ -228,15 +228,15 @@ exports.get_unread_ids = function () {
return unread.get_msg_ids_for_person(pm_string); 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(); 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(); 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(); return unread.get_msg_ids_for_starred();
} }