Mercurial > nebulaweb3
diff default/node_modules/shoestring/test/unit/extensions.js @ 0:1d038bc9b3d2 default tip
Up:default
author | Liny <dev@neowd.com> |
---|---|
date | Sat, 31 May 2025 09:21:51 +0800 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/default/node_modules/shoestring/test/unit/extensions.js Sat May 31 09:21:51 2025 +0800 @@ -0,0 +1,1929 @@ +(function(undefined){ + var config, ss = shoestring; + var $fixture = shoestring( '#qunit-fixture' ); + + module( 'dom', config = { + setup: function() { + $fixture = shoestring( '#qunit-fixture' ); + }, + + teardown: function() { + $fixture.unbind("foo"); + $(document).unbind("foo"); + } + }); + + test( '`.add()` adds selected elements to the set', function(){ + var length, count; + + length = $fixture.length; + count = shoestring( '.add' ).length; + $fixture = $fixture.add( '.add' ); + + ok( count > 0 ); + equal( $fixture.length, length + count ); + }); + + test( '`.addClass()` adds a classes when they doesnt exit', function(){ + var $element = $fixture.find( '.add-class' ); + + $element.addClass( 'foo bar baz' ); + equal( $element.attr( "class" ), "add-class foo bar baz" ); + }); + + test( '`.addClass()` doesnt duplicate classes', function(){ + var $element = $fixture.find( '.add-class' ); + + $element.addClass( 'add-class' ); + equal( $element.attr( "class" ), "add-class" ); + }); + + test( '`.after()` inserts a sibling after the current obj element', function(){ + expect( 3 ); + var $element = $fixture.find( '.after' ); + + equal( $fixture.find( '.foo-after' ).length, 0 ); + $element.after( "<div class='foo-after'></div> "); + equal( $fixture.find( '.foo-after' ).length, 1 ); + + // sibling to .foo-after + $fixture.children().each(function(i) { + if( shoestring( this ).is( '.after' ) ){ + equal( $fixture.children()[i+1].className, "foo-after" ); + } + }); + }); + + test( '`.after()` inserts siblings after the current obj element in the correct order', function(){ + expect( 6 ); + var $element = $fixture.find( '.after' ); + + equal( $fixture.find( '.foo-after' ).length, 0 ); + equal( $fixture.find( '.foo-after2' ).length, 0 ); + $element.after( "<div class='foo-after'></div><div class='foo-after2'></div> "); + equal( $fixture.find( '.foo-after' ).length, 1 ); + equal( $fixture.find( '.foo-after2' ).length, 1 ); + + // sibling to .foo-after + $fixture.children().each(function(i) { + if( shoestring( this ).is( '.after' ) ){ + equal( $fixture.children()[i+1].className, "foo-after" ); + equal( $fixture.children()[i+2].className, "foo-after2" ); + } + }); + }); + + test( '`.insertAfter()` inserts after the selector', function(){ + expect( 3 ); + + equal( $fixture.find( '.foo-after' ).length, 0 ); + shoestring( "<div class='foo-after'></div> ").insertAfter( '.after' ); + equal( $fixture.find( '.foo-after' ).length, 1 ); + + // sibling to .foo-after + $fixture.children().each(function(i) { + if( shoestring( this ).is( '.after' ) ){ + equal( $fixture.children()[i+1].className, "foo-after" ); + } + }); + }); + + test( '`.append()` inserts a child in the current obj element', function(){ + var $element = $fixture.find( '.append' ); + + equal( $element.find( '.foo-append' ).length, 0 ); + $element.append( "<div class='foo-append'></div> "); + equal( $element.find( '.foo-append' ).length, 1 ); + }); + + test( '`.insertAfter()` inserts after the selector', function(){ + var $element = $fixture.find( '.append' ); + + equal( $element.find( '.foo-append' ).length, 0 ); + shoestring( "<div class='foo-append'></div> ").appendTo( $element ); + equal( $element.find( '.foo-append' ).length, 1 ); + }); + + test( '`.attr()` returns undefined on empty set', function(){ + var $element = $( '#this_will_not_match' ); + + equal( $element.attr( 'class' ), undefined ); + }); + + test( '`.attr()` gets the attribute', function(){ + var $element = $fixture.find( '.attr' ); + + equal( $element.attr( 'class' ), "attr" ); + }); + + test( '`.attr()` sets the attribute', function(){ + var $element = $fixture.find( '.attr' ); + + equal( $element.attr( 'class', "foo" ).attr( 'class' ), "foo" ); + }); + + test( '`.before()` inserts a sibling before the current obj element', function(){ + expect( 3 ); + var $element = $fixture.find( '.before' ); + + equal( $fixture.find( '.foo-before' ).length, 0 ); + $element.before( "<div class='foo-before'></div> "); + equal( $fixture.find( '.foo-before' ).length, 1 ); + + // sibling to .foo-before + $fixture.children().each(function(i) { + if( shoestring( this ).is( '.before' ) ){ + equal( $fixture.children()[i-1].className, "foo-before" ); + } + }); + }); + + test( '`.data` and falsy values', function() { + var $fixture = shoestring( '#qunit-fixture' ), + $el; + + $fixture.html( '<div id="el"></div>' ); + $el = $( "#el" ); + + $el.data( "val-false", false ); + strictEqual( $( '#el' ).data( "val-false" ), false ); + + $el.data( "val-zero", 0 ); + strictEqual( $( '#el' ).data( "val-zero" ), 0 ); + + $el.data( "val-undefined", undefined ); + strictEqual( $( '#el' ).data( "val-undefined" ), undefined ); + }); + + test( '`.data` works on empty nodelists', function() { + var $fixture = shoestring( '#qunit-fixture' ), + $el; + + $fixture.html( '<div id="el"></div>' ); + $el = $( "#el" ); + + strictEqual( $( '#thiswontmatch' ).data(), undefined, 'should be undefined on an empty result set.' ); + strictEqual( $( '#thiswontmatch' ).data( "somekey" ), undefined, 'should be undefined on an empty result set with a key passed in.' ); + + deepEqual( $( '#el' ).data(), {}, 'should be an empty object on an nonempty result set.' ); + strictEqual( $( '#el' ).data( "somekey" ), undefined, 'should be undefined on an nonempty result set with a key passed in.' ); + }); + + test( '`.data` does not alias to `data-` attributes', function() { + expect( 3 ); + var $fixture = shoestring( '#qunit-fixture' ), + $el; + + $fixture.html( '<div id="el" data-attr1 data-attr2="test"></div>' ); + $el = $( "#el" ); + + strictEqual( $( '#el' ).data( "attr0" ), undefined, 'attribute does not exist, should not throw an error.' ); + + throws(function() { + $( '#el' ).data( "attr1" ); + }, 'attribute exists but has no value, should have thrown a dev error.' ); + + throws(function() { + $( '#el' ).data( "attr2" ); + }, 'attribute exists and has a value, should have thrown a dev error.' ); + }); + + test( '`.insertBefore()` inserts before the selector', function(){ + expect( 3 ); + + equal( $fixture.find( '.foo-before' ).length, 0 ); + shoestring( "<div class='foo-before'></div> ").insertBefore( '.before' ); + equal( $fixture.find( '.foo-before' ).length, 1 ); + + // sibling to .foo-before + $fixture.children().each(function(i) { + if( shoestring( this ).is( '.before' ) ){ + equal( $fixture.children()[i-1].className, "foo-before" ); + } + }); + }); + + test( '`.clone()` prevents alteration of original', function() { + var $clone, $element; + + $element = $fixture.find( ".clone" ); + $clone = $element.clone(); + + equal( $element.attr( "class" ), "clone" ); + equal( $clone.attr( "class" ), "clone" ); + $clone.attr( "class", "foo" ); + equal( $element.attr( "class" ), "clone" ); + equal( $clone.attr( "class" ), "foo" ); + }); + + test( '`.closest()`', function() { + var $fixture = shoestring( '#qunit-fixture' ); + + var $child = $fixture.find( '.closest .child' ); + + equal( $child[0], $child.closest( '.child' )[0], 'Closest returns current element on match' ); + + equal( $child.closest( '.parent' ).length, 1, 'Closest returns only one element when original nodelist has one element.' ); + + var $children = $fixture.find( '.closest .second-child' ).add( $child ); + + equal( $children.closest( '.parent' ).length, 2, 'Closest returns only two elements when original nodelist has two element.' ); + + ok( $child.closest( '.parent' ).is( '.first' ), 'Closest returns from the bottom up.' ); + + ok( $child.closest( '.parent.second' ).is( '.second' ), 'Closest will traverse at least two parents correctly.' ); + }); + + test('`.css()`', function() { + var $css = $fixture.find( ".css" ), + $otherCss = $fixture.find( ".othercss" ); + + $css.css({ + foo: "bar", + baz: "bak", + "float": "left", + "margin-right": "1px", + "transform": "rotateX(0)", + "WebkitTransform": "rotateX(0)", + "box-sizing": "border-box", + "WebkitBoxSizing": "border-box" + }); + + $css.css( 'margin-left', "2px" ); + + // computed style should ignore spurious styles + equal( ss._getStyle($css[0], 'baz'), undefined ); + + // width is defined in the page + equal( ss._getStyle($css[0], 'width'), "200px", "width should show value set from <style> tag." ); + + // margin-right is defined in the object assignment above + equal( ss._getStyle($css[0], 'margin-right'), "1px", "margin-right should be set" ); + + // margin-left is defined in the property assignment above + equal( ss._getStyle($css[0], 'margin-left'), "2px", "margin-left should be set" ); + + equal( ss._getStyle($css[0], "float"), "left", "float is a special case (cssFloat in JS)." ); + + equal( ss._getStyle($css[0], 'box-sizing'), 'border-box', 'Box-sizing should default to content-box.' ); + + if( document.defaultView ) { // CTM for this vendor prefix test. + notEqual( ss._getStyle($css[0], 'transform'), undefined, 'transform should **NOT** be undefined (get vendor prefixes correctly).' ); + } + + notEqual( ss._getStyle($otherCss[0], 'width'), undefined, 'Width should **NOT** have a value because it’s not set.' ); + }); + + test('`.eq()`', function() { + equal( $fixture.eq( 0 )[0], $fixture[0] ); + equal( $fixture.eq( 1000000 )[0], undefined ); + }); + + test('`.filter( selector )`', function() { + var $divs = $fixture.find( "div" ); + + equal( $divs.filter( ".filter" ).length, 1 ); + equal( $divs.filter( ".filter" )[0], $fixture.find( ".filter" )[0] ); + + var $withoutParent = $( "<div class='filter'></div><div></div>" ); + + equal( $withoutParent.filter( ".filter" ).length, 1 ); + equal( $withoutParent.filter( ".filter" )[0], $withoutParent[0] ); + }); + + test('`.add( document ).filter( selector )`', function() { + var $divs = $fixture.find( "div" ); + var $addDoc = $divs.add( document ); + equal( $addDoc.filter( ".filter" ).length, 1 ); + + var $doc = $( document ); + equal( $doc.filter( document ).length, 1 ); + }); + + test('`.filter( function )`', function() { + var $divs = $fixture.find( ".filter" ); + + equal( $divs.length, 1 ); + equal( $divs.filter(function() { return false; }).length, 0 ); + equal( $divs.filter(function() { return true; }).length, 1 ); + }); + + test('`.first()`', function() { + equal( $fixture.eq( 0 )[0], $fixture.first()[0] ); + }); + + test('`.get()`', function() { + equal( $fixture[0], $fixture.get(0) ); + }); + + test('`.height()`', function() { + var $height = $fixture.find( ".height" ); + + // returns the value without param + equal( $height.height(), 200 ); + + // works with integers + $height.height( 300 ); + equal( $height.height(), 300 ); + + // works with strings + $height.height( "400px" ); + equal( $height.height(), 400 ); + }); + + test( '`.html()`', function() { + var $old = shoestring( '.html .old' ), + $new = shoestring( '.html .new' ), + htmlStr = '<div id="sibling"></div>'; + + $old[0].innerHTML = htmlStr; + $new.html( htmlStr ); + + ok( !!$old[0].innerHTML ); + equal( $new[0].innerHTML, $old[0].innerHTML, '.html(str) set properly.' ); + equal( $new.html(), $old[0].innerHTML, '.html() get str properly.' ); + }); + + test( '`.html(Number)`', function() { + var $old = shoestring( '.html .old' ), + $new = shoestring( '.html .new' ), + htmlStr = 2; + + $old[0].innerHTML = htmlStr; + $new.html( htmlStr ); + + ok( !!$old[0].innerHTML ); + equal( $new[0].innerHTML, $old[0].innerHTML, '.html(number) set a number properly.' ); + equal( $new.html(), $old[0].innerHTML, '.html() get number properly.' ); + }); + + test( '`.html(HTML Object)`', function() { + var $old = shoestring( '.html .old' ), + $new = shoestring( '.html .new' ); + + var div = document.createElement( "div" ); + div.id = "sibling"; + + $old[0].innerHTML = "<div id='sibling'></div>"; + $new.html( div ); + + ok( !!$old[0].innerHTML ); + equal( $new[0].innerHTML, $old[0].innerHTML, '.html(obj) set properly.' ); + equal( $new.html(), $old[0].innerHTML, '.html() get obj properly.' ); + }); + + test( '`.html(HTML Object)`', function() { + var $old = shoestring( '.html .old' ), + $new = shoestring( '.html .new' ); + + var div = document.createElement( "div" ); + div.id = "sibling"; + + $old[0].innerHTML = "<div id='sibling'></div>"; + $new.html( div ); + + ok( !!$old[0].innerHTML ); + equal( $new[0].innerHTML, $old[0].innerHTML, '.html(obj) set properly.' ); + equal( $new.html(), $old[0].innerHTML, '.html() get properly.' ); + }); + + test( '`.html(Array)`', function() { + var $old = shoestring( '.html .old' ), + $new = shoestring( '.html .new' ); + + var arr = []; + + var div = document.createElement( "div" ); + div.id = "sibling"; + var div2 = document.createElement( "div" ); + div2.id = "sibling2"; + + arr.push( div ); + arr.push( div2 ); + + $old[0].innerHTML = "<div id='sibling'></div><div id='sibling2'></div>"; + $new.html( arr ); + + ok( !!$old[0].innerHTML ); + equal( $new[0].innerHTML, $old[0].innerHTML, '.html(Array) set properly.' ); + equal( $new.html(), $old[0].innerHTML, '.html() get properly.' ); + }); + + test('`.index()`', function() { + var $indexed = $fixture.find( ".index div" ); + equal( $indexed.index( ".first" ), 0 ); + equal( $indexed.index( ".second" ), 1 ); + + var $second = $fixture.find( ".index .second" ); + equal( $second.index(), 1 ); + equal( $indexed.index( $second.get( 0 ) ), 1, "index() DOM element argument" ); + + throws(function() { + equal( $indexed.index( $second ), 1, "index() shoestring argument" ); + }, 'index(shoestring()) should throw a dev error.' ); + + }); + + test('empty set `.index()`', function() { + equal( $( ".this-set-will-be-empty" ).index(), -1 ); + }); + + test('`.is()`', function() { + ok( $fixture.is("#qunit-fixture") ); + ok( !$fixture.is(".jacky-jormp-jomp") ); + ok( $("html").is("html") ); + ok( $("body").is("body") ); + ok( $("body").is(document.body), "body is document.body" ); + + // For some reason in IE8, document[0] returns the first form. + ok( !$("form[name=abc]").is( document ), "a form is not document" ); + + // element checks permitted, works at parent level + ok( $( document ).is( document ), "document should be document" ); + + ok( $fixture.is( $fixture ) ); + + // correctly matches the child/descendant selector combinators + ok( $fixture.find( ".is .child" ).is( ".is > .child" ) ); + ok( $fixture.find( ".is .child" ).is( "body .child" ) ); + }); + + test('`.last()`', function() { + equal( $fixture.eq( $fixture.length - 1 )[0], $fixture.last()[0] ); + }); + + test( '`.next()`', function() { + var $first, $all; + + $first = $fixture.find( ".next .first" ); + $all = $fixture.find( ".next > div" ); + + + equal( $first.next().length, 1 ); + equal( $first.next()[0], $fixture.find(".next .second")[0]); + + equal( $all.next().length, 2 ); + equal( $all.next()[0], $fixture.find(".next .second")[0]); + equal( $all.next()[1], $fixture.find(".next .third")[0]); + equal( $all.next()[2], undefined ); + }); + + test( '`.not()`', function() { + var $divs = $fixture.find( ".not div" ); + + equal( $divs.not( ".is-not" ).length, 1 ); + equal( $divs.not( ".is-so" ).length, $divs.length - 1 ); + }); + + test( '`.parent()`', function() { + var $children, $parent; + + $parent = $( "#qunit-fixture > .parent" ); + $children = $parent.find( ".child" ); + + // double parent + equal( $children.parent()[0], $parent[0] ); + equal( $children.parent()[1], $parent[0] ); + + // default to document element + // NOTE: this behavior is to match the jQuery semantics + equal( $( "html" ).parent()[0], document ); + + $children.remove(); + + equal( $children.eq(0).parent().length, 0); + }); + + test( '`.parents()` ... with an s', function() { + var $children, $parent; + + $parent = $( "#qunit-fixture > .parents" ); + $children = $parent.find( ".child" ); + + // the shared parents of the first and second child + // +1 for the second parent which is unique + equal( $children.parents().length, 6); + equal( $children.parents()[0], $(".parents > .first-parent")[0] ); + equal( $children.parents()[2], $("#qunit-fixture")[0] ); + equal( $children.parents()[4], $("html")[0] ); + equal( $children.parents()[5], $(".parents > .second-parent")[0] ); + }); + + test( '`.prepend() adds a first child element', function() { + var tmp, $prepend = $fixture.find( ".prepend" ); + + tmp = $( "<div class='first'></div>" ); + $prepend.append( tmp[0] ); + $prepend.append( "<div class='second'></div>" ); + $prepend.append( ".testel" ); + + equal( $prepend.find( ".first" )[0], tmp[0] ); + equal( $prepend.find( ".second" ).length, 1 ); + equal( $prepend.find( ".testel" ).length, 1 ); + }); + + test( '`.prependTo() adds the all elements to the selected element` ', function() { + var tmp, $prepend = $fixture.find( ".prepend" ); + + tmp = $( "<div class='first'></div>" ); + + tmp.appendTo( "#qunit-fixture > .prepend" ); + + equal( $prepend.find( ".first" )[0], tmp[0] ); + }); + + test( '`.prev()`', function() { + var $last, $all; + + $last = $fixture.find( ".prev div.third" ); + $all = $fixture.find( ".prev > div" ); + + equal( $last.prev().length, 1 ); + equal( $last.prev()[0], $fixture.find(".prev .second")[0]); + + // ordering correct according to jquery api + // http://api.jquery.com/prev/ + equal( $all.prev().length, 2 ); + equal( $all.prev()[0], $fixture.find(".prev .first")[0]); + equal( $all.prev()[1], $fixture.find(".prev .second")[0]); + equal( $all.prev()[2], undefined ); + }); + + test( '`.prevAll()`', function() { + var $last; + + $last = $fixture.find( ".prevall div.third" ); + + equal( $last.prevAll().length, 2 ); + + // ordering correct according to jquery api + // http://api.jquery.com/prevall/ + equal( $last.prevAll()[0], $fixture.find(".prevall .second")[0]); + equal( $last.prevAll()[1], $fixture.find(".prevall .first")[0]); + equal( $last.prevAll()[2], undefined ); + }); + + test( '`.prop()` returns undefined on empty set', function(){ + var $element = $( '#this_will_not_match' ); + + equal( $element.prop( 'class' ), undefined ); + }); + + test( '`.prop()` gets the attribute', function(){ + var $element = $fixture.find( '.prop' ); + + equal( $element.prop( 'class' ), "prop" ); + }); + + test( '`.prop()` sets the attribute', function(){ + var $element = $fixture.find( '.prop' ); + + equal( $element.prop( 'class', "bar" )[0].className, "bar" ); + }); + + test( '`.remove()`', function(){ + var $el, $fixture; + + $fixture = shoestring( '#qunit-fixture' ); + $fixture.html( '<div id="el"></div>' ); + $el = $( "#el" ); + + equal( $fixture.children().length, 1 ); + $el.remove(); + + equal( $fixture.children().length, 0 ); + }); + + test( '`.remove()` on unattached nodes', function(){ + var $el; + $el = $( document.createElement( "div" ) ); + + $el.remove(); + ok( true ); + }); + + // here to test for ie8 + test( '`.removeAttr()`', function() { + var $removeAttr = $fixture.find( ".remove-attr" ); + + equal( $removeAttr.attr( "data-foo" ), "bar" ); + $removeAttr.removeAttr( "data-foo" ); + equal( $removeAttr.attr( "data-foo" ), undefined ); + }); + + test( '`.removeClass()` removes the class', function() { + var $removeClass = $fixture.find( ".remove-class" ); + + ok( $removeClass.is( ".foo" ) ); + $removeClass.removeClass( "foo" ); + ok( !$removeClass.is( ".foo" ) ); + }); + + test( '`.removeClass()` leaves no extra whitespace', function() { + var $removeClass = $fixture.find( ".remove-class" ); + + $removeClass.addClass( "foo" ); + $removeClass.removeClass( "foo" ); + $removeClass.addClass( "foo" ); + $removeClass.removeClass( "foo" ); + + equal( $removeClass[0].className, "remove-class" ); + }); + + test( '`.removeProp()`', function() { + var $removeProp = $fixture.find( ".remove-prop" ); + + equal( $removeProp.attr( "class" ), "remove-prop" ); + $removeProp.removeProp( "class" ); + + // NOTE this is bullshit, unquoted undefined works in everything but phantom + equal( $removeProp.attr( "class"), "undefined" ); + }); + + test( '`.replaceWith()`', function() { + var $replaceWith = $fixture.find( ".replace-with" ); + + equal( $fixture.find( ".replace-with" ).length, 1 ); + + var old = $replaceWith.replaceWith( "<div class='replacement'></div>" ); + + equal( $fixture.find( ".replace-with" ).length, 0 ); + equal( $fixture.find( ".replacement" ).length, 1 ); + ok( old[0].className === "replace-with", "Returned element should be the original element copied" ); + }); + + test( '`.replaceWith()` with multiple pieces', function() { + var $replaceWith = $fixture.find( ".replace-with-multiple" ); + + equal( $fixture.find( ".replace-with-multiple" ).length, 1 ); + + var old = $replaceWith.replaceWith( "<div class='replacement1'></div><div class='replacement2'></div>" ); + + equal( $fixture.find( ".replace-with-multiple" ).length, 0 ); + equal( $fixture.find( ".replacement1" ).length, 1 ); + equal( $fixture.find( ".replacement2" ).length, 1 ); + ok( old[0].className === "replace-with-multiple", "Returned element should be the original element copied" ); + + $fixture.children().each(function(i) { + if( shoestring( this ).is( '.replacement1' ) ){ + equal( $fixture.children()[i+1].className, "replacement2", "Elements should be in order" ); + } + }); + }); + + test( '`.replaceWith()` with no dom piece/missing parentNode', function() { + var $replaceWith = $( "<div class='replace-missing'></div>" ); + + equal( $replaceWith.length, 1 ); + + var old = $replaceWith.replaceWith( "<div class='replace-it'></div>" ); + + equal( $fixture.find( ".replace-it" ).length, 0 ); + ok( old[0].className === "replace-missing", "Returned element should be the original element copied" ); + + }); + + // TODO make this suck less + test( '`.serialize()`', function() { + var data, input, type, $serialize = $fixture.find( ".serialize" ); + + for( var i = 0; i < shoestring.inputTypes.length; i++ ) { + type = shoestring.inputTypes[i]; + input = "<input type='" + type + "'" + + "name='" + type + "'" + + "value='" + type + "'></input>"; + + $serialize.append( input ); + } + + data = $serialize.serialize(); + + for( var val in data ) { + ok( data[ val ] || data[ val ] === "" ); + } + }); + + test( '`.siblings()`', function() { + var $fixture = shoestring( '#qunit-fixture' ); + $fixture.html( '<div></div><div id="sibling"></div><div></div>' ); + + strictEqual( $( '#imaginary_element' ).siblings().length, 0, '.siblings runs on an empty set.' ); + equal( $( '#sibling' ).siblings().length, 2, '.siblings returns non-empty set.' ); + }); + + test( '`.text()` returns content properly', function(){ + var container = $( "<div class='text-test'><div class='demo-box'>Demonstration Box</div><ul><li>list item 1</li><li>list <strong>item</strong> 2</li></ul></div></div>" ); + var content = "Demonstration Boxlist item 1list item 2"; + + equal( container.text(), content, "should return nested text properly" ); + }); + + test( '`.val()` returns correct value of element', function(){ + var value = "happy"; + var input = document.createElement( "input" ); + input.type = "text"; + input.value = value; + + equal( $( input ).val(), value, ".val should return the equivalent of the input's value" ); + }); + + test( '`.val()` returns correct value of select element', function(){ + var select = document.createElement( "select" ); + var option1 = document.createElement( "option" ); + var option2 = document.createElement( "option" ); + + option1.value = "1"; + option2.value = "2"; + + option2.selected = "selected"; + + select.appendChild( option1 ); + select.appendChild( option2 ); + + equal( $( select ).val(), "2", ".val should return the equivalent of the select's selected option's value" ); + }); + + test( '`.val()` returns correct value of select element', function(){ + var select = document.createElement( "select" ); + var option1 = document.createElement( "option" ); + var option2 = document.createElement( "option" ); + + option1.value = "1"; + option2.value = "2"; + + + select.appendChild( option1 ); + select.appendChild( option2 ); + + select.selectedIndex = -1; + + equal( $( select ).val(), "", ".val should return empty string if nothing is selected" ); + }); + + test( '`$( input ).val(value)` inserts value into input', function(){ + var value = "happy"; + var input = document.createElement( "input" ); + input.type = "text"; + $( input ).val( value ); + + equal( input.value, value, ".val should be the equivalent of setting the input's value" ); + }); + + test( '`$( select ).val(value)` selects the option that matches the value', function(){ + var select = document.createElement( "select" ); + var option1 = document.createElement( "option" ); + var option2 = document.createElement( "option" ); + var option3 = document.createElement( "option" ); + + option1.value = "1"; + option2.value = "2"; + option3.value = "3"; + + option2.selected = "selected"; + + select.appendChild( option1 ); + select.appendChild( option2 ); + select.appendChild( option3 ); + + $( select ).val( "3" ); + + + equal( $( select ).val(), "3", ".val should set the correct option" ); + }); + + test('`.width()`', function() { + var $width = $fixture.find( ".width" ); + + // returns the value without param + equal( $width.width(), 200 ); + + // works with integers + $width.width( 300 ); + equal( $width.width(), 300 ); + + // works with strings + $width.width( "400px" ); + equal( $width.width(), 400 ); + }); + + test('`.wrapInner()`', function() { + var $wrapInner = $fixture.find( ".wrap-inner" ); + + $wrapInner.wrapInner( "<div class='wrapper'></div>" ); + equal( $wrapInner.find( ".wrapper > .inner" ).length, 1 ); + equal( $wrapInner.find( ".wrapper" ).length, 1 ); + }); + + module( 'events', config ); + + asyncTest( '`.bind()` and `.trigger()`', function() { + expect( 2 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "click", function( e ) { + ok( true, 'event callback should execute.' ); + ok( e.target, 'event.target should exist.' ); + start(); + }).trigger( "click" ); + }); + + test( '`.trigger("click")` checks a checkbox', function() { + expect( 2 ); + shoestring( '#qunit-fixture' ).html( '<input id="cbx" type="checkbox" />' ); + + ok( !$( "#cbx" )[0].checked, "Checkbox shouldn't be checked" ); + $( "#cbx" ).trigger( "click" ); + ok( !!$( "#cbx" )[0].checked, "Checkbox should be checked" ); + }); + + asyncTest( "custom event bindings get the right target", function() { + expect( 1 ); + + var $div = $fixture.find( "div" ).first(); + + $fixture.one( "foo", function( event ) { + equal( $div[0], event.target ); + start(); + }); + + $div.trigger( "foo" ); + }); + + asyncTest( "custom event bindings get the right context (`this`)", function() { + expect( 1 ); + + var $div = $fixture.find( "div" ).first(); + + $fixture.one( "foo", function( event ) { + equal( this, $fixture[0] ); + start(); + }); + + $div.trigger( "foo" ); + }); + + asyncTest( "`document` bindings get events triggered on `documentElement` children", function() { + expect( 1 ); + + $(document).one( "foo", function() { + ok( true ); + start(); + }); + + $fixture.trigger( "foo" ); + }); + + asyncTest( "`document` bindings get events triggered on `document`", function() { + expect( 1 ); + + $(document).one( "foo", function() { + ok( true ); + start(); + }); + + $( document ).trigger( "foo" ); + }); + + asyncTest( 'DOM Event `.bind()` and `.trigger()` with arguments', function() { + expect( 1 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "click", function( e, myArgument ) { + equal( myArgument, "Argument", 'a custom argument should exist.' ); + start(); + }).trigger( "click", [ "Argument" ] ); + }); + + asyncTest( 'Custom Event `.bind()` and `.trigger()` with arguments', function() { + expect( 1 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "myCustomEvent", function( e, myArgument ) { + equal( myArgument, "Argument", 'a custom argument should exist.' ); + start(); + }).trigger( "myCustomEvent", [ "Argument" ] ); + }); + + asyncTest( '`.bind()` and `.trigger()` with data', function() { + expect( 2 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "click", { key: "test-value" }, function( e ) { + ok( true, 'event callback should execute.' ); + equal( e.data.key, "test-value", "Data should be present on event object" ); + start(); + }).trigger( "click" ); + }); + + asyncTest( '`.on()` and click event bubbles to parent', function() { + expect( 1 ); + + shoestring( '#qunit-fixture' ).html( '<div id="parent"><div id="child"></div></div>' ); + + $( '#parent' ).on( "click", function() { + ok( true, 'event callback should execute.' ); + start(); + }); + + $( '#child' ).trigger( "click" ); + }); + + asyncTest( '`.bind()` and `.trigger()` with custom events', function() { + expect( 1 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "aCustomEvent", function() { + ok( true, 'event callback should execute.' ); + start(); + }).trigger( "aCustomEvent" ); + + $( "#el" ).unbind( "aCustomEvent" ); + }); + + asyncTest( '`.bind()` and `.trigger()` with custom events and data', function() { + expect( 2 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "aCustomEvent", { key: "custom" }, function(e) { + ok( true, 'event callback should execute.' ); + equal( e.data.key, "custom" ); + start(); + }).trigger( "aCustomEvent" ); + + $( "#el" ).unbind( "aCustomEvent" ); + }); + + asyncTest( '`.bind()` doesn’t execute callback without `.trigger()` with custom events', function() { + expect( 1 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "aCustomEvent", function() { + ok( false, "Should not execute without being triggered." ); + }).bind( "anotherCustomEvent", function() { + ok( false, "Should not execute without being triggered." ); + }); + + setTimeout(function() { + ok( true ); + + $( "#el" ).unbind( "aCustomEvent anotherCustomEvent" ); + + start(); + }, 30); + }); + + asyncTest( '`.on()` and custom events bubble to parent', function() { + expect( 1 ); + + shoestring( '#qunit-fixture' ).html( '<div id="parent"><div id="child"></div></div>' ); + + $( '#parent' ).on( "aCustomEvent", function() { + ok( true, 'event callback should execute.' ); + + start(); + }); + + $( '#child' ).trigger( "aCustomEvent" ); + $( "#parent" ).unbind( "aCustomEvent" ); + }); + + asyncTest( '`.bind()` and `.trigger()` with multiple of the same event on a single element', function() { + expect( 3 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "click", function() { + counter++; + equal( counter, 1, 'event callback should execute first.' ); + }).bind( "click", function() { + counter++; + equal( counter, 2, 'event callback should execute second.' ); + }).bind( "click", function() { + counter++; + equal( counter, 3, 'event callback should execute third.' ); + start(); + }).trigger( "click" ); + }); + + asyncTest( '`.bind()` and `.trigger()` with multiple of the same event on a single element, bubbles to parent', function() { + expect( 3 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="parent"><div id="child"></div></div>' ); + + $( "#parent" ).bind( "click", function() { + counter++; + equal( counter, 1, 'event callback should execute first.' ); + }).bind( "click", function() { + counter++; + equal( counter, 2, 'event callback should execute second.' ); + }).bind( "click", function() { + counter++; + equal( counter, 3, 'event callback should execute third.' ); + start(); + }); + + $( "#child" ).trigger( "click" ); + }); + + asyncTest( '`.bind()` and `.trigger()` with multiple of the same event on different elements', function() { + expect( 2 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el1"></div><div id="el2"></div>' ); + + $( "#el1" ).bind( "click", function() { + counter++; + equal( counter, 1, 'event callback should execute first.' ); + }); + $( "#el2" ).bind( "click", function() { + counter++; + equal( counter, 2, 'event callback should execute second.' ); + start(); + }); + $( "#el1" ).trigger( "click" ); + $( "#el2" ).trigger( "click" ); + }); + + asyncTest( '`.bind()` and `.trigger()` with multiple of the same custom event on a single element', function() { + expect( 4 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "aCustomEvent", function() { + counter++; + equal( counter, 1, 'event callback should execute first.' ); + }).bind( "aCustomEvent", function() { + counter++; + equal( counter, 2, 'event callback should execute second.' ); + }).bind( "aCustomEvent", function() { + counter++; + equal( counter, 3, 'event callback should execute third.' ); + }).bind( "aCustomEvent", function() { + counter++; + equal( counter, 4, 'event callback should execute fourth.' ); + start(); + }).trigger( "aCustomEvent" ); + + $( "#el" ).unbind( "aCustomEvent" ); + }); + + asyncTest( '`.bind()` and `.trigger()` with multiple of the same custom event on a single element, bubbles to parent', function() { + expect( 2 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="parent"><div id="child"></div></div>' ); + + $( "#parent" ).bind( "aCustomEvent", function() { + counter++; + equal( counter, 1, 'event callback should execute first.' ); + }).bind( "aCustomEvent", function() { + counter++; + equal( counter, 2, 'event callback should execute second.' ); + start(); + }); + + $( "#child" ).trigger( "aCustomEvent" ); + + $( "#parent" ).unbind( "aCustomEvent" ); + }); + + asyncTest( '`.bind()` and `.trigger()` with multiple of the same custom event on different elements', function() { + expect( 2 ); + + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el1"></div><div id="el2"></div>' ); + + $( "#el1" ).bind( "aCustomEvent", function() { + counter++; + equal( counter, 1, 'event callback should execute first.' ); + }); + $( "#el2" ).bind( "aCustomEvent", function() { + counter++; + equal( counter, 2, 'event callback should execute second.' ); + start(); + }); + $( "#el1" ).trigger( "aCustomEvent" ); + $( "#el2" ).trigger( "aCustomEvent" ); + + $( "#el1" ).unbind( "aCustomEvent" ); + $( "#el2" ).unbind( "aCustomEvent" ); + }); + + asyncTest( '`.bind()` should not execute without trigger', function() { + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( '#el' ) + .bind( "dragmove.carousel", function( e, data ){ + ok( false, "Should not execute without being triggered."); + }); + + setTimeout(function() { + ok( true ); + + $( "#el" ).unbind( "dragmove.carousel" ); + + start(); + }, 30); + }); + + asyncTest( '`.unbind("click", function)`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "click", f ) + .trigger( "click" ) + .unbind( "click", f ) + .trigger( "click" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`.unbind("mouseup mousedown", function) multiple dom events`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "mouseup", f ) + .bind( "mousedown", f ) + .unbind( "mouseup mousedown", f ) + .trigger( "mouseup" ) + .trigger( "mousedown" ); + + setTimeout(function() { + strictEqual( counter, 0, "callback should not have fired." ); + start(); + }, 30); + }); + + asyncTest( '`.unbind("aCustomEvent anotherCustomEvent", function)`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "aCustomEvent", f ) + .bind( "anotherCustomEvent", f ) + .unbind( "aCustomEvent anotherCustomEvent", f ) + .trigger( "aCustomEvent" ) + .trigger( "anotherCustomEvent" ); + + setTimeout(function() { + strictEqual( counter, 0, "callback should not have fired." ); + start(); + }, 30); + }); + + asyncTest( '`.unbind("click")`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "click", f ) + .trigger( "click" ) + .unbind( "click" ) + .trigger( "click" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`.unbind("aCustomEvent", function)`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "aCustomEvent", f ) + .trigger( "aCustomEvent" ) + .unbind( "aCustomEvent", f ) + .trigger( "aCustomEvent" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`.unbind("aCustomEvent")`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "aCustomEvent", f ) + .trigger( "aCustomEvent" ) + .unbind( "aCustomEvent" ) + .trigger( "aCustomEvent" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`.unbind()` all', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "aCustomEvent", f ) + .trigger( "aCustomEvent" ) + .unbind() + .trigger( "aCustomEvent" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`.unbind("aCustomEvent", function)` in a `.bind()` callback', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + $( this ).unbind( "aCustomEvent", f ); + }; + + $( "#el" ).bind( "aCustomEvent", f ) + .trigger( "aCustomEvent" ) + .trigger( "aCustomEvent" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`.unbind("eventThatDoesntExist", function)` doesn\'t throw error, does nothing', function() { + expect( 1 ); + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + $( "#el" ).unbind( "eventThatDoesntExist" ); + setTimeout(function() { + ok( true, "No error thrown, nothing happened" ); + start(); + }, 30); + + }); + + test( '`.one()` with multiple events (see #13)', function() { + var $fixture = shoestring( '#qunit-fixture' ), + triggerCount = 0, + $el; + + $fixture.html( '<div id="el"></div>' ); + $el = $( "#el" ); + + $el.one( "hover mousedown", function() { + triggerCount++; + }); + + $el.trigger( "hover" ); + $el.trigger( "mousedown" ); + + strictEqual( triggerCount, 1, 'only one event callback should execute.' ); + }); + + asyncTest( '`.one()` with multiple custom events', function() { + expect( 1 ); + var $fixture = shoestring( '#qunit-fixture' ), + triggerCount = 0, + $el; + + $fixture.html( '<div id="el"></div>' ); + $el = $( "#el" ); + + $el.one( "aCustomEvent anotherCustomEvent yetAnotherCustomEvent", function() { + triggerCount++; + }); + + $el.trigger( "aCustomEvent" ); + $el.trigger( "anotherCustomEvent" ); + + window.setTimeout(function() { + strictEqual( triggerCount, 1, 'only one event callback should execute.' ); + start(); + }, 15); + }); + + asyncTest( '`.bind()` bubbling event order', function() { + expect( 2 ); + + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="parent"><div id="child"></div></div>' ); + + $( '#parent' ).bind( "click", function() { + counter++; + equal( counter, 2, 'event callback should execute second.' ); + }); + + $( '#child' ).bind( "click", function() { + counter++; + equal( counter, 1, 'event callback should execute first.' ); + }).trigger( "click" ); + + setTimeout(function() { + start(); + }, 15); + }); + + + asyncTest( '`.bind()` bubbling custom event order (parent first)', function() { + expect( 2 ); + + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="parent"><div id="child"></div></div>' ); + + $( '#parent' ).bind( "aCustomEvent", function() { + counter++; + equal( counter, 2, 'parent event callback should execute second.' ); + }); + + $( '#child' ).bind( "aCustomEvent", function() { + counter++; + equal( counter, 1, 'child event callback should execute first.' ); + }).trigger( "aCustomEvent" ); + + setTimeout(function() { + start(); + }, 15); + }); + + asyncTest( '`.bind()` bubbling custom event order (child first)', function() { + expect( 2 ); + + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="parent"><div id="child"></div></div>' ); + + $( '#child' ).bind( "aCustomEvent", function() { + counter++; + equal( counter, 1, 'child event callback should execute first.' ); + }); + + $( '#parent' ).bind( "aCustomEvent", function() { + counter++; + equal( counter, 2, 'parent event callback should execute second.' ); + }); + + $( '#child' ).trigger( "aCustomEvent" ); + + setTimeout(function() { + start(); + }, 15); + }); + + asyncTest( 'trigger click executes a native click', function() { + var hash = location.hash; + + expect( 1 ); + shoestring( '#qunit-fixture' ).html( '<a href="#test" id="el">Link</a>' ); + + $( '#el' ).trigger( "click" ); + + setTimeout(function() { + notEqual( location.hash, hash, 'hash should have changed, link should have been clicked.' ); + + location.hash = ""; + start(); + }, 15); + }); + + asyncTest( 'preventDefault on dom event', function() { + var hash = location.hash; + + expect( 1 ); + shoestring( '#qunit-fixture' ).html( '<a href="#test" id="el">Link</a>' ); + + $( '#el' ).bind( "click", function( e ) { + e.preventDefault(); + }).trigger( "click" ); + + setTimeout(function() { + equal( location.hash, hash, 'hash should not have changed, event should preventDefault' ); + + location.hash = ""; + start(); + }, 15); + }); + + asyncTest( '`.isDefaultPrevented()`', function(){ + expect(1); + var fn = function(e){ + e.preventDefault(); + ok(e.isDefaultPrevented()); + }; + + shoestring( '#qunit-fixture' ).html( '<div id="preventdefault"></div>' ); + + $( "#preventdefault" ).bind( "click", fn ) + .trigger( "click" ); + + setTimeout(function() { + start(); + }, 15); + + }); + + asyncTest( '`.isDefaultPrevented()` without `.preventDefault()`', function(){ + expect(1); + var fn = function(e){ + ok(!e.isDefaultPrevented()); + }; + + shoestring( '#qunit-fixture' ).html( '<div id="preventdefault2"></div>' ); + + $( "#preventdefault2" ).bind( "click", fn ) + .trigger( "click" ); + + setTimeout(function() { + start(); + }, 15); + + }); + + asyncTest( 'return false prevents propagation', function() { + expect( 1 ) ; + + shoestring( '#qunit-fixture' ).html( '<div id="parent"><div id="child"></div></div>' ); + + $( "#child" ).one( "click", function() { + ok( true, "one runs" ); + + setTimeout(function() { + start(); + }); + + return false; + }); + + $( "#parent" ).one( "click", function() { + ok( false, "never runs" ); + }); + + $( "#child" ).trigger( "click" ); + }); + + asyncTest( 'stopPropagation prevents propagation', function() { + expect( 1 ) ; + + shoestring( '#qunit-fixture' ).html( '<div id="parent"><div id="child"></div></div>' ); + + $( "#child" ).one( "click", function(e) { + e.stopPropagation(); + ok( true, "one runs" ); + + setTimeout(function() { + start(); + }); + + }); + + $( "#parent" ).one( "click", function() { + ok( false, "never runs" ); + }); + + $( "#child" ).trigger( "click" ); + }); + + asyncTest( 'no stopPropagation allows propagation', function() { + expect( 2 ) ; + + shoestring( '#qunit-fixture' ).html( '<div id="parent"><div id="child"></div></div>' ); + + $( "#child" ).one( "click", function(e) { + ok( true, "one runs" ); + + setTimeout(function() { + start(); + }); + + }); + + $( "#parent" ).one( "click", function() { + ok( true, "also runs" ); + }); + + $( "#child" ).trigger( "click" ); + }); + + asyncTest( 'Custom Events: namespaced bind, namespaced trigger', function() { + expect( 2 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "customEvent.myNamespace", function( e ) { + ok( true, 'event callback should execute.' ); + ok( e.namespace, 'namespace property should exist.' ); + }) + .trigger( "customEvent.myNamespace" ); + + setTimeout(function() { + start(); + }, 15); + }); + + asyncTest( 'Custom Events: namespaced bind, unnamespaced trigger', function() { + expect( 2 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "customEvent.myNamespace", function( e ) { + ok( true, 'event callback should execute.' ); + ok( !e.namespace, 'namespace property should not exist.' ); + }) + .trigger( "customEvent" ); + + setTimeout(function() { + start(); + }, 15); + }); + + asyncTest( 'DOM Events: namespaced bind, namespaced trigger', function() { + expect( 2 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "click.myNamespace", function( e ) { + ok( true, 'event callback should execute.' ); + ok( e.namespace, 'namespace property should exist.' ); + }) + .trigger( "click.myNamespace" ); + + setTimeout(function() { + start(); + }, 15); + }); + + asyncTest( 'DOM Events: namespaced bind, unnamespaced trigger', function() { + expect( 2 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el2"></div>' ); + + $( "#el2" ).bind( "click.myNamespace", function( e ) { + ok( true, 'event callback should execute.' ); + ok( !e.namespace, 'namespace property should not exist.' ); + }) + .trigger( "click" ); + + setTimeout(function() { + start(); + }, 15); + }); + + asyncTest( 'DOM Events: unnamespaced bind, namespaced trigger', function() { + expect( 0 ); + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + + $( "#el" ).bind( "click", function( e ) { + ok( true, 'event callback should not execute.' ); + }).trigger( "click.myNamespace" ); + + setTimeout(function() { + start(); + }, 15); + }); + +asyncTest( '`Custom Events: .bind("myCustomEvent.myNamespace") .unbind("myCustomEvent.myNamespace")`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "myCustomEvent.myNamespace", f ) + .trigger( "myCustomEvent.myNamespace" ) + .unbind( "myCustomEvent.myNamespace" ) + .trigger( "myCustomEvent.myNamespace" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`Custom Events: .bind("myCustomEvent.myNamespace") .unbind("myCustomEvent.myNamespace", function)`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "myCustomEvent.myNamespace", f ) + .trigger( "myCustomEvent.myNamespace" ) + .unbind( "myCustomEvent.myNamespace", f ) + .trigger( "myCustomEvent.myNamespace" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`Custom Events: .bind("myCustomEvent.myNamespace") .unbind("myCustomEvent")`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "myCustomEvent.myNamespace", f ) + .trigger( "myCustomEvent.myNamespace" ) + .unbind( "myCustomEvent" ) + .trigger( "myCustomEvent.myNamespace" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`Custom Events: .bind("myCustomEvent") .unbind("myCustomEvent.myNamespace", function)`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "myCustomEvent", f ) + .trigger( "myCustomEvent" ) + .unbind( "myCustomEvent.myNamespace", f ) + .trigger( "myCustomEvent" ); + + setTimeout(function() { + equal( counter, 2, "callback should fire twice. unbind should have not matched anything." ); + start(); + }, 30); + }); + + asyncTest( '`DOM Events: .bind("click.myNamespace") .unbind("click.myNamespace")`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "click.myNamespace", f ) + .trigger( "click.myNamespace" ) + .unbind( "click.myNamespace" ) + .trigger( "click.myNamespace" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`DOM Events: .bind("click.myNamespace") .unbind("click.myNamespace", function)`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "click.myNamespace", f ) + .trigger( "click.myNamespace" ) + .unbind( "click.myNamespace", f ) + .trigger( "click.myNamespace" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`DOM Events: .bind("click.myNamespace") .unbind("click")`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "click.myNamespace", f ) + .trigger( "click.myNamespace" ) + .unbind( "click" ) + .trigger( "click.myNamespace" ); + + setTimeout(function() { + equal( counter, 1, "callback should have fired once." ); + start(); + }, 30); + }); + + asyncTest( '`DOM Events: .bind("click") .unbind("click.myNamespace", function)`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "click", f ) + .trigger( "click" ) + .unbind( "click.myNamespace", f ) + .trigger( "click" ); + + setTimeout(function() { + equal( counter, 2, "callback should fire twice. unbind should have not matched anything." ); + start(); + }, 30); + }); + + asyncTest( '`DOM Events: .unbind(".myNamespace")`', function() { + expect( 1 ); + var counter = 0; + + shoestring( '#qunit-fixture' ).html( '<div id="el"></div>' ); + var f = function() { + counter++; + }; + + $( "#el" ).bind( "click.myNamespace", f ) + .trigger( "click.myNamespace" ) + .unbind( ".myNamespace", f ) + .trigger( "click.myNamespace" ); + + setTimeout(function() { + equal( counter, 1, "callback should fire once." ); + start(); + }, 30); + }); + + if( window.JSON && 'localStorage' in window ) { + module( "util", config ); + + test( "when a shoestring.fn method is called it gets tracked", function() { + var tracked; + + window.localStorage.setItem( shoestring.trackedMethodsKey, "{}" ); + + $fixture.find( "div" ).remove(); + + tracked = JSON.parse( window.localStorage.getItem(shoestring.trackedMethodsKey) ); + + ok( tracked.find ); + ok( tracked.remove ); + }); + } + + module( 'ajax', config ); + + test( "ajax doesn't override default options", function() { + equal( shoestring.ajax.settings.method, "GET" ); + shoestring.ajax( "foo", { method: "POST" } ); + equal( shoestring.ajax.settings.method, "GET" ); + }); + + var mockXHR = function() { + var fakeXHR = sinon.useFakeXMLHttpRequest(); + var requests = sinon.requests = []; + + fakeXHR.onCreate = function ( request ) { + requests.push( request ); + }; + + return requests; + }; + + test( ".ajax throws exception with data and url with params", function(){ + mockXHR(); + + throws(function() { + shoestring.ajax( "/some/url?foo=bar", { + data: { bar: 'baz' } + }); + }); + }); + + test( ".ajax defaul headers", function(){ + var requests = mockXHR(); + + // call ajax method + shoestring.ajax( "/some/url", { success: function() {} }); + + equal(requests[0].requestHeaders['X-Requested-With'], "XMLHttpRequest"); + }); + + test( ".ajax includes headers", function(){ + var requests = mockXHR(); + + // call ajax method + shoestring.ajax( "/some/url", { + data: { param1: "one", param2: "two" }, + headers: { foo: 'bar' }, + success: function() {} + }); + + equal(requests[0].requestHeaders.foo, 'bar'); + }); + + test( ".ajax sends request with method GET and appends data elements to url", function(){ + var requests = mockXHR(); + var callback = sinon.spy(); + + // call ajax method + shoestring.ajax( "/some/url", { + data: { param1: "one", param2: "two" }, + success: callback + }); + + // check that only one request is sent + equal( sinon.requests.length, 1 ); + // check correct method is used + equal( sinon.requests[0].method, "GET" ); + // check that parameter string was appended to url + equal( sinon.requests[0].url, "/some/url?param1=one¶m2=two" ); + + // mock response to test callback + requests[0].respond( 200, { "Content-Type": "application/json" }, '{}' ); + // check that callback was called + ok( callback.called ); + }); + + test( ".post sends request with method POST, send data in request body", function(){ + var requests = mockXHR(); + + var url = "/some/url"; + var callback = sinon.spy(); + + // call post method + shoestring.post( url, { param1: "one", param2: "two" }, callback ); + + // check that only one request is sent + equal( sinon.requests.length, 1 ); + // check correct method is used + equal( sinon.requests[0].method, "POST" ); + // check that url has not been changed + equal( sinon.requests[0].url, url ); + // check data elements are sent in request body + equal( sinon.requests[0].requestBody, "param1=one¶m2=two" ); + // check that only one request is sent + ok( sinon.requests[0].requestHeaders['Content-type'].indexOf("application/x-www-form-urlencode") >= 0); + + requests[0].respond( 200, { "Content-Type": "application/json" }, '[]' ); + + ok( callback.called ); + }); +})();