This commit is contained in:
vitalets
2012-11-09 12:58:42 +04:00
commit ccdff0ee51
160 changed files with 83260 additions and 0 deletions
.gitignoreCHANGELOG.txtLICENSE-GPLLICENSE-MITREADME.mdgrunt.js
libs
bootstrap204
bootstrap211
bootstrap221
jquery-ui-1.9.1.custom
jquery-ui-datepicker
jquery
mockjax
poshytip
qunit
makezippackage.json
src
test

10
test/coverage Normal file

@ -0,0 +1,10 @@
C:/jscoverage-0.5.1/jscoverage --exclude=locales ../src/js/ instrumented/
cp index.html instrumented/index.html
sed -i "s/..\/src\/js\/bootstrap-editable.js/instrumented\/bootstrap-editable.js/g" instrumented/index.html
sed -i "s/<\/title>/<\/title>\n<base href=\"..\/\">/g" instrumented/index.html
echo Success!
echo To get coverage report open instrumented/jscoverage.html?index.html

50
test/index.html Normal file

@ -0,0 +1,50 @@
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test Bootstrap Editable</title>
<!-- jquery -->
<script src="../libs/jquery/jquery-1.8.2.js"></script>
<!-- qunit -->
<link rel="stylesheet" href="../libs/qunit/qunit-1.10.0.css" type="text/css" media="screen" />
<script src="../libs/qunit/qunit-1.10.0.js"></script>
<!-- mockjax -->
<script src="../libs/mockjax/jquery.mockjax.js"></script>
<script src="mocks.js"></script>
<script src="loader.js"></script>
<script>
var fc = getFC(),
assets = getAssets(fc.f, fc.c, '../src/', '../libs/');
loadAssets(assets.css, assets.js);
</script>
</head>
<body>
<div>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div id="async-fixture"></div>
</div>
<!-- unit tests -->
<!-- You can also add "?module=[module]" URL to run only tests within that module-->
<script src="unit/common.js"></script>
<script src="unit/text.js"></script>
<script src="unit/select.js"></script>
<script src="unit/textarea.js"></script>
<script src="unit/api.js"></script>
<script>
if(fc.f === 'bootstrap') {
loadJs('unit/date.js');
} else {
loadJs('unit/dateui.js');
}
</script>
</body>
</html>

126
test/loader.js Normal file

@ -0,0 +1,126 @@
/**
* load requred js and css according to f (form) and c (container) parameters
*/
function getFC() {
var url = window.location.href, f, c;
if(url.match(/f=jqueryui/i)) {
f = 'jqueryui';
} else if(url.match(/f=plain/i)) {
f = 'plain';
} else { //bootstrap
f = 'bootstrap';
}
c = url.match(/c=inline/i) ? 'inline' : 'popup';
return {f: f, c: c};
}
function getAssets(f, c, src, libs) {
var
forms = src+'editable-form/',
inputs = src+'inputs/',
containers = src+'containers/',
element = src+'element/',
bootstrap = libs+'bootstrap221/',
jqueryui = libs+'jquery-ui-1.9.1.custom/',
js = [
forms+'editable-form.js',
forms+'editable-form-utils.js',
containers+'editable-container.js',
element+'editable-element.js',
inputs+'abstract.js',
inputs+'text.js',
inputs+'textarea.js',
inputs+'select.js'
],
css = [
forms+'editable-form.css',
containers+'editable-container.css',
element+'editable-element.css'
];
//tune js and css
if(f==='jqueryui') {
//core
js.unshift(jqueryui+'js/jquery-ui-1.9.1.custom.js')
css.unshift(jqueryui+'css/redmond/jquery-ui-1.9.1.custom.css');
//editable
js.push(forms+'editable-form-jqueryui.js');
js.push(getContainer('editable-tooltip.js'));
//date
js.push(inputs+'dateui.js');
//style
css.push('style.css');
} else if(f==='plain') {
//core
js.unshift(libs+'poshytip/jquery.poshytip.js');
css.unshift(libs+'poshytip/tip-yellowsimple/tip-yellowsimple.css');
//editable
js.push(getContainer('editable-poshytip.js'));
//date
js.push(inputs+'dateui.js');
js.push(libs+'jquery-ui-datepicker/js/jquery-ui-1.9.1.custom.js');
css.unshift(jqueryui+'css/redmond/jquery-ui-1.9.1.custom.css');
//style
css.push('style.css');
} else { //bootstrap
//core
js.unshift(bootstrap+'js/bootstrap.js')
css.unshift(bootstrap+'css/bootstrap.css');
//editable
js.push(forms+'editable-form-bootstrap.js');
js.push(getContainer('editable-popover.js'));
//date
js.push(inputs+'date/bootstrap-datepicker.js');
js.push(inputs+'date/date.js');
css.push(inputs+'date/datepicker.css');
}
function getContainer(container) {
return (c === 'inline') ? containers+'/editable-inline.js' : containers + container;
}
js.push('main.js');
return {css: css, js: js};
}
function loadAssets(css, js) {
for(var i = 0; i < css.length; i++) {
loadCss(css[i]);
}
for(i = 0; i < js.length; i++) {
loadJs(js[i]);
}
}
function loadCss(url) {
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
document.getElementsByTagName("head")[0].appendChild(link);
}
function loadJs(url) {
//console.log(url);
if(!url) return;
var script = document.createElement("script");
// script.src = url+'?'+Math.random(); //debug doesnot work with random
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}

5
test/main.js Normal file

@ -0,0 +1,5 @@
var fx, sfx;
$(function () {
$.fx.off = true;
$.support.transition = false;
});

32
test/mocks.js Normal file

@ -0,0 +1,32 @@
var timeout = 200;
$(function () {
$.mockjaxSettings.responseTime = 50;
$.mockjax({
url: 'post.php',
responseText: {
success: true
}
});
$.mockjax({
url: 'error.php',
status: 500,
statusText: 'Internal Server Error',
responseText: 'customtext'
});
$.mockjax({
url: 'post-resp.php',
response: function(settings) {
this.responseText = settings;
}
});
});
// usefull functions
function tip(e) {
return e.data('editableContainer').tip();
}

0
test/style.css Normal file

401
test/unit/api.js Normal file

