From bb570af2c841614bffe5734154bfdfe1c42124b9 Mon Sep 17 00:00:00 2001 From: Michael Pollmeier Date: Mon, 26 Aug 2024 10:32:47 +0200 Subject: [PATCH] TestUtils: copy single node (#252) --- core/src/main/scala/flatgraph/Accessors.scala | 12 +++++++--- .../main/scala/flatgraph/misc/TestUtils.scala | 17 +++++++++++++ .../src/test/scala/flatgraph/GraphTests.scala | 24 +++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/flatgraph/Accessors.scala b/core/src/main/scala/flatgraph/Accessors.scala index 9d3ed644..ef947079 100644 --- a/core/src/main/scala/flatgraph/Accessors.scala +++ b/core/src/main/scala/flatgraph/Accessors.scala @@ -162,14 +162,20 @@ object Accessors { new ISeq(vals, qty(seq), qty(seq + 1)) } - def getNodeProperties(node: GNode): IterableOnce[(String, IndexedSeq[Any])] = { + def _getNodeProperties(node: GNode): IterableOnce[(Int, IndexedSeq[Any])] = { val schema = node.graph.schema for { propertyKind <- schema.propertyKinds property = Accessors.getNodeProperty(node, propertyKind) if property.nonEmpty - propertyLabel = schema.getPropertyLabel(node.nodeKind, propertyKind) - } yield propertyLabel -> property + } yield propertyKind -> property + } + + def getNodeProperties(node: GNode): IterableOnce[(String, IndexedSeq[Any])] = { + for { + (propertyKind, value) <- _getNodeProperties(node) + schema = node.graph.schema + } yield schema.getPropertyLabel(node.nodeKind, propertyKind) -> value } def getInverseIndex(graph: Graph, nodeKind: Int, propertyKind: Int): MultiDictIndex[GNode] = { diff --git a/core/src/main/scala/flatgraph/misc/TestUtils.scala b/core/src/main/scala/flatgraph/misc/TestUtils.scala index db8702e5..43b2a44a 100644 --- a/core/src/main/scala/flatgraph/misc/TestUtils.scala +++ b/core/src/main/scala/flatgraph/misc/TestUtils.scala @@ -60,7 +60,24 @@ object TestUtils { newGraph } + } + + /** copies a single GNode into a different graph, including all properties, but excluding edges */ + def copyNode(node: GNode, targetGraph: Graph): GNode = { + assert(node.graph.schema == targetGraph.schema, "schemas of the two graphs must be identical, but they are not...") + // first pass: create raw node + val newNode = new GenericDNode(node.nodeKind) + DiffGraphApplier.applyDiff(targetGraph, new DiffGraphBuilder(targetGraph.schema).addNode(newNode)) + val nodeInTargetGraph = newNode.storedRef.get // this is set by `applyDiff` + + // second pass: set node properties + val diffGraphForProperties = new DiffGraphBuilder(targetGraph.schema) + for { + (propertyKind, value) <- Accessors._getNodeProperties(node) + } diffGraphForProperties._setNodeProperty(nodeInTargetGraph, propertyKind, value) + DiffGraphApplier.applyDiff(targetGraph, diffGraphForProperties) + nodeInTargetGraph } } diff --git a/core/src/test/scala/flatgraph/GraphTests.scala b/core/src/test/scala/flatgraph/GraphTests.scala index ddd73037..701816b0 100644 --- a/core/src/test/scala/flatgraph/GraphTests.scala +++ b/core/src/test/scala/flatgraph/GraphTests.scala @@ -3,10 +3,12 @@ package flatgraph import flatgraph.TestHelpers.withTemporaryFile import flatgraph.TestSchema.testSerialization import flatgraph.misc.DebugDump.debugDump +import flatgraph.misc.TestUtils import flatgraph.storage.Deserialization import flatgraph.storage.Deserialization.DeserializationException import flatgraph.traversal.language.* import flatgraph.util.DiffToolTests +import flatgraph.util.DiffToolTests.sampleSchema import org.scalatest.matchers.should.Matchers import org.scalatest.matchers.should.Matchers.shouldBe import org.scalatest.wordspec.AnyWordSpec @@ -1091,4 +1093,26 @@ class GraphTests extends AnyWordSpec with Matchers { // original graph should be untouched debugDump(graph) shouldBe debugDumpOriginalGraph } + + "copy a single node (ignoring edges)" in { + val graphA = DiffToolTests.makeSampleGraph() + debugDump(graphA) shouldBe + """#Node numbers (kindId, nnodes) (0: 2), total 2 + |Node kind 0. (eid, nEdgesOut, nEdgesIn): (0, 1 [dense], 1 [dense]), + | V0_0 : 0: [A], 1: [40] + | V0_0 [0] -> (edgePropertyValue) V0_1 + | V0_1 : 0: [X, Y], 1: [50, 51] + | V0_1 [0] <- (edgePropertyValue) V0_0 + |""".stripMargin + + val V0_1 = graphA.node(kind = 0, seq = 1) + val graphB = new Graph(sampleSchema) + TestUtils.copyNode(V0_1, graphB) + + debugDump(graphB) shouldBe + """#Node numbers (kindId, nnodes) (0: 1), total 1 + |Node kind 0. (eid, nEdgesOut, nEdgesIn): (0, 0 [NA], 0 [NA]), + | V0_0 : 0: [X, Y], 1: [50, 51] + |""".stripMargin + } }