@Test
public void shouldGenerateNodesAndRelationshipsCorrectlyForVertexProperties() {
// todo: review this feature check - this test does a lot of stuff - maybe losing some important assertions this way
if (g.features().vertex().supportsMultiProperties()) {
g.tx().readWrite();
ExecutionEngine cypher = Neo4jHelper.getCypher(g);
Neo4jVertex a = (Neo4jVertex) g.addVertex("name", "marko", "name", "okram");
Neo4jVertex b = (Neo4jVertex) g.addVertex("name", "stephen", "location", "virginia");
tryCommit(g, g -> {
assertEquals(2, g.V().count().next().intValue());
assertEquals(2, a.properties("name").count().next().intValue());
assertEquals(1, b.properties("name").count().next().intValue());
assertEquals(1, b.properties("location").count().next().intValue());
assertEquals(0, g.E().count().next().intValue());
assertEquals(4l, cypher.execute("MATCH n RETURN COUNT(n)").iterator().next().get("COUNT(n)"));
assertEquals(2l, cypher.execute("MATCH (n)-[r]->(m) RETURN COUNT(r)").iterator().next().get("COUNT(r)"));
assertEquals(2l, cypher.execute("MATCH (a)-[r]->() WHERE id(a) = " + a.id() + " RETURN COUNT(r)").iterator().next().get("COUNT(r)"));
final AtomicInteger counter = new AtomicInteger(0);
a.getBaseVertex().getRelationships(Direction.OUTGOING).forEach(relationship -> {
assertEquals(Neo4jVertexProperty.VERTEX_PROPERTY_PREFIX.concat("name"), relationship.getType().name());
counter.incrementAndGet();
});
assertEquals(2, counter.getAndSet(0));
cypher.execute("MATCH (a)-[]->(m) WHERE id(a) = " + a.id() + " RETURN labels(m)").forEach(results -> {
assertEquals(VertexProperty.DEFAULT_LABEL, ((List<String>) results.get("labels(m)")).get(0));
counter.incrementAndGet();
});
assertEquals(2, counter.getAndSet(0));
StreamFactory.stream(a.getBaseVertex().getRelationships(Direction.OUTGOING)).map(Relationship::getEndNode).forEach(node -> {
assertEquals(2, StreamFactory.stream(node.getPropertyKeys()).count());
assertEquals("name", node.getProperty(T.key.getAccessor()));
assertTrue("marko".equals(node.getProperty(T.value.getAccessor())) || "okram".equals(node.getProperty(T.value.getAccessor())));
assertEquals(0, node.getDegree(Direction.OUTGOING));
assertEquals(1, node.getDegree(Direction.INCOMING));
assertEquals(Neo4jVertexProperty.VERTEX_PROPERTY_PREFIX.concat("name"), node.getRelationships(Direction.INCOMING).iterator().next().getType().name());
counter.incrementAndGet();
});
assertEquals(2, counter.getAndSet(0));
assertEquals(2, StreamFactory.stream(b.getBaseVertex().getPropertyKeys()).count());
assertEquals("stephen", b.getBaseVertex().getProperty("name"));
assertEquals("virginia", b.getBaseVertex().getProperty("location"));
});
a.singleProperty("name", "the marko");
tryCommit(g, g -> {
assertEquals(2, g.V().count().next().intValue());
assertEquals(1, a.properties().count().next().intValue());
assertEquals(1, b.properties("name").count().next().intValue());
assertEquals(1, b.properties("location").count().next().intValue());
assertEquals(0, g.E().count().next().intValue());
assertEquals(2l, cypher.execute("MATCH n RETURN COUNT(n)").iterator().next().get("COUNT(n)"));
assertEquals(0l, cypher.execute("MATCH (n)-[r]->(m) RETURN COUNT(r)").iterator().next().get("COUNT(r)"));
assertEquals(1, StreamFactory.stream(a.getBaseVertex().getPropertyKeys()).count());
assertEquals("the marko", a.getBaseVertex().getProperty("name"));
assertEquals(2, StreamFactory.stream(b.getBaseVertex().getPropertyKeys()).count());
assertEquals("stephen", b.getBaseVertex().getProperty("name"));
assertEquals("virginia", b.getBaseVertex().getProperty("location"));
});
a.property("name").remove();
tryCommit(g, g -> {
assertEquals(2, g.V().count().next().intValue());
assertEquals(0, a.properties().count().next().intValue());
assertEquals(2, b.properties().count().next().intValue());
assertEquals(0, g.E().count().next().intValue());
assertEquals(2l, cypher.execute("MATCH n RETURN COUNT(n)").iterator().next().get("COUNT(n)"));
assertEquals(0l, cypher.execute("MATCH (n)-[r]->(m) RETURN COUNT(r)").iterator().next().get("COUNT(r)"));
assertEquals(0, StreamFactory.stream(a.getBaseVertex().getPropertyKeys()).count());
assertEquals(2, StreamFactory.stream(b.getBaseVertex().getPropertyKeys()).count());
});
a.singleProperty("name", "the marko", "acl", "private");
tryCommit(g, g -> {
assertEquals(2, g.V().count().next().intValue());
assertEquals(1, a.properties("name").count().next().intValue());
assertEquals(1, b.properties("name").count().next().intValue());
assertEquals(1, b.properties("location").count().next().intValue());
assertEquals(0, g.E().count().next().intValue());
assertEquals(3l, cypher.execute("MATCH n RETURN COUNT(n)").iterator().next().get("COUNT(n)"));
assertEquals(1l, cypher.execute("MATCH (n)-[r]->(m) RETURN COUNT(r)").iterator().next().get("COUNT(r)"));
assertEquals(1l, cypher.execute("MATCH (a)-[r]->() WHERE id(a) = " + a.id() + " RETURN COUNT(r)").iterator().next().get("COUNT(r)"));
final AtomicInteger counter = new AtomicInteger(0);
a.getBaseVertex().getRelationships(Direction.OUTGOING).forEach(relationship -> {
assertEquals(Neo4jVertexProperty.VERTEX_PROPERTY_PREFIX.concat("name"), relationship.getType().name());
counter.incrementAndGet();
});
assertEquals(1, counter.getAndSet(0));
cypher.execute("MATCH (a)-[]->(m) WHERE id(a) = " + a.id() + " RETURN labels(m)").forEach(results -> {
assertEquals(VertexProperty.DEFAULT_LABEL, ((List<String>) results.get("labels(m)")).get(0));
counter.incrementAndGet();
});
assertEquals(1, counter.getAndSet(0));
StreamFactory.stream(a.getBaseVertex().getRelationships(Direction.OUTGOING)).map(Relationship::getEndNode).forEach(node -> {
assertEquals(3, StreamFactory.stream(node.getPropertyKeys()).count());
assertEquals("name", node.getProperty(T.key.getAccessor()));
assertEquals("the marko", node.getProperty(T.value.getAccessor()));
assertEquals("private", node.getProperty("acl"));
assertEquals(0, node.getDegree(Direction.OUTGOING));
assertEquals(1, node.getDegree(Direction.INCOMING));
assertEquals(Neo4jVertexProperty.VERTEX_PROPERTY_PREFIX.concat("name"), node.getRelationships(Direction.INCOMING).iterator().next().getType().name());
counter.incrementAndGet();
});
assertEquals(1, counter.getAndSet(0));
assertEquals(1, StreamFactory.stream(a.getBaseVertex().getPropertyKeys()).count());
assertTrue(a.getBaseVertex().hasProperty("name"));
assertEquals(Neo4jVertexProperty.VERTEX_PROPERTY_TOKEN, a.getBaseVertex().getProperty("name"));
assertEquals(2, StreamFactory.stream(b.getBaseVertex().getPropertyKeys()).count());
assertEquals("stephen", b.getBaseVertex().getProperty("name"));
assertEquals("virginia", b.getBaseVertex().getProperty("location"));
});
a.property("name", "marko", "acl", "private");
a.property("name", "okram", "acl", "public");
// TODO tx.commit() THIS IS REQUIRED: ?! Why does Neo4j not delete vertices correctly?
g.tx().commit();
a.singleProperty("name", "the marko", "acl", "private");
tryCommit(g, g -> {
assertEquals(2, g.V().count().next().intValue());
assertEquals(1, a.properties("name").count().next().intValue());
assertEquals(1, b.properties("name").count().next().intValue());
assertEquals(1, b.properties("location").count().next().intValue());
assertEquals(0, g.E().count().next().intValue());
assertEquals(3l, cypher.execute("MATCH n RETURN COUNT(n)").iterator().next().get("COUNT(n)"));
assertEquals(1l, cypher.execute("MATCH (n)-[r]->(m) RETURN COUNT(r)").iterator().next().get("COUNT(r)"));
assertEquals(1l, cypher.execute("MATCH (a)-[r]->() WHERE id(a) = " + a.id() + " RETURN COUNT(r)").iterator().next().get("COUNT(r)"));
final AtomicInteger counter = new AtomicInteger(0);
a.getBaseVertex().getRelationships(Direction.OUTGOING).forEach(relationship -> {
assertEquals(Neo4jVertexProperty.VERTEX_PROPERTY_PREFIX.concat("name"), relationship.getType().name());
counter.incrementAndGet();
});
assertEquals(1, counter.getAndSet(0));
cypher.execute("MATCH (a)-[]->(m) WHERE id(a) = " + a.id() + " RETURN labels(m)").forEach(results -> {
assertEquals(VertexProperty.DEFAULT_LABEL, ((List<String>) results.get("labels(m)")).get(0));
counter.incrementAndGet();
});
assertEquals(1, counter.getAndSet(0));
StreamFactory.stream(a.getBaseVertex().getRelationships(Direction.OUTGOING)).map(Relationship::getEndNode).forEach(node -> {