@ -0,0 +1,401 @@
$(function () {
module("api", {
setup: function(){
fx = $('#async-fixture');
delete $.fn.editable.defaults.name;
}
});
test("validate, getValue, option", function () {
var e = $(
'<a href="#" data-type="text" id="username">user</a>' +
'<a href="#" data-type="textarea" id="comment">12345</a>' +
'<a href="#" data-type="select" id="sex" data-value="1" data-source=\'{"1":"q", "2":"w"}\'>q</a>' +
'<a href="#" data-type="date" id="dob" data-format="dd.mm.yyyy">15.05.1984</a>'
).appendTo('#qunit-fixture').editable(),
e1 = $('#username').editable('option', 'validate', function(value) {
if($.trim(value) !== 'user1') return 'username is required';
}),
e2 = $('#sex').editable('option', 'validate', function(value) {
if($.trim(value) != 2) return 'error';
});
//check get value
var values = e.editable('getValue');
equal(values.username, 'user', 'username ok') ;
equal(values.comment, '12345', 'comment ok') ;
equal(values.sex, 1, 'sex ok') ;
equal(values.dob, '15.05.1984', 'dob ok') ;
//validate
var errors = e.editable('validate');
ok(errors.username && errors.sex && !errors.comment, 'validation failed ok');
//enter correct values
e1.click();
var p = tip(e1);
p.find('input').val('user1');
p.find('button[type="submit"]').click();
ok(!p.is(':visible'), 'username changed');
e2.click();
p = tip(e2);
p.find('select').val(2);
p.find('button[type="submit"]').click();
ok(!p.is(':visible'), 'sex changed');
//validate again
var errors = e.editable('validate');
ok($.isEmptyObject(errors), 'validation ok');
/*
equal(e.filter('.editable-unsaved').length, 2, 'editable-unsaved exist');
e.editable('markAsSaved');
ok(!e.filter('.editable-unsaved').length, 'editable-unsaved not exist');
*/
});
test("getValue with originally empty elements", function () {
var e = $(
'<a href="#" data-type="text" id="username"></a>' +
'<a href="#" data-type="textarea" id="comment"></a>' +
'<a href="#" data-type="select" id="sex" data-source=\'{"1":"q", "2":"w"}\'></a>' +
'<a href="#" data-type="date" id="dob"></a>'
).appendTo('#qunit-fixture').editable();
//check get value
var values = e.editable('getValue');
equal(values.username, '', 'text empyt value') ;
equal(values.comment, '', 'textarea empty value') ;
ok(!('sex' in values), 'select value not present') ;
ok(!('dob' in values), 'date value not present') ;
});
/*
//deprecated in 2.0
asyncTest("'update' event", function () {
expect(2);
var e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo(fx).editable(),
e_nopk = $('<a href="#" data-url="post.php" data-name="text1">abc</a>').appendTo(fx).editable(),
newVal = 'xyt';
e.on('update', function() {
equal($(this).data('editable').value, newVal, 'triggered update after submit');
});
e_nopk.on('update', function() {
equal($(this).data('editable').value, newVal, 'triggered update after no-submit');
});
e_nopk.click();
var p = e_nopk.data('popover').$tip;
p.find('input').val(newVal);
p.find('form').submit();
e.click();
p = tip(e);
p.find('input').val(newVal);
p.find('form').submit();
setTimeout(function() {
e.remove();
e_nopk.remove();
start();
}, timeout);
});
*/
/*
//deprecated in 2.0
test("'init' event", function () {
expect(1);
var e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo('#qunit-fixture');
e.on('init', function(e, editable) {
equal(editable.value, 'abc', 'init triggered, value correct');
});
e.editable();
});
*/
asyncTest("'render' event for text", function () {
expect(4);
var val = 'afas',
e = $('<a href="#" data-pk="1" data-type="text" data-url="post.php" data-name="text1">'+val+'</a>').appendTo(fx),
isInit = true;
e.on('render', function(e, editable) {
equal(editable.isInit, isInit, 'isInit flag correct');
equal(editable.value, val, 'value correct');
});
e.editable();
isInit = false;
val = '123';
e.click();
var p = tip(e);
p.find('input[type=text]').val(val);
p.find('form').submit();
setTimeout(function() {
e.remove();
start();
}, timeout);
});
asyncTest("'render' event for select", function () {
expect(4);
var val = '1',
e = $('<a href="#" data-pk="1" data-type="select" data-url="post.php" data-name="text1" data-value="'+val+'"></a>').appendTo(fx),
isInit = true;
e.on('render', function(e, editable) {
equal(editable.isInit, isInit, 'isInit flag correct');
equal(editable.value, val, 'init triggered, value correct');
});
e.editable({
source: 'groups.php',
autotext: 'always'
});
setTimeout(function() {
isInit = false;
val = '3';
e.click();
var p = tip(e);
p.find('select').val(val);
p.find('form').submit();
setTimeout(function() {
e.remove();
start();
}, timeout);
}, timeout);
});
//shown / hidden events are totally depend on container.
/*
asyncTest("'shown' / 'hidden' events", function () {
expect(3);
var val = '1',
e = $('<a href="#" data-pk="1" data-type="select" data-url="post.php" data-name="text1" data-value="'+val+'"></a>').appendTo(fx);
e.on('shown', function(event, editable) {
var p = $(this).data('popover').$tip;
ok(p.is(':visible'), 'popover shown');
equal(editable.value, val, 'show triggered, value correct');
});
e.on('hidden', function(event, editable) {
var p = $(this).data('popover').$tip;
ok(!p.is(':visible'), 'popover hidden');
});
e.editable({
source: 'groups.php',
});
e.click();
setTimeout(function() {
var p = tip(e);
p.find('button[type=button]').click();
e.remove();
start();
}, timeout);
});
*/
test("show/hide/toggle methods", function () {
var e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable();
e.editable('show');
var p = tip(e);
ok(p.is(':visible'), 'popover shown');
e.editable('hide');
p = tip(e);
ok(!p.is(':visible'), 'popover closed');
e.editable('toggle');
p = tip(e);
ok(p.is(':visible'), 'popover shown');
});
test("enable/disable/toggleDisabled methods", function () {
var e = $('<a href="#" data-type="text" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable({
disabled: true
});
ok(e.hasClass('editable-disabled'), 'has disabled class');
ok(!e.hasClass('editable-click'), 'does not have click class');
e.click();
ok(!e.data('editableContainer'), 'nothing on click');
e.editable('enable');
ok(!e.hasClass('editable-disabled'), 'does not have disabled class');
ok(e.hasClass('editable-click'), 'has click class');
e.click();
var p = tip(e);
ok(p.is(':visible'), 'popover shown on click');
e.editable('disable');
p = tip(e);
ok(e.hasClass('editable-disabled'), 'has disabled class');
ok(!e.hasClass('editable-click'), 'does not have click class');
ok(!p.is(':visible'), 'popover closed');
e.editable('toggleDisabled');
ok(!e.hasClass('editable-disabled'), 'does not have disabled class (toggle)');
});
test("option method", function () {
var e = $('<a href="#" data-url="post.php" data-name="text">abc</a>').appendTo('#qunit-fixture').editable(),
e1 = $('<a href="#" data-pk="1" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable(),
url = 'abc';
$('#qunit-fixture a').editable('option', 'pk', 2);
equal(e.data('editable').options.pk, 2, 'pk set correctly');
equal(e1.data('editable').options.pk, 2, 'pk2 set correctly');
});
asyncTest("'submit' method: client and server validation", function () {
expect(6);
var ev1 = 'ev1',
ev2 = 'ev2',
e1v = 'e1v',
e = $('<a href="#" class="new" data-type="text" data-url="post.php" data-name="text">'+ev1+'</a>').appendTo(fx).editable({
validate: function(value) {
if(value == ev1) return 'invalid';
}
}),
e1 = $('<a href="#" class="new" data-type="text" data-name="text1">'+e1v+'</a>').appendTo(fx).editable();
$.mockjax({
url: 'new-error.php',
response: function(settings) {
equal(settings.data.text, ev2, 'first value ok');
equal(settings.data.text1, e1v, 'second value ok');
equal(settings.data.a, 123, 'custom data ok');
this.responseText = {errors: {
text1: 'server-invalid'
}
};
}
});
$(fx).find('.new').editable('submit', {
url: 'new.php',
error: function(data) {
ok(data.errors, 'errors defined');
equal(data.errors.text, 'invalid', 'client validation error ok');
}
});
//change value to pass client side validation
e.click();
var p = tip(e);
p.find('input[type=text]').val(ev2);
p.find('button[type=submit]').click();
$(fx).find('.new').editable('submit', {
url: 'new-error.php',
data: {a: 123},
error: function(data) {
equal(data.errors.text1, 'server-invalid', 'server validation error ok');
e.remove();
e1.remove();
start();
}
});
});
asyncTest("'submit' method: server error", function () {
expect(2);
var ev1 = 'ev1',
e1v = 'e1v',
e = $('<a href="#" class="new" data-type="text" data-url="post.php" data-name="text">'+ev1+'</a>').appendTo(fx).editable(),
e1 = $('<a href="#" class="new" data-type="text" data-name="text1">'+e1v+'</a>').appendTo(fx).editable();
$(fx).find('.new').editable('submit', {
url: 'error.php',
error: function(data) {
ok(!data.errors, 'no client errors');
equal(data.responseText, 'customtext', 'server error ok');
e.remove();
e1.remove();
start();
}
});
});
asyncTest("'submit' method: success", function () {
expect(7);
var ev1 = 'ev1',
e1v = 'e1v',
pk = 123,
e = $('<a href="#" class="new" data-type="text" data-url="post.php" data-name="text">'+ev1+'</a>').appendTo(fx).editable(),
e1 = $('<a href="#" class="new" data-type="text" data-name="text1">'+e1v+'</a>').appendTo(fx).editable();
$.mockjax({
url: 'new-success.php',
response: function(settings) {
equal(settings.data.text, ev1, 'first value ok');
equal(settings.data.text1, e1v, 'second value ok');
this.responseText = {id: pk};
}
});
$(fx).find('.new').editable('submit', {
url: 'new-success.php',
success: function(data) {
equal(e.data('editable').options.pk, pk, 'pk1 ok');
ok(!e.hasClass('editable-changed'), 'no "editable-changed" class');
equal(e1.data('editable').options.pk, pk, 'pk2 ok');
ok(!e1.hasClass('editable-changed'), 'no "editable-changed" class');
equal(data.id, pk, 'server result id ok');
e.remove();
e1.remove();
start();
}
});
});
test("setValue", function () {
var e = $('<a href="#" data-name="name" data-type="select" data-url="post.php"></a>').appendTo('#qunit-fixture').editable({
value: 1,
source: groups
});
equal(e.data('editable').value, 1, 'value correct');
equal(e.text(), groups[1], 'text shown correctly');
e.editable('setValue', 2);
equal(e.data('editable').value, 2, 'new value correct');
equal(e.text(), groups[2], 'new text shown correctly');
});
});

