d3js unit testing removal of elements

家住魔仙堡 提交于 2019-12-02 07:27:28

问题


I am using jasmine to unit test some interactions in a d3.js chart. I have been using d3.timerFlush() to complete the executions of animations. This works great for when entering new elements or updating attribute, and I am able to accurately test the new values. However, I am having a hard time getting it to remove elements.

I have a method like this:

exit() {
    let arcs = svg.selectAll("path.arc");

    arcs.transition().duration(1000)
        .attrTween("d", function(d, i) { return vm._arcTween(this, d) })
        .remove();
}

And my test looks something like this:

it('it will remove all of the pie related elements from the DOM', () => {
        chartSvc.exit();
        d3.timerFlush();
        let elements = svg.querySelectorAll(/* selects my elements */);
        expect(elements.length).toEqual(0);
});

which fails. If I debug the tests, I can see that the elements are not being removed. However if I change the expect:

expect(pieChartSvc._arcTween).toHaveBeenCalled();

that passes, so I know that the method is being executed correctly and the timer flushed, but the elements aren't removed.

What am I doing wrong?

This issue: Disabling all D3 animations (for testing) does not answer my question. The transition is being executed and the elements have been changed to the state they are in before they are removed from the DOM, however they still appear on the DOM


回答1:


Alright, figured it out, d3 version 3 used to use date.now to measure time. Version 4 moved to performance.now.

So, the correct code should be:

it('it will remove all of the pie related elements from the DOM', () => {
    chartSvc.exit();
    performance.now = function() { return Infinity; };
    d3.timerFlush();
    let elements = svg.querySelectorAll(/* selects my elements */);
    expect(elements.length).toEqual(0);
});

Here's some test code:

<!DOCTYPE html>
<html>

  <head>
    <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
    <style>
      path {
        fill: none;
        stroke: steelblue;
      }
    </style>
  </head>

  <body>
    <svg width="300" height="300">
      <g transform="translate(20,20)">
        <path class="arc" d="M0,0L100,0"></path>
        <path class="arc" d="M0,50L100,50"></path>
        <path class="arc" d="M0,100L100,100"></path>
        <path class="arc" d="M0,150L100,150"></path>
      </g>
    </svg>
    <script>
      
      var svg = d3.select('svg');
      
      let arcs = svg.selectAll("path.arc");
      
      arcs.transition()
        .duration(10000)
        .remove();
          
      performance.now = function() { return Infinity; };
      d3.timerFlush();

    </script>
  </body>

</html>


来源:https://stackoverflow.com/questions/42538240/d3js-unit-testing-removal-of-elements

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!