2020-08-01 03:43:15 +02:00
|
|
|
"use strict";
|
|
|
|
|
2020-11-30 23:46:45 +01:00
|
|
|
const {strict: assert} = require("assert");
|
|
|
|
|
zjsunit: Remove rewiremock dependency.
We now just use a module._load hook to inject
stubs into our code.
For conversion purposes I temporarily maintain
the API of rewiremock, apart from the enable/disable
pieces, but I will make a better wrapper in an
upcoming commit.
We can detect when rewiremock is called after
zrequire now, and I fix all the violations in
this commit, mostly by using override.
We can also detect when a mock is needlessly
created, and I fix all the violations in this
commit.
The one minor nuisance that this commit introduces
is that you can only stub out modules in the Zulip
source tree, which is now static/js. This should
not really be a problem--there are usually better
techniques to deal with third party depenencies.
In the prior commit I show a typical workaround,
which is to create a one-line wrapper in your
test code. It's often the case that you can simply
use override(), as well.
In passing I kill off `reset_modules`, and I
eliminated the second argument to zrequire,
which dates back to pre-es6 days.
2021-03-06 12:47:54 +01:00
|
|
|
const {rewiremock, set_global, zrequire} = require("../zjsunit/namespace");
|
2020-12-01 00:39:47 +01:00
|
|
|
const {run_test} = require("../zjsunit/test");
|
2020-12-01 00:02:16 +01:00
|
|
|
|
2021-02-23 03:54:07 +01:00
|
|
|
const page_params = set_global("page_params", {
|
2018-07-14 12:46:02 +02:00
|
|
|
search_pills_enabled: false,
|
|
|
|
});
|
2021-02-28 01:10:03 +01:00
|
|
|
rewiremock("../../static/js/message_store").with({
|
2020-01-02 15:17:10 +01:00
|
|
|
user_ids: () => [],
|
|
|
|
});
|
2021-02-28 01:10:03 +01:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
const settings_config = zrequire("settings_config");
|
2020-02-25 12:46:14 +01:00
|
|
|
page_params.realm_email_address_visibility =
|
|
|
|
settings_config.email_address_visibility_values.admins_only.code;
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
const huddle_data = zrequire("huddle_data");
|
2020-05-26 14:25:21 +02:00
|
|
|
|
2021-02-10 04:53:22 +01:00
|
|
|
const narrow_state = zrequire("narrow_state");
|
|
|
|
const stream_data = zrequire("stream_data");
|
|
|
|
const stream_topic_history = zrequire("stream_topic_history");
|
2020-08-20 21:24:06 +02:00
|
|
|
const people = zrequire("people");
|
2020-07-15 01:29:15 +02:00
|
|
|
const search = zrequire("search_suggestion");
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 01:04:35 +01:00
|
|
|
search.__Rewire__("max_num_of_search_results", 15);
|
2019-12-25 16:58:11 +01:00
|
|
|
|
2020-05-26 15:40:46 +02:00
|
|
|
const me = {
|
2020-07-15 01:29:15 +02:00
|
|
|
email: "myself@zulip.com",
|
|
|
|
full_name: "Me Myself",
|
2020-05-26 15:40:46 +02:00
|
|
|
user_id: 41,
|
|
|
|
};
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const bob = {
|
2020-07-15 01:29:15 +02:00
|
|
|
email: "bob@zulip.com",
|
|
|
|
full_name: "Bob Roberts",
|
2018-07-14 12:46:02 +02:00
|
|
|
user_id: 42,
|
|
|
|
};
|
|
|
|
|
2020-07-15 00:34:28 +02:00
|
|
|
const ted = {
|
2020-07-15 01:29:15 +02:00
|
|
|
email: "ted@zulip.com",
|
2020-05-26 16:06:57 +02:00
|
|
|
user_id: 101,
|
2020-07-15 01:29:15 +02:00
|
|
|
full_name: "Ted Smith",
|
2020-05-26 16:06:57 +02:00
|
|
|
};
|
|
|
|
|
2020-07-15 00:34:28 +02:00
|
|
|
const alice = {
|
2020-07-15 01:29:15 +02:00
|
|
|
email: "alice@zulip.com",
|
2020-05-26 16:06:57 +02:00
|
|
|
user_id: 102,
|
2020-07-15 01:29:15 +02:00
|
|
|
full_name: "Alice Ignore",
|
2020-05-26 16:06:57 +02:00
|
|
|
};
|
|
|
|
|
2020-07-15 00:34:28 +02:00
|
|
|
const jeff = {
|
2020-07-15 01:29:15 +02:00
|
|
|
email: "jeff@zulip.com",
|
2020-05-26 16:06:57 +02:00
|
|
|
user_id: 103,
|
2020-07-15 01:29:15 +02:00
|
|
|
full_name: "Jeff Zoolipson",
|
2020-05-26 16:06:57 +02:00
|
|
|
};
|
|
|
|
|
2018-07-14 12:46:02 +02:00
|
|
|
function init() {
|
|
|
|
people.init();
|
2020-05-26 22:34:15 +02:00
|
|
|
people.add_active_user(bob);
|
|
|
|
people.add_active_user(me);
|
|
|
|
people.add_active_user(ted);
|
|
|
|
people.add_active_user(alice);
|
|
|
|
people.add_active_user(jeff);
|
2020-05-26 16:06:57 +02:00
|
|
|
|
2020-05-26 15:40:46 +02:00
|
|
|
people.initialize_current_user(me.user_id);
|
2018-07-14 12:46:02 +02:00
|
|
|
}
|
|
|
|
init();
|
|
|
|
|
2020-02-25 12:46:14 +01:00
|
|
|
page_params.is_admin = true;
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-03-22 18:40:05 +01:00
|
|
|
stream_topic_history.reset();
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-06-01 15:00:42 +02:00
|
|
|
function get_suggestions(base_query, query) {
|
|
|
|
return search.get_suggestions(base_query, query);
|
|
|
|
}
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("basic_get_suggestions", () => {
|
|
|
|
const query = "fred";
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => []);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => "office");
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
const suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 00:34:28 +02:00
|
|
|
const expected = ["fred"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("subset_suggestions", () => {
|
|
|
|
const query = "stream:Denmark topic:Hamlet shakespeare";
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => []);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
const suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const expected = [
|
2018-07-14 12:46:02 +02:00
|
|
|
"stream:Denmark topic:Hamlet shakespeare",
|
|
|
|
"stream:Denmark topic:Hamlet",
|
|
|
|
"stream:Denmark",
|
|
|
|
];
|
|
|
|
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("private_suggestions", () => {
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => []);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
let query = "is:private";
|
|
|
|
let suggestions = get_suggestions("", query);
|
2019-11-02 00:06:25 +01:00
|
|
|
let expected = [
|
2018-07-14 12:46:02 +02:00
|
|
|
"is:private",
|
|
|
|
"pm-with:alice@zulip.com",
|
|
|
|
"pm-with:bob@zulip.com",
|
2020-05-26 16:06:57 +02:00
|
|
|
"pm-with:jeff@zulip.com",
|
2020-05-26 15:40:46 +02:00
|
|
|
"pm-with:myself@zulip.com",
|
2018-07-14 12:46:02 +02:00
|
|
|
"pm-with:ted@zulip.com",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "is:private al";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"is:private al",
|
|
|
|
"is:private is:alerted",
|
|
|
|
"is:private sender:alice@zulip.com",
|
|
|
|
"is:private pm-with:alice@zulip.com",
|
|
|
|
"is:private group-pm-with:alice@zulip.com",
|
|
|
|
"is:private",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "pm-with:t";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["pm-with:t", "pm-with:ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-pm-with:t";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-pm-with:t", "is:private -pm-with:ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "pm-with:ted@zulip.com";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["pm-with:ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sender:ted";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["sender:ted", "sender:ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sender:te";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["sender:te", "sender:ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-sender:te";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-sender:te", "-sender:ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sender:ted@zulip.com";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["sender:ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "is:unread from:ted";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["is:unread from:ted", "is:unread from:ted@zulip.com", "is:unread"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// Users can enter bizarre queries, and if they do, we want to
|
|
|
|
// be conservative with suggestions.
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "is:private near:3";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["is:private near:3", "is:private"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "pm-with:ted@zulip.com near:3";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["pm-with:ted@zulip.com near:3", "pm-with:ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// Make sure suggestions still work if preceding tokens
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "is:alerted sender:ted@zulip.com";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["is:alerted sender:ted@zulip.com", "is:alerted"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "is:starred has:link is:private al";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"is:starred has:link is:private al",
|
|
|
|
"is:starred has:link is:private is:alerted",
|
|
|
|
"is:starred has:link is:private sender:alice@zulip.com",
|
|
|
|
"is:starred has:link is:private pm-with:alice@zulip.com",
|
|
|
|
"is:starred has:link is:private group-pm-with:alice@zulip.com",
|
|
|
|
"is:starred has:link is:private",
|
|
|
|
"is:starred has:link",
|
|
|
|
"is:starred",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// Make sure it handles past context correctly
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "stream:Denmark pm-with:";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["stream:Denmark pm-with:", "stream:Denmark"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sender:ted@zulip.com sender:";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["sender:ted@zulip.com sender:", "sender:ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("group_suggestions", () => {
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => []);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
|
|
|
// Entering a comma in a pm-with query should immediately generate
|
|
|
|
// suggestions for the next person.
|
2020-07-15 01:29:15 +02:00
|
|
|
let query = "pm-with:bob@zulip.com,";
|
|
|
|
let suggestions = get_suggestions("", query);
|
2019-11-02 00:06:25 +01:00
|
|
|
let expected = [
|
2018-07-14 12:46:02 +02:00
|
|
|
"pm-with:bob@zulip.com,",
|
|
|
|
"pm-with:bob@zulip.com,alice@zulip.com",
|
|
|
|
"pm-with:bob@zulip.com,jeff@zulip.com",
|
|
|
|
"pm-with:bob@zulip.com,ted@zulip.com",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// Only the last part of a comma-separated pm-with query should be used to
|
|
|
|
// generate suggestions.
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "pm-with:bob@zulip.com,t";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["pm-with:bob@zulip.com,t", "pm-with:bob@zulip.com,ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// Smit should also generate ted@zulip.com (Ted Smith) as a suggestion.
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "pm-with:bob@zulip.com,Smit";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["pm-with:bob@zulip.com,Smit", "pm-with:bob@zulip.com,ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-05-26 15:40:46 +02:00
|
|
|
// Do not suggest "myself@zulip.com" (the name of the current user)
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "pm-with:ted@zulip.com,my";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["pm-with:ted@zulip.com,my"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// No superfluous suggestions should be generated.
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "pm-with:bob@zulip.com,red";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["pm-with:bob@zulip.com,red"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// is:private should be properly prepended to each suggestion if the pm-with
|
|
|
|
// operator is negated.
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-pm-with:bob@zulip.com,";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"-pm-with:bob@zulip.com,",
|
|
|
|
"is:private -pm-with:bob@zulip.com,alice@zulip.com",
|
|
|
|
"is:private -pm-with:bob@zulip.com,jeff@zulip.com",
|
|
|
|
"is:private -pm-with:bob@zulip.com,ted@zulip.com",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-pm-with:bob@zulip.com,t";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-pm-with:bob@zulip.com,t", "is:private -pm-with:bob@zulip.com,ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-pm-with:bob@zulip.com,Smit";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-pm-with:bob@zulip.com,Smit", "is:private -pm-with:bob@zulip.com,ted@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-pm-with:bob@zulip.com,red";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-pm-with:bob@zulip.com,red"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// Test multiple operators
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "is:starred has:link pm-with:bob@zulip.com,Smit";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"is:starred has:link pm-with:bob@zulip.com,Smit",
|
|
|
|
"is:starred has:link pm-with:bob@zulip.com,ted@zulip.com",
|
|
|
|
"is:starred has:link",
|
|
|
|
"is:starred",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "stream:Denmark has:link pm-with:bob@zulip.com,Smit";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"stream:Denmark has:link pm-with:bob@zulip.com,Smit",
|
|
|
|
"stream:Denmark has:link",
|
|
|
|
"stream:Denmark",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-05-26 14:25:21 +02:00
|
|
|
function message(user_ids, timestamp) {
|
|
|
|
return {
|
2020-07-15 01:29:15 +02:00
|
|
|
type: "private",
|
2020-07-02 01:41:40 +02:00
|
|
|
display_recipient: user_ids.map((id) => ({
|
2020-07-20 22:18:43 +02:00
|
|
|
id,
|
2020-07-02 01:41:40 +02:00
|
|
|
})),
|
2020-07-20 22:18:43 +02:00
|
|
|
timestamp,
|
2020-05-26 14:25:21 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
huddle_data.process_loaded_messages([
|
|
|
|
message([bob.user_id, ted.user_id], 99),
|
|
|
|
message([bob.user_id, ted.user_id, jeff.user_id], 98),
|
|
|
|
]);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
|
|
|
// Simulate a past huddle which should now prioritize ted over alice
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "pm-with:bob@zulip.com,";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"pm-with:bob@zulip.com,",
|
|
|
|
"pm-with:bob@zulip.com,ted@zulip.com",
|
|
|
|
"pm-with:bob@zulip.com,alice@zulip.com",
|
|
|
|
"pm-with:bob@zulip.com,jeff@zulip.com",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// bob,ted,jeff is already an existing huddle, so prioritize this one
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "pm-with:bob@zulip.com,ted@zulip.com,";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"pm-with:bob@zulip.com,ted@zulip.com,",
|
|
|
|
"pm-with:bob@zulip.com,ted@zulip.com,jeff@zulip.com",
|
|
|
|
"pm-with:bob@zulip.com,ted@zulip.com,alice@zulip.com",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-05-26 15:40:46 +02:00
|
|
|
// bob,ted,jeff is already an existing huddle, but if we start with just jeff,
|
2018-07-14 12:46:02 +02:00
|
|
|
// then don't prioritize ted over alice because it doesn't complete the full huddle.
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "pm-with:jeff@zulip.com,";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"pm-with:jeff@zulip.com,",
|
|
|
|
"pm-with:jeff@zulip.com,alice@zulip.com",
|
2020-05-26 15:40:46 +02:00
|
|
|
"pm-with:jeff@zulip.com,bob@zulip.com",
|
2018-07-14 12:46:02 +02:00
|
|
|
"pm-with:jeff@zulip.com,ted@zulip.com",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
2019-06-27 19:16:55 +02:00
|
|
|
|
|
|
|
query = "pm-with:jeff@zulip.com,ted@zulip.com hi";
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["pm-with:jeff@zulip.com,ted@zulip.com hi", "pm-with:jeff@zulip.com,ted@zulip.com"];
|
2019-06-27 19:16:55 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
2018-07-14 12:46:02 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
init();
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("empty_query_suggestions", () => {
|
|
|
|
const query = "";
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => ["devel", "office"]);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
const suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const expected = [
|
2018-07-14 12:46:02 +02:00
|
|
|
"",
|
2019-08-13 20:20:36 +02:00
|
|
|
"streams:public",
|
2018-07-14 12:46:02 +02:00
|
|
|
"is:private",
|
|
|
|
"is:starred",
|
|
|
|
"is:mentioned",
|
|
|
|
"is:alerted",
|
|
|
|
"is:unread",
|
2020-05-26 15:40:46 +02:00
|
|
|
"sender:myself@zulip.com",
|
2018-07-14 12:46:02 +02:00
|
|
|
"stream:devel",
|
|
|
|
"stream:office",
|
2020-07-15 01:29:15 +02:00
|
|
|
"has:link",
|
|
|
|
"has:image",
|
|
|
|
"has:attachment",
|
2018-07-14 12:46:02 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
function describe(q) {
|
2020-02-12 06:58:20 +01:00
|
|
|
return suggestions.lookup_table.get(q).description;
|
2018-07-14 12:46:02 +02:00
|
|
|
}
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal(describe("is:private"), "Private messages");
|
|
|
|
assert.equal(describe("is:starred"), "Starred messages");
|
|
|
|
assert.equal(describe("is:mentioned"), "@-mentions");
|
|
|
|
assert.equal(describe("is:alerted"), "Alerted messages");
|
|
|
|
assert.equal(describe("is:unread"), "Unread messages");
|
|
|
|
assert.equal(describe("sender:myself@zulip.com"), "Sent by me");
|
|
|
|
assert.equal(describe("has:link"), "Messages with one or more link");
|
|
|
|
assert.equal(describe("has:image"), "Messages with one or more image");
|
|
|
|
assert.equal(describe("has:attachment"), "Messages with one or more attachment");
|
2018-07-14 12:46:02 +02:00
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("has_suggestions", () => {
|
2018-07-14 12:46:02 +02:00
|
|
|
// Checks that category wise suggestions are displayed instead of a single
|
|
|
|
// default suggestion when suggesting `has` operator.
|
2020-07-15 01:29:15 +02:00
|
|
|
let query = "h";
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => ["devel", "office"]);
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
let suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
let expected = ["h", "has:link", "has:image", "has:attachment"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
function describe(q) {
|
2020-02-12 06:58:20 +01:00
|
|
|
return suggestions.lookup_table.get(q).description;
|
2018-07-14 12:46:02 +02:00
|
|
|
}
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal(describe("has:link"), "Messages with one or more link");
|
|
|
|
assert.equal(describe("has:image"), "Messages with one or more image");
|
|
|
|
assert.equal(describe("has:attachment"), "Messages with one or more attachment");
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-h";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-h", "-has:link", "-has:image", "-has:attachment"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal(describe("-has:link"), "Exclude messages with one or more link");
|
|
|
|
assert.equal(describe("-has:image"), "Exclude messages with one or more image");
|
|
|
|
assert.equal(describe("-has:attachment"), "Exclude messages with one or more attachment");
|
2018-07-14 12:46:02 +02:00
|
|
|
|
|
|
|
// operand suggestions follow.
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "has:";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["has:link", "has:image", "has:attachment"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "has:im";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["has:image"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-has:im";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-has:image"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "att";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["att", "has:attachment"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "stream:Denmark is:alerted has:lin";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
2020-07-15 01:29:15 +02:00
|
|
|
"stream:Denmark is:alerted has:link",
|
|
|
|
"stream:Denmark is:alerted",
|
|
|
|
"stream:Denmark",
|
2018-07-14 12:46:02 +02:00
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("check_is_suggestions", () => {
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => ["devel", "office"]);
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
let query = "i";
|
|
|
|
let suggestions = get_suggestions("", query);
|
2019-11-02 00:06:25 +01:00
|
|
|
let expected = [
|
2020-07-15 01:29:15 +02:00
|
|
|
"i",
|
|
|
|
"is:private",
|
|
|
|
"is:starred",
|
|
|
|
"is:mentioned",
|
|
|
|
"is:alerted",
|
|
|
|
"is:unread",
|
|
|
|
"sender:alice@zulip.com",
|
|
|
|
"pm-with:alice@zulip.com",
|
|
|
|
"group-pm-with:alice@zulip.com",
|
|
|
|
"has:image",
|
2018-07-14 12:46:02 +02:00
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
function describe(q) {
|
2020-02-12 06:58:20 +01:00
|
|
|
return suggestions.lookup_table.get(q).description;
|
2018-07-14 12:46:02 +02:00
|
|
|
}
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal(describe("is:private"), "Private messages");
|
|
|
|
assert.equal(describe("is:starred"), "Starred messages");
|
|
|
|
assert.equal(describe("is:mentioned"), "@-mentions");
|
|
|
|
assert.equal(describe("is:alerted"), "Alerted messages");
|
|
|
|
assert.equal(describe("is:unread"), "Unread messages");
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-i";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-i", "-is:private", "-is:starred", "-is:mentioned", "-is:alerted", "-is:unread"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal(describe("-is:private"), "Exclude private messages");
|
|
|
|
assert.equal(describe("-is:starred"), "Exclude starred messages");
|
|
|
|
assert.equal(describe("-is:mentioned"), "Exclude @-mentions");
|
|
|
|
assert.equal(describe("-is:alerted"), "Exclude alerted messages");
|
|
|
|
assert.equal(describe("-is:unread"), "Exclude unread messages");
|
2018-07-14 12:46:02 +02:00
|
|
|
|
|
|
|
// operand suggestions follow.
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "is:";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["is:private", "is:starred", "is:mentioned", "is:alerted", "is:unread"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "is:st";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["is:starred"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-is:st";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-is:starred"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "st";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["st", "streams:public", "is:starred", "stream:"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "stream:Denmark has:link is:sta";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["stream:Denmark has:link is:starred", "stream:Denmark has:link", "stream:Denmark"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("sent_by_me_suggestions", () => {
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => []);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
let query = "";
|
|
|
|
let suggestions = get_suggestions("", query);
|
|
|
|
assert(suggestions.strings.includes("sender:myself@zulip.com"));
|
2020-07-15 00:34:28 +02:00
|
|
|
assert.equal(suggestions.lookup_table.get("sender:myself@zulip.com").description, "Sent by me");
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sender";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
let expected = ["sender", "sender:myself@zulip.com", "sender:"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-sender";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-sender", "-sender:myself@zulip.com", "-sender:"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "from";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["from", "from:myself@zulip.com", "from:"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-from";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-from", "-from:myself@zulip.com", "-from:"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sender:bob@zulip.com";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["sender:bob@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "from:bob@zulip.com";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["from:bob@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sent";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["sent", "sender:myself@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-sent";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-sent", "-sender:myself@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "stream:Denmark topic:Denmark1 sent";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"stream:Denmark topic:Denmark1 sent",
|
2020-05-26 15:40:46 +02:00
|
|
|
"stream:Denmark topic:Denmark1 sender:myself@zulip.com",
|
2018-07-14 12:46:02 +02:00
|
|
|
"stream:Denmark topic:Denmark1",
|
|
|
|
"stream:Denmark",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "is:starred sender:m";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["is:starred sender:m", "is:starred sender:myself@zulip.com", "is:starred"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sender:alice@zulip.com sender:";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["sender:alice@zulip.com sender:", "sender:alice@zulip.com"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("topic_suggestions", () => {
|
2019-11-02 00:06:25 +01:00
|
|
|
let suggestions;
|
|
|
|
let expected;
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => ["office"]);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => "office");
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const devel_id = 44;
|
|
|
|
const office_id = 77;
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("get_stream_id", (stream_name) => {
|
2018-07-14 12:46:02 +02:00
|
|
|
switch (stream_name) {
|
2020-07-15 00:34:28 +02:00
|
|
|
case "office":
|
|
|
|
return office_id;
|
|
|
|
case "devel":
|
|
|
|
return devel_id;
|
2020-09-24 07:50:36 +02:00
|
|
|
default:
|
|
|
|
return undefined;
|
2018-07-14 12:46:02 +02:00
|
|
|
}
|
2021-02-28 00:53:59 +01:00
|
|
|
});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-03-22 18:40:05 +01:00
|
|
|
stream_topic_history.reset();
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", "te");
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"te",
|
2020-05-26 16:06:57 +02:00
|
|
|
"sender:ted@zulip.com",
|
|
|
|
"pm-with:ted@zulip.com",
|
|
|
|
"group-pm-with:ted@zulip.com",
|
2018-07-14 12:46:02 +02:00
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-03-22 18:40:05 +01:00
|
|
|
stream_topic_history.add_message({
|
2018-07-14 12:46:02 +02:00
|
|
|
stream_id: devel_id,
|
2020-07-15 01:29:15 +02:00
|
|
|
topic_name: "REXX",
|
2018-07-14 12:46:02 +02:00
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
for (const topic_name of ["team", "ignore", "test"]) {
|
2020-03-22 18:40:05 +01:00
|
|
|
stream_topic_history.add_message({
|
2018-07-14 12:46:02 +02:00
|
|
|
stream_id: office_id,
|
2020-07-20 22:18:43 +02:00
|
|
|
topic_name,
|
2018-07-14 12:46:02 +02:00
|
|
|
});
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", "te");
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
|
|
|
"te",
|
2020-05-26 16:06:57 +02:00
|
|
|
"sender:ted@zulip.com",
|
|
|
|
"pm-with:ted@zulip.com",
|
|
|
|
"group-pm-with:ted@zulip.com",
|
2018-07-14 12:46:02 +02:00
|
|
|
"stream:office topic:team",
|
|
|
|
"stream:office topic:test",
|
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
function describe(q) {
|
2020-02-12 06:58:20 +01:00
|
|
|
return suggestions.lookup_table.get(q).description;
|
2018-07-14 12:46:02 +02:00
|
|
|
}
|
2020-07-15 01:29:15 +02:00
|
|
|
assert.equal(describe("te"), "Search for te");
|
|
|
|
assert.equal(describe("stream:office topic:team"), "Stream office > team");
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", "topic:staplers stream:office");
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["topic:staplers stream:office", "topic:staplers"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", "stream:devel topic:");
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["stream:devel topic:", "stream:devel topic:REXX", "stream:devel"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", "stream:devel -topic:");
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["stream:devel -topic:", "stream:devel -topic:REXX", "stream:devel"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", "-topic:te");
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-topic:te", "stream:office -topic:team", "stream:office -topic:test"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", "is:alerted stream:devel is:starred topic:");
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
2020-07-15 01:29:15 +02:00
|
|
|
"is:alerted stream:devel is:starred topic:",
|
|
|
|
"is:alerted stream:devel is:starred topic:REXX",
|
|
|
|
"is:alerted stream:devel is:starred",
|
|
|
|
"is:alerted stream:devel",
|
|
|
|
"is:alerted",
|
2018-07-14 12:46:02 +02:00
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", "is:private stream:devel topic:");
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["is:private stream:devel topic:", "is:private stream:devel", "is:private"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", "topic:REXX stream:devel topic:");
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["topic:REXX stream:devel topic:", "topic:REXX stream:devel", "topic:REXX"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("whitespace_glitch", () => {
|
|
|
|
const query = "stream:office "; // note trailing space
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => ["office"]);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-03-22 18:40:05 +01:00
|
|
|
stream_topic_history.reset();
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
const suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 00:34:28 +02:00
|
|
|
const expected = ["stream:office"];
|
2018-07-14 12:46:02 +02:00
|
|
|
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("stream_completion", () => {
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => ["office", "dev help"]);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-03-22 18:40:05 +01:00
|
|
|
stream_topic_history.reset();
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
let query = "stream:of";
|
|
|
|
let suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
let expected = ["stream:of", "stream:office"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-stream:of";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-stream:of", "-stream:office"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "hel";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["hel", "stream:dev+help"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("people_suggestions", () => {
|
|
|
|
let query = "te";
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => []);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const ted = {
|
2020-07-15 01:29:15 +02:00
|
|
|
email: "ted@zulip.com",
|
2018-07-14 12:46:02 +02:00
|
|
|
user_id: 201,
|
2020-07-15 01:29:15 +02:00
|
|
|
full_name: "Ted Smith",
|
2018-07-14 12:46:02 +02:00
|
|
|
};
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const bob = {
|
2020-07-15 01:29:15 +02:00
|
|
|
email: "bob@zulip.com",
|
2018-07-14 12:46:02 +02:00
|
|
|
user_id: 202,
|
2020-07-15 01:29:15 +02:00
|
|
|
full_name: "Bob Térry",
|
2018-07-14 12:46:02 +02:00
|
|
|
};
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const alice = {
|
2020-07-15 01:29:15 +02:00
|
|
|
email: "alice@zulip.com",
|
2018-07-14 12:46:02 +02:00
|
|
|
user_id: 203,
|
2020-07-15 01:29:15 +02:00
|
|
|
full_name: "Alice Ignore",
|
2018-07-14 12:46:02 +02:00
|
|
|
};
|
2020-05-26 22:34:15 +02:00
|
|
|
people.add_active_user(ted);
|
|
|
|
people.add_active_user(bob);
|
|
|
|
people.add_active_user(alice);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-03-22 18:40:05 +01:00
|
|
|
stream_topic_history.reset();
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
let suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
let expected = [
|
2018-07-14 12:46:02 +02:00
|
|
|
"te",
|
|
|
|
"sender:bob@zulip.com",
|
|
|
|
"sender:ted@zulip.com",
|
|
|
|
"pm-with:bob@zulip.com", // bob térry
|
|
|
|
"pm-with:ted@zulip.com",
|
|
|
|
"group-pm-with:bob@zulip.com",
|
|
|
|
"group-pm-with:ted@zulip.com",
|
|
|
|
];
|
|
|
|
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
function describe(q) {
|
2020-02-12 06:58:20 +01:00
|
|
|
return suggestions.lookup_table.get(q).description;
|
2018-07-14 12:46:02 +02:00
|
|
|
}
|
2020-07-15 00:34:28 +02:00
|
|
|
assert.equal(
|
|
|
|
describe("pm-with:ted@zulip.com"),
|
|
|
|
"Private messages with <strong>Te</strong>d Smith <<strong>te</strong>d@zulip.com>",
|
|
|
|
);
|
|
|
|
assert.equal(
|
|
|
|
describe("sender:ted@zulip.com"),
|
|
|
|
"Sent by <strong>Te</strong>d Smith <<strong>te</strong>d@zulip.com>",
|
|
|
|
);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", "Ted "); // note space
|
2018-07-14 12:46:02 +02:00
|
|
|
|
|
|
|
expected = [
|
|
|
|
"Ted",
|
|
|
|
"sender:ted@zulip.com",
|
|
|
|
"pm-with:ted@zulip.com",
|
|
|
|
"group-pm-with:ted@zulip.com",
|
|
|
|
];
|
|
|
|
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sender:ted sm";
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["sender:ted+sm", "sender:ted@zulip.com"];
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sender:ted@zulip.com new";
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["sender:ted@zulip.com new", "sender:ted@zulip.com"];
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "sender:ted@tulip.com new";
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["sender:ted@tulip.com+new"];
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("operator_suggestions", () => {
|
2018-07-14 12:46:02 +02:00
|
|
|
// Completed operator should return nothing
|
2020-07-15 01:29:15 +02:00
|
|
|
let query = "stream:";
|
|
|
|
let suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
let expected = ["stream:"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "st";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["st", "streams:public", "is:starred", "stream:"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "group-";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["group-", "group-pm-with:"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "-s";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["-s", "-streams:public", "-sender:myself@zulip.com", "-stream:", "-sender:"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "stream:Denmark is:alerted -f";
|
|
|
|
suggestions = get_suggestions("", query);
|
2018-07-14 12:46:02 +02:00
|
|
|
expected = [
|
2020-07-15 01:29:15 +02:00
|
|
|
"stream:Denmark is:alerted -f",
|
|
|
|
"stream:Denmark is:alerted -from:myself@zulip.com",
|
|
|
|
"stream:Denmark is:alerted -from:",
|
|
|
|
"stream:Denmark is:alerted",
|
|
|
|
"stream:Denmark",
|
2018-07-14 12:46:02 +02:00
|
|
|
];
|
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
run_test("queries_with_spaces", () => {
|
2021-02-28 00:53:59 +01:00
|
|
|
stream_data.__Rewire__("subscribed_streams", () => ["office", "dev help"]);
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2021-02-28 00:47:56 +01:00
|
|
|
narrow_state.__Rewire__("stream", () => {});
|
2018-07-14 12:46:02 +02:00
|
|
|
|
2020-03-22 18:40:05 +01:00
|
|
|
stream_topic_history.reset();
|
2018-07-14 12:46:02 +02:00
|
|
|
|
|
|
|
// test allowing spaces with quotes surrounding operand
|
2019-11-02 00:06:25 +01:00
|
|
|
let query = 'stream:"dev he"';
|
2020-07-15 01:29:15 +02:00
|
|
|
let suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
let expected = ["stream:dev+he", "stream:dev+help"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// test mismatched quote
|
|
|
|
query = 'stream:"dev h';
|
2020-07-15 01:29:15 +02:00
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["stream:dev+h", "stream:dev+help"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
|
|
|
|
// test extra space after operator still works
|
2020-07-15 01:29:15 +02:00
|
|
|
query = "stream: offi";
|
|
|
|
suggestions = get_suggestions("", query);
|
2020-07-15 00:34:28 +02:00
|
|
|
expected = ["stream:offi", "stream:office"];
|
2018-07-14 12:46:02 +02:00
|
|
|
assert.deepEqual(suggestions.strings, expected);
|
|
|
|
});
|