156
test/unit/common.js Normal file

@ -0,0 +1,156 @@
(function($) {
module("common", {
setup: function() {
fx = $('#async-fixture');
}
});
test("should be defined on jquery object", function () {
var div = $("<div id='modal-test'></div>")
ok(div.editable, 'editable method is defined')
});
test("should return element", function () {
var div = $('<div id="a"></div>');
ok(div.editable() == div, 'element returned');
});
test("should expose defaults var for settings", function () {
ok($.fn.editable.defaults, 'default object exposed');
});
test("should store editable instance in data object", function () {
var editable = $('<a href="#" id="a">link</a>').editable();
ok(!!editable.data('editable'), 'editable instance exists');
});
test("should add 'editable' class when applied", function () {
var editable = $('<a href="#" id="a">link</a>').appendTo('#qunit-fixture').editable();
ok($('.editable').length, 'editable class exists');
});
test("container should be close when element is removed from dom", function () {
var e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable(),
e1 = $('<a href="#" data-pk="1" data-url="post.php" data-name="text2">abc</a>').appendTo('#qunit-fixture').editable().wrap('<div>');
e.click();
var p = tip(e);
ok(p.is(':visible'), 'popover shown');
e.remove();
ok(!p.is(':visible'), 'popover closed');
});
// test("should store name and value and lastSavedValue", function () {
test("should store name and value", function () {
var v = 'abr><"&<b>e</b>',
visible_v = 'abr><"&e',
esc_v = $('<div>').text(v).html(),
e = $('<a href="#123" data-name="abc" data-value="123">qwe</a>').appendTo('#qunit-fixture').editable(),
e2 = $('<a href="#" id="a2">'+v+'</a>').appendTo('#qunit-fixture').editable(),
e3 = $('<a href="#" id="a3">'+esc_v+'</a>').appendTo('#qunit-fixture').editable();
equal(e.data('editable').options.name, 'abc', 'name exists');
equal(e.data('editable').value, '123', 'value exists');
// equal(e.data('editable').lastSavedValue, '123', 'lastSavedValue exists');
equal(e2.data('editable').value, visible_v, 'value taken from elem content correctly');
// equal(e2.data('editable').lastSavedValue, visible_v, 'lastSavedValue taken from text correctly');
equal(e3.data('editable').value, v, 'value taken from elem content correctly (escaped)');
// equal(e3.data('editable').lastSavedValue, v, 'lastSavedValue taken from text correctly (escaped)');
});
test("should take container's title from json options", function () {
//do not test inline
if(fc.c === 'inline') {
expect(0);
return;
}
var title = 'abc',
//add to fx because qunit-fixture has wrong positioning
e = $('<a href="#" id="a"></a>').appendTo(fx).editable({
placement: 'bottom',
title: title
});
e.click();
var p = tip(e);
ok(p.is(':visible'), 'popover shown');
//todo: for jqueryui phantomjs calcs wrong position. Need investigation
if(!$.browser.webkit && fc.f !== 'jqueryui') {
ok(p.offset().top > e.offset().top, 'placement ok');
}
ok(p.find(':contains("'+title+'")').length, 'title ok');
e.remove();
});
test("should close all other containers on click on editable", function () {
var e1 = $('<a href="#" data-pk="1" data-url="post.php" id="a">abc</a>').appendTo('#qunit-fixture').editable(),
e2 = $('<a href="#" data-pk="1" data-url="post.php" id="b">abcd</a>').appendTo('#qunit-fixture').editable();
e1.click()
var p1 = tip(e1);
ok(p1.is(':visible'), 'popover1 visible');
e2.click()
var p2 = tip(e2);
ok(p2.is(':visible'), 'popover2 visible');
ok(!p1.is(':visible'), 'popover1 closed');
p2.find('button[type=button]').click();
ok(!p2.is(':visible'), 'popover2 closed');
});
test("click outside popoover should hide it", function () {
var e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable(),
e1 = $('<div>').appendTo('body');
e.click();
var p = tip(e);
ok(p.is(':visible'), 'popover shown');
p.click();
ok(p.is(':visible'), 'popover still shown');
e1.click();
ok(!p.is(':visible'), 'popover closed');
});
//unfortunatly, testing this feature does not always work in browsers. Tested manually.
/*
test("enablefocus option", function () {
// focusing not passed in phantomjs
if($.browser.webkit) {
ok(true, 'skipped in PhantomJS');
return;
}
var e = $('<a href="#">abc</a>').appendTo('#qunit-fixture').editable({
enablefocus: true
}),
e1 = $('<a href="#">abcd</a>').appendTo('#qunit-fixture').editable({
enablefocus: false
});
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover 1 visible');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover closed');
ok(e.is(':focus'), 'element 1 is focused');
e1.click()
p = tip(e1);
ok(p.is(':visible'), 'popover 2 visible');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover closed');
ok(!e1.is(':focus'), 'element 2 is not focused');
});
*/
}(jQuery));

