- Testing (math_test): Fix undeclared variables
- Testing: Move JavaScript out of HTML to own files - Linting: ESLint; unfinished: editor/extensions/, editor/ (root); some of test
This commit is contained in:
@@ -22,13 +22,5 @@
|
||||
<iframe src="coords_test.html" width="100%" height="70" scrolling="no"></iframe>
|
||||
<iframe src="recalculate_test.html" width="100%" height="70" scrolling="no"></iframe>
|
||||
</body>
|
||||
<script>
|
||||
window.setTimeout(function() {
|
||||
var iframes = document.getElementsByTagName('iframe');
|
||||
for (var i = 0, len = iframes.length; i < len; ++i) {
|
||||
var f = iframes[i];
|
||||
f.style.height = (f.contentDocument.body.scrollHeight + 20) + 'px';
|
||||
}
|
||||
}, 5000);
|
||||
</script>
|
||||
<script src="all_tests.js"></script>
|
||||
</html>
|
||||
|
||||
8
test/all_tests.js
Normal file
8
test/all_tests.js
Normal file
@@ -0,0 +1,8 @@
|
||||
/* eslint-disable no-var */
|
||||
window.setTimeout(function () {
|
||||
var iframes = document.getElementsByTagName('iframe');
|
||||
for (var i = 0, len = iframes.length; i < len; ++i) {
|
||||
var f = iframes[i];
|
||||
f.style.height = (f.contentDocument.body.scrollHeight + 20) + 'px';
|
||||
}
|
||||
}, 5000);
|
||||
@@ -11,67 +11,7 @@
|
||||
</script>
|
||||
<script src="../editor/contextmenu.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
function tearDown(){
|
||||
svgedit.contextmenu.resetCustomMenus();
|
||||
}
|
||||
|
||||
module('svgedit.contextmenu');
|
||||
|
||||
test('Test svgedit.contextmenu package', function() {
|
||||
expect(4);
|
||||
|
||||
ok(svgedit.contextmenu,"contextmenu registered correctly");
|
||||
ok(svgedit.contextmenu.add,"contextmenu.add registered correctly");
|
||||
ok(svgedit.contextmenu.hasCustomHandler,"contextmenu hasCustomHandler registered correctly");
|
||||
ok(svgedit.contextmenu.getCustomHandler,"contextmenu getCustomHandler registered correctly");
|
||||
});
|
||||
|
||||
test('Test svgedit.contextmenu does not add invalid menu item', function() {
|
||||
expect(3);
|
||||
|
||||
svgedit.contextmenu.add({id:"justanid"});
|
||||
ok(!svgedit.contextmenu.hasCustomHandler("justanid"),"menu item with just an id is invalid");
|
||||
|
||||
svgedit.contextmenu.add({id:"idandlabel",label:"anicelabel"});
|
||||
ok(!svgedit.contextmenu.hasCustomHandler("idandlabel"),"menu item with just an id and label is invalid");
|
||||
|
||||
svgedit.contextmenu.add({id:"idandlabel",label:"anicelabel",action:'notafunction'});
|
||||
ok(!svgedit.contextmenu.hasCustomHandler("idandlabel"),"menu item with action that is not a function is invalid");
|
||||
});
|
||||
|
||||
test('Test svgedit.contextmenu adds valid menu item', function() {
|
||||
expect(2);
|
||||
|
||||
var validItem = {id:"valid",label:"anicelabel",action:function(){alert('testing')}};
|
||||
svgedit.contextmenu.add(validItem);
|
||||
|
||||
ok(svgedit.contextmenu.hasCustomHandler("valid"),"Valid menu item is added.");
|
||||
equals(svgedit.contextmenu.getCustomHandler("valid"),validItem.action,"Valid menu action is added.");
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test svgedit.contextmenu rejects valid duplicate menu item id', function() {
|
||||
expect(1);
|
||||
|
||||
var validItem1 = {id:"valid",label:"anicelabel",action:function(){alert('testing')}};
|
||||
var validItem2 = {id:"valid",label:"anicelabel",action:function(){alert('testingtwice')}};
|
||||
svgedit.contextmenu.add(validItem1);
|
||||
svgedit.contextmenu.add(validItem2);
|
||||
|
||||
equals(svgedit.contextmenu.getCustomHandler("valid"),validItem1.action,"duplicate menu item is rejected.");
|
||||
tearDown();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script src="contextmenu_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for contextmenu.js</h1>
|
||||
|
||||
62
test/contextmenu_test.js
Normal file
62
test/contextmenu_test.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/* eslint-disable no-var */
|
||||
/* eslint-env qunit */
|
||||
/* globals svgedit, $, equals */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
function tearDown () {
|
||||
svgedit.contextmenu.resetCustomMenus();
|
||||
}
|
||||
|
||||
module('svgedit.contextmenu');
|
||||
|
||||
test('Test svgedit.contextmenu package', function () {
|
||||
expect(4);
|
||||
|
||||
ok(svgedit.contextmenu, 'contextmenu registered correctly');
|
||||
ok(svgedit.contextmenu.add, 'contextmenu.add registered correctly');
|
||||
ok(svgedit.contextmenu.hasCustomHandler, 'contextmenu hasCustomHandler registered correctly');
|
||||
ok(svgedit.contextmenu.getCustomHandler, 'contextmenu getCustomHandler registered correctly');
|
||||
});
|
||||
|
||||
test('Test svgedit.contextmenu does not add invalid menu item', function () {
|
||||
expect(3);
|
||||
|
||||
svgedit.contextmenu.add({id: 'justanid'});
|
||||
ok(!svgedit.contextmenu.hasCustomHandler('justanid'), 'menu item with just an id is invalid');
|
||||
|
||||
svgedit.contextmenu.add({id: 'idandlabel', label: 'anicelabel'});
|
||||
ok(!svgedit.contextmenu.hasCustomHandler('idandlabel'), 'menu item with just an id and label is invalid');
|
||||
|
||||
svgedit.contextmenu.add({id: 'idandlabel', label: 'anicelabel', action: 'notafunction'});
|
||||
ok(!svgedit.contextmenu.hasCustomHandler('idandlabel'), 'menu item with action that is not a function is invalid');
|
||||
});
|
||||
|
||||
test('Test svgedit.contextmenu adds valid menu item', function () {
|
||||
expect(2);
|
||||
|
||||
var validItem = {id: 'valid', label: 'anicelabel', action: function () { alert('testing'); }};
|
||||
svgedit.contextmenu.add(validItem);
|
||||
|
||||
ok(svgedit.contextmenu.hasCustomHandler('valid'), 'Valid menu item is added.');
|
||||
equals(svgedit.contextmenu.getCustomHandler('valid'), validItem.action, 'Valid menu action is added.');
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test svgedit.contextmenu rejects valid duplicate menu item id', function () {
|
||||
expect(1);
|
||||
|
||||
var validItem1 = {id: 'valid', label: 'anicelabel', action: function () { alert('testing'); }};
|
||||
var validItem2 = {id: 'valid', label: 'anicelabel', action: function () { alert('testingtwice'); }};
|
||||
svgedit.contextmenu.add(validItem1);
|
||||
svgedit.contextmenu.add(validItem2);
|
||||
|
||||
equals(svgedit.contextmenu.getCustomHandler('valid'), validItem1.action, 'duplicate menu item is rejected.');
|
||||
tearDown();
|
||||
});
|
||||
});
|
||||
@@ -15,341 +15,7 @@
|
||||
<script src="../editor/coords.js"></script>
|
||||
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var root = document.getElementById('root');
|
||||
var svgroot = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
svgroot.id = 'svgroot';
|
||||
root.appendChild(svgroot);
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
svgroot.appendChild(svg);
|
||||
var elemId = 1;
|
||||
|
||||
function setUp() {
|
||||
// Mock out editor context.
|
||||
svgedit.utilities.init({
|
||||
getSVGRoot: function() { return svg },
|
||||
getDOMDocument: function() { return null },
|
||||
getDOMContainer: function() { return null }
|
||||
});
|
||||
svgedit.coords.init({
|
||||
getGridSnapping: function() { return false; },
|
||||
getDrawing: function() {
|
||||
return {
|
||||
getNextId: function() { return '' + elemId++; }
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
while(svg.hasChildNodes()) {
|
||||
svg.removeChild(svg.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
test('Test remapElement(translate) for rect', function() {
|
||||
expect(4);
|
||||
|
||||
setUp();
|
||||
|
||||
var rect = document.createElementNS(svgedit.NS.SVG, 'rect');
|
||||
rect.setAttribute('x', '200');
|
||||
rect.setAttribute('y', '150');
|
||||
rect.setAttribute('width', '250');
|
||||
rect.setAttribute('height', '120');
|
||||
svg.appendChild(rect);
|
||||
|
||||
var attrs = {
|
||||
x: '200',
|
||||
y: '150',
|
||||
width: '125',
|
||||
height: '75'
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
|
||||
svgedit.coords.remapElement(rect, attrs, m);
|
||||
|
||||
equals(rect.getAttribute('x'), '300');
|
||||
equals(rect.getAttribute('y'), '100');
|
||||
equals(rect.getAttribute('width'), '125');
|
||||
equals(rect.getAttribute('height'), '75');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(scale) for rect', function() {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var rect = document.createElementNS(svgedit.NS.SVG, 'rect');
|
||||
rect.setAttribute('width', '250');
|
||||
rect.setAttribute('height', '120');
|
||||
svg.appendChild(rect);
|
||||
|
||||
var attrs = {
|
||||
x: '0',
|
||||
y: '0',
|
||||
width: '250',
|
||||
height: '120'
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
|
||||
svgedit.coords.remapElement(rect, attrs, m);
|
||||
|
||||
equals(rect.getAttribute('x'), '0');
|
||||
equals(rect.getAttribute('y'), '0');
|
||||
equals(rect.getAttribute('width'), '500');
|
||||
equals(rect.getAttribute('height'), '60');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(translate) for circle', function() {
|
||||
expect(3);
|
||||
setUp();
|
||||
|
||||
var circle = document.createElementNS(svgedit.NS.SVG, 'circle');
|
||||
circle.setAttribute('cx', '200');
|
||||
circle.setAttribute('cy', '150');
|
||||
circle.setAttribute('r', '125');
|
||||
svg.appendChild(circle);
|
||||
|
||||
var attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
r: '125'
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
|
||||
svgedit.coords.remapElement(circle, attrs, m);
|
||||
|
||||
equals(circle.getAttribute('cx'), '300');
|
||||
equals(circle.getAttribute('cy'), '100');
|
||||
equals(circle.getAttribute('r'), '125');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(scale) for circle', function() {
|
||||
expect(3);
|
||||
setUp();
|
||||
|
||||
var circle = document.createElementNS(svgedit.NS.SVG, 'circle');
|
||||
circle.setAttribute('cx', '200');
|
||||
circle.setAttribute('cy', '150');
|
||||
circle.setAttribute('r', '250');
|
||||
svg.appendChild(circle);
|
||||
|
||||
var attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
r: '250'
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
|
||||
svgedit.coords.remapElement(circle, attrs, m);
|
||||
|
||||
equals(circle.getAttribute('cx'), '400');
|
||||
equals(circle.getAttribute('cy'), '75');
|
||||
// Radius is the minimum that fits in the new bounding box.
|
||||
equals(circle.getAttribute('r'), '125');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(translate) for ellipse', function() {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var ellipse = document.createElementNS(svgedit.NS.SVG, 'ellipse');
|
||||
ellipse.setAttribute('cx', '200');
|
||||
ellipse.setAttribute('cy', '150');
|
||||
ellipse.setAttribute('rx', '125');
|
||||
ellipse.setAttribute('ry', '75');
|
||||
svg.appendChild(ellipse);
|
||||
|
||||
var attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
rx: '125',
|
||||
ry: '75'
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
|
||||
svgedit.coords.remapElement(ellipse, attrs, m);
|
||||
|
||||
equals(ellipse.getAttribute('cx'), '300');
|
||||
equals(ellipse.getAttribute('cy'), '100');
|
||||
equals(ellipse.getAttribute('rx'), '125');
|
||||
equals(ellipse.getAttribute('ry'), '75');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(scale) for ellipse', function() {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var ellipse = document.createElementNS(svgedit.NS.SVG, 'ellipse');
|
||||
ellipse.setAttribute('cx', '200');
|
||||
ellipse.setAttribute('cy', '150');
|
||||
ellipse.setAttribute('rx', '250');
|
||||
ellipse.setAttribute('ry', '120');
|
||||
svg.appendChild(ellipse);
|
||||
|
||||
var attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
rx: '250',
|
||||
ry: '120'
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
|
||||
svgedit.coords.remapElement(ellipse, attrs, m);
|
||||
|
||||
equals(ellipse.getAttribute('cx'), '400');
|
||||
equals(ellipse.getAttribute('cy'), '75');
|
||||
equals(ellipse.getAttribute('rx'), '500');
|
||||
equals(ellipse.getAttribute('ry'), '60');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(translate) for line', function() {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var line = document.createElementNS(svgedit.NS.SVG, 'line');
|
||||
line.setAttribute('x1', '50');
|
||||
line.setAttribute('y1', '100');
|
||||
line.setAttribute('x2', '120');
|
||||
line.setAttribute('y2', '200');
|
||||
svg.appendChild(line);
|
||||
|
||||
var attrs = {
|
||||
x1: '50',
|
||||
y1: '100',
|
||||
x2: '120',
|
||||
y2: '200'
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
|
||||
svgedit.coords.remapElement(line, attrs, m);
|
||||
|
||||
equals(line.getAttribute('x1'), '150');
|
||||
equals(line.getAttribute('y1'), '50');
|
||||
equals(line.getAttribute('x2'), '220');
|
||||
equals(line.getAttribute('y2'), '150');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(scale) for line', function() {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var line = document.createElementNS(svgedit.NS.SVG, 'line');
|
||||
line.setAttribute('x1', '50');
|
||||
line.setAttribute('y1', '100');
|
||||
line.setAttribute('x2', '120');
|
||||
line.setAttribute('y2', '200');
|
||||
svg.appendChild(line);
|
||||
|
||||
var attrs = {
|
||||
x1: '50',
|
||||
y1: '100',
|
||||
x2: '120',
|
||||
y2: '200'
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
|
||||
svgedit.coords.remapElement(line, attrs, m);
|
||||
|
||||
equals(line.getAttribute('x1'), '100');
|
||||
equals(line.getAttribute('y1'), '50');
|
||||
equals(line.getAttribute('x2'), '240');
|
||||
equals(line.getAttribute('y2'), '100');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(translate) for text', function() {
|
||||
expect(2);
|
||||
setUp();
|
||||
|
||||
var text = document.createElementNS(svgedit.NS.SVG, 'text');
|
||||
text.setAttribute('x', '50');
|
||||
text.setAttribute('y', '100');
|
||||
svg.appendChild(text);
|
||||
|
||||
var attrs = {
|
||||
x: '50',
|
||||
y: '100'
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
|
||||
svgedit.coords.remapElement(text, attrs, m);
|
||||
|
||||
equals(text.getAttribute('x'), '150');
|
||||
equals(text.getAttribute('y'), '50');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script src="coords_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for svgedit.coords</h1>
|
||||
|
||||
336
test/coords_test.js
Normal file
336
test/coords_test.js
Normal file
@@ -0,0 +1,336 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit, equals */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var root = document.getElementById('root');
|
||||
var svgroot = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
svgroot.id = 'svgroot';
|
||||
root.appendChild(svgroot);
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
svgroot.appendChild(svg);
|
||||
var elemId = 1;
|
||||
|
||||
function setUp () {
|
||||
// Mock out editor context.
|
||||
svgedit.utilities.init({
|
||||
getSVGRoot: function () { return svg; },
|
||||
getDOMDocument: function () { return null; },
|
||||
getDOMContainer: function () { return null; }
|
||||
});
|
||||
svgedit.coords.init({
|
||||
getGridSnapping: function () { return false; },
|
||||
getDrawing: function () {
|
||||
return {
|
||||
getNextId: function () { return '' + elemId++; }
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function tearDown () {
|
||||
while (svg.hasChildNodes()) {
|
||||
svg.removeChild(svg.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
test('Test remapElement(translate) for rect', function () {
|
||||
expect(4);
|
||||
|
||||
setUp();
|
||||
|
||||
var rect = document.createElementNS(svgedit.NS.SVG, 'rect');
|
||||
rect.setAttribute('x', '200');
|
||||
rect.setAttribute('y', '150');
|
||||
rect.setAttribute('width', '250');
|
||||
rect.setAttribute('height', '120');
|
||||
svg.appendChild(rect);
|
||||
|
||||
var attrs = {
|
||||
x: '200',
|
||||
y: '150',
|
||||
width: '125',
|
||||
height: '75'
|
||||
};
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
|
||||
svgedit.coords.remapElement(rect, attrs, m);
|
||||
|
||||
equals(rect.getAttribute('x'), '300');
|
||||
equals(rect.getAttribute('y'), '100');
|
||||
equals(rect.getAttribute('width'), '125');
|
||||
equals(rect.getAttribute('height'), '75');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(scale) for rect', function () {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var rect = document.createElementNS(svgedit.NS.SVG, 'rect');
|
||||
rect.setAttribute('width', '250');
|
||||
rect.setAttribute('height', '120');
|
||||
svg.appendChild(rect);
|
||||
|
||||
var attrs = {
|
||||
x: '0',
|
||||
y: '0',
|
||||
width: '250',
|
||||
height: '120'
|
||||
};
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
|
||||
svgedit.coords.remapElement(rect, attrs, m);
|
||||
|
||||
equals(rect.getAttribute('x'), '0');
|
||||
equals(rect.getAttribute('y'), '0');
|
||||
equals(rect.getAttribute('width'), '500');
|
||||
equals(rect.getAttribute('height'), '60');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(translate) for circle', function () {
|
||||
expect(3);
|
||||
setUp();
|
||||
|
||||
var circle = document.createElementNS(svgedit.NS.SVG, 'circle');
|
||||
circle.setAttribute('cx', '200');
|
||||
circle.setAttribute('cy', '150');
|
||||
circle.setAttribute('r', '125');
|
||||
svg.appendChild(circle);
|
||||
|
||||
var attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
r: '125'
|
||||
};
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
|
||||
svgedit.coords.remapElement(circle, attrs, m);
|
||||
|
||||
equals(circle.getAttribute('cx'), '300');
|
||||
equals(circle.getAttribute('cy'), '100');
|
||||
equals(circle.getAttribute('r'), '125');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(scale) for circle', function () {
|
||||
expect(3);
|
||||
setUp();
|
||||
|
||||
var circle = document.createElementNS(svgedit.NS.SVG, 'circle');
|
||||
circle.setAttribute('cx', '200');
|
||||
circle.setAttribute('cy', '150');
|
||||
circle.setAttribute('r', '250');
|
||||
svg.appendChild(circle);
|
||||
|
||||
var attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
r: '250'
|
||||
};
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
|
||||
svgedit.coords.remapElement(circle, attrs, m);
|
||||
|
||||
equals(circle.getAttribute('cx'), '400');
|
||||
equals(circle.getAttribute('cy'), '75');
|
||||
// Radius is the minimum that fits in the new bounding box.
|
||||
equals(circle.getAttribute('r'), '125');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(translate) for ellipse', function () {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var ellipse = document.createElementNS(svgedit.NS.SVG, 'ellipse');
|
||||
ellipse.setAttribute('cx', '200');
|
||||
ellipse.setAttribute('cy', '150');
|
||||
ellipse.setAttribute('rx', '125');
|
||||
ellipse.setAttribute('ry', '75');
|
||||
svg.appendChild(ellipse);
|
||||
|
||||
var attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
rx: '125',
|
||||
ry: '75'
|
||||
};
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
|
||||
svgedit.coords.remapElement(ellipse, attrs, m);
|
||||
|
||||
equals(ellipse.getAttribute('cx'), '300');
|
||||
equals(ellipse.getAttribute('cy'), '100');
|
||||
equals(ellipse.getAttribute('rx'), '125');
|
||||
equals(ellipse.getAttribute('ry'), '75');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(scale) for ellipse', function () {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var ellipse = document.createElementNS(svgedit.NS.SVG, 'ellipse');
|
||||
ellipse.setAttribute('cx', '200');
|
||||
ellipse.setAttribute('cy', '150');
|
||||
ellipse.setAttribute('rx', '250');
|
||||
ellipse.setAttribute('ry', '120');
|
||||
svg.appendChild(ellipse);
|
||||
|
||||
var attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
rx: '250',
|
||||
ry: '120'
|
||||
};
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
|
||||
svgedit.coords.remapElement(ellipse, attrs, m);
|
||||
|
||||
equals(ellipse.getAttribute('cx'), '400');
|
||||
equals(ellipse.getAttribute('cy'), '75');
|
||||
equals(ellipse.getAttribute('rx'), '500');
|
||||
equals(ellipse.getAttribute('ry'), '60');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(translate) for line', function () {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var line = document.createElementNS(svgedit.NS.SVG, 'line');
|
||||
line.setAttribute('x1', '50');
|
||||
line.setAttribute('y1', '100');
|
||||
line.setAttribute('x2', '120');
|
||||
line.setAttribute('y2', '200');
|
||||
svg.appendChild(line);
|
||||
|
||||
var attrs = {
|
||||
x1: '50',
|
||||
y1: '100',
|
||||
x2: '120',
|
||||
y2: '200'
|
||||
};
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
|
||||
svgedit.coords.remapElement(line, attrs, m);
|
||||
|
||||
equals(line.getAttribute('x1'), '150');
|
||||
equals(line.getAttribute('y1'), '50');
|
||||
equals(line.getAttribute('x2'), '220');
|
||||
equals(line.getAttribute('y2'), '150');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(scale) for line', function () {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var line = document.createElementNS(svgedit.NS.SVG, 'line');
|
||||
line.setAttribute('x1', '50');
|
||||
line.setAttribute('y1', '100');
|
||||
line.setAttribute('x2', '120');
|
||||
line.setAttribute('y2', '200');
|
||||
svg.appendChild(line);
|
||||
|
||||
var attrs = {
|
||||
x1: '50',
|
||||
y1: '100',
|
||||
x2: '120',
|
||||
y2: '200'
|
||||
};
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
|
||||
svgedit.coords.remapElement(line, attrs, m);
|
||||
|
||||
equals(line.getAttribute('x1'), '100');
|
||||
equals(line.getAttribute('y1'), '50');
|
||||
equals(line.getAttribute('x2'), '240');
|
||||
equals(line.getAttribute('y2'), '100');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test remapElement(translate) for text', function () {
|
||||
expect(2);
|
||||
setUp();
|
||||
|
||||
var text = document.createElementNS(svgedit.NS.SVG, 'text');
|
||||
text.setAttribute('x', '50');
|
||||
text.setAttribute('y', '100');
|
||||
svg.appendChild(text);
|
||||
|
||||
var attrs = {
|
||||
x: '50',
|
||||
y: '100'
|
||||
};
|
||||
|
||||
// Create a translate.
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
|
||||
svgedit.coords.remapElement(text, attrs, m);
|
||||
|
||||
equals(text.getAttribute('x'), '150');
|
||||
equals(text.getAttribute('y'), '50');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
});
|
||||
@@ -15,802 +15,7 @@
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script src="sinon/sinon-1.17.3.js"></script>
|
||||
<script src="sinon/sinon-qunit-1.0.0.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
var NS = svgedit.NS;
|
||||
var LAYER_CLASS = svgedit.draw.Layer.CLASS_NAME;
|
||||
var NONCE = 'foo';
|
||||
var LAYER1 = 'Layer 1';
|
||||
var LAYER2 = 'Layer 2';
|
||||
var LAYER3 = 'Layer 3';
|
||||
var PATH_ATTR = {
|
||||
// clone will convert relative to absolute, so the test for equality fails.
|
||||
//'d': 'm7.38867,57.38867c0,-27.62431 22.37569,-50 50,-50c27.62431,0 50,22.37569 50,50c0,27.62431 -22.37569,50 -50,50c-27.62431,0 -50,-22.37569 -50,-50z',
|
||||
'd': 'M7.389,57.389C7.389,29.764 29.764,7.389 57.389,7.389C85.013,7.389 107.389,29.764 107.389,57.389C107.389,85.013 85.013,107.389 57.389,107.389C29.764,107.389 7.389,85.013 7.389,57.389z',
|
||||
'transform': 'rotate(45 57.388671875000036,57.388671874999986) ',
|
||||
'stroke-width': '5',
|
||||
'stroke': '#660000',
|
||||
'fill':'#ff0000'
|
||||
};
|
||||
|
||||
var svg = document.createElementNS(NS.SVG, 'svg');
|
||||
var sandbox = document.getElementById('sandbox');
|
||||
// Firefox throws exception in getBBox() when svg is not attached to DOM.
|
||||
sandbox.appendChild(svg);
|
||||
|
||||
// Set up <svg> with nonce.
|
||||
var svg_n = document.createElementNS(NS.SVG, 'svg');
|
||||
svg_n.setAttributeNS(NS.XMLNS, 'xmlns:se', NS.SE);
|
||||
svg_n.setAttributeNS(NS.SE, 'se:nonce', NONCE);
|
||||
|
||||
svgedit.units.init({
|
||||
// used by svgedit.units.shortFloat - call path: cloneLayer -> copyElem -> convertPath -> pathDSegment -> shortFloat
|
||||
getRoundDigits: function() { return 3; }
|
||||
});
|
||||
|
||||
function createSVGElement(jsonMap) {
|
||||
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||
for (var attr in jsonMap['attr']) {
|
||||
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
var setupSvgWith3Layers = function(svgElem) {
|
||||
var layer1 = document.createElementNS(NS.SVG, 'g');
|
||||
var layer1_title = document.createElementNS(NS.SVG, 'title');
|
||||
layer1_title.appendChild(document.createTextNode(LAYER1));
|
||||
layer1.appendChild(layer1_title);
|
||||
svgElem.appendChild(layer1);
|
||||
|
||||
var layer2 = document.createElementNS(NS.SVG, 'g');
|
||||
var layer2_title = document.createElementNS(NS.SVG, 'title');
|
||||
layer2_title.appendChild(document.createTextNode(LAYER2));
|
||||
layer2.appendChild(layer2_title);
|
||||
svgElem.appendChild(layer2);
|
||||
|
||||
var layer3 = document.createElementNS(NS.SVG, 'g');
|
||||
var layer3_title = document.createElementNS(NS.SVG, 'title');
|
||||
layer3_title.appendChild(document.createTextNode(LAYER3));
|
||||
layer3.appendChild(layer3_title);
|
||||
svgElem.appendChild(layer3);
|
||||
|
||||
return [layer1, layer2, layer3];
|
||||
};
|
||||
|
||||
var createSomeElementsInGroup = function(group) {
|
||||
group.appendChild(createSVGElement({
|
||||
'element': 'path',
|
||||
'attr': PATH_ATTR
|
||||
}));
|
||||
// group.appendChild(createSVGElement({
|
||||
// 'element': 'path',
|
||||
// 'attr': {'d': 'M0,1L2,3'}
|
||||
// }));
|
||||
group.appendChild(createSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
}));
|
||||
group.appendChild(createSVGElement({
|
||||
'element': 'line',
|
||||
'attr': {'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||
}));
|
||||
|
||||
var g = createSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {}
|
||||
});
|
||||
g.appendChild(createSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
}));
|
||||
group.appendChild(g);
|
||||
return 4;
|
||||
};
|
||||
|
||||
var cleanupSvg = function(svgElem) {
|
||||
while(svgElem.firstChild) {svgElem.removeChild(svgElem.firstChild);}
|
||||
};
|
||||
|
||||
module('svgedit.draw.Drawing', {
|
||||
setup: function() {
|
||||
},
|
||||
teardown: function() {
|
||||
}
|
||||
});
|
||||
|
||||
test('Test draw module', function() {
|
||||
expect(4);
|
||||
|
||||
ok(svgedit.draw);
|
||||
equals(typeof svgedit.draw, typeof {});
|
||||
|
||||
ok(svgedit.draw.Drawing);
|
||||
equals(typeof svgedit.draw.Drawing, typeof function(){});
|
||||
});
|
||||
|
||||
test('Test document creation', function() {
|
||||
expect(3);
|
||||
|
||||
try {
|
||||
var doc = new svgedit.draw.Drawing();
|
||||
ok(false, 'Created drawing without a valid <svg> element');
|
||||
} catch(e) {
|
||||
ok(true);
|
||||
}
|
||||
|
||||
try {
|
||||
var doc = new svgedit.draw.Drawing(svg);
|
||||
ok(doc);
|
||||
equals(typeof doc, typeof {});
|
||||
} catch(e) {
|
||||
ok(false, 'Could not create document from valid <svg> element: ' + e)
|
||||
}
|
||||
});
|
||||
|
||||
test('Test nonce', function() {
|
||||
expect(7);
|
||||
|
||||
var doc = new svgedit.draw.Drawing(svg);
|
||||
equals(doc.getNonce(), "");
|
||||
|
||||
doc = new svgedit.draw.Drawing(svg_n);
|
||||
equals(doc.getNonce(), NONCE);
|
||||
equals(doc.getSvgElem().getAttributeNS(NS.SE, 'nonce'), NONCE);
|
||||
|
||||
doc.clearNonce();
|
||||
ok(!doc.getNonce());
|
||||
ok(!doc.getSvgElem().getAttributeNS(NS.SE, 'se:nonce'));
|
||||
|
||||
doc.setNonce(NONCE);
|
||||
equals(doc.getNonce(), NONCE);
|
||||
equals(doc.getSvgElem().getAttributeNS(NS.SE, 'nonce'), NONCE);
|
||||
});
|
||||
|
||||
test('Test getId() and getNextId() without nonce', function() {
|
||||
expect(7);
|
||||
|
||||
var elem2 = document.createElementNS(NS.SVG, 'circle');
|
||||
elem2.id = 'svg_2';
|
||||
svg.appendChild(elem2);
|
||||
|
||||
var doc = new svgedit.draw.Drawing(svg);
|
||||
|
||||
equals(doc.getId(), "svg_0");
|
||||
|
||||
equals(doc.getNextId(), "svg_1");
|
||||
equals(doc.getId(), "svg_1");
|
||||
|
||||
equals(doc.getNextId(), "svg_3");
|
||||
equals(doc.getId(), "svg_3");
|
||||
|
||||
equals(doc.getNextId(), "svg_4");
|
||||
equals(doc.getId(), "svg_4");
|
||||
// clean out svg document
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getId() and getNextId() with prefix without nonce', function() {
|
||||
expect(7);
|
||||
|
||||
var prefix = 'Bar-';
|
||||
var doc = new svgedit.draw.Drawing(svg, prefix);
|
||||
|
||||
equals(doc.getId(), prefix+"0");
|
||||
|
||||
equals(doc.getNextId(), prefix+"1");
|
||||
equals(doc.getId(), prefix+"1");
|
||||
|
||||
equals(doc.getNextId(), prefix+"2");
|
||||
equals(doc.getId(), prefix+"2");
|
||||
|
||||
equals(doc.getNextId(), prefix+"3");
|
||||
equals(doc.getId(), prefix+"3");
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getId() and getNextId() with nonce', function() {
|
||||
expect(7);
|
||||
|
||||
var prefix = "svg_" + NONCE;
|
||||
|
||||
var elem2 = document.createElementNS(NS.SVG, 'circle');
|
||||
elem2.id = prefix+'_2';
|
||||
svg_n.appendChild(elem2);
|
||||
|
||||
var doc = new svgedit.draw.Drawing(svg_n);
|
||||
|
||||
equals(doc.getId(), prefix+"_0");
|
||||
|
||||
equals(doc.getNextId(), prefix+"_1");
|
||||
equals(doc.getId(), prefix+"_1");
|
||||
|
||||
equals(doc.getNextId(), prefix+"_3");
|
||||
equals(doc.getId(), prefix+"_3");
|
||||
|
||||
equals(doc.getNextId(), prefix+"_4");
|
||||
equals(doc.getId(), prefix+"_4");
|
||||
|
||||
cleanupSvg(svg_n);
|
||||
});
|
||||
|
||||
test('Test getId() and getNextId() with prefix with nonce', function() {
|
||||
expect(7);
|
||||
|
||||
var PREFIX = 'Bar-';
|
||||
var doc = new svgedit.draw.Drawing(svg_n, PREFIX);
|
||||
|
||||
var prefix = PREFIX + NONCE + "_";
|
||||
equals(doc.getId(), prefix+"0");
|
||||
|
||||
equals(doc.getNextId(), prefix+"1");
|
||||
equals(doc.getId(), prefix+"1");
|
||||
|
||||
equals(doc.getNextId(), prefix+"2");
|
||||
equals(doc.getId(), prefix+"2");
|
||||
|
||||
equals(doc.getNextId(), prefix+"3");
|
||||
equals(doc.getId(), prefix+"3");
|
||||
|
||||
cleanupSvg(svg_n);
|
||||
});
|
||||
|
||||
test('Test releaseId()', function() {
|
||||
expect(6);
|
||||
|
||||
var doc = new svgedit.draw.Drawing(svg);
|
||||
|
||||
var firstId = doc.getNextId();
|
||||
var secondId = doc.getNextId();
|
||||
|
||||
var result = doc.releaseId(firstId);
|
||||
ok(result);
|
||||
equals(doc.getNextId(), firstId);
|
||||
equals(doc.getNextId(), "svg_3");
|
||||
|
||||
ok(!doc.releaseId("bad-id"));
|
||||
ok(doc.releaseId(firstId));
|
||||
ok(!doc.releaseId(firstId));
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getNumLayers', function() {
|
||||
expect(3);
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
equals(typeof drawing.getNumLayers, typeof function() {});
|
||||
equals(drawing.getNumLayers(), 0);
|
||||
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
equals(drawing.getNumLayers(), 3);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test hasLayer', function() {
|
||||
expect(5);
|
||||
|
||||
setupSvgWith3Layers(svg);
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
equals(typeof drawing.hasLayer, typeof function() {});
|
||||
ok(!drawing.hasLayer('invalid-layer'));
|
||||
|
||||
ok(drawing.hasLayer(LAYER3));
|
||||
ok(drawing.hasLayer(LAYER2));
|
||||
ok(drawing.hasLayer(LAYER1));
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test identifyLayers() with empty document', function() {
|
||||
expect(11);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
equals(drawing.getCurrentLayer(), null);
|
||||
// By default, an empty document gets an empty group created.
|
||||
drawing.identifyLayers();
|
||||
|
||||
// Check that <svg> element now has one child node
|
||||
ok(drawing.getSvgElem().hasChildNodes());
|
||||
equals(drawing.getSvgElem().childNodes.length, 1);
|
||||
|
||||
// Check that all_layers are correctly set up.
|
||||
equals(drawing.getNumLayers(), 1);
|
||||
var empty_layer = drawing.all_layers[0];
|
||||
ok(empty_layer);
|
||||
var layerGroup = empty_layer.getGroup();
|
||||
equals(layerGroup, drawing.getSvgElem().firstChild);
|
||||
equals(layerGroup.tagName, 'g');
|
||||
equals(layerGroup.getAttribute('class'), LAYER_CLASS);
|
||||
ok(layerGroup.hasChildNodes());
|
||||
equals(layerGroup.childNodes.length, 1);
|
||||
var firstChild = layerGroup.childNodes.item(0);
|
||||
equals(firstChild.tagName, 'title');
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test identifyLayers() with some layers', function() {
|
||||
expect(8);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
|
||||
equals(svg.childNodes.length, 3);
|
||||
|
||||
drawing.identifyLayers();
|
||||
|
||||
equals(drawing.getNumLayers(), 3);
|
||||
equals(drawing.all_layers[0].getGroup(), svg.childNodes.item(0));
|
||||
equals(drawing.all_layers[1].getGroup(), svg.childNodes.item(1));
|
||||
equals(drawing.all_layers[2].getGroup(), svg.childNodes.item(2));
|
||||
|
||||
equals(drawing.all_layers[0].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
equals(drawing.all_layers[1].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
equals(drawing.all_layers[2].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test identifyLayers() with some layers and orphans', function() {
|
||||
expect(14);
|
||||
|
||||
setupSvgWith3Layers(svg);
|
||||
|
||||
var orphan1 = document.createElementNS(NS.SVG, 'rect');
|
||||
var orphan2 = document.createElementNS(NS.SVG, 'rect');
|
||||
svg.appendChild(orphan1);
|
||||
svg.appendChild(orphan2);
|
||||
|
||||
equals(svg.childNodes.length, 5);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
equals(drawing.getNumLayers(), 4);
|
||||
equals(drawing.all_layers[0].getGroup(), svg.childNodes.item(0));
|
||||
equals(drawing.all_layers[1].getGroup(), svg.childNodes.item(1));
|
||||
equals(drawing.all_layers[2].getGroup(), svg.childNodes.item(2));
|
||||
equals(drawing.all_layers[3].getGroup(), svg.childNodes.item(3));
|
||||
|
||||
equals(drawing.all_layers[0].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
equals(drawing.all_layers[1].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
equals(drawing.all_layers[2].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
equals(drawing.all_layers[3].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
|
||||
var layer4 = drawing.all_layers[3].getGroup();
|
||||
equals(layer4.tagName, 'g');
|
||||
equals(layer4.childNodes.length, 3);
|
||||
equals(layer4.childNodes.item(1), orphan1);
|
||||
equals(layer4.childNodes.item(2), orphan2);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getLayerName()', function() {
|
||||
expect(4);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
|
||||
drawing.identifyLayers();
|
||||
|
||||
equals(drawing.getNumLayers(), 3);
|
||||
equals(drawing.getLayerName(0), LAYER1);
|
||||
equals(drawing.getLayerName(1), LAYER2);
|
||||
equals(drawing.getLayerName(2), LAYER3);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getCurrentLayer()', function() {
|
||||
expect(4);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.getCurrentLayer);
|
||||
equals(typeof drawing.getCurrentLayer, typeof function(){});
|
||||
ok(drawing.getCurrentLayer());
|
||||
equals(drawing.getCurrentLayer(), drawing.all_layers[2].getGroup());
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test setCurrentLayer() and getCurrentLayerName()', function() {
|
||||
expect(6);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.setCurrentLayer);
|
||||
equals(typeof drawing.setCurrentLayer, typeof function(){});
|
||||
|
||||
drawing.setCurrentLayer(LAYER2);
|
||||
equals(drawing.getCurrentLayerName(), LAYER2);
|
||||
equals(drawing.getCurrentLayer(), drawing.all_layers[1].getGroup());
|
||||
|
||||
drawing.setCurrentLayer(LAYER3);
|
||||
equals(drawing.getCurrentLayerName(), LAYER3);
|
||||
equals(drawing.getCurrentLayer(), drawing.all_layers[2].getGroup());
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test setCurrentLayerName()', function() {
|
||||
|
||||
var mockHrService = {
|
||||
changeElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.setCurrentLayerName);
|
||||
equals(typeof drawing.setCurrentLayerName, typeof function(){});
|
||||
|
||||
var oldName = drawing.getCurrentLayerName();
|
||||
var newName = 'New Name'
|
||||
ok(drawing.layer_map[oldName]);
|
||||
equals(drawing.layer_map[newName], undefined); // newName shouldn't exist.
|
||||
var result = drawing.setCurrentLayerName(newName, mockHrService);
|
||||
equals(result, newName);
|
||||
equals(drawing.getCurrentLayerName(), newName);
|
||||
// Was the map updated?
|
||||
equals(drawing.layer_map[oldName], undefined);
|
||||
equals(drawing.layer_map[newName], drawing.current_layer);
|
||||
// Was mockHrService called?
|
||||
ok(mockHrService.changeElement.calledOnce);
|
||||
equals(oldName, mockHrService.changeElement.getCall(0).args[1]['#text']);
|
||||
equals(newName, mockHrService.changeElement.getCall(0).args[0].textContent);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test createLayer()', function() {
|
||||
expect(10);
|
||||
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
insertElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.createLayer);
|
||||
equals(typeof drawing.createLayer, typeof function(){});
|
||||
|
||||
var NEW_LAYER_NAME = 'Layer A';
|
||||
var layer_g = drawing.createLayer(NEW_LAYER_NAME, mockHrService);
|
||||
equals(drawing.getNumLayers(), 4);
|
||||
equals(layer_g, drawing.getCurrentLayer());
|
||||
equals(layer_g.getAttribute('class'), LAYER_CLASS);
|
||||
equals(NEW_LAYER_NAME, drawing.getCurrentLayerName());
|
||||
equals(NEW_LAYER_NAME, drawing.getLayerName(3));
|
||||
|
||||
equals(layer_g, mockHrService.insertElement.getCall(0).args[0]);
|
||||
ok(mockHrService.startBatchCommand.calledOnce);
|
||||
ok(mockHrService.endBatchCommand.calledOnce);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test mergeLayer()', function() {
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
moveElement: this.spy(),
|
||||
removeElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
var layers = setupSvgWith3Layers(svg);
|
||||
var elementCount = createSomeElementsInGroup(layers[2]) + 1; // +1 for title element
|
||||
equals(layers[1].childElementCount, 1);
|
||||
equals(layers[2].childElementCount, elementCount);
|
||||
drawing.identifyLayers();
|
||||
equals(drawing.getCurrentLayer(), layers[2])
|
||||
|
||||
ok(drawing.mergeLayer);
|
||||
equals(typeof drawing.mergeLayer, typeof function(){});
|
||||
|
||||
drawing.mergeLayer(mockHrService);
|
||||
|
||||
equals(drawing.getNumLayers(), 2);
|
||||
equals(svg.childElementCount, 2);
|
||||
equals(drawing.getCurrentLayer(), layers[1]);
|
||||
equals(layers[1].childElementCount, elementCount);
|
||||
|
||||
|
||||
// check history record
|
||||
ok(mockHrService.startBatchCommand.calledOnce);
|
||||
ok(mockHrService.endBatchCommand.calledOnce);
|
||||
equals(mockHrService.startBatchCommand.getCall(0).args[0], 'Merge Layer');
|
||||
equals(mockHrService.moveElement.callCount, elementCount - 1); // -1 because the title was not moved.
|
||||
equals(mockHrService.removeElement.callCount, 2); // remove group and title.
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test mergeLayer() when no previous layer to merge', function() {
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
moveElement: this.spy(),
|
||||
removeElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
var layers = setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
drawing.setCurrentLayer(LAYER1);
|
||||
equals(drawing.getCurrentLayer(), layers[0]);
|
||||
|
||||
drawing.mergeLayer(mockHrService);
|
||||
|
||||
equals(drawing.getNumLayers(), 3);
|
||||
equals(svg.childElementCount, 3);
|
||||
equals(drawing.getCurrentLayer(), layers[0]);
|
||||
equals(layers[0].childElementCount, 1);
|
||||
equals(layers[1].childElementCount, 1);
|
||||
equals(layers[2].childElementCount, 1);
|
||||
|
||||
|
||||
// check history record
|
||||
equals(mockHrService.startBatchCommand.callCount, 0);
|
||||
equals(mockHrService.endBatchCommand.callCount, 0);
|
||||
equals(mockHrService.moveElement.callCount, 0);
|
||||
equals(mockHrService.removeElement.callCount, 0);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test mergeAllLayers()', function() {
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
moveElement: this.spy(),
|
||||
removeElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
var layers = setupSvgWith3Layers(svg);
|
||||
var elementCount = createSomeElementsInGroup(layers[0]) + 1; // +1 for title element
|
||||
createSomeElementsInGroup(layers[1]);
|
||||
createSomeElementsInGroup(layers[2]);
|
||||
equals(layers[0].childElementCount, elementCount);
|
||||
equals(layers[1].childElementCount, elementCount);
|
||||
equals(layers[2].childElementCount, elementCount);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.mergeAllLayers);
|
||||
equals(typeof drawing.mergeAllLayers, typeof function(){});
|
||||
|
||||
drawing.mergeAllLayers(mockHrService);
|
||||
|
||||
equals(drawing.getNumLayers(), 1);
|
||||
equals(svg.childElementCount, 1);
|
||||
equals(drawing.getCurrentLayer(), layers[0]);
|
||||
equals(layers[0].childElementCount, elementCount * 3 - 2); // -2 because two titles were deleted.
|
||||
|
||||
// check history record
|
||||
equals(mockHrService.startBatchCommand.callCount, 3); // mergeAllLayers + 2 * mergeLayer
|
||||
equals(mockHrService.endBatchCommand.callCount, 3);
|
||||
equals(mockHrService.startBatchCommand.getCall(0).args[0], 'Merge all Layers');
|
||||
equals(mockHrService.startBatchCommand.getCall(1).args[0], 'Merge Layer');
|
||||
equals(mockHrService.startBatchCommand.getCall(2).args[0], 'Merge Layer');
|
||||
// moveElement count is times 3 instead of 2, because one layer's elements were moved twice.
|
||||
// moveElement count is minus 3 because the three titles were not moved.
|
||||
equals(mockHrService.moveElement.callCount, elementCount * 3 - 3);
|
||||
equals(mockHrService.removeElement.callCount, 2 * 2); // remove group and title twice.
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test cloneLayer()', function() {
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
insertElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
var layers = setupSvgWith3Layers(svg);
|
||||
var layer3 = layers[2];
|
||||
var elementCount = createSomeElementsInGroup(layer3) + 1; // +1 for title element
|
||||
equals(layer3.childElementCount, elementCount);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.cloneLayer);
|
||||
equals(typeof drawing.cloneLayer, typeof function(){});
|
||||
|
||||
var clone = drawing.cloneLayer('clone', mockHrService);
|
||||
|
||||
equals(drawing.getNumLayers(), 4);
|
||||
equals(svg.childElementCount, 4);
|
||||
equals(drawing.getCurrentLayer(), clone);
|
||||
equals(clone.childElementCount, elementCount);
|
||||
|
||||
// check history record
|
||||
ok(mockHrService.startBatchCommand.calledOnce); // mergeAllLayers + 2 * mergeLayer
|
||||
ok(mockHrService.endBatchCommand.calledOnce);
|
||||
equals(mockHrService.startBatchCommand.getCall(0).args[0], 'Duplicate Layer');
|
||||
equals(mockHrService.insertElement.callCount, 1);
|
||||
equals(mockHrService.insertElement.getCall(0).args[0], clone);
|
||||
|
||||
// check that path is cloned properly
|
||||
equals(clone.childNodes.length, elementCount);
|
||||
var path = clone.childNodes[1]
|
||||
equals(path.id, 'svg_1');
|
||||
equals(path.getAttribute('d'), PATH_ATTR.d);
|
||||
equals(path.getAttribute('transform'), PATH_ATTR.transform);
|
||||
equals(path.getAttribute('fill'), PATH_ATTR.fill);
|
||||
equals(path.getAttribute('stroke'), PATH_ATTR.stroke);
|
||||
equals(path.getAttribute('stroke-width'), PATH_ATTR['stroke-width']);
|
||||
|
||||
// check that g is cloned properly
|
||||
var g = clone.childNodes[4]
|
||||
equals(g.childNodes.length, 1);
|
||||
equals(g.id, 'svg_4');
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getLayerVisibility()', function() {
|
||||
expect(5);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.getLayerVisibility);
|
||||
equals(typeof drawing.getLayerVisibility, typeof function(){});
|
||||
ok(drawing.getLayerVisibility(LAYER1));
|
||||
ok(drawing.getLayerVisibility(LAYER2));
|
||||
ok(drawing.getLayerVisibility(LAYER3));
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test setLayerVisibility()', function() {
|
||||
expect(6);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.setLayerVisibility);
|
||||
equals(typeof drawing.setLayerVisibility, typeof function(){});
|
||||
|
||||
drawing.setLayerVisibility(LAYER3, false);
|
||||
drawing.setLayerVisibility(LAYER2, true);
|
||||
drawing.setLayerVisibility(LAYER1, false);
|
||||
|
||||
ok(!drawing.getLayerVisibility(LAYER1));
|
||||
ok(drawing.getLayerVisibility(LAYER2));
|
||||
ok(!drawing.getLayerVisibility(LAYER3));
|
||||
|
||||
drawing.setLayerVisibility(LAYER3, 'test-string');
|
||||
ok(!drawing.getLayerVisibility(LAYER3));
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getLayerOpacity()', function() {
|
||||
expect(5);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.getLayerOpacity);
|
||||
equals(typeof drawing.getLayerOpacity, typeof function(){});
|
||||
ok(drawing.getLayerOpacity(LAYER1) == 1.0);
|
||||
ok(drawing.getLayerOpacity(LAYER2) == 1.0);
|
||||
ok(drawing.getLayerOpacity(LAYER3) == 1.0);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test setLayerOpacity()', function() {
|
||||
expect(6);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.setLayerOpacity);
|
||||
equals(typeof drawing.setLayerOpacity, typeof function(){});
|
||||
|
||||
drawing.setLayerOpacity(LAYER1, 0.4);
|
||||
drawing.setLayerOpacity(LAYER2, 'invalid-string');
|
||||
drawing.setLayerOpacity(LAYER3, -1.4);
|
||||
|
||||
ok(drawing.getLayerOpacity(LAYER1) == 0.4);
|
||||
QUnit.log({result: 'layer2 opacity', message: drawing.getLayerOpacity(LAYER2)});
|
||||
ok(drawing.getLayerOpacity(LAYER2) == 1.0);
|
||||
ok(drawing.getLayerOpacity(LAYER3) == 1.0);
|
||||
|
||||
drawing.setLayerOpacity(LAYER3, 100);
|
||||
ok(drawing.getLayerOpacity(LAYER3) == 1.0);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test deleteCurrentLayer()', function() {
|
||||
expect(6);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
drawing.setCurrentLayer(LAYER2);
|
||||
|
||||
var curLayer = drawing.getCurrentLayer();
|
||||
equals(curLayer, drawing.all_layers[1].getGroup());
|
||||
var deletedLayer = drawing.deleteCurrentLayer();
|
||||
|
||||
equals(curLayer, deletedLayer);
|
||||
equals(2, drawing.getNumLayers());
|
||||
equals(LAYER1, drawing.all_layers[0].getName());
|
||||
equals(LAYER3, drawing.all_layers[1].getName());
|
||||
equals(drawing.getCurrentLayer(), drawing.all_layers[1].getGroup());
|
||||
});
|
||||
|
||||
test('Test svgedit.draw.randomizeIds()', function() {
|
||||
expect(9);
|
||||
|
||||
// Confirm in LET_DOCUMENT_DECIDE mode that the document decides
|
||||
// if there is a nonce.
|
||||
var drawing = new svgedit.draw.Drawing(svg_n.cloneNode(true));
|
||||
ok(!!drawing.getNonce());
|
||||
|
||||
drawing = new svgedit.draw.Drawing(svg.cloneNode(true));
|
||||
ok(!drawing.getNonce());
|
||||
|
||||
// Confirm that a nonce is set once we're in ALWAYS_RANDOMIZE mode.
|
||||
svgedit.draw.randomizeIds(true, drawing);
|
||||
ok(!!drawing.getNonce());
|
||||
|
||||
// Confirm new drawings in ALWAYS_RANDOMIZE mode have a nonce.
|
||||
drawing = new svgedit.draw.Drawing(svg.cloneNode(true));
|
||||
ok(!!drawing.getNonce());
|
||||
|
||||
drawing.clearNonce();
|
||||
ok(!drawing.getNonce());
|
||||
|
||||
// Confirm new drawings in NEVER_RANDOMIZE mode do not have a nonce
|
||||
// but that their se:nonce attribute is left alone.
|
||||
svgedit.draw.randomizeIds(false, drawing);
|
||||
ok(!drawing.getNonce());
|
||||
ok(!!drawing.getSvgElem().getAttributeNS(NS.SE, 'nonce'));
|
||||
|
||||
drawing = new svgedit.draw.Drawing(svg.cloneNode(true));
|
||||
ok(!drawing.getNonce());
|
||||
|
||||
drawing = new svgedit.draw.Drawing(svg_n.cloneNode(true));
|
||||
ok(!drawing.getNonce());
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="draw_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for draw.js</h1>
|
||||
|
||||
793
test/draw_test.js
Normal file
793
test/draw_test.js
Normal file
@@ -0,0 +1,793 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit, equals */
|
||||
/* eslint-disable no-var, no-redeclare */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
var NS = svgedit.NS;
|
||||
var LAYER_CLASS = svgedit.draw.Layer.CLASS_NAME;
|
||||
var NONCE = 'foo';
|
||||
var LAYER1 = 'Layer 1';
|
||||
var LAYER2 = 'Layer 2';
|
||||
var LAYER3 = 'Layer 3';
|
||||
var PATH_ATTR = {
|
||||
// clone will convert relative to absolute, so the test for equality fails.
|
||||
// 'd': 'm7.38867,57.38867c0,-27.62431 22.37569,-50 50,-50c27.62431,0 50,22.37569 50,50c0,27.62431 -22.37569,50 -50,50c-27.62431,0 -50,-22.37569 -50,-50z',
|
||||
'd': 'M7.389,57.389C7.389,29.764 29.764,7.389 57.389,7.389C85.013,7.389 107.389,29.764 107.389,57.389C107.389,85.013 85.013,107.389 57.389,107.389C29.764,107.389 7.389,85.013 7.389,57.389z',
|
||||
'transform': 'rotate(45 57.388671875000036,57.388671874999986) ',
|
||||
'stroke-width': '5',
|
||||
'stroke': '#660000',
|
||||
'fill': '#ff0000'
|
||||
};
|
||||
|
||||
var svg = document.createElementNS(NS.SVG, 'svg');
|
||||
var sandbox = document.getElementById('sandbox');
|
||||
// Firefox throws exception in getBBox() when svg is not attached to DOM.
|
||||
sandbox.appendChild(svg);
|
||||
|
||||
// Set up <svg> with nonce.
|
||||
var svgN = document.createElementNS(NS.SVG, 'svg');
|
||||
svgN.setAttributeNS(NS.XMLNS, 'xmlns:se', NS.SE);
|
||||
svgN.setAttributeNS(NS.SE, 'se:nonce', NONCE);
|
||||
|
||||
svgedit.units.init({
|
||||
// used by svgedit.units.shortFloat - call path: cloneLayer -> copyElem -> convertPath -> pathDSegment -> shortFloat
|
||||
getRoundDigits: function () { return 3; }
|
||||
});
|
||||
|
||||
function createSVGElement (jsonMap) {
|
||||
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||
for (var attr in jsonMap['attr']) {
|
||||
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
var setupSvgWith3Layers = function (svgElem) {
|
||||
var layer1 = document.createElementNS(NS.SVG, 'g');
|
||||
var layer1Title = document.createElementNS(NS.SVG, 'title');
|
||||
layer1Title.appendChild(document.createTextNode(LAYER1));
|
||||
layer1.appendChild(layer1Title);
|
||||
svgElem.appendChild(layer1);
|
||||
|
||||
var layer2 = document.createElementNS(NS.SVG, 'g');
|
||||
var layer2Title = document.createElementNS(NS.SVG, 'title');
|
||||
layer2Title.appendChild(document.createTextNode(LAYER2));
|
||||
layer2.appendChild(layer2Title);
|
||||
svgElem.appendChild(layer2);
|
||||
|
||||
var layer3 = document.createElementNS(NS.SVG, 'g');
|
||||
var layer3Title = document.createElementNS(NS.SVG, 'title');
|
||||
layer3Title.appendChild(document.createTextNode(LAYER3));
|
||||
layer3.appendChild(layer3Title);
|
||||
svgElem.appendChild(layer3);
|
||||
|
||||
return [layer1, layer2, layer3];
|
||||
};
|
||||
|
||||
var createSomeElementsInGroup = function (group) {
|
||||
group.appendChild(createSVGElement({
|
||||
'element': 'path',
|
||||
'attr': PATH_ATTR
|
||||
}));
|
||||
// group.appendChild(createSVGElement({
|
||||
// 'element': 'path',
|
||||
// 'attr': {'d': 'M0,1L2,3'}
|
||||
// }));
|
||||
group.appendChild(createSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
}));
|
||||
group.appendChild(createSVGElement({
|
||||
'element': 'line',
|
||||
'attr': {'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||
}));
|
||||
|
||||
var g = createSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {}
|
||||
});
|
||||
g.appendChild(createSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
}));
|
||||
group.appendChild(g);
|
||||
return 4;
|
||||
};
|
||||
|
||||
var cleanupSvg = function (svgElem) {
|
||||
while (svgElem.firstChild) { svgElem.removeChild(svgElem.firstChild); }
|
||||
};
|
||||
|
||||
module('svgedit.draw.Drawing', {
|
||||
setup: function () {
|
||||
},
|
||||
teardown: function () {
|
||||
}
|
||||
});
|
||||
|
||||
test('Test draw module', function () {
|
||||
expect(4);
|
||||
|
||||
ok(svgedit.draw);
|
||||
equals(typeof svgedit.draw, typeof {});
|
||||
|
||||
ok(svgedit.draw.Drawing);
|
||||
equals(typeof svgedit.draw.Drawing, typeof function () {});
|
||||
});
|
||||
|
||||
test('Test document creation', function () {
|
||||
expect(3);
|
||||
|
||||
try {
|
||||
var doc = new svgedit.draw.Drawing();
|
||||
ok(false, 'Created drawing without a valid <svg> element');
|
||||
} catch (e) {
|
||||
ok(true);
|
||||
}
|
||||
|
||||
try {
|
||||
var doc = new svgedit.draw.Drawing(svg);
|
||||
ok(doc);
|
||||
equals(typeof doc, typeof {});
|
||||
} catch (e) {
|
||||
ok(false, 'Could not create document from valid <svg> element: ' + e);
|
||||
}
|
||||
});
|
||||
|
||||
test('Test nonce', function () {
|
||||
expect(7);
|
||||
|
||||
var doc = new svgedit.draw.Drawing(svg);
|
||||
equals(doc.getNonce(), '');
|
||||
|
||||
doc = new svgedit.draw.Drawing(svgN);
|
||||
equals(doc.getNonce(), NONCE);
|
||||
equals(doc.getSvgElem().getAttributeNS(NS.SE, 'nonce'), NONCE);
|
||||
|
||||
doc.clearNonce();
|
||||
ok(!doc.getNonce());
|
||||
ok(!doc.getSvgElem().getAttributeNS(NS.SE, 'se:nonce'));
|
||||
|
||||
doc.setNonce(NONCE);
|
||||
equals(doc.getNonce(), NONCE);
|
||||
equals(doc.getSvgElem().getAttributeNS(NS.SE, 'nonce'), NONCE);
|
||||
});
|
||||
|
||||
test('Test getId() and getNextId() without nonce', function () {
|
||||
expect(7);
|
||||
|
||||
var elem2 = document.createElementNS(NS.SVG, 'circle');
|
||||
elem2.id = 'svg_2';
|
||||
svg.appendChild(elem2);
|
||||
|
||||
var doc = new svgedit.draw.Drawing(svg);
|
||||
|
||||
equals(doc.getId(), 'svg_0');
|
||||
|
||||
equals(doc.getNextId(), 'svg_1');
|
||||
equals(doc.getId(), 'svg_1');
|
||||
|
||||
equals(doc.getNextId(), 'svg_3');
|
||||
equals(doc.getId(), 'svg_3');
|
||||
|
||||
equals(doc.getNextId(), 'svg_4');
|
||||
equals(doc.getId(), 'svg_4');
|
||||
// clean out svg document
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getId() and getNextId() with prefix without nonce', function () {
|
||||
expect(7);
|
||||
|
||||
var prefix = 'Bar-';
|
||||
var doc = new svgedit.draw.Drawing(svg, prefix);
|
||||
|
||||
equals(doc.getId(), prefix + '0');
|
||||
|
||||
equals(doc.getNextId(), prefix + '1');
|
||||
equals(doc.getId(), prefix + '1');
|
||||
|
||||
equals(doc.getNextId(), prefix + '2');
|
||||
equals(doc.getId(), prefix + '2');
|
||||
|
||||
equals(doc.getNextId(), prefix + '3');
|
||||
equals(doc.getId(), prefix + '3');
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getId() and getNextId() with nonce', function () {
|
||||
expect(7);
|
||||
|
||||
var prefix = 'svg_' + NONCE;
|
||||
|
||||
var elem2 = document.createElementNS(NS.SVG, 'circle');
|
||||
elem2.id = prefix + '_2';
|
||||
svgN.appendChild(elem2);
|
||||
|
||||
var doc = new svgedit.draw.Drawing(svgN);
|
||||
|
||||
equals(doc.getId(), prefix + '_0');
|
||||
|
||||
equals(doc.getNextId(), prefix + '_1');
|
||||
equals(doc.getId(), prefix + '_1');
|
||||
|
||||
equals(doc.getNextId(), prefix + '_3');
|
||||
equals(doc.getId(), prefix + '_3');
|
||||
|
||||
equals(doc.getNextId(), prefix + '_4');
|
||||
equals(doc.getId(), prefix + '_4');
|
||||
|
||||
cleanupSvg(svgN);
|
||||
});
|
||||
|
||||
test('Test getId() and getNextId() with prefix with nonce', function () {
|
||||
expect(7);
|
||||
|
||||
var PREFIX = 'Bar-';
|
||||
var doc = new svgedit.draw.Drawing(svgN, PREFIX);
|
||||
|
||||
var prefix = PREFIX + NONCE + '_';
|
||||
equals(doc.getId(), prefix + '0');
|
||||
|
||||
equals(doc.getNextId(), prefix + '1');
|
||||
equals(doc.getId(), prefix + '1');
|
||||
|
||||
equals(doc.getNextId(), prefix + '2');
|
||||
equals(doc.getId(), prefix + '2');
|
||||
|
||||
equals(doc.getNextId(), prefix + '3');
|
||||
equals(doc.getId(), prefix + '3');
|
||||
|
||||
cleanupSvg(svgN);
|
||||
});
|
||||
|
||||
test('Test releaseId()', function () {
|
||||
expect(6);
|
||||
|
||||
var doc = new svgedit.draw.Drawing(svg);
|
||||
|
||||
var firstId = doc.getNextId();
|
||||
// var secondId = doc.getNextId();
|
||||
|
||||
var result = doc.releaseId(firstId);
|
||||
ok(result);
|
||||
equals(doc.getNextId(), firstId);
|
||||
equals(doc.getNextId(), 'svg_3');
|
||||
|
||||
ok(!doc.releaseId('bad-id'));
|
||||
ok(doc.releaseId(firstId));
|
||||
ok(!doc.releaseId(firstId));
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getNumLayers', function () {
|
||||
expect(3);
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
equals(typeof drawing.getNumLayers, typeof function () {});
|
||||
equals(drawing.getNumLayers(), 0);
|
||||
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
equals(drawing.getNumLayers(), 3);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test hasLayer', function () {
|
||||
expect(5);
|
||||
|
||||
setupSvgWith3Layers(svg);
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
equals(typeof drawing.hasLayer, typeof function () {});
|
||||
ok(!drawing.hasLayer('invalid-layer'));
|
||||
|
||||
ok(drawing.hasLayer(LAYER3));
|
||||
ok(drawing.hasLayer(LAYER2));
|
||||
ok(drawing.hasLayer(LAYER1));
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test identifyLayers() with empty document', function () {
|
||||
expect(11);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
equals(drawing.getCurrentLayer(), null);
|
||||
// By default, an empty document gets an empty group created.
|
||||
drawing.identifyLayers();
|
||||
|
||||
// Check that <svg> element now has one child node
|
||||
ok(drawing.getSvgElem().hasChildNodes());
|
||||
equals(drawing.getSvgElem().childNodes.length, 1);
|
||||
|
||||
// Check that all_layers are correctly set up.
|
||||
equals(drawing.getNumLayers(), 1);
|
||||
var emptyLayer = drawing.all_layers[0];
|
||||
ok(emptyLayer);
|
||||
var layerGroup = emptyLayer.getGroup();
|
||||
equals(layerGroup, drawing.getSvgElem().firstChild);
|
||||
equals(layerGroup.tagName, 'g');
|
||||
equals(layerGroup.getAttribute('class'), LAYER_CLASS);
|
||||
ok(layerGroup.hasChildNodes());
|
||||
equals(layerGroup.childNodes.length, 1);
|
||||
var firstChild = layerGroup.childNodes.item(0);
|
||||
equals(firstChild.tagName, 'title');
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test identifyLayers() with some layers', function () {
|
||||
expect(8);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
|
||||
equals(svg.childNodes.length, 3);
|
||||
|
||||
drawing.identifyLayers();
|
||||
|
||||
equals(drawing.getNumLayers(), 3);
|
||||
equals(drawing.all_layers[0].getGroup(), svg.childNodes.item(0));
|
||||
equals(drawing.all_layers[1].getGroup(), svg.childNodes.item(1));
|
||||
equals(drawing.all_layers[2].getGroup(), svg.childNodes.item(2));
|
||||
|
||||
equals(drawing.all_layers[0].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
equals(drawing.all_layers[1].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
equals(drawing.all_layers[2].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test identifyLayers() with some layers and orphans', function () {
|
||||
expect(14);
|
||||
|
||||
setupSvgWith3Layers(svg);
|
||||
|
||||
var orphan1 = document.createElementNS(NS.SVG, 'rect');
|
||||
var orphan2 = document.createElementNS(NS.SVG, 'rect');
|
||||
svg.appendChild(orphan1);
|
||||
svg.appendChild(orphan2);
|
||||
|
||||
equals(svg.childNodes.length, 5);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
equals(drawing.getNumLayers(), 4);
|
||||
equals(drawing.all_layers[0].getGroup(), svg.childNodes.item(0));
|
||||
equals(drawing.all_layers[1].getGroup(), svg.childNodes.item(1));
|
||||
equals(drawing.all_layers[2].getGroup(), svg.childNodes.item(2));
|
||||
equals(drawing.all_layers[3].getGroup(), svg.childNodes.item(3));
|
||||
|
||||
equals(drawing.all_layers[0].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
equals(drawing.all_layers[1].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
equals(drawing.all_layers[2].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
equals(drawing.all_layers[3].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||
|
||||
var layer4 = drawing.all_layers[3].getGroup();
|
||||
equals(layer4.tagName, 'g');
|
||||
equals(layer4.childNodes.length, 3);
|
||||
equals(layer4.childNodes.item(1), orphan1);
|
||||
equals(layer4.childNodes.item(2), orphan2);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getLayerName()', function () {
|
||||
expect(4);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
|
||||
drawing.identifyLayers();
|
||||
|
||||
equals(drawing.getNumLayers(), 3);
|
||||
equals(drawing.getLayerName(0), LAYER1);
|
||||
equals(drawing.getLayerName(1), LAYER2);
|
||||
equals(drawing.getLayerName(2), LAYER3);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getCurrentLayer()', function () {
|
||||
expect(4);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.getCurrentLayer);
|
||||
equals(typeof drawing.getCurrentLayer, typeof function () {});
|
||||
ok(drawing.getCurrentLayer());
|
||||
equals(drawing.getCurrentLayer(), drawing.all_layers[2].getGroup());
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test setCurrentLayer() and getCurrentLayerName()', function () {
|
||||
expect(6);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.setCurrentLayer);
|
||||
equals(typeof drawing.setCurrentLayer, typeof function () {});
|
||||
|
||||
drawing.setCurrentLayer(LAYER2);
|
||||
equals(drawing.getCurrentLayerName(), LAYER2);
|
||||
equals(drawing.getCurrentLayer(), drawing.all_layers[1].getGroup());
|
||||
|
||||
drawing.setCurrentLayer(LAYER3);
|
||||
equals(drawing.getCurrentLayerName(), LAYER3);
|
||||
equals(drawing.getCurrentLayer(), drawing.all_layers[2].getGroup());
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test setCurrentLayerName()', function () {
|
||||
var mockHrService = {
|
||||
changeElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.setCurrentLayerName);
|
||||
equals(typeof drawing.setCurrentLayerName, typeof function () {});
|
||||
|
||||
var oldName = drawing.getCurrentLayerName();
|
||||
var newName = 'New Name';
|
||||
ok(drawing.layer_map[oldName]);
|
||||
equals(drawing.layer_map[newName], undefined); // newName shouldn't exist.
|
||||
var result = drawing.setCurrentLayerName(newName, mockHrService);
|
||||
equals(result, newName);
|
||||
equals(drawing.getCurrentLayerName(), newName);
|
||||
// Was the map updated?
|
||||
equals(drawing.layer_map[oldName], undefined);
|
||||
equals(drawing.layer_map[newName], drawing.current_layer);
|
||||
// Was mockHrService called?
|
||||
ok(mockHrService.changeElement.calledOnce);
|
||||
equals(oldName, mockHrService.changeElement.getCall(0).args[1]['#text']);
|
||||
equals(newName, mockHrService.changeElement.getCall(0).args[0].textContent);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test createLayer()', function () {
|
||||
expect(10);
|
||||
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
insertElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.createLayer);
|
||||
equals(typeof drawing.createLayer, typeof function () {});
|
||||
|
||||
var NEW_LAYER_NAME = 'Layer A';
|
||||
var layerG = drawing.createLayer(NEW_LAYER_NAME, mockHrService);
|
||||
equals(drawing.getNumLayers(), 4);
|
||||
equals(layerG, drawing.getCurrentLayer());
|
||||
equals(layerG.getAttribute('class'), LAYER_CLASS);
|
||||
equals(NEW_LAYER_NAME, drawing.getCurrentLayerName());
|
||||
equals(NEW_LAYER_NAME, drawing.getLayerName(3));
|
||||
|
||||
equals(layerG, mockHrService.insertElement.getCall(0).args[0]);
|
||||
ok(mockHrService.startBatchCommand.calledOnce);
|
||||
ok(mockHrService.endBatchCommand.calledOnce);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test mergeLayer()', function () {
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
moveElement: this.spy(),
|
||||
removeElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
var layers = setupSvgWith3Layers(svg);
|
||||
var elementCount = createSomeElementsInGroup(layers[2]) + 1; // +1 for title element
|
||||
equals(layers[1].childElementCount, 1);
|
||||
equals(layers[2].childElementCount, elementCount);
|
||||
drawing.identifyLayers();
|
||||
equals(drawing.getCurrentLayer(), layers[2]);
|
||||
|
||||
ok(drawing.mergeLayer);
|
||||
equals(typeof drawing.mergeLayer, typeof function () {});
|
||||
|
||||
drawing.mergeLayer(mockHrService);
|
||||
|
||||
equals(drawing.getNumLayers(), 2);
|
||||
equals(svg.childElementCount, 2);
|
||||
equals(drawing.getCurrentLayer(), layers[1]);
|
||||
equals(layers[1].childElementCount, elementCount);
|
||||
|
||||
// check history record
|
||||
ok(mockHrService.startBatchCommand.calledOnce);
|
||||
ok(mockHrService.endBatchCommand.calledOnce);
|
||||
equals(mockHrService.startBatchCommand.getCall(0).args[0], 'Merge Layer');
|
||||
equals(mockHrService.moveElement.callCount, elementCount - 1); // -1 because the title was not moved.
|
||||
equals(mockHrService.removeElement.callCount, 2); // remove group and title.
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test mergeLayer() when no previous layer to merge', function () {
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
moveElement: this.spy(),
|
||||
removeElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
var layers = setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
drawing.setCurrentLayer(LAYER1);
|
||||
equals(drawing.getCurrentLayer(), layers[0]);
|
||||
|
||||
drawing.mergeLayer(mockHrService);
|
||||
|
||||
equals(drawing.getNumLayers(), 3);
|
||||
equals(svg.childElementCount, 3);
|
||||
equals(drawing.getCurrentLayer(), layers[0]);
|
||||
equals(layers[0].childElementCount, 1);
|
||||
equals(layers[1].childElementCount, 1);
|
||||
equals(layers[2].childElementCount, 1);
|
||||
|
||||
// check history record
|
||||
equals(mockHrService.startBatchCommand.callCount, 0);
|
||||
equals(mockHrService.endBatchCommand.callCount, 0);
|
||||
equals(mockHrService.moveElement.callCount, 0);
|
||||
equals(mockHrService.removeElement.callCount, 0);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test mergeAllLayers()', function () {
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
moveElement: this.spy(),
|
||||
removeElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
var layers = setupSvgWith3Layers(svg);
|
||||
var elementCount = createSomeElementsInGroup(layers[0]) + 1; // +1 for title element
|
||||
createSomeElementsInGroup(layers[1]);
|
||||
createSomeElementsInGroup(layers[2]);
|
||||
equals(layers[0].childElementCount, elementCount);
|
||||
equals(layers[1].childElementCount, elementCount);
|
||||
equals(layers[2].childElementCount, elementCount);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.mergeAllLayers);
|
||||
equals(typeof drawing.mergeAllLayers, typeof function () {});
|
||||
|
||||
drawing.mergeAllLayers(mockHrService);
|
||||
|
||||
equals(drawing.getNumLayers(), 1);
|
||||
equals(svg.childElementCount, 1);
|
||||
equals(drawing.getCurrentLayer(), layers[0]);
|
||||
equals(layers[0].childElementCount, elementCount * 3 - 2); // -2 because two titles were deleted.
|
||||
|
||||
// check history record
|
||||
equals(mockHrService.startBatchCommand.callCount, 3); // mergeAllLayers + 2 * mergeLayer
|
||||
equals(mockHrService.endBatchCommand.callCount, 3);
|
||||
equals(mockHrService.startBatchCommand.getCall(0).args[0], 'Merge all Layers');
|
||||
equals(mockHrService.startBatchCommand.getCall(1).args[0], 'Merge Layer');
|
||||
equals(mockHrService.startBatchCommand.getCall(2).args[0], 'Merge Layer');
|
||||
// moveElement count is times 3 instead of 2, because one layer's elements were moved twice.
|
||||
// moveElement count is minus 3 because the three titles were not moved.
|
||||
equals(mockHrService.moveElement.callCount, elementCount * 3 - 3);
|
||||
equals(mockHrService.removeElement.callCount, 2 * 2); // remove group and title twice.
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test cloneLayer()', function () {
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
insertElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
var layers = setupSvgWith3Layers(svg);
|
||||
var layer3 = layers[2];
|
||||
var elementCount = createSomeElementsInGroup(layer3) + 1; // +1 for title element
|
||||
equals(layer3.childElementCount, elementCount);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.cloneLayer);
|
||||
equals(typeof drawing.cloneLayer, typeof function () {});
|
||||
|
||||
var clone = drawing.cloneLayer('clone', mockHrService);
|
||||
|
||||
equals(drawing.getNumLayers(), 4);
|
||||
equals(svg.childElementCount, 4);
|
||||
equals(drawing.getCurrentLayer(), clone);
|
||||
equals(clone.childElementCount, elementCount);
|
||||
|
||||
// check history record
|
||||
ok(mockHrService.startBatchCommand.calledOnce); // mergeAllLayers + 2 * mergeLayer
|
||||
ok(mockHrService.endBatchCommand.calledOnce);
|
||||
equals(mockHrService.startBatchCommand.getCall(0).args[0], 'Duplicate Layer');
|
||||
equals(mockHrService.insertElement.callCount, 1);
|
||||
equals(mockHrService.insertElement.getCall(0).args[0], clone);
|
||||
|
||||
// check that path is cloned properly
|
||||
equals(clone.childNodes.length, elementCount);
|
||||
var path = clone.childNodes[1];
|
||||
equals(path.id, 'svg_1');
|
||||
equals(path.getAttribute('d'), PATH_ATTR.d);
|
||||
equals(path.getAttribute('transform'), PATH_ATTR.transform);
|
||||
equals(path.getAttribute('fill'), PATH_ATTR.fill);
|
||||
equals(path.getAttribute('stroke'), PATH_ATTR.stroke);
|
||||
equals(path.getAttribute('stroke-width'), PATH_ATTR['stroke-width']);
|
||||
|
||||
// check that g is cloned properly
|
||||
var g = clone.childNodes[4];
|
||||
equals(g.childNodes.length, 1);
|
||||
equals(g.id, 'svg_4');
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getLayerVisibility()', function () {
|
||||
expect(5);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.getLayerVisibility);
|
||||
equals(typeof drawing.getLayerVisibility, typeof function () {});
|
||||
ok(drawing.getLayerVisibility(LAYER1));
|
||||
ok(drawing.getLayerVisibility(LAYER2));
|
||||
ok(drawing.getLayerVisibility(LAYER3));
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test setLayerVisibility()', function () {
|
||||
expect(6);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.setLayerVisibility);
|
||||
equals(typeof drawing.setLayerVisibility, typeof function () {});
|
||||
|
||||
drawing.setLayerVisibility(LAYER3, false);
|
||||
drawing.setLayerVisibility(LAYER2, true);
|
||||
drawing.setLayerVisibility(LAYER1, false);
|
||||
|
||||
ok(!drawing.getLayerVisibility(LAYER1));
|
||||
ok(drawing.getLayerVisibility(LAYER2));
|
||||
ok(!drawing.getLayerVisibility(LAYER3));
|
||||
|
||||
drawing.setLayerVisibility(LAYER3, 'test-string');
|
||||
ok(!drawing.getLayerVisibility(LAYER3));
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test getLayerOpacity()', function () {
|
||||
expect(5);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.getLayerOpacity);
|
||||
equals(typeof drawing.getLayerOpacity, typeof function () {});
|
||||
ok(drawing.getLayerOpacity(LAYER1) === 1.0);
|
||||
ok(drawing.getLayerOpacity(LAYER2) === 1.0);
|
||||
ok(drawing.getLayerOpacity(LAYER3) === 1.0);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test setLayerOpacity()', function () {
|
||||
expect(6);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
ok(drawing.setLayerOpacity);
|
||||
equals(typeof drawing.setLayerOpacity, typeof function () {});
|
||||
|
||||
drawing.setLayerOpacity(LAYER1, 0.4);
|
||||
drawing.setLayerOpacity(LAYER2, 'invalid-string');
|
||||
drawing.setLayerOpacity(LAYER3, -1.4);
|
||||
|
||||
ok(drawing.getLayerOpacity(LAYER1) === 0.4);
|
||||
QUnit.log({result: 'layer2 opacity', message: drawing.getLayerOpacity(LAYER2)});
|
||||
ok(drawing.getLayerOpacity(LAYER2) === 1.0);
|
||||
ok(drawing.getLayerOpacity(LAYER3) === 1.0);
|
||||
|
||||
drawing.setLayerOpacity(LAYER3, 100);
|
||||
ok(drawing.getLayerOpacity(LAYER3) === 1.0);
|
||||
|
||||
cleanupSvg(svg);
|
||||
});
|
||||
|
||||
test('Test deleteCurrentLayer()', function () {
|
||||
expect(6);
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
drawing.identifyLayers();
|
||||
|
||||
drawing.setCurrentLayer(LAYER2);
|
||||
|
||||
var curLayer = drawing.getCurrentLayer();
|
||||
equals(curLayer, drawing.all_layers[1].getGroup());
|
||||
var deletedLayer = drawing.deleteCurrentLayer();
|
||||
|
||||
equals(curLayer, deletedLayer);
|
||||
equals(2, drawing.getNumLayers());
|
||||
equals(LAYER1, drawing.all_layers[0].getName());
|
||||
equals(LAYER3, drawing.all_layers[1].getName());
|
||||
equals(drawing.getCurrentLayer(), drawing.all_layers[1].getGroup());
|
||||
});
|
||||
|
||||
test('Test svgedit.draw.randomizeIds()', function () {
|
||||
expect(9);
|
||||
|
||||
// Confirm in LET_DOCUMENT_DECIDE mode that the document decides
|
||||
// if there is a nonce.
|
||||
var drawing = new svgedit.draw.Drawing(svgN.cloneNode(true));
|
||||
ok(!!drawing.getNonce());
|
||||
|
||||
drawing = new svgedit.draw.Drawing(svg.cloneNode(true));
|
||||
ok(!drawing.getNonce());
|
||||
|
||||
// Confirm that a nonce is set once we're in ALWAYS_RANDOMIZE mode.
|
||||
svgedit.draw.randomizeIds(true, drawing);
|
||||
ok(!!drawing.getNonce());
|
||||
|
||||
// Confirm new drawings in ALWAYS_RANDOMIZE mode have a nonce.
|
||||
drawing = new svgedit.draw.Drawing(svg.cloneNode(true));
|
||||
ok(!!drawing.getNonce());
|
||||
|
||||
drawing.clearNonce();
|
||||
ok(!drawing.getNonce());
|
||||
|
||||
// Confirm new drawings in NEVER_RANDOMIZE mode do not have a nonce
|
||||
// but that their se:nonce attribute is left alone.
|
||||
svgedit.draw.randomizeIds(false, drawing);
|
||||
ok(!drawing.getNonce());
|
||||
ok(!!drawing.getSvgElem().getAttributeNS(NS.SE, 'nonce'));
|
||||
|
||||
drawing = new svgedit.draw.Drawing(svg.cloneNode(true));
|
||||
ok(!drawing.getNonce());
|
||||
|
||||
drawing = new svgedit.draw.Drawing(svgN.cloneNode(true));
|
||||
ok(!drawing.getNonce());
|
||||
});
|
||||
});
|
||||
@@ -8,571 +8,7 @@
|
||||
<script src="../editor/svgedit.js"></script>
|
||||
<script src="../editor/history.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// TODO(codedread): Write tests for handling history events.
|
||||
|
||||
// Mocked out methods.
|
||||
svgedit.transformlist = {};
|
||||
svgedit.transformlist.removeElementFromListMap = function(elem) {};
|
||||
svgedit.utilities = {};
|
||||
svgedit.utilities.getHref = function(elem) { return '#foo'; };
|
||||
svgedit.utilities.setHref = function(elem, val) {};
|
||||
svgedit.utilities.getRotationAngle = function(elem) { return 0; };
|
||||
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var NS = svgedit.NS;
|
||||
var svg = document.createElementNS(NS.SVG, 'svg');
|
||||
var undoMgr = null;
|
||||
var divparent = document.getElementById('divparent');
|
||||
var div1 = document.getElementById('div1');
|
||||
var div2 = document.getElementById('div2');
|
||||
var div3 = document.getElementById('div3');
|
||||
var div4 = document.getElementById('div4');
|
||||
var div5 = document.getElementById('div5');
|
||||
|
||||
module('svgedit.history');
|
||||
|
||||
var MockCommand = function(opt_text) { this.text_ = opt_text; };
|
||||
MockCommand.prototype.apply = function() {};
|
||||
MockCommand.prototype.unapply = function() {};
|
||||
MockCommand.prototype.getText = function() { return this.text_; };
|
||||
MockCommand.prototype.elements = function() { return []; };
|
||||
|
||||
var MockHistoryEventHandler = function() {};
|
||||
MockHistoryEventHandler.prototype.handleHistoryEvent = function(eventType, command) {};
|
||||
|
||||
function setUp() {
|
||||
undoMgr = new svgedit.history.UndoManager();
|
||||
}
|
||||
function tearDown() {
|
||||
undoMgr = null;
|
||||
}
|
||||
|
||||
test('Test svgedit.history package', function() {
|
||||
expect(13);
|
||||
|
||||
ok(svgedit.history);
|
||||
ok(svgedit.history.MoveElementCommand);
|
||||
ok(svgedit.history.InsertElementCommand);
|
||||
ok(svgedit.history.ChangeElementCommand);
|
||||
ok(svgedit.history.RemoveElementCommand);
|
||||
ok(svgedit.history.BatchCommand);
|
||||
ok(svgedit.history.UndoManager);
|
||||
equals(typeof svgedit.history.MoveElementCommand, typeof function(){});
|
||||
equals(typeof svgedit.history.InsertElementCommand, typeof function(){});
|
||||
equals(typeof svgedit.history.ChangeElementCommand, typeof function(){});
|
||||
equals(typeof svgedit.history.RemoveElementCommand, typeof function(){});
|
||||
equals(typeof svgedit.history.BatchCommand, typeof function(){});
|
||||
equals(typeof svgedit.history.UndoManager, typeof function(){});
|
||||
});
|
||||
|
||||
test('Test UndoManager methods', function() {
|
||||
expect(14);
|
||||
setUp();
|
||||
|
||||
ok(undoMgr);
|
||||
ok(undoMgr.addCommandToHistory);
|
||||
ok(undoMgr.getUndoStackSize);
|
||||
ok(undoMgr.getRedoStackSize);
|
||||
ok(undoMgr.resetUndoStack);
|
||||
ok(undoMgr.getNextUndoCommandText);
|
||||
ok(undoMgr.getNextRedoCommandText);
|
||||
|
||||
equals(typeof undoMgr, typeof {});
|
||||
equals(typeof undoMgr.addCommandToHistory, typeof function(){});
|
||||
equals(typeof undoMgr.getUndoStackSize, typeof function(){});
|
||||
equals(typeof undoMgr.getRedoStackSize, typeof function(){});
|
||||
equals(typeof undoMgr.resetUndoStack, typeof function(){});
|
||||
equals(typeof undoMgr.getNextUndoCommandText, typeof function(){});
|
||||
equals(typeof undoMgr.getNextRedoCommandText, typeof function(){});
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.addCommandToHistory() function', function() {
|
||||
expect(3);
|
||||
|
||||
setUp();
|
||||
|
||||
equals(undoMgr.getUndoStackSize(), 0);
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
equals(undoMgr.getUndoStackSize(), 1);
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
equals(undoMgr.getUndoStackSize(), 2);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.getUndoStackSize() and getRedoStackSize() functions', function() {
|
||||
expect(18);
|
||||
|
||||
setUp();
|
||||
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
|
||||
equals(undoMgr.getUndoStackSize(), 3);
|
||||
equals(undoMgr.getRedoStackSize(), 0);
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getUndoStackSize(), 2);
|
||||
equals(undoMgr.getRedoStackSize(), 1);
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getUndoStackSize(), 1);
|
||||
equals(undoMgr.getRedoStackSize(), 2);
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getUndoStackSize(), 0);
|
||||
equals(undoMgr.getRedoStackSize(), 3);
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getUndoStackSize(), 0);
|
||||
equals(undoMgr.getRedoStackSize(), 3);
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getUndoStackSize(), 1);
|
||||
equals(undoMgr.getRedoStackSize(), 2);
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getUndoStackSize(), 2);
|
||||
equals(undoMgr.getRedoStackSize(), 1);
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getUndoStackSize(), 3);
|
||||
equals(undoMgr.getRedoStackSize(), 0);
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getUndoStackSize(), 3);
|
||||
equals(undoMgr.getRedoStackSize(), 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.resetUndoStackSize() function', function() {
|
||||
expect(4);
|
||||
|
||||
setUp();
|
||||
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.undo();
|
||||
|
||||
equals(undoMgr.getUndoStackSize(), 2);
|
||||
equals(undoMgr.getRedoStackSize(), 1);
|
||||
|
||||
undoMgr.resetUndoStack();
|
||||
|
||||
equals(undoMgr.getUndoStackSize(), 0);
|
||||
equals(undoMgr.getRedoStackSize(), 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.getNextUndoCommandText() function', function() {
|
||||
expect(9);
|
||||
|
||||
setUp();
|
||||
|
||||
equals(undoMgr.getNextUndoCommandText(), '');
|
||||
|
||||
undoMgr.addCommandToHistory(new MockCommand('First'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Second'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Third'));
|
||||
|
||||
equals(undoMgr.getNextUndoCommandText(), 'Third');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'Second');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'First');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextUndoCommandText(), '');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'First');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'Second');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'Third');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'Third');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.getNextRedoCommandText() function', function() {
|
||||
expect(8);
|
||||
|
||||
setUp();
|
||||
|
||||
equals(undoMgr.getNextRedoCommandText(), '');
|
||||
|
||||
undoMgr.addCommandToHistory(new MockCommand('First'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Second'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Third'));
|
||||
|
||||
equals(undoMgr.getNextRedoCommandText(), '');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextRedoCommandText(), 'Third');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextRedoCommandText(), 'Second');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextRedoCommandText(), 'First');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextRedoCommandText(), 'Second');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextRedoCommandText(), 'Third');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextRedoCommandText(), '');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.undo() and redo() functions', function() {
|
||||
expect(10);
|
||||
|
||||
setUp();
|
||||
|
||||
var lastCalled = null;
|
||||
var cmd1 = new MockCommand();
|
||||
var cmd2 = new MockCommand();
|
||||
var cmd3 = new MockCommand();
|
||||
cmd1.apply = function() { lastCalled = 'cmd1.apply'; };
|
||||
cmd2.apply = function() { lastCalled = 'cmd2.apply'; };
|
||||
cmd3.apply = function() { lastCalled = 'cmd3.apply'; };
|
||||
cmd1.unapply = function() { lastCalled = 'cmd1.unapply'; };
|
||||
cmd2.unapply = function() { lastCalled = 'cmd2.unapply'; };
|
||||
cmd3.unapply = function() { lastCalled = 'cmd3.unapply'; };
|
||||
|
||||
undoMgr.addCommandToHistory(cmd1);
|
||||
undoMgr.addCommandToHistory(cmd2);
|
||||
undoMgr.addCommandToHistory(cmd3);
|
||||
|
||||
ok(!lastCalled);
|
||||
|
||||
undoMgr.undo();
|
||||
equals(lastCalled, 'cmd3.unapply');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(lastCalled, 'cmd3.apply');
|
||||
|
||||
undoMgr.undo();
|
||||
undoMgr.undo();
|
||||
equals(lastCalled, 'cmd2.unapply');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(lastCalled, 'cmd1.unapply');
|
||||
lastCalled = null;
|
||||
|
||||
undoMgr.undo();
|
||||
ok(!lastCalled);
|
||||
|
||||
undoMgr.redo();
|
||||
equals(lastCalled, 'cmd1.apply');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(lastCalled, 'cmd2.apply');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(lastCalled, 'cmd3.apply');
|
||||
lastCalled = null;
|
||||
|
||||
undoMgr.redo();
|
||||
ok(!lastCalled);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test MoveElementCommand', function() {
|
||||
expect(26);
|
||||
|
||||
setUp();
|
||||
|
||||
var move = new svgedit.history.MoveElementCommand(div3, div1, divparent);
|
||||
ok(move.unapply);
|
||||
ok(move.apply);
|
||||
equals(typeof move.unapply, typeof function(){});
|
||||
equals(typeof move.apply, typeof function(){});
|
||||
|
||||
move.unapply();
|
||||
equals(divparent.firstElementChild, div3);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div1);
|
||||
equals(divparent.lastElementChild, div2);
|
||||
|
||||
move.apply();
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div2);
|
||||
equals(divparent.lastElementChild, div3);
|
||||
|
||||
move = new svgedit.history.MoveElementCommand(div1, null, divparent);
|
||||
|
||||
move.unapply();
|
||||
equals(divparent.firstElementChild, div2);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div3);
|
||||
equals(divparent.lastElementChild, div1);
|
||||
|
||||
move.apply();
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div2);
|
||||
equals(divparent.lastElementChild, div3);
|
||||
|
||||
move = new svgedit.history.MoveElementCommand(div2, div5, div4);
|
||||
|
||||
move.unapply();
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div3);
|
||||
equals(divparent.lastElementChild, div3);
|
||||
equals(div4.firstElementChild, div2);
|
||||
equals(div4.firstElementChild.nextElementSibling, div5);
|
||||
|
||||
move.apply();
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div2);
|
||||
equals(divparent.lastElementChild, div3);
|
||||
equals(div4.firstElementChild, div5);
|
||||
equals(div4.lastElementChild, div5);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test InsertElementCommand', function() {
|
||||
expect(20);
|
||||
|
||||
setUp();
|
||||
|
||||
var insert = new svgedit.history.InsertElementCommand(div3);
|
||||
ok(insert.unapply);
|
||||
ok(insert.apply);
|
||||
equals(typeof insert.unapply, typeof function(){});
|
||||
equals(typeof insert.apply, typeof function(){});
|
||||
|
||||
insert.unapply();
|
||||
equals(divparent.childElementCount, 2);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(divparent.lastElementChild, div2);
|
||||
|
||||
insert.apply();
|
||||
equals(divparent.childElementCount, 3);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
|
||||
insert = new svgedit.history.InsertElementCommand(div2);
|
||||
|
||||
insert.unapply();
|
||||
equals(divparent.childElementCount, 2);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div3);
|
||||
equals(divparent.lastElementChild, div3);
|
||||
|
||||
insert.apply();
|
||||
equals(divparent.childElementCount, 3);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test RemoveElementCommand', function() {
|
||||
expect(22);
|
||||
|
||||
setUp();
|
||||
|
||||
var div6 = document.createElement('div');
|
||||
div6.id = 'div6';
|
||||
|
||||
var remove = new svgedit.history.RemoveElementCommand(div6, null, divparent);
|
||||
ok(remove.unapply);
|
||||
ok(remove.apply);
|
||||
equals(typeof remove.unapply, typeof function(){});
|
||||
equals(typeof remove.apply, typeof function(){});
|
||||
|
||||
remove.unapply();
|
||||
equals(divparent.childElementCount, 4);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
equals(div3.nextElementSibling, div6);
|
||||
|
||||
remove.apply();
|
||||
equals(divparent.childElementCount, 3);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
|
||||
remove = new svgedit.history.RemoveElementCommand(div6, div2, divparent);
|
||||
|
||||
remove.unapply();
|
||||
equals(divparent.childElementCount, 4);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div6);
|
||||
equals(div6.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
|
||||
remove.apply();
|
||||
equals(divparent.childElementCount, 3);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test ChangeElementCommand', function() {
|
||||
expect(26);
|
||||
|
||||
setUp();
|
||||
|
||||
div1.setAttribute('title', 'new title');
|
||||
var change = new svgedit.history.ChangeElementCommand(div1,
|
||||
{'title': 'old title', 'class': 'foo'});
|
||||
ok(change.unapply);
|
||||
ok(change.apply);
|
||||
equals(typeof change.unapply, typeof function(){});
|
||||
equals(typeof change.apply, typeof function(){});
|
||||
|
||||
change.unapply();
|
||||
equals(div1.getAttribute('title'), 'old title');
|
||||
equals(div1.getAttribute('class'), 'foo');
|
||||
|
||||
change.apply();
|
||||
equals(div1.getAttribute('title'), 'new title');
|
||||
ok(!div1.getAttribute('class'));
|
||||
|
||||
div1.textContent = 'inner text';
|
||||
change = new svgedit.history.ChangeElementCommand(div1,
|
||||
{'#text': null});
|
||||
|
||||
change.unapply();
|
||||
ok(!div1.textContent);
|
||||
|
||||
change.apply();
|
||||
equals(div1.textContent, 'inner text');
|
||||
|
||||
div1.textContent = '';
|
||||
change = new svgedit.history.ChangeElementCommand(div1,
|
||||
{'#text': 'old text'});
|
||||
|
||||
change.unapply();
|
||||
equals(div1.textContent, 'old text');
|
||||
|
||||
change.apply();
|
||||
ok(!div1.textContent);
|
||||
|
||||
// TODO(codedread): Refactor this #href stuff in history.js and svgcanvas.js
|
||||
var rect = document.createElementNS(NS.SVG, 'rect');
|
||||
var justCalled = null;
|
||||
var gethrefvalue = null;
|
||||
var sethrefvalue = null;
|
||||
svgedit.utilities.getHref = function(elem) {
|
||||
equals(elem, rect);
|
||||
justCalled = 'getHref';
|
||||
return gethrefvalue;
|
||||
};
|
||||
svgedit.utilities.setHref = function(elem, val) {
|
||||
equals(elem, rect);
|
||||
equals(val, sethrefvalue);
|
||||
justCalled = 'setHref';
|
||||
};
|
||||
|
||||
gethrefvalue = '#newhref';
|
||||
change = new svgedit.history.ChangeElementCommand(rect,
|
||||
{'#href': '#oldhref'});
|
||||
equals(justCalled, 'getHref');
|
||||
|
||||
justCalled = null;
|
||||
sethrefvalue = '#oldhref';
|
||||
change.unapply();
|
||||
equals(justCalled, 'setHref');
|
||||
|
||||
justCalled = null;
|
||||
sethrefvalue = '#newhref';
|
||||
change.apply();
|
||||
equals(justCalled, 'setHref');
|
||||
|
||||
var line = document.createElementNS(NS.SVG,'line');
|
||||
line.setAttributeNS(null, 'class', 'newClass');
|
||||
change = new svgedit.history.ChangeElementCommand(line,{class:'oldClass'});
|
||||
|
||||
ok(change.unapply);
|
||||
ok(change.apply);
|
||||
equals(typeof change.unapply, typeof function(){});
|
||||
equals(typeof change.apply, typeof function(){});
|
||||
|
||||
change.unapply();
|
||||
equals(line.getAttributeNS(null, 'class'), 'oldClass');
|
||||
|
||||
change.apply();
|
||||
equals(line.getAttributeNS(null, 'class'), 'newClass');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test BatchCommand', function() {
|
||||
expect(13);
|
||||
|
||||
setUp();
|
||||
|
||||
var concatResult = '';
|
||||
MockCommand.prototype.apply = function() { concatResult += this.text_; };
|
||||
|
||||
var batch = new svgedit.history.BatchCommand();
|
||||
ok(batch.unapply);
|
||||
ok(batch.apply);
|
||||
ok(batch.addSubCommand);
|
||||
ok(batch.isEmpty);
|
||||
equals(typeof batch.unapply, typeof function(){});
|
||||
equals(typeof batch.apply, typeof function(){});
|
||||
equals(typeof batch.addSubCommand, typeof function(){});
|
||||
equals(typeof batch.isEmpty, typeof function(){});
|
||||
|
||||
ok(batch.isEmpty());
|
||||
|
||||
batch.addSubCommand(new MockCommand('a'));
|
||||
ok(!batch.isEmpty());
|
||||
batch.addSubCommand(new MockCommand('b'));
|
||||
batch.addSubCommand(new MockCommand('c'));
|
||||
|
||||
ok(!concatResult);
|
||||
batch.apply();
|
||||
equals(concatResult, 'abc');
|
||||
|
||||
MockCommand.prototype.apply = function() {};
|
||||
MockCommand.prototype.unapply = function() { concatResult += this.text_; };
|
||||
concatResult = '';
|
||||
batch.unapply();
|
||||
equals(concatResult, 'cba');
|
||||
|
||||
MockCommand.prototype.unapply = function() {};
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="history_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for history.js</h1>
|
||||
|
||||
565
test/history_test.js
Normal file
565
test/history_test.js
Normal file
@@ -0,0 +1,565 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit, equals */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// TODO(codedread): Write tests for handling history events.
|
||||
|
||||
// Mocked out methods.
|
||||
svgedit.transformlist = {};
|
||||
svgedit.transformlist.removeElementFromListMap = function (elem) {};
|
||||
svgedit.utilities = {};
|
||||
svgedit.utilities.getHref = function (elem) { return '#foo'; };
|
||||
svgedit.utilities.setHref = function (elem, val) {};
|
||||
svgedit.utilities.getRotationAngle = function (elem) { return 0; };
|
||||
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var NS = svgedit.NS;
|
||||
// var svg = document.createElementNS(NS.SVG, 'svg');
|
||||
var undoMgr = null;
|
||||
var divparent = document.getElementById('divparent');
|
||||
var div1 = document.getElementById('div1');
|
||||
var div2 = document.getElementById('div2');
|
||||
var div3 = document.getElementById('div3');
|
||||
var div4 = document.getElementById('div4');
|
||||
var div5 = document.getElementById('div5');
|
||||
|
||||
module('svgedit.history');
|
||||
|
||||
var MockCommand = function (optText) { this.text_ = optText; };
|
||||
MockCommand.prototype.apply = function () {};
|
||||
MockCommand.prototype.unapply = function () {};
|
||||
MockCommand.prototype.getText = function () { return this.text_; };
|
||||
MockCommand.prototype.elements = function () { return []; };
|
||||
|
||||
var MockHistoryEventHandler = function () {};
|
||||
MockHistoryEventHandler.prototype.handleHistoryEvent = function (eventType, command) {};
|
||||
|
||||
function setUp () {
|
||||
undoMgr = new svgedit.history.UndoManager();
|
||||
}
|
||||
function tearDown () {
|
||||
undoMgr = null;
|
||||
}
|
||||
|
||||
test('Test svgedit.history package', function () {
|
||||
expect(13);
|
||||
|
||||
ok(svgedit.history);
|
||||
ok(svgedit.history.MoveElementCommand);
|
||||
ok(svgedit.history.InsertElementCommand);
|
||||
ok(svgedit.history.ChangeElementCommand);
|
||||
ok(svgedit.history.RemoveElementCommand);
|
||||
ok(svgedit.history.BatchCommand);
|
||||
ok(svgedit.history.UndoManager);
|
||||
equals(typeof svgedit.history.MoveElementCommand, typeof function () {});
|
||||
equals(typeof svgedit.history.InsertElementCommand, typeof function () {});
|
||||
equals(typeof svgedit.history.ChangeElementCommand, typeof function () {});
|
||||
equals(typeof svgedit.history.RemoveElementCommand, typeof function () {});
|
||||
equals(typeof svgedit.history.BatchCommand, typeof function () {});
|
||||
equals(typeof svgedit.history.UndoManager, typeof function () {});
|
||||
});
|
||||
|
||||
test('Test UndoManager methods', function () {
|
||||
expect(14);
|
||||
setUp();
|
||||
|
||||
ok(undoMgr);
|
||||
ok(undoMgr.addCommandToHistory);
|
||||
ok(undoMgr.getUndoStackSize);
|
||||
ok(undoMgr.getRedoStackSize);
|
||||
ok(undoMgr.resetUndoStack);
|
||||
ok(undoMgr.getNextUndoCommandText);
|
||||
ok(undoMgr.getNextRedoCommandText);
|
||||
|
||||
equals(typeof undoMgr, typeof {});
|
||||
equals(typeof undoMgr.addCommandToHistory, typeof function () {});
|
||||
equals(typeof undoMgr.getUndoStackSize, typeof function () {});
|
||||
equals(typeof undoMgr.getRedoStackSize, typeof function () {});
|
||||
equals(typeof undoMgr.resetUndoStack, typeof function () {});
|
||||
equals(typeof undoMgr.getNextUndoCommandText, typeof function () {});
|
||||
equals(typeof undoMgr.getNextRedoCommandText, typeof function () {});
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.addCommandToHistory() function', function () {
|
||||
expect(3);
|
||||
|
||||
setUp();
|
||||
|
||||
equals(undoMgr.getUndoStackSize(), 0);
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
equals(undoMgr.getUndoStackSize(), 1);
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
equals(undoMgr.getUndoStackSize(), 2);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.getUndoStackSize() and getRedoStackSize() functions', function () {
|
||||
expect(18);
|
||||
|
||||
setUp();
|
||||
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
|
||||
equals(undoMgr.getUndoStackSize(), 3);
|
||||
equals(undoMgr.getRedoStackSize(), 0);
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getUndoStackSize(), 2);
|
||||
equals(undoMgr.getRedoStackSize(), 1);
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getUndoStackSize(), 1);
|
||||
equals(undoMgr.getRedoStackSize(), 2);
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getUndoStackSize(), 0);
|
||||
equals(undoMgr.getRedoStackSize(), 3);
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getUndoStackSize(), 0);
|
||||
equals(undoMgr.getRedoStackSize(), 3);
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getUndoStackSize(), 1);
|
||||
equals(undoMgr.getRedoStackSize(), 2);
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getUndoStackSize(), 2);
|
||||
equals(undoMgr.getRedoStackSize(), 1);
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getUndoStackSize(), 3);
|
||||
equals(undoMgr.getRedoStackSize(), 0);
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getUndoStackSize(), 3);
|
||||
equals(undoMgr.getRedoStackSize(), 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.resetUndoStackSize() function', function () {
|
||||
expect(4);
|
||||
|
||||
setUp();
|
||||
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.undo();
|
||||
|
||||
equals(undoMgr.getUndoStackSize(), 2);
|
||||
equals(undoMgr.getRedoStackSize(), 1);
|
||||
|
||||
undoMgr.resetUndoStack();
|
||||
|
||||
equals(undoMgr.getUndoStackSize(), 0);
|
||||
equals(undoMgr.getRedoStackSize(), 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.getNextUndoCommandText() function', function () {
|
||||
expect(9);
|
||||
|
||||
setUp();
|
||||
|
||||
equals(undoMgr.getNextUndoCommandText(), '');
|
||||
|
||||
undoMgr.addCommandToHistory(new MockCommand('First'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Second'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Third'));
|
||||
|
||||
equals(undoMgr.getNextUndoCommandText(), 'Third');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'Second');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'First');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextUndoCommandText(), '');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'First');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'Second');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'Third');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextUndoCommandText(), 'Third');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.getNextRedoCommandText() function', function () {
|
||||
expect(8);
|
||||
|
||||
setUp();
|
||||
|
||||
equals(undoMgr.getNextRedoCommandText(), '');
|
||||
|
||||
undoMgr.addCommandToHistory(new MockCommand('First'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Second'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Third'));
|
||||
|
||||
equals(undoMgr.getNextRedoCommandText(), '');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextRedoCommandText(), 'Third');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextRedoCommandText(), 'Second');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(undoMgr.getNextRedoCommandText(), 'First');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextRedoCommandText(), 'Second');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextRedoCommandText(), 'Third');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(undoMgr.getNextRedoCommandText(), '');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test UndoManager.undo() and redo() functions', function () {
|
||||
expect(10);
|
||||
|
||||
setUp();
|
||||
|
||||
var lastCalled = null;
|
||||
var cmd1 = new MockCommand();
|
||||
var cmd2 = new MockCommand();
|
||||
var cmd3 = new MockCommand();
|
||||
cmd1.apply = function () { lastCalled = 'cmd1.apply'; };
|
||||
cmd2.apply = function () { lastCalled = 'cmd2.apply'; };
|
||||
cmd3.apply = function () { lastCalled = 'cmd3.apply'; };
|
||||
cmd1.unapply = function () { lastCalled = 'cmd1.unapply'; };
|
||||
cmd2.unapply = function () { lastCalled = 'cmd2.unapply'; };
|
||||
cmd3.unapply = function () { lastCalled = 'cmd3.unapply'; };
|
||||
|
||||
undoMgr.addCommandToHistory(cmd1);
|
||||
undoMgr.addCommandToHistory(cmd2);
|
||||
undoMgr.addCommandToHistory(cmd3);
|
||||
|
||||
ok(!lastCalled);
|
||||
|
||||
undoMgr.undo();
|
||||
equals(lastCalled, 'cmd3.unapply');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(lastCalled, 'cmd3.apply');
|
||||
|
||||
undoMgr.undo();
|
||||
undoMgr.undo();
|
||||
equals(lastCalled, 'cmd2.unapply');
|
||||
|
||||
undoMgr.undo();
|
||||
equals(lastCalled, 'cmd1.unapply');
|
||||
lastCalled = null;
|
||||
|
||||
undoMgr.undo();
|
||||
ok(!lastCalled);
|
||||
|
||||
undoMgr.redo();
|
||||
equals(lastCalled, 'cmd1.apply');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(lastCalled, 'cmd2.apply');
|
||||
|
||||
undoMgr.redo();
|
||||
equals(lastCalled, 'cmd3.apply');
|
||||
lastCalled = null;
|
||||
|
||||
undoMgr.redo();
|
||||
ok(!lastCalled);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test MoveElementCommand', function () {
|
||||
expect(26);
|
||||
|
||||
setUp();
|
||||
|
||||
var move = new svgedit.history.MoveElementCommand(div3, div1, divparent);
|
||||
ok(move.unapply);
|
||||
ok(move.apply);
|
||||
equals(typeof move.unapply, typeof function () {});
|
||||
equals(typeof move.apply, typeof function () {});
|
||||
|
||||
move.unapply();
|
||||
equals(divparent.firstElementChild, div3);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div1);
|
||||
equals(divparent.lastElementChild, div2);
|
||||
|
||||
move.apply();
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div2);
|
||||
equals(divparent.lastElementChild, div3);
|
||||
|
||||
move = new svgedit.history.MoveElementCommand(div1, null, divparent);
|
||||
|
||||
move.unapply();
|
||||
equals(divparent.firstElementChild, div2);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div3);
|
||||
equals(divparent.lastElementChild, div1);
|
||||
|
||||
move.apply();
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div2);
|
||||
equals(divparent.lastElementChild, div3);
|
||||
|
||||
move = new svgedit.history.MoveElementCommand(div2, div5, div4);
|
||||
|
||||
move.unapply();
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div3);
|
||||
equals(divparent.lastElementChild, div3);
|
||||
equals(div4.firstElementChild, div2);
|
||||
equals(div4.firstElementChild.nextElementSibling, div5);
|
||||
|
||||
move.apply();
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(divparent.firstElementChild.nextElementSibling, div2);
|
||||
equals(divparent.lastElementChild, div3);
|
||||
equals(div4.firstElementChild, div5);
|
||||
equals(div4.lastElementChild, div5);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test InsertElementCommand', function () {
|
||||
expect(20);
|
||||
|
||||
setUp();
|
||||
|
||||
var insert = new svgedit.history.InsertElementCommand(div3);
|
||||
ok(insert.unapply);
|
||||
ok(insert.apply);
|
||||
equals(typeof insert.unapply, typeof function () {});
|
||||
equals(typeof insert.apply, typeof function () {});
|
||||
|
||||
insert.unapply();
|
||||
equals(divparent.childElementCount, 2);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(divparent.lastElementChild, div2);
|
||||
|
||||
insert.apply();
|
||||
equals(divparent.childElementCount, 3);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
|
||||
insert = new svgedit.history.InsertElementCommand(div2);
|
||||
|
||||
insert.unapply();
|
||||
equals(divparent.childElementCount, 2);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div3);
|
||||
equals(divparent.lastElementChild, div3);
|
||||
|
||||
insert.apply();
|
||||
equals(divparent.childElementCount, 3);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test RemoveElementCommand', function () {
|
||||
expect(22);
|
||||
|
||||
setUp();
|
||||
|
||||
var div6 = document.createElement('div');
|
||||
div6.id = 'div6';
|
||||
|
||||
var remove = new svgedit.history.RemoveElementCommand(div6, null, divparent);
|
||||
ok(remove.unapply);
|
||||
ok(remove.apply);
|
||||
equals(typeof remove.unapply, typeof function () {});
|
||||
equals(typeof remove.apply, typeof function () {});
|
||||
|
||||
remove.unapply();
|
||||
equals(divparent.childElementCount, 4);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
equals(div3.nextElementSibling, div6);
|
||||
|
||||
remove.apply();
|
||||
equals(divparent.childElementCount, 3);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
|
||||
remove = new svgedit.history.RemoveElementCommand(div6, div2, divparent);
|
||||
|
||||
remove.unapply();
|
||||
equals(divparent.childElementCount, 4);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div6);
|
||||
equals(div6.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
|
||||
remove.apply();
|
||||
equals(divparent.childElementCount, 3);
|
||||
equals(divparent.firstElementChild, div1);
|
||||
equals(div1.nextElementSibling, div2);
|
||||
equals(div2.nextElementSibling, div3);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test ChangeElementCommand', function () {
|
||||
expect(26);
|
||||
|
||||
setUp();
|
||||
|
||||
div1.setAttribute('title', 'new title');
|
||||
var change = new svgedit.history.ChangeElementCommand(div1,
|
||||
{'title': 'old title', 'class': 'foo'});
|
||||
ok(change.unapply);
|
||||
ok(change.apply);
|
||||
equals(typeof change.unapply, typeof function () {});
|
||||
equals(typeof change.apply, typeof function () {});
|
||||
|
||||
change.unapply();
|
||||
equals(div1.getAttribute('title'), 'old title');
|
||||
equals(div1.getAttribute('class'), 'foo');
|
||||
|
||||
change.apply();
|
||||
equals(div1.getAttribute('title'), 'new title');
|
||||
ok(!div1.getAttribute('class'));
|
||||
|
||||
div1.textContent = 'inner text';
|
||||
change = new svgedit.history.ChangeElementCommand(div1,
|
||||
{'#text': null});
|
||||
|
||||
change.unapply();
|
||||
ok(!div1.textContent);
|
||||
|
||||
change.apply();
|
||||
equals(div1.textContent, 'inner text');
|
||||
|
||||
div1.textContent = '';
|
||||
change = new svgedit.history.ChangeElementCommand(div1,
|
||||
{'#text': 'old text'});
|
||||
|
||||
change.unapply();
|
||||
equals(div1.textContent, 'old text');
|
||||
|
||||
change.apply();
|
||||
ok(!div1.textContent);
|
||||
|
||||
// TODO(codedread): Refactor this #href stuff in history.js and svgcanvas.js
|
||||
var rect = document.createElementNS(NS.SVG, 'rect');
|
||||
var justCalled = null;
|
||||
var gethrefvalue = null;
|
||||
var sethrefvalue = null;
|
||||
svgedit.utilities.getHref = function (elem) {
|
||||
equals(elem, rect);
|
||||
justCalled = 'getHref';
|
||||
return gethrefvalue;
|
||||
};
|
||||
svgedit.utilities.setHref = function (elem, val) {
|
||||
equals(elem, rect);
|
||||
equals(val, sethrefvalue);
|
||||
justCalled = 'setHref';
|
||||
};
|
||||
|
||||
gethrefvalue = '#newhref';
|
||||
change = new svgedit.history.ChangeElementCommand(rect,
|
||||
{'#href': '#oldhref'});
|
||||
equals(justCalled, 'getHref');
|
||||
|
||||
justCalled = null;
|
||||
sethrefvalue = '#oldhref';
|
||||
change.unapply();
|
||||
equals(justCalled, 'setHref');
|
||||
|
||||
justCalled = null;
|
||||
sethrefvalue = '#newhref';
|
||||
change.apply();
|
||||
equals(justCalled, 'setHref');
|
||||
|
||||
var line = document.createElementNS(NS.SVG, 'line');
|
||||
line.setAttributeNS(null, 'class', 'newClass');
|
||||
change = new svgedit.history.ChangeElementCommand(line, {class: 'oldClass'});
|
||||
|
||||
ok(change.unapply);
|
||||
ok(change.apply);
|
||||
equals(typeof change.unapply, typeof function () {});
|
||||
equals(typeof change.apply, typeof function () {});
|
||||
|
||||
change.unapply();
|
||||
equals(line.getAttributeNS(null, 'class'), 'oldClass');
|
||||
|
||||
change.apply();
|
||||
equals(line.getAttributeNS(null, 'class'), 'newClass');
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test BatchCommand', function () {
|
||||
expect(13);
|
||||
|
||||
setUp();
|
||||
|
||||
var concatResult = '';
|
||||
MockCommand.prototype.apply = function () { concatResult += this.text_; };
|
||||
|
||||
var batch = new svgedit.history.BatchCommand();
|
||||
ok(batch.unapply);
|
||||
ok(batch.apply);
|
||||
ok(batch.addSubCommand);
|
||||
ok(batch.isEmpty);
|
||||
equals(typeof batch.unapply, typeof function () {});
|
||||
equals(typeof batch.apply, typeof function () {});
|
||||
equals(typeof batch.addSubCommand, typeof function () {});
|
||||
equals(typeof batch.isEmpty, typeof function () {});
|
||||
|
||||
ok(batch.isEmpty());
|
||||
|
||||
batch.addSubCommand(new MockCommand('a'));
|
||||
ok(!batch.isEmpty());
|
||||
batch.addSubCommand(new MockCommand('b'));
|
||||
batch.addSubCommand(new MockCommand('c'));
|
||||
|
||||
ok(!concatResult);
|
||||
batch.apply();
|
||||
equals(concatResult, 'abc');
|
||||
|
||||
MockCommand.prototype.apply = function () {};
|
||||
MockCommand.prototype.unapply = function () { concatResult += this.text_; };
|
||||
concatResult = '';
|
||||
batch.unapply();
|
||||
equals(concatResult, 'cba');
|
||||
|
||||
MockCommand.prototype.unapply = function () {};
|
||||
|
||||
tearDown();
|
||||
});
|
||||
});
|
||||
@@ -6,17 +6,7 @@
|
||||
<link rel="stylesheet" href="qunit/qunit.css"/>
|
||||
<script src="../editor/jquery.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="jquery-svg_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for jquery-svg</h1>
|
||||
|
||||
10
test/jquery-svg_test.js
vendored
Normal file
10
test/jquery-svg_test.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $ */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -8,127 +8,7 @@
|
||||
<script src="../editor/svgedit.js"></script>
|
||||
<script src="../editor/math.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
|
||||
module('svgedit.math');
|
||||
|
||||
test('Test svgedit.math package', function() {
|
||||
expect(7);
|
||||
|
||||
ok(svgedit.math);
|
||||
ok(svgedit.math.transformPoint);
|
||||
ok(svgedit.math.isIdentity);
|
||||
ok(svgedit.math.matrixMultiply);
|
||||
equals(typeof svgedit.math.transformPoint, typeof function(){});
|
||||
equals(typeof svgedit.math.isIdentity, typeof function(){});
|
||||
equals(typeof svgedit.math.matrixMultiply, typeof function(){});
|
||||
});
|
||||
|
||||
test('Test svgedit.math.transformPoint() function', function() {
|
||||
expect(6);
|
||||
var transformPoint = svgedit.math.transformPoint;
|
||||
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 0; m.f = 0;
|
||||
var pt = transformPoint(100, 200, m);
|
||||
equals(pt.x, 100);
|
||||
equals(pt.y, 200);
|
||||
|
||||
m.e = 300; m.f = 400;
|
||||
pt = transformPoint(100, 200, m);
|
||||
equals(pt.x, 400);
|
||||
equals(pt.y, 600);
|
||||
|
||||
m.a = 0.5; m.b = 0.75;
|
||||
m.c = 1.25; m.d = 2;
|
||||
pt = transformPoint(100, 200, m);
|
||||
equals(pt.x, 100 * m.a + 200 * m.c + m.e);
|
||||
equals(pt.y, 100 * m.b + 200 * m.d + m.f);
|
||||
});
|
||||
|
||||
test('Test svgedit.math.isIdentity() function', function() {
|
||||
expect(2);
|
||||
|
||||
ok(svgedit.math.isIdentity(svg.createSVGMatrix()));
|
||||
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 0; m.f = 0;
|
||||
ok(svgedit.math.isIdentity(m));
|
||||
});
|
||||
|
||||
test('Test svgedit.math.matrixMultiply() function', function() {
|
||||
expect(5);
|
||||
var mult = svgedit.math.matrixMultiply;
|
||||
var isIdentity = svgedit.math.isIdentity;
|
||||
|
||||
// translate there and back
|
||||
var tr_1 = svg.createSVGMatrix().translate(100,50),
|
||||
tr_2 = svg.createSVGMatrix().translate(-90,0),
|
||||
tr_3 = svg.createSVGMatrix().translate(-10,-50),
|
||||
I = mult(tr_1,tr_2,tr_3);
|
||||
ok(isIdentity(I), 'Expected identity matrix when translating there and back');
|
||||
|
||||
// rotate there and back
|
||||
// TODO: currently Mozilla fails this when rotating back at -50 and then -40 degrees
|
||||
// (b and c are *almost* zero, but not zero)
|
||||
var rot_there = svg.createSVGMatrix().rotate(90),
|
||||
rot_back = svg.createSVGMatrix().rotate(-90); // TODO: set this to -50
|
||||
rot_back_more = svg.createSVGMatrix().rotate(0); // TODO: set this to -40
|
||||
I = mult(rot_there, rot_back, rot_back_more);
|
||||
ok(isIdentity(I), 'Expected identity matrix when rotating there and back');
|
||||
|
||||
// scale up and down
|
||||
var scale_up = svg.createSVGMatrix().scale(4),
|
||||
scale_down = svg.createSVGMatrix().scaleNonUniform(0.25,1);
|
||||
scale_down_more = svg.createSVGMatrix().scaleNonUniform(1,0.25);
|
||||
I = mult(scale_up, scale_down, scale_down_more);
|
||||
ok(isIdentity(I), 'Expected identity matrix when scaling up and down');
|
||||
|
||||
// test multiplication with its inverse
|
||||
I = mult(rot_there, rot_there.inverse());
|
||||
ok(isIdentity(I), 'Expected identity matrix when multiplying a matrix by its inverse');
|
||||
I = mult(rot_there.inverse(), rot_there);
|
||||
ok(isIdentity(I), 'Expected identity matrix when multiplying a matrix by its inverse');
|
||||
});
|
||||
|
||||
test('Test svgedit.math.transformBox() function', function() {
|
||||
expect(12);
|
||||
var transformBox = svgedit.math.transformBox;
|
||||
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 0; m.f = 0;
|
||||
|
||||
var r = transformBox(10, 10, 200, 300, m);
|
||||
equals(r.tl.x, 10);
|
||||
equals(r.tl.y, 10);
|
||||
equals(r.tr.x, 210);
|
||||
equals(r.tr.y, 10);
|
||||
equals(r.bl.x, 10);
|
||||
equals(r.bl.y, 310);
|
||||
equals(r.br.x, 210);
|
||||
equals(r.br.y, 310);
|
||||
equals(r.aabox.x, 10);
|
||||
equals(r.aabox.y, 10);
|
||||
equals(r.aabox.width, 200);
|
||||
equals(r.aabox.height, 300);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script src="math_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for math.js</h1>
|
||||
|
||||
122
test/math_test.js
Normal file
122
test/math_test.js
Normal file
@@ -0,0 +1,122 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit, equals */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
|
||||
module('svgedit.math');
|
||||
|
||||
test('Test svgedit.math package', function () {
|
||||
expect(7);
|
||||
|
||||
ok(svgedit.math);
|
||||
ok(svgedit.math.transformPoint);
|
||||
ok(svgedit.math.isIdentity);
|
||||
ok(svgedit.math.matrixMultiply);
|
||||
equals(typeof svgedit.math.transformPoint, typeof function () {});
|
||||
equals(typeof svgedit.math.isIdentity, typeof function () {});
|
||||
equals(typeof svgedit.math.matrixMultiply, typeof function () {});
|
||||
});
|
||||
|
||||
test('Test svgedit.math.transformPoint() function', function () {
|
||||
expect(6);
|
||||
var transformPoint = svgedit.math.transformPoint;
|
||||
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 0; m.f = 0;
|
||||
var pt = transformPoint(100, 200, m);
|
||||
equals(pt.x, 100);
|
||||
equals(pt.y, 200);
|
||||
|
||||
m.e = 300; m.f = 400;
|
||||
pt = transformPoint(100, 200, m);
|
||||
equals(pt.x, 400);
|
||||
equals(pt.y, 600);
|
||||
|
||||
m.a = 0.5; m.b = 0.75;
|
||||
m.c = 1.25; m.d = 2;
|
||||
pt = transformPoint(100, 200, m);
|
||||
equals(pt.x, 100 * m.a + 200 * m.c + m.e);
|
||||
equals(pt.y, 100 * m.b + 200 * m.d + m.f);
|
||||
});
|
||||
|
||||
test('Test svgedit.math.isIdentity() function', function () {
|
||||
expect(2);
|
||||
|
||||
ok(svgedit.math.isIdentity(svg.createSVGMatrix()));
|
||||
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 0; m.f = 0;
|
||||
ok(svgedit.math.isIdentity(m));
|
||||
});
|
||||
|
||||
test('Test svgedit.math.matrixMultiply() function', function () {
|
||||
expect(5);
|
||||
var mult = svgedit.math.matrixMultiply;
|
||||
var isIdentity = svgedit.math.isIdentity;
|
||||
|
||||
// translate there and back
|
||||
var tr1 = svg.createSVGMatrix().translate(100, 50),
|
||||
tr2 = svg.createSVGMatrix().translate(-90, 0),
|
||||
tr3 = svg.createSVGMatrix().translate(-10, -50),
|
||||
I = mult(tr1, tr2, tr3);
|
||||
ok(isIdentity(I), 'Expected identity matrix when translating there and back');
|
||||
|
||||
// rotate there and back
|
||||
// TODO: currently Mozilla fails this when rotating back at -50 and then -40 degrees
|
||||
// (b and c are *almost* zero, but not zero)
|
||||
var rotThere = svg.createSVGMatrix().rotate(90),
|
||||
rotBack = svg.createSVGMatrix().rotate(-90), // TODO: set this to -50
|
||||
rotBackMore = svg.createSVGMatrix().rotate(0); // TODO: set this to -40
|
||||
I = mult(rotThere, rotBack, rotBackMore);
|
||||
ok(isIdentity(I), 'Expected identity matrix when rotating there and back');
|
||||
|
||||
// scale up and down
|
||||
var scaleUp = svg.createSVGMatrix().scale(4),
|
||||
scaleDown = svg.createSVGMatrix().scaleNonUniform(0.25, 1),
|
||||
scaleDownMore = svg.createSVGMatrix().scaleNonUniform(1, 0.25);
|
||||
I = mult(scaleUp, scaleDown, scaleDownMore);
|
||||
ok(isIdentity(I), 'Expected identity matrix when scaling up and down');
|
||||
|
||||
// test multiplication with its inverse
|
||||
I = mult(rotThere, rotThere.inverse());
|
||||
ok(isIdentity(I), 'Expected identity matrix when multiplying a matrix by its inverse');
|
||||
I = mult(rotThere.inverse(), rotThere);
|
||||
ok(isIdentity(I), 'Expected identity matrix when multiplying a matrix by its inverse');
|
||||
});
|
||||
|
||||
test('Test svgedit.math.transformBox() function', function () {
|
||||
expect(12);
|
||||
var transformBox = svgedit.math.transformBox;
|
||||
|
||||
var m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 0; m.f = 0;
|
||||
|
||||
var r = transformBox(10, 10, 200, 300, m);
|
||||
equals(r.tl.x, 10);
|
||||
equals(r.tl.y, 10);
|
||||
equals(r.tr.x, 210);
|
||||
equals(r.tr.y, 10);
|
||||
equals(r.bl.x, 10);
|
||||
equals(r.bl.y, 310);
|
||||
equals(r.br.x, 210);
|
||||
equals(r.br.y, 310);
|
||||
equals(r.aabox.x, 10);
|
||||
equals(r.aabox.y, 10);
|
||||
equals(r.aabox.width, 200);
|
||||
equals(r.aabox.height, 300);
|
||||
});
|
||||
});
|
||||
@@ -11,145 +11,7 @@
|
||||
<script src="../editor/svgutils.js"></script>
|
||||
<script src="../editor/path.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
test('Test svgedit.path.replacePathSeg', function() {
|
||||
expect(6);
|
||||
|
||||
var path = document.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
|
||||
svgedit.path.init();
|
||||
svgedit.path.Path(path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
equals(path.pathSegList.getItem(1).x, 10);
|
||||
equals(path.pathSegList.getItem(1).y, 11);
|
||||
|
||||
svgedit.path.replacePathSeg(SVGPathSeg.PATHSEG_LINETO_REL, 1, [30, 31], path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'l');
|
||||
equals(path.pathSegList.getItem(1).x, 30);
|
||||
equals(path.pathSegList.getItem(1).y, 31);
|
||||
});
|
||||
|
||||
test('Test svgedit.path.Segment.setType simple', function() {
|
||||
expect(9);
|
||||
|
||||
var path = document.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
|
||||
svgedit.path.init();
|
||||
svgedit.path.Path(path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
equals(path.pathSegList.getItem(1).x, 10);
|
||||
equals(path.pathSegList.getItem(1).y, 11);
|
||||
|
||||
var segment = new svgedit.path.Segment(1, path.pathSegList.getItem(1));
|
||||
segment.setType(SVGPathSeg.PATHSEG_LINETO_REL, [30, 31]);
|
||||
equals(segment.item.pathSegTypeAsLetter, 'l');
|
||||
equals(segment.item.x, 30);
|
||||
equals(segment.item.y, 31);
|
||||
|
||||
// Also verify that the actual path changed.
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'l');
|
||||
equals(path.pathSegList.getItem(1).x, 30);
|
||||
equals(path.pathSegList.getItem(1).y, 31);
|
||||
});
|
||||
|
||||
test('Test svgedit.path.Segment.setType with control points', function() {
|
||||
expect(14);
|
||||
|
||||
// Setup the dom for a mock control group.
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
var path = document.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 C11,12 13,14 15,16 Z');
|
||||
svg.appendChild(path);
|
||||
var selectorParentGroup = document.createElementNS(svgedit.NS.SVG, 'g');
|
||||
selectorParentGroup.setAttribute('id', 'selectorParentGroup');
|
||||
svg.appendChild(selectorParentGroup);
|
||||
var mockContext = {
|
||||
getDOMDocument: function() { return svg; },
|
||||
getDOMContainer: function() { return svg; },
|
||||
getSVGRoot: function() { return svg; },
|
||||
getCurrentZoom: function() { return 1; }
|
||||
};
|
||||
svgedit.path.init(mockContext);
|
||||
svgedit.utilities.init(mockContext);
|
||||
var segment = new svgedit.path.Segment(1, path.pathSegList.getItem(1));
|
||||
segment.path = new svgedit.path.Path(path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C');
|
||||
equals(path.pathSegList.getItem(1).x1, 11);
|
||||
equals(path.pathSegList.getItem(1).y1, 12);
|
||||
equals(path.pathSegList.getItem(1).x2, 13);
|
||||
equals(path.pathSegList.getItem(1).y2, 14);
|
||||
equals(path.pathSegList.getItem(1).x, 15);
|
||||
equals(path.pathSegList.getItem(1).y, 16);
|
||||
|
||||
segment.setType(SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, [30, 31, 32, 33, 34, 35]);
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'c');
|
||||
equals(path.pathSegList.getItem(1).x1, 32);
|
||||
equals(path.pathSegList.getItem(1).y1, 33);
|
||||
equals(path.pathSegList.getItem(1).x2, 34);
|
||||
equals(path.pathSegList.getItem(1).y2, 35);
|
||||
equals(path.pathSegList.getItem(1).x, 30);
|
||||
equals(path.pathSegList.getItem(1).y, 31);
|
||||
});
|
||||
|
||||
test('Test svgedit.path.Segment.move', function() {
|
||||
expect(6);
|
||||
|
||||
var path = document.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
|
||||
svgedit.path.init();
|
||||
svgedit.path.Path(path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
equals(path.pathSegList.getItem(1).x, 10);
|
||||
equals(path.pathSegList.getItem(1).y, 11);
|
||||
|
||||
var segment = new svgedit.path.Segment(1, path.pathSegList.getItem(1));
|
||||
segment.move(-3, 4);
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
equals(path.pathSegList.getItem(1).x, 7);
|
||||
equals(path.pathSegList.getItem(1).y, 15);
|
||||
});
|
||||
|
||||
test('Test svgedit.path.Segment.moveCtrl', function() {
|
||||
expect(14);
|
||||
|
||||
var path = document.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 C11,12 13,14 15,16 Z');
|
||||
svgedit.path.init();
|
||||
svgedit.path.Path(path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C');
|
||||
equals(path.pathSegList.getItem(1).x1, 11);
|
||||
equals(path.pathSegList.getItem(1).y1, 12);
|
||||
equals(path.pathSegList.getItem(1).x2, 13);
|
||||
equals(path.pathSegList.getItem(1).y2, 14);
|
||||
equals(path.pathSegList.getItem(1).x, 15);
|
||||
equals(path.pathSegList.getItem(1).y, 16);
|
||||
|
||||
var segment = new svgedit.path.Segment(1, path.pathSegList.getItem(1));
|
||||
segment.moveCtrl(1, 100, -200);
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C');
|
||||
equals(path.pathSegList.getItem(1).x1, 111);
|
||||
equals(path.pathSegList.getItem(1).y1, -188);
|
||||
equals(path.pathSegList.getItem(1).x2, 13);
|
||||
equals(path.pathSegList.getItem(1).y2, 14);
|
||||
equals(path.pathSegList.getItem(1).x, 15);
|
||||
equals(path.pathSegList.getItem(1).y, 16);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script src="path_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for path.js</h1>
|
||||
|
||||
140
test/path_test.js
Normal file
140
test/path_test.js
Normal file
@@ -0,0 +1,140 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit, equals */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
test('Test svgedit.path.replacePathSeg', function () {
|
||||
expect(6);
|
||||
|
||||
var path = document.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
|
||||
svgedit.path.init();
|
||||
svgedit.path.Path(path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
equals(path.pathSegList.getItem(1).x, 10);
|
||||
equals(path.pathSegList.getItem(1).y, 11);
|
||||
|
||||
svgedit.path.replacePathSeg(SVGPathSeg.PATHSEG_LINETO_REL, 1, [30, 31], path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'l');
|
||||
equals(path.pathSegList.getItem(1).x, 30);
|
||||
equals(path.pathSegList.getItem(1).y, 31);
|
||||
});
|
||||
|
||||
test('Test svgedit.path.Segment.setType simple', function () {
|
||||
expect(9);
|
||||
|
||||
var path = document.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
|
||||
svgedit.path.init();
|
||||
svgedit.path.Path(path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
equals(path.pathSegList.getItem(1).x, 10);
|
||||
equals(path.pathSegList.getItem(1).y, 11);
|
||||
|
||||
var segment = new svgedit.path.Segment(1, path.pathSegList.getItem(1));
|
||||
segment.setType(SVGPathSeg.PATHSEG_LINETO_REL, [30, 31]);
|
||||
equals(segment.item.pathSegTypeAsLetter, 'l');
|
||||
equals(segment.item.x, 30);
|
||||
equals(segment.item.y, 31);
|
||||
|
||||
// Also verify that the actual path changed.
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'l');
|
||||
equals(path.pathSegList.getItem(1).x, 30);
|
||||
equals(path.pathSegList.getItem(1).y, 31);
|
||||
});
|
||||
|
||||
test('Test svgedit.path.Segment.setType with control points', function () {
|
||||
expect(14);
|
||||
|
||||
// Setup the dom for a mock control group.
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
var path = document.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 C11,12 13,14 15,16 Z');
|
||||
svg.appendChild(path);
|
||||
var selectorParentGroup = document.createElementNS(svgedit.NS.SVG, 'g');
|
||||
selectorParentGroup.setAttribute('id', 'selectorParentGroup');
|
||||
svg.appendChild(selectorParentGroup);
|
||||
var mockContext = {
|
||||
getDOMDocument: function () { return svg; },
|
||||
getDOMContainer: function () { return svg; },
|
||||
getSVGRoot: function () { return svg; },
|
||||
getCurrentZoom: function () { return 1; }
|
||||
};
|
||||
svgedit.path.init(mockContext);
|
||||
svgedit.utilities.init(mockContext);
|
||||
var segment = new svgedit.path.Segment(1, path.pathSegList.getItem(1));
|
||||
segment.path = new svgedit.path.Path(path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C');
|
||||
equals(path.pathSegList.getItem(1).x1, 11);
|
||||
equals(path.pathSegList.getItem(1).y1, 12);
|
||||
equals(path.pathSegList.getItem(1).x2, 13);
|
||||
equals(path.pathSegList.getItem(1).y2, 14);
|
||||
equals(path.pathSegList.getItem(1).x, 15);
|
||||
equals(path.pathSegList.getItem(1).y, 16);
|
||||
|
||||
segment.setType(SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, [30, 31, 32, 33, 34, 35]);
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'c');
|
||||
equals(path.pathSegList.getItem(1).x1, 32);
|
||||
equals(path.pathSegList.getItem(1).y1, 33);
|
||||
equals(path.pathSegList.getItem(1).x2, 34);
|
||||
equals(path.pathSegList.getItem(1).y2, 35);
|
||||
equals(path.pathSegList.getItem(1).x, 30);
|
||||
equals(path.pathSegList.getItem(1).y, 31);
|
||||
});
|
||||
|
||||
test('Test svgedit.path.Segment.move', function () {
|
||||
expect(6);
|
||||
|
||||
var path = document.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
|
||||
svgedit.path.init();
|
||||
svgedit.path.Path(path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
equals(path.pathSegList.getItem(1).x, 10);
|
||||
equals(path.pathSegList.getItem(1).y, 11);
|
||||
|
||||
var segment = new svgedit.path.Segment(1, path.pathSegList.getItem(1));
|
||||
segment.move(-3, 4);
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
equals(path.pathSegList.getItem(1).x, 7);
|
||||
equals(path.pathSegList.getItem(1).y, 15);
|
||||
});
|
||||
|
||||
test('Test svgedit.path.Segment.moveCtrl', function () {
|
||||
expect(14);
|
||||
|
||||
var path = document.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 C11,12 13,14 15,16 Z');
|
||||
svgedit.path.init();
|
||||
svgedit.path.Path(path);
|
||||
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C');
|
||||
equals(path.pathSegList.getItem(1).x1, 11);
|
||||
equals(path.pathSegList.getItem(1).y1, 12);
|
||||
equals(path.pathSegList.getItem(1).x2, 13);
|
||||
equals(path.pathSegList.getItem(1).y2, 14);
|
||||
equals(path.pathSegList.getItem(1).x, 15);
|
||||
equals(path.pathSegList.getItem(1).y, 16);
|
||||
|
||||
var segment = new svgedit.path.Segment(1, path.pathSegList.getItem(1));
|
||||
segment.moveCtrl(1, 100, -200);
|
||||
equals(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C');
|
||||
equals(path.pathSegList.getItem(1).x1, 111);
|
||||
equals(path.pathSegList.getItem(1).y1, -188);
|
||||
equals(path.pathSegList.getItem(1).x2, 13);
|
||||
equals(path.pathSegList.getItem(1).y2, 14);
|
||||
equals(path.pathSegList.getItem(1).x, 15);
|
||||
equals(path.pathSegList.getItem(1).y, 16);
|
||||
});
|
||||
});
|
||||
@@ -17,136 +17,7 @@
|
||||
<script src="../editor/coords.js"></script>
|
||||
<script src="../editor/recalculate.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var root = document.getElementById('root');
|
||||
var svgroot = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
svgroot.id = 'svgroot';
|
||||
root.appendChild(svgroot);
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
svgroot.appendChild(svg);
|
||||
var elemId = 1;
|
||||
var elem;
|
||||
|
||||
function setUp() {
|
||||
svgedit.utilities.init({
|
||||
getSVGRoot: function() { return svg },
|
||||
getDOMDocument: function() { return null },
|
||||
getDOMContainer: function() { return null }
|
||||
});
|
||||
svgedit.coords.init({
|
||||
getGridSnapping: function() { return false; },
|
||||
getDrawing: function() {
|
||||
return {
|
||||
getNextId: function() { return '' + elemId++; }
|
||||
};
|
||||
}
|
||||
});
|
||||
svgedit.recalculate.init({
|
||||
getSVGRoot: function() { return svg },
|
||||
getStartTransform: function() { return ''},
|
||||
setStartTransform: function() { }
|
||||
});
|
||||
}
|
||||
|
||||
function setUpRect() {
|
||||
setUp();
|
||||
elem = document.createElementNS(svgedit.NS.SVG, 'rect');
|
||||
elem.setAttribute('x', '200');
|
||||
elem.setAttribute('y', '150');
|
||||
elem.setAttribute('width', '250');
|
||||
elem.setAttribute('height', '120');
|
||||
svg.appendChild(elem);
|
||||
}
|
||||
|
||||
function setUpTextWithTspan() {
|
||||
setUp();
|
||||
elem = document.createElementNS(svgedit.NS.SVG, 'text');
|
||||
elem.setAttribute('x', '200');
|
||||
elem.setAttribute('y', '150');
|
||||
|
||||
var tspan = document.createElementNS(svgedit.NS.SVG, 'tspan');
|
||||
tspan.setAttribute('x', '200');
|
||||
tspan.setAttribute('y', '150');
|
||||
|
||||
var theText = document.createTextNode('Foo bar');
|
||||
tspan.appendChild(theText);
|
||||
elem.appendChild(tspan);
|
||||
svg.appendChild(elem);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
while(svg.hasChildNodes()) {
|
||||
svg.removeChild(svg.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
test('Test recalculateDimensions() on rect with identity matrix', function() {
|
||||
expect(1);
|
||||
|
||||
setUpRect();
|
||||
elem.setAttribute('transform', 'matrix(1,0,0,1,0,0)');
|
||||
|
||||
svgedit.recalculate.recalculateDimensions(elem);
|
||||
|
||||
// Ensure that the identity matrix is swallowed and the element has no
|
||||
// transform on it.
|
||||
equal(false, elem.hasAttribute('transform'));
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test recalculateDimensions() on rect with simple translate', function() {
|
||||
expect(5);
|
||||
|
||||
setUpRect();
|
||||
elem.setAttribute('transform', 'translate(100,50)');
|
||||
|
||||
svgedit.recalculate.recalculateDimensions(elem);
|
||||
|
||||
equal(false, elem.hasAttribute('transform'));
|
||||
equal('300', elem.getAttribute('x'));
|
||||
equal('200', elem.getAttribute('y'));
|
||||
equal('250', elem.getAttribute('width'));
|
||||
equal('120', elem.getAttribute('height'));
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test recalculateDimensions() on text w/tspan with simple translate', function() {
|
||||
expect(5);
|
||||
|
||||
setUpTextWithTspan();
|
||||
elem.setAttribute('transform', 'translate(100,50)');
|
||||
|
||||
svgedit.recalculate.recalculateDimensions(elem);
|
||||
|
||||
// Ensure that the identity matrix is swallowed and the element has no
|
||||
// transform on it.
|
||||
equal(false, elem.hasAttribute('transform'));
|
||||
equal('300', elem.getAttribute('x'));
|
||||
equal('200', elem.getAttribute('y'));
|
||||
|
||||
var tspan = elem.firstElementChild;
|
||||
equal('300', tspan.getAttribute('x'));
|
||||
equal('200', tspan.getAttribute('y'));
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
// TODO: Since recalculateDimensions() and surrounding code is
|
||||
// probably the largest, most complicated and strange piece of
|
||||
// code in SVG-edit, we need to write a whole lot of unit tests
|
||||
// for it here.
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="recalculate_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for svgedit.recalculate</h1>
|
||||
|
||||
130
test/recalculate_test.js
Normal file
130
test/recalculate_test.js
Normal file
@@ -0,0 +1,130 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var root = document.getElementById('root');
|
||||
var svgroot = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
svgroot.id = 'svgroot';
|
||||
root.appendChild(svgroot);
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
svgroot.appendChild(svg);
|
||||
var elemId = 1;
|
||||
var elem;
|
||||
|
||||
function setUp () {
|
||||
svgedit.utilities.init({
|
||||
getSVGRoot: function () { return svg; },
|
||||
getDOMDocument: function () { return null; },
|
||||
getDOMContainer: function () { return null; }
|
||||
});
|
||||
svgedit.coords.init({
|
||||
getGridSnapping: function () { return false; },
|
||||
getDrawing: function () {
|
||||
return {
|
||||
getNextId: function () { return '' + elemId++; }
|
||||
};
|
||||
}
|
||||
});
|
||||
svgedit.recalculate.init({
|
||||
getSVGRoot: function () { return svg; },
|
||||
getStartTransform: function () { return ''; },
|
||||
setStartTransform: function () {}
|
||||
});
|
||||
}
|
||||
|
||||
function setUpRect () {
|
||||
setUp();
|
||||
elem = document.createElementNS(svgedit.NS.SVG, 'rect');
|
||||
elem.setAttribute('x', '200');
|
||||
elem.setAttribute('y', '150');
|
||||
elem.setAttribute('width', '250');
|
||||
elem.setAttribute('height', '120');
|
||||
svg.appendChild(elem);
|
||||
}
|
||||
|
||||
function setUpTextWithTspan () {
|
||||
setUp();
|
||||
elem = document.createElementNS(svgedit.NS.SVG, 'text');
|
||||
elem.setAttribute('x', '200');
|
||||
elem.setAttribute('y', '150');
|
||||
|
||||
var tspan = document.createElementNS(svgedit.NS.SVG, 'tspan');
|
||||
tspan.setAttribute('x', '200');
|
||||
tspan.setAttribute('y', '150');
|
||||
|
||||
var theText = document.createTextNode('Foo bar');
|
||||
tspan.appendChild(theText);
|
||||
elem.appendChild(tspan);
|
||||
svg.appendChild(elem);
|
||||
}
|
||||
|
||||
function tearDown () {
|
||||
while (svg.hasChildNodes()) {
|
||||
svg.removeChild(svg.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
test('Test recalculateDimensions() on rect with identity matrix', function () {
|
||||
expect(1);
|
||||
|
||||
setUpRect();
|
||||
elem.setAttribute('transform', 'matrix(1,0,0,1,0,0)');
|
||||
|
||||
svgedit.recalculate.recalculateDimensions(elem);
|
||||
|
||||
// Ensure that the identity matrix is swallowed and the element has no
|
||||
// transform on it.
|
||||
equal(false, elem.hasAttribute('transform'));
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test recalculateDimensions() on rect with simple translate', function () {
|
||||
expect(5);
|
||||
|
||||
setUpRect();
|
||||
elem.setAttribute('transform', 'translate(100,50)');
|
||||
|
||||
svgedit.recalculate.recalculateDimensions(elem);
|
||||
|
||||
equal(false, elem.hasAttribute('transform'));
|
||||
equal('300', elem.getAttribute('x'));
|
||||
equal('200', elem.getAttribute('y'));
|
||||
equal('250', elem.getAttribute('width'));
|
||||
equal('120', elem.getAttribute('height'));
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test recalculateDimensions() on text w/tspan with simple translate', function () {
|
||||
expect(5);
|
||||
|
||||
setUpTextWithTspan();
|
||||
elem.setAttribute('transform', 'translate(100,50)');
|
||||
|
||||
svgedit.recalculate.recalculateDimensions(elem);
|
||||
|
||||
// Ensure that the identity matrix is swallowed and the element has no
|
||||
// transform on it.
|
||||
equal(false, elem.hasAttribute('transform'));
|
||||
equal('300', elem.getAttribute('x'));
|
||||
equal('200', elem.getAttribute('y'));
|
||||
|
||||
var tspan = elem.firstElementChild;
|
||||
equal('300', tspan.getAttribute('x'));
|
||||
equal('200', tspan.getAttribute('y'));
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
// TODO: Since recalculateDimensions() and surrounding code is
|
||||
// probably the largest, most complicated and strange piece of
|
||||
// code in SVG-edit, we need to write a whole lot of unit tests
|
||||
// for it here.
|
||||
});
|
||||
@@ -11,32 +11,7 @@
|
||||
<script src="../editor/svgutils.js"></script>
|
||||
<script src="../editor/sanitize.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
|
||||
test('Test sanitizeSvg() strips ws from style attr', function() {
|
||||
expect(2);
|
||||
|
||||
var rect = document.createElementNS(svgedit.NS.SVG, 'rect');
|
||||
rect.setAttribute('style', 'stroke: blue ; stroke-width : 40;');
|
||||
// sanitizeSvg() requires the node to have a parent and a document.
|
||||
svg.appendChild(rect);
|
||||
svgedit.sanitize.sanitizeSvg(rect);
|
||||
|
||||
equals(rect.getAttribute('stroke'), 'blue');
|
||||
equals(rect.getAttribute('stroke-width'), '40');
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="sanitize_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for sanitize.js</h1>
|
||||
|
||||
26
test/sanitize_test.js
Normal file
26
test/sanitize_test.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit, equals */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
|
||||
test('Test sanitizeSvg() strips ws from style attr', function () {
|
||||
expect(2);
|
||||
|
||||
var rect = document.createElementNS(svgedit.NS.SVG, 'rect');
|
||||
rect.setAttribute('style', 'stroke: blue ; stroke-width : 40;');
|
||||
// sanitizeSvg() requires the node to have a parent and a document.
|
||||
svg.appendChild(rect);
|
||||
svgedit.sanitize.sanitizeSvg(rect);
|
||||
|
||||
equals(rect.getAttribute('stroke'), 'blue');
|
||||
equals(rect.getAttribute('stroke-width'), '40');
|
||||
});
|
||||
});
|
||||
@@ -12,137 +12,7 @@
|
||||
<script src="../editor/svgutils.js"></script>
|
||||
<script src="../editor/select.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
module('svgedit.select');
|
||||
|
||||
var sandbox = document.getElementById('sandbox');
|
||||
var svgroot;
|
||||
var svgcontent;
|
||||
var rect;
|
||||
var mockConfig = {
|
||||
dimensions: [640,480]
|
||||
};
|
||||
var mockFactory = {
|
||||
createSVGElement: function(jsonMap) {
|
||||
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||
for (var attr in jsonMap['attr']) {
|
||||
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||
}
|
||||
return elem;
|
||||
},
|
||||
svgRoot: function() { return svgroot; },
|
||||
svgContent: function() { return svgcontent; }
|
||||
};
|
||||
|
||||
function setUp() {
|
||||
svgroot = mockFactory.createSVGElement({
|
||||
'element': 'svg',
|
||||
'attr': {'id': 'svgroot'}
|
||||
});
|
||||
svgcontent = svgroot.appendChild(
|
||||
mockFactory.createSVGElement({
|
||||
'element': 'svg',
|
||||
'attr': {'id': 'svgcontent'}
|
||||
})
|
||||
);
|
||||
rect = svgcontent.appendChild(
|
||||
mockFactory.createSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {
|
||||
'id': 'rect',
|
||||
'x': '50',
|
||||
'y': '75',
|
||||
'width': '200',
|
||||
'height': '100'
|
||||
}
|
||||
})
|
||||
);
|
||||
sandbox.appendChild(svgroot);
|
||||
}
|
||||
|
||||
function setUpWithInit() {
|
||||
setUp();
|
||||
svgedit.select.init(mockConfig, mockFactory);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
while (sandbox.hasChildNodes()) {
|
||||
sandbox.removeChild(sandbox.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
test('Test svgedit.select package', function() {
|
||||
expect(10);
|
||||
|
||||
ok(svgedit.select);
|
||||
ok(svgedit.select.Selector);
|
||||
ok(svgedit.select.SelectorManager);
|
||||
ok(svgedit.select.init);
|
||||
ok(svgedit.select.getSelectorManager);
|
||||
equals(typeof svgedit.select, typeof {});
|
||||
equals(typeof svgedit.select.Selector, typeof function(){});
|
||||
equals(typeof svgedit.select.SelectorManager, typeof function(){});
|
||||
equals(typeof svgedit.select.init, typeof function(){});
|
||||
equals(typeof svgedit.select.getSelectorManager, typeof function(){});
|
||||
});
|
||||
|
||||
test('Test Selector DOM structure', function() {
|
||||
expect(24);
|
||||
|
||||
setUp();
|
||||
|
||||
ok(svgroot);
|
||||
ok(svgroot.hasChildNodes());
|
||||
|
||||
// Verify non-existence of Selector DOM nodes
|
||||
equals(svgroot.childNodes.length, 1);
|
||||
equals(svgroot.childNodes.item(0), svgcontent);
|
||||
ok(!svgroot.querySelector('#selectorParentGroup'));
|
||||
|
||||
svgedit.select.init(mockConfig, mockFactory);
|
||||
|
||||
equals(svgroot.childNodes.length, 3);
|
||||
|
||||
// Verify existence of canvas background.
|
||||
var cb = svgroot.childNodes.item(0);
|
||||
ok(cb);
|
||||
equals(cb.id, 'canvasBackground');
|
||||
|
||||
ok(svgroot.childNodes.item(1));
|
||||
equals(svgroot.childNodes.item(1), svgcontent);
|
||||
|
||||
// Verify existence of selectorParentGroup.
|
||||
var spg = svgroot.childNodes.item(2);
|
||||
ok(spg);
|
||||
equals(svgroot.querySelector('#selectorParentGroup'), spg);
|
||||
equals(spg.id, 'selectorParentGroup');
|
||||
equals(spg.tagName, 'g');
|
||||
|
||||
// Verify existence of all grip elements.
|
||||
ok(spg.querySelector('#selectorGrip_resize_nw'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_n'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_ne'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_e'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_se'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_s'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_sw'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_w'));
|
||||
ok(spg.querySelector('#selectorGrip_rotateconnector'));
|
||||
ok(spg.querySelector('#selectorGrip_rotate'));
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="select_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for select.js</h1>
|
||||
|
||||
132
test/select_test.js
Normal file
132
test/select_test.js
Normal file
@@ -0,0 +1,132 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit, equals */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
module('svgedit.select');
|
||||
|
||||
var sandbox = document.getElementById('sandbox');
|
||||
var svgroot;
|
||||
var svgcontent;
|
||||
var mockConfig = {
|
||||
dimensions: [640, 480]
|
||||
};
|
||||
var mockFactory = {
|
||||
createSVGElement: function (jsonMap) {
|
||||
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||
for (var attr in jsonMap['attr']) {
|
||||
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||
}
|
||||
return elem;
|
||||
},
|
||||
svgRoot: function () { return svgroot; },
|
||||
svgContent: function () { return svgcontent; }
|
||||
};
|
||||
|
||||
function setUp () {
|
||||
svgroot = mockFactory.createSVGElement({
|
||||
'element': 'svg',
|
||||
'attr': {'id': 'svgroot'}
|
||||
});
|
||||
svgcontent = svgroot.appendChild(
|
||||
mockFactory.createSVGElement({
|
||||
'element': 'svg',
|
||||
'attr': {'id': 'svgcontent'}
|
||||
})
|
||||
);
|
||||
/* var rect = */ svgcontent.appendChild(
|
||||
mockFactory.createSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {
|
||||
'id': 'rect',
|
||||
'x': '50',
|
||||
'y': '75',
|
||||
'width': '200',
|
||||
'height': '100'
|
||||
}
|
||||
})
|
||||
);
|
||||
sandbox.appendChild(svgroot);
|
||||
}
|
||||
|
||||
/*
|
||||
function setUpWithInit () {
|
||||
setUp();
|
||||
svgedit.select.init(mockConfig, mockFactory);
|
||||
}
|
||||
*/
|
||||
|
||||
function tearDown () {
|
||||
while (sandbox.hasChildNodes()) {
|
||||
sandbox.removeChild(sandbox.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
test('Test svgedit.select package', function () {
|
||||
expect(10);
|
||||
|
||||
ok(svgedit.select);
|
||||
ok(svgedit.select.Selector);
|
||||
ok(svgedit.select.SelectorManager);
|
||||
ok(svgedit.select.init);
|
||||
ok(svgedit.select.getSelectorManager);
|
||||
equals(typeof svgedit.select, typeof {});
|
||||
equals(typeof svgedit.select.Selector, typeof function () {});
|
||||
equals(typeof svgedit.select.SelectorManager, typeof function () {});
|
||||
equals(typeof svgedit.select.init, typeof function () {});
|
||||
equals(typeof svgedit.select.getSelectorManager, typeof function () {});
|
||||
});
|
||||
|
||||
test('Test Selector DOM structure', function () {
|
||||
expect(24);
|
||||
|
||||
setUp();
|
||||
|
||||
ok(svgroot);
|
||||
ok(svgroot.hasChildNodes());
|
||||
|
||||
// Verify non-existence of Selector DOM nodes
|
||||
equals(svgroot.childNodes.length, 1);
|
||||
equals(svgroot.childNodes.item(0), svgcontent);
|
||||
ok(!svgroot.querySelector('#selectorParentGroup'));
|
||||
|
||||
svgedit.select.init(mockConfig, mockFactory);
|
||||
|
||||
equals(svgroot.childNodes.length, 3);
|
||||
|
||||
// Verify existence of canvas background.
|
||||
var cb = svgroot.childNodes.item(0);
|
||||
ok(cb);
|
||||
equals(cb.id, 'canvasBackground');
|
||||
|
||||
ok(svgroot.childNodes.item(1));
|
||||
equals(svgroot.childNodes.item(1), svgcontent);
|
||||
|
||||
// Verify existence of selectorParentGroup.
|
||||
var spg = svgroot.childNodes.item(2);
|
||||
ok(spg);
|
||||
equals(svgroot.querySelector('#selectorParentGroup'), spg);
|
||||
equals(spg.id, 'selectorParentGroup');
|
||||
equals(spg.tagName, 'g');
|
||||
|
||||
// Verify existence of all grip elements.
|
||||
ok(spg.querySelector('#selectorGrip_resize_nw'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_n'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_ne'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_e'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_se'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_s'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_sw'));
|
||||
ok(spg.querySelector('#selectorGrip_resize_w'));
|
||||
ok(spg.querySelector('#selectorGrip_rotateconnector'));
|
||||
ok(spg.querySelector('#selectorGrip_rotate'));
|
||||
|
||||
tearDown();
|
||||
});
|
||||
});
|
||||
@@ -13,398 +13,7 @@
|
||||
</script>
|
||||
<script src="../editor/svgtransformlist.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
var NS = svgedit.NS;
|
||||
var svgroot = document.getElementById('svgroot');
|
||||
var svgcontent, rect, circle;
|
||||
|
||||
var NEAR_ZERO = 5e-6; // 0.000005, Firefox fails at higher levels of precision.
|
||||
function almostEquals(a, b, msg) {
|
||||
msg = msg || (a + ' did not equal ' + b);
|
||||
ok(Math.abs(a - b) < NEAR_ZERO, msg);
|
||||
}
|
||||
|
||||
function checkOutOfBoundsException(obj, fn, arg1) {
|
||||
var caughtException = false;
|
||||
try {
|
||||
obj[fn](arg1);
|
||||
}
|
||||
catch(e) {
|
||||
if (e.code == 1) {
|
||||
caughtException = true;
|
||||
}
|
||||
}
|
||||
ok(caughtException, 'Caugh an INDEX_SIZE_ERR exception');
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
svgcontent = svgroot.appendChild(document.createElementNS(NS.SVG, 'svg'));
|
||||
rect = svgcontent.appendChild(document.createElementNS(NS.SVG, 'rect'));
|
||||
rect.id = 'r';
|
||||
circle = svgcontent.appendChild(document.createElementNS(NS.SVG, 'circle'));
|
||||
circle.id = 'c';
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
svgedit.transformlist.resetListMap();
|
||||
while (svgroot.hasChildNodes()) {
|
||||
svgroot.removeChild(svgroot.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
module('svgedit.svgtransformlist');
|
||||
|
||||
test('Test svgedit.transformlist package', function() {
|
||||
expect(2);
|
||||
|
||||
ok(svgedit.transformlist);
|
||||
ok(svgedit.transformlist.getTransformList);
|
||||
});
|
||||
|
||||
test('Test svgedit.transformlist.getTransformList() function', function() {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
var cxform = svgedit.transformlist.getTransformList(circle);
|
||||
|
||||
ok(rxform);
|
||||
ok(cxform);
|
||||
equals(typeof rxform, typeof {});
|
||||
equals(typeof cxform, typeof {});
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.numberOfItems property', function() {
|
||||
expect(2);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
|
||||
equals(typeof rxform.numberOfItems, typeof 0);
|
||||
equals(rxform.numberOfItems, 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.initialize()', function() {
|
||||
expect(6);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
var cxform = svgedit.transformlist.getTransformList(circle);
|
||||
|
||||
var t = svgcontent.createSVGTransform();
|
||||
ok(t);
|
||||
ok(rxform.initialize);
|
||||
equals(typeof rxform.initialize, typeof function(){});
|
||||
rxform.initialize(t);
|
||||
equals(rxform.numberOfItems, 1);
|
||||
equals(cxform.numberOfItems, 0);
|
||||
|
||||
// If a transform was already in a transform list, this should
|
||||
// remove it from its old list and add it to this list.
|
||||
cxform.initialize(t);
|
||||
// This also fails in Firefox native.
|
||||
// equals(rxform.numberOfItems, 0, 'Did not remove transform from list before initializing another transformlist');
|
||||
equals(cxform.numberOfItems, 1);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.appendItem() and getItem()', function() {
|
||||
expect(12);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
var cxform = svgedit.transformlist.getTransformList(circle);
|
||||
|
||||
var t1 = svgcontent.createSVGTransform(),
|
||||
t2 = svgcontent.createSVGTransform(),
|
||||
t3 = svgcontent.createSVGTransform();
|
||||
|
||||
ok(rxform.appendItem);
|
||||
ok(rxform.getItem);
|
||||
equals(typeof rxform.appendItem, typeof function(){});
|
||||
equals(typeof rxform.getItem, typeof function(){});
|
||||
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
rxform.appendItem(t3);
|
||||
|
||||
equals(rxform.numberOfItems, 3);
|
||||
var rxf = rxform.getItem(0);
|
||||
equals(rxf, t1);
|
||||
equals(rxform.getItem(1), t2);
|
||||
equals(rxform.getItem(2), t3);
|
||||
|
||||
checkOutOfBoundsException(rxform, 'getItem', -1);
|
||||
checkOutOfBoundsException(rxform, 'getItem', 3);
|
||||
cxform.appendItem(t1);
|
||||
// These also fail in Firefox native.
|
||||
// equals(rxform.numberOfItems, 2, 'Did not remove a transform from a list before appending it to a new transformlist');
|
||||
// equals(rxform.getItem(0), t2, 'Found the wrong transform in a transformlist');
|
||||
// equals(rxform.getItem(1), t3, 'Found the wrong transform in a transformlist');
|
||||
|
||||
equals(cxform.numberOfItems, 1);
|
||||
equals(cxform.getItem(0), t1);
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.removeItem()', function() {
|
||||
expect(7);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
|
||||
var t1 = svgcontent.createSVGTransform(),
|
||||
t2 = svgcontent.createSVGTransform();
|
||||
ok(rxform.removeItem);
|
||||
equals(typeof rxform.removeItem, typeof function(){});
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
|
||||
var removedTransform = rxform.removeItem(0);
|
||||
equals(rxform.numberOfItems, 1);
|
||||
equals(removedTransform, t1);
|
||||
equals(rxform.getItem(0), t2);
|
||||
|
||||
checkOutOfBoundsException(rxform, 'removeItem', -1);
|
||||
checkOutOfBoundsException(rxform, 'removeItem', 1);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.replaceItem()', function() {
|
||||
expect(8);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
var cxform = svgedit.transformlist.getTransformList(circle);
|
||||
|
||||
ok(rxform.replaceItem);
|
||||
equals(typeof rxform.replaceItem, typeof function(){});
|
||||
|
||||
var t1 = svgcontent.createSVGTransform(),
|
||||
t2 = svgcontent.createSVGTransform(),
|
||||
t3 = svgcontent.createSVGTransform();
|
||||
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
cxform.appendItem(t3);
|
||||
|
||||
var newItem = rxform.replaceItem(t3, 0);
|
||||
equals(rxform.numberOfItems, 2);
|
||||
equals(newItem, t3);
|
||||
equals(rxform.getItem(0), t3);
|
||||
equals(rxform.getItem(1), t2);
|
||||
// Fails in Firefox native
|
||||
// equals(cxform.numberOfItems, 0);
|
||||
|
||||
// test replaceItem within a list
|
||||
rxform.appendItem(t1);
|
||||
rxform.replaceItem(t1, 0);
|
||||
// Fails in Firefox native
|
||||
// equals(rxform.numberOfItems, 2);
|
||||
equals(rxform.getItem(0), t1);
|
||||
equals(rxform.getItem(1), t2);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.insertItemBefore()', function() {
|
||||
expect(10);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
var cxform = svgedit.transformlist.getTransformList(circle);
|
||||
|
||||
ok(rxform.insertItemBefore);
|
||||
equals(typeof rxform.insertItemBefore, typeof function(){});
|
||||
|
||||
var t1 = svgcontent.createSVGTransform(),
|
||||
t2 = svgcontent.createSVGTransform(),
|
||||
t3 = svgcontent.createSVGTransform();
|
||||
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
cxform.appendItem(t3);
|
||||
|
||||
var newItem = rxform.insertItemBefore(t3, 0);
|
||||
equals(rxform.numberOfItems, 3);
|
||||
equals(newItem, t3);
|
||||
equals(rxform.getItem(0), t3);
|
||||
equals(rxform.getItem(1), t1);
|
||||
equals(rxform.getItem(2), t2);
|
||||
// Fails in Firefox native
|
||||
// equals(cxform.numberOfItems, 0);
|
||||
|
||||
rxform.insertItemBefore(t2, 1);
|
||||
// Fails in Firefox native (they make copies of the transforms)
|
||||
// equals(rxform.numberOfItems, 3);
|
||||
equals(rxform.getItem(0), t3);
|
||||
equals(rxform.getItem(1), t2);
|
||||
equals(rxform.getItem(2), t1);
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for translate(200,100)', function() {
|
||||
expect(8);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'translate(200,100)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var translate = rxform.getItem(0);
|
||||
equals(translate.type, 2);
|
||||
|
||||
var m = translate.matrix;
|
||||
equals(m.a, 1);
|
||||
equals(m.b, 0);
|
||||
equals(m.c, 0);
|
||||
equals(m.d, 1);
|
||||
equals(m.e, 200);
|
||||
equals(m.f, 100);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for scale(4)', function() {
|
||||
expect(8);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'scale(4)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var scale = rxform.getItem(0);
|
||||
equals(3, scale.type);
|
||||
|
||||
var m = scale.matrix;
|
||||
equals(m.a, 4);
|
||||
equals(m.b, 0);
|
||||
equals(m.c, 0);
|
||||
equals(m.d, 4);
|
||||
equals(m.e, 0);
|
||||
equals(m.f, 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for scale(4,3)', function() {
|
||||
expect(8);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'scale(4,3)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var scale = rxform.getItem(0);
|
||||
equals(3, scale.type);
|
||||
|
||||
var m = scale.matrix;
|
||||
equals(m.a, 4);
|
||||
equals(m.b, 0);
|
||||
equals(m.c, 0);
|
||||
equals(m.d, 3);
|
||||
equals(m.e, 0);
|
||||
equals(m.f, 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for rotate(45)', function() {
|
||||
expect(9);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'rotate(45)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var rotate = rxform.getItem(0);
|
||||
equals(4, rotate.type);
|
||||
equals(45, rotate.angle);
|
||||
|
||||
var m = rotate.matrix;
|
||||
almostEquals(m.a, 1/Math.sqrt(2));
|
||||
almostEquals(m.b, 1/Math.sqrt(2));
|
||||
almostEquals(m.c, -1/Math.sqrt(2));
|
||||
almostEquals(m.d, 1/Math.sqrt(2));
|
||||
equals(m.e, 0);
|
||||
equals(m.f, 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for rotate(45, 100, 200)', function() {
|
||||
expect(9);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'rotate(45, 100, 200)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var rotate = rxform.getItem(0);
|
||||
equals(4, rotate.type);
|
||||
equals(45, rotate.angle);
|
||||
|
||||
var m = rotate.matrix;
|
||||
almostEquals(m.a, 1/Math.sqrt(2));
|
||||
almostEquals(m.b, 1/Math.sqrt(2));
|
||||
almostEquals(m.c, -1/Math.sqrt(2));
|
||||
almostEquals(m.d, 1/Math.sqrt(2));
|
||||
|
||||
var r = svgcontent.createSVGMatrix();
|
||||
r.a = 1/Math.sqrt(2); r.b = 1/Math.sqrt(2);
|
||||
r.c = -1/Math.sqrt(2); r.d = 1/Math.sqrt(2);
|
||||
|
||||
var t = svgcontent.createSVGMatrix();
|
||||
t.e = -100; t.f = -200;
|
||||
|
||||
var t_ = svgcontent.createSVGMatrix();
|
||||
t_.e = 100; t_.f = 200;
|
||||
|
||||
var result = t_.multiply(r).multiply(t);
|
||||
|
||||
almostEquals(m.e, result.e);
|
||||
almostEquals(m.f, result.f);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for matrix(1, 2, 3, 4, 5, 6)', function() {
|
||||
expect(8);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'matrix(1,2,3,4,5,6)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var mt = rxform.getItem(0);
|
||||
equals(1, mt.type);
|
||||
|
||||
var m = mt.matrix;
|
||||
equals(m.a, 1);
|
||||
equals(m.b, 2);
|
||||
equals(m.c, 3);
|
||||
equals(m.d, 4);
|
||||
equals(m.e, 5);
|
||||
equals(m.f, 6);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="svgtransformlist_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for svgtransformlist.js</h1>
|
||||
|
||||
391
test/svgtransformlist_test.js
Normal file
391
test/svgtransformlist_test.js
Normal file
@@ -0,0 +1,391 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit, equals */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
var NS = svgedit.NS;
|
||||
var svgroot = document.getElementById('svgroot');
|
||||
var svgcontent, rect, circle;
|
||||
|
||||
var NEAR_ZERO = 5e-6; // 0.000005, Firefox fails at higher levels of precision.
|
||||
function almostEquals (a, b, msg) {
|
||||
msg = msg || (a + ' did not equal ' + b);
|
||||
ok(Math.abs(a - b) < NEAR_ZERO, msg);
|
||||
}
|
||||
|
||||
function checkOutOfBoundsException (obj, fn, arg1) {
|
||||
var caughtException = false;
|
||||
try {
|
||||
obj[fn](arg1);
|
||||
} catch (e) {
|
||||
if (e.code === 1) {
|
||||
caughtException = true;
|
||||
}
|
||||
}
|
||||
ok(caughtException, 'Caugh an INDEX_SIZE_ERR exception');
|
||||
}
|
||||
|
||||
function setUp () {
|
||||
svgcontent = svgroot.appendChild(document.createElementNS(NS.SVG, 'svg'));
|
||||
rect = svgcontent.appendChild(document.createElementNS(NS.SVG, 'rect'));
|
||||
rect.id = 'r';
|
||||
circle = svgcontent.appendChild(document.createElementNS(NS.SVG, 'circle'));
|
||||
circle.id = 'c';
|
||||
}
|
||||
|
||||
function tearDown () {
|
||||
svgedit.transformlist.resetListMap();
|
||||
while (svgroot.hasChildNodes()) {
|
||||
svgroot.removeChild(svgroot.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
module('svgedit.svgtransformlist');
|
||||
|
||||
test('Test svgedit.transformlist package', function () {
|
||||
expect(2);
|
||||
|
||||
ok(svgedit.transformlist);
|
||||
ok(svgedit.transformlist.getTransformList);
|
||||
});
|
||||
|
||||
test('Test svgedit.transformlist.getTransformList() function', function () {
|
||||
expect(4);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
var cxform = svgedit.transformlist.getTransformList(circle);
|
||||
|
||||
ok(rxform);
|
||||
ok(cxform);
|
||||
equals(typeof rxform, typeof {});
|
||||
equals(typeof cxform, typeof {});
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.numberOfItems property', function () {
|
||||
expect(2);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
|
||||
equals(typeof rxform.numberOfItems, typeof 0);
|
||||
equals(rxform.numberOfItems, 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.initialize()', function () {
|
||||
expect(6);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
var cxform = svgedit.transformlist.getTransformList(circle);
|
||||
|
||||
var t = svgcontent.createSVGTransform();
|
||||
ok(t);
|
||||
ok(rxform.initialize);
|
||||
equals(typeof rxform.initialize, typeof function () {});
|
||||
rxform.initialize(t);
|
||||
equals(rxform.numberOfItems, 1);
|
||||
equals(cxform.numberOfItems, 0);
|
||||
|
||||
// If a transform was already in a transform list, this should
|
||||
// remove it from its old list and add it to this list.
|
||||
cxform.initialize(t);
|
||||
// This also fails in Firefox native.
|
||||
// equals(rxform.numberOfItems, 0, 'Did not remove transform from list before initializing another transformlist');
|
||||
equals(cxform.numberOfItems, 1);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.appendItem() and getItem()', function () {
|
||||
expect(12);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
var cxform = svgedit.transformlist.getTransformList(circle);
|
||||
|
||||
var t1 = svgcontent.createSVGTransform(),
|
||||
t2 = svgcontent.createSVGTransform(),
|
||||
t3 = svgcontent.createSVGTransform();
|
||||
|
||||
ok(rxform.appendItem);
|
||||
ok(rxform.getItem);
|
||||
equals(typeof rxform.appendItem, typeof function () {});
|
||||
equals(typeof rxform.getItem, typeof function () {});
|
||||
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
rxform.appendItem(t3);
|
||||
|
||||
equals(rxform.numberOfItems, 3);
|
||||
var rxf = rxform.getItem(0);
|
||||
equals(rxf, t1);
|
||||
equals(rxform.getItem(1), t2);
|
||||
equals(rxform.getItem(2), t3);
|
||||
|
||||
checkOutOfBoundsException(rxform, 'getItem', -1);
|
||||
checkOutOfBoundsException(rxform, 'getItem', 3);
|
||||
cxform.appendItem(t1);
|
||||
// These also fail in Firefox native.
|
||||
// equals(rxform.numberOfItems, 2, 'Did not remove a transform from a list before appending it to a new transformlist');
|
||||
// equals(rxform.getItem(0), t2, 'Found the wrong transform in a transformlist');
|
||||
// equals(rxform.getItem(1), t3, 'Found the wrong transform in a transformlist');
|
||||
|
||||
equals(cxform.numberOfItems, 1);
|
||||
equals(cxform.getItem(0), t1);
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.removeItem()', function () {
|
||||
expect(7);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
|
||||
var t1 = svgcontent.createSVGTransform(),
|
||||
t2 = svgcontent.createSVGTransform();
|
||||
ok(rxform.removeItem);
|
||||
equals(typeof rxform.removeItem, typeof function () {});
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
|
||||
var removedTransform = rxform.removeItem(0);
|
||||
equals(rxform.numberOfItems, 1);
|
||||
equals(removedTransform, t1);
|
||||
equals(rxform.getItem(0), t2);
|
||||
|
||||
checkOutOfBoundsException(rxform, 'removeItem', -1);
|
||||
checkOutOfBoundsException(rxform, 'removeItem', 1);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.replaceItem()', function () {
|
||||
expect(8);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
var cxform = svgedit.transformlist.getTransformList(circle);
|
||||
|
||||
ok(rxform.replaceItem);
|
||||
equals(typeof rxform.replaceItem, typeof function () {});
|
||||
|
||||
var t1 = svgcontent.createSVGTransform(),
|
||||
t2 = svgcontent.createSVGTransform(),
|
||||
t3 = svgcontent.createSVGTransform();
|
||||
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
cxform.appendItem(t3);
|
||||
|
||||
var newItem = rxform.replaceItem(t3, 0);
|
||||
equals(rxform.numberOfItems, 2);
|
||||
equals(newItem, t3);
|
||||
equals(rxform.getItem(0), t3);
|
||||
equals(rxform.getItem(1), t2);
|
||||
// Fails in Firefox native
|
||||
// equals(cxform.numberOfItems, 0);
|
||||
|
||||
// test replaceItem within a list
|
||||
rxform.appendItem(t1);
|
||||
rxform.replaceItem(t1, 0);
|
||||
// Fails in Firefox native
|
||||
// equals(rxform.numberOfItems, 2);
|
||||
equals(rxform.getItem(0), t1);
|
||||
equals(rxform.getItem(1), t2);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.insertItemBefore()', function () {
|
||||
expect(10);
|
||||
setUp();
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
var cxform = svgedit.transformlist.getTransformList(circle);
|
||||
|
||||
ok(rxform.insertItemBefore);
|
||||
equals(typeof rxform.insertItemBefore, typeof function () {});
|
||||
|
||||
var t1 = svgcontent.createSVGTransform(),
|
||||
t2 = svgcontent.createSVGTransform(),
|
||||
t3 = svgcontent.createSVGTransform();
|
||||
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
cxform.appendItem(t3);
|
||||
|
||||
var newItem = rxform.insertItemBefore(t3, 0);
|
||||
equals(rxform.numberOfItems, 3);
|
||||
equals(newItem, t3);
|
||||
equals(rxform.getItem(0), t3);
|
||||
equals(rxform.getItem(1), t1);
|
||||
equals(rxform.getItem(2), t2);
|
||||
// Fails in Firefox native
|
||||
// equals(cxform.numberOfItems, 0);
|
||||
|
||||
rxform.insertItemBefore(t2, 1);
|
||||
// Fails in Firefox native (they make copies of the transforms)
|
||||
// equals(rxform.numberOfItems, 3);
|
||||
equals(rxform.getItem(0), t3);
|
||||
equals(rxform.getItem(1), t2);
|
||||
equals(rxform.getItem(2), t1);
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for translate(200,100)', function () {
|
||||
expect(8);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'translate(200,100)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var translate = rxform.getItem(0);
|
||||
equals(translate.type, 2);
|
||||
|
||||
var m = translate.matrix;
|
||||
equals(m.a, 1);
|
||||
equals(m.b, 0);
|
||||
equals(m.c, 0);
|
||||
equals(m.d, 1);
|
||||
equals(m.e, 200);
|
||||
equals(m.f, 100);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for scale(4)', function () {
|
||||
expect(8);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'scale(4)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var scale = rxform.getItem(0);
|
||||
equals(3, scale.type);
|
||||
|
||||
var m = scale.matrix;
|
||||
equals(m.a, 4);
|
||||
equals(m.b, 0);
|
||||
equals(m.c, 0);
|
||||
equals(m.d, 4);
|
||||
equals(m.e, 0);
|
||||
equals(m.f, 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for scale(4,3)', function () {
|
||||
expect(8);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'scale(4,3)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var scale = rxform.getItem(0);
|
||||
equals(3, scale.type);
|
||||
|
||||
var m = scale.matrix;
|
||||
equals(m.a, 4);
|
||||
equals(m.b, 0);
|
||||
equals(m.c, 0);
|
||||
equals(m.d, 3);
|
||||
equals(m.e, 0);
|
||||
equals(m.f, 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for rotate(45)', function () {
|
||||
expect(9);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'rotate(45)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var rotate = rxform.getItem(0);
|
||||
equals(4, rotate.type);
|
||||
equals(45, rotate.angle);
|
||||
|
||||
var m = rotate.matrix;
|
||||
almostEquals(m.a, 1 / Math.sqrt(2));
|
||||
almostEquals(m.b, 1 / Math.sqrt(2));
|
||||
almostEquals(m.c, -1 / Math.sqrt(2));
|
||||
almostEquals(m.d, 1 / Math.sqrt(2));
|
||||
equals(m.e, 0);
|
||||
equals(m.f, 0);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for rotate(45, 100, 200)', function () {
|
||||
expect(9);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'rotate(45, 100, 200)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var rotate = rxform.getItem(0);
|
||||
equals(4, rotate.type);
|
||||
equals(45, rotate.angle);
|
||||
|
||||
var m = rotate.matrix;
|
||||
almostEquals(m.a, 1 / Math.sqrt(2));
|
||||
almostEquals(m.b, 1 / Math.sqrt(2));
|
||||
almostEquals(m.c, -1 / Math.sqrt(2));
|
||||
almostEquals(m.d, 1 / Math.sqrt(2));
|
||||
|
||||
var r = svgcontent.createSVGMatrix();
|
||||
r.a = 1 / Math.sqrt(2); r.b = 1 / Math.sqrt(2);
|
||||
r.c = -1 / Math.sqrt(2); r.d = 1 / Math.sqrt(2);
|
||||
|
||||
var t = svgcontent.createSVGMatrix();
|
||||
t.e = -100; t.f = -200;
|
||||
|
||||
var t_ = svgcontent.createSVGMatrix();
|
||||
t_.e = 100; t_.f = 200;
|
||||
|
||||
var result = t_.multiply(r).multiply(t);
|
||||
|
||||
almostEquals(m.e, result.e);
|
||||
almostEquals(m.f, result.f);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
|
||||
test('Test SVGTransformList.init() for matrix(1, 2, 3, 4, 5, 6)', function () {
|
||||
expect(8);
|
||||
setUp();
|
||||
rect.setAttribute('transform', 'matrix(1,2,3,4,5,6)');
|
||||
|
||||
var rxform = svgedit.transformlist.getTransformList(rect);
|
||||
equals(1, rxform.numberOfItems);
|
||||
|
||||
var mt = rxform.getItem(0);
|
||||
equals(1, mt.type);
|
||||
|
||||
var m = mt.matrix;
|
||||
equals(m.a, 1);
|
||||
equals(m.b, 2);
|
||||
equals(m.c, 3);
|
||||
equals(m.d, 4);
|
||||
equals(m.e, 5);
|
||||
equals(m.f, 6);
|
||||
|
||||
tearDown();
|
||||
});
|
||||
});
|
||||
@@ -16,504 +16,7 @@
|
||||
<script src="../editor/svgutils.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script src="qunit/qunit-assert-close.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
function mockCreateSVGElement(jsonMap) {
|
||||
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||
for (var attr in jsonMap['attr']) {
|
||||
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
var mockAddSvgElementFromJsonCallCount = 0;
|
||||
function mockAddSvgElementFromJson( json) {
|
||||
var elem = mockCreateSVGElement( json)
|
||||
svgroot.appendChild( elem)
|
||||
mockAddSvgElementFromJsonCallCount++;
|
||||
return elem
|
||||
}
|
||||
var mockPathActions = {
|
||||
resetOrientation: function(path) {
|
||||
if (path == null || path.nodeName != 'path') {return false;}
|
||||
var tlist = svgedit.transformlist.getTransformList(path);
|
||||
var m = svgedit.math.transformListToTransform(tlist).matrix;
|
||||
tlist.clear();
|
||||
path.removeAttribute('transform');
|
||||
var segList = path.pathSegList;
|
||||
|
||||
var len = segList.numberOfItems;
|
||||
var i, last_x, last_y;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
var seg = segList.getItem(i);
|
||||
var type = seg.pathSegType;
|
||||
if (type == 1) {continue;}
|
||||
var pts = [];
|
||||
$.each(['',1,2], function(j, n) {
|
||||
var x = seg['x'+n], y = seg['y'+n];
|
||||
if (x !== undefined && y !== undefined) {
|
||||
var pt = svgedit.math.transformPoint(x, y, m);
|
||||
pts.splice(pts.length, 0, pt.x, pt.y);
|
||||
}
|
||||
});
|
||||
svgedit.path.replacePathSeg(type, i, pts, path);
|
||||
}
|
||||
|
||||
//svgedit.utilities.reorientGrads(path, m);
|
||||
}
|
||||
}
|
||||
|
||||
var EPSILON = 0.001
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
var sandbox = document.getElementById('sandbox');
|
||||
var svgroot = mockCreateSVGElement({
|
||||
'element': 'svg',
|
||||
'attr': {'id': 'svgroot'}
|
||||
});
|
||||
sandbox.appendChild(svgroot);
|
||||
|
||||
|
||||
module('svgedit.utilities_bbox', {
|
||||
setup: function() {
|
||||
// We're reusing ID's so we need to do this for transforms.
|
||||
svgedit.transformlist.resetListMap();
|
||||
svgedit.path.init(null);
|
||||
mockAddSvgElementFromJsonCallCount = 0;
|
||||
},
|
||||
teardown: function() {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
test('Test svgedit.utilities package', function() {
|
||||
ok(svgedit.utilities);
|
||||
ok(svgedit.utilities.getBBoxWithTransform);
|
||||
ok(svgedit.utilities.getStrokedBBox);
|
||||
ok(svgedit.utilities.getRotationAngleFromTransformList);
|
||||
ok(svgedit.utilities.getRotationAngle);
|
||||
});
|
||||
|
||||
|
||||
test("Test getBBoxWithTransform and no transform", function() {
|
||||
var getBBoxWithTransform = svgedit.utilities.getBBoxWithTransform
|
||||
|
||||
var bbox;
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M0,1 L2,3'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getBBoxWithTransform(elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual(bbox, {"x": 0, "y": 1, "width": 2, "height": 2 });
|
||||
equal( mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
equal( mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': { 'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 5});
|
||||
equal( mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
equal( mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild( g);
|
||||
|
||||
});
|
||||
|
||||
|
||||
test("Test getBBoxWithTransform and a rotation transform", function() {
|
||||
var getBBoxWithTransform = svgedit.utilities.getBBoxWithTransform
|
||||
|
||||
var bbox;
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M10,10 L20,20', 'transform': 'rotate(45 10,10)'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getBBoxWithTransform(elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
close( bbox.x, 10, EPSILON);
|
||||
close( bbox.y, 10, EPSILON);
|
||||
close( bbox.width, 0, EPSILON);
|
||||
close( bbox.height, Math.sqrt(100 + 100), EPSILON);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '10', 'y': '10', 'width': '10', 'height': '20', 'transform': 'rotate(90 15,20)'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
close( bbox.x, 5, EPSILON);
|
||||
close( bbox.y, 15, EPSILON);
|
||||
close( bbox.width, 20, EPSILON);
|
||||
close( bbox.height, 10, EPSILON);
|
||||
equal( mockAddSvgElementFromJsonCallCount, 1);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
var rect = {x: 10, y: 10, width: 10, height: 20};
|
||||
var angle = 45;
|
||||
var origin = { x: 15, y: 20};
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect2', 'x': rect.x, 'y': rect.y, 'width': rect.width, 'height': rect.height, 'transform': 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
mockAddSvgElementFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
var r2 = rotateRect( rect, angle, origin);
|
||||
close( bbox.x, r2.x, EPSILON, 'rect2 x is ' + r2.x);
|
||||
close( bbox.y, r2.y, EPSILON, 'rect2 y is ' + r2.y);
|
||||
close( bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
close( bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
equal( mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
|
||||
// Same as previous but wrapped with g and the transform is with the g.
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect3', 'x': rect.x, 'y': rect.y, 'width': rect.width, 'height': rect.height}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {'transform': 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')'}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
mockAddSvgElementFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform( g, mockAddSvgElementFromJson, mockPathActions);
|
||||
close( bbox.x, r2.x, EPSILON, 'rect2 x is ' + r2.x);
|
||||
close( bbox.y, r2.y, EPSILON, 'rect2 y is ' + r2.y);
|
||||
close( bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
close( bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
equal( mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild( g);
|
||||
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'ellipse',
|
||||
'attr': { 'id': 'ellipse1', 'cx': '100', 'cy': '100', 'rx': '50', 'ry': '50', 'transform': 'rotate(45 100,100)'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
mockAddSvgElementFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
// TODO: the BBox algorithm is using the bezier control points to calculate the bounding box. Should be 50, 50, 100, 100.
|
||||
ok( bbox.x > 45 && bbox.x <= 50);
|
||||
ok( bbox.y > 45 && bbox.y <= 50);
|
||||
ok( bbox.width >= 100 && bbox.width < 110);
|
||||
ok( bbox.height >= 100 && bbox.height < 110);
|
||||
equal( mockAddSvgElementFromJsonCallCount, 1);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
test("Test getBBoxWithTransform with rotation and matrix transforms", function() {
|
||||
var getBBoxWithTransform = svgedit.utilities.getBBoxWithTransform
|
||||
|
||||
var bbox;
|
||||
var tx = 10; // tx right
|
||||
var ty = 10; // tx down
|
||||
var txInRotatedSpace = Math.sqrt(tx*tx + ty*ty); // translate in rotated 45 space.
|
||||
var tyInRotatedSpace = 0;
|
||||
var matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M10,10 L20,20', 'transform': 'rotate(45 10,10) ' + matrix}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getBBoxWithTransform(elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
close( bbox.x, 10 + tx, EPSILON);
|
||||
close( bbox.y, 10 + ty, EPSILON);
|
||||
close( bbox.width, 0, EPSILON)
|
||||
close( bbox.height, Math.sqrt(100 + 100), EPSILON)
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
txInRotatedSpace = tx; // translate in rotated 90 space.
|
||||
tyInRotatedSpace = -ty;
|
||||
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '10', 'y': '10', 'width': '10', 'height': '20', 'transform': 'rotate(90 15,20) ' + matrix}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
close( bbox.x, 5 + tx, EPSILON);
|
||||
close( bbox.y, 15 + ty, EPSILON);
|
||||
close( bbox.width, 20, EPSILON);
|
||||
close( bbox.height, 10, EPSILON);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
var rect = {x: 10, y: 10, width: 10, height: 20}
|
||||
var angle = 45
|
||||
var origin = { x: 15, y: 20}
|
||||
tx = 10; // tx right
|
||||
ty = 10; // tx down
|
||||
txInRotatedSpace = Math.sqrt(tx*tx + ty*ty); // translate in rotated 45 space.
|
||||
tyInRotatedSpace = 0;
|
||||
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect2', 'x': rect.x, 'y': rect.y, 'width': rect.width, 'height': rect.height, 'transform': 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
var r2 = rotateRect( rect, angle, origin)
|
||||
close( bbox.x, r2.x + tx, EPSILON, 'rect2 x is ' + r2.x);
|
||||
close( bbox.y, r2.y + ty, EPSILON, 'rect2 y is ' + r2.y);
|
||||
close( bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
close( bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
|
||||
// Same as previous but wrapped with g and the transform is with the g.
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect3', 'x': rect.x, 'y': rect.y, 'width': rect.width, 'height': rect.height}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {'transform': 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
bbox = getBBoxWithTransform( g, mockAddSvgElementFromJson, mockPathActions)
|
||||
close( bbox.x, r2.x + tx, EPSILON, 'rect2 x is ' + r2.x);
|
||||
close( bbox.y, r2.y + ty, EPSILON, 'rect2 y is ' + r2.y);
|
||||
close( bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
close( bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
svgroot.removeChild( g);
|
||||
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'ellipse',
|
||||
'attr': { 'id': 'ellipse1', 'cx': '100', 'cy': '100', 'rx': '50', 'ry': '50', 'transform': 'rotate(45 100,100) ' + matrix}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
// TODO: the BBox algorithm is using the bezier control points to calculate the bounding box. Should be 50, 50, 100, 100.
|
||||
ok( bbox.x > 45 + tx && bbox.x <= 50 + tx);
|
||||
ok( bbox.y > 45 + ty && bbox.y <= 50 + ty);
|
||||
ok( bbox.width >= 100 && bbox.width < 110);
|
||||
ok( bbox.height >= 100 && bbox.height < 110);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
});
|
||||
|
||||
|
||||
test("Test getStrokedBBox with stroke-width 10", function() {
|
||||
var getStrokedBBox = svgedit.utilities.getStrokedBBox
|
||||
|
||||
var bbox;
|
||||
var strokeWidth = 10
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M0,1 L2,3', 'stroke-width': strokeWidth}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual(bbox, {"x": 0 - strokeWidth / 2, "y": 1 - strokeWidth / 2, "width": 2 + strokeWidth, "height": 2 + strokeWidth});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10', 'stroke-width': strokeWidth}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0 - strokeWidth / 2, "y": 1 - strokeWidth / 2, "width": 5 + strokeWidth, "height": 10 + strokeWidth});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': { 'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6', 'stroke-width': strokeWidth}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0 - strokeWidth / 2, "y": 1 - strokeWidth / 2, "width": 5 + strokeWidth, "height": 5 + strokeWidth});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10', 'stroke-width': strokeWidth}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0 - strokeWidth / 2, "y": 1 - strokeWidth / 2, "width": 5 + strokeWidth, "height": 10 + strokeWidth});
|
||||
svgroot.removeChild( g);
|
||||
|
||||
});
|
||||
|
||||
|
||||
test("Test getStrokedBBox with stroke-width 'none'", function() {
|
||||
var getStrokedBBox = svgedit.utilities.getStrokedBBox
|
||||
|
||||
var bbox;
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M0,1 L2,3', 'stroke-width': 'none'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual(bbox, {"x": 0, "y": 1, "width": 2, "height": 2});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10', 'stroke-width': 'none'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': { 'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6', 'stroke-width': 'none'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 5});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10', 'stroke-width': 'none'}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
svgroot.removeChild( g);
|
||||
|
||||
});
|
||||
|
||||
|
||||
test("Test getStrokedBBox with no stroke-width attribute", function() {
|
||||
var getStrokedBBox = svgedit.utilities.getStrokedBBox
|
||||
|
||||
var bbox;
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M0,1 L2,3'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual(bbox, {"x": 0, "y": 1, "width": 2, "height": 2});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': { 'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 5});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
svgroot.removeChild( g);
|
||||
|
||||
});
|
||||
|
||||
|
||||
function radians( degrees) {
|
||||
return degrees * Math.PI / 180;
|
||||
}
|
||||
function rotatePoint( point, angle, origin) {
|
||||
if( !origin)
|
||||
origin = {x: 0, y: 0};
|
||||
var x = point.x - origin.x;
|
||||
var y = point.y - origin.y;
|
||||
var theta = radians( angle);
|
||||
return {
|
||||
x: x * Math.cos(theta) + y * Math.sin(theta) + origin.x,
|
||||
y: x * Math.sin(theta) + y * Math.cos(theta) + origin.y
|
||||
}
|
||||
}
|
||||
function rotateRect( rect, angle, origin) {
|
||||
var tl = rotatePoint( { x: rect.x, y: rect.y}, angle, origin);
|
||||
var tr = rotatePoint( { x: rect.x + rect.width, y: rect.y}, angle, origin);
|
||||
var br = rotatePoint( { x: rect.x + rect.width, y: rect.y + rect.height}, angle, origin);
|
||||
var bl = rotatePoint( { x: rect.x, y: rect.y + rect.height}, angle, origin);
|
||||
|
||||
var minx = Math.min(tl.x, tr.x, bl.x, br.x);
|
||||
var maxx = Math.max(tl.x, tr.x, bl.x, br.x);
|
||||
var miny = Math.min(tl.y, tr.y, bl.y, br.y);
|
||||
var maxy = Math.max(tl.y, tr.y, bl.y, br.y);
|
||||
|
||||
return {
|
||||
x: minx,
|
||||
y: miny,
|
||||
width: (maxx - minx),
|
||||
height: (maxy - miny)
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="svgutils_bbox_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for svgutils.js BBox functions</h1>
|
||||
|
||||
499
test/svgutils_bbox_test.js
Normal file
499
test/svgutils_bbox_test.js
Normal file
@@ -0,0 +1,499 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
function mockCreateSVGElement (jsonMap) {
|
||||
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||
for (var attr in jsonMap['attr']) {
|
||||
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
var mockAddSvgElementFromJsonCallCount = 0;
|
||||
function mockAddSvgElementFromJson (json) {
|
||||
var elem = mockCreateSVGElement(json);
|
||||
svgroot.appendChild(elem);
|
||||
mockAddSvgElementFromJsonCallCount++;
|
||||
return elem;
|
||||
}
|
||||
var mockPathActions = {
|
||||
resetOrientation: function (path) {
|
||||
if (path == null || path.nodeName !== 'path') { return false; }
|
||||
var tlist = svgedit.transformlist.getTransformList(path);
|
||||
var m = svgedit.math.transformListToTransform(tlist).matrix;
|
||||
tlist.clear();
|
||||
path.removeAttribute('transform');
|
||||
var segList = path.pathSegList;
|
||||
|
||||
var len = segList.numberOfItems;
|
||||
var i, last_x, last_y;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
var seg = segList.getItem(i);
|
||||
var type = seg.pathSegType;
|
||||
if (type == 1) {continue;}
|
||||
var pts = [];
|
||||
$.each(['',1,2], function(j, n) {
|
||||
var x = seg['x'+n], y = seg['y'+n];
|
||||
if (x !== undefined && y !== undefined) {
|
||||
var pt = svgedit.math.transformPoint(x, y, m);
|
||||
pts.splice(pts.length, 0, pt.x, pt.y);
|
||||
}
|
||||
});
|
||||
svgedit.path.replacePathSeg(type, i, pts, path);
|
||||
}
|
||||
|
||||
//svgedit.utilities.reorientGrads(path, m);
|
||||
}
|
||||
}
|
||||
|
||||
var EPSILON = 0.001
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
var sandbox = document.getElementById('sandbox');
|
||||
var svgroot = mockCreateSVGElement({
|
||||
'element': 'svg',
|
||||
'attr': {'id': 'svgroot'}
|
||||
});
|
||||
sandbox.appendChild(svgroot);
|
||||
|
||||
|
||||
module('svgedit.utilities_bbox', {
|
||||
setup: function() {
|
||||
// We're reusing ID's so we need to do this for transforms.
|
||||
svgedit.transformlist.resetListMap();
|
||||
svgedit.path.init(null);
|
||||
mockAddSvgElementFromJsonCallCount = 0;
|
||||
},
|
||||
teardown: function() {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
test('Test svgedit.utilities package', function() {
|
||||
ok(svgedit.utilities);
|
||||
ok(svgedit.utilities.getBBoxWithTransform);
|
||||
ok(svgedit.utilities.getStrokedBBox);
|
||||
ok(svgedit.utilities.getRotationAngleFromTransformList);
|
||||
ok(svgedit.utilities.getRotationAngle);
|
||||
});
|
||||
|
||||
|
||||
test("Test getBBoxWithTransform and no transform", function() {
|
||||
var getBBoxWithTransform = svgedit.utilities.getBBoxWithTransform
|
||||
|
||||
var bbox;
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M0,1 L2,3'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
bbox = getBBoxWithTransform(elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
deepEqual(bbox, {x: 0, y: 1, width: 2, height: 2});
|
||||
equal(mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual(bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
equal(mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': {'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
bbox = getBBoxWithTransform(elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 5});
|
||||
equal( mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
equal( mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild( g);
|
||||
|
||||
});
|
||||
|
||||
|
||||
test("Test getBBoxWithTransform and a rotation transform", function() {
|
||||
var getBBoxWithTransform = svgedit.utilities.getBBoxWithTransform
|
||||
|
||||
var bbox;
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M10,10 L20,20', 'transform': 'rotate(45 10,10)'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getBBoxWithTransform(elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
close( bbox.x, 10, EPSILON);
|
||||
close( bbox.y, 10, EPSILON);
|
||||
close( bbox.width, 0, EPSILON);
|
||||
close( bbox.height, Math.sqrt(100 + 100), EPSILON);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '10', 'y': '10', 'width': '10', 'height': '20', 'transform': 'rotate(90 15,20)'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
close( bbox.x, 5, EPSILON);
|
||||
close( bbox.y, 15, EPSILON);
|
||||
close( bbox.width, 20, EPSILON);
|
||||
close( bbox.height, 10, EPSILON);
|
||||
equal( mockAddSvgElementFromJsonCallCount, 1);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
var rect = {x: 10, y: 10, width: 10, height: 20};
|
||||
var angle = 45;
|
||||
var origin = { x: 15, y: 20};
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect2', 'x': rect.x, 'y': rect.y, 'width': rect.width, 'height': rect.height, 'transform': 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
mockAddSvgElementFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
var r2 = rotateRect( rect, angle, origin);
|
||||
close( bbox.x, r2.x, EPSILON, 'rect2 x is ' + r2.x);
|
||||
close( bbox.y, r2.y, EPSILON, 'rect2 y is ' + r2.y);
|
||||
close( bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
close( bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
equal( mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
|
||||
// Same as previous but wrapped with g and the transform is with the g.
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect3', 'x': rect.x, 'y': rect.y, 'width': rect.width, 'height': rect.height}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {'transform': 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')'}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
mockAddSvgElementFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform( g, mockAddSvgElementFromJson, mockPathActions);
|
||||
close( bbox.x, r2.x, EPSILON, 'rect2 x is ' + r2.x);
|
||||
close( bbox.y, r2.y, EPSILON, 'rect2 y is ' + r2.y);
|
||||
close( bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
close( bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
equal( mockAddSvgElementFromJsonCallCount, 0);
|
||||
svgroot.removeChild( g);
|
||||
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'ellipse',
|
||||
'attr': { 'id': 'ellipse1', 'cx': '100', 'cy': '100', 'rx': '50', 'ry': '50', 'transform': 'rotate(45 100,100)'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
mockAddSvgElementFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
// TODO: the BBox algorithm is using the bezier control points to calculate the bounding box. Should be 50, 50, 100, 100.
|
||||
ok( bbox.x > 45 && bbox.x <= 50);
|
||||
ok( bbox.y > 45 && bbox.y <= 50);
|
||||
ok( bbox.width >= 100 && bbox.width < 110);
|
||||
ok( bbox.height >= 100 && bbox.height < 110);
|
||||
equal( mockAddSvgElementFromJsonCallCount, 1);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
test("Test getBBoxWithTransform with rotation and matrix transforms", function() {
|
||||
var getBBoxWithTransform = svgedit.utilities.getBBoxWithTransform
|
||||
|
||||
var bbox;
|
||||
var tx = 10; // tx right
|
||||
var ty = 10; // tx down
|
||||
var txInRotatedSpace = Math.sqrt(tx*tx + ty*ty); // translate in rotated 45 space.
|
||||
var tyInRotatedSpace = 0;
|
||||
var matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M10,10 L20,20', 'transform': 'rotate(45 10,10) ' + matrix}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getBBoxWithTransform(elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
close( bbox.x, 10 + tx, EPSILON);
|
||||
close( bbox.y, 10 + ty, EPSILON);
|
||||
close( bbox.width, 0, EPSILON)
|
||||
close( bbox.height, Math.sqrt(100 + 100), EPSILON)
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
txInRotatedSpace = tx; // translate in rotated 90 space.
|
||||
tyInRotatedSpace = -ty;
|
||||
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '10', 'y': '10', 'width': '10', 'height': '20', 'transform': 'rotate(90 15,20) ' + matrix}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
close( bbox.x, 5 + tx, EPSILON);
|
||||
close( bbox.y, 15 + ty, EPSILON);
|
||||
close( bbox.width, 20, EPSILON);
|
||||
close( bbox.height, 10, EPSILON);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
var rect = {x: 10, y: 10, width: 10, height: 20}
|
||||
var angle = 45
|
||||
var origin = { x: 15, y: 20}
|
||||
tx = 10; // tx right
|
||||
ty = 10; // tx down
|
||||
txInRotatedSpace = Math.sqrt(tx*tx + ty*ty); // translate in rotated 45 space.
|
||||
tyInRotatedSpace = 0;
|
||||
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect2', 'x': rect.x, 'y': rect.y, 'width': rect.width, 'height': rect.height, 'transform': 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
var r2 = rotateRect( rect, angle, origin)
|
||||
close( bbox.x, r2.x + tx, EPSILON, 'rect2 x is ' + r2.x);
|
||||
close( bbox.y, r2.y + ty, EPSILON, 'rect2 y is ' + r2.y);
|
||||
close( bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
close( bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
|
||||
// Same as previous but wrapped with g and the transform is with the g.
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect3', 'x': rect.x, 'y': rect.y, 'width': rect.width, 'height': rect.height}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {'transform': 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
bbox = getBBoxWithTransform( g, mockAddSvgElementFromJson, mockPathActions)
|
||||
close( bbox.x, r2.x + tx, EPSILON, 'rect2 x is ' + r2.x);
|
||||
close( bbox.y, r2.y + ty, EPSILON, 'rect2 y is ' + r2.y);
|
||||
close( bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
close( bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
svgroot.removeChild( g);
|
||||
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'ellipse',
|
||||
'attr': { 'id': 'ellipse1', 'cx': '100', 'cy': '100', 'rx': '50', 'ry': '50', 'transform': 'rotate(45 100,100) ' + matrix}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxWithTransform( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
// TODO: the BBox algorithm is using the bezier control points to calculate the bounding box. Should be 50, 50, 100, 100.
|
||||
ok( bbox.x > 45 + tx && bbox.x <= 50 + tx);
|
||||
ok( bbox.y > 45 + ty && bbox.y <= 50 + ty);
|
||||
ok( bbox.width >= 100 && bbox.width < 110);
|
||||
ok( bbox.height >= 100 && bbox.height < 110);
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
});
|
||||
|
||||
|
||||
test("Test getStrokedBBox with stroke-width 10", function() {
|
||||
var getStrokedBBox = svgedit.utilities.getStrokedBBox
|
||||
|
||||
var bbox;
|
||||
var strokeWidth = 10
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M0,1 L2,3', 'stroke-width': strokeWidth}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual(bbox, {"x": 0 - strokeWidth / 2, "y": 1 - strokeWidth / 2, "width": 2 + strokeWidth, "height": 2 + strokeWidth});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10', 'stroke-width': strokeWidth}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0 - strokeWidth / 2, "y": 1 - strokeWidth / 2, "width": 5 + strokeWidth, "height": 10 + strokeWidth});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': { 'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6', 'stroke-width': strokeWidth}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0 - strokeWidth / 2, "y": 1 - strokeWidth / 2, "width": 5 + strokeWidth, "height": 5 + strokeWidth});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10', 'stroke-width': strokeWidth}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0 - strokeWidth / 2, "y": 1 - strokeWidth / 2, "width": 5 + strokeWidth, "height": 10 + strokeWidth});
|
||||
svgroot.removeChild( g);
|
||||
|
||||
});
|
||||
|
||||
|
||||
test("Test getStrokedBBox with stroke-width 'none'", function() {
|
||||
var getStrokedBBox = svgedit.utilities.getStrokedBBox
|
||||
|
||||
var bbox;
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M0,1 L2,3', 'stroke-width': 'none'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual(bbox, {"x": 0, "y": 1, "width": 2, "height": 2});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10', 'stroke-width': 'none'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': { 'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6', 'stroke-width': 'none'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 5});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10', 'stroke-width': 'none'}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
svgroot.removeChild( g);
|
||||
|
||||
});
|
||||
|
||||
|
||||
test("Test getStrokedBBox with no stroke-width attribute", function() {
|
||||
var getStrokedBBox = svgedit.utilities.getStrokedBBox
|
||||
|
||||
var bbox;
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M0,1 L2,3'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual(bbox, {"x": 0, "y": 1, "width": 2, "height": 2});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': { 'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 5});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
var g = mockCreateSVGElement({
|
||||
'element': 'g',
|
||||
'attr': {}
|
||||
});
|
||||
g.appendChild( elem);
|
||||
svgroot.appendChild( g);
|
||||
bbox = getStrokedBBox( [elem], mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
svgroot.removeChild( g);
|
||||
|
||||
});
|
||||
|
||||
|
||||
function radians( degrees) {
|
||||
return degrees * Math.PI / 180;
|
||||
}
|
||||
function rotatePoint( point, angle, origin) {
|
||||
if( !origin)
|
||||
origin = {x: 0, y: 0};
|
||||
var x = point.x - origin.x;
|
||||
var y = point.y - origin.y;
|
||||
var theta = radians( angle);
|
||||
return {
|
||||
x: x * Math.cos(theta) + y * Math.sin(theta) + origin.x,
|
||||
y: x * Math.sin(theta) + y * Math.cos(theta) + origin.y
|
||||
}
|
||||
}
|
||||
function rotateRect( rect, angle, origin) {
|
||||
var tl = rotatePoint( { x: rect.x, y: rect.y}, angle, origin);
|
||||
var tr = rotatePoint( { x: rect.x + rect.width, y: rect.y}, angle, origin);
|
||||
var br = rotatePoint( { x: rect.x + rect.width, y: rect.y + rect.height}, angle, origin);
|
||||
var bl = rotatePoint( { x: rect.x, y: rect.y + rect.height}, angle, origin);
|
||||
|
||||
var minx = Math.min(tl.x, tr.x, bl.x, br.x);
|
||||
var maxx = Math.max(tl.x, tr.x, bl.x, br.x);
|
||||
var miny = Math.min(tl.y, tr.y, bl.y, br.y);
|
||||
var maxy = Math.max(tl.y, tr.y, bl.y, br.y);
|
||||
|
||||
return {
|
||||
x: minx,
|
||||
y: miny,
|
||||
width: (maxx - minx),
|
||||
height: (maxy - miny)
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
@@ -18,179 +18,7 @@
|
||||
<script src="../editor/units.js"></script>
|
||||
<script src="../editor/svgutils.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var current_layer = document.getElementById('layer1');
|
||||
|
||||
|
||||
function mockCreateSVGElement(jsonMap) {
|
||||
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||
for (var attr in jsonMap['attr']) {
|
||||
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
function mockAddSvgElementFromJson( json) {
|
||||
var elem = mockCreateSVGElement( json)
|
||||
current_layer.appendChild( elem)
|
||||
return elem
|
||||
}
|
||||
|
||||
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
var groupWithMatrixTransform = document.getElementById('svg_group_with_matrix_transform');
|
||||
var textWithMatrixTransform = document.getElementById('svg_text_with_matrix_transform');
|
||||
|
||||
function fillDocumentByCloningElement( elem, count) {
|
||||
var elemId = elem.getAttribute( 'id') + '-'
|
||||
for( var index = 0; index < count; index++) {
|
||||
var clone = elem.cloneNode(true); // t: deep clone
|
||||
// Make sure you set a unique ID like a real document.
|
||||
clone.setAttribute( 'id', elemId + index)
|
||||
var parent = elem.parentNode;
|
||||
parent.appendChild(clone);
|
||||
}
|
||||
}
|
||||
|
||||
module('svgedit.utilities_performance', {
|
||||
setup: function() {
|
||||
},
|
||||
teardown: function() {
|
||||
}
|
||||
});
|
||||
|
||||
var mockPathActions = {
|
||||
resetOrientation: function(path) {
|
||||
if (path == null || path.nodeName != 'path') {return false;}
|
||||
var tlist = svgedit.transformlist.getTransformList(path);
|
||||
var m = svgedit.math.transformListToTransform(tlist).matrix;
|
||||
tlist.clear();
|
||||
path.removeAttribute('transform');
|
||||
var segList = path.pathSegList;
|
||||
|
||||
var len = segList.numberOfItems;
|
||||
var i, last_x, last_y;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
var seg = segList.getItem(i);
|
||||
var type = seg.pathSegType;
|
||||
if (type == 1) {continue;}
|
||||
var pts = [];
|
||||
$.each(['',1,2], function(j, n) {
|
||||
var x = seg['x'+n], y = seg['y'+n];
|
||||
if (x !== undefined && y !== undefined) {
|
||||
var pt = svgedit.math.transformPoint(x, y, m);
|
||||
pts.splice(pts.length, 0, pt.x, pt.y);
|
||||
}
|
||||
});
|
||||
//svgedit.path.replacePathSeg(type, i, pts, path);
|
||||
}
|
||||
|
||||
//svgedit.utilities.reorientGrads(path, m);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Performance times with various browsers on Macbook 2011 8MB RAM OS X El Capitan 10.11.4
|
||||
//
|
||||
// To see 'Before Optimization' performance, making the following two edits.
|
||||
// 1. svgedit.utilities.getStrokedBBox - change if( elems.length === 1) to if( false && elems.length === 1)
|
||||
// 2. svgedit.utilities.getBBoxWithTransform - uncomment 'Old technique that was very slow'
|
||||
|
||||
// Chrome
|
||||
// Before Optimization
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 4,218, ave ms 41.0, min/max 37 51
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 4,458, ave ms 43.3, min/max 32 63
|
||||
// Optimized Code
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 1,112, ave ms 10.8, min/max 9 20
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 34, ave ms 0.3, min/max 0 20
|
||||
|
||||
// Firefox
|
||||
// Before Optimization
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 3,794, ave ms 36.8, min/max 33 48
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 4,049, ave ms 39.3, min/max 28 53
|
||||
// Optimized Code
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 104, ave ms 1.0, min/max 0 23
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 71, ave ms 0.7, min/max 0 23
|
||||
|
||||
// Safari
|
||||
// Before Optimization
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 4,840, ave ms 47.0, min/max 45 62
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 4,849, ave ms 47.1, min/max 34 62
|
||||
// Optimized Code
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 42, ave ms 0.4, min/max 0 23
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 17, ave ms 0.2, min/max 0 23
|
||||
|
||||
|
||||
asyncTest('Test svgCanvas.getStrokedBBox() performance with matrix transforms', function( ) {
|
||||
expect(2);
|
||||
var getStrokedBBox = svgedit.utilities.getStrokedBBox;
|
||||
var children = current_layer.children;
|
||||
|
||||
|
||||
var obj, index, count, child, start, delta, lastTime, now, ave,
|
||||
min = Number.MAX_VALUE,
|
||||
max = 0,
|
||||
total = 0;
|
||||
|
||||
fillDocumentByCloningElement( groupWithMatrixTransform, 50)
|
||||
fillDocumentByCloningElement( textWithMatrixTransform, 50)
|
||||
|
||||
// The first pass through all elements is slower.
|
||||
count = children.length;
|
||||
start = lastTime = now = Date.now();
|
||||
// Skip the first child which is the title.
|
||||
for( index = 1; index< count; index++) {
|
||||
child = children[index]
|
||||
obj = getStrokedBBox([child], mockAddSvgElementFromJson, mockPathActions );
|
||||
now = Date.now(); delta = now - lastTime; lastTime = now;
|
||||
total += delta;
|
||||
min = Math.min( min, delta);
|
||||
max = Math.max( max, delta);
|
||||
}
|
||||
total = lastTime - start;
|
||||
ave = total / count;
|
||||
ok( ave < 20, 'svgedit.utilities.getStrokedBBox average execution time is less than 20 ms')
|
||||
console.log( 'Pass1 svgCanvas.getStrokedBBox total ms ' + total + ', ave ms ' + ave.toFixed(1) + ', min/max ' + min + ' ' + max)
|
||||
|
||||
// The second pass is two to ten times faster.
|
||||
setTimeout(function() {
|
||||
count = children.length;
|
||||
|
||||
start = lastTime = now = Date.now();
|
||||
// Skip the first child which is the title.
|
||||
for( index = 1; index< count; index++) {
|
||||
child = children[index]
|
||||
obj = getStrokedBBox([child], mockAddSvgElementFromJson, mockPathActions );
|
||||
now = Date.now(); delta = now - lastTime; lastTime = now;
|
||||
total += delta;
|
||||
min = Math.min( min, delta);
|
||||
max = Math.max( max, delta);
|
||||
}
|
||||
|
||||
|
||||
total = lastTime - start;
|
||||
ave = total / count;
|
||||
ok( ave < 2, 'svgedit.utilities.getStrokedBBox average execution time is less than 1 ms')
|
||||
console.log( 'Pass2 svgCanvas.getStrokedBBox total ms ' + total + ', ave ms ' + ave.toFixed(1) + ', min/max ' + min + ' ' + max)
|
||||
|
||||
QUnit.start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="svgutils_performance_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Performance Unit Tests for svgutils.js</h1>
|
||||
|
||||
164
test/svgutils_performance_test.js
Normal file
164
test/svgutils_performance_test.js
Normal file
@@ -0,0 +1,164 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
var currentLayer = document.getElementById('layer1');
|
||||
|
||||
function mockCreateSVGElement (jsonMap) {
|
||||
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||
for (var attr in jsonMap['attr']) {
|
||||
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
function mockAddSvgElementFromJson (json) {
|
||||
var elem = mockCreateSVGElement(json);
|
||||
currentLayer.appendChild(elem);
|
||||
return elem;
|
||||
}
|
||||
|
||||
// var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
var groupWithMatrixTransform = document.getElementById('svg_group_with_matrix_transform');
|
||||
var textWithMatrixTransform = document.getElementById('svg_text_with_matrix_transform');
|
||||
|
||||
function fillDocumentByCloningElement (elem, count) {
|
||||
var elemId = elem.getAttribute('id') + '-';
|
||||
for (var index = 0; index < count; index++) {
|
||||
var clone = elem.cloneNode(true); // t: deep clone
|
||||
// Make sure you set a unique ID like a real document.
|
||||
clone.setAttribute('id', elemId + index);
|
||||
var parent = elem.parentNode;
|
||||
parent.appendChild(clone);
|
||||
}
|
||||
}
|
||||
|
||||
module('svgedit.utilities_performance', {
|
||||
setup: function () {
|
||||
},
|
||||
teardown: function () {
|
||||
}
|
||||
});
|
||||
|
||||
var mockPathActions = {
|
||||
resetOrientation: function (path) {
|
||||
if (path == null || path.nodeName !== 'path') { return false; }
|
||||
var tlist = svgedit.transformlist.getTransformList(path);
|
||||
var m = svgedit.math.transformListToTransform(tlist).matrix;
|
||||
tlist.clear();
|
||||
path.removeAttribute('transform');
|
||||
var segList = path.pathSegList;
|
||||
|
||||
var len = segList.numberOfItems;
|
||||
var i; // , lastX, lastY;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
var seg = segList.getItem(i);
|
||||
var type = seg.pathSegType;
|
||||
if (type === 1) { continue; }
|
||||
var pts = [];
|
||||
$.each(['', 1, 2], function (j, n) {
|
||||
var x = seg['x' + n], y = seg['y' + n];
|
||||
if (x !== undefined && y !== undefined) {
|
||||
var pt = svgedit.math.transformPoint(x, y, m);
|
||||
pts.splice(pts.length, 0, pt.x, pt.y);
|
||||
}
|
||||
});
|
||||
// svgedit.path.replacePathSeg(type, i, pts, path);
|
||||
}
|
||||
|
||||
// svgedit.utilities.reorientGrads(path, m);
|
||||
}
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////
|
||||
// Performance times with various browsers on Macbook 2011 8MB RAM OS X El Capitan 10.11.4
|
||||
//
|
||||
// To see 'Before Optimization' performance, making the following two edits.
|
||||
// 1. svgedit.utilities.getStrokedBBox - change if( elems.length === 1) to if( false && elems.length === 1)
|
||||
// 2. svgedit.utilities.getBBoxWithTransform - uncomment 'Old technique that was very slow'
|
||||
|
||||
// Chrome
|
||||
// Before Optimization
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 4,218, ave ms 41.0, min/max 37 51
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 4,458, ave ms 43.3, min/max 32 63
|
||||
// Optimized Code
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 1,112, ave ms 10.8, min/max 9 20
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 34, ave ms 0.3, min/max 0 20
|
||||
|
||||
// Firefox
|
||||
// Before Optimization
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 3,794, ave ms 36.8, min/max 33 48
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 4,049, ave ms 39.3, min/max 28 53
|
||||
// Optimized Code
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 104, ave ms 1.0, min/max 0 23
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 71, ave ms 0.7, min/max 0 23
|
||||
|
||||
// Safari
|
||||
// Before Optimization
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 4,840, ave ms 47.0, min/max 45 62
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 4,849, ave ms 47.1, min/max 34 62
|
||||
// Optimized Code
|
||||
// Pass1 svgCanvas.getStrokedBBox total ms 42, ave ms 0.4, min/max 0 23
|
||||
// Pass2 svgCanvas.getStrokedBBox total ms 17, ave ms 0.2, min/max 0 23
|
||||
|
||||
asyncTest('Test svgCanvas.getStrokedBBox() performance with matrix transforms', function () {
|
||||
expect(2);
|
||||
var getStrokedBBox = svgedit.utilities.getStrokedBBox;
|
||||
var children = currentLayer.children;
|
||||
|
||||
var index, count, child, start, delta, lastTime, now, ave,
|
||||
min = Number.MAX_VALUE,
|
||||
max = 0,
|
||||
total = 0;
|
||||
|
||||
fillDocumentByCloningElement(groupWithMatrixTransform, 50);
|
||||
fillDocumentByCloningElement(textWithMatrixTransform, 50);
|
||||
|
||||
// The first pass through all elements is slower.
|
||||
count = children.length;
|
||||
start = lastTime = now = Date.now();
|
||||
// Skip the first child which is the title.
|
||||
for (index = 1; index < count; index++) {
|
||||
child = children[index];
|
||||
/* var obj = */ getStrokedBBox([child], mockAddSvgElementFromJson, mockPathActions);
|
||||
now = Date.now(); delta = now - lastTime; lastTime = now;
|
||||
total += delta;
|
||||
min = Math.min(min, delta);
|
||||
max = Math.max(max, delta);
|
||||
}
|
||||
total = lastTime - start;
|
||||
ave = total / count;
|
||||
ok(ave < 20, 'svgedit.utilities.getStrokedBBox average execution time is less than 20 ms');
|
||||
console.log('Pass1 svgCanvas.getStrokedBBox total ms ' + total + ', ave ms ' + ave.toFixed(1) + ', min/max ' + min + ' ' + max);
|
||||
|
||||
// The second pass is two to ten times faster.
|
||||
setTimeout(function () {
|
||||
count = children.length;
|
||||
|
||||
start = lastTime = now = Date.now();
|
||||
// Skip the first child which is the title.
|
||||
for (index = 1; index < count; index++) {
|
||||
child = children[index];
|
||||
/* var obj = */ getStrokedBBox([child], mockAddSvgElementFromJson, mockPathActions);
|
||||
now = Date.now(); delta = now - lastTime; lastTime = now;
|
||||
total += delta;
|
||||
min = Math.min(min, delta);
|
||||
max = Math.max(max, delta);
|
||||
}
|
||||
|
||||
total = lastTime - start;
|
||||
ave = total / count;
|
||||
ok(ave < 2, 'svgedit.utilities.getStrokedBBox average execution time is less than 1 ms');
|
||||
console.log('Pass2 svgCanvas.getStrokedBBox total ms ' + total + ', ave ms ' + ave.toFixed(1) + ', min/max ' + min + ' ' + max);
|
||||
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -13,349 +13,7 @@
|
||||
<script src="../editor/jquery-svg.js"></script> <!-- has $.attr() that takes an array . Used by svgedit.utilities.getPathDFromElement -->
|
||||
<script src="../editor/svgutils.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
function mockCreateSVGElement(jsonMap) {
|
||||
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||
for (var attr in jsonMap['attr']) {
|
||||
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
function mockAddSvgElementFromJson( json) {
|
||||
var elem = mockCreateSVGElement( json)
|
||||
svgroot.appendChild( elem)
|
||||
return elem
|
||||
}
|
||||
var mockPathActions = { resetOrientation: function () {}}
|
||||
var mockHistorySubCommands = []
|
||||
var mockHistory = {
|
||||
BatchCommand: function() {
|
||||
return {
|
||||
addSubCommand: function( cmd) { mockHistorySubCommands.push(cmd)}
|
||||
}
|
||||
},
|
||||
RemoveElementCommand: function(elem, nextSibling, parent) {
|
||||
this.elem = elem;
|
||||
this.nextSibling = nextSibling;
|
||||
this.parent = parent
|
||||
},
|
||||
InsertElementCommand: function(path){
|
||||
this.path = path
|
||||
}
|
||||
}
|
||||
var mockCount = {
|
||||
clearSelection: 0,
|
||||
addToSelection: 0,
|
||||
addCommandToHistory: 0
|
||||
}
|
||||
function mockClearSelection() { mockCount.clearSelection ++}
|
||||
function mockAddToSelection() { mockCount.addToSelection ++}
|
||||
function mockAddCommandToHistory() {mockCount.addCommandToHistory ++}
|
||||
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
var sandbox = document.getElementById('sandbox');
|
||||
var svgroot = mockCreateSVGElement({
|
||||
'element': 'svg',
|
||||
'attr': {'id': 'svgroot'}
|
||||
});
|
||||
sandbox.appendChild(svgroot);
|
||||
|
||||
|
||||
module('svgedit.utilities', {
|
||||
setup: function() {
|
||||
mockHistorySubCommands = [];
|
||||
mockCount.clearSelection = 0;
|
||||
mockCount.addToSelection = 0;
|
||||
mockCount.addCommandToHistory = 0;
|
||||
},
|
||||
teardown: function() {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
test('Test svgedit.utilities package', function() {
|
||||
expect(3);
|
||||
|
||||
ok(svgedit.utilities);
|
||||
ok(svgedit.utilities.toXml);
|
||||
equals(typeof svgedit.utilities.toXml, typeof function(){});
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.toXml() function', function() {
|
||||
expect(6);
|
||||
var toXml = svgedit.utilities.toXml;
|
||||
|
||||
equals(toXml('a'), 'a');
|
||||
equals(toXml('ABC_'), 'ABC_');
|
||||
equals(toXml('PB&J'), 'PB&J');
|
||||
equals(toXml('2 < 5'), '2 < 5');
|
||||
equals(toXml('5 > 2'), '5 > 2');
|
||||
equals(toXml('\'<&>"'), ''<&>"');
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.fromXml() function', function() {
|
||||
expect(6);
|
||||
var fromXml = svgedit.utilities.fromXml;
|
||||
|
||||
equals(fromXml('a'), 'a');
|
||||
equals(fromXml('ABC_'), 'ABC_');
|
||||
equals(fromXml('PB&J'), 'PB&J');
|
||||
equals(fromXml('2 < 5'), '2 < 5');
|
||||
equals(fromXml('5 > 2'), '5 > 2');
|
||||
equals(fromXml('<&>'), '<&>');
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.encode64() function', function() {
|
||||
expect(4);
|
||||
var encode64 = svgedit.utilities.encode64;
|
||||
|
||||
equals(encode64('abcdef'), 'YWJjZGVm');
|
||||
equals(encode64('12345'), 'MTIzNDU=');
|
||||
equals(encode64(' '), 'IA==');
|
||||
equals(encode64('`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?'), 'YH4hQCMkJV4mKigpLV89K1t7XX1cfDs6JyIsPC4+Lz8=');
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.decode64() function', function() {
|
||||
expect(4);
|
||||
var decode64 = svgedit.utilities.decode64;
|
||||
|
||||
equals(decode64('YWJjZGVm'), 'abcdef');
|
||||
equals(decode64('MTIzNDU='), '12345');
|
||||
equals(decode64('IA=='), ' ');
|
||||
equals(decode64('YH4hQCMkJV4mKigpLV89K1t7XX1cfDs6JyIsPC4+Lz8='), '`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?');
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.convertToXMLReferences() function', function() {
|
||||
expect(1);
|
||||
|
||||
var convert = svgedit.utilities.convertToXMLReferences;
|
||||
equals(convert('ABC'), 'ABC');
|
||||
// equals(convert('<27>BC'), 'ÀBC');
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.bboxToObj() function', function() {
|
||||
expect(5);
|
||||
var bboxToObj = svgedit.utilities.bboxToObj;
|
||||
|
||||
var rect = svg.createSVGRect();
|
||||
rect.x = 1;
|
||||
rect.y = 2;
|
||||
rect.width = 3;
|
||||
rect.height = 4;
|
||||
|
||||
var obj = bboxToObj(rect);
|
||||
equals(typeof obj, typeof {});
|
||||
equals(obj.x, 1);
|
||||
equals(obj.y, 2);
|
||||
equals(obj.width, 3);
|
||||
equals(obj.height, 4);
|
||||
});
|
||||
|
||||
test("Test getUrlFromAttr", function() {
|
||||
expect(4);
|
||||
|
||||
equal(svgedit.utilities.getUrlFromAttr("url(#foo)"), "#foo");
|
||||
equal(svgedit.utilities.getUrlFromAttr("url(somefile.svg#foo)"), "somefile.svg#foo");
|
||||
equal(svgedit.utilities.getUrlFromAttr("url('#foo')"), "#foo");
|
||||
equal(svgedit.utilities.getUrlFromAttr('url("#foo")'), "#foo");
|
||||
});
|
||||
|
||||
test("Test getPathBBox", function() {
|
||||
if(svgedit.browser.supportsPathBBox()) return;
|
||||
var doc = svgedit.utilities.text2xml('<svg></svg>');
|
||||
var path = doc.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttributeNS(null, 'd', 'm0,0l5,0l0,5l-5,0l0,-5z');
|
||||
var bb = svgedit.utilities.getPathBBox(path);
|
||||
equals(typeof bb, 'object', 'BBox returned object');
|
||||
ok(bb.x && !isNaN(bb.x));
|
||||
ok(bb.y && !isNaN(bb.y));
|
||||
});
|
||||
|
||||
test("Test getPathDFromSegments", function() {
|
||||
var d;
|
||||
var getPathDFromSegments = svgedit.utilities.getPathDFromSegments;
|
||||
|
||||
var doc = svgedit.utilities.text2xml('<svg></svg>');
|
||||
var path = doc.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttributeNS(null, 'd', 'm0,0l5,0l0,5l-5,0l0,-5z');
|
||||
d = getPathDFromSegments( [
|
||||
['M', [1, 2]],
|
||||
['Z', []],
|
||||
]);
|
||||
equal( d, 'M1,2 Z');
|
||||
|
||||
d = getPathDFromSegments( [
|
||||
['M', [1, 2]],
|
||||
['M', [3, 4]],
|
||||
['Z', []],
|
||||
]);
|
||||
equal( d, 'M1,2 M3,4 Z');
|
||||
|
||||
d = getPathDFromSegments( [
|
||||
['M', [1, 2]],
|
||||
['C', [3, 4, 5, 6]],
|
||||
['Z', []],
|
||||
]);
|
||||
equal( d, 'M1,2 C3,4 5,6 Z');
|
||||
|
||||
});
|
||||
|
||||
test("Test getPathDFromElement", function() {
|
||||
var getPathDFromElement = svgedit.utilities.getPathDFromElement;
|
||||
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M0,1 Z'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
equal( getPathDFromElement( elem), 'M0,1 Z');
|
||||
svgroot.removeChild( elem)
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
equal( getPathDFromElement( elem), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z');
|
||||
svgroot.removeChild( elem)
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'roundrect', 'x': '0', 'y': '1', 'rx': '2', 'ry': '3', 'width': '10', 'height': '11'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
var closeEnough = new RegExp( 'M0,4 C0,2.3[0-9]* 0.9[0-9]*,1 2,1 L8,1 C9.0[0-9]*,1 10,2.3[0-9]* 10,4 L10,9 C10,10.6[0-9]* 9.08675799086758,12 8,12 L2,12 C0.9[0-9]*,12 0,10.6[0-9]* 0,9 L0,4 Z')
|
||||
equal(closeEnough.test(getPathDFromElement( elem)), true);
|
||||
svgroot.removeChild( elem)
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': { 'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
equal( getPathDFromElement( elem), 'M0,1L5,6');
|
||||
svgroot.removeChild( elem)
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'circle',
|
||||
'attr': { 'id': 'circle', 'cx': '10', 'cy': '11', 'rx': '5', 'ry': '10'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
equal( getPathDFromElement( elem), 'M10,11 C10,11 10,11 10,11 C10,11 10,11 10,11 C10,11 10,11 10,11 C10,11 10,11 10,11 Z');
|
||||
svgroot.removeChild( elem)
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'polyline',
|
||||
'attr': { 'id': 'polyline', 'points': '0,1 5,1 5,11 0,11'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
equal( getPathDFromElement( elem), 'M0,1 5,1 5,11 0,11');
|
||||
svgroot.removeChild( elem)
|
||||
|
||||
equal( getPathDFromElement( {tagName: 'something unknown'}), undefined);
|
||||
});
|
||||
|
||||
test("Test getBBoxOfElementAsPath", function() {
|
||||
function getBBoxOfElementAsPath( elem, addSvgElementFromJson, pathActions) {
|
||||
var bbox = svgedit.utilities.getBBoxOfElementAsPath(elem, addSvgElementFromJson, pathActions);
|
||||
return svgedit.utilities.bboxToObj( bbox) // need this for QUnit equal() to work.
|
||||
}
|
||||
|
||||
var bbox;
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': { 'id': 'path', 'd': 'M0,1 Z'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
bbox = getBBoxOfElementAsPath(elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual(bbox, {"x": 0, "y": 1, "width": 0, "height": 0 });
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxOfElementAsPath( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 10});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': { 'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||
});
|
||||
svgroot.appendChild( elem);
|
||||
bbox = getBBoxOfElementAsPath( elem, mockAddSvgElementFromJson, mockPathActions)
|
||||
deepEqual( bbox, { "x": 0, "y": 1, "width": 5, "height": 5});
|
||||
svgroot.removeChild( elem);
|
||||
|
||||
// TODO: test element with transform. Need resetOrientation above to be working or mock it.
|
||||
|
||||
});
|
||||
|
||||
test("Test convertToPath rect", function() {
|
||||
var convertToPath = svgedit.utilities.convertToPath;
|
||||
var attrs = {
|
||||
'fill': 'red',
|
||||
'stroke': 'white',
|
||||
'stroke-width': '1',
|
||||
'visibility':'hidden'
|
||||
};
|
||||
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': { 'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
svgroot.appendChild( elem)
|
||||
var path = convertToPath( elem, attrs, mockAddSvgElementFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory);
|
||||
equal( path.getAttribute('d'), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z');
|
||||
equal( path.getAttribute('visibilituy'), null);
|
||||
equal( path.id, 'rect');
|
||||
equal( path.parentNode, svgroot);
|
||||
equal( elem.parentNode, null);
|
||||
equal( mockHistorySubCommands.length, 2);
|
||||
equal( mockCount.clearSelection, 1);
|
||||
equal( mockCount.addToSelection, 1);
|
||||
equal( mockCount.addCommandToHistory, 1);
|
||||
svgroot.removeChild( path);
|
||||
});
|
||||
|
||||
|
||||
test("Test convertToPath unknown element", function() {
|
||||
var convertToPath = svgedit.utilities.convertToPath;
|
||||
var attrs = {
|
||||
'fill': 'red',
|
||||
'stroke': 'white',
|
||||
'stroke-width': '1',
|
||||
'visibility':'hidden'
|
||||
};
|
||||
|
||||
var elem = {
|
||||
tagName: 'something unknown',
|
||||
id: 'something-unknown',
|
||||
getAttribute: function( attr) { return '';},
|
||||
parentNode: svgroot
|
||||
};
|
||||
var path = convertToPath( elem, attrs, mockAddSvgElementFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory);
|
||||
equal( path, null);
|
||||
equal( elem.parentNode, svgroot);
|
||||
equal( mockHistorySubCommands.length, 0);
|
||||
equal( mockCount.clearSelection, 0);
|
||||
equal( mockCount.addToSelection, 0);
|
||||
equal( mockCount.addCommandToHistory, 0);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="svgutils_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for svgutils.js</h1>
|
||||
|
||||
337
test/svgutils_test.js
Normal file
337
test/svgutils_test.js
Normal file
@@ -0,0 +1,337 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit, equals */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
function mockCreateSVGElement (jsonMap) {
|
||||
var elem = document.createElementNS(svgedit.NS.SVG, jsonMap['element']);
|
||||
for (var attr in jsonMap['attr']) {
|
||||
elem.setAttribute(attr, jsonMap['attr'][attr]);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
function mockAddSvgElementFromJson (json) {
|
||||
var elem = mockCreateSVGElement(json);
|
||||
svgroot.appendChild(elem);
|
||||
return elem;
|
||||
}
|
||||
var mockPathActions = {resetOrientation: function () {}};
|
||||
var mockHistorySubCommands = [];
|
||||
var mockHistory = {
|
||||
BatchCommand: function () {
|
||||
return {
|
||||
addSubCommand: function (cmd) { mockHistorySubCommands.push(cmd); }
|
||||
};
|
||||
},
|
||||
RemoveElementCommand: function (elem, nextSibling, parent) {
|
||||
this.elem = elem;
|
||||
this.nextSibling = nextSibling;
|
||||
this.parent = parent;
|
||||
},
|
||||
InsertElementCommand: function (path) {
|
||||
this.path = path;
|
||||
}
|
||||
};
|
||||
var mockCount = {
|
||||
clearSelection: 0,
|
||||
addToSelection: 0,
|
||||
addCommandToHistory: 0
|
||||
};
|
||||
function mockClearSelection () { mockCount.clearSelection++; }
|
||||
function mockAddToSelection () { mockCount.addToSelection++; }
|
||||
function mockAddCommandToHistory () { mockCount.addCommandToHistory++; }
|
||||
|
||||
var svg = document.createElementNS(svgedit.NS.SVG, 'svg');
|
||||
var sandbox = document.getElementById('sandbox');
|
||||
var svgroot = mockCreateSVGElement({
|
||||
'element': 'svg',
|
||||
'attr': {'id': 'svgroot'}
|
||||
});
|
||||
sandbox.appendChild(svgroot);
|
||||
|
||||
module('svgedit.utilities', {
|
||||
setup: function () {
|
||||
mockHistorySubCommands = [];
|
||||
mockCount.clearSelection = 0;
|
||||
mockCount.addToSelection = 0;
|
||||
mockCount.addCommandToHistory = 0;
|
||||
},
|
||||
teardown: function () {
|
||||
}
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities package', function () {
|
||||
expect(3);
|
||||
|
||||
ok(svgedit.utilities);
|
||||
ok(svgedit.utilities.toXml);
|
||||
equals(typeof svgedit.utilities.toXml, typeof function () {});
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.toXml() function', function () {
|
||||
expect(6);
|
||||
var toXml = svgedit.utilities.toXml;
|
||||
|
||||
equals(toXml('a'), 'a');
|
||||
equals(toXml('ABC_'), 'ABC_');
|
||||
equals(toXml('PB&J'), 'PB&J');
|
||||
equals(toXml('2 < 5'), '2 < 5');
|
||||
equals(toXml('5 > 2'), '5 > 2');
|
||||
equals(toXml('\'<&>"'), ''<&>"');
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.fromXml() function', function () {
|
||||
expect(6);
|
||||
var fromXml = svgedit.utilities.fromXml;
|
||||
|
||||
equals(fromXml('a'), 'a');
|
||||
equals(fromXml('ABC_'), 'ABC_');
|
||||
equals(fromXml('PB&J'), 'PB&J');
|
||||
equals(fromXml('2 < 5'), '2 < 5');
|
||||
equals(fromXml('5 > 2'), '5 > 2');
|
||||
equals(fromXml('<&>'), '<&>');
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.encode64() function', function () {
|
||||
expect(4);
|
||||
var encode64 = svgedit.utilities.encode64;
|
||||
|
||||
equals(encode64('abcdef'), 'YWJjZGVm');
|
||||
equals(encode64('12345'), 'MTIzNDU=');
|
||||
equals(encode64(' '), 'IA==');
|
||||
equals(encode64('`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?'), 'YH4hQCMkJV4mKigpLV89K1t7XX1cfDs6JyIsPC4+Lz8=');
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.decode64() function', function () {
|
||||
expect(4);
|
||||
var decode64 = svgedit.utilities.decode64;
|
||||
|
||||
equals(decode64('YWJjZGVm'), 'abcdef');
|
||||
equals(decode64('MTIzNDU='), '12345');
|
||||
equals(decode64('IA=='), ' ');
|
||||
equals(decode64('YH4hQCMkJV4mKigpLV89K1t7XX1cfDs6JyIsPC4+Lz8='), '`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?');
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.convertToXMLReferences() function', function () {
|
||||
expect(1);
|
||||
|
||||
var convert = svgedit.utilities.convertToXMLReferences;
|
||||
equals(convert('ABC'), 'ABC');
|
||||
// equals(convert('<27>BC'), 'ÀBC');
|
||||
});
|
||||
|
||||
test('Test svgedit.utilities.bboxToObj() function', function () {
|
||||
expect(5);
|
||||
var bboxToObj = svgedit.utilities.bboxToObj;
|
||||
|
||||
var rect = svg.createSVGRect();
|
||||
rect.x = 1;
|
||||
rect.y = 2;
|
||||
rect.width = 3;
|
||||
rect.height = 4;
|
||||
|
||||
var obj = bboxToObj(rect);
|
||||
equals(typeof obj, typeof {});
|
||||
equals(obj.x, 1);
|
||||
equals(obj.y, 2);
|
||||
equals(obj.width, 3);
|
||||
equals(obj.height, 4);
|
||||
});
|
||||
|
||||
test('Test getUrlFromAttr', function () {
|
||||
expect(4);
|
||||
|
||||
equal(svgedit.utilities.getUrlFromAttr('url(#foo)'), '#foo');
|
||||
equal(svgedit.utilities.getUrlFromAttr('url(somefile.svg#foo)'), 'somefile.svg#foo');
|
||||
equal(svgedit.utilities.getUrlFromAttr('url("#foo")'), '#foo');
|
||||
equal(svgedit.utilities.getUrlFromAttr('url("#foo")'), '#foo');
|
||||
});
|
||||
|
||||
test('Test getPathBBox', function () {
|
||||
if (svgedit.browser.supportsPathBBox()) return;
|
||||
var doc = svgedit.utilities.text2xml('<svg></svg>');
|
||||
var path = doc.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttributeNS(null, 'd', 'm0,0l5,0l0,5l-5,0l0,-5z');
|
||||
var bb = svgedit.utilities.getPathBBox(path);
|
||||
equals(typeof bb, 'object', 'BBox returned object');
|
||||
ok(bb.x && !isNaN(bb.x));
|
||||
ok(bb.y && !isNaN(bb.y));
|
||||
});
|
||||
|
||||
test('Test getPathDFromSegments', function () {
|
||||
var d;
|
||||
var getPathDFromSegments = svgedit.utilities.getPathDFromSegments;
|
||||
|
||||
var doc = svgedit.utilities.text2xml('<svg></svg>');
|
||||
var path = doc.createElementNS(svgedit.NS.SVG, 'path');
|
||||
path.setAttributeNS(null, 'd', 'm0,0l5,0l0,5l-5,0l0,-5z');
|
||||
d = getPathDFromSegments([
|
||||
['M', [1, 2]],
|
||||
['Z', []]
|
||||
]);
|
||||
equal(d, 'M1,2 Z');
|
||||
|
||||
d = getPathDFromSegments([
|
||||
['M', [1, 2]],
|
||||
['M', [3, 4]],
|
||||
['Z', []]
|
||||
]);
|
||||
equal(d, 'M1,2 M3,4 Z');
|
||||
|
||||
d = getPathDFromSegments([
|
||||
['M', [1, 2]],
|
||||
['C', [3, 4, 5, 6]],
|
||||
['Z', []]
|
||||
]);
|
||||
equal(d, 'M1,2 C3,4 5,6 Z');
|
||||
});
|
||||
|
||||
test('Test getPathDFromElement', function () {
|
||||
var getPathDFromElement = svgedit.utilities.getPathDFromElement;
|
||||
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': {'id': 'path', 'd': 'M0,1 Z'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
equal(getPathDFromElement(elem), 'M0,1 Z');
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
equal(getPathDFromElement(elem), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z');
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {'id': 'roundrect', 'x': '0', 'y': '1', 'rx': '2', 'ry': '3', 'width': '10', 'height': '11'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
var closeEnough = new RegExp('M0,4 C0,2.3[0-9]* 0.9[0-9]*,1 2,1 L8,1 C9.0[0-9]*,1 10,2.3[0-9]* 10,4 L10,9 C10,10.6[0-9]* 9.08675799086758,12 8,12 L2,12 C0.9[0-9]*,12 0,10.6[0-9]* 0,9 L0,4 Z');
|
||||
equal(closeEnough.test(getPathDFromElement(elem)), true);
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': {'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
equal(getPathDFromElement(elem), 'M0,1L5,6');
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'circle',
|
||||
'attr': {'id': 'circle', 'cx': '10', 'cy': '11', 'rx': '5', 'ry': '10'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
equal(getPathDFromElement(elem), 'M10,11 C10,11 10,11 10,11 C10,11 10,11 10,11 C10,11 10,11 10,11 C10,11 10,11 10,11 Z');
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'polyline',
|
||||
'attr': {'id': 'polyline', 'points': '0,1 5,1 5,11 0,11'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
equal(getPathDFromElement(elem), 'M0,1 5,1 5,11 0,11');
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
equal(getPathDFromElement({tagName: 'something unknown'}), undefined);
|
||||
});
|
||||
|
||||
test('Test getBBoxOfElementAsPath', function () {
|
||||
function getBBoxOfElementAsPath (elem, addSvgElementFromJson, pathActions) {
|
||||
var bbox = svgedit.utilities.getBBoxOfElementAsPath(elem, addSvgElementFromJson, pathActions);
|
||||
return svgedit.utilities.bboxToObj(bbox); // need this for QUnit equal() to work.
|
||||
}
|
||||
|
||||
var bbox;
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'path',
|
||||
'attr': {'id': 'path', 'd': 'M0,1 Z'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
bbox = getBBoxOfElementAsPath(elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
deepEqual(bbox, {x: 0, y: 1, width: 0, height: 0});
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
bbox = getBBoxOfElementAsPath(elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
deepEqual(bbox, {x: 0, y: 1, width: 5, height: 10});
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
'element': 'line',
|
||||
'attr': {'id': 'line', 'x1': '0', 'y1': '1', 'x2': '5', 'y2': '6'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
bbox = getBBoxOfElementAsPath(elem, mockAddSvgElementFromJson, mockPathActions);
|
||||
deepEqual(bbox, {x: 0, y: 1, width: 5, height: 5});
|
||||
svgroot.removeChild(elem);
|
||||
|
||||
// TODO: test element with transform. Need resetOrientation above to be working or mock it.
|
||||
});
|
||||
|
||||
test('Test convertToPath rect', function () {
|
||||
var convertToPath = svgedit.utilities.convertToPath;
|
||||
var attrs = {
|
||||
'fill': 'red',
|
||||
'stroke': 'white',
|
||||
'stroke-width': '1',
|
||||
'visibility': 'hidden'
|
||||
};
|
||||
|
||||
var elem = mockCreateSVGElement({
|
||||
'element': 'rect',
|
||||
'attr': {'id': 'rect', 'x': '0', 'y': '1', 'width': '5', 'height': '10'}
|
||||
});
|
||||
svgroot.appendChild(elem);
|
||||
var path = convertToPath(elem, attrs, mockAddSvgElementFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory);
|
||||
equal(path.getAttribute('d'), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z');
|
||||
equal(path.getAttribute('visibilituy'), null);
|
||||
equal(path.id, 'rect');
|
||||
equal(path.parentNode, svgroot);
|
||||
equal(elem.parentNode, null);
|
||||
equal(mockHistorySubCommands.length, 2);
|
||||
equal(mockCount.clearSelection, 1);
|
||||
equal(mockCount.addToSelection, 1);
|
||||
equal(mockCount.addCommandToHistory, 1);
|
||||
svgroot.removeChild(path);
|
||||
});
|
||||
|
||||
test('Test convertToPath unknown element', function () {
|
||||
var convertToPath = svgedit.utilities.convertToPath;
|
||||
var attrs = {
|
||||
'fill': 'red',
|
||||
'stroke': 'white',
|
||||
'stroke-width': '1',
|
||||
'visibility': 'hidden'
|
||||
};
|
||||
|
||||
var elem = {
|
||||
tagName: 'something unknown',
|
||||
id: 'something-unknown',
|
||||
getAttribute: function (attr) { return ''; },
|
||||
parentNode: svgroot
|
||||
};
|
||||
var path = convertToPath(elem, attrs, mockAddSvgElementFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory);
|
||||
equal(path, null);
|
||||
equal(elem.parentNode, svgroot);
|
||||
equal(mockHistorySubCommands.length, 0);
|
||||
equal(mockCount.clearSelection, 0);
|
||||
equal(mockCount.addToSelection, 0);
|
||||
equal(mockCount.addCommandToHistory, 0);
|
||||
});
|
||||
});
|
||||
247
test/test1.html
247
test/test1.html
@@ -26,252 +26,7 @@
|
||||
<script src="../editor/svg-editor.js"></script>
|
||||
<script src="../editor/locale/locale.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
// helper functions
|
||||
var isIdentity = function(m) {
|
||||
return (m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 && m.e == 0 && m.f == 0);
|
||||
};
|
||||
var matrixString = function(m) {
|
||||
return [m.a,m.b,m.c,m.d,m.e,m.f].join(',');
|
||||
}
|
||||
|
||||
var svgCanvas = new $.SvgCanvas(document.getElementById("svgcanvas"), {
|
||||
canvas_expansion: 3,
|
||||
dimensions: [640,480],
|
||||
initFill: {
|
||||
color: 'FF0000', // solid red
|
||||
opacity: 1
|
||||
},
|
||||
initStroke: {
|
||||
width: 5,
|
||||
color: '000000', // solid black
|
||||
opacity: 1
|
||||
},
|
||||
initOpacity: 1,
|
||||
imgPath: 'images/',
|
||||
langPath: 'locale/',
|
||||
extPath: 'extensions/',
|
||||
extensions: ['ext-arrows.js', 'ext-connector.js', 'ext-eyedropper.js'],
|
||||
initTool: 'select',
|
||||
wireframe: false
|
||||
}),
|
||||
svgroot = document.getElementById("svgroot"),
|
||||
svgdoc = svgroot.documentElement,
|
||||
svgns = "http://www.w3.org/2000/svg",
|
||||
xlinkns = "http://www.w3.org/1999/xlink";
|
||||
|
||||
module("Basic Module");
|
||||
|
||||
test("Test existence of SvgCanvas object", function() {
|
||||
expect(1);
|
||||
equal(typeof {}, typeof svgCanvas);
|
||||
});
|
||||
|
||||
module("Path Module");
|
||||
|
||||
test("Test path conversion from absolute to relative", function() {
|
||||
expect(6);
|
||||
var convert = svgCanvas.pathActions.convertPath;
|
||||
|
||||
// TODO: Test these paths:
|
||||
// "m400.00491,625.01379a1.78688,1.78688 0 1 1-3.57373,0a1.78688,1.78688 0 1 13.57373,0z"
|
||||
// "m36.812,15.8566c-28.03099,0 -26.28099,12.15601 -26.28099,12.15601l0.03099,12.59399h26.75v3.781h-37.37399c0,0 -17.938,-2.034 -133.00001,26.25c115.06201,28.284 130.71801,27.281 130.71801,27.281h9.34399v-13.125c0,0 -0.504,-15.656 15.40601,-15.656h26.532c0,0 14.90599,0.241 14.90599,-14.406v-24.219c0,0 2.263,-14.65601 -27.032,-14.65601zm-14.75,8.4684c2.662,0 4.813,2.151 4.813,4.813c0,2.661 -2.151,4.812 -4.813,4.812c-2.661,0 -4.812,-2.151 -4.812,-4.812c0,-2.662 2.151,-4.813 4.812,-4.813z"
|
||||
// "m 0,0 l 200,0 l 0,100 L 0,100"
|
||||
|
||||
svgCanvas.setSvgString("<svg xmlns='http://www.w3.org/2000/svg' width='400' x='300'>" +
|
||||
"<path id='p1' d='M100,100 L200,100 L100,100Z'/>" +
|
||||
"<path id='p2' d='m 0,0 l 200,0 l 0,100 L 0,100'/>" +
|
||||
"</svg>");
|
||||
|
||||
var p1 = document.getElementById("p1"),
|
||||
p2 = document.getElementById("p2"),
|
||||
d_abs = p1.getAttribute("d"),
|
||||
seglist = p1.pathSegList,
|
||||
curseg = null;
|
||||
|
||||
equal(p1.nodeName, "path", "Expected 'path', got");
|
||||
|
||||
equal(seglist.numberOfItems, 4, "Number of segments before conversion");
|
||||
|
||||
// verify segments before conversion
|
||||
curseg = seglist.getItem(0);
|
||||
equal(curseg.pathSegTypeAsLetter.toUpperCase(), "M", "Before conversion, segment #1 type");
|
||||
curseg = seglist.getItem(1);
|
||||
equal(curseg.pathSegTypeAsLetter.toUpperCase(), "L", "Before conversion, segment #2 type");
|
||||
curseg = seglist.getItem(3);
|
||||
equal(curseg.pathSegTypeAsLetter.toUpperCase(), "Z", "Before conversion, segment #3 type" + d_abs);
|
||||
|
||||
// convert and verify segments
|
||||
var d = convert(p1, true);
|
||||
equal(d, "m100,100l100,0l-100,0z", "Converted path to relative string");
|
||||
|
||||
// TODO: see why this isn't working in SVG-edit
|
||||
d = convert(p2, true);
|
||||
QUnit.log({result: d});
|
||||
d = convert(p2, false);
|
||||
QUnit.log({result: d});
|
||||
});
|
||||
|
||||
module("Import Module");
|
||||
|
||||
test("Test import use", function() {
|
||||
expect(3);
|
||||
|
||||
svgCanvas.setSvgString("<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='400' x='300'>" +
|
||||
"<rect id='the-rect' width='200' height='200'/>" +
|
||||
"<use id='the-use' xlink:href='#the-rect'/>" +
|
||||
"<use id='foreign-use' xlink:href='somefile.svg#the-rect'/>" +
|
||||
"<use id='no-use'/>" +
|
||||
"</svg>");
|
||||
|
||||
var u = document.getElementById("the-use"),
|
||||
fu = document.getElementById("foreign-use"),
|
||||
nfu = document.getElementById("no-use");
|
||||
|
||||
equal((u && u.nodeName == "use"), true, "Did not import <use> element");
|
||||
equal(fu, null, "Removed <use> element that had a foreign href");
|
||||
equal(nfu, null, "Removed <use> element that had no href");
|
||||
});
|
||||
|
||||
// This test shows that an element with an invalid attribute is still parsed in properly
|
||||
// and only the attribute is not imported
|
||||
test("Test invalid attribute", function() {
|
||||
expect(2);
|
||||
|
||||
svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">'+
|
||||
'<text x="182.75" y="173.5" id="the-text" fill="#008000" font-size="150" font-family="serif" text-anchor="middle" d="M116,222 L110,108">words</text>' +
|
||||
'</svg>');
|
||||
|
||||
var t = document.getElementById("the-text");
|
||||
|
||||
equal(true, (t && t.nodeName == "text"), "Did not import <text> element");
|
||||
equal(null, t.getAttribute("d"), "Imported a <text> with a d attribute");
|
||||
});
|
||||
|
||||
// This test makes sure import/export properly handles namespaced attributes
|
||||
test("Test importing/exporting namespaced attributes", function() {
|
||||
expect(5);
|
||||
var setStr = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:se="http://svg-edit.googlecode.com" xmlns:foo="http://example.com">'+
|
||||
'<image xlink:href="../editor/images/logo.png"/>' +
|
||||
'<polyline id="se_test_elem" se:foo="bar" foo:bar="baz"/>' +
|
||||
'</svg>');
|
||||
var attrVal = document.getElementById('se_test_elem').getAttributeNS("http://svg-edit.googlecode.com", "foo");
|
||||
|
||||
equal(attrVal === "bar", true, "Preserved namespaced attribute on import");
|
||||
//
|
||||
//console.log('getSvgString' in svgCanvas)
|
||||
|
||||
var output = svgCanvas.getSvgString();
|
||||
//} catch(e) {console.log(e)}
|
||||
//console.log('output',output);
|
||||
var has_xlink = output.indexOf('xmlns:xlink="http://www.w3.org/1999/xlink"') !== -1;
|
||||
var has_se = output.indexOf('xmlns:se=') !== -1;
|
||||
var has_foo = output.indexOf('xmlns:foo=') !== -1;
|
||||
var has_attr = output.indexOf('se:foo="bar"') !== -1;
|
||||
|
||||
equal(has_attr, true, "Preserved namespaced attribute on export");
|
||||
equal(has_xlink, true, "Included xlink: xmlns");
|
||||
equal(has_se, true, "Included se: xmlns");
|
||||
equal(has_foo, false, "Did not include foo: xmlns");
|
||||
});
|
||||
|
||||
test("Test import math elements inside a foreignObject", function() {
|
||||
expect(4);
|
||||
var set = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:se="http://svg-edit.googlecode.com" xmlns:xlink="http://www.w3.org/1999/xlink">'+
|
||||
'<foreignObject id="fo" width="24" height="26" font-size="24"><math id="m" display="inline" xmlns="http://www.w3.org/1998/Math/MathML">'+
|
||||
'<msub>'+
|
||||
'<mi>A</mi>'+
|
||||
'<mn>0</mn>'+
|
||||
'</msub>'+
|
||||
'</math>'+
|
||||
'</foreignObject>'+
|
||||
'</svg>');
|
||||
var fo = document.getElementById('fo');
|
||||
// we cannot use getElementById('math') because not all browsers understand MathML and do not know to use the @id attribute
|
||||
// see Bug https://bugs.webkit.org/show_bug.cgi?id=35042
|
||||
var math = fo.firstChild;
|
||||
|
||||
equal(!!math, true, "Math element exists");
|
||||
equal(math.nodeName, 'math', "Math element has the proper nodeName");
|
||||
equal(math.getAttribute('id'), 'm', "Math element has an id");
|
||||
equal(math.namespaceURI, "http://www.w3.org/1998/Math/MathML", "Preserved MathML namespace");
|
||||
});
|
||||
|
||||
test("Test importing SVG into existing drawing", function() {
|
||||
expect(3);
|
||||
|
||||
var doc = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">'+
|
||||
'<g><title>Layer 1</title>'+
|
||||
'<circle cx="200" cy="200" r="50" fill="blue"/>'+
|
||||
'<ellipse cx="300" cy="100" rx="40" ry="30" fill="green"/>'+
|
||||
'</g>'+
|
||||
'</svg>');
|
||||
|
||||
svgCanvas.importSvgString('<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">'+
|
||||
'<circle cx="50" cy="50" r="40" fill="yellow"/>'+
|
||||
'<rect width="20" height="20" fill="blue"/>'+
|
||||
'</svg>');
|
||||
|
||||
var svgcontent = document.getElementById("svgcontent"),
|
||||
circles = svgcontent.getElementsByTagNameNS(svgns, "circle"),
|
||||
rects = svgcontent.getElementsByTagNameNS(svgns, "rect"),
|
||||
ellipses = svgcontent.getElementsByTagNameNS(svgns, "ellipse");
|
||||
equal(circles.length, 2, "Found two circles upon importing");
|
||||
equal(rects.length, 1, "Found one rectangle upon importing");
|
||||
equal(ellipses.length, 1, "Found one ellipse upon importing");
|
||||
});
|
||||
|
||||
test("Test importing SVG remaps IDs", function() {
|
||||
expect(6);
|
||||
|
||||
var doc = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">'+
|
||||
'<g><title>Layer 1</title>'+
|
||||
'<ellipse id="svg_1" cx="200" cy="200" rx="50" ry="20" fill="blue"/>'+
|
||||
'<ellipse id="svg_2" cx="300" cy="100" rx="40" ry="30" fill="green"/>'+
|
||||
'<ellipse id="svg_3" cx="300" cy="100" rx="40" ry="30" fill="green"/>'+
|
||||
'</g>'+
|
||||
'</svg>');
|
||||
|
||||
svgCanvas.importSvgString('<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink">'+
|
||||
'<defs>'+
|
||||
'<linearGradient id="svg_2">'+
|
||||
'<stop stop-color="red" offset="0"/>'+
|
||||
'<stop stop-color="green" offset="1"/>'+
|
||||
'</linearGradient>'+
|
||||
'<rect id="svg_3" width="20" height="20" fill="blue" stroke="url(#svg_2)"/>'+
|
||||
'</defs>'+
|
||||
'<circle id="svg_1" cx="50" cy="50" r="40" fill="url(#svg_2)"/>'+
|
||||
'<use id="svg_4" width="30" height="30" xl:href="#svg_3"/>'+
|
||||
'</svg>');
|
||||
|
||||
var svgcontent = document.getElementById("svgcontent"),
|
||||
circles = svgcontent.getElementsByTagNameNS(svgns, "circle"),
|
||||
rects = svgcontent.getElementsByTagNameNS(svgns, "rect"),
|
||||
ellipses = svgcontent.getElementsByTagNameNS(svgns, "ellipse"),
|
||||
defs = svgcontent.getElementsByTagNameNS(svgns, "defs"),
|
||||
grads = svgcontent.getElementsByTagNameNS(svgns, "linearGradient"),
|
||||
uses = svgcontent.getElementsByTagNameNS(svgns, "use");
|
||||
notEqual(circles.item(0).id, "svg_1", "Circle not re-identified");
|
||||
notEqual(rects.item(0).id, "svg_3", "Rectangle not re-identified");
|
||||
// TODO: determine why this test fails in WebKit browsers
|
||||
//equal(grads.length, 1, "Linear gradient imported");
|
||||
var grad = defs.item(0).firstChild;
|
||||
notEqual(grad.id, "svg_2", "Linear gradient not re-identified");
|
||||
notEqual(circles.item(0).getAttribute("fill"), "url(#svg_2)", "Circle fill value not remapped");
|
||||
notEqual(rects.item(0).getAttribute("stroke"), "url(#svg_2)", "Rectangle stroke value not remapped");
|
||||
notEqual(uses.item(0).getAttributeNS(xlinkns, "href"), "#svg_3");
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<script src="test1.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for SvgCanvas</h1>
|
||||
|
||||
247
test/test1.js
Normal file
247
test/test1.js
Normal file
@@ -0,0 +1,247 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $ */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
// helper functions
|
||||
var isIdentity = function (m) {
|
||||
return (m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1 && m.e === 0 && m.f === 0);
|
||||
};
|
||||
var matrixString = function (m) {
|
||||
return [m.a, m.b, m.c, m.d, m.e, m.f].join(',');
|
||||
};
|
||||
|
||||
var svgCanvas = new $.SvgCanvas(
|
||||
document.getElementById('svgcanvas'), {
|
||||
canvas_expansion: 3,
|
||||
dimensions: [640,480],
|
||||
initFill: {
|
||||
color: 'FF0000', // solid red
|
||||
opacity: 1
|
||||
},
|
||||
initStroke: {
|
||||
width: 5,
|
||||
color: '000000', // solid black
|
||||
opacity: 1
|
||||
},
|
||||
initOpacity: 1,
|
||||
imgPath: 'images/',
|
||||
langPath: 'locale/',
|
||||
extPath: 'extensions/',
|
||||
extensions: ['ext-arrows.js', 'ext-connector.js', 'ext-eyedropper.js'],
|
||||
initTool: 'select',
|
||||
wireframe: false
|
||||
}),
|
||||
svgroot = document.getElementById("svgroot"),
|
||||
svgdoc = svgroot.documentElement,
|
||||
svgns = "http://www.w3.org/2000/svg",
|
||||
xlinkns = "http://www.w3.org/1999/xlink";
|
||||
|
||||
module("Basic Module");
|
||||
|
||||
test("Test existence of SvgCanvas object", function() {
|
||||
expect(1);
|
||||
equal(typeof {}, typeof svgCanvas);
|
||||
});
|
||||
|
||||
module("Path Module");
|
||||
|
||||
test("Test path conversion from absolute to relative", function() {
|
||||
expect(6);
|
||||
var convert = svgCanvas.pathActions.convertPath;
|
||||
|
||||
// TODO: Test these paths:
|
||||
// "m400.00491,625.01379a1.78688,1.78688 0 1 1-3.57373,0a1.78688,1.78688 0 1 13.57373,0z"
|
||||
// "m36.812,15.8566c-28.03099,0 -26.28099,12.15601 -26.28099,12.15601l0.03099,12.59399h26.75v3.781h-37.37399c0,0 -17.938,-2.034 -133.00001,26.25c115.06201,28.284 130.71801,27.281 130.71801,27.281h9.34399v-13.125c0,0 -0.504,-15.656 15.40601,-15.656h26.532c0,0 14.90599,0.241 14.90599,-14.406v-24.219c0,0 2.263,-14.65601 -27.032,-14.65601zm-14.75,8.4684c2.662,0 4.813,2.151 4.813,4.813c0,2.661 -2.151,4.812 -4.813,4.812c-2.661,0 -4.812,-2.151 -4.812,-4.812c0,-2.662 2.151,-4.813 4.812,-4.813z"
|
||||
// "m 0,0 l 200,0 l 0,100 L 0,100"
|
||||
|
||||
svgCanvas.setSvgString("<svg xmlns='http://www.w3.org/2000/svg' width='400' x='300'>" +
|
||||
"<path id='p1' d='M100,100 L200,100 L100,100Z'/>" +
|
||||
"<path id='p2' d='m 0,0 l 200,0 l 0,100 L 0,100'/>" +
|
||||
"</svg>");
|
||||
|
||||
var p1 = document.getElementById("p1"),
|
||||
p2 = document.getElementById("p2"),
|
||||
d_abs = p1.getAttribute("d"),
|
||||
seglist = p1.pathSegList,
|
||||
curseg = null;
|
||||
|
||||
equal(p1.nodeName, "path", "Expected 'path', got");
|
||||
|
||||
equal(seglist.numberOfItems, 4, "Number of segments before conversion");
|
||||
|
||||
// verify segments before conversion
|
||||
curseg = seglist.getItem(0);
|
||||
equal(curseg.pathSegTypeAsLetter.toUpperCase(), 'M', 'Before conversion, segment #1 type');
|
||||
curseg = seglist.getItem(1);
|
||||
equal(curseg.pathSegTypeAsLetter.toUpperCase(), 'L', 'Before conversion, segment #2 type');
|
||||
curseg = seglist.getItem(3);
|
||||
equal(curseg.pathSegTypeAsLetter.toUpperCase(), 'Z', 'Before conversion, segment #3 type' + d_abs);
|
||||
|
||||
// convert and verify segments
|
||||
var d = convert(p1, true);
|
||||
equal(d, 'm100,100l100,0l-100,0z', 'Converted path to relative string');
|
||||
|
||||
// TODO: see why this isn't working in SVG-edit
|
||||
d = convert(p2, true);
|
||||
QUnit.log({result: d});
|
||||
d = convert(p2, false);
|
||||
QUnit.log({result: d});
|
||||
});
|
||||
|
||||
module('Import Module');
|
||||
|
||||
test('Test import use', function() {
|
||||
expect(3);
|
||||
|
||||
svgCanvas.setSvgString("<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='400' x='300'>" +
|
||||
"<rect id='the-rect' width='200' height='200'/>" +
|
||||
"<use id='the-use' xlink:href='#the-rect'/>" +
|
||||
"<use id='foreign-use' xlink:href='somefile.svg#the-rect'/>" +
|
||||
"<use id='no-use'/>" +
|
||||
"</svg>");
|
||||
|
||||
var u = document.getElementById("the-use"),
|
||||
fu = document.getElementById("foreign-use"),
|
||||
nfu = document.getElementById("no-use");
|
||||
|
||||
equal((u && u.nodeName == 'use'), true, 'Did not import <use> element');
|
||||
equal(fu, null, 'Removed <use> element that had a foreign href');
|
||||
equal(nfu, null, 'Removed <use> element that had no href');
|
||||
});
|
||||
|
||||
// This test shows that an element with an invalid attribute is still parsed in properly
|
||||
// and only the attribute is not imported
|
||||
test('Test invalid attribute', function() {
|
||||
expect(2);
|
||||
|
||||
svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">'+
|
||||
'<text x="182.75" y="173.5" id="the-text" fill="#008000" font-size="150" font-family="serif" text-anchor="middle" d="M116,222 L110,108">words</text>' +
|
||||
'</svg>');
|
||||
|
||||
var t = document.getElementById('the-text');
|
||||
|
||||
equal(true, (t && t.nodeName === 'text'), 'Did not import <text> element');
|
||||
equal(null, t.getAttribute("d"), "Imported a <text> with a d attribute");
|
||||
});
|
||||
|
||||
// This test makes sure import/export properly handles namespaced attributes
|
||||
test("Test importing/exporting namespaced attributes", function() {
|
||||
expect(5);
|
||||
var setStr = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:se="http://svg-edit.googlecode.com" xmlns:foo="http://example.com">'+
|
||||
'<image xlink:href="../editor/images/logo.png"/>' +
|
||||
'<polyline id="se_test_elem" se:foo="bar" foo:bar="baz"/>' +
|
||||
'</svg>');
|
||||
var attrVal = document.getElementById('se_test_elem').getAttributeNS("http://svg-edit.googlecode.com", "foo");
|
||||
|
||||
equal(attrVal === "bar", true, "Preserved namespaced attribute on import");
|
||||
//
|
||||
//console.log('getSvgString' in svgCanvas)
|
||||
|
||||
var output = svgCanvas.getSvgString();
|
||||
//} catch(e) {console.log(e)}
|
||||
//console.log('output',output);
|
||||
var has_xlink = output.indexOf('xmlns:xlink="http://www.w3.org/1999/xlink"') !== -1;
|
||||
var has_se = output.indexOf('xmlns:se=') !== -1;
|
||||
var has_foo = output.indexOf('xmlns:foo=') !== -1;
|
||||
var has_attr = output.indexOf('se:foo="bar"') !== -1;
|
||||
|
||||
equal(has_attr, true, "Preserved namespaced attribute on export");
|
||||
equal(has_xlink, true, "Included xlink: xmlns");
|
||||
equal(has_se, true, "Included se: xmlns");
|
||||
equal(has_foo, false, "Did not include foo: xmlns");
|
||||
});
|
||||
|
||||
test("Test import math elements inside a foreignObject", function() {
|
||||
expect(4);
|
||||
var set = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:se="http://svg-edit.googlecode.com" xmlns:xlink="http://www.w3.org/1999/xlink">'+
|
||||
'<foreignObject id="fo" width="24" height="26" font-size="24"><math id="m" display="inline" xmlns="http://www.w3.org/1998/Math/MathML">'+
|
||||
'<msub>'+
|
||||
'<mi>A</mi>'+
|
||||
'<mn>0</mn>'+
|
||||
'</msub>'+
|
||||
'</math>'+
|
||||
'</foreignObject>'+
|
||||
'</svg>');
|
||||
var fo = document.getElementById('fo');
|
||||
// we cannot use getElementById('math') because not all browsers understand MathML and do not know to use the @id attribute
|
||||
// see Bug https://bugs.webkit.org/show_bug.cgi?id=35042
|
||||
var math = fo.firstChild;
|
||||
|
||||
equal(!!math, true, "Math element exists");
|
||||
equal(math.nodeName, 'math', "Math element has the proper nodeName");
|
||||
equal(math.getAttribute('id'), 'm', "Math element has an id");
|
||||
equal(math.namespaceURI, "http://www.w3.org/1998/Math/MathML", "Preserved MathML namespace");
|
||||
});
|
||||
|
||||
test("Test importing SVG into existing drawing", function() {
|
||||
expect(3);
|
||||
|
||||
var doc = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">'+
|
||||
'<g><title>Layer 1</title>'+
|
||||
'<circle cx="200" cy="200" r="50" fill="blue"/>'+
|
||||
'<ellipse cx="300" cy="100" rx="40" ry="30" fill="green"/>'+
|
||||
'</g>'+
|
||||
'</svg>');
|
||||
|
||||
svgCanvas.importSvgString('<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">'+
|
||||
'<circle cx="50" cy="50" r="40" fill="yellow"/>'+
|
||||
'<rect width="20" height="20" fill="blue"/>'+
|
||||
'</svg>');
|
||||
|
||||
var svgcontent = document.getElementById("svgcontent"),
|
||||
circles = svgcontent.getElementsByTagNameNS(svgns, "circle"),
|
||||
rects = svgcontent.getElementsByTagNameNS(svgns, "rect"),
|
||||
ellipses = svgcontent.getElementsByTagNameNS(svgns, "ellipse");
|
||||
equal(circles.length, 2, "Found two circles upon importing");
|
||||
equal(rects.length, 1, "Found one rectangle upon importing");
|
||||
equal(ellipses.length, 1, "Found one ellipse upon importing");
|
||||
});
|
||||
|
||||
test("Test importing SVG remaps IDs", function() {
|
||||
expect(6);
|
||||
|
||||
var doc = svgCanvas.setSvgString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">'+
|
||||
'<g><title>Layer 1</title>'+
|
||||
'<ellipse id="svg_1" cx="200" cy="200" rx="50" ry="20" fill="blue"/>'+
|
||||
'<ellipse id="svg_2" cx="300" cy="100" rx="40" ry="30" fill="green"/>'+
|
||||
'<ellipse id="svg_3" cx="300" cy="100" rx="40" ry="30" fill="green"/>'+
|
||||
'</g>'+
|
||||
'</svg>');
|
||||
|
||||
svgCanvas.importSvgString('<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink">'+
|
||||
'<defs>'+
|
||||
'<linearGradient id="svg_2">'+
|
||||
'<stop stop-color="red" offset="0"/>'+
|
||||
'<stop stop-color="green" offset="1"/>'+
|
||||
'</linearGradient>'+
|
||||
'<rect id="svg_3" width="20" height="20" fill="blue" stroke="url(#svg_2)"/>'+
|
||||
'</defs>'+
|
||||
'<circle id="svg_1" cx="50" cy="50" r="40" fill="url(#svg_2)"/>'+
|
||||
'<use id="svg_4" width="30" height="30" xl:href="#svg_3"/>'+
|
||||
'</svg>');
|
||||
|
||||
var svgcontent = document.getElementById("svgcontent"),
|
||||
circles = svgcontent.getElementsByTagNameNS(svgns, "circle"),
|
||||
rects = svgcontent.getElementsByTagNameNS(svgns, "rect"),
|
||||
ellipses = svgcontent.getElementsByTagNameNS(svgns, "ellipse"),
|
||||
defs = svgcontent.getElementsByTagNameNS(svgns, "defs"),
|
||||
grads = svgcontent.getElementsByTagNameNS(svgns, "linearGradient"),
|
||||
uses = svgcontent.getElementsByTagNameNS(svgns, "use");
|
||||
notEqual(circles.item(0).id, "svg_1", "Circle not re-identified");
|
||||
notEqual(rects.item(0).id, "svg_3", "Rectangle not re-identified");
|
||||
// TODO: determine why this test fails in WebKit browsers
|
||||
//equal(grads.length, 1, "Linear gradient imported");
|
||||
var grad = defs.item(0).firstChild;
|
||||
notEqual(grad.id, "svg_2", "Linear gradient not re-identified");
|
||||
notEqual(circles.item(0).getAttribute("fill"), "url(#svg_2)", "Circle fill value not remapped");
|
||||
notEqual(rects.item(0).getAttribute("stroke"), "url(#svg_2)", "Rectangle stroke value not remapped");
|
||||
notEqual(uses.item(0).getAttributeNS(xlinkns, "href"), "#svg_3");
|
||||
});
|
||||
});
|
||||
@@ -8,88 +8,7 @@
|
||||
<script src="../editor/svgedit.js"></script>
|
||||
<script src="../editor/units.js"></script>
|
||||
<script src="qunit/qunit.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
// log function
|
||||
QUnit.log = function(details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result +' :: '+ details.message);
|
||||
}
|
||||
};
|
||||
|
||||
function setUp() {
|
||||
svgedit.units.init({
|
||||
getBaseUnit: function() { return "cm"; },
|
||||
getHeight: function() { return 600; },
|
||||
getWidth: function() { return 800; },
|
||||
getRoundDigits: function() { return 4; },
|
||||
getElement: function(elementId){ return document.getElementById(elementId); }
|
||||
});
|
||||
}
|
||||
|
||||
test('Test svgedit.units package', function() {
|
||||
expect(2);
|
||||
ok(svgedit.units);
|
||||
equals(typeof svgedit.units, typeof {});
|
||||
});
|
||||
|
||||
test('Test svgedit.units.shortFloat()', function() {
|
||||
expect(7);
|
||||
|
||||
setUp();
|
||||
|
||||
ok(svgedit.units.shortFloat);
|
||||
equals(typeof svgedit.units.shortFloat, typeof function(){});
|
||||
|
||||
var shortFloat = svgedit.units.shortFloat;
|
||||
equals(shortFloat(0.00000001), 0);
|
||||
equals(shortFloat(1), 1);
|
||||
equals(shortFloat(3.45678), 3.4568);
|
||||
equals(shortFloat(1.23443), 1.2344);
|
||||
equals(shortFloat(1.23455), 1.2346);
|
||||
});
|
||||
|
||||
test('Test svgedit.units.isValidUnit()', function() {
|
||||
expect(18);
|
||||
|
||||
setUp();
|
||||
|
||||
ok(svgedit.units.isValidUnit);
|
||||
equals(typeof svgedit.units.isValidUnit, typeof function(){});
|
||||
|
||||
var isValidUnit = svgedit.units.isValidUnit;
|
||||
ok(isValidUnit("0"));
|
||||
ok(isValidUnit("1"));
|
||||
ok(isValidUnit("1.1"));
|
||||
ok(isValidUnit("-1.1"));
|
||||
ok(isValidUnit(".6mm"));
|
||||
ok(isValidUnit("-.6cm"));
|
||||
ok(isValidUnit("6000in"));
|
||||
ok(isValidUnit("6px"));
|
||||
ok(isValidUnit("6.3pc"));
|
||||
ok(isValidUnit("-0.4em"));
|
||||
ok(isValidUnit("-0.ex"));
|
||||
ok(isValidUnit("40.123%"));
|
||||
|
||||
equals(isValidUnit("id","uniqueId",document.getElementById("uniqueId")), true);
|
||||
equals(isValidUnit("id","newId",document.getElementById("uniqueId")), true);
|
||||
equals(isValidUnit("id","uniqueId"), false);
|
||||
equals(isValidUnit("id","uniqueId",document.getElementById("nonUniqueId")), false);
|
||||
});
|
||||
|
||||
test('Test svgedit.units.convertUnit()', function() {
|
||||
expect(4);
|
||||
|
||||
setUp();
|
||||
|
||||
ok(svgedit.units.convertUnit);
|
||||
equals(typeof svgedit.units.convertUnit, typeof function(){});
|
||||
// cm in default setup
|
||||
equals(svgedit.units.convertUnit(42), 1.1113);
|
||||
equals(svgedit.units.convertUnit(42, 'px'), 42);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script src="units_test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit Tests for units.js</h1>
|
||||
|
||||
83
test/units_test.js
Normal file
83
test/units_test.js
Normal file
@@ -0,0 +1,83 @@
|
||||
/* eslint-env qunit */
|
||||
/* globals $, svgedit, equals */
|
||||
/* eslint-disable no-var */
|
||||
$(function () {
|
||||
// log function
|
||||
QUnit.log = function (details) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(details.result + ' :: ' + details.message);
|
||||
}
|
||||
};
|
||||
|
||||
function setUp () {
|
||||
svgedit.units.init({
|
||||
getBaseUnit: function () { return 'cm'; },
|
||||
getHeight: function () { return 600; },
|
||||
getWidth: function () { return 800; },
|
||||
getRoundDigits: function () { return 4; },
|
||||
getElement: function (elementId) { return document.getElementById(elementId); }
|
||||
});
|
||||
}
|
||||
|
||||
test('Test svgedit.units package', function () {
|
||||
expect(2);
|
||||
ok(svgedit.units);
|
||||
equals(typeof svgedit.units, typeof {});
|
||||
});
|
||||
|
||||
test('Test svgedit.units.shortFloat()', function () {
|
||||
expect(7);
|
||||
|
||||
setUp();
|
||||
|
||||
ok(svgedit.units.shortFloat);
|
||||
equals(typeof svgedit.units.shortFloat, typeof function () {});
|
||||
|
||||
var shortFloat = svgedit.units.shortFloat;
|
||||
equals(shortFloat(0.00000001), 0);
|
||||
equals(shortFloat(1), 1);
|
||||
equals(shortFloat(3.45678), 3.4568);
|
||||
equals(shortFloat(1.23443), 1.2344);
|
||||
equals(shortFloat(1.23455), 1.2346);
|
||||
});
|
||||
|
||||
test('Test svgedit.units.isValidUnit()', function () {
|
||||
expect(18);
|
||||
|
||||
setUp();
|
||||
|
||||
ok(svgedit.units.isValidUnit);
|
||||
equals(typeof svgedit.units.isValidUnit, typeof function () {});
|
||||
|
||||
var isValidUnit = svgedit.units.isValidUnit;
|
||||
ok(isValidUnit('0'));
|
||||
ok(isValidUnit('1'));
|
||||
ok(isValidUnit('1.1'));
|
||||
ok(isValidUnit('-1.1'));
|
||||
ok(isValidUnit('.6mm'));
|
||||
ok(isValidUnit('-.6cm'));
|
||||
ok(isValidUnit('6000in'));
|
||||
ok(isValidUnit('6px'));
|
||||
ok(isValidUnit('6.3pc'));
|
||||
ok(isValidUnit('-0.4em'));
|
||||
ok(isValidUnit('-0.ex'));
|
||||
ok(isValidUnit('40.123%'));
|
||||
|
||||
equals(isValidUnit('id', 'uniqueId', document.getElementById('uniqueId')), true);
|
||||
equals(isValidUnit('id', 'newId', document.getElementById('uniqueId')), true);
|
||||
equals(isValidUnit('id', 'uniqueId'), false);
|
||||
equals(isValidUnit('id', 'uniqueId', document.getElementById('nonUniqueId')), false);
|
||||
});
|
||||
|
||||
test('Test svgedit.units.convertUnit()', function () {
|
||||
expect(4);
|
||||
|
||||
setUp();
|
||||
|
||||
ok(svgedit.units.convertUnit);
|
||||
equals(typeof svgedit.units.convertUnit, typeof function () {});
|
||||
// cm in default setup
|
||||
equals(svgedit.units.convertUnit(42), 1.1113);
|
||||
equals(svgedit.units.convertUnit(42, 'px'), 42);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user