mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	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.
		
	
		
			
				
	
	
		
			177 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
 | 
						|
This test module actually tests our test code, particularly zjquery, and
 | 
						|
it is intended to demonstrate how to use zjquery (as well as, of course, verify
 | 
						|
that it works as advertised).
 | 
						|
 | 
						|
What is zjquery?
 | 
						|
 | 
						|
    The zjquery test module behaves like jQuery at a very surface level, and it
 | 
						|
    allows you to test code that uses actual jQuery without pulling in all the
 | 
						|
    complexity of jQuery.  It also allows you to mostly simulate DOM for the
 | 
						|
    purposes of unit testing, so that your tests focus on component interactions
 | 
						|
    that aren't super tightly coupled to building the DOM.  The tests also run
 | 
						|
    faster!
 | 
						|
 | 
						|
The code we are testing lives here:
 | 
						|
 | 
						|
    https://github.com/zulip/zulip/blob/master/frontend_tests/zjsunit/zjquery.js
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
// The first thing we do to use zjquery is patch our global namespace
 | 
						|
// with zjquery as follows.  This call gives us our own instance of a
 | 
						|
// zjquery stub variable.  Like with real jQuery, the '$' function will
 | 
						|
// be the gateway to a bigger API.
 | 
						|
set_global('$', global.make_zjquery());
 | 
						|
 | 
						|
 | 
						|
(function test_basics() {
 | 
						|
    // Let's create a sample piece of code to test:
 | 
						|
 | 
						|
    function show_my_form() {
 | 
						|
        $('#my-form').show();
 | 
						|
    }
 | 
						|
 | 
						|
    // Before we call show_my_form, we can assert that my-form is hidden:
 | 
						|
    assert(!$('#my-form').visible());
 | 
						|
 | 
						|
    // Then calling show_my_form() should make it visible.
 | 
						|
    show_my_form();
 | 
						|
    assert($('#my-form').visible());
 | 
						|
 | 
						|
    // Next, look at how several functions correctly simulate setting
 | 
						|
    // and getting for you.
 | 
						|
    var widget = $('#my-widget');
 | 
						|
 | 
						|
    widget.attr('data-employee-id', 42);
 | 
						|
    assert.equal(widget.attr('data-employee-id'), 42);
 | 
						|
 | 
						|
    widget.html('<b>hello</b>');
 | 
						|
    assert.equal(widget.html(), '<b>hello</b>');
 | 
						|
 | 
						|
    widget.prop('title', 'My Widget');
 | 
						|
    assert.equal(widget.prop('title'), 'My Widget');
 | 
						|
 | 
						|
    widget.val('42');
 | 
						|
    assert.equal(widget.val(), '42');
 | 
						|
}());
 | 
						|
 | 
						|
(function test_finding_related_objects() {
 | 
						|
    // Let's say you have a function like the following:
 | 
						|
    function update_message_emoji(emoji_src) {
 | 
						|
        $('#my-message').find('.emoji').attr('src', emoji_src);
 | 
						|
    }
 | 
						|
 | 
						|
    // This would explode:
 | 
						|
    // update_message_emoji('foo.png');
 | 
						|
 | 
						|
    // The error would be:
 | 
						|
    // Error: Cannot find .emoji in #my-message
 | 
						|
 | 
						|
    // 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 = $('<div class="emoji">');
 | 
						|
    $('#my-message').set_find_results('.emoji', emoji);
 | 
						|
 | 
						|
    // And then calling the function produces the desired effect:
 | 
						|
    update_message_emoji('foo.png');
 | 
						|
    assert.equal(emoji.attr('src'), 'foo.png');
 | 
						|
 | 
						|
    /*
 | 
						|
    An important thing to understand is that zjquery doesn't truly
 | 
						|
    simulate DOM.  The way you make relationships work in zjquery
 | 
						|
    is that you explicitly set up what your functions want to return.
 | 
						|
 | 
						|
    Here is another example.
 | 
						|
    */
 | 
						|
 | 
						|
    var my_parents = $('#folder1,#folder4');
 | 
						|
    var elem = $('#folder555');
 | 
						|
 | 
						|
    elem.set_parents_result('.folder', my_parents);
 | 
						|
    elem.parents('.folder').addClass('active');
 | 
						|
    assert(my_parents.hasClass('active'));
 | 
						|
 | 
						|
}());
 | 
						|
 | 
						|
(function test_clicks() {
 | 
						|
    // We can support basic handlers like click and keydown.
 | 
						|
 | 
						|
    var state = {};
 | 
						|
 | 
						|
    function set_up_click_handlers() {
 | 
						|
        $('#widget1').click(function () {
 | 
						|
            state.clicked = true;
 | 
						|
        });
 | 
						|
 | 
						|
        $('.some-class').keydown(function () {
 | 
						|
            state.keydown = true;
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    // Setting up the click handlers doesn't change state right away.
 | 
						|
    set_up_click_handlers();
 | 
						|
    assert(!state.clicked);
 | 
						|
    assert(!state.keydown);
 | 
						|
 | 
						|
    // But we can simulate clicks.
 | 
						|
    $('#widget1').click();
 | 
						|
    assert.equal(state.clicked, true);
 | 
						|
 | 
						|
    // and keydown
 | 
						|
    $('.some-class').keydown();
 | 
						|
    assert.equal(state.keydown, true);
 | 
						|
 | 
						|
}());
 | 
						|
 | 
						|
(function test_events() {
 | 
						|
    // Zulip's codebase uses jQuery's event API heavily with anonymous
 | 
						|
    // functions that are hard for naive test code to cover.  zjquery
 | 
						|
    // will come to our rescue.
 | 
						|
 | 
						|
    var value;
 | 
						|
 | 
						|
    function initialize_handler() {
 | 
						|
        $('#my-parent').on('input', '.some-child-class', function (e) {
 | 
						|
            value = 42; // just a dummy side effect
 | 
						|
            e.stopPropagation();
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    // Calling initialize_handler() doesn't immediately do much of interest.
 | 
						|
    initialize_handler();
 | 
						|
    assert.equal(value, undefined);
 | 
						|
 | 
						|
    // 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');
 | 
						|
 | 
						|
    // Set up a stub event so that stopPropagation doesn't explode on us.
 | 
						|
    var stub_event = {
 | 
						|
        stopPropagation: function () {},
 | 
						|
    };
 | 
						|
 | 
						|
    // Now call the hander.
 | 
						|
    handler_func(stub_event);
 | 
						|
 | 
						|
    // 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'));
 | 
						|
}());
 |