128
test/unit/date.js Normal file

@ -0,0 +1,128 @@
$(function () {
var dpg, f = 'dd.mm.yyyy';
module("date", {
setup: function(){
fx = $('#async-fixture');
$.fn.editable.defaults.name = 'name1';
dpg = $.fn.datepicker.DPGlobal;
}
});
function frmt(date, format) {
return dpg.formatDate(date, dpg.parseFormat(format), 'en');
}
asyncTest("popover should contain datepicker with value and save new entered date", function () {
expect(9);
var d = '15.05.1984',
e = $('<a href="#" data-type="date" data-pk="1" data-weekstart="1" data-url="post-date.php">'+d+'</a>').appendTo(fx).editable({
format: f,
datepicker: {
}
}),
nextD = '16.05.1984';
$.mockjax({
url: 'post-date.php',
response: function(settings) {
equal(settings.data.value, nextD, 'submitted value correct');
}
});
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), d, 'value correct');
e.click();
var p = tip(e);
ok(p.find('.datepicker').is(':visible'), 'datepicker exists');
equal(frmt(e.data('editable').value, f), d, 'day set correct');
equal(p.find('td.day.active').text(), 15, 'day shown correct');
equal(p.find('th.dow').eq(0).text(), 'Mo', 'weekStart correct');
//set new day
p.find('td.day.active').next().click();
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed')
equal(frmt(e.data('editable').value, f), nextD, 'new date saved to value')
equal(e.text(), nextD, 'new text shown')
e.remove();
start();
}, timeout);
});
asyncTest("viewformat, init by text", function () {
var dview = '15/05/1984',
d = '1984-05-15',
e = $('<a href="#" data-type="date" data-pk="1" data-weekstart="1" data-url="post-date1.php">'+dview+'</a>').appendTo(fx).editable({
format: 'yyyy-mm-dd',
viewformat: 'dd/mm/yyyy',
datepicker: {
}
}),
nextD = '1984-05-16',
nextDview = '16/05/1984';
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), d, 'value correct');
$.mockjax({
url: 'post-date1.php',
response: function(settings) {
equal(settings.data.value, nextD, 'submitted value correct');
}
});
e.click();
var p = tip(e);
ok(p.find('.datepicker').is(':visible'), 'datepicker exists');
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), d, 'day set correct');
equal(p.find('td.day.active').text(), 15, 'day shown correct');
equal(p.find('th.dow').eq(0).text(), 'Mo', 'weekStart correct');
//set new day
p.find('td.day.active').next().click();
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed')
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), nextD, 'new date saved to value')
equal(e.text(), nextDview, 'new text shown in correct format')
e.remove();
start();
}, timeout);
});
test("viewformat, init by value", function () {
var dview = '15/05/1984',
d = '1984-05-15',
e = $('<a href="#" data-type="date" data-pk="1" data-weekstart="1" data-value="'+d+'"></a>').appendTo('#qunit-fixture').editable({
format: 'yyyy-mm-dd',
viewformat: 'dd/mm/yyyy'
});
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), d, 'value correct');
equal(e.text(), dview, 'text correct');
});
test("input should contain today if element is empty", function () {
var e = $('<a href="#" data-type="date"></a>').appendTo('#qunit-fixture').editable();
e.click();
var p = tip(e),
today = new Date();
equal(p.find('td.day.active').text(), today.getDate(), 'day shown correct');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover closed');
});
});

83
test/unit/dateui.js Normal file

