Merge Work-In-Progress 4320 to 4320

This commit is contained in:
Jon D
2018-07-06 22:20:19 +01:00
parent 68a3e6e69a
commit 3bad09d497
9 changed files with 700 additions and 5 deletions
+5
View File
@@ -229,6 +229,11 @@ en:
annotation:
create: Added a turn restriction
delete: Deleted a turn restriction
detachNode:
title: Detach
key: D
description: Detach this node from these lines/areas.
annotation: Detached a node from owning lines/areas.
restriction:
controls:
distance: Distance
+6
View File
@@ -297,6 +297,12 @@
"create": "Added a turn restriction",
"delete": "Deleted a turn restriction"
}
},
"detachNode": {
"title": "Detach",
"key": "D",
"description": "Detach this node from these lines/areas.",
"annotation": "Detached a node from owning lines/areas."
}
},
"restriction": {
+27
View File
@@ -0,0 +1,27 @@
import { osmNode } from '../osm';
export function actionDetachNode(nodeId) {
return function (graph) {
// Get the point in question
var node = graph.entity(nodeId);
// Get all of the ways it's currently attached to
var parentWays = graph.parentWays(node);
// Create a new node to replace the one we will detach
var replacementNode = osmNode({ loc: node.loc });
// We need to process each way in turn, updating the graph as we go
return parentWays
.reduce(function (accGraph, parentWay) {
// Make a note of where in the way our target node is inside this way
var originalIndex = parentWay.nodes.indexOf(nodeId);
// Swap out the target node for the replacement
var updatedWay = parentWay
.removeNode(nodeId) // Remove our target node from the parent way
.addNode(replacementNode.id, originalIndex); // Add in the replacement node in its place
// Update the graph with the updated way
return accGraph.replace(updatedWay);
},
// Seed the reduction with the input graph, updated to include the replacementNode so
// that is accessible to the ways when we add it in to them
graph.replace(replacementNode));
};
}
+1
View File
@@ -33,3 +33,4 @@ export { actionSplit } from './split';
export { actionStraighten } from './straighten';
export { actionUnrestrictTurn } from './unrestrict_turn';
export { actionReflect } from './reflect.js';
export { actionDetachNode } from './detach_node';
+50
View File
@@ -0,0 +1,50 @@
import { actionDetachNode } from '../actions/index';
import { behaviorOperation } from '../behavior/index';
import { modeMove } from '../modes/index';
import { t } from '../util/locale';
export function operationDetachNode(selectedIDs, context) {
var selectedNode = selectedIDs[0];
var operation = function () {
context.perform(actionDetachNode(selectedNode));
context.enter(modeMove(context, [selectedNode], context.graph));
};
var hasTags = function (entity) {
return Object.keys(entity.tags).length > 0;
};
operation.available = function () {
// Check multiple items aren't selected
if (selectedIDs.length !== 1) {
return false;
}
// Get the entity itself
var graph = context.graph();
var entity = graph.hasEntity(selectedNode);
if (!entity) {
// This probably isn't possible
return false;
}
// Confirm entity is a node with tags
if (entity.type === 'node' && hasTags(entity)) {
// Confirm that the node is owned by at least 1 parent way
var parentWays = graph.parentWays(entity);
return parentWays && parentWays.length > 0;
}
// Not appropriate
return false;
};
operation.disabled = function () {
return false;
};
operation.tooltip = function () {
return t('operations.detachNode.description');
};
operation.annotation = function () {
return t('operations.detachNode.annotation');
};
operation.id = 'detachNode';
operation.keys = [t('operations.detachNode.key')];
operation.title = t('operations.detachNode.title');
operation.behavior = behaviorOperation(context).which(operation);
return operation;
}
+1
View File
@@ -10,3 +10,4 @@ export { operationReverse } from './reverse';
export { operationRotate } from './rotate';
export { operationSplit } from './split';
export { operationStraighten } from './straighten';
export { operationDetachNode } from './detach_node';
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
x="0"
y="0"
width="20"
height="20"
viewBox="0 0 20 20"
id="svg838"
sodipodi:docname="operation-detachNode.svg"
inkscape:version="0.92.3 (3ce5693, 2018-03-11)">
<metadata
id="metadata844">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs842" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2070"
id="namedview840"
showgrid="false"
inkscape:zoom="90.9"
inkscape:cx="9.889989"
inkscape:cy="10"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg838" />
<path
style="fill:currentColor"
d="m 11.414214,2.9289322 v 1.4142136 l 1.414213,1.4142135 -1.54715,1.5471497 c 0.294864,0.1421284 0.596092,0.3302188 0.840043,0.5741707 0.25173,0.25173 0.431335,0.5359869 0.574171,0.8400428 l 1.54715,-1.5471496 1.414213,1.4142135 h 1.414214 V 2.9289322 Z"
id="path834" />
<path
d="M10,7.987 C8.895,7.987 8,8.883 8,9.987 C8,11.092 8.895,11.987 10,11.987 C11.105,11.987 12,11.092 12,9.987 C12,8.883 11.105,7.987 10,7.987 z"
fill="inherit"
id="path836" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

+9 -5
View File
@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Mocha Tests</title>
@@ -7,6 +8,7 @@
<link rel='stylesheet' href='../dist/iD.css'>
<!-- <script src='../node_modules/d3/build/d3.js'></script> -->
</head>
<body style="overflow:scroll">
<div id='mocha'></div>
@@ -17,9 +19,9 @@
<script src='../node_modules/happen/happen.js'></script>
<script>
if (typeof initMochaPhantomJS === 'function') {
initMochaPhantomJS()
}
if (typeof initMochaPhantomJS === 'function') {
initMochaPhantomJS()
}
</script>
<!-- include source files here... -->
@@ -60,6 +62,7 @@
<script src='spec/actions/straighten.js'></script>
<script src='spec/actions/unrestrict_turn.js'></script>
<script src='spec/actions/reflect.js'></script>
<script src='spec/actions/detach_node.js'></script>
<script src='spec/behavior/hash.js'></script>
<script src='spec/behavior/hover.js'></script>
@@ -138,7 +141,8 @@
<script src='spec/util/util.js'></script>
<script>
window.mocha.run();
window.mocha.run();
</script>
</body>
</html>
</html>
+540
View File
@@ -0,0 +1,540 @@
describe('iD.actionDetachNode', function () {
var tags = { 'name': 'test' };
function createTargetNode(id, lonlat) {
return iD.Node({ id: id, loc: lonlat, tags: tags });
}
describe('simple way', function () {
var graph;
beforeEach(function () {
// Set up a simple way
// a-b-c-d
// (0,0)-(1,0)-(2,0)-(3,0)
graph = iD.Graph([
iD.Node({ id: 'a', loc: [0, 0] }),
iD.Node({ id: 'b', loc: [1, 0] }),
iD.Node({ id: 'c', loc: [2, 0] }),
iD.Node({ id: 'd', loc: [3, 0] }),
iD.Way({ id: 'w', nodes: ['a', 'b', 'c', 'd'] })
]);
});
describe('target in first position', function () {
beforeEach(function () {
// Swap target into the location & position of A
var targetNode = createTargetNode('a', graph.entity('a').loc);
graph = graph.replace(targetNode);
});
it('does not change length of way', function () {
// Act
var assertionGraph = iD.actionDetachNode('a')(graph);
// Confirm that the way still has 4 nodes
var target = assertionGraph.entity('w');
expect(target.nodes.length).to.eql(4);
});
it('does not change order of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('a')(graph);
// Confirm that the way is ordered correctly
var target = assertionGraph.entity('w');
// Note that we can't be sure of the id of the replacement node
// so we only assert the nodes we know the ids for
// As we have already confirmed the size of the array we can assume
// that the replacement node is in the correct posisiton by a process of elimination
expect(target.nodes[1]).to.eql('b');
expect(target.nodes[2]).to.eql('c');
expect(target.nodes[3]).to.eql('d');
});
it('does not change location of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('a')(graph);
// Confirm that the nodes have not moved, including the replacement node
var nodes = assertionGraph.entity('w').nodes;
expect(assertionGraph.entity(nodes[0]).loc).to.eql([0, 0]);
expect(assertionGraph.entity(nodes[1]).loc).to.eql([1, 0]);
expect(assertionGraph.entity(nodes[2]).loc).to.eql([2, 0]);
expect(assertionGraph.entity(nodes[3]).loc).to.eql([3, 0]);
});
it('does replace target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('a')(graph);
var nodes = assertionGraph.entity('w').nodes;
// Confirm that the target is no longer "a"
expect(nodes[0]).not.to.eql('a');
// and that the tags are not present
expect(assertionGraph.entity(nodes[0]).tags).to.eql({});
});
it('does detach target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('a')(graph);
// confirm that a still exists
var targetNode = assertionGraph.entity('a');
expect(targetNode).not.to.eql(undefined);
// .., and that the location is correct
expect(targetNode.loc).to.eql([0, 0]);
// ... and that the tags are intact
expect(targetNode.tags).to.eql(tags);
// ... and that the parentWay is empty
expect(assertionGraph.parentWays(targetNode)).to.eql([]);
});
});
describe('target in second position', function () {
beforeEach(function () {
// Swap target into the location & position of B
var targetNode = createTargetNode('b', graph.entity('b').loc);
graph = graph.replace(targetNode);
});
it('does not change length of way', function () {
// Act
var assertionGraph = iD.actionDetachNode('b')(graph);
// Confirm that the way still has 4 nodes
var target = assertionGraph.entity('w');
expect(target.nodes.length).to.eql(4);
});
it('does not change order of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('b')(graph);
// Confirm that the way is ordered correctly
var target = assertionGraph.entity('w');
// Note that we can't be sure of the id of the replacement node
// so we only assert the nodes we know the ids for
// As we have already confirmed the size of the array we can assume
// that the replacement node is in the correct posisiton by a process of elimination
expect(target.nodes[0]).to.eql('a');
expect(target.nodes[2]).to.eql('c');
expect(target.nodes[3]).to.eql('d');
});
it('does not change location of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('b')(graph);
// Confirm that the nodes have not moved, including the replacement node
var nodes = assertionGraph.entity('w').nodes;
expect(assertionGraph.entity(nodes[0]).loc).to.eql([0, 0]);
expect(assertionGraph.entity(nodes[1]).loc).to.eql([1, 0]);
expect(assertionGraph.entity(nodes[2]).loc).to.eql([2, 0]);
expect(assertionGraph.entity(nodes[3]).loc).to.eql([3, 0]);
});
it('does replace target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('b')(graph);
var nodes = assertionGraph.entity('w').nodes;
// Confirm that the target is no longer "a"
expect(nodes[1]).not.to.eql('b');
// and that the tags are not present
expect(assertionGraph.entity(nodes[1]).tags).to.eql({});
});
it('does detach target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('b')(graph);
// confirm that a still exists
var targetNode = assertionGraph.entity('b');
expect(targetNode).not.to.eql(undefined);
// .., and that the location is correct
expect(targetNode.loc).to.eql([1, 0]);
// ... and that the tags are intact
expect(targetNode.tags).to.eql(tags);
// ... and that the parentWay is empty
expect(assertionGraph.parentWays(targetNode)).to.eql([]);
});
});
});
describe('closed way', function () {
var graph;
beforeEach(function () {
// Set up a closed way
// a-b (0,0)-(1,0)
// | |
// d-c (0,1)-(1,1)
graph = iD.Graph([
iD.Node({ id: 'a', loc: [0, 0] }),
iD.Node({ id: 'b', loc: [1, 0] }),
iD.Node({ id: 'c', loc: [1, 1] }),
iD.Node({ id: 'd', loc: [0, 1] }),
iD.Way({ id: 'w', nodes: ['a', 'b', 'c', 'd', 'a'] })
]);
});
describe('target in first position', function () {
beforeEach(function () {
// Swap target into the location & position of A
var targetNode = createTargetNode('a', graph.entity('a').loc);
graph = graph.replace(targetNode);
});
it('does not change length of way', function () {
// Act
var assertionGraph = iD.actionDetachNode('a')(graph);
// Confirm that the way still has 5 nodes
var target = assertionGraph.entity('w');
expect(target.nodes.length).to.eql(5);
});
it('does not change order of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('a')(graph);
// Confirm that the way is ordered correctly
var target = assertionGraph.entity('w');
// Note that we can't be sure of the id of the replacement node
// so we only assert the nodes we know the ids for
// As we have already confirmed the size of the array we can assume
// that the replacement node is in the correct posisiton by a process of elimination
expect(target.nodes[1]).to.eql('b');
expect(target.nodes[2]).to.eql('c');
expect(target.nodes[3]).to.eql('d');
// Need to confirm that the id of the first & last node is the same so that the way remains closed
expect(target.nodes[0]).to.eql(target.nodes[4]);
});
it('does not change location of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('a')(graph);
// Confirm that the nodes have not moved, including the replacement node
var nodes = assertionGraph.entity('w').nodes;
expect(assertionGraph.entity(nodes[0]).loc).to.eql([0, 0]);
expect(assertionGraph.entity(nodes[1]).loc).to.eql([1, 0]);
expect(assertionGraph.entity(nodes[2]).loc).to.eql([1, 1]);
expect(assertionGraph.entity(nodes[3]).loc).to.eql([0, 1]);
// We don't need to assert node[4] location as we've already confirmed that it is the same as node 0
});
it('does replace target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('a')(graph);
var nodes = assertionGraph.entity('w').nodes;
// Confirm that the target is no longer "a"
expect(nodes[0]).not.to.eql('a');
// .. also in the tail position
expect(nodes[4]).not.to.eql('a');
// and that the tags are not present (already confirmed same node in position 0 & 4, so only need to check tags once)
expect(assertionGraph.entity(nodes[0]).tags).to.eql({});
});
it('does detach target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('a')(graph);
// confirm that a still exists
var targetNode = assertionGraph.entity('a');
expect(targetNode).not.to.eql(undefined);
// .., and that the location is correct
expect(targetNode.loc).to.eql([0, 0]);
// ... and that the tags are intact
expect(targetNode.tags).to.eql(tags);
// ... and that the parentWay is empty
expect(assertionGraph.parentWays(targetNode)).to.eql([]);
});
});
describe('target in second position', function () {
beforeEach(function () {
// Swap target into the location & position of B
var targetNode = createTargetNode('b', graph.entity('b').loc);
graph = graph.replace(targetNode);
});
it('does not change length of way', function () {
// Act
var assertionGraph = iD.actionDetachNode('b')(graph);
// Confirm that the way still has 5 nodes
var target = assertionGraph.entity('w');
expect(target.nodes.length).to.eql(5);
});
it('does not change order of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('b')(graph);
// Confirm that the way is ordered correctly
var target = assertionGraph.entity('w');
// Note that we can't be sure of the id of the replacement node
// so we only assert the nodes we know the ids for
// As we have already confirmed the size of the array we can assume
// that the replacement node is in the correct posisiton by a process of elimination
expect(target.nodes[0]).to.eql('a');
expect(target.nodes[2]).to.eql('c');
expect(target.nodes[3]).to.eql('d');
expect(target.nodes[4]).to.eql('a');
});
it('does not change location of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('b')(graph);
// Confirm that the nodes have not moved, including the replacement node
var nodes = assertionGraph.entity('w').nodes;
expect(assertionGraph.entity(nodes[0]).loc).to.eql([0, 0]);
expect(assertionGraph.entity(nodes[1]).loc).to.eql([1, 0]);
expect(assertionGraph.entity(nodes[2]).loc).to.eql([1, 1]);
expect(assertionGraph.entity(nodes[3]).loc).to.eql([0, 1]);
// Confirmed already that node[4] is node[0] so no further assertion needed
});
it('does replace target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('b')(graph);
var nodes = assertionGraph.entity('w').nodes;
// Confirm that the target is no longer "a"
expect(nodes[1]).not.to.eql('b');
// and that the tags are not present
expect(assertionGraph.entity(nodes[1]).tags).to.eql({});
});
it('does detach target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('b')(graph);
// confirm that a still exists
var targetNode = assertionGraph.entity('b');
expect(targetNode).not.to.eql(undefined);
// .., and that the location is correct
expect(targetNode.loc).to.eql([1, 0]);
// ... and that the tags are intact
expect(targetNode.tags).to.eql(tags);
// ... and that the parentWay is empty
expect(assertionGraph.parentWays(targetNode)).to.eql([]);
});
});
});
describe('intersecting simple ways', function () {
var graph;
beforeEach(function () {
// Set up two simple ways
// a-b-c-d (0,0)-(1,0)-(2,0)-(3,0)
// e (2,1)
// f (2,2)
// Node c represents the target
graph = iD.Graph([
iD.Node({ id: 'a', loc: [0, 0] }),
iD.Node({ id: 'b', loc: [1, 0] }),
iD.Node({ id: 'c', loc: [2, 0], tags: tags }),
iD.Node({ id: 'd', loc: [3, 0] }),
iD.Node({ id: 'e', loc: [2, 1] }),
iD.Node({ id: 'f', loc: [2, 2] }),
iD.Way({ id: 'w', nodes: ['a', 'b', 'c', 'd'] }),
iD.Way({ id: 'x', nodes: ['c', 'e', 'f'] })
]);
});
it('does not change length of ways', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
// Confirm that the way still has 4 nodes
var target = assertionGraph.entity('w');
expect(target.nodes.length).to.eql(4);
// .. and second way has 3
target = assertionGraph.entity('x');
expect(target.nodes.length).to.eql(3);
});
it('does not change order of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
// Confirm that the way is ordered correctly
var target = assertionGraph.entity('w');
// Note that we can't be sure of the id of the replacement node
// so we only assert the nodes we know the ids for
// As we have already confirmed the size of the array we can assume
// that the replacement node is in the correct posisiton by a process of elimination
expect(target.nodes[0]).to.eql('a');
expect(target.nodes[1]).to.eql('b');
expect(target.nodes[3]).to.eql('d');
// and second way
target = assertionGraph.entity('x');
expect(target.nodes[1]).to.eql('e');
expect(target.nodes[2]).to.eql('f');
});
it('does not change location of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
// Confirm that the nodes have not moved, including the replacement node
var nodes = assertionGraph.entity('w').nodes;
expect(assertionGraph.entity(nodes[0]).loc).to.eql([0, 0]);
expect(assertionGraph.entity(nodes[1]).loc).to.eql([1, 0]);
expect(assertionGraph.entity(nodes[2]).loc).to.eql([2, 0]);
expect(assertionGraph.entity(nodes[3]).loc).to.eql([3, 0]);
// and second way
nodes = assertionGraph.entity('x').nodes;
expect(assertionGraph.entity(nodes[0]).loc).to.eql([2, 0]);
expect(assertionGraph.entity(nodes[1]).loc).to.eql([2, 1]);
expect(assertionGraph.entity(nodes[2]).loc).to.eql([2, 2]);
});
it('uses same replacement node at intersection', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
// Confirm both ways have the same replacement node
expect(assertionGraph.entity('w').nodes[2]).to.eql(assertionGraph.entity('x').nodes[0]);
});
it('does replace target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
var nodes = assertionGraph.entity('w').nodes;
// Confirm that the target is no longer "c"
expect(nodes[2]).not.to.eql('c');
// and that the tags are not present
expect(assertionGraph.entity(nodes[2]).tags).to.eql({});
// Confirm that the second way's first node is the same
expect(assertionGraph.entity('x').nodes[0]).to.eql(nodes[2]);
});
it('does detach target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
// confirm that a still exists
var targetNode = assertionGraph.entity('c');
expect(targetNode).not.to.eql(undefined);
// .., and that the location is correct
expect(targetNode.loc).to.eql([2, 0]);
// ... and that the tags are intact
expect(targetNode.tags).to.eql(tags);
// ... and that the parentWay is empty
expect(assertionGraph.parentWays(targetNode)).to.eql([]);
});
});
describe('intersecting closed way', function () {
var graph;
beforeEach(function () {
// Set up two intersecting closed ways
// a-b (0,0)-(1,0)
// | |
// d-c-e (0,1)-(1,1)-(2,1)
// | |
// g f (0,2) - (1,2)
// C is the target node
graph = iD.Graph([
iD.Node({ id: 'a', loc: [0, 0] }),
iD.Node({ id: 'b', loc: [1, 0] }),
iD.Node({ id: 'c', loc: [1, 1], tags: tags }),
iD.Node({ id: 'd', loc: [0, 1] }),
iD.Node({ id: 'e', loc: [2, 1] }),
iD.Node({ id: 'f', loc: [1, 2] }),
iD.Node({ id: 'g', loc: [0, 2] }),
iD.Way({ id: 'w', nodes: ['a', 'b', 'c', 'd', 'a'] }),
iD.Way({ id: 'x', nodes: ['c', 'e', 'f', 'g', 'c'] })
]);
});
it('does not change length of ways', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
// Confirm that the way still has 5 nodes
var target = assertionGraph.entity('w');
expect(target.nodes.length).to.eql(5);
// and the second
target = assertionGraph.entity('x');
expect(target.nodes.length).to.eql(5);
});
it('does not change order of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
// Confirm that the way is ordered correctly
var target = assertionGraph.entity('w');
// Note that we can't be sure of the id of the replacement node
// so we only assert the nodes we know the ids for
// As we have already confirmed the size of the array we can assume
// that the replacement node is in the correct posisiton by a process of elimination
expect(target.nodes[0]).to.eql('a');
expect(target.nodes[1]).to.eql('b');
expect(target.nodes[3]).to.eql('d');
// Need to confirm that the id of the first & last node is the same so that the way remains closed
expect(target.nodes[0]).to.eql(target.nodes[4]);
// and the same for the other way
target = assertionGraph.entity('x');
expect(target.nodes[1]).to.eql('e');
expect(target.nodes[2]).to.eql('f');
expect(target.nodes[3]).to.eql('g');
expect(target.nodes[0]).to.eql(target.nodes[4]);
});
it('does not change location of nodes', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
// Confirm that the nodes have not moved, including the replacement node
var nodes = assertionGraph.entity('w').nodes;
expect(assertionGraph.entity(nodes[0]).loc).to.eql([0, 0]);
expect(assertionGraph.entity(nodes[1]).loc).to.eql([1, 0]);
expect(assertionGraph.entity(nodes[2]).loc).to.eql([1, 1]);
expect(assertionGraph.entity(nodes[3]).loc).to.eql([0, 1]);
// We don't need to assert node[4] location as we've already confirmed that it is the same as node 0
// and the other way
nodes = assertionGraph.entity('x').nodes;
expect(assertionGraph.entity(nodes[0]).loc).to.eql([1, 1]);
expect(assertionGraph.entity(nodes[1]).loc).to.eql([2, 1]);
expect(assertionGraph.entity(nodes[2]).loc).to.eql([1, 2]);
expect(assertionGraph.entity(nodes[3]).loc).to.eql([0, 2]);
});
it('uses same replacement node at intersection', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
// Confirm both ways have the same replacement node
expect(assertionGraph.entity('w').nodes[2]).to.eql(assertionGraph.entity('x').nodes[0]);
});
it('does replace target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
var nodes = assertionGraph.entity('w').nodes;
// Confirm that the target is no longer "c"
expect(nodes[0]).not.to.eql('c');
// .. also in the tail position
expect(nodes[4]).not.to.eql('c');
// and that the tags are not present (already confirmed same node in position 0 & 4, so only need to check tags once)
expect(assertionGraph.entity(nodes[0]).tags).to.eql({});
// Don't need to check for way 2 since we've already confirmed it is the same node
});
it('does detach target node', function () {
// Act
var assertionGraph = iD.actionDetachNode('c')(graph);
// confirm that a still exists
var targetNode = assertionGraph.entity('c');
expect(targetNode).not.to.eql(undefined);
// .., and that the location is correct
expect(targetNode.loc).to.eql([1, 1]);
// ... and that the tags are intact
expect(targetNode.tags).to.eql(tags);
// ... and that the parentWay is empty
expect(assertionGraph.parentWays(targetNode)).to.eql([]);
});
});
});