d3.drag() 导致通过 jsdom 测试 mousedown 事件时出错

d3.drag() causes error in testing mousedown event via jsdom

添加 d3.drag() 导致在 jsdom 环境中通过 jest 测试 mousedown 事件时出错。

function App() {
    const array = [1];

    React.useEffect(() => {
        d3.select(".App")
            .style("outline", "none")
            .append("svg")
            .attr("width", "400px")
            .attr("height", "500px");

        d3.select('svg')
            .selectAll('g')
            .data(array)
            .join(
                enter => {
                    return enter
                        .append('text')
                        .attr('x', 100)
                        .attr('y', 100)
                        .attr('fill', '#000')
                        .text('hello');
                }
            )
            .call(d3.drag().on("start", () => {
                console.log("dragStart");
            }));
    }, []);

    return (
        <div className="App">
        </div>
    );
}

const wrapper = TestingLibraryReact.render(<App/>);
const circle = wrapper.container.querySelector('svg').querySelector("text");
TestingLibraryReact.fireEvent.mouseDown(circle);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom-test-utils.development.js"></script>
<script src="https://unpkg.com/@testing-library/react@11.2.2/dist/@testing-library/react.umd.js"></script>

错误:

    Error: Uncaught [TypeError: Cannot read property 'document' of null]
        at reportException (C:\MyFiles\workspace\d3-bug\node_modules\jsdom\lib\jsdom\living\helpers\runtime-script-errors.js:66:24)
        at invokeEventListeners (C:\MyFiles\workspace\d3-bug\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:209:9)
        at SVGElementImpl._dispatch (C:\MyFiles\workspace\d3-bug\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:119:9)
        at SVGElementImpl.dispatchEvent (C:\MyFiles\workspace\d3-bug\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:82:17)
        at SVGElement.dispatchEvent (C:\MyFiles\workspace\d3-bug\node_modules\jsdom\lib\jsdom\living\generated\EventTarget.js:157:21)
        at C:\MyFiles\workspace\d3-bug\node_modules\@testing-library\dom\dist\events.js:25:20

这是一个完整的例子: d3-bug.zip

使用非缩小版 d3 时出现的错误是 view is undefined。这是因为 d3 期望存在一些自定义属性 view,您不能通过测试库添加这些属性,因为 it's not in the list of curated events. However, you can just use vanilla JavaScript 如果您愿意:

function App() {
    const array = [1];

    React.useEffect(() => {
        d3.select(".App")
            .style("outline", "none")
            .append("svg")
            .attr("width", "400px")
            .attr("height", "500px");

        d3.select('svg')
            .selectAll('g')
            .data(array)
            .join(
                enter => {
                    return enter
                        .append('text')
                        .attr('x', 100)
                        .attr('y', 100)
                        .attr('fill', '#000')
                        .text('hello');
                }
            )
            .call(d3.drag().on("start", () => {
                console.log("dragStart");
            }));
    }, []);

    return (
        <div className="App">
        </div>
    );
}

const wrapper = TestingLibraryReact.render(<App/>);
const circle = wrapper.container.querySelector('svg').querySelector("text");

circle.dispatchEvent(new MouseEvent("mousedown", {
  view: window,
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom-test-utils.development.js"></script>
<script src="https://unpkg.com/@testing-library/react@11.2.2/dist/@testing-library/react.umd.js"></script>