@ -0,0 +1,83 @@
$(function () {
var dpg;
module("dateui", {
setup: function(){
fx = $('#async-fixture');
$.fn.editable.defaults.name = 'name1';
}
});
function frmt(date, format) {
format = format.replace('yyyy', 'yy');
return $.datepicker.formatDate(format, date);
}
asyncTest("container should contain datepicker with value and save new entered date", function () {
var d = '15.05.1984',
dview = '15/05/1984',
e = $('<a href="#" data-type="date" data-pk="1" data-url="post-date.php">'+dview+'</a>').appendTo(fx).editable({
format: 'dd.mm.yyyy',
viewformat: 'dd/mm/yyyy',
firstDay: 1
}),
nextD = '16.05.1984',
nextDview = '16/05/1984';
$.mockjax({
url: 'post-date.php',
response: function(settings) {
equal(settings.data.value, nextD, 'submitted value correct');
}
});
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), d, 'value correct');
e.click();
var p = tip(e);
ok(p.find('.ui-datepicker').is(':visible'), 'datepicker exists');
equal(p.find('a.ui-state-active').text(), 15, 'day shown correct');
equal(p.find('.ui-datepicker-calendar > thead > tr > th').eq(0).find('span').text(), 'Mo', 'weekStart correct');
//set new day
p.find('a.ui-state-active').parent().next().click();
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed');
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), nextD, 'new date saved to value');
equal(e.text(), nextDview, 'new text shown');
e.remove();
start();
}, timeout);
});
test("viewformat, init by value", function () {
var dview = '15/05/1984',
d = '1984-05-15',
e = $('<a href="#" data-type="date" data-pk="1" data-weekstart="1" data-value="'+d+'"></a>').appendTo('#qunit-fixture').editable({
format: 'yyyy-mm-dd',
viewformat: 'dd/mm/yyyy'
});
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), d, 'value correct');
equal(e.text(), dview, 'text correct');
});
test("input should contain today if element is empty", function () {
var e = $('<a href="#" data-type="date"></a>').appendTo('#qunit-fixture').editable();
e.click();
var p = tip(e),
today = new Date();
equal(p.find('a.ui-state-active').text(), today.getDate(), 'day shown correct');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover closed');
});
});

453
test/unit/select.js Normal file

