text: /* jshint unused: false */
  /* global beforeEach, afterEach */
  /* global describe, it, expect, spyOn, jasmine */
  /* global window, eb, loadFixtures, document */
  /* global $, _, d3*/
  /* global helper*/
  /* global EdgeShaper*/
  
  // //////////////////////////////////////////////////////////////////////////////
  // / @brief Graph functionality
  // /
  // / @file
  // /
  // / DISCLAIMER
  // /
  // / Copyright 2010-2012 triagens GmbH, Cologne, Germany
  // /
  // / Licensed under the Apache License, Version 2.0 (the "License")
  // / you may not use this file except in compliance with the License.
  // / You may obtain a copy of the License at
  // /
  // /     http://www.apache.org/licenses/LICENSE-2.0
  // /
  // / Unless required by applicable law or agreed to in writing, software
  // / distributed under the License is distributed on an "AS IS" BASIS,
  // / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // / See the License for the specific language governing permissions and
  // / limitations under the License.
  // /
  // / Copyright holder is triAGENS GmbH, Cologne, Germany
  // /
  // / @author Michael Hackstein
  // / @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
  // //////////////////////////////////////////////////////////////////////////////
  
  (function () {
    'use strict';
  
    describe('Edge Shaper', function () {
      var svg,
        getDistance = function (s, t) {
          var res = Math.sqrt(
              (t.y - s.y)
              * (t.y - s.y)
              + (t.x - s.x)
              * (t.x - s.x)
            ),
            m;
          if (s.x === t.x) {
            res -= t.z * 18;
          } else {
            m = Math.abs((t.y - s.y) / (t.x - s.x));
            if (m < 0.4) {
              res -= Math.abs((res * t.z * 45) / (t.x - s.x));
            } else {
              res -= Math.abs((res * t.z * 18) / (t.y - s.y));
            }
          }
          return res;
      };
  
      beforeEach(function () {
        svg = document.createElement('svg');
        svg.id = 'svg';
        document.body.appendChild(svg);
      });
  
      afterEach(function () {
        document.body.removeChild(svg);
      });
  
      describe('checking the context menu', function () {
        var edges, shaper, fakeMenu, fakeCM;
  
        beforeEach(function () {
          var nodes = helper.createSimpleNodes([1, 2]),
            source = nodes[0],
            target = nodes[1],
            fakeMenu = {};
          fakeCM = {
            addEntry: function () {},
            bindMenu: function () {}
          };
          edges = [
            {
              _id: '1-2',
              source: source,
              target: target
            }
          ];
          spyOn(window, 'ContextMenu').andReturn(fakeCM);
          spyOn(fakeCM, 'addEntry');
          spyOn(fakeCM, 'bindMenu');
          shaper = new EdgeShaper(d3.select('svg'));
        });
  
        it('should create the context menu', function () {
          expect(window.ContextMenu).toHaveBeenCalledWith('gv_edge_cm');
          expect(fakeCM.addEntry).not.toHaveBeenCalled();
          expect(fakeCM.bindMenu).not.toHaveBeenCalled();
          shaper.drawEdges(edges);
          expect(fakeCM.bindMenu).toHaveBeenCalledWith($('.link'));
        });
  
        it('should be able to insert an entry in the menu', function () {
          var lbl = 'Label', func = function () {};
          shaper.addMenuEntry(lbl, func);
          expect(fakeCM.addEntry).toHaveBeenCalledWith(lbl, jasmine.any(Function));
        });
      });
  
      it('should be able to draw an edge', function () {
        var nodes = helper.createSimpleNodes([1, 2]),
          source = nodes[0],
          target = nodes[1],
          edges = [
            {
              _id: '1-2',
              source: source,
              target: target
            }
          ],
          shaper = new EdgeShaper(d3.select('svg'));
        shaper.drawEdges(edges);
        expect($('svg .link line').length).toEqual(1);
        expect($('svg .link line')[0]).toBeDefined();
        expect($('svg #1-2')[0]).toBeDefined();
      });
  
      it('should be able to draw many edges', function () {
        var nodes = helper.createSimpleNodes([1, 2, 3, 4]),
          edges = [
            {
              _id: '1-2',
              source: nodes[0],
              target: nodes[1]
            },
            {
              _id: '2-3',
              source: nodes[1],
              target: nodes[2]
            },
            {
              _id: '3-4',
              source: nodes[2],
              target: nodes[3]
            },
            {
              _id: '4-1',
              source: nodes[3],
              target: nodes[0]
            }
          ],
          shaper = new EdgeShaper(d3.select('svg'));
        shaper.drawEdges(edges);
        expect($('svg .link line').length).toEqual(4);
      });
  
      it('should be able to add an event', function () {
        var nodes = helper.createSimpleNodes([1, 2, 3, 4]),
          edges = [
            {
              _id: '1-2',
              source: nodes[0],
              target: nodes[1]
            },
            {
              _id: '2-3',
              source: nodes[1],
              target: nodes[2]
            },
            {
              _id: '3-4',
              source: nodes[2],
              target: nodes[3]
            },
            {
              _id: '4-1',
              source: nodes[3],
              target: nodes[0]
            }
          ],
          clicked = [],
          click = function (edge) {
            clicked[edge.source._id] = !clicked[edge.source._id];
          },
          shaper = new EdgeShaper(d3.select('svg'), {
            actions: {
              click: click
            }
          });
        shaper.drawEdges(edges);
        helper.simulateMouseEvent('click', '1-2');
        helper.simulateMouseEvent('click', '3-4');
  
        expect($('svg .link line').length).toEqual(4);
        expect(clicked[1]).toBeTruthy();
        expect(clicked[3]).toBeTruthy();
        expect(clicked[2]).toBeFalsy();
        expect(clicked[4]).toBeFalsy();
      });
  
      it('should be able to unbind all events', function () {
        var nodes = helper.createSimpleNodes([1, 2, 3, 4]),
          edges = [
            {
              _id: '1-2',
              source: nodes[0],
              target: nodes[1]
            },
            {
              _id: '2-3',
              source: nodes[1],
              target: nodes[2]
            },
            {
              _id: '3-4',
              source: nodes[2],
              target: nodes[3]
            },
            {
              _id: '4-1',
              source: nodes[3],
              target: nodes[0]
            }
          ],
          clicked = [],
          click = function (edge) {
            clicked[edge.source._id] = !clicked[edge.source._id];
          },
          shaper = new EdgeShaper(d3.select('svg'), {
            actions: {
              click: click
            }
          });
        shaper.drawEdges(edges);
        shaper.changeTo({
          actions: {
            reset: true
          }
        });
  
        helper.simulateMouseEvent('click', '1-2');
        helper.simulateMouseEvent('click', '3-4');
  
        expect($('svg .link line').length).toEqual(4);
        expect(clicked[1]).toBeFalsy();
        expect(clicked[3]).toBeFalsy();
        expect(clicked[2]).toBeFalsy();
        expect(clicked[4]).toBeFalsy();
      });
  
      it('should be able to add an arrow on target side', function () {
        var nodes = helper.createSimpleNodes([1, 2]),
          edges = [
            {
              _id: '1-2',
              source: nodes[0],
              target: nodes[1]
            }
          ],
          shaper = new EdgeShaper(d3.select('svg'), {
            shape: {
              type: EdgeShaper.shapes.ARROW
            }
          });
        shaper.drawEdges(edges);
  
        expect($('#1-2 line').attr('marker-end')).toEqual('url(#arrow)');
        expect($('svg defs marker').length).toEqual(1);
        expect($('svg defs #arrow').length).toEqual(1);
        // Orientation is important. Other layout not yet.
        expect($('svg defs #arrow').attr('orient')).toEqual('auto');
      });
  
      it('should position the edges correctly', function () {
        var center = {
            _id: 1,
            position: {
              x: 20,
              y: 20,
              z: 1
            }
          },
          NE = {
            _id: 2,
            position: {
              x: 30,
              y: 10,
              z: 1
            }
          },
          SE = {
            _id: 3,
            position: {
              x: 40,
              y: 30,
              z: 1
            }
          },
          SW = {
            _id: 4,
            position: {
              x: 10,
              y: 40,
              z: 1
            }
          },
          NW = {
            _id: 5,
            position: {
              x: 0,
              y: 0,
              z: 1
            }
          },
          edges = [
            {
              _id: '1-2',
              source: center,
              target: NE
            },
            {
              _id: '1-3',
              source: center,
              target: SE
            },
            {
              _id: '1-4',
              source: center,
              target: SW
            },
            {
              _id: '1-5',
              source: center,
              target: NW
            }
          ],
          shaper = new EdgeShaper(d3.select('svg'), {
            shape: {
              type: EdgeShaper.shapes.ARROW
            }
          });
        shaper.drawEdges(edges);
  
        // Check Position and rotation
        expect($('#1-2').attr('transform')).toEqual('translate(20, 20)rotate(-45)');
        expect($('#1-3').attr('transform')).toEqual('translate(20, 20)rotate(26.56505117707799)');
        expect($('#1-4').attr('transform')).toEqual('translate(20, 20)rotate(116.56505117707799)');
        expect($('#1-5').attr('transform')).toEqual('translate(20, 20)rotate(-135)');
  
        // Check length of line
        expect($('#1-2 line').attr('x2')).toEqual(String(getDistance(center.position, NE.position)));
        expect($('#1-3 line').attr('x2')).toEqual(String(getDistance(center.position, SE.position)));
        expect($('#1-4 line').attr('x2')).toEqual(String(getDistance(center.position, SW.position)));
        expect($('#1-5 line').attr('x2')).toEqual(String(getDistance(center.position, NW.position)));
      });
  
      it('should be able to draw an edge that follows the cursor', function () {
        var line,
          jqLine,
          cursorX,
          cursorY,
          nodeX = 15,
          nodeY = 20,
          shaper = new EdgeShaper(d3.select('svg')),
          moveCB = shaper.addAnEdgeFollowingTheCursor(nodeX, nodeY);
  
        cursorX = 20;
        cursorY = 30;
        moveCB(cursorX, cursorY);
  
        expect($('#connectionLine').length).toEqual(1);
  
        jqLine = $('#connectionLine');
        line = document.getElementById('connectionLine');
        expect(line.tagName.toLowerCase()).toEqual('line');
        expect(jqLine.attr('x1')).toEqual(String(nodeX));
        expect(jqLine.attr('y1')).toEqual(String(nodeY));
  
        expect(jqLine.attr('x2')).toEqual(String(cursorX));
        expect(jqLine.attr('y2')).toEqual(String(cursorY));
  
        cursorX = 45;
        cursorY = 12;
        moveCB(cursorX, cursorY);
        expect(jqLine.attr('x2')).toEqual(String(cursorX));
        expect(jqLine.attr('y2')).toEqual(String(cursorY));
      });
  
      it('should be able to remove the cursor-following edge on demand', function () {
        var cursorX,
          cursorY,
          nodeX = 15,
          nodeY = 20,
          shaper = new EdgeShaper(d3.select('svg')),
          moveCB;
  
        moveCB = shaper.addAnEdgeFollowingTheCursor(nodeX, nodeY);
        cursorX = 20;
        cursorY = 30;
        moveCB(cursorX, cursorY);
        shaper.removeCursorFollowingEdge();
        expect($('#connectionLine').length).toEqual(0);
      });
  
      describe('testing for colours', function () {
        it('should have a default colouring of no colour flag is given', function () {
          var nodes = helper.createSimpleNodes([1, 2]),
            edges = [{
              _id: '1-2',
              source: nodes[0],
              target: nodes[1]
            }, {
              _id: '2-1',
              source: nodes[1],
              target: nodes[0]
            }],
            shaper = new EdgeShaper(d3.select('svg'));
          shaper.drawEdges(edges);
  
          expect($('#1-2 line').attr('stroke')).toEqual('#686766');
          expect($('#2-1 line').attr('stroke')).toEqual('#686766');
        });
  
        it('should be able to use the same colour for all edges', function () {
          var nodes = helper.createSimpleNodes([1, 2]),
            edges = [{
              _id: '1-2',
              source: nodes[0],
              target: nodes[1]
            }, {
              _id: '2-1',
              source: nodes[1],
              target: nodes[0]
            }],
            shaper = new EdgeShaper(d3.select('svg'),
              {
                color: {
                  type: 'single',
                  stroke: '#123456'
                }
              }
          );
          shaper.drawEdges(edges);
  
          expect($('#1-2 line').attr('stroke')).toEqual('#123456');
          expect($('#2-1 line').attr('stroke')).toEqual('#123456');
        });
  
        it('should be able to use a colour based on attribute value', function () {
          var nodes = helper.createSimpleNodes([1, 2, 3, 4]),
            n1 = nodes[0],
            n2 = nodes[1],
            n3 = nodes[2],
            n4 = nodes[3],
            edges = [{
              _id: '1-2',
              source: n1,
              target: n2,
              _data: {
                label: 'lbl1'
              }
            }, {
              _id: '2-3',
              source: n2,
              target: n3,
              _data: {
                label: 'lbl2'
              }
            }, {
              _id: '3-4',
              source: n3,
              target: n4,
              _data: {
                label: 'lbl3'
              }
            }, {
              _id: '4-1',
              source: n4,
              target: n1,
              _data: {
                label: 'lbl1'
              }
            }],
            shaper = new EdgeShaper(d3.select('svg'),
              {
                color: {
                  type: 'attribute',
                  key: 'label'
                }
              }
            ),
            c1,c2,c3,c4;
          shaper.drawEdges(edges);
  
          c1 = $('#1-2').attr('stroke');
          c2 = $('#2-3').attr('stroke');
          c3 = $('#3-4').attr('stroke');
          c4 = $('#4-1').attr('stroke');
  
          expect(c1).toBeDefined();
          expect(c2).toBeDefined();
          expect(c3).toBeDefined();
          expect(c4).toBeDefined();
  
          expect(c1).toEqual(c4);
          expect(c1).not.toEqual(c2);
          expect(c1).not.toEqual(c3);
          expect(c2).not.toEqual(c3);
        });
  
        it('should be able to use a gradient colour', function () {
          var nodes = helper.createSimpleNodes([1, 2]),
            edges = [{
              _id: '1-2',
              source: nodes[0],
              target: nodes[1]
            }],
            shaper = new EdgeShaper(d3.select('svg'),
              {
                color: {
                  type: 'gradient',
                  source: '#123456',
                  target: '#654321'
                }
              }
            ),
            allStops;
          shaper.drawEdges(edges);
  
          expect($('#1-2 line').attr('stroke')).toEqual('url(#gradientEdgeColor)');
  
          // Sorry if the line is plain horizontal it is not displayed.
          expect($('#1-2 line').attr('y2')).toBeDefined();
          expect($('#1-2 line').attr('y2')).not.toEqual('0');
  
          // This check may not work
          // expect($("svg defs linearGradient").length).toEqual(1)
          expect($('svg defs #gradientEdgeColor').length).toEqual(1);
  
          allStops = $('svg defs #gradientEdgeColor stop');
          expect(allStops[0].getAttribute('offset')).toEqual('0');
          expect(allStops[1].getAttribute('offset')).toEqual('0.4');
          expect(allStops[2].getAttribute('offset')).toEqual('0.6');
          expect(allStops[3].getAttribute('offset')).toEqual('1');
  
          expect(allStops[0].getAttribute('stop-color')).toEqual('#123456');
          expect(allStops[1].getAttribute('stop-color')).toEqual('#123456');
          expect(allStops[2].getAttribute('stop-color')).toEqual('#654321');
          expect(allStops[3].getAttribute('stop-color')).toEqual('#654321');
        });
      });
  
      describe('configured for arrow shape', function () {
        var shaper;
  
        beforeEach(function () {
          var nodes = helper.createSimpleNodes([1, 2]),
            edges = [
              {
                _id: '1-2',
                source: nodes[0],
                target: nodes[1]
              }
          ];
          shaper = new EdgeShaper(d3.select('svg'), {
            shape: {
              type: EdgeShaper.shapes.ARROW
            }
          });
          shaper.drawEdges(edges);
        });
  
        it('should clean the defs if a different shape is chosen', function () {
          shaper.changeTo({
            shape: {
              type: EdgeShaper.shapes.NONE
            }
          });
          expect($('#1-2').attr('marker-end')).toBeUndefined();
          expect($('svg defs marker#arrow').length).toEqual(0);
        });
  
        it('should not append the same marker multiple times', function () {
          shaper.changeTo({
            shape: {
              type: EdgeShaper.shapes.ARROW
            }
          });
          expect($('svg defs marker#arrow').length).toEqual(1);
          shaper.changeTo({
            shape: {
              type: EdgeShaper.shapes.ARROW
            }
          });
          expect($('svg defs marker#arrow').length).toEqual(1);
        });
      });
  
      describe('when edges are already drawn', function () {
        var edges,
          nodes,
          clicked,
          click = function (edge) {
            clicked[edge._id] = !clicked[edge._id];
          },
          shaper;
  
        beforeEach(function () {
          nodes = helper.createSimpleNodes([1, 2, 3, 4]);
          edges = [
            {_id: '1-2', source: nodes[0], target: nodes[1]},
            {_id: '2-3', source: nodes[1], target: nodes[2]},
            {_id: '3-4', source: nodes[2], target: nodes[3]}
          ];
          clicked = [];
          shaper = new EdgeShaper(d3.select('svg'));
          shaper.drawEdges(edges);
          expect($('svg .link').length).toEqual(3);
        });
  
        it('should be able to add a click event to existing edges', function () {
          expect($('svg .link').length).toEqual(3);
          shaper.changeTo({
            actions: {
              click: click
            }
          });
          helper.simulateMouseEvent('click', '1-2');
          helper.simulateMouseEvent('click', '3-4');
          expect(clicked['1-2']).toBeTruthy();
          expect(clicked['3-4']).toBeTruthy();
          expect(clicked['2-3']).toBeUndefined();
        });
  
        it('should add a click event to newly arriving edges', function () {
          shaper.changeTo({
            actions: {
              click: click
            }
          });
          edges.push({_id: '4-1', source: nodes[3], target: nodes[0]});
          edges.push({_id: '1-3', source: nodes[0], target: nodes[2]});
          shaper.drawEdges(edges);
  
          helper.simulateMouseEvent('click', '4-1');
          helper.simulateMouseEvent('click', '1-3');
          expect($('svg .link').length).toEqual(5);
          expect(clicked['4-1']).toBeTruthy();
          expect(clicked['1-3']).toBeTruthy();
          expect(clicked['1-2']).toBeUndefined();
          expect(clicked['2-3']).toBeUndefined();
          expect(clicked['3-4']).toBeUndefined();
        });
  
        it('should display each edge exactly once if an event is added', function () {
          shaper.changeTo({
            actions: {
              click: function () {return 0;}
            }
          });
          expect($('svg .link').length).toEqual(3);
          shaper.changeTo({
            actions: {
              click: function () {return 0;}
            }
          });
          expect($('svg .link').length).toEqual(3);
          shaper.changeTo({
            actions: {
              click: function () {return 0;}
            }
          });
          expect($('svg .link').length).toEqual(3);
        });
      });
  
      describe('configured for label', function () {
        var shaper;
  
        beforeEach(function () {
          shaper = new EdgeShaper(d3.select('svg'), {'label': 'label'});
        });
  
        it('should display the correct label', function () {
          var nodes = helper.createSimpleNodes([1, 2, 3, 4]),
            edges = [
              {
                _id: '1-2',
                source: nodes[0],
                target: nodes[1],
                _data: {
                  label: 'first'
                }
              },
              {
                _id: '2-3',
                source: nodes[1],
                target: nodes[2],
                _data: {
                  label: 'second'
                }
              },
              {
                _id: '3-4',
                source: nodes[2],
                target: nodes[3],
                _data: {
                  label: 'third'
                }
              },
              {
                _id: '4-1',
                source: nodes[3],
                target: nodes[0],
                _data: {
                  label: 'fourth'
                }
              }
          ];
          shaper.drawEdges(edges);
  
          expect($('text').length).toEqual(4);
          expect($('#1-2 text')[0].textContent).toEqual('first');
          expect($('#2-3 text')[0].textContent).toEqual('second');
          expect($('#3-4 text')[0].textContent).toEqual('third');
          expect($('#4-1 text')[0].textContent).toEqual('fourth');
        });
  
        it('should display the label at the correct position', function () {
          var nodes = [
              {
                _id: 1,
                position: {
                  x: 20,
                  y: 20,
                  z: 1
                }
              },
              {
                _id: 2,
                position: {
                  x: 100,
                  y: 20,
                  z: 1
                }
              }
            ],
            edges = [
              {
                _id: '1-2',
                source: nodes[0],
                target: nodes[1],
                _data: {
                  label: 'first'
                }
              }
          ];
          shaper.drawEdges(edges);
  
          expect($('#1-2 text').attr('transform')).toEqual('translate('
            + getDistance(nodes[0].position, nodes[1].position) / 2
            + ', -3)');
        });
  
        it('should ignore other attributes', function () {
          var nodes = helper.createSimpleNodes([1, 2, 3, 4]),
            edges = [
              {
                _id: '1-2',
                source: nodes[0],
                target: nodes[1],
                _data: {
                  'label': 'correct'
                }
              },
              {
                _id: '2-3',
                source: nodes[1],
                target: nodes[2],
                _data: {
                  alt: 'incorrect'
                }
              },
              {
                _id: '3-4',
                source: nodes[2],
                target: nodes[3],
                _data: {}
              },
              {
                _id: '4-1',
                source: nodes[3],
                target: nodes[0],
                _data: {
                  'label': 'correct',
                  'alt': 'incorrect'
                }
              }
          ];
          shaper.drawEdges(edges);
  
          expect($('text').length).toEqual(4);
          expect($('#1-2 text')[0].textContent).toEqual('correct');
          expect($('#2-3 text')[0].textContent).toEqual('');
          expect($('#3-4 text')[0].textContent).toEqual('');
          expect($('#4-1 text')[0].textContent).toEqual('correct');
        });
  
        it('should be able to switch to another label', function () {
          var nodes = helper.createSimpleNodes([1, 2]),
            edges = [
              {
                _id: '1-2',
                source: nodes[0],
                target: nodes[1],
                _data: {
                  label: 'old'
                }
              },
              {
                _id: '2-1',
                source: nodes[1],
                target: nodes[0],
                _data: {
                  'new': 'new'
                }
              }
          ];
          shaper.drawEdges(edges);
  
          expect($('#1-2')[0].textContent).toEqual('old');
          expect($('#2-1')[0].textContent).toEqual('');
  
          shaper.changeTo({label: 'new'});
  
          expect($('#1-2')[0].textContent).toEqual('');
          expect($('#2-1')[0].textContent).toEqual('new');
        });
  
        it('should be possible to toggle label display', function () {
          var nodes = helper.createSimpleNodes([1, 2]),
            edges = [
              {
                _id: '1-2',
                source: nodes[0],
                target: nodes[1],
                _data: {
                  label: 'test'
                }
              }
          ];
          shaper.drawEdges(edges);
  
          expect($('#1-2')[0].textContent).toEqual('test');
  
          shaper.activateLabel(false);
  
          expect($('#1-2')[0].textContent).toEqual('');
          expect($('#1-2 text').length).toEqual(0);
  
          shaper.activateLabel(true);
  
          expect($('#1-2')[0].textContent).toEqual('test');
        });
      });
  
      describe('using a function for labels', function () {
        var shaper,
          labelFunction = function (edge) {
            if (edge.source._id === 1) {
              return 'from first';
            }
            if (edge.target._id === 3) {
              return 'to third';
            }
            return 'default';
        };
  
        beforeEach(function () {
          shaper = new EdgeShaper(d3.select('svg'), {'label': labelFunction});
        });
  
        it('should display the correct label', function () {
          var nodes = helper.createSimpleNodes([1, 2, 3, 4]),
            edges = [
              {
                _id: '1-2',
                source: nodes[0],
                target: nodes[1]
              },
              {
                _id: '2-3',
                source: nodes[1],
                target: nodes[2]
              },
              {
                _id: '3-4',
                source: nodes[2],
                target: nodes[3]
              },
              {
                _id: '4-1',
                source: nodes[3],
                target: nodes[0]
              }
          ];
          shaper.drawEdges(edges);
  
          expect($('text').length).toEqual(4);
          expect($('#1-2 text')[0].textContent).toEqual('from first');
          expect($('#2-3 text')[0].textContent).toEqual('to third');
          expect($('#3-4 text')[0].textContent).toEqual('default');
          expect($('#4-1 text')[0].textContent).toEqual('default');
        });
      });
  
      describe('that has already drawn some edges', function () {
        var shaper, edges, nodes;
  
        beforeEach(function () {
          shaper = new EdgeShaper(d3.select('svg'));
          nodes = helper.createSimpleNodes([1, 2, 3, 4]);
          edges = [
            {
              _id: '1-2',
              source: nodes[0],
              target: nodes[1]
            },
            {
              _id: '2-3',
              source: nodes[1],
              target: nodes[2]
            },
            {
              _id: '3-4',
              source: nodes[2],
              target: nodes[3]
            },
            {
              _id: '4-1',
              source: nodes[3],
              target: nodes[0]
            }
          ];
          shaper.drawEdges(edges);
        });
  
        it('should be able to draw more edges', function () {
          edges.push(
            {
              _id: '3-1',
              source: nodes[2],
              target: nodes[0]
            }
          );
          edges.push({
            _id: '2-4',
            source: nodes[1],
            target: nodes[3]
          });
          shaper.drawEdges(edges);
          expect($('svg .link').length).toEqual(6);
          expect($('svg #2-3')[0]).toBeDefined();
          expect($('svg #4-1')[0]).toBeDefined();
          expect($('svg #3-1')[0]).toBeDefined();
          expect($('svg #2-4')[0]).toBeDefined();
          expect($('svg #1-2')[0]).toBeDefined();
          expect($('svg #3-4')[0]).toBeDefined();
        });
  
        it('should be able to remove edges', function () {
          edges.splice(2, 1);
          edges.splice(0, 1);
          shaper.drawEdges(edges);
          expect($('svg .link').length).toEqual(2);
          expect($('svg #2-3')[0]).toBeDefined();
          expect($('svg #4-1')[0]).toBeDefined();
          expect($('svg #1-2')[0]).toBeUndefined();
          expect($('svg #3-4')[0]).toBeUndefined();
        });
  
        it('should be able to add some edges and remove other edges', function () {
          edges.splice(2, 1);
          edges.splice(0, 1);
          edges.push(
            {
              _id: '3-1',
              source: nodes[2],
              target: nodes[0]
            }
          );
          edges.push({
            _id: '2-4',
            source: nodes[1],
            target: nodes[3]
          });
          shaper.drawEdges(edges);
  
          expect($('svg .link').length).toEqual(4);
          expect($('svg #2-3')[0]).toBeDefined();
          expect($('svg #4-1')[0]).toBeDefined();
          expect($('svg #3-1')[0]).toBeDefined();
          expect($('svg #2-4')[0]).toBeDefined();
          expect($('svg #1-2')[0]).toBeUndefined();
          expect($('svg #3-4')[0]).toBeUndefined();
        });
      });
  
      describe('that has an other parent then body.svg', function () {
        it('should draw edges in the correct position', function () {
          var internalObject = d3.select('svg')
              .append('g')
              .append('svg')
              .append('g'),
            shaper = new EdgeShaper(internalObject),
            nodes = helper.createSimpleNodes([1, 2]),
            source = nodes[0],
            target = nodes[1],
            edges = [
              {
                _id: '1-2',
                source: source,
                target: target
              }
          ];
  
          shaper.drawEdges(edges);
  
          expect($('svg g svg g .link line').length).toEqual(1);
        });
      });
    });
  }());
  