Fix merge/cloneLayer. Migrate more Canvas functions to Draw. Tests.
Fixed recently introduced bugs in mergeLayer, cloneLayer. More Draw unit tests. Migrating Canvas methods to Draw, Layer, and utilities: copyElem, pathActions.convertPath, cloneLayer, mergeLayer, and mergeAllLayers. Canvas API is unchanged for backwards compatibility (i.e. previous functions forward to new functions).
This commit is contained in:
@@ -8,10 +8,13 @@
|
||||
<script src='../editor/svgedit.js'></script>
|
||||
<script src='../editor/pathseg.js'></script>
|
||||
<script src='../editor/browser.js'></script>
|
||||
<script src='../editor/units.js'></script>
|
||||
<script src='../editor/svgutils.js'></script>
|
||||
<script src='../editor/draw.js'></script>
|
||||
<script src='../editor/layer.js'></script>
|
||||
<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
|
||||
@@ -26,6 +29,15 @@
|
||||
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');
|
||||
@@ -37,6 +49,19 @@
|
||||
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');
|
||||
@@ -55,12 +80,51 @@
|
||||
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);
|
||||
|
||||
@@ -389,11 +453,8 @@
|
||||
test('Test setCurrentLayerName()', function() {
|
||||
|
||||
var mockHrService = {
|
||||
changeElement: function(elem, attrs){
|
||||
mockHrService.elem = elem;
|
||||
mockHrService.attrs = attrs;
|
||||
}
|
||||
}
|
||||
changeElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
@@ -413,14 +474,21 @@
|
||||
equals( drawing.layer_map[oldName], undefined);
|
||||
equals( drawing.layer_map[newName], drawing.current_layer);
|
||||
// Was mockHrService called?
|
||||
equals( oldName, mockHrService.attrs['#text']);
|
||||
equals( newName, mockHrService.elem.textContent);
|
||||
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(7);
|
||||
expect(10);
|
||||
|
||||
var mockHrService = {
|
||||
startBatchCommand: this.spy(),
|
||||
endBatchCommand: this.spy(),
|
||||
insertElement: this.spy()
|
||||
};
|
||||
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
setupSvgWith3Layers(svg);
|
||||
@@ -430,13 +498,178 @@
|
||||
equals(typeof drawing.createLayer, typeof function(){});
|
||||
|
||||
var NEW_LAYER_NAME = 'Layer A';
|
||||
var layer_g = drawing.createLayer(NEW_LAYER_NAME);
|
||||
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);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user