@ -0,0 +1,453 @@
$(function () {
window.groups = {
0: 'Guest',
1: 'Service',
2: 'Customer',
3: 'Operator',
4: 'Support',
5: 'Admin',
6: '',
'': 'Nothing'
};
window.size = 0;
for (e in groups) { size++; }
$.mockjax({
url: 'groups.php',
responseText: groups
});
$.mockjax({
url: 'groups-error.php',
status: 500,
responseText: 'Internal Server Error'
});
module("select", {
setup: function(){
sfx = $('#qunit-fixture'),
fx = $('#async-fixture');
$.fn.editable.defaults.name = 'name1';
//clear cache
$(document).removeData('groups.php-'+$.fn.editable.defaults.name);
}
});
test("popover should contain SELECT even if value & source not defined", function () {
var e = $('<a href="#" data-type="select">w</a>').appendTo('#qunit-fixture').editable();
e.click();
var p = tip(e);
ok(p.find('select').length, 'select exists')
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
})
asyncTest("load options from server", function () {
var e = $('<a href="#" data-type="select" data-name="load-srv" data-value="2" data-source="groups.php">customer</a>').appendTo(fx).editable();
e.click();
var p = tip(e);
ok(p.find('.editableform-loading').length, 'loading class exists');
ok(p.find('.editableform-loading').is(':visible'), 'loading class is visible');
setTimeout(function() {
ok(p.is(':visible'), 'popover visible');
ok(p.find('.editableform-loading').length, 'loading class exists');
ok(!p.find('.editableform-loading').is(':visible'), 'loading class is hidden');
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
start();
}, timeout);
})
test("load options from json", function () {
var e = $('<a href="#" data-type="select" data-value="2" data-url="post.php">customer</a>').appendTo('#qunit-fixture').editable({
pk: 1,
source: groups
});
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible')
ok(p.find('.editableform-loading').length, 'loading class exists')
ok(!p.find('.editableform-loading').is(':visible'), 'loading class is hidden')
ok(p.find('select').length, 'select exists')
equal(p.find('select').find('option').length, size, 'options loaded')
equal(p.find('select').val(), e.data('editable').value, 'selected value correct')
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
});
test("load options from native array", function () {
var arr = ['q', 'w', 'x'],
e = $('<a href="#" data-type="select" data-value="2" data-url="post.php">customer</a>').appendTo('#qunit-fixture').editable({
pk: 1,
autotext: true,
source: arr
});
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible')
ok(p.find('select').length, 'select exists')
equal(p.find('select').find('option').length, arr.length, 'options loaded')
equal(p.find('select').val(), 2, 'selected value correct')
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
})
test("load options from html (single quotes)", function () {
var e = $('<a href="#" data-type="select" data-value="M" data-source=\'{"L":"Low", "": "None", "M": "Medium", "H": "High"}\'>customer</a>').appendTo('#qunit-fixture').editable({
pk: 1
}),
size = 4;
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible');
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
})
test("load options from html (double quotes)", function () {
var e = $('<a href="#" data-type="select" data-value="M" data-source="{\'L\':\'Low\', \'\': \'None\', \'M\': \'Medium\', \'H\': \'High\'}">customer</a>').appendTo('#qunit-fixture').editable({
pk: 1
}),
size = 4;
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible');
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
})
test("load options from html (json syntax error)", function () {
var e = $('<a href="#" data-type="select" data-value="M" data-source=\'{L :Low, "": "None", "M": "Medium", "H": "High"}\'>customer</a>').appendTo('#qunit-fixture').editable({
pk: 1,
sourceError: 'error'
}),
size = 4;
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible');
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, 0, 'options not loaded');
equal(p.find('.editable-error-block').text(), 'error', 'sourceError message shown');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
})
asyncTest("should show error if options cant be loaded", function () {
var e = $('<a href="#" data-type="select" data-value="2" data-source="groups-error.php">customer</a>').appendTo(fx).editable();
e.click();
var p = tip(e);
setTimeout(function() {
ok(p.is(':visible'), 'popover visible')
ok(p.find('select:disabled').length, 'select disabled')
ok(!p.find('select').find('option').length, 'options not loaded')
ok(p.find('button[type=submit]:disabled').length, 'submit-btn disabled')
ok(p.find('.editable-error-block').text().length, 'error shown')
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
start();
}, timeout);
})
asyncTest("popover should save new selected value", function () {
var e = $('<a href="#" data-type="select" data-value="2" data-url="post.php">customer</a>').appendTo(fx).editable({
pk: 1,
source: groups
}),
selected = 3;
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible');
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct');
p.find('select').val(selected);
p.find('form').submit();
ok(p.find('.editableform-loading').is(':visible'), 'loading class is visible');
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed')
equal(e.data('editable').value, selected, 'new value saved')
equal(e.text(), groups[selected], 'new text shown')
e.remove();
start();
}, timeout);
});
asyncTest("if new text is empty --> show emptytext on save", function () {
var e = $('<a href="#" data-type="select" data-value="2" data-url="post.php">customer</a>').appendTo(fx).editable({
pk: 1,
source: groups
}),
selected = 6;
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible')
ok(p.find('select').length, 'select exists')
equal(p.find('select').find('option').length, size, 'options loaded')
equal(p.find('select').val(), e.data('editable').value, 'selected value correct')
p.find('select').val(selected);
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed')
equal(e.data('editable').value, selected, 'new value saved')
equal(e.text(), e.data('editable').options.emptytext, 'emptytext shown')
e.remove();
start();
}, timeout);
})
asyncTest("if new value is empty --> show work correct", function () {
var e = $('<a href="#" data-type="select" data-value="2" data-url="post.php">customer</a>').appendTo(fx).editable({
pk: 1,
source: groups
}),
selected = '';
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible')
ok(p.find('select').length, 'select exists')
equal(p.find('select').find('option').length, size, 'options loaded')
equal(p.find('select').val(), e.data('editable').value, 'selected value correct')
p.find('select').val(selected);
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed')
equal(e.data('editable').value, selected, 'new value saved')
equal(e.text(), groups[selected], 'text shown correctly')
e.remove();
start();
}, timeout);
});
asyncTest("cache request for same selects", function () {
var e = $('<a href="#" data-type="select" data-pk="1" data-value="2" data-url="post.php" data-source="groups-cache.php">customer</a>').appendTo(fx).editable(),
e1 = $('<a href="#" data-type="select" data-pk="1" data-value="2" data-url="post.php" data-source="groups-cache.php">customer</a>').appendTo(fx).editable(),
req = 0;
$.mockjax({
url: 'groups-cache.php',
response: function() {
req++;
this.responseText = groups;
}
});
e.click();
var p = tip(e);
setTimeout(function() {
ok(p.is(':visible'), 'popover visible');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(req, 1, 'one request performed');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
//click second
e1.click();
p = tip(e1);
setTimeout(function() {
ok(p.is(':visible'), 'popover2 visible');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(req, 1, 'no extra request, options taken from cache');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
e1.remove();
start();
}, timeout);
}, timeout);
});
asyncTest("cache simultaneous requests", function () {
expect(4);
var req = 0;
$.mockjax({
url: 'groups-cache-sim.php',
responseTime: 200,
response: function() {
req++;
this.responseText = groups;
}
});
var e = $('<a href="#" data-type="select" data-pk="1" data-value="1" data-url="post.php" data-source="groups-cache-sim.php"></a>').appendTo(fx).editable(),
e1 = $('<a href="#" data-type="select" data-pk="1" data-value="2" data-url="post.php" data-source="groups-cache-sim.php"></a>').appendTo(fx).editable(),
e2 = $('<a href="#" data-type="select" data-pk="1" data-value="3" data-url="post.php" data-source="groups-cache-sim.php"></a>').appendTo(fx).editable();
setTimeout(function() {
equal(req, 1, 'one request');
equal(e.text(), groups[1], 'text1 correct');
equal(e1.text(), groups[2], 'text2 correct');
equal(e2.text(), groups[3], 'text3 correct');
e.remove();
e1.remove();
e2.remove();
start();
}, 300);
});
asyncTest("cache simultaneous requests (loading error)", function () {
expect(4);
var req = 0;
$.mockjax({
url: 'groups-cache-sim-err.php',
responseTime: 200,
status: 500,
response: function() {
req++;
}
});
var e = $('<a href="#" data-type="select" data-pk="1" data-value="1" data-autotext="always" data-url="post.php" data-source="groups-cache-sim-err.php">35</a>').appendTo(fx).editable(),
e1 = $('<a href="#" data-type="select" data-pk="1" data-value="2" data-autotext="always" data-url="post.php" data-source="groups-cache-sim-err.php">35</a>').appendTo(fx).editable(),
e2 = $('<a href="#" data-type="select" data-pk="1" data-value="3" data-autotext="always" data-url="post.php" data-source="groups-cache-sim-err.php">6456</a>').appendTo(fx).editable(),
errText = $.fn.editableform.types.select.defaults.sourceError;
setTimeout(function() {
equal(req, 1, 'one request');
equal(e.text(), errText, 'text1 correct');
equal(e1.text(), errText, 'text2 correct');
equal(e2.text(), errText, 'text3 correct');
e.remove();
e1.remove();
e2.remove();
start();
}, 300);
});
asyncTest("autotext: auto", function () {
expect(3);
//auto, text->empty, source->array
var e = $('<a href="#" data-type="select" data-value="3"></a>').appendTo(sfx).editable({
source: groups,
autotext: 'auto'
}),
//auto, text->not empty, source->array
e1 = $('<a href="#" data-type="select" data-value="3">blabla</a>').appendTo(sfx).editable({
source: groups,
autotext: 'auto'
}),
//auto, text->empty, source->url
e2 = $('<a href="#" data-type="select" data-value="3" data-source="groups.php"></a>').appendTo(fx).editable({
autotext: 'auto'
});
equal(e.text(), groups[3], 'text set ok');
equal(e1.text(), 'blabla', 'text1 not changed');
setTimeout(function() {
equal(e2.text(), groups[3], 'text2 set ok');
e2.remove();
start();
}, timeout);
});
asyncTest("autotext: always (source = url)", function () {
expect(1);
var e = $('<a href="#" data-type="select" data-value="3" data-source="groups.php">blabla</a>').appendTo(fx).editable({
autotext: 'always'
});
setTimeout(function() {
equal(e.text(), groups[3], 'text setup ok');
e.remove();
start();
}, timeout);
});
test("autotext: never", function () {
var e = $('<a href="#" data-type="select" data-value="3"></a>').appendTo(sfx).editable({
source: groups,
autotext: 'never'
});
equal(e.text(), e.data('editable').options.emptytext, 'text set to emptytext');
});
asyncTest("test prepend option (sync & async)", function () {
//sync
var e = $('<a href="#" data-type="select" data-name="prepend-test-sync" data-value="" data-url="post.php">customer</a>').appendTo('#qunit-fixture').editable({
pk: 1,
source: {q: 'qq', w: 'ww'},
prepend: 'empty'
});
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible');
equal(p.find('select').find('option').length, 3, 'options prepended (sync)');
equal(p.find('select').val(), '', 'selected value correct');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
//async
e = $('<a href="#" data-type="select" data-name="prepend-test-async" data-value="r" data-url="post.php">customer</a>').appendTo(fx).editable({
pk: 1,
source: 'groups.php',
prepend: {r: 'abc'}
});
e.click()
p = tip(e);
setTimeout(function() {
ok(p.is(':visible'), 'popover visible');
equal(p.find('select').find('option').length, size+1, 'options prepended (async)');
equal(p.find('select').val(), 'r', 'selected value correct');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
start();
}, timeout);
});
});

