fuelux
Version:
Base Fuel UX styles and controls
471 lines (432 loc) • 19.5 kB
JavaScript
/* global QUnit:false, module:false, test:false, asyncTest:false, expect:false */
/* global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false */
/* global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false */
define( function ( require ) {
var QUnit = require('qunit');
var $ = require( 'jquery' );
var html = require( 'text!test/markup/repeater-markup.html!strip' );
/* FOR DEV TESTING - uncomment to test against index.html */
// Html = require('text!index.html!strip');
// html = $('<div>'+html+'</div>').find('#MyRepeaterContainer');
require( 'bootstrap' );
require( 'fuelux/repeater' );
QUnit.module( 'Fuel UX Repeater', {
beforeEach: function setup( assert ) {
this.$markup = $( html );
this.$markup.find( '.repeater-views' ).append( '' +
'<label class="btn btn-default active">' +
'<input name="repeaterViews" type="radio" value="test1.view1">' +
'<span class="glyphicon glyphicon-asterisk"></span>' +
'</label>' +
'<label class="btn btn-default">' +
'<input name="repeaterViews" type="radio" value="test2.view2">' +
'<span class="glyphicon glyphicon-asterisk"></span>' +
'</label>' );
},
afterEach: function teardown( assert ) {
delete $.fn.repeater.viewTypes.test1;
}
} );
QUnit.test( 'should be defined on jquery object', function jqueryObject( assert ) {
assert.ok( $().repeater, 'repeater method is defined' );
} );
QUnit.test( 'should return element', function returnElement( assert ) {
var $repeater = $( this.$markup );
assert.ok( $repeater.repeater() === $repeater, 'repeater should be initialized' );
} );
QUnit.test( 'should call dataSource correctly', function callDatasource( assert ) {
var $repeater = $( this.$markup );
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
assert.ok( true, 'dataSource function called prior to rendering' );
assert.equal( typeof options, 'object', 'dataSource provided options object' );
assert.equal( typeof callback, 'function', 'dataSource provided callback function' );
callback( {} );
}
} );
} );
QUnit.test( 'should handle filtering correctly', function filtering( assert ) {
var hasCalledDS = false;
var $repeater = $( this.$markup );
var $filters = $repeater.find( '.repeater-filters' );
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
if ( hasCalledDS ) {
assert.ok( true, 'dataSource called again upon selecting different filter' );
assert.equal( options.filter.text, 'Some', 'filter text property correct on change' );
assert.equal( options.filter.value, 'some', 'filter value property correct on change' );
} else {
assert.equal( typeof options.filter, 'object', 'filter object passed to dataSource' );
assert.equal( options.filter.text, 'All', 'filter text property correct initially' );
assert.equal( options.filter.value, 'all', 'filter value property correct initially' );
callback( {} );
hasCalledDS = true;
$filters.find( 'button' ).click();
$filters.find( 'li:nth-child(2) a' ).click();
}
}
} );
} );
QUnit.test( 'should handle itemization correctly', function itemization( assert ) {
var hasCalledDS = false;
var $repeater = $( this.$markup );
var $pageSizes = $repeater.find( '.repeater-itemization .selectlist' );
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
if ( hasCalledDS ) {
assert.ok( true, 'dataSource called again upon selecting different page size' );
assert.equal( options.pageSize, 5, 'correct pageSize passed after change' );
} else {
assert.equal( options.pageIndex, 0, 'correct pageIndex passed to dataSource' );
assert.equal( options.pageSize, 10, 'correct pageSize passed to dataSource' );
callback( { count: 200, end: 10, start: 1 } );
assert.equal( $repeater.find( '.repeater-count' ).text(), '200', 'count set correctly' );
assert.equal( $repeater.find( '.repeater-end' ).text(), '10', 'end index set correctly' );
assert.equal( $repeater.find( '.repeater-start' ).text(), '1', 'start index set correctly' );
hasCalledDS = true;
$pageSizes.find( 'button' ).click();
$pageSizes.find( 'li:first a' ).click();
}
}
} );
} );
QUnit.test( 'should handle pagination correctly', function pagination( assert ) {
var count = -1;
var $repeater = $( this.$markup );
var $primaryPaging = $repeater.find( '.repeater-primaryPaging' );
var $secondaryPaging = $repeater.find( '.repeater-secondaryPaging' );
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
count++;
switch ( count ) {
case 0:
assert.equal( options.pageIndex, 0, 'correct pageIndex passed to dataSource' );
callback( { page: 0, pages: 2 } );
assert.equal( $primaryPaging.hasClass( 'active' ), true, 'primary paging has active class' );
assert.equal( $primaryPaging.find( 'input' ).val(), '1', 'primary paging displaying correct page' );
assert.equal( $primaryPaging.find( 'li' ).length, 2, 'primary paging has correct number of selectable items' );
$repeater.find( '.repeater-next' ).click();
break;
case 1:
assert.ok( true, 'dataSource called again upon clicking next button' );
assert.equal( options.pageIndex, 1, 'correct pageIndex passed to dataSource on next click' );
callback( { page: 1, pages: 6 } );
assert.equal( $secondaryPaging.hasClass( 'active' ), true, 'secondary paging has active class' );
assert.equal( $secondaryPaging.val(), '2', 'secondary paging displaying correct page' );
$repeater.find( '.repeater-prev' ).click();
break;
case 2:
assert.ok( true, 'dataSource called again upon clicking prev button' );
assert.equal( options.pageIndex, 0, 'correct pageIndex passed to dataSource on prev click' );
callback( {} );
break;
default:
break;
}
},
dropPagingCap: 3
} );
} );
QUnit.test( 'should handle search correctly', function search( assert ) {
var count = -1;
var $repeater = $( this.$markup );
var $search = $repeater.find( '.repeater-search' );
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
count++;
switch ( count ) {
case 0:
assert.equal( options.search, undefined, 'search value not passed to dataSource initially as expected' );
callback( {} );
$search.find( 'input' ).val( 'something' );
$search.trigger( 'searched.fu.repeater' );
break;
case 1:
assert.equal( options.search, 'something', 'correct search value passed to dataSource upon searching' );
callback( {} );
$search.find( 'input' ).val( '' );
$search.trigger( 'cleared.fu.repeater' );
break;
case 2:
assert.equal( options.search, undefined, 'search value not passed to dataSource after clearing' );
callback( {} );
break;
default:
break;
}
},
dropPagingCap: 3
} );
} );
QUnit.test( 'should handle canceling search correctly', function cancelSearch( assert ) {
var count = -1;
var $repeater = $( this.$markup );
var $search = $repeater.find( '.repeater-search' );
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
count++;
switch ( count ) {
case 0:
assert.equal( options.search, undefined, 'search value not passed to dataSource initially as expected' );
callback( {} );
$search.find( 'input' ).val( 'something' );
$search.trigger( 'searched.fu.repeater' );
break;
case 1:
assert.equal( options.search, 'something', 'correct search value passed to dataSource upon searching' );
callback( {} );
$search.find( 'input' ).val( '' );
$search.trigger( 'canceled.fu.repeater' );
break;
case 2:
assert.equal( options.search, undefined, 'search value not passed to dataSource after canceling' );
callback( {} );
break;
default:
break;
}
},
dropPagingCap: 3
} );
} );
QUnit.test( 'should handle views correctly', function views( assert ) {
var hasCalledDS = false;
var $repeater = $( this.$markup );
var $views = $repeater.find( '.repeater-views' );
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
if ( hasCalledDS ) {
assert.equal( options.view, 'test2.view2', 'correct view value passed to dataSource upon selecting different view' );
} else {
assert.equal( options.view, 'test1.view1', 'correct view value passed to dataSource initially' );
hasCalledDS = true;
callback( {} );
$views.find( 'label:last input' ).trigger( 'change' );
}
},
dropPagingCap: 3
} );
} );
QUnit.test( 'should run view plugin aspects correctly - pt 1', function viewTypes( assert ) {
var ran = 0;
var $repeater = $( this.$markup );
$.fn.repeater.viewTypes.test1 = {
initialize: function initialize( helpers, callback ) {
assert.equal( ran, 0, 'initialize function correctly ran first' );
assert.equal( typeof helpers, 'object', 'initialize function provided helpers object' );
assert.equal( typeof callback, 'function', 'initialize function provided callback function' );
ran++;
callback( {} );
},
selected: function selected( helpers ) {
assert.equal( ran, 1, 'selected function correctly ran upon view select' );
assert.equal( typeof helpers, 'object', 'selected function provided helpers object' );
ran++;
},
dataOptions: function dataOptions( options ) {
assert.equal( ran, 2, 'dataOptions function correctly ran prior to rendering' );
assert.equal( typeof options, 'object', 'dataOptions function provided options object' );
ran++;
return options;
},
before: function before( helpers ) {
assert.equal( ran, 3, 'before function ran before renderItems function' );
assert.equal( typeof helpers, 'object', 'before function provided helpers object' );
assert.equal( ( helpers.container.length > 0 && typeof helpers.data === 'object' ), true, 'helpers object contains appropriate attributes' );
ran++;
return { item: '<div class="test1-wrapper" data-container="true"></div>' };
},
renderItem: function renderItem( helpers ) {
assert.equal( ( ran > 3 ), true, 'renderItem function ran after before function' );
assert.equal( typeof helpers, 'object', 'renderItem function provided helpers object' );
assert.equal( ( helpers.container.length > 0 && typeof helpers.data === 'object' &&
typeof helpers.index === 'number' && typeof helpers.subset === 'object' ), true, 'helpers object contains appropriate attributes' );
assert.equal( helpers.container.hasClass( 'test1-wrapper' ), true, 'data-container="true" attribute functioning correctly' );
ran++;
return { item: '<div class="test1-item"></div>' };
},
after: function after( helpers ) {
assert.equal( ran, 7, 'after function ran after renderItems function' );
assert.equal( typeof helpers, 'object', 'after function provided helpers object' );
assert.equal( ( helpers.container.length > 0 && typeof helpers.data === 'object' ), true, 'helpers object contains appropriate attributes' );
return false;
},
repeat: 'data.smileys'
};
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
callback( { smileys: [ ':)', ':)', ':)' ] } );
}
} );
} );
QUnit.test( 'should run view plugin aspects correctly - pt 2', function viewTypes2( assert ) {
var $repeater = $( this.$markup );
$.fn.repeater.viewTypes.test1 = {
render: function render( helpers ) {
assert.equal( 1, 1, 'render function ran when defined' );
assert.equal( typeof helpers, 'object', 'render function provided helpers object' );
assert.equal( ( helpers.container.length > 0 && typeof helpers.data === 'object' ), true, 'helpers object contains appropriate attributes' );
},
resize: function resize( helpers ) {
assert.equal( 1, 1, 'resize function correctly ran when control is cleared' );
assert.equal( typeof helpers, 'object', 'resize function provided helpers object' );
},
cleared: function cleared( helpers ) {
assert.equal( 1, 1, 'cleared function correctly ran when control is cleared' );
assert.equal( typeof helpers, 'object', 'cleared function provided helpers object' );
}
};
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
callback( { smileys: [ ':)', ':)', ':)' ] } );
$repeater.repeater( 'resize' );
$repeater.repeater( 'clear' );
}
} );
} );
QUnit.test( 'views config option should function as expected', function configOption( assert ) {
var $repeater = $( this.$markup );
var $views = $repeater.find( '.repeater-views' );
$repeater.repeater( {
views: {
view1: {
dataSource: function dataSource( options, callback ) {
assert.equal( options.view, 'test1.view1', 'view-specific configuration honored' );
callback( {} );
$views.find( 'label:last input' ).trigger( 'change' );
}
},
'test2.view2': {
dataSource: function dataSource( options, callback ) {
assert.equal( options.view, 'test2.view2', 'view-specific configuration honored' );
callback( {} );
}
}
}
} );
} );
QUnit.test( 'should handle disable / enable correctly', function enableDisable( assert ) {
var $repeater = $( this.$markup );
var $search = $repeater.find( '.repeater-header .search' );
var $filters = $repeater.find( '.repeater-header .repeater-filters' );
var $views = $repeater.find( '.repeater-header .repeater-views label' );
var $pageSize = $repeater.find( '.repeater-footer .repeater-itemization .selectlist' );
var $primaryPaging = $repeater.find( '.repeater-footer .repeater-primaryPaging .combobox' );
var $secondaryPaging = $repeater.find( '.repeater-footer .repeater-secondaryPaging' );
var $prevBtn = $repeater.find( '.repeater-prev' );
var $nextBtn = $repeater.find( '.repeater-next' );
$repeater.on( 'disabled.fu.repeater', function disabled() {
assert.ok( true, 'disabled event called as expected' );
} );
$repeater.on( 'enabled.fu.repeater', function enabled() {
assert.ok( true, 'enabled event called as expected' );
} );
$repeater.on( 'rendered.fu.repeater', function rendered() {
setTimeout( function renderedTimeout() {
$repeater.repeater( 'disable' );
$views.click();
assert.equal( $search.hasClass( 'disabled' ), true, 'repeater search disabled as expected' );
assert.equal( $filters.hasClass( 'disabled' ), true, 'repeater filters disabled as expected' );
assert.equal( $views.attr( 'disabled' ), 'disabled', 'repeater views disabled as expected' );
assert.equal( $pageSize.hasClass( 'disabled' ), true, 'repeater pageSize disabled as expected' );
assert.equal( $primaryPaging.hasClass( 'disabled' ), true, 'repeater primaryPaging disabled as expected' );
assert.equal( $secondaryPaging.attr( 'disabled' ), 'disabled', 'repeater secondaryPaging disabled as expected' );
assert.equal( $prevBtn.attr( 'disabled' ), 'disabled', 'repeater prevBtn disabled as expected' );
assert.equal( $nextBtn.attr( 'disabled' ), 'disabled', 'repeater nextBtn disabled as expected' );
assert.equal( $repeater.hasClass( 'disabled' ), true, 'repeater has disabled class as expected' );
$repeater.repeater( 'enable' );
assert.equal( $search.hasClass( 'disabled' ), false, 'repeater search enabled as expected' );
assert.equal( $filters.hasClass( 'disabled' ), false, 'repeater filters enabled as expected' );
assert.equal( $views.attr( 'disabled' ), undefined, 'repeater views enabled as expected' );
assert.equal( $pageSize.hasClass( 'disabled' ), true, 'repeater pageSize disabled as expected' );
assert.equal( $primaryPaging.hasClass( 'disabled' ), false, 'repeater primaryPaging enabled as expected' );
assert.equal( $secondaryPaging.attr( 'disabled' ), undefined, 'repeater secondaryPaging enabled as expected' );
assert.equal( $prevBtn.attr( 'disabled' ), 'disabled', 'repeater prevBtn still disabled as expected (no more pages)' );
assert.equal( $nextBtn.attr( 'disabled' ), 'disabled', 'repeater nextBtn still disabled as expected (no more pages)' );
assert.equal( $repeater.hasClass( 'disabled' ), false, 'repeater no longer has disabled class as expected' );
}, 0 );
} );
$repeater.repeater();
} );
QUnit.test( 'rendered.fu.repeater callback should receive correct data when called by renderItems function', function dataSourceCallbackTest( assert ) {
var ready = assert.async();
var $repeater = $( this.$markup );
$repeater.on( 'rendered.fu.repeater', function rendered ( e, state ) {
// rendered is triggered on `this.$search` and `this.$element` in repeater.js
if ( e.target.id === $repeater.attr('id') ) {
assert.ok( state.data, 'data object exists' );
assert.equal( state.data.myVar, 'passalong', 'data returned from datasource was passed along' );
ready();
}
} );
$repeater.repeater( {
views: {
'test1.view1': {
dataSource: function dataSource( options, callback ) {
callback( { myVar: 'passalong' } );
}
}
}
} );
} );
QUnit.test( 'custom views render function should receive correct data when called by renderItems function', function dataSourceCallbackTest( assert ) {
var ready = assert.async();
var $repeater = $( this.$markup );
$.fn.repeater.viewTypes.test1 = {
render: function render ( state, callback ) {
assert.ok( state.data, 'data was passed to custom viewtype callback' );
assert.equal( state.data.myVar, 'passalong', 'data returned from datasource was passed along to custom viewtype callback' );
callback( state.data );
ready();
}
};
$repeater.repeater( {
views: {
'test1.view1': {
dataSource: function dataSource( options, callback ) {
callback( { myVar: 'passalong' } );
}
}
}
} );
} );
QUnit.test( 'resize should set height correctly when called inside hidden DOM object', function resize (assert) {
var ready = assert.async();
var $hiddenDiv = $('' +
'<div style="display:none">' +
' <div class="repeaterDiv"></div>' +
'</div>');
$('.fuelux').append($hiddenDiv);
$hiddenDiv.find('.repeaterDiv').append(this.$markup);
var $repeater = $( $hiddenDiv.find('.repeater'));
var $repeaterViewport = $( $repeater.find('.repeater-viewport'));
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
callback( { smileys: [ ':)', ':)', ':)' ] } );
$hiddenDiv.show();
$repeaterViewport.css('min-height', 0);
assert.notEqual($repeaterViewport.height(), 0, 'height set to non-zero value on resize');
$hiddenDiv.remove();
ready();
},
staticHeight:true
} );
} );
QUnit.test( 'should destroy control', function destroy( assert ) {
var ready = assert.async();
var $repeater = $( this.$markup );
var afterSource = function afterSource() {
setTimeout( function afterSourceTimeout() {
assert.equal( typeof $repeater.repeater( 'destroy' ), 'string', 'returns string (markup)' );
assert.equal( $repeater.parent().length, false, 'control has been removed from DOM' );
ready();
}, 0 );
};
$repeater.repeater( {
dataSource: function dataSource( options, callback ) {
callback( { smileys: [ ':)', ':)', ':)' ] } );
afterSource();
}
} );
} );
} );