mirror of https://github.com/zulip/zulip.git
node_tests: Enforce 100% coverage for test files.
This makes it easier to find obsolete parts of the tests that should be cleaned up. Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
8aed6321bd
commit
a682530fd4
|
@ -381,36 +381,40 @@ test("first/prev/next", ({override, mock_template}) => {
|
|||
let rendered_fred;
|
||||
|
||||
mock_template("user_presence_row.hbs", false, (data) => {
|
||||
if (data.user_id === alice.user_id) {
|
||||
rendered_alice = true;
|
||||
assert.deepEqual(data, {
|
||||
faded: true,
|
||||
href: "#narrow/pm-with/1-alice",
|
||||
is_current_user: false,
|
||||
my_user_status: undefined,
|
||||
name: "Alice Smith",
|
||||
num_unread: 0,
|
||||
user_circle_class: "user_circle_green",
|
||||
user_circle_status: "translated: Active",
|
||||
user_id: alice.user_id,
|
||||
status_emoji_info: undefined,
|
||||
});
|
||||
} else if (data.user_id === fred.user_id) {
|
||||
rendered_fred = true;
|
||||
assert.deepEqual(data, {
|
||||
href: "#narrow/pm-with/2-fred",
|
||||
name: "Fred Flintstone",
|
||||
user_id: fred.user_id,
|
||||
my_user_status: undefined,
|
||||
is_current_user: false,
|
||||
num_unread: 0,
|
||||
user_circle_class: "user_circle_green",
|
||||
user_circle_status: "translated: Active",
|
||||
faded: false,
|
||||
status_emoji_info: undefined,
|
||||
});
|
||||
} else {
|
||||
throw new Error(`we did not expect to have to render a row for ${data.name}`);
|
||||
switch (data.user_id) {
|
||||
case alice.user_id:
|
||||
rendered_alice = true;
|
||||
assert.deepEqual(data, {
|
||||
faded: true,
|
||||
href: "#narrow/pm-with/1-alice",
|
||||
is_current_user: false,
|
||||
my_user_status: undefined,
|
||||
name: "Alice Smith",
|
||||
num_unread: 0,
|
||||
user_circle_class: "user_circle_green",
|
||||
user_circle_status: "translated: Active",
|
||||
user_id: alice.user_id,
|
||||
status_emoji_info: undefined,
|
||||
});
|
||||
break;
|
||||
case fred.user_id:
|
||||
rendered_fred = true;
|
||||
assert.deepEqual(data, {
|
||||
href: "#narrow/pm-with/2-fred",
|
||||
name: "Fred Flintstone",
|
||||
user_id: fred.user_id,
|
||||
my_user_status: undefined,
|
||||
is_current_user: false,
|
||||
num_unread: 0,
|
||||
user_circle_class: "user_circle_green",
|
||||
user_circle_status: "translated: Active",
|
||||
faded: false,
|
||||
status_emoji_info: undefined,
|
||||
});
|
||||
break;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`we did not expect to have to render a row for ${data.name}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -555,13 +559,8 @@ test("realm_presence_disabled", () => {
|
|||
|
||||
test("redraw_muted_user", () => {
|
||||
muted_users.add_muted_user(mark.user_id);
|
||||
let appended_html;
|
||||
$("#user_presences").append = function (html) {
|
||||
appended_html = html;
|
||||
};
|
||||
|
||||
activity.redraw_user(mark.user_id);
|
||||
assert.equal(appended_html, undefined);
|
||||
assert.equal($("#user_presences").html(), "never-been-set");
|
||||
});
|
||||
|
||||
test("update_presence_info", ({override, override_rewire}) => {
|
||||
|
|
|
@ -136,14 +136,12 @@ run_test("licensechange", ({override, override_rewire}) => {
|
|||
assert.ok(confirm_license_modal_shown);
|
||||
|
||||
override(helpers, "is_valid_input", () => false);
|
||||
let prevent_default_called = false;
|
||||
const event = {
|
||||
prevent_default: () => {
|
||||
prevent_default_called = true;
|
||||
preventDefault: /* istanbul ignore next */ () => {
|
||||
throw new Error("unexpected preventDefault call");
|
||||
},
|
||||
};
|
||||
update_licenses_button_click_handler(event);
|
||||
assert.ok(!prevent_default_called);
|
||||
|
||||
const update_next_renewal_licenses_button_click_handler = $(
|
||||
"#update-licenses-at-next-renewal-button",
|
||||
|
|
|
@ -399,19 +399,18 @@ test("while_reloading", () => {
|
|||
|
||||
assert.equal(channel.get({ignore_reload: false}), undefined);
|
||||
|
||||
let orig_success_called = false;
|
||||
let orig_error_called = false;
|
||||
|
||||
test_with_mock_ajax({
|
||||
run_code() {
|
||||
channel.del({
|
||||
url: "/json/endpoint",
|
||||
ignore_reload: true,
|
||||
/* istanbul ignore next */
|
||||
success() {
|
||||
orig_success_called = true;
|
||||
throw new Error("unexpected success");
|
||||
},
|
||||
/* istanbul ignore next */
|
||||
error() {
|
||||
orig_error_called = true;
|
||||
throw new Error("unexpected error");
|
||||
},
|
||||
});
|
||||
},
|
||||
|
@ -419,11 +418,9 @@ test("while_reloading", () => {
|
|||
check_ajax_options(options) {
|
||||
blueslip.expect("log", "Ignoring DELETE /json/endpoint response while reloading");
|
||||
options.simulate_success();
|
||||
assert.ok(!orig_success_called);
|
||||
|
||||
blueslip.expect("log", "Ignoring DELETE /json/endpoint error response while reloading");
|
||||
options.simulate_error();
|
||||
assert.ok(!orig_error_called);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
@ -106,6 +106,7 @@ function make_switcher() {
|
|||
switch (sel) {
|
||||
case ".ind-tab":
|
||||
return ind_tab;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error("unknown selector: " + sel);
|
||||
}
|
||||
|
@ -151,6 +152,7 @@ mock_jquery((sel, attributes) => {
|
|||
);
|
||||
return make_tab(tab_id);
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error("unknown selector: " + sel);
|
||||
}
|
||||
|
|
|
@ -145,10 +145,6 @@ test_ui("send_message", ({override, override_rewire}) => {
|
|||
return stub_state;
|
||||
}
|
||||
|
||||
set_global("setTimeout", (func) => {
|
||||
func();
|
||||
});
|
||||
|
||||
override(server_events, "assert_get_events_running", () => {
|
||||
stub_state.get_events_running_called += 1;
|
||||
});
|
||||
|
@ -635,13 +631,15 @@ test_ui("on_events", ({override, override_rewire}) => {
|
|||
);
|
||||
|
||||
helper.$container.data = (field) => {
|
||||
if (field === "user-id") {
|
||||
return "34";
|
||||
switch (field) {
|
||||
case "user-id":
|
||||
return "34";
|
||||
case "stream-id":
|
||||
return "102";
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`Unknown field ${field}`);
|
||||
}
|
||||
if (field === "stream-id") {
|
||||
return "102";
|
||||
}
|
||||
throw new Error(`Unknown field ${field}`);
|
||||
};
|
||||
helper.$target.prop("disabled", false);
|
||||
|
||||
|
@ -737,9 +735,6 @@ test_ui("on_events", ({override, override_rewire}) => {
|
|||
|
||||
(function test_attach_files_compose_clicked() {
|
||||
const handler = $("#compose").get_on_handler("click", ".compose_upload_file");
|
||||
$("#compose .file_input").clone = (param) => {
|
||||
assert.ok(param);
|
||||
};
|
||||
let compose_file_input_clicked = false;
|
||||
$("#compose .file_input").on("click", () => {
|
||||
compose_file_input_clicked = true;
|
||||
|
|
|
@ -390,6 +390,7 @@ test("quote_and_reply", ({override, override_rewire}) => {
|
|||
raw_content: "Testing.",
|
||||
};
|
||||
|
||||
/* istanbul ignore next */
|
||||
function whiny_get() {
|
||||
assert.fail("channel.get should not be used if raw_content is present");
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ mock_jquery((selector) => {
|
|||
return "lunch";
|
||||
},
|
||||
};
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`Unknown selector ${selector}`);
|
||||
}
|
||||
|
|
|
@ -41,8 +41,6 @@ run_test("pills", ({override}) => {
|
|||
people.add_active_user(iago);
|
||||
people.add_active_user(hamlet);
|
||||
|
||||
people.get_realm_users = () => [iago, othello, hamlet];
|
||||
|
||||
const $recipient_stub = $("#private_message_recipient");
|
||||
const pill_container_stub = "pill-container";
|
||||
$recipient_stub.set_parent(pill_container_stub);
|
||||
|
@ -81,25 +79,29 @@ run_test("pills", ({override}) => {
|
|||
let get_by_email_called = false;
|
||||
people.get_by_email = (user_email) => {
|
||||
get_by_email_called = true;
|
||||
if (user_email === iago.email) {
|
||||
return iago;
|
||||
switch (user_email) {
|
||||
case iago.email:
|
||||
return iago;
|
||||
case othello.email:
|
||||
return othello;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`Unknown user email ${user_email}`);
|
||||
}
|
||||
if (user_email === othello.email) {
|
||||
return othello;
|
||||
}
|
||||
throw new Error(`Unknown user email ${user_email}`);
|
||||
};
|
||||
|
||||
let get_by_user_id_called = false;
|
||||
people.get_by_user_id = (id) => {
|
||||
get_by_user_id_called = true;
|
||||
if (id === othello.user_id) {
|
||||
return othello;
|
||||
switch (id) {
|
||||
case othello.user_id:
|
||||
return othello;
|
||||
case hamlet.user_id:
|
||||
return hamlet;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`Unknown user ID ${id}`);
|
||||
}
|
||||
if (id === hamlet.user_id) {
|
||||
return hamlet;
|
||||
}
|
||||
throw new Error(`Unknown user ID ${id}`);
|
||||
};
|
||||
|
||||
function test_create_item(handler) {
|
||||
|
|
|
@ -71,6 +71,7 @@ function make_textbox(s) {
|
|||
};
|
||||
|
||||
$widget.val = function (new_val) {
|
||||
/* istanbul ignore if */
|
||||
if (new_val) {
|
||||
$widget.s = new_val;
|
||||
return this;
|
||||
|
@ -301,6 +302,7 @@ run_test("quote_and_reply", ({override, override_rewire}) => {
|
|||
textarea_caret_pos = arg;
|
||||
return this;
|
||||
}
|
||||
/* istanbul ignore if */
|
||||
if (typeof arg !== "string") {
|
||||
console.info(arg);
|
||||
throw new Error("We expected the actual code to pass in a string.");
|
||||
|
|
|
@ -163,12 +163,10 @@ test_ui("validate", ({override, mock_template}) => {
|
|||
|
||||
add_content_to_compose_box();
|
||||
let zephyr_checked = false;
|
||||
$("#zephyr-mirror-error").is = () => {
|
||||
if (!zephyr_checked) {
|
||||
zephyr_checked = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$("#zephyr-mirror-error").is = (arg) => {
|
||||
assert.equal(arg, ":visible");
|
||||
zephyr_checked = true;
|
||||
return true;
|
||||
};
|
||||
assert.ok(!compose_validate.validate());
|
||||
assert.ok(zephyr_checked);
|
||||
|
@ -740,14 +738,17 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, override_rewire, moc
|
|||
|
||||
let looked_for_existing;
|
||||
$warning_row.data = (field) => {
|
||||
if (field === "user-id") {
|
||||
looked_for_existing = true;
|
||||
return "34";
|
||||
switch (field) {
|
||||
case "user-id":
|
||||
looked_for_existing = true;
|
||||
return "34";
|
||||
/* istanbul ignore next */
|
||||
case "stream-id":
|
||||
return "111";
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`Unknown field ${field}`);
|
||||
}
|
||||
if (field === "stream-id") {
|
||||
return "111";
|
||||
}
|
||||
throw new Error(`Unknown field ${field}`);
|
||||
};
|
||||
|
||||
const $previous_users = $("#compose_invite_users .compose_invite_user");
|
||||
|
|
|
@ -32,6 +32,7 @@ const compose = zrequire("compose");
|
|||
function stub_out_video_calls() {
|
||||
const $elem = $("#below-compose-content .video_link");
|
||||
$elem.toggle = (show) => {
|
||||
/* istanbul ignore if */
|
||||
if (show) {
|
||||
$elem.show();
|
||||
} else {
|
||||
|
@ -77,8 +78,6 @@ test("videos", ({override, override_rewire}) => {
|
|||
compose.initialize();
|
||||
|
||||
(function test_no_provider_video_link_compose_clicked() {
|
||||
let called = false;
|
||||
|
||||
const $textarea = $.create("target-stub");
|
||||
$textarea.set_parents_result(".message_edit_form", []);
|
||||
|
||||
|
@ -90,15 +89,19 @@ test("videos", ({override, override_rewire}) => {
|
|||
},
|
||||
};
|
||||
|
||||
override_rewire(compose_ui, "insert_syntax_and_focus", () => {
|
||||
called = true;
|
||||
});
|
||||
override_rewire(
|
||||
compose_ui,
|
||||
"insert_syntax_and_focus",
|
||||
/* istanbul ignore next */
|
||||
() => {
|
||||
throw new Error("unexpected insert_syntax_and_focus call");
|
||||
},
|
||||
);
|
||||
|
||||
const handler = $("body").get_on_handler("click", ".video_link");
|
||||
$("#compose-textarea").val("");
|
||||
|
||||
handler(ev);
|
||||
assert.ok(!called);
|
||||
})();
|
||||
|
||||
(function test_jitsi_video_link_compose_clicked() {
|
||||
|
|
|
@ -54,9 +54,6 @@ const composebox_typeahead = zrequire("composebox_typeahead");
|
|||
const settings_config = zrequire("settings_config");
|
||||
const pygments_data = zrequire("../generated/pygments_data.json");
|
||||
|
||||
// To be eliminated in next commit:
|
||||
stream_data.__Rewire__("set_filter_out_inactives", () => false);
|
||||
|
||||
const ct = composebox_typeahead;
|
||||
|
||||
// Use a slightly larger value than what's user-facing
|
||||
|
@ -143,19 +140,10 @@ const emojis_by_name = new Map(
|
|||
headphones: emoji_headphones,
|
||||
}),
|
||||
);
|
||||
const emoji_list = Array.from(emojis_by_name.values(), (emoji_dict) => {
|
||||
if (emoji_dict.is_realm_emoji === true) {
|
||||
return {
|
||||
emoji_name: emoji_dict.name,
|
||||
emoji_url: emoji_dict.url,
|
||||
is_realm_emoji: true,
|
||||
};
|
||||
}
|
||||
return {
|
||||
emoji_name: emoji_dict.name,
|
||||
emoji_code: emoji_dict.emoji_code,
|
||||
};
|
||||
});
|
||||
const emoji_list = Array.from(emojis_by_name.values(), (emoji_dict) => ({
|
||||
emoji_name: emoji_dict.name,
|
||||
emoji_code: emoji_dict.emoji_code,
|
||||
}));
|
||||
|
||||
const me_slash = {
|
||||
name: "me",
|
||||
|
@ -1070,14 +1058,8 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
|||
stopPropagation: noop,
|
||||
};
|
||||
|
||||
$("#stream_message_recipient_topic").data = () => ({typeahead: {shown: true}});
|
||||
$("form#send_message_form").trigger(event);
|
||||
|
||||
const stub_typeahead_hidden = () => ({typeahead: {shown: false}});
|
||||
$("#stream_message_recipient_topic").data = stub_typeahead_hidden;
|
||||
$("#stream_message_recipient_stream").data = stub_typeahead_hidden;
|
||||
$("#private_message_recipient").data = stub_typeahead_hidden;
|
||||
$("#compose-textarea").data = stub_typeahead_hidden;
|
||||
$("form#send_message_form").trigger(event);
|
||||
|
||||
event.key = "Tab";
|
||||
|
@ -1144,7 +1126,6 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
|||
preventDefault: noop,
|
||||
};
|
||||
// We trigger keydown in order to make nextFocus !== false
|
||||
$("#stream_message_recipient_topic").data = () => ({typeahead: {shown: true}});
|
||||
$("form#send_message_form").trigger(event);
|
||||
$("#stream_message_recipient_topic").off("mouseup");
|
||||
event.type = "keyup";
|
||||
|
|
|
@ -78,7 +78,7 @@ run_test("no_default_value", () => {
|
|||
widget_name: "my_setting",
|
||||
data: ["one", "two", "three"].map((x) => ({name: x, value: x})),
|
||||
default_text: $t({defaultMessage: "not set"}),
|
||||
render_text: (text) => `rendered: ${text}`,
|
||||
render_text: /* istanbul ignore next */ (text) => `rendered: ${text}`,
|
||||
null_value: "null-value",
|
||||
};
|
||||
|
||||
|
|
|
@ -17,11 +17,13 @@ run_test("explore make_stub", ({override}) => {
|
|||
// Let's say you have to test the following code.
|
||||
|
||||
const app = {
|
||||
/* istanbul ignore next */
|
||||
notify_server_of_deposit(deposit_amount) {
|
||||
// simulate difficulty
|
||||
throw new Error(`We cannot report this value without wifi: ${deposit_amount}`);
|
||||
},
|
||||
|
||||
/* istanbul ignore next */
|
||||
pop_up_fancy_confirmation_screen(deposit_amount, label) {
|
||||
// simulate difficulty
|
||||
throw new Error(`We cannot make a ${label} dialog for amount ${deposit_amount}`);
|
||||
|
|
|
@ -91,8 +91,6 @@ run_test("unread_ops", ({override, override_rewire}) => {
|
|||
|
||||
// We don't want recent topics to process message for this test.
|
||||
override_rewire(recent_topics_util, "is_visible", () => false);
|
||||
// Show message_viewport as not visible so that messages will be stored as unread.
|
||||
override(message_viewport, "is_visible_and_focused", () => false);
|
||||
|
||||
// Make our test message appear to be unread, so that
|
||||
// we then need to subsequently process them as read.
|
||||
|
|
|
@ -105,7 +105,6 @@ message_lists.current = {
|
|||
flags: ["read", "starred"],
|
||||
};
|
||||
},
|
||||
selected_row() {},
|
||||
get_row() {
|
||||
return 101;
|
||||
},
|
||||
|
@ -138,7 +137,6 @@ function stubbing_rewire(module, func_name_to_stub, test_function) {
|
|||
}
|
||||
|
||||
// Set up defaults for most tests.
|
||||
hotkey.__Rewire__("in_content_editable_widget", () => false);
|
||||
hotkey.__Rewire__("processing_text", () => false);
|
||||
|
||||
run_test("mappings", () => {
|
||||
|
@ -228,7 +226,7 @@ function process(s) {
|
|||
};
|
||||
try {
|
||||
return hotkey.process_keypress(e);
|
||||
} catch (error) {
|
||||
} catch (error) /* istanbul ignore next */ {
|
||||
// An exception will be thrown here if a different
|
||||
// function is called than the one declared. Try to
|
||||
// provide a useful error message.
|
||||
|
@ -292,8 +290,8 @@ run_test("allow normal typing when processing text", ({override_rewire}) => {
|
|||
|
||||
run_test("streams", ({override}) => {
|
||||
settings_data.user_can_create_private_streams = () => true;
|
||||
settings_data.user_can_create_public_streams = () => true;
|
||||
settings_data.user_can_create_web_public_streams = () => true;
|
||||
delete settings_data.user_can_create_public_streams;
|
||||
delete settings_data.user_can_create_web_public_streams;
|
||||
override(overlays, "streams_open", () => true);
|
||||
override(overlays, "is_active", () => true);
|
||||
assert_mapping("S", stream_settings_ui, "keyboard_sub");
|
||||
|
@ -435,7 +433,7 @@ run_test("motion_keys", () => {
|
|||
|
||||
try {
|
||||
return hotkey.process_keydown(e);
|
||||
} catch (error) {
|
||||
} catch (error) /* istanbul ignore next */ {
|
||||
// An exception will be thrown here if a different
|
||||
// function is called than the one declared. Try to
|
||||
// provide a useful error message.
|
||||
|
@ -493,12 +491,12 @@ run_test("motion_keys", () => {
|
|||
overlays.streams_open = () => true;
|
||||
assert_mapping("up_arrow", stream_settings_ui, "switch_rows");
|
||||
assert_mapping("down_arrow", stream_settings_ui, "switch_rows");
|
||||
overlays.streams_open = () => false;
|
||||
delete overlays.streams_open;
|
||||
|
||||
overlays.lightbox_open = () => true;
|
||||
assert_mapping("left_arrow", lightbox, "prev");
|
||||
assert_mapping("right_arrow", lightbox, "next");
|
||||
overlays.lightbox_open = () => false;
|
||||
delete overlays.lightbox_open;
|
||||
|
||||
overlays.settings_open = () => true;
|
||||
assert_unmapped("end");
|
||||
|
@ -507,12 +505,12 @@ run_test("motion_keys", () => {
|
|||
assert_unmapped("page_up");
|
||||
assert_unmapped("page_down");
|
||||
assert_unmapped("spacebar");
|
||||
overlays.settings_open = () => false;
|
||||
delete overlays.settings_open;
|
||||
|
||||
overlays.is_active = () => true;
|
||||
delete overlays.is_active;
|
||||
overlays.drafts_open = () => true;
|
||||
assert_mapping("up_arrow", drafts, "drafts_handle_events");
|
||||
assert_mapping("down_arrow", drafts, "drafts_handle_events");
|
||||
overlays.is_active = () => false;
|
||||
overlays.drafts_open = () => false;
|
||||
delete overlays.is_active;
|
||||
delete overlays.drafts_open;
|
||||
});
|
||||
|
|
|
@ -644,7 +644,7 @@ run_test("appendValue/clear", ({mock_template}) => {
|
|||
const config = {
|
||||
$container,
|
||||
create_item_from_text: (s) => ({type: "color", display_value: s}),
|
||||
get_text_from_item: (s) => s.display_value,
|
||||
get_text_from_item: /* istanbul ignore next */ (s) => s.display_value,
|
||||
};
|
||||
|
||||
$pill_input.before = () => {};
|
||||
|
|
|
@ -11,7 +11,7 @@ run_test("test_early_returns", () => {
|
|||
const opts = {
|
||||
$elem: $stub,
|
||||
handlers: {
|
||||
ArrowLeft: () => {
|
||||
ArrowLeft: /* istanbul ignore next */ () => {
|
||||
throw new Error("do not dispatch this with alt key");
|
||||
},
|
||||
},
|
||||
|
|
|
@ -34,8 +34,8 @@ function basic_conf({first_key, prev_key, next_key}) {
|
|||
run_test("misc errors", ({override}) => {
|
||||
const conf = basic_conf({
|
||||
first_key: () => undefined,
|
||||
prev_key: () => undefined,
|
||||
next_key: () => undefined,
|
||||
prev_key: /* istanbul ignore next */ () => undefined,
|
||||
next_key: /* istanbul ignore next */ () => undefined,
|
||||
});
|
||||
|
||||
const cursor = new ListCursor(conf);
|
||||
|
@ -64,7 +64,7 @@ run_test("single item list", ({override}) => {
|
|||
const valid_key = "42";
|
||||
|
||||
const conf = basic_conf({
|
||||
first_key: () => valid_key,
|
||||
first_key: /* istanbul ignore next */ () => valid_key,
|
||||
next_key: () => undefined,
|
||||
prev_key: () => undefined,
|
||||
});
|
||||
|
@ -91,7 +91,7 @@ run_test("single item list", ({override}) => {
|
|||
|
||||
run_test("multiple item list", ({override}) => {
|
||||
const conf = basic_conf({
|
||||
first_key: () => 1,
|
||||
first_key: /* istanbul ignore next */ () => 1,
|
||||
next_key: (key) => (key < 3 ? key + 1 : undefined),
|
||||
prev_key: (key) => (key > 1 ? key - 1 : undefined),
|
||||
});
|
||||
|
|
|
@ -43,13 +43,6 @@ const ListWidget = zrequire("list_widget");
|
|||
function make_container() {
|
||||
const $container = {};
|
||||
|
||||
$container.length = () => 1;
|
||||
$container.is = () => false;
|
||||
$container.css = (prop) => {
|
||||
assert.equal(prop, "max-height");
|
||||
return "none";
|
||||
};
|
||||
|
||||
// Make our append function just set a field we can
|
||||
// check in our tests.
|
||||
$container.append = ($data) => {
|
||||
|
@ -123,6 +116,7 @@ function make_search_input() {
|
|||
|
||||
// Allow ourselves to be wrapped by $(...) and
|
||||
// return ourselves.
|
||||
/* istanbul ignore next */
|
||||
$element.to_jquery = () => $element;
|
||||
|
||||
$element.on = (event_name, f) => {
|
||||
|
@ -322,6 +316,7 @@ function sort_button(opts) {
|
|||
return opts.sort_type;
|
||||
case "sort-prop":
|
||||
return opts.prop_name;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error("unknown selector: " + sel);
|
||||
}
|
||||
|
@ -549,7 +544,7 @@ run_test("clear_event_handlers", () => {
|
|||
modifier: () => {},
|
||||
filter: {
|
||||
$element: $filter_element,
|
||||
predicate: () => true,
|
||||
predicate: /* istanbul ignore next */ () => true,
|
||||
},
|
||||
$simplebar_container: $scroll_container,
|
||||
};
|
||||
|
@ -602,8 +597,8 @@ run_test("errors", () => {
|
|||
blueslip.expect("error", "Filterer and predicate are mutually exclusive.");
|
||||
ListWidget.create($container, list, {
|
||||
filter: {
|
||||
filterer: () => true,
|
||||
predicate: () => true,
|
||||
filterer: /* istanbul ignore next */ () => true,
|
||||
predicate: /* istanbul ignore next */ () => true,
|
||||
},
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
|
@ -795,7 +790,8 @@ run_test("render item", () => {
|
|||
blueslip.expect("error", "html_selector should be a function.");
|
||||
ListWidget.create($container, list, {
|
||||
name: "replace-list",
|
||||
modifier: (item) => `<tr data-item=${item.value}>${item.text}</tr>\n`,
|
||||
modifier: /* istanbul ignore next */ (item) =>
|
||||
`<tr data-item=${item.value}>${item.text}</tr>\n`,
|
||||
get_item,
|
||||
html_selector: "hello world",
|
||||
$simplebar_container: $scroll_container,
|
||||
|
@ -855,6 +851,7 @@ run_test("Multiselect dropdown retain_selected_items", () => {
|
|||
if (element) {
|
||||
return true;
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,11 +27,6 @@ const example_realm_linkifiers = [
|
|||
];
|
||||
user_settings.translate_emoticons = false;
|
||||
|
||||
function Image() {
|
||||
return {};
|
||||
}
|
||||
set_global("Image", Image);
|
||||
|
||||
set_global("document", {compatMode: "CSS1Compat"});
|
||||
|
||||
const emoji = zrequire("emoji");
|
||||
|
@ -244,6 +239,7 @@ test("marked_shared", () => {
|
|||
|
||||
for (const test of tests) {
|
||||
// Ignore tests if specified
|
||||
/* istanbul ignore if */
|
||||
if (test.ignore === true) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,8 @@ function get_user_id_from_name(name) {
|
|||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
/* istanbul ignore next */
|
||||
throw new Error(`unexpected name ${name}`);
|
||||
}
|
||||
|
||||
function is_valid_full_name_and_user_id(name, user_id) {
|
||||
|
@ -99,7 +100,8 @@ function get_emoji_name(codepoint) {
|
|||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
/* istanbul ignore next */
|
||||
throw new Error(`unexpected codepoint ${codepoint}`);
|
||||
}
|
||||
|
||||
const realm_emoji_map = new Map();
|
||||
|
|
|
@ -93,17 +93,13 @@ function config_fake_channel(conf) {
|
|||
// There's a separate call with anchor="newest" that happens
|
||||
// unconditionally; do basic verification of that call.
|
||||
if (opts.data.anchor === "newest") {
|
||||
if (!called_with_newest_flag) {
|
||||
called_with_newest_flag = true;
|
||||
assert.equal(opts.data.num_after, 0);
|
||||
return;
|
||||
}
|
||||
throw new Error("Only one 'newest' call allowed");
|
||||
assert.ok(!called_with_newest_flag, "Only one 'newest' call allowed");
|
||||
called_with_newest_flag = true;
|
||||
assert.equal(opts.data.num_after, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (called && !conf.can_call_again) {
|
||||
throw new Error("only use this for one call");
|
||||
}
|
||||
assert.ok(!called || conf.can_call_again, "only use this for one call");
|
||||
if (!conf.can_call_again) {
|
||||
assert.equal(self.success, undefined);
|
||||
}
|
||||
|
|
|
@ -2,19 +2,10 @@
|
|||
|
||||
const {strict: assert} = require("assert");
|
||||
|
||||
const {
|
||||
set_global,
|
||||
with_function_call_disallowed_rewire,
|
||||
zrequire,
|
||||
} = require("../zjsunit/namespace");
|
||||
const {with_function_call_disallowed_rewire, zrequire} = require("../zjsunit/namespace");
|
||||
const {run_test} = require("../zjsunit/test");
|
||||
const blueslip = require("../zjsunit/zblueslip");
|
||||
|
||||
set_global("setTimeout", (f, delay) => {
|
||||
assert.equal(delay, 0);
|
||||
return f();
|
||||
});
|
||||
|
||||
const muted_topics = zrequire("muted_topics");
|
||||
const muted_users = zrequire("muted_users");
|
||||
const {MessageListData} = zrequire("../js/message_list_data");
|
||||
|
|
|
@ -6,14 +6,11 @@ const _ = require("lodash");
|
|||
|
||||
const {mock_esm, set_global, zrequire} = require("../zjsunit/namespace");
|
||||
const {run_test} = require("../zjsunit/test");
|
||||
const {user_settings} = require("../zjsunit/zpage_params");
|
||||
|
||||
set_global("document", "document-stub");
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
user_settings.twenty_four_hour_time = false;
|
||||
|
||||
mock_esm("../../static/js/message_lists", {home: "stub"});
|
||||
|
||||
// timerender calls setInterval when imported
|
||||
|
@ -25,9 +22,6 @@ mock_esm("../../static/js/timerender", {
|
|||
return [{outerHTML: String(time1.getTime()) + " - " + String(time2.getTime())}];
|
||||
},
|
||||
stringify_time(time) {
|
||||
if (user_settings.twenty_four_hour_time) {
|
||||
return time.toString("HH:mm");
|
||||
}
|
||||
return time.toString("h:mm TT");
|
||||
},
|
||||
});
|
||||
|
|
|
@ -160,13 +160,6 @@ run_test("basics", () => {
|
|||
|
||||
all_messages_data.all_messages_data = {
|
||||
all_messages: () => messages,
|
||||
get: (msg_id) => {
|
||||
assert.equal(msg_id, selected_id);
|
||||
return selected_message;
|
||||
},
|
||||
fetch_status: {
|
||||
has_found_newest: () => true,
|
||||
},
|
||||
empty: () => false,
|
||||
first: () => ({id: 900}),
|
||||
last: () => ({id: 1100}),
|
||||
|
|
|
@ -26,7 +26,6 @@ const alice = {
|
|||
|
||||
people.init();
|
||||
people.add_active_user(alice);
|
||||
people.is_my_user_id = () => false;
|
||||
|
||||
function set_filter(terms) {
|
||||
const filter = new Filter(terms);
|
||||
|
|
|
@ -56,13 +56,17 @@ test("allow_notification_alert", () => {
|
|||
assert.equal(navbar_alerts.should_show_notifications(ls), false);
|
||||
|
||||
// Avoid showing if notification is already granted.
|
||||
/* istanbul ignore next */
|
||||
notifications.permission_state = () => "granted";
|
||||
notifications.granted_desktop_notifications_permission = () => "granted";
|
||||
assert.equal(navbar_alerts.should_show_notifications(ls), false);
|
||||
|
||||
// Don't ask for permission to spectator.
|
||||
/* istanbul ignore next */
|
||||
util.is_mobile = () => false;
|
||||
/* istanbul ignore next */
|
||||
notifications.granted_desktop_notifications_permission = () => false;
|
||||
/* istanbul ignore next */
|
||||
notifications.permission_state = () => "granted";
|
||||
page_params.is_spectator = true;
|
||||
assert.equal(navbar_alerts.should_show_notifications(ls), false);
|
||||
|
|
|
@ -11,12 +11,15 @@ function password_field(min_length, min_guesses) {
|
|||
const self = {};
|
||||
|
||||
self.data = (field) => {
|
||||
if (field === "minLength") {
|
||||
return min_length;
|
||||
} else if (field === "minGuesses") {
|
||||
return min_guesses;
|
||||
switch (field) {
|
||||
case "minLength":
|
||||
return min_length;
|
||||
case "minGuesses":
|
||||
return min_guesses;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`Unknown field ${field}`);
|
||||
}
|
||||
throw new Error(`Unknown field ${field}`);
|
||||
};
|
||||
|
||||
return self;
|
||||
|
|
|
@ -835,9 +835,13 @@ test_people("extract_people_from_message", ({override_rewire}) => {
|
|||
assert.ok(reported);
|
||||
|
||||
// Get line coverage
|
||||
people.__Rewire__("report_late_add", () => {
|
||||
throw new Error("unexpected late add");
|
||||
});
|
||||
people.__Rewire__(
|
||||
"report_late_add",
|
||||
/* istanbul ignore next */
|
||||
() => {
|
||||
throw new Error("unexpected late add");
|
||||
},
|
||||
);
|
||||
|
||||
message = {
|
||||
type: "private",
|
||||
|
|
|
@ -49,9 +49,6 @@ const spectators = mock_esm("../../static/js/spectators", {
|
|||
});
|
||||
|
||||
message_lists.current = {
|
||||
selected_message() {
|
||||
return {sent_by_me: true};
|
||||
},
|
||||
selected_row() {
|
||||
return $(".selected-row");
|
||||
},
|
||||
|
|
|
@ -63,9 +63,11 @@ const ListWidget = mock_esm("../../static/js/list_widget", {
|
|||
hard_redraw: noop,
|
||||
render_item: (item) => ListWidget.modifier(item),
|
||||
replace_list_data: (data) => {
|
||||
if (expected_data_to_replace_in_list_widget === undefined) {
|
||||
throw new Error("You must set expected_data_to_replace_in_list_widget");
|
||||
}
|
||||
assert.notEqual(
|
||||
expected_data_to_replace_in_list_widget,
|
||||
undefined,
|
||||
"You must set expected_data_to_replace_in_list_widget",
|
||||
);
|
||||
assert.deepEqual(data, expected_data_to_replace_in_list_widget);
|
||||
expected_data_to_replace_in_list_widget = undefined;
|
||||
},
|
||||
|
@ -110,7 +112,6 @@ mock_esm("../../static/js/stream_data", {
|
|||
// We only test via muted topics for now.
|
||||
// TODO: Make muted streams and test them.
|
||||
false,
|
||||
is_subscribed: () => true,
|
||||
});
|
||||
mock_esm("../../static/js/stream_list", {
|
||||
handle_narrow_deactivated: noop,
|
||||
|
|
|
@ -88,6 +88,7 @@ const get_content_element = () => {
|
|||
|
||||
// Fend off dumb security bugs by forcing devs to be
|
||||
// intentional about HTML manipulation.
|
||||
/* istanbul ignore next */
|
||||
function security_violation() {
|
||||
throw new Error(`
|
||||
Be super careful about HTML manipulation.
|
||||
|
@ -401,9 +402,7 @@ function test_code_playground(mock_template, viewing_code) {
|
|||
// our case "fake" zjquery objects).
|
||||
const prepends = [];
|
||||
$pre.prepend = (arg) => {
|
||||
if (!arg.__zjquery) {
|
||||
throw new Error("We should only prepend jQuery objects.");
|
||||
}
|
||||
assert.ok(arg.__zjquery, "We should only prepend jQuery objects.");
|
||||
prepends.push(arg);
|
||||
};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
const {strict: assert} = require("assert");
|
||||
|
||||
const {mock_esm, set_global, zrequire} = require("../zjsunit/namespace");
|
||||
const {mock_esm, zrequire} = require("../zjsunit/namespace");
|
||||
const {run_test} = require("../zjsunit/test");
|
||||
const $ = require("../zjsunit/zjquery");
|
||||
const {page_params} = require("../zjsunit/zpage_params");
|
||||
|
@ -25,8 +25,6 @@ mock_esm("../../static/js/ui_util", {
|
|||
place_caret_at_end: noop,
|
||||
});
|
||||
|
||||
set_global("setTimeout", (func) => func());
|
||||
|
||||
const search = zrequire("search");
|
||||
const search_pill = zrequire("search_pill");
|
||||
const {Filter} = zrequire("../js/filter");
|
||||
|
@ -63,14 +61,14 @@ test("update_button_visibility", () => {
|
|||
|
||||
$search_query.is = () => true;
|
||||
$search_query.val("");
|
||||
narrow_state.active = () => false;
|
||||
delete narrow_state.active;
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
$search_query.is = () => false;
|
||||
$search_query.val("Test search term");
|
||||
narrow_state.active = () => false;
|
||||
delete narrow_state.active;
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
@ -144,9 +142,13 @@ test("initialize", () => {
|
|||
let operators;
|
||||
let is_blurred;
|
||||
let is_append_search_string_called;
|
||||
$search_query_box.on("blur", () => {
|
||||
is_blurred = true;
|
||||
});
|
||||
$search_query_box.on(
|
||||
"blur",
|
||||
/* istanbul ignore next */
|
||||
() => {
|
||||
is_blurred = true;
|
||||
},
|
||||
);
|
||||
search_pill.append_search_string = () => {
|
||||
is_append_search_string_called = true;
|
||||
};
|
||||
|
@ -155,14 +157,17 @@ test("initialize", () => {
|
|||
is_blurred = false;
|
||||
is_append_search_string_called = false;
|
||||
$search_query_box.val(search_box_val);
|
||||
/* istanbul ignore next */
|
||||
Filter.parse = (search_string) => {
|
||||
assert.equal(search_string, search_box_val);
|
||||
return operators;
|
||||
};
|
||||
/* istanbul ignore next */
|
||||
narrow.activate = (raw_operators, options) => {
|
||||
assert.deepEqual(raw_operators, operators);
|
||||
assert.deepEqual(options, {trigger: "search"});
|
||||
};
|
||||
/* istanbul ignore next */
|
||||
search_pill.get_search_string_for_current_filter = () => search_box_val;
|
||||
};
|
||||
|
||||
|
@ -285,6 +290,7 @@ test("initialize", () => {
|
|||
type: "keyup",
|
||||
which: 15,
|
||||
};
|
||||
/* istanbul ignore next */
|
||||
$search_query_box.is = () => false;
|
||||
$searchbox_form.trigger(ev);
|
||||
|
||||
|
|
|
@ -53,14 +53,14 @@ run_test("update_button_visibility", () => {
|
|||
|
||||
$search_query.is = () => true;
|
||||
$search_query.val("");
|
||||
narrow_state.active = () => false;
|
||||
delete narrow_state.active;
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
$search_query.is = () => false;
|
||||
$search_query.val("Test search term");
|
||||
narrow_state.active = () => false;
|
||||
delete narrow_state.active;
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
@ -247,6 +247,7 @@ run_test("initialize", () => {
|
|||
_setup("");
|
||||
|
||||
ev.key = "a";
|
||||
/* istanbul ignore next */
|
||||
$search_query_box.is = () => false;
|
||||
$searchbox_form.trigger(ev);
|
||||
|
||||
|
|
|
@ -676,8 +676,9 @@ test("topic_suggestions", ({override, override_rewire}) => {
|
|||
return office_id;
|
||||
case "devel":
|
||||
return devel_id;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
return undefined;
|
||||
throw new Error(`unknown stream ${stream_name}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -641,8 +641,9 @@ test("topic_suggestions", ({override, override_rewire}) => {
|
|||
return office_id;
|
||||
case "devel":
|
||||
return devel_id;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
return undefined;
|
||||
throw new Error(`unknown stream ${stream_name}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -40,9 +40,6 @@ mock_esm("../../static/js/ui_report", {
|
|||
hide_error() {
|
||||
return false;
|
||||
},
|
||||
show_error() {
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
mock_esm("../../static/js/stream_events", {
|
||||
|
|
|
@ -60,15 +60,16 @@ run_test("settings", ({override_rewire}) => {
|
|||
|
||||
let topic_data_called = 0;
|
||||
$topic_tr_html.attr = (opts) => {
|
||||
if (opts === "data-stream-id") {
|
||||
topic_data_called += 1;
|
||||
return frontend.stream_id;
|
||||
topic_data_called += 1;
|
||||
switch (opts) {
|
||||
case "data-stream-id":
|
||||
return frontend.stream_id;
|
||||
case "data-topic":
|
||||
return "js";
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`Unknown attribute ${opts}`);
|
||||
}
|
||||
if (opts === "data-topic") {
|
||||
topic_data_called += 1;
|
||||
return "js";
|
||||
}
|
||||
throw new Error(`Unknown attribute ${opts}`);
|
||||
};
|
||||
|
||||
let unmute_topic_called = false;
|
||||
|
|
|
@ -51,11 +51,9 @@ run_test("settings", ({override_rewire}) => {
|
|||
|
||||
let row_attribute_fetched = false;
|
||||
$fake_row.attr = (opts) => {
|
||||
if (opts === "data-user-id") {
|
||||
row_attribute_fetched += 1;
|
||||
return "5";
|
||||
}
|
||||
throw new Error(`Unknown attribute ${opts}`);
|
||||
assert.equal(opts, "data-user-id");
|
||||
row_attribute_fetched += 1;
|
||||
return "5";
|
||||
};
|
||||
|
||||
let unmute_user_called = false;
|
||||
|
|
|
@ -47,7 +47,6 @@ const settings_bots = zrequire("settings_bots");
|
|||
const stream_settings_data = zrequire("stream_settings_data");
|
||||
const settings_account = zrequire("settings_account");
|
||||
const settings_org = zrequire("settings_org");
|
||||
const sub_store = zrequire("sub_store");
|
||||
const dropdown_list_widget = zrequire("dropdown_list_widget");
|
||||
|
||||
function test(label, f) {
|
||||
|
@ -195,7 +194,6 @@ function test_submit_settings_form(override, submit_form) {
|
|||
let stubs = createSaveButtons(subsection);
|
||||
let $save_button = stubs.$save_button;
|
||||
$save_button.attr("id", `org-submit-${subsection}`);
|
||||
$save_button.replace = () => `${subsection}`;
|
||||
|
||||
$("#id_realm_waiting_period_threshold").val(10);
|
||||
|
||||
|
@ -241,6 +239,7 @@ function test_submit_settings_form(override, submit_form) {
|
|||
$add_custom_emoji_policy_elem,
|
||||
$create_public_stream_policy_elem,
|
||||
$create_private_stream_policy_elem,
|
||||
$invite_to_realm_policy_elem,
|
||||
$invite_to_stream_policy_elem,
|
||||
]);
|
||||
|
||||
|
@ -250,6 +249,7 @@ function test_submit_settings_form(override, submit_form) {
|
|||
|
||||
let expected_value = {
|
||||
bot_creation_policy: 1,
|
||||
invite_to_realm_policy: 2,
|
||||
invite_to_stream_policy: 1,
|
||||
email_address_visibility: 1,
|
||||
add_custom_emoji_policy: 1,
|
||||
|
@ -925,10 +925,6 @@ test("misc", ({override_rewire}) => {
|
|||
let setting_name = "realm_notifications_stream_id";
|
||||
let $elem = $(`#${CSS.escape(setting_name)}_widget #${CSS.escape(setting_name)}_name`);
|
||||
$elem.closest = () => $stub_notification_disable_parent;
|
||||
sub_store.__Rewire__("get", (stream_id) => {
|
||||
assert.equal(stream_id, 42);
|
||||
return {name: "some_stream"};
|
||||
});
|
||||
settings_org.notifications_stream_widget.render(42);
|
||||
assert.equal($elem.text(), "#some_stream");
|
||||
assert.ok(!$elem.hasClass("text-warning"));
|
||||
|
@ -940,10 +936,6 @@ test("misc", ({override_rewire}) => {
|
|||
setting_name = "realm_signup_notifications_stream_id";
|
||||
$elem = $(`#${CSS.escape(setting_name)}_widget #${CSS.escape(setting_name)}_name`);
|
||||
$elem.closest = () => $stub_notification_disable_parent;
|
||||
sub_store.__Rewire__("get", (stream_id) => {
|
||||
assert.equal(stream_id, 75);
|
||||
return {name: "some_stream"};
|
||||
});
|
||||
settings_org.signup_notifications_stream_widget.render(75);
|
||||
assert.equal($elem.text(), "#some_stream");
|
||||
assert.ok(!$elem.hasClass("text-warning"));
|
||||
|
|
|
@ -116,8 +116,6 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
|||
|
||||
user_groups.get_realm_user_groups = () => [realm_user_group];
|
||||
|
||||
people.get_visible_email = () => bob.email;
|
||||
|
||||
let templates_render_called = false;
|
||||
const $fake_rendered_temp = $.create("fake_admin_user_group_list_template_rendered");
|
||||
mock_template("settings/admin_user_group_list.hbs", false, (args) => {
|
||||
|
@ -139,12 +137,6 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
|||
if (user_id === iago.user_id) {
|
||||
return iago;
|
||||
}
|
||||
if (user_id === alice.user_id) {
|
||||
return alice;
|
||||
}
|
||||
if (user_id === undefined) {
|
||||
return noop;
|
||||
}
|
||||
assert.equal(user_id, 4);
|
||||
blueslip.expect("warn", "Undefined user in function append_user");
|
||||
get_by_user_id_called = true;
|
||||
|
@ -246,9 +238,6 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
|||
saved_fade_out_called = true;
|
||||
};
|
||||
$(cancel_selector).css = (data) => {
|
||||
if (typeof data === "string") {
|
||||
assert.equal(data, "display");
|
||||
}
|
||||
assert.equal(typeof data, "object");
|
||||
assert.equal(data.display, "inline-block");
|
||||
assert.equal(data.opacity, "0");
|
||||
|
@ -258,9 +247,6 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
|||
cancel_fade_to_called = true;
|
||||
};
|
||||
$(instructions_selector).css = (data) => {
|
||||
if (typeof data === "string") {
|
||||
assert.equal(data, "display");
|
||||
}
|
||||
assert.equal(typeof data, "object");
|
||||
assert.equal(data.display, "block");
|
||||
assert.equal(data.opacity, "0");
|
||||
|
@ -284,17 +270,15 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
|||
let get_by_email_called = false;
|
||||
people.get_by_email = (user_email) => {
|
||||
get_by_email_called = true;
|
||||
if (user_email === iago.email) {
|
||||
return iago;
|
||||
switch (user_email) {
|
||||
case iago.email:
|
||||
return iago;
|
||||
case bob.email:
|
||||
return bob;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error("Expected user email to be of Iago or Bob here.");
|
||||
}
|
||||
if (user_email === bob.email) {
|
||||
return bob;
|
||||
}
|
||||
throw new Error("Expected user email to be of Alice or Iago here.");
|
||||
};
|
||||
pills.onPillCreate = (handler) => {
|
||||
assert.equal(typeof handler, "function");
|
||||
handler();
|
||||
};
|
||||
|
||||
function test_create_item(handler) {
|
||||
|
@ -363,8 +347,9 @@ test_ui("with_external_user", ({override_rewire, mock_template}) => {
|
|||
|
||||
user_groups.get_realm_user_groups = () => [realm_user_group];
|
||||
|
||||
// We return noop because these are already tested, so we skip them
|
||||
people.get_realm_users = () => noop;
|
||||
// We return [] because these are already tested, so we skip them
|
||||
/* istanbul ignore next */
|
||||
people.get_realm_users = () => [];
|
||||
|
||||
mock_template(
|
||||
"settings/admin_user_group_list.hbs",
|
||||
|
@ -372,9 +357,9 @@ test_ui("with_external_user", ({override_rewire, mock_template}) => {
|
|||
() => "settings/admin_user_group_list.hbs",
|
||||
);
|
||||
|
||||
people.get_by_user_id = () => noop;
|
||||
people.get_by_user_id = () => "user stub";
|
||||
|
||||
override_rewire(user_pill, "append_person", () => noop);
|
||||
override_rewire(user_pill, "append_person", noop);
|
||||
|
||||
let can_edit_called = 0;
|
||||
override_rewire(settings_user_groups, "can_edit", () => {
|
||||
|
@ -391,30 +376,32 @@ test_ui("with_external_user", ({override_rewire, mock_template}) => {
|
|||
const $description_field_stub = $.create("fake-description-field");
|
||||
const $input_stub = $.create("fake-input");
|
||||
$user_group_stub.find = (elem) => {
|
||||
if (elem === ".name") {
|
||||
user_group_find_called += 1;
|
||||
return $name_field_stub;
|
||||
user_group_find_called += 1;
|
||||
switch (elem) {
|
||||
case ".name":
|
||||
return $name_field_stub;
|
||||
case ".description":
|
||||
return $description_field_stub;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`Unknown element ${elem}`);
|
||||
}
|
||||
if (elem === ".description") {
|
||||
user_group_find_called += 1;
|
||||
return $description_field_stub;
|
||||
}
|
||||
throw new Error(`Unknown element ${elem}`);
|
||||
};
|
||||
|
||||
const $pill_container_stub = $(`.pill-container[data-group-pills="${CSS.escape(1)}"]`);
|
||||
const $pill_stub = $.create("fake-pill");
|
||||
let pill_container_find_called = 0;
|
||||
$pill_container_stub.find = (elem) => {
|
||||
if (elem === ".input") {
|
||||
pill_container_find_called += 1;
|
||||
return $input_stub;
|
||||
pill_container_find_called += 1;
|
||||
switch (elem) {
|
||||
case ".input":
|
||||
return $input_stub;
|
||||
case ".pill":
|
||||
return $pill_stub;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`Unknown element ${elem}`);
|
||||
}
|
||||
if (elem === ".pill") {
|
||||
pill_container_find_called += 1;
|
||||
return $pill_stub;
|
||||
}
|
||||
throw new Error(`Unknown element ${elem}`);
|
||||
};
|
||||
|
||||
$input_stub.css = (property, val) => {
|
||||
|
@ -437,10 +424,10 @@ test_ui("with_external_user", ({override_rewire, mock_template}) => {
|
|||
assert.equal(value, "0.5");
|
||||
};
|
||||
|
||||
// We return noop because these are already tested, so we skip them
|
||||
$pill_container_stub.children = () => noop;
|
||||
// We return [] because these are already tested, so we skip them
|
||||
$pill_container_stub.children = () => [];
|
||||
|
||||
$("#user-groups").append = () => noop;
|
||||
$("#user-groups").append = noop;
|
||||
|
||||
reset_test_setup($pill_container_stub);
|
||||
|
||||
|
@ -621,6 +608,7 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
|||
(function test_do_not_blur() {
|
||||
const blur_event_classes = [".name", ".description", ".input"];
|
||||
let api_endpoint_called = false;
|
||||
/* istanbul ignore next */
|
||||
channel.post = () => {
|
||||
api_endpoint_called = true;
|
||||
};
|
||||
|
@ -658,10 +646,8 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
|||
|
||||
api_endpoint_called = false;
|
||||
$fake_this.closest = (class_name) => {
|
||||
if (class_name === ".typeahead") {
|
||||
return [1];
|
||||
}
|
||||
return [];
|
||||
assert.equal(class_name, ".typeahead");
|
||||
return [1];
|
||||
};
|
||||
handler.call($fake_this, event);
|
||||
assert.ok(!api_endpoint_called);
|
||||
|
@ -755,9 +741,6 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
|||
cancel_fade_out_called = true;
|
||||
};
|
||||
$(saved_selector).css = (data) => {
|
||||
if (typeof data === "string") {
|
||||
assert.equal(data, "display");
|
||||
}
|
||||
assert.equal(typeof data, "object");
|
||||
assert.equal(data.display, "inline-block");
|
||||
assert.equal(data.opacity, "0");
|
||||
|
|
|
@ -10,7 +10,6 @@ const denmark_stream_id = 101;
|
|||
|
||||
const ui = mock_esm("../../static/js/ui", {
|
||||
get_content_element: ($element) => $element,
|
||||
get_scroll_element: ($element) => $element,
|
||||
});
|
||||
|
||||
mock_esm("../../static/js/hash_util", {
|
||||
|
|
|
@ -81,7 +81,7 @@ test("basics", () => {
|
|||
max_message_id = stream_topic_history.get_max_message_id(stream_id);
|
||||
assert.deepEqual(max_message_id, 103);
|
||||
|
||||
message_util.get_messages_in_topic = () => [{id: 102}];
|
||||
delete message_util.get_messages_in_topic;
|
||||
// Removing first topic1 message has no effect.
|
||||
stream_topic_history.remove_messages({
|
||||
stream_id,
|
||||
|
@ -163,8 +163,6 @@ test("server_history", () => {
|
|||
const stream_id = sub.stream_id;
|
||||
stream_data.add_sub(sub);
|
||||
|
||||
all_messages_data.all_messages_data.fetch_status.has_found_newest = () => false;
|
||||
|
||||
assert.equal(stream_topic_history.is_complete_for_stream_id(stream_id), false);
|
||||
|
||||
stream_topic_history.add_message({
|
||||
|
@ -332,6 +330,7 @@ test("server_history_end_to_end", () => {
|
|||
|
||||
// Try getting server history for a second time.
|
||||
|
||||
/* istanbul ignore next */
|
||||
channel.get = () => {
|
||||
throw new Error("We should not get more data.");
|
||||
};
|
||||
|
|
|
@ -60,9 +60,14 @@ run_test("transmit_message_ajax", () => {
|
|||
});
|
||||
|
||||
run_test("transmit_message_ajax_reload_pending", () => {
|
||||
/* istanbul ignore next */
|
||||
const success = () => {
|
||||
throw new Error("unexpected success");
|
||||
};
|
||||
/* istanbul ignore next */
|
||||
const error = () => {
|
||||
throw new Error("unexpected error");
|
||||
};
|
||||
|
||||
reload_state.is_pending = () => true;
|
||||
|
||||
|
@ -80,13 +85,6 @@ run_test("transmit_message_ajax_reload_pending", () => {
|
|||
|
||||
const request = {foo: "bar"};
|
||||
|
||||
let error_func_called;
|
||||
const error = (response) => {
|
||||
assert.equal(response, "Error sending message");
|
||||
error_func_called = true;
|
||||
};
|
||||
|
||||
error_func_called = false;
|
||||
channel.post = (opts) => {
|
||||
assert.equal(opts.url, "/json/messages");
|
||||
assert.equal(opts.data.foo, "bar");
|
||||
|
@ -94,7 +92,6 @@ run_test("transmit_message_ajax_reload_pending", () => {
|
|||
opts.error(xhr, "bad request");
|
||||
};
|
||||
transmit.send_message(request, success, error);
|
||||
assert.ok(!error_func_called);
|
||||
assert.ok(reload_initiated);
|
||||
});
|
||||
|
||||
|
@ -143,8 +140,6 @@ run_test("reply_message_private", ({override_rewire}) => {
|
|||
};
|
||||
people.add_active_user(fred);
|
||||
|
||||
people.is_my_user_id = () => false;
|
||||
|
||||
const pm_message = {
|
||||
type: "private",
|
||||
display_recipient: [{id: fred.user_id}],
|
||||
|
|
|
@ -453,6 +453,7 @@ test("sort_recipients pm counts", () => {
|
|||
"zman@test.net",
|
||||
]);
|
||||
|
||||
/* istanbul ignore next */
|
||||
function compare() {
|
||||
throw new Error("We do not expect to need a tiebreaker here.");
|
||||
}
|
||||
|
|
|
@ -250,10 +250,8 @@ test("num_unread_for_topic", ({override_rewire}) => {
|
|||
const stream_id = 301;
|
||||
|
||||
override_rewire(sub_store, "get", (arg) => {
|
||||
if (arg === stream_id) {
|
||||
return {name: "Some stream"};
|
||||
}
|
||||
throw new Error(`Unknown stream ${arg}`);
|
||||
assert.equal(arg, stream_id);
|
||||
return {name: "Some stream"};
|
||||
});
|
||||
|
||||
let count = unread.num_unread_for_topic(stream_id, "lunch");
|
||||
|
|
|
@ -63,6 +63,7 @@ run_test("initialize", ({override_rewire}) => {
|
|||
};
|
||||
success_callback();
|
||||
break;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error("Unhandled case");
|
||||
}
|
||||
|
@ -85,9 +86,6 @@ run_test("initialize", ({override_rewire}) => {
|
|||
$("input[type=radio][name=schedule]:checked").val = () =>
|
||||
document.querySelector("input[type=radio][name=schedule]:checked").value;
|
||||
|
||||
$("#autopay-form").data = (key) =>
|
||||
document.querySelector("#autopay-form").getAttribute("data-" + key);
|
||||
|
||||
const initialize_function = $.get_initialize_function();
|
||||
initialize_function();
|
||||
|
||||
|
|
|
@ -175,6 +175,7 @@ run_test("partial updates", () => {
|
|||
|
||||
assert.equal(rendered_html, "<ul>\n<li>foo1</li>\n<li>foo2</li>\n<li>foo3</li>\n</ul>");
|
||||
|
||||
/* istanbul ignore next */
|
||||
replace_content = () => {
|
||||
throw new Error("should not replace entire html");
|
||||
};
|
||||
|
@ -209,6 +210,7 @@ run_test("partial updates", () => {
|
|||
});
|
||||
|
||||
run_test("eq_array easy cases", () => {
|
||||
/* istanbul ignore next */
|
||||
const bogus_eq = () => {
|
||||
throw new Error("we should not be comparing elements");
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@ exports.intl = createIntl(
|
|||
defaultRichTextElements: Object.fromEntries(
|
||||
["b", "code", "em", "i", "kbd", "p", "strong"].map((tag) => [
|
||||
tag,
|
||||
/* istanbul ignore next */
|
||||
(content_html) => `<${tag}>${content_html}</${tag}>`,
|
||||
]),
|
||||
),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
const {strict: assert} = require("assert");
|
||||
const path = require("path");
|
||||
|
||||
require("css.escape");
|
||||
|
@ -39,9 +40,7 @@ function immediate(f) {
|
|||
|
||||
// Find the files we need to run.
|
||||
const files = process.argv.slice(2);
|
||||
if (files.length === 0) {
|
||||
throw new Error("No tests found");
|
||||
}
|
||||
assert.notEqual(files.length, 0, "No tests found");
|
||||
|
||||
// Set up our namespace helpers.
|
||||
const window = new Proxy(global, {
|
||||
|
@ -73,6 +72,7 @@ handlebars.hook_require();
|
|||
|
||||
const noop = function () {};
|
||||
|
||||
/* istanbul ignore next */
|
||||
function short_tb(tb) {
|
||||
const lines = tb.split("\n");
|
||||
|
||||
|
@ -102,7 +102,6 @@ try {
|
|||
for (const file of files) {
|
||||
namespace.start();
|
||||
namespace.set_global("window", window);
|
||||
namespace.set_global("to_$", () => window);
|
||||
namespace.set_global("location", dom.window.location);
|
||||
window.location.href = "http://zulip.zulipdev.com/#";
|
||||
namespace.set_global("setTimeout", noop);
|
||||
|
@ -132,7 +131,7 @@ try {
|
|||
|
||||
namespace.finish();
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error) /* istanbul ignore next */ {
|
||||
if (process.env.USING_INSTRUMENTED_CODE) {
|
||||
console.info(`
|
||||
TEST FAILED! Before using the --coverage option please make sure that your
|
||||
|
|
|
@ -36,6 +36,7 @@ class MarkdownComparer {
|
|||
constructor(output_formatter) {
|
||||
this._output_formatter =
|
||||
output_formatter ||
|
||||
/* istanbul ignore next */
|
||||
function (actual, expected) {
|
||||
return ["Actual and expected output do not match.", actual, "!=", expected].join(
|
||||
"\n",
|
||||
|
@ -44,6 +45,7 @@ class MarkdownComparer {
|
|||
this._document = new JSDOM().window.document;
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
setFormatter(output_formatter) {
|
||||
this._output_formatter = output_formatter || this._output_formatter;
|
||||
}
|
||||
|
@ -88,6 +90,7 @@ class MarkdownComparer {
|
|||
} else if (name_a > name_b) {
|
||||
return 1;
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
return 0;
|
||||
});
|
||||
|
||||
|
@ -139,6 +142,7 @@ class MarkdownComparer {
|
|||
message = message || "";
|
||||
message += "\n";
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (comparison_results.are_equivalent === false) {
|
||||
throw new assert.AssertionError({
|
||||
message:
|
||||
|
@ -157,6 +161,7 @@ class MarkdownComparer {
|
|||
message = message || "";
|
||||
message += "\n";
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (comparison_results.are_equivalent) {
|
||||
throw new assert.AssertionError({
|
||||
message:
|
||||
|
@ -174,11 +179,13 @@ class MarkdownComparer {
|
|||
|
||||
function returnComparer() {
|
||||
if (!_markdownComparerInstance) {
|
||||
_markdownComparerInstance = new MarkdownComparer((actual, expected) =>
|
||||
[
|
||||
"Actual and expected output do not match. Showing diff",
|
||||
mdiff.diff_strings(actual, expected),
|
||||
].join("\n"),
|
||||
_markdownComparerInstance = new MarkdownComparer(
|
||||
/* istanbul ignore next */
|
||||
(actual, expected) =>
|
||||
[
|
||||
"Actual and expected output do not match. Showing diff",
|
||||
mdiff.diff_strings(actual, expected),
|
||||
].join("\n"),
|
||||
);
|
||||
}
|
||||
return _markdownComparerInstance;
|
||||
|
@ -193,6 +200,7 @@ module.exports = {
|
|||
returnComparer().assertNotEqual(actual, expected, message);
|
||||
},
|
||||
|
||||
/* istanbul ignore next */
|
||||
setFormatter(output_formatter) {
|
||||
returnComparer().setFormatter(output_formatter);
|
||||
},
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
const {strict: assert} = require("assert");
|
||||
const Module = require("module");
|
||||
const path = require("path");
|
||||
|
||||
|
@ -24,6 +25,7 @@ let jquery_function;
|
|||
|
||||
const template_path = "/static/templates/";
|
||||
|
||||
/* istanbul ignore next */
|
||||
function need_to_mock_template_error(filename) {
|
||||
const i = filename.indexOf(template_path);
|
||||
|
||||
|
@ -100,6 +102,7 @@ function template_stub({filename, actual_render}) {
|
|||
|
||||
// Force devs to call mock_template on every top-level template
|
||||
// render so they can introspect the data.
|
||||
/* istanbul ignore if */
|
||||
if (!template_mocks.has(filename)) {
|
||||
throw new Error(need_to_mock_template_error(filename));
|
||||
}
|
||||
|
@ -126,9 +129,7 @@ function template_stub({filename, actual_render}) {
|
|||
}
|
||||
|
||||
exports.start = () => {
|
||||
if (actual_load !== undefined) {
|
||||
throw new Error("namespace.start was called twice in a row.");
|
||||
}
|
||||
assert.equal(actual_load, undefined, "namespace.start was called twice in a row.");
|
||||
actual_load = Module._load;
|
||||
Module._load = load;
|
||||
};
|
||||
|
@ -163,11 +164,11 @@ exports.start = () => {
|
|||
// format preferred by Webpack.
|
||||
|
||||
exports.mock_cjs = (module_path, obj) => {
|
||||
if (module_path === "jquery") {
|
||||
throw new Error(
|
||||
"We automatically mock jquery to zjquery. Grep for mock_jquery if you want more control.",
|
||||
);
|
||||
}
|
||||
assert.notEqual(
|
||||
module_path,
|
||||
"jquery",
|
||||
"We automatically mock jquery to zjquery. Grep for mock_jquery if you want more control.",
|
||||
);
|
||||
|
||||
const filename = Module._resolveFilename(
|
||||
module_path,
|
||||
|
@ -175,13 +176,12 @@ exports.mock_cjs = (module_path, obj) => {
|
|||
false,
|
||||
);
|
||||
|
||||
if (module_mocks.has(filename)) {
|
||||
throw new Error(`You already set up a mock for ${filename}`);
|
||||
}
|
||||
assert.ok(!module_mocks.has(filename), `You already set up a mock for ${filename}`);
|
||||
|
||||
if (filename in require.cache) {
|
||||
throw new Error(`It is too late to mock ${filename}; call this earlier.`);
|
||||
}
|
||||
assert.ok(
|
||||
!(filename in require.cache),
|
||||
`It is too late to mock ${filename}; call this earlier.`,
|
||||
);
|
||||
|
||||
module_mocks.set(filename, obj);
|
||||
return obj;
|
||||
|
@ -199,11 +199,10 @@ exports._start_template_mocking = () => {
|
|||
|
||||
exports._finish_template_mocking = () => {
|
||||
for (const filename of template_mocks.keys()) {
|
||||
if (!used_templates.has(filename)) {
|
||||
throw new Error(
|
||||
`You called mock_template with ${filename} but we never saw it get used.`,
|
||||
);
|
||||
}
|
||||
assert.ok(
|
||||
used_templates.has(filename),
|
||||
`You called mock_template with ${filename} but we never saw it get used.`,
|
||||
);
|
||||
}
|
||||
template_mocks.clear();
|
||||
used_templates.clear();
|
||||
|
@ -222,9 +221,7 @@ exports._mock_template = (fn, exercise_template, f) => {
|
|||
};
|
||||
|
||||
exports.mock_esm = (module_path, obj = {}) => {
|
||||
if (typeof obj !== "object") {
|
||||
throw new TypeError("An ES module must be mocked with an object");
|
||||
}
|
||||
assert.equal(typeof obj, "object", "An ES module must be mocked with an object");
|
||||
return exports.mock_cjs(module_path, {...obj, __esModule: true});
|
||||
};
|
||||
|
||||
|
@ -235,24 +232,19 @@ exports.unmock_module = (module_path) => {
|
|||
false,
|
||||
);
|
||||
|
||||
if (!module_mocks.has(filename)) {
|
||||
throw new Error(`Cannot unmock ${filename}, which was not mocked`);
|
||||
}
|
||||
assert.ok(module_mocks.has(filename), `Cannot unmock ${filename}, which was not mocked`);
|
||||
|
||||
if (!used_module_mocks.has(filename)) {
|
||||
throw new Error(`You asked to mock ${filename} but we never saw it during compilation.`);
|
||||
}
|
||||
assert.ok(
|
||||
used_module_mocks.has(filename),
|
||||
`You asked to mock ${filename} but we never saw it during compilation.`,
|
||||
);
|
||||
|
||||
module_mocks.delete(filename);
|
||||
used_module_mocks.delete(filename);
|
||||
};
|
||||
|
||||
exports.set_global = function (name, val) {
|
||||
if (val === null) {
|
||||
throw new Error(`
|
||||
We try to avoid using null in our codebase.
|
||||
`);
|
||||
}
|
||||
assert.notEqual(val, null, `We try to avoid using null in our codebase.`);
|
||||
|
||||
if (!(name in old_globals)) {
|
||||
if (!(name in global)) {
|
||||
|
@ -265,14 +257,16 @@ exports.set_global = function (name, val) {
|
|||
};
|
||||
|
||||
exports.zrequire = function (short_fn) {
|
||||
if (short_fn === "templates") {
|
||||
throw new Error(`
|
||||
assert.notEqual(
|
||||
short_fn,
|
||||
"templates",
|
||||
`
|
||||
There is no need to zrequire templates.js.
|
||||
|
||||
The test runner automatically registers the
|
||||
Handlebar extensions.
|
||||
`);
|
||||
}
|
||||
`,
|
||||
);
|
||||
|
||||
return require(`../../static/js/${short_fn}`);
|
||||
};
|
||||
|
@ -281,6 +275,7 @@ const staticPath = path.resolve(__dirname, "../../static") + path.sep;
|
|||
|
||||
exports.complain_about_unused_mocks = function () {
|
||||
for (const filename of module_mocks.keys()) {
|
||||
/* istanbul ignore if */
|
||||
if (!used_module_mocks.has(filename)) {
|
||||
console.error(`You asked to mock ${filename} but we never saw it during compilation.`);
|
||||
}
|
||||
|
@ -298,9 +293,7 @@ exports.finish = function () {
|
|||
*/
|
||||
jquery_function = undefined;
|
||||
|
||||
if (actual_load === undefined) {
|
||||
throw new Error("namespace.finish was called without namespace.start.");
|
||||
}
|
||||
assert.notEqual(actual_load, undefined, "namespace.finish was called without namespace.start.");
|
||||
Module._load = actual_load;
|
||||
actual_load = undefined;
|
||||
|
||||
|
@ -321,11 +314,10 @@ exports.finish = function () {
|
|||
};
|
||||
|
||||
exports.with_field = function (obj, field, val, f) {
|
||||
if ("__esModule" in obj && "__Rewire__" in obj) {
|
||||
throw new TypeError(
|
||||
"Cannot mutate an ES module from outside. Consider exporting a test helper function from it instead.",
|
||||
);
|
||||
}
|
||||
assert.ok(
|
||||
!("__esModule" in obj && "__Rewire__" in obj),
|
||||
"Cannot mutate an ES module from outside. Consider exporting a test helper function from it instead.",
|
||||
);
|
||||
|
||||
const had_val = Object.hasOwn(obj, field);
|
||||
const old_val = obj[field];
|
||||
|
@ -350,9 +342,11 @@ exports.with_field_rewire = function (obj, field, val, f) {
|
|||
// https://github.com/rosswarren/babel-plugin-rewire-ts/issues/15
|
||||
const old_val = field in obj ? obj[field] : obj.__GetDependency__(field);
|
||||
|
||||
if (typeof old_val === "function") {
|
||||
throw new TypeError("Please try to avoid mocking here, or use override_rewire.");
|
||||
}
|
||||
assert.notEqual(
|
||||
typeof old_val,
|
||||
"function",
|
||||
"Please try to avoid mocking here, or use override_rewire.",
|
||||
);
|
||||
|
||||
try {
|
||||
obj.__Rewire__(field, val);
|
||||
|
@ -369,14 +363,16 @@ exports.with_function_call_disallowed_rewire = function (obj, field, f) {
|
|||
// https://github.com/rosswarren/babel-plugin-rewire-ts/issues/15
|
||||
const old_val = field in obj ? obj[field] : obj.__GetDependency__(field);
|
||||
|
||||
if (typeof old_val !== "function") {
|
||||
throw new TypeError(`Expected a function for ${field}`);
|
||||
}
|
||||
assert.equal(typeof old_val, "function", `Expected a function for ${field}`);
|
||||
|
||||
try {
|
||||
obj.__Rewire__(field, () => {
|
||||
throw new Error(`unexpected call to ${field}`);
|
||||
});
|
||||
obj.__Rewire__(
|
||||
field,
|
||||
/* istanbul ignore next */
|
||||
() => {
|
||||
throw new Error(`unexpected call to ${field}`);
|
||||
},
|
||||
);
|
||||
return f();
|
||||
} finally {
|
||||
obj.__Rewire__(field, old_val);
|
||||
|
@ -397,28 +393,29 @@ exports.with_overrides = function (test_function) {
|
|||
// step. Generally our code calls `run_test`, which wraps
|
||||
// `with_overrides`.
|
||||
|
||||
if ("__esModule" in obj && "__Rewire__" in obj) {
|
||||
throw new TypeError(
|
||||
"Cannot mutate an ES module from outside. Consider exporting a test helper function from it instead.",
|
||||
);
|
||||
}
|
||||
assert.ok(
|
||||
!("__esModule" in obj && "__Rewire__" in obj),
|
||||
"Cannot mutate an ES module from outside. Consider exporting a test helper function from it instead.",
|
||||
);
|
||||
|
||||
if (typeof f !== "function") {
|
||||
throw new TypeError(
|
||||
"You can only override with a function. Use with_field for non-functions.",
|
||||
);
|
||||
}
|
||||
assert.equal(
|
||||
typeof f,
|
||||
"function",
|
||||
"You can only override with a function. Use with_field for non-functions.",
|
||||
);
|
||||
|
||||
if (typeof obj !== "object" && typeof obj !== "function") {
|
||||
throw new TypeError(`We cannot override a function for ${typeof obj} objects`);
|
||||
}
|
||||
assert.ok(
|
||||
typeof obj === "object" || typeof obj === "function",
|
||||
`We cannot override a function for ${typeof obj} objects`,
|
||||
);
|
||||
|
||||
if (obj[func_name] !== undefined && typeof obj[func_name] !== "function") {
|
||||
throw new TypeError(`
|
||||
assert.ok(
|
||||
obj[func_name] === undefined || typeof obj[func_name] === "function",
|
||||
`
|
||||
You are overriding a non-function with a function.
|
||||
This is almost certainly an error.
|
||||
`);
|
||||
}
|
||||
`,
|
||||
);
|
||||
|
||||
if (!unused_funcs.has(obj)) {
|
||||
unused_funcs.set(obj, new Map());
|
||||
|
@ -449,22 +446,24 @@ exports.with_overrides = function (test_function) {
|
|||
// as exporting a helper function for tests from the module
|
||||
// containing the function you need to mock.
|
||||
|
||||
if (typeof f !== "function") {
|
||||
throw new TypeError(
|
||||
"You can only override with a function. Use with_field for non-functions.",
|
||||
);
|
||||
}
|
||||
assert.equal(
|
||||
typeof f,
|
||||
"function",
|
||||
"You can only override with a function. Use with_field for non-functions.",
|
||||
);
|
||||
|
||||
if (typeof obj !== "object" && typeof obj !== "function") {
|
||||
throw new TypeError(`We cannot override a function for ${typeof obj} objects`);
|
||||
}
|
||||
assert.ok(
|
||||
typeof obj === "object" || typeof obj === "function",
|
||||
`We cannot override a function for ${typeof obj} objects`,
|
||||
);
|
||||
|
||||
if (obj[func_name] !== undefined && typeof obj[func_name] !== "function") {
|
||||
throw new TypeError(`
|
||||
assert.ok(
|
||||
obj[func_name] === undefined || typeof obj[func_name] === "function",
|
||||
`
|
||||
You are overriding a non-function with a function.
|
||||
This is almost certainly an error.
|
||||
`);
|
||||
}
|
||||
`,
|
||||
);
|
||||
|
||||
if (!unused_funcs.has(obj)) {
|
||||
unused_funcs.set(obj, new Map());
|
||||
|
@ -497,6 +496,7 @@ exports.with_overrides = function (test_function) {
|
|||
|
||||
for (const module_unused_funcs of unused_funcs.values()) {
|
||||
for (const unused_name of module_unused_funcs.keys()) {
|
||||
/* istanbul ignore next */
|
||||
throw new Error(unused_name + " never got invoked!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ exports.set_verbose = (value) => {
|
|||
exports.run_test = (label, f, opts) => {
|
||||
const {sloppy_$} = opts || {};
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (verbose) {
|
||||
console.info(" test: " + label);
|
||||
}
|
||||
|
@ -34,7 +35,7 @@ exports.run_test = (label, f, opts) => {
|
|||
f({override, override_rewire, mock_template: namespace._mock_template});
|
||||
});
|
||||
namespace._finish_template_mocking();
|
||||
} catch (error) {
|
||||
} catch (error) /* istanbul ignore next */ {
|
||||
console.info("-".repeat(50));
|
||||
console.info(`test failed: ${current_file_name} > ${label}`);
|
||||
console.info();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const {strict: assert} = require("assert");
|
||||
|
||||
function make_zblueslip() {
|
||||
const lib = {};
|
||||
|
||||
|
@ -15,6 +17,7 @@ function make_zblueslip() {
|
|||
const names = Array.from(Object.keys(opts));
|
||||
|
||||
// For fatal messages, we should use assert.throws
|
||||
/* istanbul ignore next */
|
||||
lib.fatal = (msg) => {
|
||||
throw new Error(msg);
|
||||
};
|
||||
|
@ -28,14 +31,13 @@ function make_zblueslip() {
|
|||
lib.test_logs[name] = [];
|
||||
}
|
||||
|
||||
lib.expect = (name, message, count = 1) => {
|
||||
if (opts[name] === undefined) {
|
||||
throw new Error("unexpected arg for expect: " + name);
|
||||
}
|
||||
if (count <= 0 && Number.isInteger(count)) {
|
||||
throw new Error("expected count should be a positive integer");
|
||||
}
|
||||
const obj = {message, count, expected_count: count};
|
||||
lib.expect = (name, message, expected_count = 1) => {
|
||||
assert.notEqual(opts[name], undefined, `unexpected arg for expect: ${name}`);
|
||||
assert.ok(
|
||||
expected_count > 0 && Number.isInteger(expected_count),
|
||||
"expected count should be a positive integer",
|
||||
);
|
||||
const obj = {message, count: 0, expected_count};
|
||||
lib.test_data[name].push(obj);
|
||||
};
|
||||
|
||||
|
@ -52,22 +54,16 @@ function make_zblueslip() {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
lib.test_data[name][i].count -= 1;
|
||||
lib.test_data[name][i].count += 1;
|
||||
}
|
||||
|
||||
for (const obj of lib.test_data[name]) {
|
||||
const message = obj.message;
|
||||
if (obj.count > 0) {
|
||||
throw new Error(
|
||||
`We did not see expected ${obj.expected_count} of '${name}': ${message}`,
|
||||
);
|
||||
} else if (obj.count < 0) {
|
||||
throw new Error(
|
||||
`We saw ${obj.expected_count - obj.count} (expected ${
|
||||
obj.expected_count
|
||||
}) of '${name}': ${message}`,
|
||||
);
|
||||
}
|
||||
assert.equal(
|
||||
obj.count,
|
||||
obj.expected_count,
|
||||
`Expected ${obj.expected_count} of '${name}': ${message}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -95,6 +91,7 @@ function make_zblueslip() {
|
|||
continue;
|
||||
}
|
||||
lib[name] = function (message, more_info, stack) {
|
||||
/* istanbul ignore if */
|
||||
if (typeof message !== "string") {
|
||||
// We may catch exceptions in blueslip, and if
|
||||
// so our stub should include that.
|
||||
|
@ -121,6 +118,7 @@ function make_zblueslip() {
|
|||
|
||||
lib.measure_time = (label, f) => f();
|
||||
|
||||
/* istanbul ignore next */
|
||||
lib.preview_node = (node) => "node:" + node;
|
||||
|
||||
return lib;
|
||||
|
|
|
@ -23,16 +23,15 @@ function verify_selector_for_zulip(selector) {
|
|||
selector.includes(".") ||
|
||||
(selector.includes("[") && selector.indexOf("]") >= selector.indexOf("["));
|
||||
|
||||
if (!is_valid) {
|
||||
assert.ok(
|
||||
is_valid,
|
||||
// Check if selector has only english alphabets and space.
|
||||
// Then, the user is probably trying to use a tag as a selector
|
||||
// like $('div a').
|
||||
if (/^[ A-Za-z]+$/.test(selector)) {
|
||||
throw new Error("Selector too broad! Use id, class or attributes of target instead.");
|
||||
} else {
|
||||
throw new Error("Invalid selector: " + selector + " Use $.create() maybe?");
|
||||
}
|
||||
}
|
||||
/^[ A-Za-z]+$/.test(selector)
|
||||
? "Selector too broad! Use id, class or attributes of target instead."
|
||||
: `Invalid selector: ${selector}. Use $.create() maybe?`,
|
||||
);
|
||||
}
|
||||
|
||||
function make_zjquery() {
|
||||
|
@ -56,15 +55,16 @@ function make_zjquery() {
|
|||
// Handle the special case of equality checks, which
|
||||
// we can infer by assert.equal trying to access the
|
||||
// "stack" key.
|
||||
if (key === "stack") {
|
||||
const error =
|
||||
"\nInstead of doing equality checks on a full object, " +
|
||||
'do `assert_equal($foo.selector, ".some_class")\n';
|
||||
throw new Error(error);
|
||||
}
|
||||
assert.notEqual(
|
||||
key,
|
||||
"stack",
|
||||
"\nInstead of doing equality checks on a full object, " +
|
||||
'do `assert.equal($foo.selector, ".some_class")\n',
|
||||
);
|
||||
|
||||
const val = target[key];
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (val === undefined && typeof key !== "symbol" && key !== "inspect") {
|
||||
// For undefined values, we'll throw errors to devs saying
|
||||
// they need to create stubs. We ignore certain keys that
|
||||
|
@ -85,16 +85,17 @@ function make_zjquery() {
|
|||
|
||||
const zjquery = function (arg, arg2) {
|
||||
if (typeof arg === "function") {
|
||||
if (initialize_function) {
|
||||
throw new Error(`
|
||||
assert.ok(
|
||||
!initialize_function,
|
||||
`
|
||||
We are trying to avoid the $(...) mechanism
|
||||
for initializing modules in our codebase,
|
||||
and the code that you are compiling/running
|
||||
has tried to do this twice. Please either
|
||||
clean up the real code or reduce the scope
|
||||
of what you are testing in this test module.
|
||||
`);
|
||||
}
|
||||
`,
|
||||
);
|
||||
initialize_function = arg;
|
||||
return undefined;
|
||||
}
|
||||
|
@ -116,12 +117,15 @@ function make_zjquery() {
|
|||
return arg.to_$();
|
||||
}
|
||||
|
||||
if (arg2 !== undefined) {
|
||||
throw new Error("We only use one-argument variations of $(...) in Zulip code.");
|
||||
}
|
||||
assert.equal(
|
||||
arg2,
|
||||
undefined,
|
||||
"We only use one-argument variations of $(...) in Zulip code.",
|
||||
);
|
||||
|
||||
const selector = arg;
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (typeof selector !== "string") {
|
||||
console.info(arg);
|
||||
throw new Error("zjquery does not know how to wrap this object yet");
|
||||
|
@ -152,10 +156,7 @@ function make_zjquery() {
|
|||
return $elem;
|
||||
};
|
||||
|
||||
zjquery.trim = function (s) {
|
||||
return s;
|
||||
};
|
||||
|
||||
/* istanbul ignore next */
|
||||
zjquery.state = function () {
|
||||
// useful for debugging
|
||||
let res = Array.from(elems.values(), ($v) => $v.debug());
|
||||
|
@ -169,6 +170,7 @@ function make_zjquery() {
|
|||
|
||||
zjquery.Event = FakeEvent;
|
||||
|
||||
/* istanbul ignore next */
|
||||
fn.popover = () => {
|
||||
throw new Error(`
|
||||
Do not try to test $.fn.popover code unless
|
||||
|
@ -186,6 +188,7 @@ function make_zjquery() {
|
|||
return true;
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
throw new Error(`
|
||||
Please don't use node tests to test code
|
||||
that extends $.fn unless you really know
|
||||
|
@ -209,6 +212,7 @@ function make_zjquery() {
|
|||
};
|
||||
|
||||
zjquery.validator = {
|
||||
/* istanbul ignore next */
|
||||
addMethod() {
|
||||
throw new Error("You must create your own $.validator.addMethod stub.");
|
||||
},
|
||||
|
@ -229,6 +233,7 @@ const $ = new Proxy(make_zjquery(), {
|
|||
return true;
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
throw new Error(`
|
||||
Please don't modify $.${prop} if you are using zjquery.
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ function FakeElement(selector, opts) {
|
|||
delay() {
|
||||
return $self;
|
||||
},
|
||||
/* istanbul ignore next */
|
||||
debug() {
|
||||
return {
|
||||
value,
|
||||
|
@ -61,9 +62,6 @@ function FakeElement(selector, opts) {
|
|||
}
|
||||
return $self;
|
||||
},
|
||||
eq() {
|
||||
return $self;
|
||||
},
|
||||
expectOne() {
|
||||
// silently do nothing
|
||||
return $self;
|
||||
|
@ -80,6 +78,7 @@ function FakeElement(selector, opts) {
|
|||
// if ($.find().length) { //success }
|
||||
return [];
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
throw new Error(`
|
||||
We need you to simulate the results of $(...).find(...)
|
||||
by using set_find_results. You want something like this:
|
||||
|
@ -100,9 +99,7 @@ function FakeElement(selector, opts) {
|
|||
return classes.has(class_name);
|
||||
},
|
||||
height() {
|
||||
if (height === undefined) {
|
||||
throw new Error(`Please call $("${selector}").set_height`);
|
||||
}
|
||||
assert.notEqual(height, undefined, `Please call $("${selector}").set_height`);
|
||||
return height;
|
||||
},
|
||||
hide() {
|
||||
|
@ -117,13 +114,15 @@ function FakeElement(selector, opts) {
|
|||
return html;
|
||||
},
|
||||
is(arg) {
|
||||
if (arg === ":visible") {
|
||||
return shown;
|
||||
switch (arg) {
|
||||
case ":visible":
|
||||
return shown;
|
||||
case ":focus":
|
||||
return $self.is_focused();
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error("zjquery does not support this is() call");
|
||||
}
|
||||
if (arg === ":focus") {
|
||||
return $self.is_focused();
|
||||
}
|
||||
return $self;
|
||||
},
|
||||
is_focused() {
|
||||
// is_focused is not a jQuery thing; this is
|
||||
|
@ -144,6 +143,7 @@ function FakeElement(selector, opts) {
|
|||
event_store.on(...args);
|
||||
return $self;
|
||||
},
|
||||
/* istanbul ignore next */
|
||||
one(...args) {
|
||||
event_store.one(...args);
|
||||
return $self;
|
||||
|
@ -181,6 +181,7 @@ function FakeElement(selector, opts) {
|
|||
}
|
||||
return $self;
|
||||
},
|
||||
/* istanbul ignore next */
|
||||
remove() {
|
||||
throw new Error(`
|
||||
We don't support remove in zjquery.
|
||||
|
@ -192,21 +193,12 @@ function FakeElement(selector, opts) {
|
|||
`);
|
||||
},
|
||||
removeData: noop,
|
||||
replaceWith() {
|
||||
return $self;
|
||||
},
|
||||
scrollTop() {
|
||||
return $self;
|
||||
},
|
||||
serializeArray() {
|
||||
return $self;
|
||||
},
|
||||
set_find_results(find_selector, $jquery_object) {
|
||||
if ($jquery_object === undefined) {
|
||||
throw new Error(
|
||||
"Please make the 'find result' be something like $.create('unused')",
|
||||
);
|
||||
}
|
||||
assert.notEqual(
|
||||
$jquery_object,
|
||||
undefined,
|
||||
"Please make the 'find result' be something like $.create('unused')",
|
||||
);
|
||||
find_results.set(find_selector, $jquery_object);
|
||||
},
|
||||
set_height(fake_height) {
|
||||
|
@ -222,9 +214,6 @@ function FakeElement(selector, opts) {
|
|||
shown = true;
|
||||
return $self;
|
||||
},
|
||||
slice() {
|
||||
return $self;
|
||||
},
|
||||
stop() {
|
||||
return $self;
|
||||
},
|
||||
|
@ -242,9 +231,6 @@ function FakeElement(selector, opts) {
|
|||
shown = show;
|
||||
return $self;
|
||||
},
|
||||
tooltip() {
|
||||
return $self;
|
||||
},
|
||||
trigger(ev) {
|
||||
event_store.trigger($self, ev);
|
||||
return $self;
|
||||
|
@ -314,9 +300,7 @@ function make_event_store(selector) {
|
|||
|
||||
if (child_selector === undefined) {
|
||||
handler = on_functions.get(name);
|
||||
if (!handler) {
|
||||
throw new Error("no " + name + " handler for " + selector);
|
||||
}
|
||||
assert.ok(handler, `no ${name} handler for ${selector}`);
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
@ -325,9 +309,7 @@ function make_event_store(selector) {
|
|||
handler = child_on.get(name);
|
||||
}
|
||||
|
||||
if (!handler) {
|
||||
throw new Error("no " + name + " handler for " + selector + " " + child_selector);
|
||||
}
|
||||
assert.ok(handler, `no ${name} handler for ${selector} ${child_selector}`);
|
||||
|
||||
return handler;
|
||||
},
|
||||
|
@ -342,6 +324,7 @@ function make_event_store(selector) {
|
|||
// .off in code that we test: $(...).off('click', child_sel);
|
||||
//
|
||||
// So we don't support this for now.
|
||||
/* istanbul ignore next */
|
||||
throw new Error("zjquery does not support this call sequence");
|
||||
},
|
||||
|
||||
|
@ -351,6 +334,7 @@ function make_event_store(selector) {
|
|||
// (event_name, sel, handler)
|
||||
if (args.length === 1) {
|
||||
const [handler] = args;
|
||||
/* istanbul ignore if */
|
||||
if (on_functions.has(event_name)) {
|
||||
console.info("\nEither the app or the test can be at fault here..");
|
||||
console.info("(sometimes you just want to call $.clear_all_elements();)\n");
|
||||
|
@ -361,9 +345,7 @@ function make_event_store(selector) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (args.length !== 2) {
|
||||
throw new Error("wrong number of arguments passed in");
|
||||
}
|
||||
assert.equal(args.length, 2, "wrong number of arguments passed in");
|
||||
|
||||
const [sel, handler] = args;
|
||||
assert.equal(typeof sel, "string", "String selectors expected here.");
|
||||
|
@ -375,13 +357,15 @@ function make_event_store(selector) {
|
|||
|
||||
const child_on = child_on_functions.get(sel);
|
||||
|
||||
if (child_on.has(event_name)) {
|
||||
throw new Error("dup " + event_name + " handler for " + selector + " " + sel);
|
||||
}
|
||||
assert.ok(
|
||||
!child_on.has(event_name),
|
||||
`dup ${event_name} handler for ${selector} ${sel}`,
|
||||
);
|
||||
|
||||
child_on.set(event_name, handler);
|
||||
},
|
||||
|
||||
/* istanbul ignore next */
|
||||
one(event_name, handler) {
|
||||
self.on(event_name, function (ev) {
|
||||
self.off(event_name);
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
|
||||
class FakeEvent {
|
||||
constructor(type, props) {
|
||||
if (!(this instanceof FakeEvent)) {
|
||||
return new FakeEvent(type, props);
|
||||
}
|
||||
this.type = type;
|
||||
Object.assign(this, props);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ def make_set(files: List[str]) -> Set[str]:
|
|||
# We do not yet require 100% line coverage for these files:
|
||||
EXEMPT_FILES = make_set(
|
||||
[
|
||||
"frontend_tests/node_tests/event_status.js",
|
||||
"frontend_tests/zjsunit/mdiff.js",
|
||||
"static/js/about_zulip.js",
|
||||
"static/js/add_subscribers_pill.js",
|
||||
"static/js/admin.js",
|
||||
|
@ -372,14 +374,16 @@ def read_coverage() -> Any:
|
|||
|
||||
|
||||
def enforce_proper_coverage(coverage_json: Any) -> bool:
|
||||
all_js_files = set(
|
||||
glob.glob("static/js/*.js")
|
||||
+ glob.glob("static/js/*.ts")
|
||||
+ glob.glob("static/shared/js/*.js")
|
||||
+ glob.glob("static/shared/js/*.ts")
|
||||
+ glob.glob("static/js/billing/*.js"),
|
||||
)
|
||||
enforce_fully_covered = all_js_files - EXEMPT_FILES
|
||||
all_js_files = {
|
||||
*glob.glob("frontend_tests/node_tests/*.js"),
|
||||
*glob.glob("frontend_tests/zjsunit/*.js"),
|
||||
*glob.glob("static/js/*.js"),
|
||||
*glob.glob("static/js/*.ts"),
|
||||
*glob.glob("static/shared/js/*.js"),
|
||||
*glob.glob("static/shared/js/*.ts"),
|
||||
*glob.glob("static/js/billing/*.js"),
|
||||
}
|
||||
enforce_fully_covered = sorted(all_js_files - EXEMPT_FILES)
|
||||
|
||||
coverage_lost = False
|
||||
for relative_path in enforce_fully_covered:
|
||||
|
|
Loading…
Reference in New Issue