365
test/unit/text.js Normal file

@ -0,0 +1,365 @@
$(function () {
module("text", {
setup: function() {
fx = $('#async-fixture');
$.fn.editable.defaults.name = 'name1';
}
});
test("if element originally empty: emptytext should be shown and input should contain ''", function () {
var emptytext = 'empty!',
e = $('<a href="#" id="a"> </a>').appendTo('#qunit-fixture').editable({emptytext: emptytext});
equal(e.text(), emptytext, 'emptytext shown on init');
e.click();
var p = tip(e);
equal(p.find('input[type=text]').val(), '', 'input val is empty string')
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed')
})
test("option 'placeholder'", function () {
var e = $('<a href="#" id="a" data-placeholder="abc"> </a>').appendTo('#qunit-fixture').editable();
e.click();
var p = tip(e);
equal(p.find('input[type=text]').attr('placeholder'), 'abc', 'placeholder exists');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
});
test("option 'inputclass'", function () {
var e = $('<a href="#" id="a" data-inputclass="span4"> </a>').appendTo('#qunit-fixture').editable();
e.click();
var p = tip(e);
ok(p.find('input[type=text]').hasClass('span4'), 'class set correctly');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
});
test("option 'toggle' = manual", function () {
var e = $('<a href="#" id="a"></a>').appendTo('#qunit-fixture').editable({
toggle: 'manual'
});
e.click();
ok(!e.data().editableContainer, 'popover not visible after click');
e.editable('show');
var p = tip(e);
ok(p.is(':visible'), 'shown manually');
});
asyncTest("should load correct value and save new entered text (and value)", function () {
var v = 'ab<b>"',
esc_v = $('<div>').text(v).html(),
e = $('<a href="#" data-pk="1" data-name="text1" data-url="post-text.php" data-params="{\'q\': \'w\'}">'+esc_v+'</a>').appendTo(fx).editable({
success: function(data) {
return false;
}
}),
data,
newText = 'cd<e>;"';
$.mockjax({
url: 'post-text.php',
response: function(settings) {
data = settings.data;
}
});
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible')
ok(p.find('.editableform-loading').length, 'loading class exists')
ok(!p.find('.editableform-loading').is(':visible'), 'loading class is hidden')
ok(p.find('input[type=text]').length, 'input exists')
equal(p.find('input[type=text]').val(), v, 'input contain correct value')
p.find('input').val(newText);
p.find('button[type=submit]').click();
ok(p.find('.editableform-loading').is(':visible'), 'loading class is visible');
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed');
equal(e.data('editable').value, newText, 'new text saved to value');
equal(e.text(), newText, 'new text shown');
ok(data, 'ajax performed');
equal(data.name, 'text1', 'name sent');
equal(data.pk, 1, 'pk sent');
equal(data.value, newText, 'value sent');
equal(data.q, 'w', 'params sent');
e.remove();
start();
}, timeout);
});
asyncTest("should show error on server validation", function () {
var msg = 'required',
e = $('<a href="#" data-name="text1">abc</a>').appendTo(fx).editable({
validate: function(value) { if(value == '') return msg; }
}),
newText = '';
e.click();
var p = tip(e);
ok(p.is(':visible'), 'popover shown');
p.find('input').val(newText);
p.find('form').submit();
setTimeout(function() {
ok(p.is(':visible'), 'popover still shown');
ok(p.find('.editable-error-block').length, 'class "editable-error-block" exists');
equal(p.find('.editable-error-block').text(), 'required', 'error msg shown');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
start();
}, timeout);
});
/*
test("test validation map", function () {
var e = $('<a href="#" class="map" data-name="e" data-name="text1">abc</a>').appendTo('#qunit-fixture'),
e1 = $('<a href="#" class="map" data-name="e1" data-name="text1">abc</a>').appendTo('#qunit-fixture'),
newText = '';
$('.map').editable({
validate: {
e: function(value) { if(value == '') return 'required1';
},
e1:function(value) { if(value == '') return 'required2';
},
e2: 'qwerty' //this should not throw error
}
});
e.click();
var p = tip(e);
p.find('input').val(newText);
p.find('form').submit();
ok(p.is(':visible'), 'popover still shown');
ok(p.find('.error').length, 'class "error" exists');
equal(p.find('.editable-error-block').text(), 'required1', 'error msg shown');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
e = e1;
e.click();
var p = tip(e);
p.find('input').val(newText);
p.find('form').submit();
ok(p.is(':visible'), 'popover still shown');
ok(p.find('.error').length, 'class "error" exists');
equal(p.find('.editable-error-block').text(), 'required2', 'error msg shown');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
});
*/
asyncTest("should not perform request if value not changed", function () {
var e = $('<a href="#" data-pk="1" data-url="post-no.php" data-name="text1">abc</a>').appendTo(fx).editable(),
req = 0;
$.mockjax({
url: 'post-no.php',
response: function() {
req++;
}
});
e.click();
var p = tip(e);
ok(p.is(':visible'), 'popover visible');
p.find('button[type=submit]').click();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed');
equal(req, 0, 'request was not performed');
e.remove();
start();
}, timeout);
});
asyncTest("should show error if success callback return string", function () {
var e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo(fx).editable({
success: function(data) {
return 'error';
}
}),
newText = 'cd<e>;"'
e.click()
var p = tip(e);
ok(p.find('input[type=text]').length, 'input exists')
p.find('input').val(newText);
p.find('form').submit();
setTimeout(function() {
ok(p.is(':visible'), 'popover still shown');
ok(p.find('.editable-error-block').length, 'class "editable-error-block" exists');
equal(p.find('.editable-error-block').text(), 'error', 'error msg shown');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
start();
}, timeout);
})
asyncTest("should submit all required params", function () {
var e = $('<a href="#" data-pk="1" data-url="post-resp.php">abc</a>').appendTo(fx).editable({
name: 'username',
params: {
q: 2
},
success: function(resp) {
equal(resp.dataType, 'json', 'dataType ok');
equal(resp.data.pk, 1, 'pk ok');
equal(resp.data.name, 'username', 'name ok');
equal(resp.data.value, newText, 'value ok');
equal(resp.data.q, 2, 'additional params ok');
}
}),
newText = 'cd<e>;"'
e.click()
var p = tip(e);
ok(p.find('input[type=text]').length, 'input exists')
p.find('input').val(newText);
p.find('form').submit();
setTimeout(function() {
e.remove();
start();
}, timeout);
})
asyncTest("should show emptytext if entered text is empty", function () {
var emptytext = 'blabla',
e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1" data-emptytext="'+emptytext+'">abc</a>').appendTo(fx).editable(),
newText = ' ';
e.click()
var p = tip(e);
ok(p.find('input').length, 'input exists')
p.find('input').val(newText);
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed')
equal(e.data('editable').value, newText, 'value is empty')
equal(e.text(), emptytext, 'emptytext shown')
e.remove();
start();
}, timeout);
});
asyncTest("should show responseText on response != 200", function () {
var e = $('<a href="#" data-pk="1" data-name="text1">abc</a>').appendTo(fx).editable({
url: 'error.php'
}),
newText = 'cde';
e.click()
var p = tip(e);
ok(p.find('input').length, 'input exists')
p.find('input').val(newText);
p.find('form').submit();
setTimeout(function() {
ok(p.is(':visible'), 'popover visible')
ok(p.find('.editable-error-block').length, 'class "error" exists')
equal(p.find('.editable-error-block').text(), 'customtext', 'error shown')
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed')
e.remove();
start();
}, timeout);
});
//error callback deprecated in 2.0
/*
asyncTest("'error' callback on response != 200", function () {
var e = $('<a href="#" data-pk="1" data-name="text1">abc</a>').appendTo(fx).editable({
url: 'error.php',
error: function(xhr) {
if(xhr.status == 500) return 'Internal server error';
}
}),
newText = 'cde';
e.click()
var p = tip(e);
ok(p.find('input').length, 'input exists')
p.find('input').val(newText);
p.find('form').submit();
setTimeout(function() {
ok(p.is(':visible'), 'popover visible')
ok(p.find('.error').length, 'class "error" exists')
equal(p.find('.editable-error-block').text(), 'Internal server error', 'error shown')
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed')
e.remove();
start();
}, timeout);
});
*/
test("send: 'auto'. if pk = null --> should save new entered text and value, but no ajax", function () {
var e = $('<a href="#" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable({
send: 'auto'
}),
newText = 'cde';
e.click()
var p = tip(e);
ok(p.find('input').length, 'input exists');
p.find('input').val(newText);
p.find('form').submit();
ok(!p.is(':visible'), 'popover was removed');
equal(e.data('editable').value, newText, 'new text saved to value');
equal(e.text(), newText, 'new text shown');
ok(e.hasClass('editable-unsaved'), 'has class editable-unsaved');
});
test("send = 'never'. if pk defined --> should save new entered text and value, but no ajax", function () {
var e = $('<a href="#" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable({
pk: 123,
send: 'never'
}),
newText = 'cde';
e.click()
var p = tip(e);
ok(p.find('input').length, 'input exists');
p.find('input').val(newText);
p.find('form').submit();
ok(!p.is(':visible'), 'popover was removed');
equal(e.data('editable').value, newText, 'new text saved to value');
equal(e.text(), newText, 'new text shown');
ok(e.hasClass('editable-unsaved'), 'has class editable-unsaved');
});
test("if name not defined --> should be taken from id", function () {
delete $.fn.editable.defaults.name;
var e = $('<a href="#" id="cde">abc</a>').appendTo('#qunit-fixture').editable();
equal(e.data('editable').options.name, 'cde', 'name is taken from id');
});
});

