Make tests more stable and independent(only part of them) by using deferred objects.

Stick to new Qunit syntax (without asyncTest and with explicit assert. prefix) instead of deprecated
This commit is contained in:
prijutme4ty 2015-03-01 03:41:27 +03:00
parent c17aa829e6
commit b1e733a29b
3 changed files with 1007 additions and 1004 deletions

File diff suppressed because it is too large Load Diff

View File

@ -41,14 +41,12 @@ EVENTS:
*/ */
$(function(){ $(function(){
module('Widgets'); module('Widgets', {
beforeEach: function(assert) {
var ts = $.tablesorter, this.ts = $.tablesorter;
callback = {},
callbackName = 'init',
// filter widget table // filter widget table
$table = $('#testblock').html('<table class="tablesorter">' + this.$table = $('#testblock').html('<table class="tablesorter">' +
'<thead><tr>' + '<thead><tr>' +
'<th class="rank">Rank</th>' + '<th class="rank">Rank</th>' +
'<th class="first filter-match">First Name</th>' + '<th class="first filter-match">First Name</th>' +
@ -72,277 +70,13 @@ $(function(){
'<tr><td>100</td><td>Brenda Dexter</td><td>McMasters</td><td>18</td><td>$55.20</td><td>15%</td><td>Feb 12, 2010 7:23 PM</td><td>McMasters</td></tr>' + '<tr><td>100</td><td>Brenda Dexter</td><td>McMasters</td><td>18</td><td>$55.20</td><td>15%</td><td>Feb 12, 2010 7:23 PM</td><td>McMasters</td></tr>' +
'<tr><td>55</td><td>Dennis</td><td>Bronson</td><td>65</td><td>$123.00</td><td>32%</td><td>Jan 20, 2001 1:12 PM</td><td>Bronson</td></tr>' + '<tr><td>55</td><td>Dennis</td><td>Bronson</td><td>65</td><td>$123.00</td><td>32%</td><td>Jan 20, 2001 1:12 PM</td><td>Bronson</td></tr>' +
'<tr><td>9</td><td>Martha</td><td>delFuego</td><td>25</td><td>$22.09</td><td>17%</td><td>Jun 11, 2011 10:55 AM</td><td>delFuego</td></tr>' + '<tr><td>9</td><td>Martha</td><td>delFuego</td><td>25</td><td>$22.09</td><td>17%</td><td>Jun 11, 2011 10:55 AM</td><td>delFuego</td></tr>' +
'</tbody></table>').find('table'), '</tbody></table>').find('table');
table = $table[0], this.table = this.$table[0];
this.init = false;
/************************************************ var self = this;
Filter widget var initTablesort = function(){
************************************************/ self.$table.tablesorter({
init = false,
runFilterTests = function(){
var c = table.config,
wo = c.widgetOptions;
test( 'Filter: init', function() {
expect(6);
equal( init, true, 'Init event' );
equal( $table.hasClass('hasFilters'), true, '`hasFilters` class applied' );
equal( ts.filter.regex.child.test( c.cssChildRow ), true, 'child row regex check' );
equal( ts.filter.regex.filtered.test( wo.filter_filteredRow ), true, 'filtered row regex check' );
// this includes check of headers option & referencing column by class
equal ( c.$table.find('.tablesorter-filter').eq(0).hasClass('disabled'), true, 'filter disabled & headers class name working' );
tester.cacheCompare( table, 3, [ 12, 18, 13, 18 ], 'starting filter value on age column', true );
});
asyncTest( 'Filter searches', function() {
expect(27);
callbackName = 'regular';
callback.regular = function(){
tester.cacheCompare( table, 1, ['Peter', 'Bruce', 'Alex', 'Bruce Lee', 'Brenda Dexter', 'Dennis'], 'search regular', true );
};
ts.setFilters( table, ['', 'e'], true );
stop();
callbackName = 'fuzzy1';
callback.fuzzy1 = function(){
tester.cacheCompare( table, 1, ['Bruce Lee', 'Brenda Dexter'], 'search fuzzy', true );
};
ts.setFilters( table, ['', '~bee'], true );
stop();
callbackName = 'fuzzy2';
callback.fuzzy2 = function(){
tester.cacheCompare( table, 1, ['Philip Aaron Wong'], 'search fuzzy2', true );
};
ts.setFilters( table, ['', '~piano'], true );
stop();
callbackName = 'exact';
callback.exact = function(){
tester.cacheCompare( table, 1, ['John'], 'search exact', true );
};
ts.setFilters( table, ['', 'john='], true );
stop();
callbackName = 'wildcard1';
callback.wildcard1 = function(){
tester.cacheCompare( table, 2, ['Dumass', 'Evans'], 'search wildcard, one character (?)', true );
};
ts.setFilters( table, ['', '', 'a?s'], true );
stop();
callbackName = 'wildcard2';
callback.wildcard2 = function(){
tester.cacheCompare( table, 2, ['Dumass', 'Evans', 'McMasters'], 'search wildcard, multiple characters (*)', true );
};
ts.setFilters( table, ['', '', 'a*s'], true );
stop();
callbackName = 'regex';
callback.regex = function(){
tester.cacheCompare( table, 1, ['Peter', 'Brenda Dexter'], 'search regex', true );
};
ts.setFilters( table, ['', '/r$/'], true );
stop();
callbackName = 'operator';
callback.operator = function(){
tester.cacheCompare( table, 4, [42.29, 19.99, 15.89, 153.19, 14.19, 13.19, 55.2, 123, 22.09], 'search operator (>10)', true );
};
ts.setFilters( table, ['', '', '', '', '>10'], true );
stop();
callbackName = 'operator1';
callback.operator1 = function(){
tester.cacheCompare( table, 4, [153.19, 123], 'search operator (>100); ensure search filtered gets cleared', true );
};
ts.setFilters( table, ['', '', '', '', '>100'], true );
stop();
callbackName = 'operator2';
callback.operator2 = function(){
tester.cacheCompare( table, 5, [22, 20, 25, 44, 44, 32], 'search operator (>=)', true );
};
ts.setFilters( table, ['', '', '', '', '', '>=20'], true );
stop();
callbackName = 'operator3';
callback.operator3 = function(){
tester.cacheCompare( table, 5, [5, 4], 'search operator (<10)', true );
};
ts.setFilters( table, ['', '', '', '', '', '<10'], true );
stop();
callbackName = 'operator4';
callback.operator4 = function(){
tester.cacheCompare( table, 5, [22, 5, 18, 20, 25, 44, 44, 4, 14, 11, 15, 32, 17], 'search operator (<100); ensure search filtered gets cleared', true );
};
ts.setFilters( table, ['', '', '', '', '', '<100'], true );
stop();
callbackName = 'operator5';
callback.operator5 = function(){
tester.cacheCompare( table, 5, [5, 18, 20, 4, 14, 11, 15, 17], 'search operator (<=)', true );
};
ts.setFilters( table, ['', '', '', '', '', '<=20'], true );
stop();
callbackName = 'notMatch';
callback.notMatch = function(){
tester.cacheCompare( table, 1, ['Peter', 'John', 'Bruce', 'Jim', 'Bruce Lee', 'Dennis'], 'search not match', true );
};
ts.setFilters( table, ['', '!a'], true );
stop();
callbackName = 'notMatch2';
callback.notMatch2 = function(){
tester.cacheCompare( table, 1, ['Brandon Clark', 'Peter', 'John', 'Clark', 'Bruce', 'Alex', 'Jim', 'Bruce Lee', 'Brenda Dexter', 'Dennis', 'Martha'], 'search not match; ensure search filtered gets cleared', true );
};
ts.setFilters( table, ['', '!aa'], true );
stop();
callbackName = 'operatorAnd';
callback.operatorAnd = function(){
tester.cacheCompare( table, 1, ['Brandon Clark', 'Bruce', 'Bruce Lee'], 'search and match', true );
};
ts.setFilters( table, ['', 'br && c'], true );
stop();
callbackName = 'operatorAnd2';
callback.operatorAnd2 = function(){
tester.cacheCompare( table, 1, ['Brandon Clark'], 'search and match; ensure search filtered gets cleared', true );
};
ts.setFilters( table, ['', 'br && cl'], true );
stop();
callbackName = 'operatorOr';
callback.operatorOr = function(){
tester.cacheCompare( table, 1, ['Brandon Clark', 'Bruce', 'Alex', 'Bruce Lee', 'Brenda Dexter'], 'search OR match', true );
};
ts.setFilters( table, ['', 'alex|br*'], true );
stop();
callbackName = 'range';
callback.range = function(){
tester.cacheCompare( table, 4, [5.95, 9.99, 5.29], 'search range', true );
};
ts.setFilters( table, ['', '', '', '', '5 - 10'], true );
stop();
callbackName = 'range2';
callback.range2 = function(){
tester.cacheCompare( table, 4, [5.95, 42.29, 9.99, 19.99, 15.89, 5.29, 14.19, 13.19, 55.2, 22.09], 'search range; ensure search filtered gets cleared', true );
};
ts.setFilters( table, ['', '', '', '', '5 - 100'], true );
stop();
// test filter_startsWith (false by default)
wo.filter_startsWith = false;
callbackName = 'startsWith';
callback.startsWith = function(){
tester.cacheCompare( table, 1, ['Philip Aaron Wong', 'Aaron'], 'search - filter_startsWith : false', true );
};
ts.setFilters( table, ['', 'aa'], true );
stop();
// test filter_startsWith (false by default)
wo.filter_startsWith = true;
callbackName = 'startsWith2';
callback.startsWith2 = function(){
tester.cacheCompare( table, 1, ['Aaron'], 'search - filter_startsWith : true', true );
wo.filter_startsWith = false;
};
c.$table.trigger('search', false);
stop();
// test filter_ignoreCase (true by default)
wo.filter_ignoreCase = false;
callbackName = 'ignoreCase1';
callback.ignoreCase1 = function(){
tester.cacheCompare( table, 1, [], 'search - filter_ignoreCase : false', true );
wo.filter_ignoreCase = true;
};
c.$table.trigger('search', false);
stop();
// test filter-match class (added in the example code)
callbackName = 'filterMatch';
callback.filterMatch = function(){
tester.cacheCompare( table, 1, ['Brandon Clark', 'Clark', 'Bruce', 'Alex', 'Bruce Lee', 'Brenda Dexter'], 'search - filter-match', true );
};
ts.setFilters( table, ['', 'alex|br*|c'], true );
stop();
// test filter-match class
c.$table.find('.tablesorter-header').eq(1).removeClass('filter-match');
callbackName = 'notFilterMatch';
callback.notFilterMatch = function(){
tester.cacheCompare( table, 1, ['Bruce', 'Alex'], 'search - filter-match removed', true );
};
c.$table.trigger('search', false);
stop();
// filter reset
callbackName = 'filterReset';
callback.filterReset = function(){
tester.cacheCompare( table, 5, [22, 5, 18, 20, 25, 44, 44, 4, 14, 11, 15, 32, 17], 'filterReset', true );
};
c.$table.trigger('filterReset');
stop();
// filter parsed class
wo.filter_startsWith = false;
callbackName = 'filterParsed';
callback.filterParsed = function(){
tester.cacheCompare( table, 6, [ new Date('Oct 13, 2000 1:15 PM').getTime() ], 'search - filter-parsed', true );
};
ts.setFilters( table, ['', '', '', '', '', '', '< 1/1/2001'], true );
});
test( 'Filter: function & selectSource', function() {
expect(3);
var $t, opts = [];
$t = c.$table.find('.tablesorter-filter-row select:last');
equal ( $t.length !== 0, true, 'filter_functions: true working' );
c.$table.find('.tablesorter-filter-row select:first option').each(function(){
opts.push( $.trim( $(this).text() ) );
});
equal ( opts.length === 3 && opts.join('') === '< 10> 10', true, 'filter_functions set' );
opts = [];
$t.find('option').each(function(){
opts.push( $.trim( $(this).text() ) );
});
equal ( opts.length === 4 && opts.join('') === 'abcdefzyx', true, 'filter_selectSource set' );
});
$table.on('filterEnd', function(){
start();
if (callbackName !== '' && callback[callbackName]) {
callback[callbackName]();
}
callbackName = '';
});
};
$table
.on('filterInit', function(){
init = true;
runFilterTests();
})
.tablesorter({
ignoreCase: false, ignoreCase: false,
widgets: ['zebra', 'filter'], widgets: ['zebra', 'filter'],
headers: { headers: {
@ -365,5 +99,185 @@ $(function(){
} }
} }
}); });
};
var onEventCallback = function(){
self.init = true;
self.c = self.table.config,
self.wo = self.c.widgetOptions;
};
return QUnit.SequentialRunner().next(
QUnit.assertOnEvent(
self.$table,
'filterInit',
initTablesort,
onEventCallback
)
).promise();
},
afterEach: function(assert) {
var done = assert.async();
this.$table.trigger('destroy', [false, done]);
}
});
/************************************************
Filter widget
************************************************/
QUnit.test( 'Filter: init', function(assert) {
expect(6);
assert.equal( this.init, true, 'Init event' );
assert.equal( this.$table.hasClass('hasFilters'), true, '`hasFilters` class applied' );
assert.equal( this.ts.filter.regex.child.test( this.c.cssChildRow ), true, 'child row regex check' );
assert.equal( this.ts.filter.regex.filtered.test( this.wo.filter_filteredRow ), true, 'filtered row regex check' );
// this includes check of headers option & referencing column by class
assert.equal ( this.c.$table.find('.tablesorter-filter').eq(0).hasClass('disabled'), true, 'filter disabled & headers class name working' );
assert.cacheCompare( this.table, 3, [ 12, 18, 13, 18 ], 'starting filter value on age column', true );
});
QUnit.test( 'Filter searches', function(assert) {
var ts = this.ts,
c = this.c,
wo = this.wo,
$table = this.$table,
table = this.table;
expect(27);
return QUnit.SequentialRunner(
function(actions, assertions) {
return QUnit.assertOnEvent($table, 'filterEnd', actions, assertions);
}
).nextTask(
function(){ ts.setFilters( table, ['', 'e'], true ); },
function(){ assert.cacheCompare( table, 1, ['Peter', 'Bruce', 'Alex', 'Bruce Lee', 'Brenda Dexter', 'Dennis'], 'search regular', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '~bee'], true ); },
function(){ assert.cacheCompare( table, 1, ['Bruce Lee', 'Brenda Dexter'], 'search fuzzy', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '~piano'], true ); },
function(){ assert.cacheCompare( table, 1, ['Philip Aaron Wong'], 'search fuzzy2', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', 'john='], true ); },
function(){ assert.cacheCompare( table, 1, ['John'], 'search exact', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '', 'a?s'], true ); },
function(){ assert.cacheCompare( table, 2, ['Dumass', 'Evans'], 'search wildcard, one character (?)', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '', 'a*s'], true ); },
function(){ assert.cacheCompare( table, 2, ['Dumass', 'Evans', 'McMasters'], 'search wildcard, multiple characters (*)', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '/r$/'], true ); },
function(){ assert.cacheCompare( table, 1, ['Peter', 'Brenda Dexter'], 'search regex', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '', '', '', '>10'], true ); },
function(){ assert.cacheCompare( table, 4, [42.29, 19.99, 15.89, 153.19, 14.19, 13.19, 55.2, 123, 22.09], 'search operator (>10)', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '', '', '', '>100'], true ); },
function(){ assert.cacheCompare( table, 4, [153.19, 123], 'search operator (>100); ensure search filtered gets cleared', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '', '', '', '', '>=20'], true ); },
function(){ assert.cacheCompare( table, 5, [22, 20, 25, 44, 44, 32], 'search operator (>=)', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '', '', '', '', '<10'], true ); },
function(){ assert.cacheCompare( table, 5, [5, 4], 'search operator (<10)', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '', '', '', '', '<100'], true ); },
function(){ assert.cacheCompare( table, 5, [22, 5, 18, 20, 25, 44, 44, 4, 14, 11, 15, 32, 17], 'search operator (<100); ensure search filtered gets cleared', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '', '', '', '', '<=20'], true ); },
function(){ assert.cacheCompare( table, 5, [5, 18, 20, 4, 14, 11, 15, 17], 'search operator (<=)', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '!a'], true ); },
function(){ assert.cacheCompare( table, 1, ['Peter', 'John', 'Bruce', 'Jim', 'Bruce Lee', 'Dennis'], 'search not match', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '!aa'], true ); },
function(){ assert.cacheCompare( table, 1, ['Brandon Clark', 'Peter', 'John', 'Clark', 'Bruce', 'Alex', 'Jim', 'Bruce Lee', 'Brenda Dexter', 'Dennis', 'Martha'], 'search not match; ensure search filtered gets cleared', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', 'br && c'], true ); },
function(){ assert.cacheCompare( table, 1, ['Brandon Clark', 'Bruce', 'Bruce Lee'], 'search and match', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', 'br && cl'], true ); },
function(){ assert.cacheCompare( table, 1, ['Brandon Clark'], 'search and match; ensure search filtered gets cleared', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', 'alex|br*'], true ); },
function(){ assert.cacheCompare( table, 1, ['Brandon Clark', 'Bruce', 'Alex', 'Bruce Lee', 'Brenda Dexter'], 'search OR match', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '', '', '', '5 - 10'], true ); },
function(){ assert.cacheCompare( table, 4, [5.95, 9.99, 5.29], 'search range', true ); }
).nextTask(
function(){ ts.setFilters( table, ['', '', '', '', '5 - 100'], true ); },
function(){ assert.cacheCompare( table, 4, [5.95, 42.29, 9.99, 19.99, 15.89, 5.29, 14.19, 13.19, 55.2, 22.09], 'search range; ensure search filtered gets cleared', true ); }
).nextTask( // test filter_startsWith (false by default)
function(){
wo.filter_startsWith = false;
ts.setFilters( table, ['', 'aa'], true );
},
function(){ assert.cacheCompare( table, 1, ['Philip Aaron Wong', 'Aaron'], 'search - filter_startsWith : false', true ); }
).nextTask( // test filter_startsWith (false by default)
function(){
wo.filter_startsWith = true;
c.$table.trigger('search', false);
},
function(){
assert.cacheCompare( table, 1, ['Aaron'], 'search - filter_startsWith : true', true );
wo.filter_startsWith = false;
}
).nextTask( // test filter_ignoreCase (true by default)
function(){
wo.filter_ignoreCase = false;
c.$table.trigger('search', false);
},
function(){
assert.cacheCompare( table, 1, [], 'search - filter_ignoreCase : false', true );
wo.filter_ignoreCase = true;
}
).nextTask( // test filter-match class (added in the example code)
function(){ ts.setFilters( table, ['', 'alex|br*|c'], true ); },
function(){ assert.cacheCompare( table, 1, ['Brandon Clark', 'Clark', 'Bruce', 'Alex', 'Bruce Lee', 'Brenda Dexter'], 'search - filter-match', true ); }
).nextTask( // test filter-match class
function(){
c.$table.find('.tablesorter-header').eq(1).removeClass('filter-match');
c.$table.trigger('search', false);
},
function(){ assert.cacheCompare( table, 1, ['Bruce', 'Alex'], 'search - filter-match removed', true ); }
).nextTask( // filter reset
function(){ c.$table.trigger('filterReset'); },
function(){ assert.cacheCompare( table, 5, [22, 5, 18, 20, 25, 44, 44, 4, 14, 11, 15, 32, 17], 'filterReset', true ); }
).nextTask( // filter parsed class
function(){
wo.filter_startsWith = false;
ts.setFilters( table, ['', '', '', '', '', '', '< 1/1/2001'], true );
},
function(){ assert.cacheCompare( table, 6, [ new Date('Oct 13, 2000 1:15 PM').getTime() ], 'search - filter-parsed', true ); }
).promise();
});
QUnit.test( 'Filter: function & selectSource', function(assert) {
expect(3);
var $t, opts = [];
$t = this.c.$table.find('.tablesorter-filter-row select:last');
assert.equal ( $t.length !== 0, true, 'filter_functions: true working' );
this.c.$table.find('.tablesorter-filter-row select:first option').each(function(){
opts.push( $.trim( $(this).text() ) );
});
assert.equal ( opts.length === 3 && opts.join('') === '< 10> 10', true, 'filter_functions set' );
opts = [];
$t.find('option').each(function(){
opts.push( $.trim( $(this).text() ) );
});
assert.equal ( opts.length === 4 && opts.join('') === 'abcdefzyx', true, 'filter_selectSource set' );
});
}); });

