2010-02-06 04:36:35 +01:00
< html >
< head >
< link rel = "stylesheet" href = "qunit/qunit.css" type = "text/css" / >
2010-02-17 21:28:00 +01:00
< script src = "../editor/jquery.js" > < / script >
2010-02-06 04:36:35 +01:00
< script type = "text/javascript" src = "../editor/svgicons/jquery.svgicons.js" > < / script >
< script type = "text/javascript" src = "../editor/locale/locale.js" > < / script >
< script type = "text/javascript" src = "../editor/svgcanvas.js" > < / script >
< script type = "text/javascript" src = "qunit/qunit.js" > < / script >
< script type = "text/javascript" >
$(function() {
// log function
QUnit.log = function(result, message) {
if (window.console & & window.console.log) {
window.console.log(result +' :: '+ 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")),
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);
2010-02-23 01:53:15 +01:00
equal(typeof {}, typeof svgCanvas);
2010-02-06 04:36:35 +01:00
});
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"
2010-02-10 18:37:26 +01:00
// "m 0,0 l 200,0 l 0,100 L 0,100"
2010-02-06 04:36:35 +01:00
svgCanvas.setSvgString("< svg xmlns = 'http://www.w3.org/2000/svg' width = '400' x = '300' > " +
"< path id = 'p1' d = 'M100,100 L200,100 Z' / > " +
2010-02-10 18:37:26 +01:00
"< path id = 'p2' d = 'm 0,0 l 200,0 l 0,100 L 0,100' / > " +
2010-02-06 04:36:35 +01:00
"< / svg > ");
var p1 = document.getElementById("p1"),
p2 = document.getElementById("p2"),
d_abs = p1.getAttribute("d"),
seglist = p1.pathSegList,
curseg = null;
2010-02-23 01:53:15 +01:00
equal(p1.nodeName, "path", "Expected 'path', got");
2010-02-06 04:36:35 +01:00
2010-02-23 01:53:15 +01:00
equal(seglist.numberOfItems, 3, "Number of segments before conversion");
2010-02-06 04:36:35 +01:00
// verify segments before conversion
curseg = seglist.getItem(0);
2010-02-23 01:53:15 +01:00
equal(curseg.pathSegTypeAsLetter, "M", "Before conversion, segment #1 type");
2010-02-06 04:36:35 +01:00
curseg = seglist.getItem(1);
2010-02-23 01:53:15 +01:00
equal(curseg.pathSegTypeAsLetter, "L", "Before conversion, segment #2 type");
2010-02-06 04:36:35 +01:00
curseg = seglist.getItem(2);
2010-02-23 01:53:15 +01:00
equal(curseg.pathSegType, 1, "Before conversion, segment #3 type");
2010-02-06 04:36:35 +01:00
// convert and verify segments
var d = convert(p1, true);
2010-02-23 01:53:15 +01:00
equal(d, "m100,100l100,0z", "Converted path to relative string");
2010-02-10 18:37:26 +01:00
// TODO: see why this isn't working in SVG-edit
d = convert(p2, true);
QUnit.log(d);
d = convert(p2, false);
QUnit.log(d);
2010-02-06 04:36:35 +01:00
});
module("Transform Module");
test("Test matrixMultiply", function() {
expect(5);
// translate there and back
var tr_1 = svgroot.createSVGMatrix().translate(100,50),
tr_2 = svgroot.createSVGMatrix().translate(-90,0),
tr_3 = svgroot.createSVGMatrix().translate(-10,-50),
I = svgCanvas.matrixMultiply(tr_1,tr_2,tr_3);
2010-02-23 01:53:15 +01:00
equal(isIdentity(I), true,
2010-02-06 04:36:35 +01:00
"Expected identity matrix when translating there and back, got " + matrixString(I));
// 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 = svgroot.createSVGMatrix().rotate(90),
rot_back = svgroot.createSVGMatrix().rotate(-90); // TODO: set this to -50
rot_back_more = svgroot.createSVGMatrix().rotate(0); // TODO: set this to -40
I = svgCanvas.matrixMultiply(rot_there, rot_back, rot_back_more);
2010-02-23 01:53:15 +01:00
equal(isIdentity(I), true,
2010-02-06 04:36:35 +01:00
"Expected identity matrix when rotating there and back, got " + matrixString(I));
// scale up and down
var scale_up = svgroot.createSVGMatrix().scale(4),
scale_down = svgroot.createSVGMatrix().scaleNonUniform(0.25,1);
scale_down_more = svgroot.createSVGMatrix().scaleNonUniform(1,0.25);
I = svgCanvas.matrixMultiply(scale_up, scale_down, scale_down_more);
2010-02-23 01:53:15 +01:00
equal(isIdentity(I), true,
2010-02-06 04:36:35 +01:00
"Expected identity matrix when scaling up and down, got " + matrixString(I));
// test multiplication with its inverse
I = svgCanvas.matrixMultiply(rot_there, rot_there.inverse());
2010-02-23 01:53:15 +01:00
equal(isIdentity(I), true,
2010-02-06 04:36:35 +01:00
"Expected identity matrix when multiplying a matrix by its inverse, got " + matrixString(I));
I = svgCanvas.matrixMultiply(rot_there.inverse(), rot_there);
2010-02-23 01:53:15 +01:00
equal(isIdentity(I), true,
2010-02-06 04:36:35 +01:00
"Expected identity matrix when multiplying a matrix by its inverse, got " + matrixString(I));
});
module("Import Module");
test("Test import use", function() {
2010-02-18 17:12:44 +01:00
expect(3);
2010-02-06 04:36:35 +01:00
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' / > " +
2010-02-18 17:12:44 +01:00
"< use id = 'no-use' / > " +
2010-02-06 04:36:35 +01:00
"< / svg > ");
var u = document.getElementById("the-use"),
2010-02-18 17:12:44 +01:00
fu = document.getElementById("foreign-use"),
nfu = document.getElementById("no-use");
2010-02-06 04:36:35 +01:00
2010-02-23 01:53:15 +01:00
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");
2010-02-06 04:36:35 +01:00
});
test("Test getUrlFromAttr", function() {
expect(4);
2010-02-23 01:53:15 +01:00
equal(svgCanvas.getUrlFromAttr("url(#foo)"), "#foo");
equal(svgCanvas.getUrlFromAttr("url(somefile.svg#foo)"), "somefile.svg#foo");
equal(svgCanvas.getUrlFromAttr("url('#foo')"), "#foo");
equal(svgCanvas.getUrlFromAttr('url("#foo")'), "#foo");
2010-02-06 04:36:35 +01:00
});
// 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");
2010-02-23 01:53:15 +01:00
equal(true, (t & & t.nodeName == "text"), "Did not import < text > element");
equal(null, t.getAttribute("d"), "Imported a < text > with a d attribute");
2010-02-06 04:36:35 +01:00
});
2010-02-12 19:34:56 +01:00
// This test makes sure import/export properly handles namespaced attributes
test("Test importing/exporting namespaced attributes", function() {
expect(5);
var set = 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" / > ' +
'< / svg > ');
var attrVal = document.getElementById('se_test_elem').getAttributeNS("http://svg-edit.googlecode.com", "foo");
2010-02-23 01:53:15 +01:00
equal(attrVal === "bar", true, "Preserved namespaced attribute on import");
2010-02-12 19:34:56 +01:00
var output = svgCanvas.getSvgString();
var has_xlink = output.indexOf('xmlns:xlink="http://www.w3.org/1999/xlink"') !== -1;
var has_se = output.indexOf('xmlns:se=') !== -1;
2010-02-17 21:28:00 +01:00
var has_foo = output.indexOf('xmlns:foo=') !== -1;
2010-02-12 19:34:56 +01:00
var has_attr = output.indexOf('se:foo="bar"') !== -1;
2010-02-23 01:53:15 +01:00
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");
2010-02-12 19:34:56 +01:00
});
2010-02-17 21:28:00 +01:00
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;
2010-02-23 01:53:15 +01:00
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");
2010-02-17 21:28:00 +01:00
});
2010-02-12 19:34:56 +01:00
2010-02-23 01:53:15 +01:00
test("Test escaping XML entities", function() {
2010-02-17 21:28:00 +01:00
expect(3);
2010-02-23 01:53:15 +01:00
equal(svgCanvas.getPrivateMethods().toXml("< "), "< ", "Escaped < properly " ) ;
equal(svgCanvas.getPrivateMethods().toXml(">"), "> ", "Escaped > properly");
equal(svgCanvas.getPrivateMethods().toXml("& "), "& ", "Escaped & properly");
2010-02-17 21:28:00 +01:00
// TODO: what about " and ' ?
2010-02-23 01:53:15 +01:00
});
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");
});
2010-02-06 04:36:35 +01:00
});
< / script >
< / head >
< body >
< h1 id = "qunit-header" > Unit Tests for SvgCanvas< / h1 >
< h2 id = "qunit-banner" > < / h2 >
< h2 id = "qunit-userAgent" > < / h2 >
< ol id = "qunit-tests" >
< / ol >
< div id = "svgcanvas" style = "visibility:hidden" > < / div >
< / body >
< / html >