Browse Source

* qunit

tests
RubaXa 9 years ago
parent
commit
548460afec
  1. 29
      Gruntfile.js
  2. 35
      tests/index.html
  3. 97
      tests/sortable.tests.js
  4. 28
      tests/src/polyfills.js
  5. 13
      tests/src/qunit.ext.js
  6. 16
      tests/src/simulate.js

29
Gruntfile.js

@ -18,7 +18,11 @@ module.exports = function (grunt) {
}, },
jshint: { jshint: {
all: ['*.js', '!*.min.js'], all: [
'*.js',
'!*.min.js',
'tests/**/*.js'
],
options: { options: {
jshintrc: true jshintrc: true
@ -48,7 +52,25 @@ module.exports = function (grunt) {
} }
}, },
jquery: {} jquery: {},
qunit: {
all: ['tests/index.html'],
options: {
'--web-security': 'no',
coverage: {
src: ['Sortable.js'],
instrumentedFiles: 'temp/',
htmlReport: 'report/coverage/',
coberturaReport: 'report/',
baseUrl: "./coverage",
linesThresholdPct: 99,
functionsThresholdPct: 100,
branchesThresholdPct: 90,
statementsThresholdPct: 90
}
}
}
}); });
@ -91,6 +113,7 @@ module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-version'); grunt.loadNpmTasks('grunt-version');
grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-qunit-istanbul');
grunt.loadNpmTasks('grunt-exec'); grunt.loadNpmTasks('grunt-exec');
// Meteor tasks // Meteor tasks
@ -98,6 +121,6 @@ module.exports = function (grunt) {
grunt.registerTask('meteor-publish', 'exec:meteor-publish'); grunt.registerTask('meteor-publish', 'exec:meteor-publish');
grunt.registerTask('meteor', ['meteor-test', 'meteor-publish']); grunt.registerTask('meteor', ['meteor-test', 'meteor-publish']);
grunt.registerTask('tests', ['jshint']); grunt.registerTask('tests', ['jshint', 'qunit']);
grunt.registerTask('default', ['tests', 'version', 'uglify:dist']); grunt.registerTask('default', ['tests', 'version', 'uglify:dist']);
}; };

35
tests/index.html

@ -8,32 +8,27 @@
<title>Sortable :: Tests</title> <title>Sortable :: Tests</title>
</head> </head>
<body> <body>
<div id="canvas"> <style>
<ul id="simple"> .styled {
<li>item 1</li> margin: 0;
<li>item 2</li> padding: 0;
<li>item 3</li> list-style: none;
</ul> }
</div> .styled > * {
padding: 5px 10px;
}
</style>
<div id="fixture"></div>
<div id="qunit"></div> <div id="qunit"></div>
<div id="qunit-fixture"></div>
<link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.21.0.css"/> <link href="http://code.jquery.com/qunit/qunit-1.21.0.css" rel="stylesheet"/>
<script src="//code.jquery.com/qunit/qunit-1.21.0.js"></script> <script src="http://code.jquery.com/qunit/qunit-1.21.0.js"></script>
<script src="./src/raf.js"></script> <script src="./src/polyfills.js"></script>
<script src="./src/simulate.js"></script> <script src="./src/simulate.js"></script>
<script src="./src/qunit.ext.js"></script>
<script src="../Sortable.js"></script> <script src="../Sortable.js"></script>
<script>
Sortable.create(simple);
</script>
<script src="./sortable.tests.js"></script> <script src="./sortable.tests.js"></script>
</body> </body>
</html> </html>

97
tests/sortable.tests.js

