angular-ui-sortable
Version:
This directive allows you to jQueryUI Sortable.
638 lines (552 loc) • 22.5 kB
JavaScript
'use strict';
describe('uiSortable', function() {
beforeEach(
module(function($compileProvider) {
if (typeof $compileProvider.debugInfoEnabled === 'function') {
$compileProvider.debugInfoEnabled(false);
}
})
);
// Ensure the sortable angular module is loaded
beforeEach(module('ui.sortable'));
beforeEach(module('ui.sortable.testHelper'));
var EXTRA_DY_PERCENTAGE,
listContent,
beforeLiElement,
afterLiElement,
beforeTrElement,
afterTrElement;
beforeEach(
inject(function(sortableTestHelper) {
EXTRA_DY_PERCENTAGE = sortableTestHelper.EXTRA_DY_PERCENTAGE;
listContent = sortableTestHelper.listContent;
beforeLiElement =
sortableTestHelper.extraElements &&
sortableTestHelper.extraElements.beforeLiElement;
afterLiElement =
sortableTestHelper.extraElements &&
sortableTestHelper.extraElements.afterLiElement;
beforeTrElement =
sortableTestHelper.extraElements &&
sortableTestHelper.extraElements.beforeTrElement;
afterTrElement =
sortableTestHelper.extraElements &&
sortableTestHelper.extraElements.afterTrElement;
})
);
tests.description = 'Custom directive options related';
function tests(useExtraElements) {
var host;
beforeEach(
inject(function() {
host = $('<div id="test-host"></div>');
$('body').append(host);
if (!useExtraElements) {
beforeLiElement = afterLiElement = '';
beforeTrElement = afterTrElement = '';
}
})
);
afterEach(function() {
host.remove();
host = null;
});
it('should work when "ui-floating: false" option is used', function() {
inject(function($compile, $rootScope) {
var element;
element = $compile(
''.concat(
'<ul ui-sortable="opts" ng-model="items">',
beforeLiElement,
'<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item">{{ item }}</li>',
afterLiElement,
'</ul>'
)
)($rootScope);
$rootScope.$apply(function() {
$rootScope.opts = {
'ui-floating': false
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element);
var li = element.find('[ng-repeat]:eq(0)');
var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
expect($rootScope.items).toEqual(listContent(element));
li = element.find('[ng-repeat]:eq(1)');
dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
expect($rootScope.items).toEqual(listContent(element));
li = element.find('[ng-repeat]:eq(1)');
dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
expect($rootScope.items).toEqual(listContent(element));
$(element).remove();
});
});
it('should work when "ui-floating: true" option is used', function() {
inject(function($compile, $rootScope) {
var element;
element = $compile(
''.concat(
'<ul ui-sortable="opts" ng-model="items">',
beforeLiElement.replace('<li>', '<li class="floatleft">'),
'<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item floatleft">{{ item }}</li>',
afterLiElement.replace('<li>', '<li class="floatleft">'),
'</ul>'
)
)($rootScope);
$rootScope.$apply(function() {
$rootScope.opts = {
'ui-floating': true
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element).append('<div class="clear"></div>');
var li = element.find('[ng-repeat]:eq(0)');
var dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
li.simulate('drag', { dx: dx });
expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
expect($rootScope.items).toEqual(listContent(element));
li = element.find('[ng-repeat]:eq(1)');
dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
li.simulate('drag', { dx: dx });
expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
expect($rootScope.items).toEqual(listContent(element));
li = element.find('[ng-repeat]:eq(1)');
dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
li.simulate('drag', { dx: dx, moves: 5 });
expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
expect($rootScope.items).toEqual(listContent(element));
$(element).remove();
});
});
it('should work when "ui-floating: \'auto\'" option is used and elements are "float"ing', function() {
inject(function($compile, $rootScope) {
var element;
element = $compile(
''.concat(
'<ul ui-sortable="opts" ng-model="items">',
beforeLiElement.replace('<li>', '<li class="floatleft">'),
'<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item floatleft">{{ item }}</li>',
afterLiElement.replace('<li>', '<li class="floatleft">'),
'</ul>'
)
)($rootScope);
$rootScope.$apply(function() {
$rootScope.opts = {
'ui-floating': 'auto'
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element).append('<div class="clear"></div>');
var li = element.find('[ng-repeat]:eq(0)');
var dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
li.simulate('drag', { dx: dx });
expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
expect($rootScope.items).toEqual(listContent(element));
li = element.find('[ng-repeat]:eq(1)');
dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
li.simulate('drag', { dx: dx });
expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
expect($rootScope.items).toEqual(listContent(element));
li = element.find('[ng-repeat]:eq(1)');
dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
li.simulate('drag', { dx: dx, moves: 5 });
expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
expect($rootScope.items).toEqual(listContent(element));
$(element).remove();
});
});
it('should work when "ui-floating: \'auto\'" option is used and elements are "display: inline-block"', function() {
inject(function($compile, $rootScope) {
var element;
element = $compile(
''.concat(
'<ul ui-sortable="opts" ng-model="items">',
beforeLiElement.replace('<li>', '<li class="inline-block">'),
'<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item inline-block">{{ item }}</li>',
afterLiElement.replace('<li>', '<li class="inline-block">'),
'</ul>'
)
)($rootScope);
$rootScope.$apply(function() {
$rootScope.opts = {
'ui-floating': 'auto'
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element);
var li = element.find('[ng-repeat]:eq(0)');
var dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
li.simulate('drag', { dx: dx });
expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
expect($rootScope.items).toEqual(listContent(element));
li = element.find('[ng-repeat]:eq(1)');
dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
li.simulate('drag', { dx: dx });
expect($rootScope.items).toEqual(['Two', 'Three', 'One']);
expect($rootScope.items).toEqual(listContent(element));
li = element.find('[ng-repeat]:eq(1)');
dx = (1 + EXTRA_DY_PERCENTAGE) * li.outerWidth();
li.simulate('drag', { dx: dx, moves: 5 });
expect($rootScope.items).toEqual(['Two', 'One', 'Three']);
expect($rootScope.items).toEqual(listContent(element));
$(element).remove();
});
});
it('should properly reset deleted directive options', function() {
inject(function($compile, $rootScope) {
var element, logsElement;
element = $compile(
''.concat(
'<ul ui-sortable="opts" ng-model="items">',
beforeLiElement,
'<li ng-repeat="item in items" id="s-{{$index}}" sortable-item>{{ item }}</li>',
afterLiElement + '</ul>'
)
)($rootScope);
$rootScope.$apply(function() {
$rootScope.opts = {
'ui-floating': true,
'ui-model-items': '> [sortable-item]'
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element).append(logsElement);
var sortableWidgetInstance = element.data('ui-sortable');
expect(sortableWidgetInstance.floating).toBe(true);
$rootScope.$digest();
$rootScope.$apply(function() {
$rootScope.opts = {};
});
var li = element.find('[ng-repeat]:eq(1)');
var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
expect($rootScope.items).toEqual(listContent(element));
expect(sortableWidgetInstance.floating).toBe(false);
$(element).remove();
$(logsElement).remove();
});
});
it('should work when custom "ui-model-items" option is used with an attribute selector', function() {
inject(function($compile, $rootScope) {
var element;
element = $compile(
''.concat(
'<ul ui-sortable="opts" ng-model="items">',
beforeLiElement,
'<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item" ui-sortable-item>{{ item }}</li>',
afterLiElement,
'</ul>'
)
)($rootScope);
var itemsSelector = '[ui-sortable-item]';
$rootScope.$apply(function() {
$rootScope.opts = {
items: '> ' + itemsSelector,
'ui-model-items': '> ' + itemsSelector
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element).append('<div class="clear"></div>');
var li = element.find(itemsSelector + ':eq(1)');
var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
expect($rootScope.items).toEqual(listContent(element));
li = element.find(itemsSelector + ':eq(1)');
dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
expect($rootScope.items).toEqual(listContent(element));
$(element).remove();
});
});
it('should work when custom "ui-model-items" option is used with a class selector', function() {
inject(function($compile, $rootScope) {
var element;
element = $compile(
''.concat(
'<ul ui-sortable="opts" ng-model="items">',
beforeLiElement,
'<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item ui-sortable-item">{{ item }}</li>',
afterLiElement,
'</ul>'
)
)($rootScope);
var itemsSelector = '.ui-sortable-item';
$rootScope.$apply(function() {
$rootScope.opts = {
items: '> ' + itemsSelector,
'ui-model-items': '> ' + itemsSelector
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element).append('<div class="clear"></div>');
var li = element.find(itemsSelector + ':eq(1)');
var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
expect($rootScope.items).toEqual(listContent(element));
li = element.find(itemsSelector + ':eq(1)');
dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
expect($rootScope.items).toEqual(listContent(element));
$(element).remove();
});
});
xit('should work with multiple [ng-repeat] when attribute "ui-model-items" selector', function() {
inject(function($compile, $rootScope) {
var element;
element = $compile(
''.concat(
'<ul ui-sortable="opts" ng-model="items">',
beforeLiElement,
beforeLiElement.replace(
'<li>',
'<li ng-repeat="item in items" id="pre-{{$index}}" class="sortable-item">{{ item }}'
),
'<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item" ui-sortable-item>{{ item }}</li>',
afterLiElement.replace(
'<li>',
'<li ng-repeat="item in items" id="after-{{$index}}" class="sortable-item">{{ item }}'
),
afterLiElement,
'</ul>'
)
)($rootScope);
var itemsSelector = '[ui-sortable-item]';
$rootScope.$apply(function() {
$rootScope.opts = {
items: '> ' + itemsSelector,
'ui-model-items': '> ' + itemsSelector
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element).append('<div class="clear"></div>');
var li = element.find(itemsSelector + ':eq(1)');
var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
expect($rootScope.items).toEqual(listContent(element, itemsSelector));
li = element.find(itemsSelector + ':eq(1)');
dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
expect($rootScope.items).toEqual(listContent(element, itemsSelector));
$(element).remove();
});
});
xit('should work with multiple [ng-repeat] when class "ui-model-items" selector', function() {
inject(function($compile, $rootScope) {
var element;
element = $compile(
''.concat(
'<ul ui-sortable="opts" ng-model="items">',
beforeLiElement,
beforeLiElement.replace(
'<li>',
'<li ng-repeat="item in items" id="pre-{{$index}}" class="sortable-item">{{ item }}'
),
'<li ng-repeat="item in items" id="s-{{$index}}" class="sortable-item ui-sortable-item">{{ item }}</li>',
afterLiElement.replace(
'<li>',
'<li ng-repeat="item in items" id="after-{{$index}}" class="sortable-item">{{ item }}'
),
afterLiElement,
'</ul>'
)
)($rootScope);
var itemsSelector = '.ui-sortable-item';
$rootScope.$apply(function() {
$rootScope.opts = {
items: '> ' + itemsSelector,
'ui-model-items': '> ' + itemsSelector
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element).append('<div class="clear"></div>');
var li = element.find(itemsSelector + ':eq(1)');
var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
expect($rootScope.items).toEqual(listContent(element, itemsSelector));
li = element.find(itemsSelector + ':eq(1)');
dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight();
li.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
expect($rootScope.items).toEqual(listContent(element, itemsSelector));
$(element).remove();
});
});
it('should work when the "ui-preserve-size" option is used', function() {
inject(function($compile, $rootScope) {
var width = '200px';
var element;
element = $compile(
''.concat(
'<table>',
'<tbody><tr><td style="width: ' + width + ';"></td></tr></tbody>',
'<tbody ui-sortable="opts" ng-model="items">',
beforeTrElement,
'<tr ng-repeat="item in items" id="s-{{$index}}">',
'<td class="sortable-item">{{ item }}</td>',
'</tr>',
afterTrElement,
'</tbody>',
'</table>'
)
)($rootScope);
var itemsSelector = '.sortable-item';
$rootScope.$apply(function() {
$rootScope.opts = {
'ui-preserve-size': true,
stop: function(e, ui) {
expect(ui.item.children().css('width')).toEqual(width);
}
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element).append('<div class="clear"></div>');
var tr = element.find(itemsSelector + ':eq(1)');
var dy = (1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
tr.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
expect($rootScope.items).toEqual(
listContent(element.find('tbody'))
.map($)
.map($.text)
);
tr = element.find(itemsSelector + ':eq(1)');
dy = -(1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
tr.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
expect($rootScope.items).toEqual(
listContent(element.find('tbody'))
.map($)
.map($.text)
);
$(element).remove();
});
});
it('should work when the "ui-preserve-size" option is false', function() {
inject(function($compile, $rootScope) {
var width = '200px';
var element;
element = $compile(
''.concat(
'<table>',
'<tbody><tr><td style="width: ' + width + ';"></td></tr></tbody>',
'<tbody ui-sortable="opts" ng-model="items">',
beforeTrElement,
'<tr ng-repeat="item in items" id="s-{{$index}}">',
'<td class="sortable-item">{{ item }}</td>',
'</tr>',
afterTrElement,
'</tbody>',
'</table>'
)
)($rootScope);
var itemsSelector = '.sortable-item';
$rootScope.$apply(function() {
$rootScope.opts = {
'ui-preserve-size': false,
stop: function(e, ui) {
expect(ui.item.children().attr('style')).toEqual(undefined);
}
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element).append('<div class="clear"></div>');
var tr = element.find(itemsSelector + ':eq(1)');
var dy = (1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
tr.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
expect($rootScope.items).toEqual(
listContent(element.find('tbody'))
.map($)
.map($.text)
);
tr = element.find(itemsSelector + ':eq(1)');
dy = -(1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
tr.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
expect($rootScope.items).toEqual(
listContent(element.find('tbody'))
.map($)
.map($.text)
);
$(element).remove();
});
});
it('should work when the "ui-preserve-size" & helper options are used', function() {
inject(function($compile, $rootScope) {
var width = '200px';
var element;
element = $compile(
''.concat(
'<table>',
'<tbody><tr><td style="width: ' + width + ';"></td></tr></tbody>',
'<tbody ui-sortable="opts" ng-model="items">',
beforeTrElement,
'<tr ng-repeat="item in items" id="s-{{$index}}">',
'<td class="sortable-item">{{ item }}</td>',
'</tr>',
afterTrElement,
'</tbody>',
'</table>'
)
)($rootScope);
var itemsSelector = '.sortable-item';
$rootScope.$apply(function() {
$rootScope.opts = {
'ui-preserve-size': true,
helper: function(e, item) {
return item.clone();
},
stop: function(e, ui) {
expect(ui.item.children().css('width')).toEqual(width);
}
};
$rootScope.items = ['One', 'Two', 'Three'];
});
host.append(element).append('<div class="clear"></div>');
var tr = element.find(itemsSelector + ':eq(1)');
var dy = (1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
tr.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['One', 'Three', 'Two']);
expect($rootScope.items).toEqual(
listContent(element.find('tbody'))
.map($)
.map($.text)
);
tr = element.find(itemsSelector + ':eq(1)');
dy = -(1 + EXTRA_DY_PERCENTAGE) * tr.outerHeight();
tr.simulate('drag', { dy: dy });
expect($rootScope.items).toEqual(['Three', 'One', 'Two']);
expect($rootScope.items).toEqual(
listContent(element.find('tbody'))
.map($)
.map($.text)
);
$(element).remove();
});
});
}
[0, 1].forEach(function(useExtraElements) {
var testDescription = tests.description;
if (useExtraElements) {
testDescription += ' with extra elements';
}
describe(testDescription, function() {
tests(useExtraElements);
});
});
});