zjquery: Add $.create() method.

This commit add $.create(), which allows you to create a
jQuery object that just has a name to identify it, as opposed
to some selector or HTML fragment.  It's useful for things that
are really used as stubs.

This also fixes a bunch of the existing tests to use $.create().

Before this fix, you could actually just do $('some-stub'), but
now we enforce that the input to $() looks like a valid selector
or HTML fragment, and we make some exceptions for things like
window-stub and document-stub.
This commit is contained in:
Steve Howell
2017-07-08 09:16:19 -04:00
parent 90777fd1fa
commit 7376934a77
11 changed files with 147 additions and 104 deletions

View File

@@ -38,7 +38,7 @@ var presence = global.presence;
set_global('resize', {
resize_page_components: function () {},
});
set_global('window', {});
set_global('window', 'window-stub');
var me = {
email: 'me@zulip.com',
@@ -286,8 +286,8 @@ presence.presence_info[norbert.user_id] = { status: activity.ACTIVE };
}());
(function test_PM_update_dom_counts() {
var value = $('alice-value');
var count = $('alice-count');
var value = $.create('alice-value');
var count = $.create('alice-count');
var pm_key = alice.user_id.toString();
var li = $("li.user_sidebar_entry[data-user-id='" + pm_key + "']");
count.set_find_results('.value', value);
@@ -310,8 +310,8 @@ presence.presence_info[norbert.user_id] = { status: activity.ACTIVE };
}());
(function test_group_update_dom_counts() {
var value = $('alice-fred-value');
var count = $('alice-fred-count');
var value = $.create('alice-fred-value');
var count = $.create('alice-fred-count');
var pm_key = alice.user_id.toString() + "," + fred.user_id.toString();
var li_selector = "li.group-pms-sidebar-entry[data-user-ids='" + pm_key + "']";
var li = $(li_selector);
@@ -413,7 +413,7 @@ presence.presence_info[jill.user_id] = { status: activity.ACTIVE };
}());
(function test_insert_one_user_into_empty_list() {
var alice_li = $('alice-li');
var alice_li = $.create('alice list item');
// These selectors are here to avoid some short-circuit logic.
$('#user_presences').set_find_results('[data-user-id="1"]', alice_li);
@@ -434,7 +434,7 @@ presence.presence_info[jill.user_id] = { status: activity.ACTIVE };
}());
(function test_insert_fred_after_alice() {
var fred_li = $('fred-li');
var fred_li = $.create('fred list item');
// These selectors are here to avoid some short-circuit logic.
$('#user_presences').set_find_results('[data-user-id="2"]', fred_li);
@@ -444,7 +444,7 @@ presence.presence_info[jill.user_id] = { status: activity.ACTIVE };
appended_html = html;
};
$('fake-dom-for-alice').attr = function (attr_name) {
$('<fake html for alice>').attr = function (attr_name) {
assert.equal(attr_name, 'data-user-id');
return alice.user_id;
};
@@ -452,7 +452,7 @@ presence.presence_info[jill.user_id] = { status: activity.ACTIVE };
$.stub_selector('#user_presences li', {
toArray: function () {
return [
'fake-dom-for-alice',
'<fake html for alice>',
];
},
});
@@ -463,12 +463,12 @@ presence.presence_info[jill.user_id] = { status: activity.ACTIVE };
}());
(function test_insert_fred_before_jill() {
var fred_li = $('fred-li');
var fred_li = $.create('fred-li');
// These selectors are here to avoid some short-circuit logic.
$('#user_presences').set_find_results('[data-user-id="2"]', fred_li);
$('fake-dom-for-jill').attr = function (attr_name) {
$('<fake-dom-for-jill').attr = function (attr_name) {
assert.equal(attr_name, 'data-user-id');
return jill.user_id;
};
@@ -476,13 +476,13 @@ presence.presence_info[jill.user_id] = { status: activity.ACTIVE };
$.stub_selector('#user_presences li', {
toArray: function () {
return [
'fake-dom-for-jill',
'<fake-dom-for-jill',
];
},
});
var before_html;
$('fake-dom-for-jill').before = function (html) {
$('<fake-dom-for-jill').before = function (html) {
before_html = html;
};
activity.insert_user_into_list(fred.user_id);
@@ -571,8 +571,8 @@ $('.user-list-filter').is = function (sel) {
}());
(function test_update_huddles_and_redraw() {
var value = $('alice-fred-value');
var count = $('alice-fred-count');
var value = $.create('alice-fred-value');
var count = $.create('alice-fred-count');
var pm_key = alice.user_id.toString() + "," + fred.user_id.toString();
var li_selector = "li.group-pms-sidebar-entry[data-user-ids='" + pm_key + "']";
var li = $(li_selector);
@@ -607,7 +607,7 @@ $('.user-list-filter').is = function (sel) {
timestamp: server_time,
},
};
var alice_li = $('alice-li');
var alice_li = $.create('alice-li');
$('#user_presences').set_find_results('[data-user-id="1"]', alice_li);

View File

@@ -684,7 +684,7 @@ function test_raw_file_drop(raw_drop_func) {
});
$("#compose #attach_files").addClass("notdisplayed");
global.document = 'fake-document-object';
global.document = 'document-stub';
global.csrf_token = 'fake-csrf-token';
var filedrop_in_compose_checked = false;

View File

@@ -9,7 +9,7 @@ var with_overrides = global.with_overrides;
var people = global.people;
set_global('$', global.make_zjquery());
set_global('document', '');
set_global('document', 'document-stub');
set_global('alert_words', {
process_message: noop,

View File

@@ -143,8 +143,8 @@ global.people.initialize_current_user(me.user_id);
};
var private_li = $("#global_filters > li[data-name='private']");
var alice_li = $('alice-li-stub');
var bob_li = $('bob-li-stub');
var alice_li = $.create('alice-li-stub');
var bob_li = $.create('bob-li-stub');
private_li.set_find_results("li[data-user-ids-string='101']", alice_li);
private_li.set_find_results("li[data-user-ids-string='102']", bob_li);
@@ -234,15 +234,15 @@ global.people.initialize_current_user(me.user_id);
}());
(function test_update_dom_with_unread_counts() {
var total_value = $('total-value-stub');
var total_count = $('total-count-stub');
var total_value = $.create('total-value-stub');
var total_count = $.create('total-count-stub');
var private_li = $("#global_filters > li[data-name='private']");
private_li.set_find_results('.count', total_count);
total_count.set_find_results('.value', total_value);
var child_value = $('child-value-stub');
var child_count = $('child-count-stub');
var child_li = $('child-li-stub');
var child_value = $.create('child-value-stub');
var child_count = $.create('child-count-stub');
var child_li = $.create('child-li-stub');
private_li.set_find_results("li[data-user-ids-string='101,102']", child_li);
child_li.set_find_results('.private_message_count', child_count);
child_count.set_find_results('.value', child_value);

View File

@@ -143,8 +143,8 @@ set_global('message_store', {
}());
(function test_set_reaction_count() {
var count_element = $('count-stub');
var reaction_element = $('reaction-stub');
var count_element = $.create('count-stub');
var reaction_element = $.create('reaction-stub');
reaction_element.set_find_results('.message_reaction_count', count_element);
@@ -154,9 +154,9 @@ set_global('message_store', {
}());
(function test_get_reaction_section() {
var message_table = $('.message_table');
var message_row = $('some-message-row');
var message_reactions = $('our-reactions-section');
var message_table = $.create('.message_table');
var message_row = $.create('some-message-row');
var message_reactions = $.create('our-reactions-section');
message_table.set_find_results("[zid='555']", message_row);
message_row.set_find_results('.message_reactions', message_reactions);
@@ -176,7 +176,7 @@ set_global('message_store', {
},
};
var message_reactions = $('our-reactions');
var message_reactions = $.create('our-reactions');
reactions.get_reaction_section = function (message_id) {
assert.equal(message_id, 1001);
@@ -196,11 +196,11 @@ set_global('message_store', {
assert(!data.is_realm_emoji);
assert.equal(data.message_id, 1001);
assert.equal(data.title, 'You (click to remove) reacted with :8ball:');
return 'new-reaction-html-stub';
return '<new reaction html>';
};
var insert_called;
$('new-reaction-html-stub').insertBefore = function (element) {
$('<new reaction html>').insertBefore = function (element) {
assert.equal(element, 'reaction-button-stub');
insert_called = true;
};
@@ -220,8 +220,8 @@ set_global('message_store', {
},
};
var count_element = $('count-element');
var reaction_element = $('reaction-element');
var count_element = $.create('count-element');
var reaction_element = $.create('reaction-element');
reaction_element.set_find_results('.message_reaction_count', count_element);
var title_set;
@@ -287,7 +287,7 @@ set_global('message_store', {
assert.equal(data.class, 'message_reaction');
assert(data.is_realm_emoji);
template_called = true;
return 'new-reaction-html-stub';
return '<new reaction html>';
};
message_reactions.find = function (selector) {

View File

@@ -10,7 +10,7 @@ add_dependencies({
});
set_global('$', global.make_zjquery());
set_global('document', {});
set_global('document', 'document-stub');
var settings_bots = require("js/settings_bots.js");

View File

@@ -71,10 +71,10 @@ set_global('ui_report', {
function simulate_auth_methods() {
$('#admin_auth_methods_table').set_find_results(
'tr.method_row',
$('admin-tr-stub')
$.create('admin-tr-stub')
);
var controls = $('auth-methods-controls-stub');
var controls = $.create('auth-methods-controls-stub');
$(".organization-box [data-name='auth-methods']").set_find_results(
'input, button, select, checked',
@@ -86,7 +86,7 @@ function simulate_auth_methods() {
assert.equal(val, true);
};
var non_editables = $('auth-methods-not-edit-stub');
var non_editables = $.create('auth-methods-not-edit-stub');
$('.organization-box').set_find_results(
'.settings-section:not(.can-edit)',
non_editables
@@ -98,7 +98,7 @@ function simulate_auth_methods() {
function simulate_realm_domains_table() {
$('#realm_domains_table tbody').set_find_results(
'tr',
$('realm-tr-stub')
$.create('realm-tr-stub')
);
var appended;
@@ -113,7 +113,7 @@ function simulate_realm_domains_table() {
}
function test_realms_domain_modal(add_realm_domain) {
var info = $('domains-info-stub');
var info = $.create('domains-info-stub');
$('#realm_domains_modal').set_find_results(
'.realm_domains_info',
@@ -122,12 +122,12 @@ function test_realms_domain_modal(add_realm_domain) {
$('#add-realm-domain-widget').set_find_results(
'.new-realm-domain',
$('new-realm-domain-stub')
$.create('new-realm-domain-stub')
);
$('#add-realm-domain-widget').set_find_results(
'.new-realm-domain-allow-subdomains',
$('new-realm-domain-allow-subdomains-stub')
$.create('new-realm-domain-allow-subdomains-stub')
);
var posted;
@@ -323,7 +323,7 @@ function test_upload_realm_icon(upload_realm_icon) {
}
function test_change_message_editing(change_message_editing) {
var parent_elem = $('editing-parent-stub');
var parent_elem = $.create('editing-parent-stub');
$('#id_realm_message_content_edit_limit_minutes_label').set_parent(parent_elem);
@@ -337,7 +337,7 @@ function test_change_message_editing(change_message_editing) {
}
function test_change_invite_required(change_invite_required) {
var parent_elem = $('invite-parent-stub');
var parent_elem = $.create('invite-parent-stub');
$('#id_realm_invite_by_admins_only_label').set_parent(parent_elem);
@@ -380,7 +380,7 @@ function test_change_allow_subdomains(change_allow_subdomains) {
stopPropagation: noop,
};
var info = $('realm-domain-info-stub');
var info = $.create('realm-domain-info-stub');
var domain = 'example.com';
var allow = true;
@@ -398,14 +398,18 @@ function test_change_allow_subdomains(change_allow_subdomains) {
info
);
$('domain-stub').text(domain);
$('elem-stub').parents = function () {
return $('parents-stub');
};
$('parents-stub').set_find_results('.domain', $('domain-stub'));
$('elem-stub').prop('checked', allow);
var domain_obj = $.create('domain object');
domain_obj.text(domain);
change_allow_subdomains.apply('elem-stub', [ev]);
var elem_obj = $('<elem html>');
var parents_obj = $.create('parents object');
elem_obj.set_parents_result('tr', parents_obj);
parents_obj.set_find_results('.domain', domain_obj);
elem_obj.prop('checked', allow);
change_allow_subdomains.apply('<elem html>', [ev]);
success_callback();
assert.equal(info.text(),
@@ -421,8 +425,8 @@ function test_change_allow_subdomains(change_allow_subdomains) {
assert.equal(info.text(), 'no can do');
allow = false;
$('elem-stub').prop('checked', allow);
change_allow_subdomains.apply('elem-stub', [ev]);
elem_obj.prop('checked', allow);
change_allow_subdomains.apply('<elem html>', [ev]);
success_callback();
assert.equal(info.text(),
'translated: Update successful: Subdomains no longer allowed for example.com');

View File

@@ -1,7 +1,7 @@
var assert = require('assert');
var noop = function () {};
set_global('$', global.make_zjquery());
set_global('document', '');
set_global('document', 'document-stub');
set_global('colorspace', {
sRGB_to_linear: noop,

View File

@@ -48,16 +48,19 @@ set_global('topic_list', {});
};
(function create_devel_sidebar_row() {
var devel_value = $('devel-value');
var devel_count = $('devel-count');
$('devel-stub-html').set_find_results('.count', devel_count);
$('devel-count').set_find_results('.value', devel_value);
devel_count.set_parent($('devel-stub-html'));
var devel_value = $.create('devel-value');
var devel_count = $.create('devel-count');
var sidebar_row = $('<devel sidebar row>');
sidebar_row.set_find_results('.count', devel_count);
devel_count.set_find_results('.value', devel_value);
devel_count.set_parent(sidebar_row);
global.templates.render = function (template_name, data) {
assert.equal(template_name, 'stream_sidebar_row');
assert.equal(data.uri, '#narrow/stream/devel');
return 'devel-stub-html';
return '<devel sidebar row>';
};
stream_list.create_sidebar_row(devel);
@@ -65,16 +68,18 @@ set_global('topic_list', {});
}());
(function create_social_sidebar_row() {
var social_value = $('social-value');
var social_count = $('social-count');
$('social-stub-html').set_find_results('.count', social_count);
$('social-count').set_find_results('.value', social_value);
social_count.set_parent($('social-stub-html'));
var social_value = $.create('social-value');
var social_count = $.create('social-count');
var sidebar_row = $('<social sidebar row>');
sidebar_row.set_find_results('.count', social_count);
social_count.set_find_results('.value', social_value);
social_count.set_parent(sidebar_row);
global.templates.render = function (template_name, data) {
assert.equal(template_name, 'stream_sidebar_row');
assert.equal(data.uri, '#narrow/stream/social');
return 'social-stub-html';
return '<social sidebar row>';
};
stream_list.create_sidebar_row(social);
@@ -89,8 +94,8 @@ set_global('topic_list', {});
}
set_getter($('<hr class="stream-split">'), 'split');
set_getter($('devel-stub-html'), 'devel-sidebar');
set_getter($('social-stub-html'), 'social-sidebar');
set_getter($('<devel sidebar row>'), 'devel-sidebar');
set_getter($('<social sidebar row>'), 'social-sidebar');
var appended_elems;
$('#stream_filters').append = function (elems) {
@@ -107,10 +112,10 @@ set_global('topic_list', {});
assert.deepEqual(appended_elems, expected_elems);
var social_li = $('social-stub-html');
var social_li = $('<social sidebar row>');
var stream_id = social.stream_id;
var privacy_elem = $('privacy-stub');
var privacy_elem = $.create('privacy-stub');
social_li.set_find_results('.stream-privacy', privacy_elem);
social.invite_only = true;
@@ -156,8 +161,8 @@ function initialize_stream_data() {
var row = {
update_whether_active: function () {},
get_li: function () {
var selector = 'stub-' + sub.name;
return $(selector);
var html = '<' + sub.name + ' sidebar row html>';
return $(html);
},
};
stream_list.stream_sidebar.set_row(sub.stream_id, row);
@@ -249,7 +254,7 @@ function initialize_stream_data() {
perfectScrollbar: function () { scrollbar_updated = true; },
});
assert(!$('stub-devel').hasClass('active-filter'));
assert(!$('<devel sidebar row html>').hasClass('active-filter'));
stream_list.initialize();
@@ -264,7 +269,7 @@ function initialize_stream_data() {
{operator: 'stream', operand: 'devel'},
]);
activate_filter(filter);
assert($('stub-devel').hasClass('active-filter'));
assert($('<devel sidebar row html>').hasClass('active-filter'));
assert(scrollbar_updated); // Make sure we are updating perfectScrollbar.
scrollbar_updated = false;
@@ -274,7 +279,7 @@ function initialize_stream_data() {
]);
activate_filter(filter);
assert(!$("ul.filters li").hasClass('active-filter'));
assert(!$('stub-cars').hasClass('active-filter')); // false because of topic
assert(!$('<cars sidebar row html>').hasClass('active-filter')); // false because of topic
assert(scrollbar_updated); // Make sure we are updating perfectScrollbar.
assert(!pm_expanded);
@@ -301,7 +306,7 @@ function initialize_stream_data() {
]);
activate_filter(filter);
assert(!$("ul.filters li").hasClass('active-filter'));
assert($('stub-cars').hasClass('active-filter'));
assert($('<cars sidebar row html>').hasClass('active-filter'));
}());
(function test_sort_streams() {
@@ -325,14 +330,14 @@ function initialize_stream_data() {
stream_list.build_stream_list();
var expected_elems = [
'stub-devel',
'stub-Rome',
'stub-test',
'<devel sidebar row html>',
'<Rome sidebar row html>',
'<test sidebar row html>',
'split',
'stub-announce',
'stub-Denmark',
'<announce sidebar row html>',
'<Denmark sidebar row html>',
'split',
'stub-cars',
'<cars sidebar row html>',
];
assert.deepEqual(appended_elems, expected_elems);
@@ -358,8 +363,7 @@ function initialize_stream_data() {
}());
(function test_update_count_in_dom() {
function make_elem(elem_selector, count_selector, value_selector) {
var elem = $(elem_selector);
function make_elem(elem, count_selector, value_selector) {
var count = $(count_selector);
var value = $(value_selector);
elem.set_find_results('.count', count);
@@ -370,26 +374,25 @@ function initialize_stream_data() {
}
var stream_li = make_elem(
'stream-li',
'stream-count',
'stream-value'
$('<stream li>'),
'<stream-count>',
'<stream-value>'
);
stream_li.addClass('subscription_block');
stream_li.addClass('stream-with-count');
assert(stream_li.hasClass('stream-with-count'));
make_elem(
"#global_filters li[data-name='mentioned']",
'mentioned-count',
'mentioned-value'
$("#global_filters li[data-name='mentioned']"),
'<mentioned-count>',
'<mentioned-value>'
);
make_elem(
"#global_filters li[data-name='home']",
'home-count',
'home-value'
$("#global_filters li[data-name='home']"),
'<home-count>',
'<home-value>'
);
unread_ui.set_count_toggle_button = noop;
@@ -412,16 +415,16 @@ function initialize_stream_data() {
};
stream_list.update_dom_with_unread_counts(counts);
assert.equal($('stream-value').text(), '');
assert.equal($('<stream li>').text(), 'never-been-set');
assert(!stream_li.hasClass('stream-with-count'));
assert.equal($('mentioned-value').text(), '222');
assert.equal($('home-value').text(), '333');
assert.equal($('<mentioned-value>').text(), '222');
assert.equal($('<home-value>').text(), '333');
stream_count.set(stream_id, 99);
stream_list.update_dom_with_unread_counts(counts);
assert.equal($('stream-value').text(), '99');
assert.equal($('<stream-value>').text(), '99');
assert(stream_li.hasClass('stream-with-count'));
var topic_results;

View File

@@ -73,7 +73,7 @@ set_global('$', global.make_zjquery());
// But you can set up your tests to simulate DOM relationships.
//
// We will use set_find_results(), which is a special zjquery helper.
var emoji = $('emoji-stub');
var emoji = $('<div class="emoji">');
$('#my-message').set_find_results('.emoji', emoji);
// And then calling the function produces the desired effect:
@@ -135,7 +135,7 @@ set_global('$', global.make_zjquery());
var value;
function initialize_handler() {
$('my-parent').on('input', '.some-child-class', function (e) {
$('#my-parent').on('input', '.some-child-class', function (e) {
value = 42; // just a dummy side effect
e.stopPropagation();
});
@@ -147,7 +147,7 @@ set_global('$', global.make_zjquery());
// We want to call the inner function, so first let's get it using the
// get_on_handler() helper from zjquery.
var handler_func = $('my-parent').get_on_handler('input', '.some-child-class');
var handler_func = $('#my-parent').get_on_handler('input', '.some-child-class');
// Set up a stub event so that stopPropagation doesn't explode on us.
var stub_event = {
@@ -160,3 +160,17 @@ set_global('$', global.make_zjquery());
// And verify it did what it was supposed to do.
assert.equal(value, 42);
}());
(function test_create() {
// You can create jQuery objects that aren't tied to any particular
// selector, and which just have a name.
var obj1 = $.create('the table holding employees');
var obj2 = $.create('the collection of rows in the table');
obj1.show();
assert(obj1.visible());
obj2.addClass('.striped');
assert(obj2.hasClass('.striped'));
}());

View File

@@ -290,6 +290,21 @@ exports.make_zjquery = function () {
}
var selector = arg;
var valid_selector =
('<#.'.indexOf(selector[0]) >= 0) ||
(selector === 'window-stub') ||
(selector === 'document-stub') ||
(selector === 'html') ||
(selector.location) ||
(selector.indexOf('#') >= 0) ||
(selector.indexOf('.') >= 0);
assert(valid_selector,
'Invalid selector: ' + selector +
' Use $.create() maybe?');
if (elems[selector] === undefined) {
var elem = new_elem(selector);
elems[selector] = jquery_array(elem);
@@ -297,6 +312,13 @@ exports.make_zjquery = function () {
return elems[selector];
};
zjquery.create = function (name) {
assert(!elems[name],
'You already created an object with this name!!');
var elem = new_elem(name);
elems[name] = jquery_array(elem);
return elems[name];
};
zjquery.stub_selector = function (selector, stub) {
elems[selector] = stub;