From b4cc0f8e524e854bb0304c68013fafc15d054b44 Mon Sep 17 00:00:00 2001 From: sunilyadav840 Date: Wed, 5 May 2021 17:59:54 +0530 Subject: [PATCH] fixed test cases errors --- .../IndexingPolicyComponent.tsx | 22 +- .../D3ForceGraph.test.ts | 24 +- .../GraphExplorerComponent/D3ForceGraph.ts | 289 +++++++++--------- src/Utils/QueryUtils.test.ts | 34 ++- src/setupTests.ts | 9 + 5 files changed, 202 insertions(+), 176 deletions(-) diff --git a/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.tsx b/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.tsx index 9e4949bf1..e936e2ff9 100644 --- a/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.tsx +++ b/src/Explorer/Controls/Settings/SettingsSubComponents/IndexingPolicyComponent.tsx @@ -87,16 +87,18 @@ export class IndexingPolicyComponent extends React.Component< private async createIndexingPolicyEditor(): Promise { const value: string = JSON.stringify(this.props.indexingPolicyContent, undefined, 4); const monaco = await loadMonaco(); - this.indexingPolicyEditor = monaco.editor.create(this.indexingPolicyDiv.current, { - value: value, - language: "json", - readOnly: isIndexTransforming(this.props.indexTransformationProgress), - ariaLabel: "Indexing Policy", - }); - if (this.indexingPolicyEditor) { - const indexingPolicyEditorModel = this.indexingPolicyEditor.getModel(); - indexingPolicyEditorModel.onDidChangeContent(this.onEditorContentChange.bind(this)); - this.props.logIndexingPolicySuccessMessage(); + if (monaco.editor) { + this.indexingPolicyEditor = monaco.editor.create(this.indexingPolicyDiv.current, { + value: value, + language: "json", + readOnly: isIndexTransforming(this.props.indexTransformationProgress), + ariaLabel: "Indexing Policy", + }); + if (this.indexingPolicyEditor) { + const indexingPolicyEditorModel = this.indexingPolicyEditor.getModel(); + indexingPolicyEditorModel.onDidChangeContent(this.onEditorContentChange.bind(this)); + this.props.logIndexingPolicySuccessMessage(); + } } } diff --git a/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.test.ts b/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.test.ts index 1f434d577..b65b82af9 100644 --- a/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.test.ts +++ b/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.test.ts @@ -1,7 +1,7 @@ import * as sinon from "sinon"; -import { D3ForceGraph, LoadMoreDataAction, D3GraphNodeData } from "./D3ForceGraph"; -import { D3Node, D3Link, GraphData } from "../GraphExplorerComponent/GraphData"; import GraphTab from "../../Tabs/GraphTab"; +import { D3Link, D3Node, GraphData } from "../GraphExplorerComponent/GraphData"; +import { D3ForceGraph, D3GraphNodeData, LoadMoreDataAction } from "./D3ForceGraph"; describe("D3ForceGraph", () => { const v1Id = "v1"; @@ -138,18 +138,20 @@ describe("D3ForceGraph", () => { it("should call onHighlightedNode callback when mouse hovering over node", () => { forceGraph.params.onGraphUpdated = () => { - const mouseoverEvent = document.createEvent("Events"); - mouseoverEvent.initEvent("mouseover", true, false); - $(rootNode).find(".node")[0].dispatchEvent(mouseoverEvent); // [0] is v1 vertex + if (document) { + const mouseoverEvent = document.createEvent("Events"); + mouseoverEvent.initEvent("mouseover", true, false); + $(rootNode).find(".node")[0].dispatchEvent(mouseoverEvent); // [0] is v1 vertex - // onHighlightedNode is always called once to clear the selection - expect((forceGraph.params.onHighlightedNode as sinon.SinonSpy).calledTwice).toBe(true); + // onHighlightedNode is always called once to clear the selection + expect((forceGraph.params.onHighlightedNode as sinon.SinonSpy).calledTwice).toBe(true); - const onHighlightedNode = (forceGraph.params.onHighlightedNode as sinon.SinonSpy).args[1][0] as D3GraphNodeData; - expect(onHighlightedNode).not.toBe(null); - expect(onHighlightedNode.id).toEqual(v1Id); + const onHighlightedNode = (forceGraph.params.onHighlightedNode as sinon.SinonSpy) + .args[1][0] as D3GraphNodeData; + expect(onHighlightedNode).not.toBe(null); + expect(onHighlightedNode.id).toEqual(v1Id); + } }; - forceGraph.updateGraph(newGraph); }); }); diff --git a/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts b/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts index 393e92b84..dacb37eab 100644 --- a/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts +++ b/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts @@ -626,12 +626,12 @@ export class D3ForceGraph implements GraphRenderer { this.addNewLinks(); - const nodes = this.simulation.nodes(); + const nodes = this.simulation && this.simulation.nodes(); this.redrawGraph(); this.animateBigBang(nodes, newNodes); - this.simulation.alpha(1).restart(); + this.simulation && this.simulation.alpha(1).restart(); this.params.onGraphUpdated(new Date().getTime()); }); @@ -651,140 +651,143 @@ export class D3ForceGraph implements GraphRenderer { } private addNewLinks(): d3.Selection { - const newLinks = this.linkSelection.enter().append("g").attr("class", "markerEndContainer"); + let newLinks: any = {}; + if (this.linkSelection) { + newLinks = this.linkSelection.enter().append("g").attr("class", "markerEndContainer"); + const line = newLinks + .append("path") + .attr("class", "link") + .attr("fill", "none") + .attr("stroke-width", this.params.graphConfig.linkWidth()) + .attr("stroke", this.params.graphConfig.linkColor()); - const line = newLinks - .append("path") - .attr("class", "link") - .attr("fill", "none") - .attr("stroke-width", this.params.graphConfig.linkWidth()) - .attr("stroke", this.params.graphConfig.linkColor()); + if (D3ForceGraph.useSvgMarkerEnd()) { + line.attr("marker-end", `url(#${this.getArrowHeadSymbolId()}-marker)`); + } else { + newLinks + .append("g") + .append("use") + .attr("xlink:href", `#${this.getArrowHeadSymbolId()}-nonMarker`) + .attr("class", "markerEnd link") + .attr("fill", this.params.graphConfig.linkColor()) + .classed(`${this.getArrowHeadSymbolId()}`, true); + } - if (D3ForceGraph.useSvgMarkerEnd()) { - line.attr("marker-end", `url(#${this.getArrowHeadSymbolId()}-marker)`); - } else { - newLinks - .append("g") - .append("use") - .attr("xlink:href", `#${this.getArrowHeadSymbolId()}-nonMarker`) - .attr("class", "markerEnd link") - .attr("fill", this.params.graphConfig.linkColor()) - .classed(`${this.getArrowHeadSymbolId()}`, true); + this.linkSelection = newLinks.merge(this.linkSelection); } - - this.linkSelection = newLinks.merge(this.linkSelection); return newLinks; } private addNewNodes(): d3.Selection { var self = this; + let newNodes: any = {}; + if (this.nodeSelection) { + newNodes = this.nodeSelection + .enter() + .append("g") + .attr("class", (d: D3Node) => { + return d._isRoot ? "node root" : "node"; + }) + .call( + drag() + .on("start", ((e: D3DragEvent, d: D3Node) => { + return this.dragstarted(d, e); + }) as any) + .on("drag", ((e: D3DragEvent, d: D3Node) => { + return this.dragged(d, e); + }) as any) + .on("end", ((e: D3DragEvent, d: D3Node) => { + return this.dragended(d, e); + }) as any) + ) + .on("mouseover", (_: MouseEvent, d: D3Node) => { + if (this.isHighlightDisabled || this.selectedNode || this.isDragging) { + return; + } - const newNodes = this.nodeSelection - .enter() - .append("g") - .attr("class", (d: D3Node) => { - return d._isRoot ? "node root" : "node"; - }) - .call( - drag() - .on("start", ((e: D3DragEvent, d: D3Node) => { - return this.dragstarted(d, e); - }) as any) - .on("drag", ((e: D3DragEvent, d: D3Node) => { - return this.dragged(d, e); - }) as any) - .on("end", ((e: D3DragEvent, d: D3Node) => { - return this.dragended(d, e); - }) as any) - ) - .on("mouseover", (_: MouseEvent, d: D3Node) => { - if (this.isHighlightDisabled || this.selectedNode || this.isDragging) { - return; - } + this.highlightNode(this, d); + this.simulation.stop(); + }) + .on("mouseout", (_: MouseEvent, d: D3Node) => { + if (this.isHighlightDisabled || this.selectedNode || this.isDragging) { + return; + } - this.highlightNode(this, d); - this.simulation.stop(); - }) - .on("mouseout", (_: MouseEvent, d: D3Node) => { - if (this.isHighlightDisabled || this.selectedNode || this.isDragging) { - return; - } + this.unhighlightNode(); - this.unhighlightNode(); + this.simulation.restart(); + }) + .each((d: D3Node) => { + // Initial position for nodes. This prevents blinking as following the tween transition doesn't always start right away + d.x = self.viewCenter.x; + d.y = self.viewCenter.y; + }); - this.simulation.restart(); - }) - .each((d: D3Node) => { - // Initial position for nodes. This prevents blinking as following the tween transition doesn't always start right away - d.x = self.viewCenter.x; - d.y = self.viewCenter.y; - }); + newNodes + .append("circle") + .attr("fill", this.getNodeColor.bind(this)) + .attr("class", "main") + .attr("r", this.params.graphConfig.nodeSize()); - newNodes - .append("circle") - .attr("fill", this.getNodeColor.bind(this)) - .attr("class", "main") - .attr("r", this.params.graphConfig.nodeSize()); - - var iconGroup = newNodes - .append("g") - .attr("class", "iconContainer") - .attr("tabindex", 0) - .attr("aria-label", (d: D3Node) => { - return this.retrieveNodeCaption(d); - }) - .on("dblclick", function (_: MouseEvent, d: D3Node) { - // this is the element - self.onNodeClicked(this.parentNode, d); - }) - .on("click", function (_: MouseEvent, d: D3Node) { - // this is the element - self.onNodeClicked(this.parentNode, d); - }) - .on("keypress", function (event: KeyboardEvent, d: D3Node) { - if (event.charCode === Constants.KeyCodes.Space || event.charCode === Constants.KeyCodes.Enter) { - event.stopPropagation(); + var iconGroup = newNodes + .append("g") + .attr("class", "iconContainer") + .attr("tabindex", 0) + .attr("aria-label", (d: D3Node) => { + return this.retrieveNodeCaption(d); + }) + .on("dblclick", function (_: MouseEvent, d: D3Node) { // this is the element self.onNodeClicked(this.parentNode, d); - } - }); - var nodeSize = this.params.graphConfig.nodeSize(); - var bgsize = nodeSize + 1; + }) + .on("click", function (_: MouseEvent, d: D3Node) { + // this is the element + self.onNodeClicked(this.parentNode, d); + }) + .on("keypress", function (event: KeyboardEvent, d: D3Node) { + if (event.charCode === Constants.KeyCodes.Space || event.charCode === Constants.KeyCodes.Enter) { + event.stopPropagation(); + // this is the element + self.onNodeClicked(this.parentNode, d); + } + }); + var nodeSize = this.params.graphConfig.nodeSize(); + var bgsize = nodeSize + 1; - iconGroup - .append("rect") - .attr("x", -bgsize) - .attr("y", -bgsize) - .attr("width", bgsize * 2) - .attr("height", bgsize * 2) - .attr("fill-opacity", (d: D3Node) => { - return this.params.graphConfig.nodeIconKey() ? 1 : 0; - }) - .attr("class", "icon-background"); + iconGroup + .append("rect") + .attr("x", -bgsize) + .attr("y", -bgsize) + .attr("width", bgsize * 2) + .attr("height", bgsize * 2) + .attr("fill-opacity", (d: D3Node) => { + return this.params.graphConfig.nodeIconKey() ? 1 : 0; + }) + .attr("class", "icon-background"); - // Possible icon: if xlink:href is undefined, the image won't show - iconGroup - .append("svg:image") - .attr("xlink:href", (d: D3Node) => { - return D3ForceGraph.computeImageData(d, this.params.graphConfig); - }) - .attr("x", -nodeSize) - .attr("y", -nodeSize) - .attr("height", nodeSize * 2) - .attr("width", nodeSize * 2) - .attr("class", "icon"); + // Possible icon: if xlink:href is undefined, the image won't show + iconGroup + .append("svg:image") + .attr("xlink:href", (d: D3Node) => { + return D3ForceGraph.computeImageData(d, this.params.graphConfig); + }) + .attr("x", -nodeSize) + .attr("y", -nodeSize) + .attr("height", nodeSize * 2) + .attr("width", nodeSize * 2) + .attr("class", "icon"); - newNodes - .append("text") - .attr("class", "caption") - .attr("dx", D3ForceGraph.TEXT_DX) - .attr("dy", ".35em") - .text((d: D3Node) => { - return this.retrieveNodeCaption(d); - }); - - this.nodeSelection = newNodes.merge(this.nodeSelection); + newNodes + .append("text") + .attr("class", "caption") + .attr("dx", D3ForceGraph.TEXT_DX) + .attr("dy", ".35em") + .text((d: D3Node) => { + return this.retrieveNodeCaption(d); + }); + this.nodeSelection = newNodes.merge(this.nodeSelection); + } return newNodes; } @@ -967,34 +970,36 @@ export class D3ForceGraph implements GraphRenderer { * Remove LoadMore subassembly for existing nodes that show all their children in the graph */ private updateLoadMore(nodeSelection: d3.Selection) { - const self = this; - nodeSelection.selectAll(".loadmore").remove(); + if (nodeSelection) { + const self = this; + nodeSelection.selectAll(".loadmore").remove(); - var nodeSize = this.params.graphConfig.nodeSize(); - const rootSelectionG = nodeSelection - .filter((d: D3Node) => { - return !!d._isRoot && !!d._pagination; - }) - .append("g") - .attr("class", "loadmore"); - this.createPaginationControl(rootSelectionG, nodeSize); + var nodeSize = this.params.graphConfig.nodeSize(); + const rootSelectionG = nodeSelection + .filter((d: D3Node) => { + return !!d._isRoot && !!d._pagination; + }) + .append("g") + .attr("class", "loadmore"); + this.createPaginationControl(rootSelectionG, nodeSize); - const nodeNeighborMap = D3ForceGraph.countEdges(this.linkSelection.data()); - const missingNeighborNonRootG = nodeSelection - .filter((d: D3Node) => { - return !( - d._isRoot || - (d._outEAllLoaded && - d._inEAllLoaded && - nodeNeighborMap.get(d.id) >= d._outEdgeIds.length + d._inEdgeIds.length) - ); - }) - .append("g") - .attr("class", "loadmore"); - this.createLoadMoreControl(missingNeighborNonRootG, nodeSize); + const nodeNeighborMap = D3ForceGraph.countEdges(this.linkSelection.data()); + const missingNeighborNonRootG = nodeSelection + .filter((d: D3Node) => { + return !( + d._isRoot || + (d._outEAllLoaded && + d._inEAllLoaded && + nodeNeighborMap.get(d.id) >= d._outEdgeIds.length + d._inEdgeIds.length) + ); + }) + .append("g") + .attr("class", "loadmore"); + this.createLoadMoreControl(missingNeighborNonRootG, nodeSize); - // Don't color icons individually, just the definitions - this.svg.selectAll("#loadMoreIcon ellipse").attr("fill", this.params.graphConfig.nodeColor()); + // Don't color icons individually, just the definitions + this.svg.selectAll("#loadMoreIcon ellipse").attr("fill", this.params.graphConfig.nodeColor()); + } } /** diff --git a/src/Utils/QueryUtils.test.ts b/src/Utils/QueryUtils.test.ts index 76e525a06..8603afd20 100644 --- a/src/Utils/QueryUtils.test.ts +++ b/src/Utils/QueryUtils.test.ts @@ -1,6 +1,6 @@ -import * as DataModels from "../Contracts/DataModels"; import * as Q from "q"; import * as sinon from "sinon"; +import * as DataModels from "../Contracts/DataModels"; import * as ViewModels from "../Contracts/ViewModels"; import * as QueryUtils from "./QueryUtils"; @@ -101,12 +101,16 @@ describe("Query Utils", () => { }); it("should not proceed with subsequent queries if the first one errors out", (done) => { - const queryStub = sinon.stub().returns(Q.reject("Error injected for testing purposes")); - QueryUtils.queryPagesUntilContentPresent(0, queryStub).finally(() => { - expect(queryStub.callCount).toBe(1); - expect(queryStub.getCall(0).args[0]).toBe(0); - done(); - }); + try { + const queryStub = sinon.stub().returns(Q.reject("Error injected for testing purposes")); + QueryUtils.queryPagesUntilContentPresent(0, queryStub).finally(() => { + expect(queryStub.callCount).toBe(1); + expect(queryStub.getCall(0).args[0]).toBe(0); + done(); + }); + } catch (error) { + console.error(error); + } }); }); @@ -176,12 +180,16 @@ describe("Query Utils", () => { }); it("should not proceed with subsequent fetches if the first one errors out", (done) => { - const queryStub = sinon.stub().returns(Q.reject("Error injected for testing purposes")); - QueryUtils.queryAllPages(queryStub).finally(() => { - expect(queryStub.callCount).toBe(1); - expect(queryStub.getCall(0).args[0]).toBe(0); - done(); - }); + try { + const queryStub = sinon.stub().returns(Q.reject("Error injected for testing purposes")); + QueryUtils.queryAllPages(queryStub).finally(() => { + expect(queryStub.callCount).toBe(1); + expect(queryStub.getCall(0).args[0]).toBe(0); + done(); + }); + } catch (error) { + console.error(error); + } }); }); }); diff --git a/src/setupTests.ts b/src/setupTests.ts index 86f378bc0..1334c0923 100644 --- a/src/setupTests.ts +++ b/src/setupTests.ts @@ -16,3 +16,12 @@ if (typeof window.URL.createObjectURL === "undefined") { require("jquery-ui-dist/jquery-ui"); (global).TextEncoder = TextEncoder; (global).TextDecoder = TextDecoder; + +// In Node v7 unhandled promise rejections +if (process.env.LISTENING_TO_UNHANDLED_REJECTION !== "true") { + process.on("unhandledRejection", (reason) => { + console.error("reason", reason); + }); + // Avoid memory leak by adding too many listeners + process.env.LISTENING_TO_UNHANDLED_REJECTION = "true"; +}