Skip to content

Commit 9e50655

Browse files
Update the documentation for procedures and functions to have up to date code examples from linked github repo. (#97) (#101)
Co-authored-by: Gem Lamont <106068376+gem-neo4j@users.noreply.github.com>
1 parent 27913a0 commit 9e50655

File tree

3 files changed

+108
-69
lines changed

3 files changed

+108
-69
lines changed

modules/ROOT/pages/extending-neo4j/functions.adoc

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ The correct way to signal an error from within a function is to throw `RuntimeEx
4343
----
4444
package example;
4545
46+
import java.util.List;
47+
48+
import org.neo4j.procedure.Description;
4649
import org.neo4j.procedure.Name;
47-
import org.neo4j.procedure.Procedure;
4850
import org.neo4j.procedure.UserFunction;
4951
5052
public class Join
@@ -72,37 +74,47 @@ Tests for user-defined functions are created in the same way as those for proced
7274
----
7375
package example;
7476
75-
import org.junit.Rule;
76-
import org.junit.Test;
77-
import org.neo4j.driver.v1.*;
78-
import org.neo4j.harness.junit.Neo4jRule;
79-
80-
import static org.hamcrest.core.IsEqual.equalTo;
81-
import static org.junit.Assert.assertThat;
82-
83-
public class JoinTest
84-
{
85-
// This rule starts a Neo4j instance
86-
@Rule
87-
public Neo4jRule neo4j = new Neo4jRule()
77+
import org.junit.jupiter.api.AfterAll;
78+
import org.junit.jupiter.api.BeforeAll;
79+
import org.junit.jupiter.api.Test;
80+
import org.junit.jupiter.api.TestInstance;
81+
import org.neo4j.driver.Driver;
82+
import org.neo4j.driver.GraphDatabase;
83+
import org.neo4j.driver.Session;
84+
import org.neo4j.harness.Neo4j;
85+
import org.neo4j.harness.Neo4jBuilders;
86+
87+
import static org.assertj.core.api.Assertions.assertThat;
88+
89+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
90+
public class JoinTest {
91+
92+
private Neo4j embeddedDatabaseServer;
93+
94+
@BeforeAll
95+
void initializeNeo4j() {
96+
this.embeddedDatabaseServer = Neo4jBuilders.newInProcessBuilder()
97+
.withDisabledServer()
98+
.withFunction(Join.class)
99+
.build();
100+
}
88101
89-
// This is the function to test
90-
.withFunction( Join.class );
102+
@AfterAll
103+
void closeNeo4j() {
104+
this.embeddedDatabaseServer.close();
105+
}
91106
92107
@Test
93-
public void shouldAllowIndexingAndFindingANode() throws Throwable
94-
{
95-
// This is in a try-block, to make sure you close the driver after the test
96-
try( Driver driver = GraphDatabase.driver( neo4j.boltURI() , Config.build().withEncryptionLevel( Config.EncryptionLevel.NONE ).toConfig() ) )
97-
{
98-
// Given
99-
Session session = driver.session();
108+
void joinsStrings() {
109+
// This is in a try-block, to make sure we close the driver after the test
110+
try(Driver driver = GraphDatabase.driver(embeddedDatabaseServer.boltURI());
111+
Session session = driver.session()) {
100112
101113
// When
102114
String result = session.run( "RETURN example.join(['Hello', 'World']) AS result").single().get("result").asString();
103115
104116
// Then
105-
assertThat( result, equalTo( "Hello,World" ) );
117+
assertThat( result).isEqualTo(( "Hello,World" ));
106118
}
107119
}
108120
}

modules/ROOT/pages/extending-neo4j/procedures.adoc

Lines changed: 63 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ For a comparison between user-defined procedures, functions, and aggregation fun
1212

1313
[NOTE]
1414
====
15-
User-defined procedures requiring execution on the system database need to include the annotation `@SystemProcedure` or they will be classed as user database procedure.
15+
User-defined procedures requiring execution on the system database need to include the annotation `@SystemProcedure` or they will be classed as a user database procedure.
1616
====
1717

1818
[[call-procedure]]
@@ -51,52 +51,76 @@ The test dependencies include _Neo4j Harness_ and _JUnit_.
5151
These can be used to write integration tests for procedures.
5252
The tests should start a Neo4j instance, load the procedure, and execute queries against it.
5353

54-
.A template for testing a procedure that accesses Neo4j's full-text indexes from Cypher.
54+
.An example for testing a procedure that returns relationship types found in the graph.
5555
[source, java]
5656
----
5757
package example;
5858
59-
import org.junit.Rule;
60-
import org.junit.Test;
61-
import org.neo4j.driver.v1.*;
62-
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
63-
import org.neo4j.harness.junit.Neo4jRule;
64-
65-
import static org.hamcrest.core.IsEqual.equalTo;
66-
import static org.junit.Assert.assertThat;
67-
import static org.neo4j.driver.v1.Values.parameters;
59+
import org.junit.jupiter.api.AfterAll;
60+
import org.junit.jupiter.api.AfterEach;
61+
import org.junit.jupiter.api.BeforeAll;
62+
import org.junit.jupiter.api.Test;
63+
import org.junit.jupiter.api.TestInstance;
64+
import org.neo4j.driver.Driver;
65+
import org.neo4j.driver.GraphDatabase;
66+
import org.neo4j.driver.Record;
67+
import org.neo4j.driver.Result;
68+
import org.neo4j.driver.Session;
69+
import org.neo4j.driver.Value;
70+
import org.neo4j.harness.Neo4j;
71+
import org.neo4j.harness.Neo4jBuilders;
72+
73+
import static org.assertj.core.api.Assertions.assertThat;
74+
75+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
76+
public class GetRelationshipTypesTests {
77+
78+
private Driver driver;
79+
private Neo4j embeddedDatabaseServer;
80+
81+
@BeforeAll
82+
void initializeNeo4j() {
83+
this.embeddedDatabaseServer = Neo4jBuilders.newInProcessBuilder()
84+
.withDisabledServer()
85+
.withProcedure(GetRelationshipTypes.class)
86+
.build();
87+
88+
this.driver = GraphDatabase.driver(embeddedDatabaseServer.boltURI());
89+
}
6890
69-
public class ManualFullTextIndexTest
70-
{
71-
// This rule starts a Neo4j instance
72-
@Rule
73-
public Neo4jRule neo4j = new Neo4jRule()
91+
@AfterAll
92+
void closeDriver(){
93+
this.driver.close();
94+
this.embeddedDatabaseServer.close();
95+
}
7496
75-
// This is the Procedure to test
76-
.withProcedure( FullTextIndex.class );
97+
@AfterEach
98+
void cleanDb(){
99+
try(Session session = driver.session()) {
100+
session.run("MATCH (n) DETACH DELETE n");
101+
}
102+
}
77103
104+
/**
105+
* We should be getting the correct values when there is only one type in each direction
106+
*/
78107
@Test
79-
public void shouldAllowIndexingAndFindingANode() throws Throwable
80-
{
81-
// In a try-block, make sure you close the driver after the test
82-
try( Driver driver = GraphDatabase.driver( neo4j.boltURI() , Config.build().withoutEncryption().toConfig() ) )
83-
{
84-
85-
// Given you've started Neo4j with the FullTextIndex procedure class
86-
// which your 'neo4j' rule does.
87-
Session session = driver.session();
88-
89-
// And given you have a node in the database
90-
long nodeId = session.run( "CREATE (p:User {name:'Brookreson'}) RETURN id(p)" )
91-
.single()
92-
.get( 0 ).asLong();
93-
94-
// When you use the index procedure to index a node
95-
session.run( "CALL example.index($id, ['name'])", parameters( "id", nodeId ) );
96-
97-
// Then you can search for that node with Lucene query syntax
98-
StatementResult result = session.run( "CALL example.search('User', 'name:Brook*')" );
99-
assertThat( result.single().get( "nodeId" ).asLong(), equalTo( nodeId ) );
108+
public void shouldReturnTheTypesWhenThereIsOneEachWay() {
109+
final String expectedIncoming = "INCOMING";
110+
final String expectedOutgoing = "OUTGOING";
111+
112+
// In a try-block, to make sure we close the session after the test
113+
try(Session session = driver.session()) {
114+
115+
//Create our data in the database.
116+
session.run(String.format("CREATE (:Person)-[:%s]->(:Movie {id:1})-[:%s]->(:Person)", expectedIncoming, expectedOutgoing));
117+
118+
//Execute our procedure against it.
119+
Record record = session.run("MATCH (u:Movie {id:1}) CALL example.getRelationshipTypes(u) YIELD outgoing, incoming RETURN outgoing, incoming").single();
120+
121+
//Get the incoming / outgoing relationships from the result
122+
assertThat(record.get("incoming").asList(Value::asString)).containsOnly(expectedIncoming);
123+
assertThat(record.get("outgoing").asList(Value::asString)).containsOnly(expectedOutgoing);
100124
}
101125
}
102126
}

modules/ROOT/pages/extending-neo4j/project-setup.adoc

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
3838
<description>A template project for building a Neo4j Procedure</description>
3939
4040
<properties>
41+
<java.version>17</java.version>
42+
<maven.compiler.release>${java.version}</maven.compiler.release>
43+
4144
<neo4j.version>{neo4j-version-exact}</neo4j.version>
4245
</properties>
4346
----
@@ -85,10 +88,10 @@ It is used to start Neo4j with a specific procedure or function deployed, which
8588
</dependency>
8689
8790
<dependency>
88-
<groupId>junit</groupId>
89-
<artifactId>junit</artifactId>
90-
<version>4.12</version>
91-
<scope>test</scope>
91+
<groupId>org.junit.jupiter</groupId>
92+
<artifactId>junit-jupiter-engine</artifactId>
93+
<version>5.9.1</version>
94+
<scope>test</scope>
9295
</dependency>
9396
----
9497

@@ -111,8 +114,8 @@ Once the procedure has been deployed to the _plugins_ directory of each Neo4j in
111114
<plugin>
112115
<artifactId>maven-compiler-plugin</artifactId>
113116
<configuration>
114-
<source>11</source>
115-
<target>11</target>
117+
<source>17</source>
118+
<target>17</target>
116119
</configuration>
117120
</plugin>
118121
<plugin>

0 commit comments

Comments
 (0)