@ -1,18 +1,99 @@
/* global QUnit, fixture, Sortable, simulateDrag */
'use strict'; 'use strict';
QUnit.module('Sortable'); QUnit.module('Sortable');
QUnit.sortableTest('simple', { function createSortableList(options) {
var listEl = document.createElement('div');
var length = options.length;
var withHandle = options.withHandle;
if (withHandle) {
options.handle = withHandle;
}
listEl.className = 'js-list';
for (var i = 0; i < length; i++) {
var el = document.createElement('div');
el.appendChild(document.createTextNode('Item ' + (i + 1)));
el.className = 'js-list-item';
listEl.appendChild(el);
}
fixture.appendChild(listEl);
return {
el: listEl,
sortable: Sortable.create(listEl, options),
destroy: function () {
this.sortable.destroy();
fixture.removeChild(this.el);
this.el = null;
this.sortable = null;
}
};
}
QUnit.test('core', function (assert) {
var done = assert.async();
var events = {};
var logEvent = function (evt) { events[this + evt.type] = true; };
var list = createSortableList({
length: 3,
onStart: logEvent.bind('on'),
onMove: logEvent.bind('on'),
onUpdate: logEvent.bind('on'),
onEnd: logEvent.bind('on')
});
list.el.addEventListener('start', logEvent.bind(''));
list.el.addEventListener('move', logEvent.bind(''));
list.el.addEventListener('update', logEvent.bind(''));
list.el.addEventListener('end', logEvent.bind(''));
simulateDrag({
from: { from: {
el: '#simple', el: list.el,
index: 0 index: 0
}, },
to: { to: {index: 'last'},
el: '#simple',
index: 'last' ontap: function () {
assert.ok(list.el.firstChild.className.indexOf('sortable-chosen') > -1, 'sortable-choose');
},
ondragstart: function () {
setTimeout(function () {
assert.ok(list.el.firstChild.className.indexOf('sortable-ghost') > -1, 'sortable-ghost');
}, 0);
} }
}, function (assert, scope) { }, function () {
assert.ok(scope.toList.contains(scope.target), 'container'); assert.deepEqual(Object.keys(events), [
assert.equal(scope.target, scope.toList.lastElementChild, 'position'); 'start', 'onstart',
'move', 'onmove',
'update', 'onupdate',
'end', 'onend'
]);
list.destroy();
done();
}); });
});
//QUnit.test('handle', function (assert) {
// var done = assert.async();
// var list = createSortableList({
// length: 3,
// withHandle: true,
// onStart: function () { assert.ok(false, 'start'); },
// onEnd: function () { assert.ok(false, 'end'); }
// });
//});

28
tests/src/raf.js → tests/src/polyfills.js

@ -36,3 +36,31 @@
}; };
} }
}()); }());
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
'use strict';
if (typeof this !== 'function') {
// ближайший аналог внутренней функции
// IsCallable в ECMAScript 5
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}

13
tests/src/qunit.ext.js

@ -1,13 +0,0 @@
(function () {
'use strict';
QUnit.sortableTest = function sortableTest(name, options, fn) {
QUnit.test(name, function (assert) {
var done = assert.async();
var data = simulateDrag(options, function () {
fn(assert, data, options);
done();
});
});
};
})();

16
tests/src/simulate.js

@ -42,7 +42,9 @@
} }
function getTraget(target) { function getTraget(target) {
var children = document.getElementById(target.el.substr(1)).children; var el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
var children = el.children;
return ( return (
children[target.index] || children[target.index] ||
children[target.index === 'first' ? 0 : -1] || children[target.index === 'first' ? 0 : -1] ||
@ -64,10 +66,12 @@
h: height, h: height,
hw: width / 2, hw: width / 2,
wh: height / 2 wh: height / 2
} };
} }
function simulateDrag(options, callback) { function simulateDrag(options, callback) {
options.to.el = options.to.el || options.from.el;
var fromEl = getTraget(options.from); var fromEl = getTraget(options.from);
var toEl = getTraget(options.to); var toEl = getTraget(options.to);
@ -83,8 +87,14 @@
var duration = options.duration || 1000; var duration = options.duration || 1000;
simulateEvent(fromEl, 'mousedown', {button: 0}); simulateEvent(fromEl, 'mousedown', {button: 0});
options.ontap && options.ontap();
simulateEvent(toEl, 'dragstart'); simulateEvent(toEl, 'dragstart');
requestAnimationFrame(function () {
options.ondragstart && options.ondragstart();
});
requestAnimationFrame(function loop() { requestAnimationFrame(function loop() {
var progress = (new Date().getTime() - startTime) / duration; var progress = (new Date().getTime() - startTime) / duration;
var x = fromRect.cx + (toRect.cx - fromRect.cx) * progress; var x = fromRect.cx + (toRect.cx - fromRect.cx) * progress;
@ -95,6 +105,7 @@
dotEl.style.left = x + 'px'; dotEl.style.left = x + 'px';
dotEl.style.top = y + 'px'; dotEl.style.top = y + 'px';
//console.log(overEl.parentNode.parentNode.parentNode.id, overEl.className, x, y);
overEl && simulateEvent(overEl, 'dragover', { overEl && simulateEvent(overEl, 'dragover', {
clientX: x, clientX: x,
clientY: y clientY: y
@ -104,6 +115,7 @@
dotEl.style.display = ''; dotEl.style.display = '';
requestAnimationFrame(loop); requestAnimationFrame(loop);
} else { } else {
options.ondragend && options.ondragend();
simulateEvent(toEl, 'drop'); simulateEvent(toEl, 'drop');
callback(); callback();
} }

Loading…
Cancel
Save