-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathSchema02Test.scala
188 lines (155 loc) · 7.26 KB
/
Schema02Test.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import overflowdb.SchemaViolationException
import testschema02._
import testschema02.edges._
import testschema02.nodes._
import testschema02.traversal._
import scala.jdk.CollectionConverters.IteratorHasAsScala
import overflowdb.traversal._
class Schema02Test extends AnyWordSpec with Matchers {
import testschema02.traversal._
"constants" in {
BaseNode.Properties.Name.name shouldBe "NAME"
BaseNode.PropertyNames.Name shouldBe "NAME"
BaseNode.Edges.Out shouldBe Array(Edge1.Label)
BaseNode.Edges.In shouldBe Array(Edge2.Label)
Node1.Properties.Name.name shouldBe "NAME"
Node1.PropertyNames.Name shouldBe "NAME"
Node1.Edges.Out shouldBe Array(Edge1.Label)
Node1.Edges.In shouldBe Array(Edge2.Label)
}
"NewNode" can {
"be used as a product, e.g. for pretty printing" in {
val newNode = NewNode1().name("A").order(1)
newNode.productPrefix shouldBe "NewNode1"
newNode.productArity shouldBe 2
newNode.productElementName(0) shouldBe "order"
newNode.productElement(0) shouldBe Some(1)
newNode.productElementName(1) shouldBe "name"
newNode.productElement(1) shouldBe "A"
}
"get copied and mutated" in {
val original = NewNode1().name("A").order(1)
//verify that we can copy
val copy = original.copy
original.isInstanceOf[NewNode1] shouldBe true
copy.isInstanceOf[NewNode1] shouldBe true
copy.name shouldBe "A"
copy.order shouldBe Some(1)
//verify that copy preserved the static type, such that assignment is available
copy.name = "B"
copy.order = Some(2)
copy.name shouldBe "B"
copy.order shouldBe Some(2)
copy.name("C")
copy.name shouldBe "C"
copy.order(3)
copy.order shouldBe Some(3)
copy.order(Some(4))
copy.order shouldBe Some(4)
original.name shouldBe "A"
original.order shouldBe Some(1)
}
"copied and mutated when upcasted" in {
val original = NewNode1().name("A").order(1)
val upcasted: BaseNodeNew = original
val upcastedCopy = upcasted.copy
upcastedCopy.name = "C"
upcastedCopy.name shouldBe "C"
}
"be used as a Product" in {
val newNode = NewNode1().name("A").order(1)
newNode.productArity shouldBe 2
newNode.productElement(0) shouldBe Some(1)
newNode.productElement(1) shouldBe "A"
newNode.productPrefix shouldBe "NewNode1"
}
}
"working with a concrete sample graph" can {
val graph = TestSchema.empty.graph
val node1 = graph.addNode(Node1.Label, Node1.PropertyNames.Name, "node 01", PropertyNames.ORDER, 4)
val node2 = graph.addNode(Node2.Label, PropertyNames.NAME, "node 02", PropertyNames.ORDER, 3)
node1.addEdge(Edge1.Label, node2)
node2.addEdge(Edge2.Label, node1, PropertyNames.NAME, "edge 02")
def baseNodeTraversal = graph.nodes(Node1.Label).asScala.cast[BaseNode]
def node1Traversal = graph.nodes(Node1.Label).asScala.cast[Node1]
def node2Traversal = graph.nodes(Node2.Label).asScala.cast[Node2]
"lookup and traverse nodes/edges via domain specific dsl" in {
def baseNode = baseNodeTraversal.next()
def node1 = node1Traversal.next()
def node2 = node2Traversal.next()
baseNode.label shouldBe Node1.Label
node1.label shouldBe Node1.Label
node2.label shouldBe Node2.Label
baseNode.edge2In.l shouldBe Seq(node2)
baseNode.edge1Out.l shouldBe Seq(node2)
}
"generate custom defined stepNames from schema definition" in {
def baseNode = baseNodeTraversal.next()
def node1 = node1Traversal.next()
def node2 = node2Traversal.next()
val baseNodeToNode2: Traversal[Node2] = baseNode.customStepName1
baseNodeToNode2.l shouldBe Seq(node2)
val baseNodeTraversalToNode2: Traversal[Node2] = baseNodeTraversal.customStepName1
baseNodeTraversalToNode2.l shouldBe Seq(node2)
val baseNodeToNode2ViaEdge2: Node2 = baseNode.customStepName2Inverse
baseNodeToNode2ViaEdge2 shouldBe node2
val baseNodeTraversalToNode2ViaEdge2: Traversal[Node2] = baseNodeTraversal.customStepName2Inverse
baseNodeTraversalToNode2ViaEdge2.l shouldBe Seq(node2)
val node1ToNode2: Traversal[Node2] = node1.customStepName1
node1ToNode2.l shouldBe Seq(node2)
val node1TraversalToNode2: Traversal[Node2] = node1Traversal.customStepName1
node1TraversalToNode2.l shouldBe Seq(node2)
val node1ToNode2ViaEdge2: Node2 = node1.customStepName2Inverse
node1ToNode2ViaEdge2 shouldBe node2
val node1TraversalToNode2ViaEdge2: Traversal[Node2] = node1Traversal.customStepName2Inverse
node1TraversalToNode2ViaEdge2.l shouldBe Seq(node2)
val node2ToBaseNodeViaEdge2: BaseNode = node2.customStepName2
node2ToBaseNodeViaEdge2 shouldBe node1
val node2TraversalToBaseNodeViaEdge2: Traversal[BaseNode] = node2Traversal.customStepName2
node2TraversalToBaseNodeViaEdge2.l shouldBe Seq(node1)
val node2ToBaseNodeViaEdge1: Option[BaseNode] = node2.customStepName1Inverse
node2ToBaseNodeViaEdge1 shouldBe Some(node1)
val node2TraversalToBaseNodeViaEdge1: Traversal[BaseNode] = node2Traversal.customStepName1Inverse
node2TraversalToBaseNodeViaEdge1.l shouldBe Seq(node1)
}
"property filters" in {
baseNodeTraversal.name.l shouldBe Seq("node 01")
baseNodeTraversal.name(".*").size shouldBe 1
baseNodeTraversal.nameExact("node 01").size shouldBe 1
baseNodeTraversal.nameExact("not found", "node 01").size shouldBe 1
baseNodeTraversal.nameNot("abc").size shouldBe 1
node1Traversal.order.l shouldBe Seq(4)
node1Traversal.orderGt(3).size shouldBe 1
node1Traversal.orderLt(4).size shouldBe 0
node1Traversal.orderLte(4).size shouldBe 1
}
}
"provide detailed error message for schema violation" in {
val graph = TestSchema.empty.graph
def baseNodeTraversal = graph.nodes(Node1.Label).asScala.cast[BaseNode]
def node1Traversal = graph.nodes(Node1.Label).asScala.cast[Node1]
def node2Traversal = graph.nodes(Node2.Label).asScala.cast[Node2]
val node1 = graph.addNode(Node1.Label)
val node2 = graph.addNode(Node2.Label)
// no edge between these two nodes, which is a schema violation
the[SchemaViolationException].thrownBy {
node2Traversal.customStepName2.next()
}.getMessage should include ("OUT edge with label EDGE2 to an adjacent BASE_NODE is mandatory")
the[SchemaViolationException].thrownBy {
node1Traversal.customStepName2Inverse.next()
}.getMessage should include ("IN edge with label EDGE2 to an adjacent NODE2 is mandatory")
the[SchemaViolationException].thrownBy {
baseNodeTraversal.customStepName2Inverse.next()
}.getMessage should include ("IN edge with label EDGE2 to an adjacent NODE2 is mandatory")
}
"marker traits" in {
classOf[MarkerTrait1].isAssignableFrom(classOf[BaseNode]) shouldBe true
classOf[MarkerTrait1].isAssignableFrom(classOf[Node1]) shouldBe true
classOf[MarkerTrait2].isAssignableFrom(classOf[Node2]) shouldBe true
classOf[MarkerTrait1].isAssignableFrom(classOf[Node2]) shouldBe false
classOf[MarkerTrait2].isAssignableFrom(classOf[BaseNode]) shouldBe false
classOf[MarkerTrait2].isAssignableFrom(classOf[Node1]) shouldBe false
}
}