UNPKG

ullamlaboriosam

Version:
1,756 lines (1,367 loc) 87.7 kB
var expect = chai.expect; // Whether or not to run the tests. When this is set to "false", then all of // the tests for this function should fail var work = true; var wrap = function(cb){ cb(); } // Check whether or not the element has a class // - cls: the classes that should be checked // - negate: whether or not the class should be present // - root: the element to check (defaults to "base") // hasClass('bla', true, 'ul') function hasClass(cls, negate, root) { root = root ? u(root) : base; u().args(cls).forEach(function(cl){ expect(root.hasClass(cl)).to.equal(!negate); }); return hasClass; } // Check that two objects are the same // same({ a: 'hi' }, { a: 'hi' }) function same(a, b) { expect(a).to.deep.equal(b); return isFn; } // Chech whether or not something is a function function isFn(fn) { expect(typeof fn).to.equal('function'); return isFn; } // Quickly test the size of a selector and returns itself for chaining: // size('.a', 2)('.b', 3)('.c', 1) function size(sel, number) { expect(u(sel).length).to.equal(number); return size; } // Get a great list of classes for testing different configurations function getListOfClasses(){ return [ // Strings { from: 'bla blu blo', it: 'a space-separated string' }, { from: 'bla,blu,blo,', it: 'a comma-separated string' }, { from: 'bla, blu, blo, ', it: 'a comma and space separated string' }, { from: 'bla\n\tblu\n\tblo\n\t', it: 'a whitespace-separated string' }, // Single array { from: ['bla', 'blu', 'blo'], it: 'an array' }, { from: ['bla blu ', 'blo '], it: 'a space-separated array' }, { from: ['bla,blu,', 'blo,'], it: 'a comma-separated array' }, { from: ['bla, blu, ', 'blo, '], it: 'a comma and space separated array' }, { from: ['bla\n\tblu\n\t', 'blo\n\t'], it: 'a whitespace-separated array' }, // Nested { from: [['bla', 'blu'], 'blo'], it: 'an array' }, { from: [['bla blu '], 'blo '], it: 'a space-separated array' }, { from: [['bla,blu,'], 'blo,'], it: 'a comma-separated array' }, { from: [['bla, blu, '], 'blo, '], it: 'a comma and space separated array' }, { from: [['bla\n\tblu\n\t'], 'blo\n\t'], it: 'a whitespace-separated array' }, ]; } // Testing the main file describe("u()", function() { it("should be defined", function() { expect(!!u).to.equal(true); }); it("should be a function", function() { expect(typeof u).to.equal("function"); }); it("can accept no argument", function() { expect(typeof u()).to.equal('object', typeof u()); expect(u().length).to.equal(0); }); it("can select by class", function() { expect(u('.demo').length).to.equal(1); }); it("can select by tag", function() { expect(u('body').length).to.equal(1); }); it("can select by id", function() { expect(u('#demo').length).to.equal(1); }); it("can select with css", function() { expect(u('[id="demo"]').length).to.equal(1); expect(u('.demo ul').length).to.equal(1); }); it("can select a NodeList", function() { expect(u(document.querySelectorAll('.demo li')).length).to.equal(3); }); it("can select an html element", function() { var object = u('.demo li').nodes[0]; expect(u(object).length).to.equal(1); }); it("won't select a function", function() { expect(u(function(){ return "test"; }).length).to.equal(0); }); it("will select a random object", function() { expect(u({ a: 'b', c: 'd' }).length).to.equal(1); }); it("can select an Umbrella instance", function() { var inst = u('.demo'); expect(u(inst).length).to.equal(1); expect(u(inst)).to.equal(inst); }); // it("accepts a function", function() { // expect(u(function(){}).first()).to.equal(false); // }); // // it("generates some html", function() { // expect(u(function(node, i){ // return "<li></li>"; }, 2).first()).to.equal('<li></li>'); // }); it("can use a context", function() { var context = u('.demo li').nodes[0]; expect(u('a', context).length).to.equal(1); }); it("can read the length", function() { expect(u('a').nodes.length).to.equal(u('a').length); }); describe("performance tests", function(){ function performance(callback, times){ var init = new Date().getTime(); for (var i = 0; i < times; i++) { callback(i); } return new Date().getTime() - init; } // Generate a big and varied 100 element table before(function(){ performance(function(i){ u('.performance').append('<tr class="ro"><td id="idn' + i + '"></td><td class="tabletest"></td><td></td><td></td></tr>'); }, 1000); }); after(function(){ u('.performance').remove(); }); it("simple select by class 10.000/second", function() { uTime = performance(function(){ u('.demo'); }, 1000); console.log(' - u: ' + uTime + 'ms'); expect(uTime).to.be.below(100, uTime + ' ms'); }); it("select by class is comparable to jquery (50% margin)", function() { size('.demo', 1); var uTime = performance(function(){ u('.demo'); }, 5000); var $Time = performance(function(){ $('.demo'); }, 5000); console.log(' - u: ' + uTime + 'ms $: ' + $Time + 'ms'); expect(uTime).to.be.below($Time * 1.5, uTime + ' ms'); }); it("vs jquery: class selector (50% margin)", function() { size('.tabletest', 1000); var uTime = performance(function(){ u('.tabletest'); }, 100); var $Time = performance(function(){ $('.tabletest'); }, 100); console.log(' - u: ' + uTime + 'ms $: ' + $Time + 'ms'); expect(uTime).to.be.below($Time * 1.5, uTime + ' ms'); }); it("vs jquery: complex selector (50% margin)", function() { size('table td:first-child', 1000); var uTime = performance(function(){ u('table td:first-child'); }, 50); var $Time = performance(function(){ $('table td:first-child'); }, 50); console.log(' - u: ' + uTime + 'ms $: ' + $Time + 'ms'); expect(uTime).to.be.below($Time * 1.5, uTime + ' ms'); }); it("vs jquery: jquery optimized vs raw umbrella (50% margin)", function() { size(".ro > *", 4000); var uTime = performance(function(){ u(".ro > *"); }, 50); var $Time = performance(function(){ $(".ro > *"); }, 50); console.log(' - u: ' + uTime + 'ms $: ' + $Time + 'ms'); expect(uTime).to.be.below($Time * 1.5, uTime + ' ms'); }); }); }); var listOfClasses = getListOfClasses(); describe(".addClass()", function() { beforeEach(function(){ base.removeClass('bla blu blo'); hasClass('bla blu blo', true); }); afterEach(function(){ base.removeClass('bla blu blo'); hasClass('bla blu blo', true); }); it("should be defined", function() { isFn(work ? base.addClass : false); }); it("can be called empty", function() { base.addClass(); base.addClass(""); base.addClass([]); base.addClass("",""); base.addClass(" "); if (!work) throw "Forced failure"; }); it("can be concatenated", function() { if (work) base.addClass('bla').addClass('blu'); hasClass('bla')('blu'); }); it("returns the same instance", function() { var inst = false; if (work) inst = base.addClass('bla,blu'); same(base, inst); }); it("adds a single class", function() { if (work) base.addClass('bla'); hasClass('bla'); }); describe("single argument", function(){ listOfClasses.forEach(function(part){ it("accepts " + part.it, function(){ if (work) base.addClass(part.from); hasClass('bla blu blo'); }); }); }); describe("single function argument uses the return value", function(){ listOfClasses.forEach(function(part){ it("accepts as a return value " + part.it, function(){ if (work) base.addClass(function() { return part.from; }); hasClass('bla blu blo'); }); }); }); describe("multiple functions uses the return value", function(){ function add(arg){ return function(){ return arg; }; } listOfClasses.forEach(function(part){ it("accepts as a return value " + part.it, function(){ if (work) base.addClass(add(part.from), add("bli")); hasClass('bla blu blo bli'); }); }); }); describe("several arguments", function(){ listOfClasses.filter(function(part){ return Array.isArray(part.from); }).forEach(function(part){ it("used .apply() with " + part.it, function(){ if (work) base.addClass.apply(base, part.from); hasClass('bla blu blo'); }); }); }); describe("callback uses the arguments", function(){ // Testing the main file function addTest(node, i){ return 'test' + i; } it("adds classes with callback", function(){ if (work) base.addClass(addTest); hasClass('test0'); base.removeClass('test0'); expect(base.hasClass('test0')).to.equal(false); }); it("adds many classes with callback", function(){ if (work) base.find('li').addClass(addTest); base.find('li').each(function(node, i){ hasClass('test' + i, false, node); u(node).removeClass('test' + i); }); }); }); }); // Testing the main file describe(".after(html)", function() { //var work = false; // Default callback for the tests function callback(cl){ return '<a class="bla ' + cl + '">Link</a>'; } beforeEach(function(){ expect(u('.bla').length).to.equal(0); }); afterEach(function(){ u('.bla').remove(); }); it("should be a function", function() { expect(work ? typeof base.after : false).to.equal('function'); }); it("can add content in the right place", function() { if (work) base.after('<a class="bla">Link</a>'); size('.bla', 1)('.base + .bla', 1); }); it("accepts a callback that will be called once", function(){ if (work) base.after(callback); size('.bla', 1)('.base + .bla', 1); }); it("accepts a single parameter", function(){ if (work) base.after(callback, ['a']); size('.base + .bla.a', 1); }); it("can add as many as the array", function(){ if (work) base.after(callback, ['a', 'b']); expect(base.html().match('function')).to.equal(null); size('.base ~ .bla', 2)('.base ~ .bla.a', 1)('.base ~ .bla.b', 1); size('.base + .bla.a + .bla.b', 1); }); }); // Testing the main file describe(".ajax(done, before)", function() { it("should be defined", function() { expect(typeof base.ajax).to.equal('function'); }); it("works even if empty", function() { // This is needed to make sure that the previous one is cleared setTimeout(function(){ u('form.login').ajax(); u('form.login').trigger('submit'); setTimeout(function(){ u('form.login').off('submit'); }, 100); }, 110); }); it("calls before", function(next) { setTimeout(function(){ u('form.login').ajax(function(err, body, xhr){ same(this.nodeName, 'FORM'); same(!!xhr, true); next(); }); u('form.login').trigger('submit'); // SetTimeout is needed not to interrupt te current event setTimeout(function(){ u('form.login').off('submit'); }, 100); }, 110); }); }); // Testing the main file describe(".append(html)", function() { // Default callback for the tests function callback(cl){ return '<a class="bla ' + cl + '">Link</a>'; } beforeEach(function(){ expect(u('.bla, .blu').length).to.equal(0); }); afterEach(function(){ // Just in case it stringifies the callback expect(base.html().match('function')).to.equal(null); u('.bla, .blu').remove(); }); it("should be a function", function() { expect(typeof base.append).to.equal('function'); }); it("can be called empty", function() { base.append(); }); it("can be called with empty string", function() { base.append(""); }); it("a function looping data has right footprint", function() { base.append(function(value, index, node, j){ if (['a', 'b'].indexOf(value) === -1) throw new Error("Not an element"); if (value === 'a') same(index, 0); if (value === 'b') same(index, 1); same(node, base.first()); same(j, 0) }, ['a', 'b']); }); it("a function looping a number has right footprint", function() { var iterations = 0; base.append(function(value, index, node, j){ if ([0, 1].indexOf(value) === -1) throw new Error("Not an element"); if (value === 0) same(index, 0); if (value === 1) same(index, 1); same(node, base.first()); same(j, 0); iterations++; }, 2); same(iterations, 2); }); // HTML describe("HTML string", function(){ it("can add a link", function() { base.append('<a class="bla">Link</a>'); size('.base > .bla', 1); }); it("can add sibling links", function() { base.append('<a class="bla">Link</a><a class="bla">Link</a>'); size('.base > .bla', 2); }); it("can add nested content", function() { base.append('<strong class="bla"><a>Link</a></strong>'); size('.base > .bla > a', 1); }); it("can append a table row", function() { u('table.tbl').append('<tr><td>Hi</td></tr>'); }); it("can add just text", function() { var frag = u('<div>').append('Hello world!\n'); same(frag.html(), 'Hello world!\n'); }); }); describe("HTML string looped with array", function(){ it("insert two links", function() { base.append('<a class="bla">Link</a>', ['a', 'b']); size('.base > .bla', 2)('.base > .bla:last-child', 1); }); it("can add nested content", function() { base.append('<strong class="bla"><a>Link</a></strong>', ['a', 'b']); size('.base > .bla > a', 2); }); it("can append simple text", function() { var frag = u('<div>').append('Hello!\n', ['a', 'b']); same(frag.html(), 'Hello!\nHello!\n'); }); }); // Callback describe("Callback", function(){ it("can add a link", function() { base.append(function(){ return '<a class="bla">Link</a>'; }); size('.base > .bla', 1)('.base > .bla:last-child', 1); }); it("can add sibling links", function() { base.append(function(){ return '<a class="bla">Link</a><a class="bla">Link</a>'; }); size('.base > .bla', 2)('.base > .bla:last-child', 1); }); it("can add nested content", function() { base.append(function(){ return '<strong class="bla"><a>Link</a></strong>'; }); size('.base > .bla > a', 1); }); it("can add just text", function() { var frag = u('<div>').append(function(){ return 'Hello world!\n'; }); same(frag.html(), 'Hello world!\n'); }); }); describe("Callback looped with array", function(){ it("can add sibling links", function() { base.append(function(v){ return '<a class="bla">Link</a>'; }, ['a', 'b']); size('.base > .bla', 2)('.base > .bla:last-child', 1); }); it("can add nested content", function() { base.append(function(){ return '<strong class="bla"><a>Link</a></strong>'; }, ['a', 'b']); size('.base > .bla > a', 2); }); it("can add just text", function() { var frag = u('<div>').append(function(){ return 'Hello world!\n'; }, ['a', 'b']); same(frag.html(), 'Hello world!\nHello world!\n'); }); it("can add content with a callback and data", function() { base.append(callback, ['a', 'b']); size('.base > .bla', 2)('.base > .bla.a', 1)('.base > .bla.b', 1); size('.bla.a + .bla.b', 1)('.bla.b + .bla.a', 0)('.base > .bla.b:last-child', 1); }); }); describe("Umbrella instance", function(){ it("Accepts a simple one", function(){ base.append(u('<div class="bla"></div>')); size('.base > .bla', 1)('.base > .bla:last-child', 1); }); it("Keeps the events when appending", function(done){ base.append(u('<div class="bla">').on('click', function(){ done(); })); size('.base > .bla', 1)('.base > .bla:last-child', 1); u('.base .bla').trigger('click'); }); it("Clones multiple events when appending", function(done){ base.append(u('<div class="bla">').on('click touch', function(){ done(); })); size('.base > .bla', 1)('.base > .bla:last-child', 1); u('.base .bla').trigger('touch'); }); }); it("can generate some text", function(){ var list = u("<div>"); if (work) list.append(function(n){ return n + "\n" }, ['a', 'b']); expect(list.children().length).to.equal(0); expect(list.html()).to.equal('a\nb\n'); }); it("can generate some text with number", function(){ var list = u("<div>"); if (work) list.append(function(n){ return n + "\n" }, 2); expect(list.children().length).to.equal(0); expect(list.html()).to.equal('0\n1\n'); }); it("isn't called any time with 0", function(){ u('<div>').append(function(n){ throw new Error("Shouldn't be called"); }, 0); }); // Node it("can append an html node", function() { base.append(u('<div class="bla">').first()); size('.bla', 1); }); it("should append supplied html to each targeted element and not only the last instance", function() { base.append(u('<span class="test-span"></span><span class="test-span"></span><span class="test-span"></span><span class="test-span"></span>')); base.append(u('<a class="append-me"></a>')); u(".test-span").append(u(".append-me")); size(".test-span .append-me", 4); }); }); describe(".args(arguments)", function() { it("should be defined", function() { expect(typeof u().args).to.equal('function'); }); it("accepts zero parameters", function(){ expect(u().args()).to.deep.equal([]); }); it("accepts falsy", function(){ expect(u().args(null)).to.deep.equal([]); expect(u().args(false)).to.deep.equal([]); expect(u().args(undefined)).to.deep.equal([]); expect(u().args("")).to.deep.equal([]); expect(u().args([])).to.deep.equal([]); }); it("doesn't accept two parameters", function(){ expect(u().args('a', 'b')).to.deep.equal(['a']); }); it("accepts an umbrella instance", function(){ expect(u().args(u(['a', 'b']))).to.deep.equal(['a', 'b']); expect(u().args(u(['a', 'b']).nodes)).to.deep.equal(['a', 'b']); }); describe("works with a single string", function(){ it("single string", function(){ expect(u().args('a')).to.deep.equal(['a']); }); it("splits a string with space", function(){ expect(u().args('a b ')).to.deep.equal(['a', 'b']); }); it("splits a string with comma", function(){ expect(u().args('a,b,')).to.deep.equal(['a', 'b']); }); it("splits a string with space and comma", function(){ expect(u().args('a, b, ')).to.deep.equal(['a', 'b']); }); it("splits a string with enter", function(){ expect(u().args('a\nb\t')).to.deep.equal(['a', 'b']); }); }); describe("works with different arrays", function(){ it("single element", function(){ expect(u().args(['a'])).to.deep.equal(['a']); }); it("single element", function(){ expect(u().args(['a', 'b', 'c'])).to.deep.equal(['a', 'b', 'c']); }); it("splits a string with space", function(){ expect(u().args(['a b', 'c d'])).to.deep.equal(['a', 'b', 'c', 'd']); }); it("splits a string with comma", function(){ expect(u().args(['a,b', 'c,d'])).to.deep.equal(['a', 'b', 'c', 'd']); }); it("splits a string with space and comma", function(){ expect(u().args(['a, b', 'c, d'])).to.deep.equal(['a', 'b', 'c', 'd']); }); it("splits a string with whitespaces", function(){ expect(u().args(['a\nb', 'c\td'])).to.deep.equal(['a', 'b', 'c', 'd']); }); }); describe("works with a function", function(){ it("single element", function(){ expect(u().args(['a'])).to.deep.equal(['a']); }); it("single element", function(){ expect(u().args(['a', 'b', 'c'])).to.deep.equal(['a', 'b', 'c']); }); it("splits a string with space", function(){ expect(u().args(['a b', 'c d'])).to.deep.equal(['a', 'b', 'c', 'd']); }); it("splits a string with comma", function(){ expect(u().args(['a,b', 'c,d'])).to.deep.equal(['a', 'b', 'c', 'd']); }); it("splits a string with space and comma", function(){ expect(u().args(['a, b', 'c, d'])).to.deep.equal(['a', 'b', 'c', 'd']); }); it("splits a string with whitespaces", function(){ expect(u().args(['a\nb', 'c\td'])).to.deep.equal(['a', 'b', 'c', 'd']); }); }); }); describe(".array()", function() { it("should be defined", function() { expect(typeof base.array).to.equal('function'); }); it("empty gives an error", function(){ same(base.array(), [base.html()]); }); it("can loop as each()", function() { u([0, 1, 2, 3]).array(function(node, i){ expect(node).to.equal(i); }); }); it("can loop a real element", function() { base.array(function(node, i){ expect(u(node).hasClass('base')).to.equal(true); expect(i).to.equal(0); }); }); it("can remove an element", function() { var final = u([1, 2, 3, 4]).array(function(node, i){ if (i !== 0) return node; }); expect(final.length).to.equal(3); }); it("can remove several elements", function() { var final = u([1, 2, 3, 4]).array(function(node, i){ if (i >= 3) return node; }); expect(final.length).to.equal(1); }); it("can add an element", function() { var final = u([1, 2, 3, 4]).array(function(node, i){ return i === 0 ? [node, 'a'] : node; }); expect(final.length).to.equal(5); }); it("can add an many elements", function() { var final = u([1, 2, 3, 4]).array(function(node, i){ return [node + 'a', node + 'b', node + 'c']; }); expect(final.length).to.equal(12); }); it("has the right this", function(){ u(['a', 'b']).array(function(node, i){ expect(this instanceof u).to.equal(true); }); }); it("returns a simple array", function(){ var ret = u(['a', 'b']).array(function(){}); expect(Array.isArray(ret)).to.equal(true); }); }); // Testing the main file describe(".attr(name, value)", function() { afterEach(function(){ base.first().removeAttribute('title'); expect(!base.attr('title')).to.equal(true); }); it("should be a function", function() { expect(typeof base.attr).to.equal('function'); }); it("can add an attribute with two params", function() { base.attr('title', 'Hello'); expect(base.attr('title')).to.equal('Hello'); }); it("can remove an attribute with two params", function() { base.attr('title', 'Hello').attr('title', ''); expect(base.attr('title')).to.equal(''); }); it("can add an attribute with an object", function() { base.attr({title: 'Hello'}); expect(base.attr('title')).to.equal('Hello'); }); it("can read the first element attribute", function() { base.first().setAttribute('title', 'Hello'); expect(base.attr('title')).to.equal('Hello'); }); it("can be called with no nodes", function() { expect(u('dfsdf').attr('title')).to.equal(''); }); }); // Testing the main file describe(".before(html)", function() { // Default callback for the tests function callback(cl){ return '<a class="bla ' + cl + '">Link</a>'; } beforeEach(function(){ expect(u('.bla').length).to.equal(0); }); afterEach(function(){ u('.bla').remove(); }); it("should be a function", function() { expect(typeof base.after).to.equal('function'); }); it("can add content in the right place", function() { base.before('<a class="bla">Link</a>'); expect(u('.bla').length).to.equal(1); expect(base.parent().find('.base, .bla').length).to.equal(2); expect(base.parent().find('.bla ~ .base').length).to.equal(1); }); it("second parameter defaults to ''", function(){ if (work) base.before(callback); expect(base.html().match('function')).to.equal(null); size('.bla', 1)('.bla + .base', 1); }); it("can add a single one", function(){ if (work) base.before(callback, ['a']); expect(base.html().match('function')).to.equal(null); size('.bla', 1)('.bla.a', 1)('.bla.a + .base', 1); }); it("can add as many as the array", function(){ if (work) base.before(callback, ['a', 'b']); expect(base.html().match('function')).to.equal(null); size('.bla', 2)('.bla.a', 1)('.bla.b', 1)('.bla.a + .bla.b + .base', 1); }); }); // Testing the main file describe(".children(selector)", function() { afterEach(function(){ // A previous bug that would change the inner of the original reference expect(base.length).to.equal(1); }); it("should be a function", function() { expect(typeof base.children).to.equal('function'); }); it("can select the children of ul", function() { expect(base.find('ul').children().length).to.equal(3); }); it("can filter the children", function() { expect(base.find('ul').children(':first-child').length).to.equal(1); }); it("okay with no children", function() { expect(base.find('ul').children('.nonexist').length).to.equal(0); }); }); // Testing the main file describe(".clone(options)", function() { afterEach(function(){ u('.container').remove(); }); describe("clone() nodes without events", function() { beforeEach(function() { base.append('<div class="container">\ <div class="testClone1">Hello</div>\ <div class="cloneDestination">Goodbye</div>\ </div>'); }); it("should be a function", function() { isFn(base.clone); }); it("should clone a single simple node", function() { u('.cloneDestination').append(u('.testClone1')); size('.container > .testClone1', 1); size('.cloneDestination > .testClone1', 1); size('.testClone1', 2); expect(u('.cloneDestination > .testClone1').text()).to.eq('Hello'); }); it("should clone nested nodes", function() { u('.testClone1').append('<div class="testClone2">Hi</div>'); size('.container > .testClone1 > .testClone2', 1); expect(u('.testClone2').text()).to.eq('Hi'); }); }); describe("clone() nodes with events", function() { beforeEach(function() { base.append('<div class="container">\ <div class="testClone1">Hello</div>\ <div class="testClone2">\ <div class="testCloneWithEvents1">\ click, touch, etc\ </div>\ </div>\ <div class="cloneDestination"></div>\ </div>'); }); it("should clone a node and its events by default", function(done) { u('<div>').on('click', function(e){ u(e.target).off('click'); done(); }).clone().trigger('click').trigger('click'); }); it("should clone nested nodes and their events by default", function(done) { u('.testCloneWithEvents1').on('click', function() { done(); }); u('.cloneDestination').append(u('.testClone2')); u('.cloneDestination > .testClone2 > .testCloneWithEvents1').trigger('click'); }); }); describe("clone() form elements", function() { before(function() { u('form.clone [type=text]').first().value = 'test input'; u('form.clone [type=checkbox]').first().checked = true; u('form.clone [type=radio]').first().checked = true; u('form.clone select').first().value = 'b'; u('form.clone textarea').first().value = 'test textarea'; }); afterEach(function(){ u('.destination').html(""); }); it("has the correct values initially", function(){ expect(u('form.clone [type=text]').first().value).to.equal('test input', 'beforeClone'); expect(u('form.clone [type=checkbox]').first().checked).to.equal(true, 'beforeClone'); expect(u('form.clone [type=radio]').first().checked).to.equal(true, 'beforeClone'); expect(u('form.clone select').first().value).to.equal('b', 'beforeClone'); expect(u('form.clone textarea').first().value).to.equal('test textarea', 'beforeClone'); }); it ("clones a full form correctly", function(){ u('.destination').append(u('form.clone')); expect(u('.destination [type=text]').length).to.equal(1); expect(u('.destination [type=text]').first().value).to.equal('test input'); expect(u('.destination [type=checkbox]').first().checked).to.equal(true); expect(u('.destination [type=radio]').first().checked).to.equal(true); expect(u('.destination select').first().value).to.equal('b'); expect(u('.destination textarea').first().value).to.equal('test textarea'); }); it ("should clone a text input and its value by default", function() { u('.destination').append(u('form.clone [type=text]')); expect(u('.destination [type=text]').first().value).to.eq('test input'); }); it ("should clone a checkbox input and its value by default", function() { u('.destination').append(u('form.clone [type=checkbox]')); expect(u('.destination [type=checkbox]').first().checked).to.eq(true); }); it ("should clone a radio input and its value by default", function() { u('.destination').append(u('form.clone [type=radio]')); expect(u('.destination [type=radio]').first().checked).to.eq(true); }); it ("should clone a textarea input and its value by default", function() { u('.destination').append(u('form.clone textarea')); expect(u('.destination textarea').first().value).to.eq('test textarea'); }); it ("should clone a select input and its value by default", function() { u('.destination').append(u('form.clone select')); expect(u('.destination select').first().value).to.eq('b'); }); }); describe(".clone() and node data attributes", function() { beforeEach(function() { base.append('<div class="container"><div class="testCloneData" data-foo="bar"></div><div class="destination"></div></div>'); }); it("should clone node data attributes", function() { u('.destination').append(u('.testCloneData')); expect(u('.destination .testCloneData').data('foo')).to.eq('bar'); }); }); }); // Testing the main file describe(".closest(selector)", function() { afterEach(function(){ // A previous bug that would change the inner of the original reference expect(base.length).to.equal(1); }); it("should be a function", function() { expect(typeof base.closest).to.equal('function'); }); it("can select the children of ul", function() { expect(base.find('li').closest('ul').length).to.equal(1); }); it("is okay with no ancestors", function() { expect(base.closest('.nonexist').length).to.equal(0); }); }); // Testing the main file describe(".data(name, value)", function() { it("should be a function", function() { expect(typeof base.data).to.equal('function'); }); it("can add an attribute with two params", function() { base.data('title', 'Hello'); expect(base.data('title')).to.equal('Hello'); base.first().removeAttribute('data-title'); expect(!base.data('title')).to.equal(true); }); it("can add an attribute with an object", function() { base.data({title: 'Hello'}); expect(base.data('title')).to.equal('Hello'); }); it("can read the first element attribute", function() { base.first().setAttribute('data-title', 'Hello'); expect(base.data('title')).to.equal('Hello'); }); it("can be called with no nodes", function() { expect(u('dfsdf').data('title')).to.equal(''); }); }); describe(".each(function(){})", function() { it("should be defined", function() { expect(typeof base.each).to.equal('function'); }); it("empty gives an error", function(done){ try { u([0, 1, 2]).each(); } catch (e) { return done(); } throw "Shouldn't get here"; }); it("can loop", function() { u([0, 1, 2, 3]).each(function(node, i){ expect(node).to.equal(i); }); u([3, 4, 5, 6]).each(function(node, i){ expect(node).to.equal(i + 3); }); }); it("can loop a real element", function() { base.each(function(node, i){ expect(u(node).hasClass('base')).to.equal(true); expect(i).to.equal(0); }); }); it("has the right this", function(){ u(['a', 'b']).each(function(node, i){ expect(this instanceof u).to.equal(true); }); }); it("returns an umbrella object", function(){ var ret = u(['a', 'b']).each(function(){}); expect(ret instanceof u).to.equal(true); }); }); describe(".eacharg([], function(){})", function() { it("should be defined", function() { expect(typeof base.each).to.equal('function'); }); it("no data, everything is is okay", function(){ base.eacharg(); base.eacharg(""); base.eacharg("", function(){}); base.eacharg(false); base.eacharg(false, function(){}); base.eacharg(undefined); base.eacharg(undefined, function(){}); base.eacharg(function(){ return false; }); base.eacharg(function(){ return false; }, function(){}); }); it("only first arguments gives an error", function(){ expect(base.eacharg.bind(base, ["a"])).to.throw(); }); it("has the right this", function(){ u(['a', 'b']).eacharg(['a'], function(node, arg){ expect(this instanceof u).to.equal(true); }); }); it("returns an umbrella object", function(){ var ret = u(['a', 'b']).eacharg(['a'], function(){}); expect(ret instanceof u).to.equal(true); }); // STRING describe('loops over an string', function(){ it("accepts commas as separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg('A,B,', function(node, arg){ expect(node + arg).to.equal(values.shift()); }); }); it("accepts space as separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg('A B ', function(node, arg){ expect(node + arg).to.equal(values.shift()); }); }); it("accepts commas and spaces as separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg('A, B, ', function(node, arg){ expect(node + arg).to.equal(values.shift()); }); }); it("accepts other whitespace as separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg('A\nB\n', function(node, arg){ expect(node + arg).to.equal(values.shift()); }); }); }); // ARRAY describe("loops over an array", function(){ it("accepts an array of elements", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(['A', 'B', ''], function(node, arg){ expect(node + arg).to.equal(values.shift()); }); }); it("accepts an array with space-separated elements", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(['A B '], function(node, arg){ expect(node + arg).to.equal(values.shift()); }); }); it("accepts an array with comma-separated elements", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(['A,B,'], function(node, arg){ expect(node + arg).to.equal(values.shift()); }); }); it("accepts an array with comma and space separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(['A, B, '], function(node, arg){ expect(node + arg).to.equal(values.shift()); }); }); it("accepts an array with other whitespace as separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(['A\nB\n'], function(node, arg){ expect(node + arg).to.equal(values.shift()); }); }); it("accepts an array with a combination", function() { var values = ['aA', 'aB', 'aC', 'bA', 'bB', 'bC']; u(['a', 'b']).eacharg(['A, B', 'C, '], function(node, arg){ expect(node + arg).to.equal(values.shift()); }); }); }); // FUNCTION describe("loops over a function return", function(){ var called = false; beforeEach(function(){ called = false; }); it("accepts commas as separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(function(){ return 'A,B,'; }, function(node, arg){ expect(node + arg).to.equal(values.shift()); called = true; }); expect(called).to.equal(true); }); it("accepts space as separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(function(){ return 'A B '; }, function(node, arg){ expect(node + arg).to.equal(values.shift()); called = true; }); expect(called).to.equal(true); }); it("accepts commas and spaces as separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(function(){ return 'A, B, '; }, function(node, arg){ expect(node + arg).to.equal(values.shift()); called = true; }); expect(called).to.equal(true); }); it("accepts other whitespace as separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(function(){ return 'A\nB\n'; }, function(node, arg){ expect(node + arg).to.equal(values.shift()); called = true; }); expect(called).to.equal(true); }); it("accepts an array of elements", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(function(){ return ['A', 'B', '']; }, function(node, arg){ expect(node + arg).to.equal(values.shift()); called = true; }); expect(called).to.equal(true); }); it("accepts an array with space-separated elements", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(function(){ return ['A B ']; }, function(node, arg){ expect(node + arg).to.equal(values.shift()); called = true; }); expect(called).to.equal(true); }); it("accepts an array with comma-separated elements", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(function(){ return ['A,B,']; }, function(node, arg){ expect(node + arg).to.equal(values.shift()); called = true; }); expect(called).to.equal(true); }); it("accepts an array with comma and space separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(function(){ return ['A, B, ']; }, function(node, arg){ expect(node + arg).to.equal(values.shift()); called = true; }); expect(called).to.equal(true); }); it("accepts an array with other whitespace as separation", function() { var values = ['aA', 'aB', 'bA', 'bB']; u(['a', 'b']).eacharg(function(){ return ['A\nB\n']; }, function(node, arg){ expect(node + arg).to.equal(values.shift()); called = true; }); expect(called).to.equal(true); }); it("accepts an array with a combination", function() { var values = ['aA', 'aB', 'aC', 'bA', 'bB', 'bC']; u(['a', 'b']).eacharg(function(){ return ['A, B', 'C, ']; }, function(node, arg){ expect(node + arg).to.equal(values.shift()); called = true; }); expect(called).to.equal(true); }); }); }); // Testing the main file describe(".empty()", function() { beforeEach(function() { base.append('\ <div class="empty-test"> \ <p></p> \ <p></p> \ </div> \ '); expect(u('.empty-test').length).to.equal(1); expect(u('.empty-test p').length).to.equal(2); }); afterEach(function() { u('.empty-test').remove(); }); it("should be defined", function() { expect(typeof base.empty).to.equal('function'); }); it("can be called even without any node", function() { expect(u('.empty-test div').length).to.equal(0); u('.empty-test div').empty(); }); it("will clean text-only nodes", function() { u('.empty-test').html('Hello world'); expect(u('.empty-test').html()).to.equal('Hello world'); u('.empty-test').empty(); expect(u('.empty-test').html()).to.equal(''); }); it("will clean mixed nodes", function() { u('.empty-test').html('Hello world!<p>How <strong>are you</strong>?</p>'); u('.empty-test').empty(); expect(u('.empty-test').html()).to.equal(''); }); it("should return an instance of umbrella with the empty nodes", function() { var result = u('.empty-test').empty(); expect(result).to.be.instanceof(u); expect(result.nodes).to.have.length(1); expect(result.attr('class')).to.equal('empty-test'); }); it("empty element", function() { u('.empty-test').empty(); expect(u('.empty-test p').length).to.equal(0); }); }); // Testing the main file describe(".filter(selector)", function() { it("should be defined", function() { expect(typeof base.filter).to.equal('function'); }); it("can be called empty", function() { base.filter(); base.filter(""); }); it("stays the same", function() { expect(base.filter('.base').length).to.equal(1); }); it("gets only one", function() { expect(base.find('a').filter('#world').length).to.equal(1); }); it("accepts a function", function() { expect(base.filter(function(){ return true; }).length).to.equal(1); expect(base.filter(function(){ return false; }).length).to.equal(0); }); it("accepts an object", function() { expect(base.filter(base).length).to.equal(1); expect(base.filter(u('.bla')).length).to.equal(0); }); it("returns the same if called empty", function() { expect(base.find('.not-test li').filter().length).to.equal(base.find('.not-test li').length); expect(base.find('.not-test li').filter('').length).to.equal(base.find('.not-test li').length); expect(base.find('.not-test li').filter(null).length).to.equal(base.find('.not-test li').length); expect(base.find('.not-test li').filter(undefined).length).to.equal(base.find('.not-test li').length); expect(base.find('.not-test li').filter(false).length).to.equal(base.find('.not-test li').length); }); }); // Testing the main file describe(".find(selector)", function() { it("should be a function", function() { expect(typeof base.find).to.equal('function'); }); it("can be empty and it selects all", function() { expect(base.find().length).to.equal(base.find('*').length); }); it("can select the list ul", function() { expect(base.find('ul').length).to.equal(1); }); it("cannot select body", function() { expect(base.find('body').length).to.equal(0); }); it("doesn't select duplicates", function(){ expect(u("*").find('.brand a').length).to.equal(1); }); }); // Testing the main file describe(".first()", function() { it("should be a function", function() { expect(typeof base.first).to.equal('function'); }); it("the first element is an HTML element", function() { expect(base.find("li").first().nodeType).to.equal(1); }); it("can get the first li and it's a LI", function() { expect(base.find("li").first().nodeName).to.equal('LI'); }); }); // Testing the main file describe("Function ajax(done, before)", function() { // Generate the url (allow for testing locally) function url(frag){ frag = frag || ''; var url = window.location.href; if (!/^http/.test(window.location.href)) { url = 'http://localhost:3000'; } if (/tests(\/)?$/.test(url)) { url = url.replace(/tests(\/)?/, ''); } return url.replace(/\/$/, '') + '/' + frag.replace(/^\//, ''); } function ifActive(cb){ return function(done){ ajax(url('/active'), {}, function(error, data){ if (!error && data === 'active') { cb(done); } else { u('.noserver').html("Note: there is no server running, so AJAX methods are not being tested"); console.log("- Server not active"); done(); } }); } }; it("should be a function", function() { isFn(ajax); }); it("can make a simple get", ifActive(function(done) { ajax(url('/plain'), {}, function(error, data, xhr){ expect(error).to.equal(null); expect(data).to.equal('GET'); expect(xhr instanceof XMLHttpRequest).to.equal(true, 'XMLHttpRequest'); done(); }, function(xhr){ expect(xhr instanceof XMLHttpRequest).to.equal(true, 'XMLHttpRequest'); }); })); it("can make a simple get", ifActive(function(done) { ajax(url('/plain'), {}, function(error, data, xhr){ expect(data).to.equal('GET'); expect(xhr instanceof XMLHttpRequest).to.equal(true, 'XMLHttpRequest'); done(); }); })); it("can send GET but data is lost", ifActive(function(done) { var body = { send: '123' }; var options = { method: 'GET', body: body }; ajax(url('/json'), options, function(error, data){ expect(data.method).to.equal('GET'); expect(data.body).to.deep.equal({}); done(); }); })); it("can send POST with data", ifActive(function(done) { var body = { send: '123' }; var options = { method: 'POST', body: body }; ajax(url('/json'), options, function(error, data){ expect(data.method).to.equal('POST'); expect(data.body).to.deep.equal(body); done(); }); })); it("can send PUT with data", ifActive(function(done) { var body = { send: '123' }; var options = { method: 'PUT', body: body }; ajax(url('/json'), options, function(error, data){ expect(data.method).to.equal('PUT'); expect(data.body).to.deep.equal(body); done(); }); })); it("can send DELETE", ifActive(function(done) { var options = { method: 'DELETE' }; ajax(url('/json'), options, function(error, data){ expect(data.method).to.equal('DELETE'); if (!window.mochaPhantomJS) { expect(data.body).to.deep.equal({}, "Body should be ignored"); } done(); }); })); }); describe("fn ajax()", function() { beforeEach(function() { this.xhr = sinon.useFakeXMLHttpRequest(); this.requests = []; this.xhr.onCreate = function(xhr) { this.requests.push(xhr); }.bind(this); }); afterEach(function() { this.xhr.restore(); }) it("should be a function", function() { expect(typeof ajax).to.equal('function'); }); it("should parameterize objects", function() { var body = {hello: 'world'}; ajax('#', {body: body, method: 'POST'}); expect(this.requests[0].requestBody).to.equal('hello=world'); }); it("should not parameterize FormData", function() { var body = new FormData(); ajax('#', {body: body, method: 'POST'}); expect(typeof this.requests[0].requestBody).to.equal('object'); }); }); // Testing the main file describe("parseJsom(string)", function() { it("should be defined", function() { expect(typeof parseJson).to.equal('function'); }); it("can be called empty", function() { expect(parseJson()).to.equal(false); expect(parseJson("")).to.equal(false); expect(parseJson([])).to.equal(false); expect(parseJson("","")).to.equal(false); expect(parseJson(" ")).to.equal(false); }); it("parses correctly", function() { expect(parseJson('{"hello": "world"}').hello).to.equal('world'); }); }); // Note: node._e['submit'] and other events will appear as [null] in PhantomJS // but they work as expected describe(".handle(event, fn)", function() { beforeEach(function(){ base.append('<div class="clickable"><a>Hi</a></div>'); }); afterEach(function(){ u('.clickable').remove(); base.off('click'); }); it("should be defined", function() { expect(typeof base.handle).to.equal('function'); }); it("triggers the event", function(done) { base.find('.clickable').handle('click', function(e){ expect(e.target).to.equal(this); done(); }); base.find('.clickable').trigger('click'); }); it("triggers the event twice", function(done) { var i = 1; base.find('.clickable').handle('click submit', function(e){ expect(e.target).to.equal(this); i++; if (i === 3) { done(); } }); base.find('.clickable').trigger('click'); base.find('.clickable').trigger('submit'); }); it("can do event delegation", function(done) { base.handle('click', '.clickable', function(e){ expect(e.target.className).to.equal('clickable'); done(); }); base.find('.clickable').trigger('click'); base.off('click'); }); it("event delegation not triggered by others", function() { base.handle('click', '.clickable', function(e){ throw new Error("Should never get here"); }); base.find('ul').not('.clickable').trigger('click'); base.off('click'); }); it("triggers the delegated event when child element is target", function(done) { base.handle('click', '.clickable', function(e) { expect(e.target.tagName).to.equal('A'); expect(e.target.className).to.not.equal('clickable'); done(); }); base.find('.clickable a').trigger('click'); }); it("triggers the event with custom data", function(done) { base.find('.clickable').handle('click', fun