110
test/unit/textarea.js Normal file

@ -0,0 +1,110 @@
$(function () {
var v1 = 'abb&c"',
v2 = "a!b<b>'c";
module("textarea", {
setup: function(){
fx = $('#async-fixture'),
$.fn.editable.defaults.name = 'name1';
}
});
test("textarea should contain '' if element is empty", function () {
var e = $('<a href="#" data-type="textarea"></a>').appendTo('#qunit-fixture').editable()
e.click()
var p = tip(e);
ok(p.find('textarea').length, 'textarea exists')
ok(!p.find('textarea').val().length, 'textrea is empty')
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed')
})
test("placeholder", function () {
var e = $('<a href="#" data-type="textarea"></a>').appendTo('#qunit-fixture').editable({placeholder: 'abc'})
e.click()
var p = tip(e);
equal(p.find('textarea').attr('placeholder'), 'abc', 'placeholder exists');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
})
asyncTest("should load correct value and save new entered text (and value)", function () {
var e = $('<a href="#" data-pk="1" data-url="post.php">'+v1+'</a>').appendTo(fx).editable({
type: 'textarea',
send: 'ifpk',
success: function(data) {
return false;
}
});
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible');
ok(p.find('textarea').length, 'textarea exists');
equal(p.find('textarea').val(), e.data('editable').value, 'textrea val equal text');
p.find('textarea').val(v2);
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed')
equal(e.data('editable').value, v2, 'new text saved to value')
equal(e.text().toLowerCase(), v2.toLowerCase(), 'new text shown')
e.remove();
start();
}, timeout);
})
asyncTest("should replace <br> with newline (on show) and back (on save)", function () {
var v = '12<br>3&lt;i&gt;4<br />56',
e = $('<a href="#" data-type="textarea" data-pk="1" data-url="post.php">'+v+'</a>').appendTo(fx).editable(),
v1 = '12\n3<i>4\n56',
vnew = "12\n3<b>4\n56\n\n78",
vnew2 = "12<br>3&lt;b&gt;4<br>56<br><br>78";
equal(e.data('editable').value, v1, '<br> replaced with new lines');
e.click();
var p = tip(e);
equal(p.find('textarea').val(), e.data('editable').value, 'textarea contains correct value');
p.find('textarea').val(vnew)
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed')
equal(e.data('editable').value, vnew, 'new text saved to value')
equal(e.html().toLowerCase(), vnew2.toLowerCase(), 'new text shown')
e.remove();
start();
}, timeout);
})
asyncTest("submit by ctrl+enter", function () {
expect(2);
var v = '12<br>3&lt;i&gt;4<br />56',
e = $('<a href="#" data-type="textarea" data-pk="1" data-url="post.php">'+v+'</a>').appendTo(fx).editable(),
vnew = 'sdfg',
event;
e.click();
var p = tip(e);
p.find('textarea').val(vnew);
event = jQuery.Event("keydown");
event.ctrlKey = true;
event.which = 13;
p.find('textarea').trigger(event);
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed');
equal(e.data('editable').value, vnew, 'new text saved to value');
e.remove();
start();
}, timeout);
})
})