View File

@ -11,7 +11,7 @@
http://stackoverflow.com/q/13748129/145346 http://stackoverflow.com/q/13748129/145346
************************************************/ ************************************************/
QUnit.testSkip = function( testName, callback ) { QUnit.testSkip = function( testName, callback ) {
QUnit.test(testName + ' (SKIPPED)', function() { QUnit.test(testName + ' (SKIPPED)', function(assert) {
if (typeof callback === "function") { if (typeof callback === "function") {
callback(); callback();
} }
@ -22,8 +22,94 @@ QUnit.testSkip = function( testName, callback ) {
}); });
}; };
var tester = { // Accepts a function with a single argument -- deferred object, which should be resolved at some point in a function.
// Returns a promise, wrapping this function call.
QUnit.deferredCallback = function(func) {
return function(){
var defer = $.Deferred();
func(defer);
return defer.promise();
};
};
// SequentialRunner is an object to build and run a list of asynchronous calls in a sequential way.
// It wraps a deferred object; initially it's resolved, but .next and .nextTask calls add runners to be invoked.
// Underlying promise can be obtained by .promise() call.
// Each runner should accept deferred object and resolve it at some point when it's safe to invoke the next runner.
//
// Its constructor has an optional argument runnerCreator -- function which accepts task arguments
// and returns a runner (i.e. another function). If runnerCreator supplied, SequentialRunner object gets
// an additional method #nextTask(<task arguments>...) that is useful when you run lots of similar tasks.
//
// Example:
//
// QUnit.SequentialRunner(function(buttonSelector){
// return function(defer){ // each task is to wait until specified button is clicked
// $(buttonSelector).click(function(){
// defer.resolve()
// })
// };
// })
// .nextTask('#login').nextTask('#demo').nextTask('button')
// .promise()
// .then(function(){ console.log('Login, demo and any other button were clicked in that order.') });
//
QUnit.SequentialRunner = function(runnerCreator){
var result = {
defer: $.Deferred().resolve(),
promise: function(){
return this.defer.promise();
},
next: function(runner) {
this.defer = this.defer.then( QUnit.deferredCallback(runner) );
return this;
},
};
if (runnerCreator) {
result.nextTask = function(args) { // any argument list
var deferredRunner = QUnit.deferredCallback( runnerCreator.apply(this, arguments) );
this.defer = this.defer.then(deferredRunner);
return this;
};
}
return result;
};
// Returns an runner which runs some actions and wait for an event to be triggered.
// When an event is triggered assertions block is called and defer is resolved (independent on assertion result).
// This runner is useful when you want to check some conditions which should be met after an event was triggered.
//
// Example:
// QUnit.test('tablesorter initialization', function(assert){
// return QUnit.SequentialRunner()
// .next(
// QUnit.assertOnEvent(
// $('table'),
// 'tablesorter-initialized',
// function() {
// $('table').tablesorter( {sortList: [[0,0]]} );
// },
// function() {
// QUnit.assert.deepEqual($('table')[0].config.sortList, [[0,0]], 'sortList should be present in config');
// }
// )
// ).promise();
// });
//
QUnit.assertOnEvent = function($element, eventType, actions, assertions) {
return function(defer){
$element
.off(eventType)
.on(eventType, function() {
$element.off(eventType);
assertions();
defer && defer.resolve();
});
actions();
};
};
QUnit.extend(QUnit.assert, {
/************************************************ /************************************************
test table data cache test table data cache
************************************************/ ************************************************/
@ -50,10 +136,9 @@ var tester = {
} }
} }
} }
deepEqual( result, expected, 'testing parser cache: ' + txt); QUnit.assert.deepEqual( result, expected, 'testing parser cache: ' + txt);
} }
});
};
/* /*
Core plugin tested Core plugin tested
@ -164,11 +249,11 @@ $(function(){
/************************************************ /************************************************
Initialization Initialization
************************************************/ ************************************************/
test( "tablesorter loaded & initialized", function() { QUnit.test( "tablesorter loaded & initialized", function(assert) {
expect(3); assert.expect(3);
equal( typeof ts, 'object', "tablesorter loaded"); assert.equal( typeof ts, 'object', "tablesorter loaded");
equal( table1.hasInitialized, true, "tablesorter initialized flag"); assert.equal( table1.hasInitialized, true, "tablesorter initialized flag");
equal( init, true, "tablesorter initialized event"); assert.equal( init, true, "tablesorter initialized event");
}); });
c1 = table1.config; c1 = table1.config;
@ -180,24 +265,24 @@ $(function(){
Test column numbering Test column numbering
************************************************/ ************************************************/
// later: include a table header with colspan & rowspan // later: include a table header with colspan & rowspan
test( "column numbering", function() { QUnit.test( "column numbering", function(assert) {
expect(2); assert.expect(2);
var internalColumn = true, var internalColumn = true,
dataColumn = true; dataColumn = true;
$table4.find('thead th').each(function(i){ $table4.find('thead th').each(function(i){
internalColumn = internalColumn && this.column === i; internalColumn = internalColumn && this.column === i;
dataColumn = dataColumn && $(this).attr('data-column') == i; dataColumn = dataColumn && $(this).attr('data-column') == i;
}); });
equal( internalColumn, true, "Correct internal column numbering" ); assert.equal( internalColumn, true, "Correct internal column numbering" );
equal( dataColumn, true, "Correct data-column attribute numbering" ); assert.equal( dataColumn, true, "Correct data-column attribute numbering" );
}); });
/************************************************ /************************************************
check isDigit function check isDigit function
************************************************/ ************************************************/
var d = ts.isDigit; var d = ts.isDigit;
test( "isDigit", function() { QUnit.test( "isDigit", function(assert) {
expect(17); assert.expect(17);
ok( d('-1'), "allow negative (-1)"); ok( d('-1'), "allow negative (-1)");
ok( d('+1'), "allow plus (+1)"); ok( d('+1'), "allow plus (+1)");
ok( d('(1)'), "allow parenthesis (1)"); ok( d('(1)'), "allow parenthesis (1)");
@ -223,32 +308,32 @@ $(function(){
var ff = function(str) { var ff = function(str) {
return ts.formatFloat(str, table1); return ts.formatFloat(str, table1);
}; };
test( "formatFloat", function() { QUnit.test( "formatFloat", function(assert) {
expect(18); assert.expect(18);
strictEqual( ff(''), '', 'returns empty string' ); assert.strictEqual( ff(''), '', 'returns empty string' );
strictEqual( ff(5), 5, 'returns numerical values'); assert.strictEqual( ff(5), 5, 'returns numerical values');
c1.usNumberFormat = false; c1.usNumberFormat = false;
strictEqual( ts.formatFloat('1,234,567.89'), 1234567.89, 'use format float without including table - defaults to US number format'); assert.strictEqual( ts.formatFloat('1,234,567.89'), 1234567.89, 'use format float without including table - defaults to US number format');
strictEqual( ff('1 234,56'), 1234.56, 'parse non-U.S. (French) number format'); assert.strictEqual( ff('1 234,56'), 1234.56, 'parse non-U.S. (French) number format');
strictEqual( ff('1.234,56'), 1234.56, 'parse non-U.S. (German) number format'); assert.strictEqual( ff('1.234,56'), 1234.56, 'parse non-U.S. (German) number format');
strictEqual( ff('-32,32'), -32.32, 'negative non-U.S. signed numbers'); assert.strictEqual( ff('-32,32'), -32.32, 'negative non-U.S. signed numbers');
strictEqual( ff('-1.234,56'), -1234.56, 'negative non-U.S. signed numbers'); assert.strictEqual( ff('-1.234,56'), -1234.56, 'negative non-U.S. signed numbers');
strictEqual( ff('(32,32)'), -32.32, 'parenthesis wrapped non-U.S. negative number'); assert.strictEqual( ff('(32,32)'), -32.32, 'parenthesis wrapped non-U.S. negative number');
strictEqual( ff(' (32,32) '), -32.32, 'space + parenthesis wrapped non-U.S. negative number'); assert.strictEqual( ff(' (32,32) '), -32.32, 'space + parenthesis wrapped non-U.S. negative number');
c1.usNumberFormat = true; c1.usNumberFormat = true;
strictEqual( ff('1,234.56'), 1234.56, 'parse U.S. number format'); assert.strictEqual( ff('1,234.56'), 1234.56, 'parse U.S. number format');
strictEqual( ff('-32.32'), -32.32, 'negative U.S. signed numbers'); assert.strictEqual( ff('-32.32'), -32.32, 'negative U.S. signed numbers');
strictEqual( ff('(32.32)'), -32.32, 'parenthesis wrapped U.S. negative number'); assert.strictEqual( ff('(32.32)'), -32.32, 'parenthesis wrapped U.S. negative number');
strictEqual( ff(' (32.32)'), -32.32, 'space + parenthesis wrapped U.S. negative number'); assert.strictEqual( ff(' (32.32)'), -32.32, 'space + parenthesis wrapped U.S. negative number');
strictEqual( ff('fred'), 'fred', 'return string if not a number'); assert.strictEqual( ff('fred'), 'fred', 'return string if not a number');
strictEqual( ff(' fred '), 'fred', 'return trimmed string if not a number'); assert.strictEqual( ff(' fred '), 'fred', 'return trimmed string if not a number');
strictEqual( ff('fred 12'), 'fred 12', 'return string if number not at beginning'); assert.strictEqual( ff('fred 12'), 'fred 12', 'return string if number not at beginning');
strictEqual( ff('12fred'), 12, 'parse number + string into number only'); assert.strictEqual( ff('12fred'), 12, 'parse number + string into number only');
strictEqual( ff('(fred)'), '(fred)', 'leave parenthesis intact on strings'); assert.strictEqual( ff('(fred)'), '(fred)', 'leave parenthesis intact on strings');
}); });
@ -259,32 +344,33 @@ $(function(){
return ts.getData( c2.$headers[n], c2.headers[n], 'sorter' ); return ts.getData( c2.$headers[n], c2.headers[n], 'sorter' );
}; };
test( "getData", function() { QUnit.test( "getData", function(assert) {
expect(4); assert.expect(4);
var txt = [ 'jQuery data', 'meta data', 'headers option', 'header class name' ]; var txt = [ 'jQuery data', 'meta data', 'headers option', 'header class name' ];
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
equal( gd(i), 'false', txt[i]); // all columns have sorter false set assert.equal( gd(i), 'false', txt[i]); // all columns have sorter false set
} }
}); });
/************************************************ /************************************************
character equivalent replacement character equivalent replacement
************************************************/ ************************************************/
test( "replace accents", function() { QUnit.test( "replace accents", function(assert) {
expect(6); assert.expect(6);
strictEqual( ts.replaceAccents('\u00e1\u00e0\u00e2\u00e3\u00e4\u0105\u00e5\u00c1\u00c0\u00c2\u00c3\u00c4\u0104\u00c5'), 'aaaaaaaAAAAAAA', "replaced a's"); assert.strictEqual( ts.replaceAccents('\u00e1\u00e0\u00e2\u00e3\u00e4\u0105\u00e5\u00c1\u00c0\u00c2\u00c3\u00c4\u0104\u00c5'), 'aaaaaaaAAAAAAA', "replaced a's");
strictEqual( ts.replaceAccents('\u00e9\u00e8\u00ea\u00eb\u011b\u0119\u00c9\u00c8\u00ca\u00cb\u011a\u0118'), 'eeeeeeEEEEEE', "replaced e's"); assert.strictEqual( ts.replaceAccents('\u00e9\u00e8\u00ea\u00eb\u011b\u0119\u00c9\u00c8\u00ca\u00cb\u011a\u0118'), 'eeeeeeEEEEEE', "replaced e's");
strictEqual( ts.replaceAccents('\u00ed\u00ec\u0130\u00ee\u00ef\u0131\u00cd\u00cc\u0130\u00ce\u00cf'), 'iiiiiiIIiII', "replaced i's"); assert.strictEqual( ts.replaceAccents('\u00ed\u00ec\u0130\u00ee\u00ef\u0131\u00cd\u00cc\u0130\u00ce\u00cf'), 'iiiiiiIIiII', "replaced i's");
strictEqual( ts.replaceAccents('\u00f3\u00f2\u00f4\u00f5\u00f6\u00d3\u00d2\u00d4\u00d5\u00d6'), 'oooooOOOOO', "replaced o's"); assert.strictEqual( ts.replaceAccents('\u00f3\u00f2\u00f4\u00f5\u00f6\u00d3\u00d2\u00d4\u00d5\u00d6'), 'oooooOOOOO', "replaced o's");
strictEqual( ts.replaceAccents('\u00fa\u00f9\u00fb\u00fc\u016f\u00da\u00d9\u00db\u00dc\u016e'), 'uuuuuUUUUU', "replaced u's"); assert.strictEqual( ts.replaceAccents('\u00fa\u00f9\u00fb\u00fc\u016f\u00da\u00d9\u00db\u00dc\u016e'), 'uuuuuUUUUU', "replaced u's");
strictEqual( ts.replaceAccents('\u00e7\u0107\u010d\u00c7\u0106\u010c\u00df\u1e9e'), 'cccCCCssSS', "replaced c & s sharp"); assert.strictEqual( ts.replaceAccents('\u00e7\u0107\u010d\u00c7\u0106\u010c\u00df\u1e9e'), 'cccCCCssSS', "replaced c & s sharp");
}); });
/************************************************ /************************************************
detect parsers detect parsers
************************************************/ ************************************************/
asyncTest( "detect parsers", function() { QUnit.test( "detect parsers", function(assert) {
expect(2); var done = assert.async();
assert.expect(2);
$('#testblock2').html('<table class="tablesorter"><thead>' + $('#testblock2').html('<table class="tablesorter"><thead>' +
'<tr><th class="col-off" colspan="2">Info</th><th class="col-off" colspan="4">Details</th></tr>' + '<tr><th class="col-off" colspan="2">Info</th><th class="col-off" colspan="4">Details</th></tr>' +
'<tr>' + '<tr>' +
@ -310,7 +396,6 @@ $(function(){
3 : { sorter: 'digit' } // 3 sets the 4th column, not the 3rd header cell now 3 : { sorter: 'digit' } // 3 sets the 4th column, not the 3rd header cell now
}, },
initialized: function(table){ initialized: function(table){
start();
var i, var i,
result = true, result = true,
parsers = [ 'text', 'digit', 'digit', 'currency', 'percent', 'usLongDate' ], parsers = [ 'text', 'digit', 'digit', 'currency', 'percent', 'usLongDate' ],
@ -318,8 +403,7 @@ $(function(){
for (i = 0; i < c.columns; i++){ for (i = 0; i < c.columns; i++){
result = result && c.parsers[i].id === parsers[i]; result = result && c.parsers[i].id === parsers[i];
} }
equal( result, true, 'detect parsers by header index' ); assert.equal( result, true, 'detect parsers by header index' );
stop();
// table inception! // table inception!
$(table) $(table)
.trigger('destroy') .trigger('destroy')
@ -340,8 +424,8 @@ $(function(){
for (i = 0; i < c.columns; i++){ for (i = 0; i < c.columns; i++){
result = result && c.parsers[i].id === parsers[i]; result = result && c.parsers[i].id === parsers[i];
} }
equal( result, true, 'detect parsers by class/id' ); assert.equal( result, true, 'detect parsers by class/id' );
start(); done();
} }
}); });
} }
@ -378,7 +462,7 @@ $(function(){
sample3 = { sample3 = {
'shortDate' : { '2001/1/2': returnTime('1/2/2001'), '2001-1/2': returnTime('1/2/2001'), '2001,1.2': returnTime('1/2/2001') } 'shortDate' : { '2001/1/2': returnTime('1/2/2001'), '2001-1/2': returnTime('1/2/2001'), '2001,1.2': returnTime('1/2/2001') }
}, },
report = function(s) { report = function(assert, s) {
for (i = 0; i < p.length; i++) { for (i = 0; i < p.length; i++) {
t = p[i].id; t = p[i].id;
if (s.hasOwnProperty(t)) { if (s.hasOwnProperty(t)) {
@ -386,150 +470,149 @@ $(function(){
$.each(s[t], function(k,v){ $.each(s[t], function(k,v){
// check "is" and "format" functions // check "is" and "format" functions
if (p[i].is(k)) { if (p[i].is(k)) {
equal( p[i].format(k, table1, th0, 0), v, t + ' parser: "' + k + '" parsed to ' + v ); assert.equal( p[i].format(k, table1, th0, 0), v, t + ' parser: "' + k + '" parsed to ' + v );
} else { } else {
equal( p[i].format(k, table1, th0, 0), v, t + ' parser **NOT DETECTED**: "' + k + '", but returns ' + v ); assert.equal( p[i].format(k, table1, th0, 0), v, t + ' parser **NOT DETECTED**: "' + k + '", but returns ' + v );
} }
}); });
// test for undefined & null - probably overkill // test for undefined & null - probably overkill
strictEqual( p[i].format(undef, table1, th0, 0), undef, t + ' parser: will return undefined values properly' ); assert.strictEqual( p[i].format(undef, table1, th0, 0), undef, t + ' parser: will return undefined values properly' );
strictEqual( p[i].format(null, table1, th0, 0), null, t + ' parser: will return null values properly' ); assert.strictEqual( p[i].format(null, table1, th0, 0), null, t + ' parser: will return null values properly' );
} }
} }
}; };
test( "testing parsers", function() { QUnit.test( "testing parsers", function(assert) {
expect(parserTests); assert.expect(parserTests);
report(sample1); report(assert, sample1);
c1.sortLocaleCompare = true; c1.sortLocaleCompare = true;
c1.ignoreCase = false; c1.ignoreCase = false;
c1.usNumberFormat = false; c1.usNumberFormat = false;
th0.dateFormat = c1.dateFormat = "ddmmyyyy"; th0.dateFormat = c1.dateFormat = "ddmmyyyy";
report(sample2); report(assert, sample2);
c1.usNumberFormat = true; c1.usNumberFormat = true;
th0.dateFormat = c1.dateFormat = "yyyymmdd"; th0.dateFormat = c1.dateFormat = "yyyymmdd";
report(sample3); report(assert, sample3);
// undocumented sortValue // undocumented sortValue
equal( ts.getParserById('metadata').format(null, table1, th0, 0), 'zzz', 'metadata parser found sortValue'); assert.equal( ts.getParserById('metadata').format(null, table1, th0, 0), 'zzz', 'metadata parser found sortValue');
c1.parserMetadataName = 'poe'; c1.parserMetadataName = 'poe';
equal( ts.getParserById('metadata').format(null, table1, th0, 0), 'nevermore', 'metadata parser found poe'); assert.equal( ts.getParserById('metadata').format(null, table1, th0, 0), 'nevermore', 'metadata parser found poe');
}); });
test( "textExtraction Method", function() { QUnit.test( "textExtraction Method", function(assert) {
expect(4); assert.expect(4);
$table1.trigger('sorton', [[[ 0,0 ]]]); $table1.trigger('sorton', [[[ 0,0 ]]]);
tester.cacheCompare( table1, 0, [ 'test1', 'test2', 'test3', assert.cacheCompare( table1, 0, [ 'test1', 'test2', 'test3',
'testa', 'testb', 'testc' ], 'from data-attribute' ); 'testa', 'testb', 'testc' ], 'from data-attribute' );
$table3.trigger('sorton', [[[ 0,1 ]]]); $table3.trigger('sorton', [[[ 0,1 ]]]);
tester.cacheCompare( table3, 0, [ '', 'a255', 'a102', 'a87', 'a55', 'a43', 'a33', 'a10', 'a02', 'a1' ], 'ignore data-attribute' ); assert.cacheCompare( table3, 0, [ '', 'a255', 'a102', 'a87', 'a55', 'a43', 'a33', 'a10', 'a02', 'a1' ], 'ignore data-attribute' );
tester.cacheCompare( table4, 1, [ 'f11', 'f11', 'f12', 'f12', 'f12', 'f12', 'f12', 'f13', 'f13', 'f13' ], 'extract using class name' ); assert.cacheCompare( table4, 1, [ 'f11', 'f11', 'f12', 'f12', 'f12', 'f12', 'f12', 'f13', 'f13', 'f13' ], 'extract using class name' );
tester.cacheCompare( table4, 2, [ 'a21', 'a21', 'a23', 'a23', 'a23', 'a22', 'a22', 'a23', 'a24', 'a24' ], 'extract using column index' ); assert.cacheCompare( table4, 2, [ 'a21', 'a21', 'a23', 'a23', 'a23', 'a22', 'a22', 'a23', 'a24', 'a24' ], 'extract using column index' );
}); });
/************************************************ /************************************************
test parser cache test parser cache
************************************************/ ************************************************/
test( "parser cache; sorton methods; empty & string", function() { QUnit.test( "parser cache; sorton methods; empty & string", function(assert) {
expect(18); assert.expect(18);
$table1.trigger('sortReset'); $table1.trigger('sortReset');
// lower case because table was parsed before c1.ignoreCase was changed // lower case because table was parsed before c1.ignoreCase was changed
tester.cacheCompare( table1, 'all', [ 'test2', 'x2', 'test1', 'x3', 'test3', 'x1', assert.cacheCompare( table1, 'all', [ 'test2', 'x2', 'test1', 'x3', 'test3', 'x1',
'testb', 'x5', 'testc', 'x4', 'testa', 'x6' ], 'unsorted' ); 'testb', 'x5', 'testc', 'x4', 'testa', 'x6' ], 'unsorted' );
$table1.trigger('sorton', [[[ 0,0 ]]]); $table1.trigger('sorton', [[[ 0,0 ]]]);
tester.cacheCompare( table1, 'all', [ 'test1', 'x3', 'test2', 'x2', 'test3', 'x1', assert.cacheCompare( table1, 'all', [ 'test1', 'x3', 'test2', 'x2', 'test3', 'x1',
'testa', 'x6', 'testb', 'x5', 'testc', 'x4' ], 'ascending sort' ); 'testa', 'x6', 'testb', 'x5', 'testc', 'x4' ], 'ascending sort' );
$table1.trigger('sorton', [[[ 0,1 ]]]); $table1.trigger('sorton', [[[ 0,1 ]]]);
tester.cacheCompare( table1, 'all', [ 'test3', 'x1', 'test2', 'x2', 'test1', 'x3', assert.cacheCompare( table1, 'all', [ 'test3', 'x1', 'test2', 'x2', 'test1', 'x3',
'testc', 'x4', 'testb', 'x5', 'testa', 'x6' ], 'descending sort' ); 'testc', 'x4', 'testb', 'x5', 'testa', 'x6' ], 'descending sort' );
// empty cell position // empty cell position
$table3.trigger('sorton', [[[ 0,0 ]]]); $table3.trigger('sorton', [[[ 0,0 ]]]);
tester.cacheCompare( table3, 0, [ '', 'a1', 'a02', 'a10', 'a33', 'a43', 'a55', 'a87', 'a102', 'a255' ], 'asc sort; empty to top' ); assert.cacheCompare( table3, 0, [ '', 'a1', 'a02', 'a10', 'a33', 'a43', 'a55', 'a87', 'a102', 'a255' ], 'asc sort; empty to top' );
$table3.trigger('sorton', [[[ 0,1 ]]]); $table3.trigger('sorton', [[[ 0,1 ]]]);
tester.cacheCompare( table3, 0, [ '', 'a255', 'a102', 'a87', 'a55', 'a43', 'a33', 'a10', 'a02', 'a1' ], 'desc sort; empty to top' ); assert.cacheCompare( table3, 0, [ '', 'a255', 'a102', 'a87', 'a55', 'a43', 'a33', 'a10', 'a02', 'a1' ], 'desc sort; empty to top' );
// string position within number column // string position within number column
$table3.trigger('sorton', [[[ 1,0 ]]]); $table3.trigger('sorton', [[[ 1,0 ]]]);
tester.cacheCompare( table3, 1, [ -35, -5, -1, 1, 2, 4, 33, 44, 'nr', '' ], 'asc sort; empty to bottom; string to max' ); assert.cacheCompare( table3, 1, [ -35, -5, -1, 1, 2, 4, 33, 44, 'nr', '' ], 'asc sort; empty to bottom; string to max' );
$table3.trigger('sorton', [[[ 1,1 ]]]); $table3.trigger('sorton', [[[ 1,1 ]]]);
tester.cacheCompare( table3, 1, [ 'nr', 44, 33, 4, 2, 1, -1, -5, -35, '' ], 'desc sort; empty to bottom; string to max' ); assert.cacheCompare( table3, 1, [ 'nr', 44, 33, 4, 2, 1, -1, -5, -35, '' ], 'desc sort; empty to bottom; string to max' );
$table3.trigger('sorton', [[[ 2,0 ]]]); $table3.trigger('sorton', [[[ 2,0 ]]]);
tester.cacheCompare( table3, 2, [ 'nr', 'nr', 1, 2, 3, 4, 5, 6, 7, '' ], 'asc sort; empty to bottom; string to min' ); assert.cacheCompare( table3, 2, [ 'nr', 'nr', 1, 2, 3, 4, 5, 6, 7, '' ], 'asc sort; empty to bottom; string to min' );
$table3.trigger('sorton', [[[ 2,1 ]]]); $table3.trigger('sorton', [[[ 2,1 ]]]);
tester.cacheCompare( table3, 2, [ 7, 6, 5, 4, 3, 2, 1, 'nr', 'nr', '' ], 'desc sort; empty to bottom; string to min' ); assert.cacheCompare( table3, 2, [ 7, 6, 5, 4, 3, 2, 1, 'nr', 'nr', '' ], 'desc sort; empty to bottom; string to min' );
$table3.trigger('sorton', [[[ 3,0 ]]]); $table3.trigger('sorton', [[[ 3,0 ]]]);
tester.cacheCompare( table3, 3, [ 'n/a #2', 'n/a #1', -8.4, -2.2, -0.1, '', 5.2, 11.4, 23.6, 97.4 ], 'asc sort; empty to zero; string to top' ); assert.cacheCompare( table3, 3, [ 'n/a #2', 'n/a #1', -8.4, -2.2, -0.1, '', 5.2, 11.4, 23.6, 97.4 ], 'asc sort; empty to zero; string to top' );
$table3.trigger('sorton', [[[ 3,1 ]]]); $table3.trigger('sorton', [[[ 3,1 ]]]);
tester.cacheCompare( table3, 3, [ 'n/a #2', 'n/a #1', 97.4, 23.6, 11.4, 5.2, '', -0.1, -2.2, -8.4 ], 'desc sort; empty to zero; string to top' ); assert.cacheCompare( table3, 3, [ 'n/a #2', 'n/a #1', 97.4, 23.6, 11.4, 5.2, '', -0.1, -2.2, -8.4 ], 'desc sort; empty to zero; string to top' );
$table3.find('th:eq(3)').data('string', 'bottom'); $table3.find('th:eq(3)').data('string', 'bottom');
$table3.trigger('update'); $table3.trigger('update');
tester.cacheCompare( table3, 3, [ 97.4, 23.6, 11.4, 5.2, '', -0.1, -2.2, -8.4, 'n/a #1', 'n/a #2' ], 'desc sort; empty to zero; string to bottom' ); assert.cacheCompare( table3, 3, [ 97.4, 23.6, 11.4, 5.2, '', -0.1, -2.2, -8.4, 'n/a #1', 'n/a #2' ], 'desc sort; empty to zero; string to bottom' );
$table3.trigger('sorton', [[[ 3,0 ]]]); $table3.trigger('sorton', [[[ 3,0 ]]]);
tester.cacheCompare( table3, 3, [ -8.4, -2.2, -0.1, '', 5.2, 11.4, 23.6, 97.4, 'n/a #1', 'n/a #2' ], 'asc sort; empty to zero; string to bottom' ); assert.cacheCompare( table3, 3, [ -8.4, -2.2, -0.1, '', 5.2, 11.4, 23.6, 97.4, 'n/a #1', 'n/a #2' ], 'asc sort; empty to zero; string to bottom' );
$table3.find('th:eq(3)').data('string', 'none'); $table3.find('th:eq(3)').data('string', 'none');
c3.headers[3].empty = "bottom"; c3.headers[3].empty = "bottom";
c3.sortList = [[ 3, 1 ]]; // added to test sortList c3.sortList = [[ 3, 1 ]]; // added to test sortList
$table3.trigger('update'); $table3.trigger('update');
tester.cacheCompare( table3, 3, [ 97.4, 23.6, 11.4, 5.2, 'n/a #1', 'n/a #2', -0.1, -2.2, -8.4, '' ], 'desc sort; empty to zero; string to none/zero' ); assert.cacheCompare( table3, 3, [ 97.4, 23.6, 11.4, 5.2, 'n/a #1', 'n/a #2', -0.1, -2.2, -8.4, '' ], 'desc sort; empty to zero; string to none/zero' );
$table3.trigger('sorton', [[[ 3,0 ]]]); $table3.trigger('sorton', [[[ 3,0 ]]]);
tester.cacheCompare( table3, 3, [ -8.4, -2.2, -0.1, 'n/a #1', 'n/a #2', 5.2, 11.4, 23.6, 97.4, '' ], 'asc sort; empty to zero; string to none/zero' ); assert.cacheCompare( table3, 3, [ -8.4, -2.2, -0.1, 'n/a #1', 'n/a #2', 5.2, 11.4, 23.6, 97.4, '' ], 'asc sort; empty to zero; string to none/zero' );
t = [ 'x', 'X', 'y', 'Y', 'z', 'Z', 'a', 'A', 'b', 'B', 'c', 'C' ]; t = [ 'x', 'X', 'y', 'Y', 'z', 'Z', 'a', 'A', 'b', 'B', 'c', 'C' ];
deepEqual( t.sort($.tablesorter.sortText), [ 'A', 'B', 'C', 'X', 'Y', 'Z', 'a', 'b', 'c', 'x', 'y', 'z' ], 'test sortText function directly' ); assert.deepEqual( t.sort($.tablesorter.sortText), [ 'A', 'B', 'C', 'X', 'Y', 'Z', 'a', 'b', 'c', 'x', 'y', 'z' ], 'test sortText function directly' );
t = [ 'a02', 'a10', 'a43', 'a255', 'a102', 'a33', '', 'a1', 'a55', 'a87' ]; t = [ 'a02', 'a10', 'a43', 'a255', 'a102', 'a33', '', 'a1', 'a55', 'a87' ];
deepEqual( t.sort($.tablesorter.sortNatural), [ '', 'a1', 'a02', 'a10', 'a33', 'a43', 'a55', 'a87', 'a102', 'a255' ], 'test sortNatural function directly' ); assert.deepEqual( t.sort($.tablesorter.sortNatural), [ '', 'a1', 'a02', 'a10', 'a33', 'a43', 'a55', 'a87', 'a102', 'a255' ], 'test sortNatural function directly' );
tester.cacheCompare( table4, 6, [ '', '', '', '', '', '', '', '', '', '' ], 'parser-false does not extract text' ); assert.cacheCompare( table4, 6, [ '', '', '', '', '', '', '', '', '', '' ], 'parser-false does not extract text' );
}); });
test( "sorton methods", function(){ QUnit.test( "sorton methods", function(assert) {
expect(6); assert.expect(6);
$table3.trigger('sorton', [[[ 0,'d' ]]]); $table3.trigger('sorton', [[[ 0,'d' ]]]);
equal( c3.sortList + '', '0,1', 'sorton desc [0,"d"]' ); assert.equal( c3.sortList + '', '0,1', 'sorton desc [0,"d"]' );
$table3.trigger('sorton', [[[ 0,'a' ]]]); $table3.trigger('sorton', [[[ 0,'a' ]]]);
equal( c3.sortList + '', '0,0', 'sorton asc [0,"a"]' ); assert.equal( c3.sortList + '', '0,0', 'sorton asc [0,"a"]' );
$table3.trigger('sorton', [[[ 0,'n' ]]]); $table3.trigger('sorton', [[[ 0,'n' ]]]);
equal( c3.sortList + '', '0,1', 'sorton next [0,"n"]' ); assert.equal( c3.sortList + '', '0,1', 'sorton next [0,"n"]' );
$table3.trigger('sorton', [[[ 0,'n' ]]]); $table3.trigger('sorton', [[[ 0,'n' ]]]);
equal( c3.sortList + '', '0,0', 'sorton next [0,"n"]' ); assert.equal( c3.sortList + '', '0,0', 'sorton next [0,"n"]' );
$table3.trigger('sorton', [[ [ 0,'n'], [1,'o'], [2,'s'] ]]); $table3.trigger('sorton', [[ [ 0,'n'], [1,'o'], [2,'s'] ]]);
equal( c3.sortList + '', '0,1,1,0,2,1', 'sorton next/opposite/same [0,"n"],[1,"o"],[2,"s"]' ); assert.equal( c3.sortList + '', '0,1,1,0,2,1', 'sorton next/opposite/same [0,"n"],[1,"o"],[2,"s"]' );
$table3.trigger('sorton', [[ [ 0,'n'], [1,'o'], [2,'s'] ]]); $table3.trigger('sorton', [[ [ 0,'n'], [1,'o'], [2,'s'] ]]);
equal( c3.sortList + '', '0,0,1,1,2,0', 'sorton next/opposite/same [0,"n"],[1,"o"],[2,"s"]' ); assert.equal( c3.sortList + '', '0,0,1,1,2,0', 'sorton next/opposite/same [0,"n"],[1,"o"],[2,"s"]' );
}); });
test( "sort Events", function(){ QUnit.test( "sort Events", function(assert) {
expect(1); assert.expect(1);
$table1.add($table5).bind( events.join('.testing '), function(e){ $table1.add($table5).bind( events.join('.testing '), function(e){
if (e.type === events[sortIndx%3]) { if (e.type === events[sortIndx%3]) {
@ -546,14 +629,14 @@ $(function(){
$table1.add($table5).unbind( events.join('.testing ') ); $table1.add($table5).unbind( events.join('.testing ') );
// table1 sorted twice in the above test; sortIndx = 9 then empty table5 x1 (total = 3 events x 3) // table1 sorted twice in the above test; sortIndx = 9 then empty table5 x1 (total = 3 events x 3)
equal( sortIndx, 9, 'sortStart, sortBegin & sortEnd fired in order x2; including empty table' ); assert.equal( sortIndx, 9, 'sortStart, sortBegin & sortEnd fired in order x2; including empty table' );
}); });
/************************************************ /************************************************
test update methods test update methods
************************************************/ ************************************************/
test( "parser cache; update methods & callbacks", function() { QUnit.test( "parser cache; update methods & callbacks", function(assert) {
expect(10); assert.expect(10);
var oldColMax; var oldColMax;
c1.ignoreCase = true; c1.ignoreCase = true;
// updateAll // updateAll
@ -572,8 +655,8 @@ $(function(){
hd = c1.$headers[1] === nw, hd = c1.$headers[1] === nw,
hl = c1.headerList[1] === nw, hl = c1.headerList[1] === nw,
p1 = c1.parsers[1].id === 'digit'; p1 = c1.parsers[1].id === 'digit';
equal(hc && hd && hl && p1, true, 'testing header cache: updateAll - thead'); assert.equal(hc && hd && hl && p1, true, 'testing header cache: updateAll - thead');
tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, assert.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3,
'testc', 4, 'testb', 5, 'testa', 6 ], 'updateAll - tbody' ); 'testc', 4, 'testb', 5, 'testa', 6 ], 'updateAll - tbody' );
}]); }]);
@ -583,8 +666,8 @@ $(function(){
oldColMax = c1.cache[1].colMax[1]; oldColMax = c1.cache[1].colMax[1];
$table1.trigger('addRows', [t, true, function(){ $table1.trigger('addRows', [t, true, function(){
updateCallback++; updateCallback++;
equal( oldColMax === 6 && c1.cache[1].colMax[1] === 7, true, 'addRows includes updating colMax value'); assert.equal( oldColMax === 6 && c1.cache[1].colMax[1] === 7, true, 'addRows includes updating colMax value');
tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, assert.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3,
'testd', 7, 'testc', 4, 'testb', 5, 'testa', 6 ], 'addRows method' ); 'testd', 7, 'testc', 4, 'testb', 5, 'testa', 6 ], 'addRows method' );
}]); }]);
@ -594,8 +677,8 @@ $(function(){
oldColMax = c1.cache[1].colMax[1]; oldColMax = c1.cache[1].colMax[1];
$table1.trigger('updateCell', [t[0], true, function(){ $table1.trigger('updateCell', [t[0], true, function(){
updateCallback++; updateCallback++;
equal( oldColMax === 7 && c1.cache[1].colMax[1] === 8, true, 'updateCell includes updating colMax value'); assert.equal( oldColMax === 7 && c1.cache[1].colMax[1] === 8, true, 'updateCell includes updating colMax value');
tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, assert.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3,
'testd', -8, 'testc', 4, 'testb', 5, 'testa', 6 ], 'updateCell method' ); 'testd', -8, 'testc', 4, 'testb', 5, 'testa', 6 ], 'updateCell method' );
}]); }]);
@ -604,8 +687,8 @@ $(function(){
oldColMax = c1.cache[1].colMax[1]; oldColMax = c1.cache[1].colMax[1];
$table1.trigger('update', [true, function(){ $table1.trigger('update', [true, function(){
updateCallback++; updateCallback++;
equal( oldColMax === 8 && c1.cache[1].colMax[1] === 6, true, 'update includes updating colMax value'); assert.equal( oldColMax === 8 && c1.cache[1].colMax[1] === 6, true, 'update includes updating colMax value');
tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, assert.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3,
'testc', 4, 'testb', 5, 'testa', 6 ], 'update method' ); 'testc', 4, 'testb', 5, 'testa', 6 ], 'update method' );
}]); }]);
@ -613,62 +696,64 @@ $(function(){
.bind('updateComplete.testing', function(){ updateIndx++; }) .bind('updateComplete.testing', function(){ updateIndx++; })
.trigger('update', [true, function(){ .trigger('update', [true, function(){
updateCallback++; updateCallback++;
tester.cacheCompare( table5, 'all', [], 'update method on empty table' ); assert.cacheCompare( table5, 'all', [], 'update method on empty table' );
}]); }]);
$table1.add($table5).unbind('updateComplete.testing'); $table1.add($table5).unbind('updateComplete.testing');
// table1 updated 4x in the above test // table1 updated 4x in the above test
// table5 updated 1x // table5 updated 1x
equal( updateIndx, updateCallback, 'updatedComplete and update callback functions working properly' ); assert.equal( updateIndx, updateCallback, 'updatedComplete and update callback functions working properly' );
}); });
/************************************************ /************************************************
test sortForce, sortAppend, sortMultiSortKey and sortResetKey options test sortForce, sortAppend, sortMultiSortKey and sortResetKey options
************************************************/ ************************************************/
asyncTest( "sortForce, sortAppend, sortMultiSortKey & sortResetKey; and numberSorter option", function(){ QUnit.test( "sortForce, sortAppend, sortMultiSortKey & sortResetKey; and numberSorter option", function(assert){
expect(3); assert.expect(3);
var count = 0;
tester.cacheCompare( table4, 3, [ 2, 1, 7, 6, 5, 3, 4, 8, 9, 10 ], 'force x2 + sorted x2 + append x2, ascending' ); assert.cacheCompare( table4, 3, [ 2, 1, 7, 6, 5, 3, 4, 8, 9, 10 ], 'force x2 + sorted x2 + append x2, ascending' );
$table4.on('sortEnd', function(){
count++; return QUnit.SequentialRunner(
if (count === 1) { function(actions, assertions){
tester.cacheCompare( table4, 3, [ 2, 1, 6, 7, 5, 4, 3, 8, 10, 9 ], 'force x2 + sorted x2 + append x2, descending' ); return QUnit.assertOnEvent($table4, 'sortEnd', actions, assertions);
c4.sortResetKey = 'shiftKey';
var e = $.Event('sort');
e.which = 1;
e.shiftKey = true; // testing sortResetKey
c4.$headers.eq(0).trigger(e);
} else {
tester.cacheCompare( table4, 3, [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'sortResetKey' );
$table4.off('sortEnd');
// start();
} }
}); ).nextTask(
var e = $.Event('sort'); function(){
c4.sortMultiSortKey = 'altKey'; c4.sortMultiSortKey = 'altKey';
e.which = 1; c4.$headers.eq(5).trigger( $.Event('sort', { which: 1, altKey: true }) );
e.altKey = true; // testing sortMultiSortKey },
c4.$headers.eq(5).trigger(e); function(){
assert.cacheCompare( table4, 3, [ 2, 1, 6, 7, 5, 4, 3, 8, 10, 9 ], 'force x2 + sorted x2 + append x2, descending' );
}
).nextTask(
function() {
c4.sortResetKey = 'shiftKey';
c4.$headers.eq(0).trigger( $.Event('sort', {which: 1, shiftKey: true}) );
},
function() {
assert.cacheCompare( table4, 3, [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], 'sortResetKey' );
}
).promise();
}); });
/************************************************ /************************************************
check header css check header css
************************************************/ ************************************************/
test( "testing header css & sortReset method", function(){ QUnit.test( "testing header css & sortReset method", function(assert) {
expect(7); assert.expect(7);
t = $(th0); t = $(th0);
equal( $table1.hasClass(ts.css.table), true, 'table class applied'); assert.equal( $table1.hasClass(ts.css.table), true, 'table class applied');
equal( t.hasClass(ts.css.header), true, 'Header class present' ); assert.equal( t.hasClass(ts.css.header), true, 'Header class present' );
equal( t.parent().hasClass(ts.css.headerRow), true, 'Header row class present' ); assert.equal( t.parent().hasClass(ts.css.headerRow), true, 'Header row class present' );
equal( $table1.find('tbody:eq(1)').hasClass(c1.cssInfoBlock), true, 'Tbody info block class present' ); assert.equal( $table1.find('tbody:eq(1)').hasClass(c1.cssInfoBlock), true, 'Tbody info block class present' );
$table1.trigger('sorton', [[[ 0,1 ]]] ); $table1.trigger('sorton', [[[ 0,1 ]]] );
equal( t.hasClass(ts.css.sortDesc), true, 'Descending class present' ); assert.equal( t.hasClass(ts.css.sortDesc), true, 'Descending class present' );
$table1.trigger('sorton', [[[ 0,0 ]]] ); $table1.trigger('sorton', [[[ 0,0 ]]] );
equal( t.hasClass(ts.css.sortAsc), true, 'Ascending class present' ); assert.equal( t.hasClass(ts.css.sortAsc), true, 'Ascending class present' );
$table1.trigger('sortReset'); $table1.trigger('sortReset');
equal( t.hasClass(ts.css.sortAsc) || t.hasClass(ts.css.sortDesc), false, 'Testing sortReset' ); assert.equal( t.hasClass(ts.css.sortAsc) || t.hasClass(ts.css.sortDesc), false, 'Testing sortReset' );
}); });
/************************************************ /************************************************
@ -683,34 +768,34 @@ $(function(){
return t; return t;
}; };
test( "apply zebra widget", function(){ QUnit.test( "apply zebra widget", function(assert) {
expect(3); assert.expect(3);
equal( zebra(), false, 'zebra not applied' ); assert.equal( zebra(), false, 'zebra not applied' );
c2.widgets = [ 'zebra' ]; c2.widgets = [ 'zebra' ];
$table2.trigger('applyWidgets'); $table2.trigger('applyWidgets');
equal( zebra(), true, 'zebra is applied' ); assert.equal( zebra(), true, 'zebra is applied' );
$table2 $table2
.append('<tr><td>s</td><td>t</td><td>u</td><td>v</td></tr>') .append('<tr><td>s</td><td>t</td><td>u</td><td>v</td></tr>')
.trigger('update'); .trigger('update');
equal( zebra(), true, 'zebra is applied after update' ); assert.equal( zebra(), true, 'zebra is applied after update' );
}); });
/************************************************ /************************************************
check destroy method check destroy method
************************************************/ ************************************************/
test("testing destroy method", function(){ QUnit.test("testing destroy method", function(assert) {
$table2.trigger('sorton', [[[ 0,1 ]]] ); $table2.trigger('sorton', [[[ 0,1 ]]] );
$table2.trigger('destroy'); $table2.trigger('destroy');
expect(7); assert.expect(7);
t = $table2.find('th:first'); t = $table2.find('th:first');
e = jQuery._data(table2, 'events'); // get a list of all bound events e = jQuery._data(table2, 'events'); // get a list of all bound events
equal( $.isEmptyObject(e), true, 'no events applied' ); assert.equal( $.isEmptyObject(e), true, 'no events applied' );
equal( $table2.data().hasOwnProperty('tablesorter'), false, 'Data removed' ); assert.equal( $table2.data().hasOwnProperty('tablesorter'), false, 'Data removed' );
equal( $table2.attr('class'), 'tester', 'All table classes removed' ); assert.equal( $table2.attr('class'), 'tester', 'All table classes removed' );
equal( $table2.find('tr:first').attr('class'), '', 'Header row class removed' ); assert.equal( $table2.find('tr:first').attr('class'), '', 'Header row class removed' );
equal( t.attr('class').match('tablesorter'), null, 'Header classes removed' ); assert.equal( t.attr('class').match('tablesorter'), null, 'Header classes removed' );
equal( t.children().length, 0, 'Inner wrapper removed' ); assert.equal( t.children().length, 0, 'Inner wrapper removed' );
equal( typeof (t.data().column) , 'undefined', 'data-column removed'); assert.equal( typeof (t.data().column) , 'undefined', 'data-column removed');
$table2.tablesorter(); $table2.tablesorter();
}); });