From a9dc9132f2bb213c0a64c9a6d92068d30b168efd Mon Sep 17 00:00:00 2001 From: Patrick ALLAIN Date: Sat, 13 Feb 2021 13:10:14 +0100 Subject: [PATCH] Refactor error message and add behavior to chain queries --- TODOS.md | 84 ++-- pom.xml | 8 + .../api/beta/AbstractEntitiesAssert.java | 131 +++++-- .../neo4j/api/beta/AbstractNodesAssert.java | 59 ++- .../api/beta/AbstractRelationshipsAssert.java | 14 +- .../org/assertj/neo4j/api/beta/Adoptable.java | 2 +- .../ChildrenDriverRelationshipsAssert.java | 5 +- .../neo4j/api/beta/DriverAssertions.java | 2 +- .../neo4j/api/beta/DriverNodesAssert.java | 12 +- .../api/beta/DriverRelationshipsAssert.java | 7 +- .../neo4j/api/beta/DriverRequestAssert.java | 2 +- .../neo4j/api/beta/DriverResultAssert.java | 4 +- .../org/assertj/neo4j/api/beta/Navigable.java | 6 +- .../neo4j/api/beta/NavigableListAssert.java | 4 +- .../assertj/neo4j/api/beta/RecordAssert.java | 2 +- .../neo4j/api/beta/RecordMapAssert.java | 2 +- .../error/BasicEntityErrorMessageFactory.java | 78 ++++ .../BasicGroupingEntityErrorFactory.java | 130 ++++++ .../beta/error/DbEntitiesMessageFactory.java | 69 ---- .../beta/error/ElementsShouldHaveLabels.java | 61 --- .../ElementsShouldHavePropertyInstanceOf.java | 24 -- .../error/ElementsShouldHavePropertyKeys.java | 75 ---- .../ElementsShouldHavePropertyListOfType.java | 76 ---- .../error/ElementsShouldHavePropertySize.java | 23 -- .../ElementsShouldHavePropertyValue.java | 37 -- .../ElementsShouldHavePropertyValueType.java | 56 --- .../beta/error/ElementsShouldHaveType.java | 59 --- .../beta/error/EntityErrorMessageFactory.java | 114 ++++++ ...l.java => GroupingEntityErrorFactory.java} | 25 +- .../assertj/neo4j/api/beta/error/Missing.java | 68 ---- .../beta/error/ShouldBeEmptyQueryResult.java | 53 +++ .../api/beta/error/ShouldHaveNodeLabels.java | 60 +++ .../error/ShouldHavePropertyInstanceOf.java | 65 +++ .../beta/error/ShouldHavePropertyKeys.java | 63 +++ .../error/ShouldHavePropertyListOfType.java | 72 ++++ .../beta/error/ShouldHavePropertySize.java | 59 +++ .../beta/error/ShouldHavePropertyValue.java | 64 +++ .../error/ShouldHavePropertyValueType.java | 65 +++ .../error/ShouldHavePropertyWithType.java | 20 - .../api/beta/error/ShouldHaveRecord.java | 2 +- .../beta/error/ShouldHaveRecordNumber.java | 2 +- .../api/beta/error/ShouldHaveRecordType.java | 2 +- .../ShouldNodeHaveNoRelatedRelationships.java | 87 ++++ .../api/beta/error/ShouldPropertyMatch.java | 56 +++ .../error/ShouldRelationshipHaveType.java | 62 +++ .../api/beta/type/AbstractDataLoader.java | 60 ++- .../neo4j/api/beta/type/DataLoader.java | 25 +- .../assertj/neo4j/api/beta/type/DbEntity.java | 19 +- .../assertj/neo4j/api/beta/type/DbValue.java | 4 +- .../assertj/neo4j/api/beta/type/Drivers.java | 9 +- .../neo4j/api/beta/type/LoaderFactory.java | 44 +++ .../api/beta/type/LoaderFactoryGeneric.java | 46 +++ .../neo4j/api/beta/type/NodeLoader.java | 68 ++++ .../assertj/neo4j/api/beta/type/Nodes.java | 62 +-- .../assertj/neo4j/api/beta/type/Queries.java | 37 ++ .../neo4j/api/beta/type/RecordType.java | 2 +- .../api/beta/type/RelationshipLoader.java | 60 +++ .../neo4j/api/beta/type/Relationships.java | 105 +++-- .../neo4j/api/beta/type/ValueType.java | 26 +- .../assertj/neo4j/api/beta/util/Checks.java | 78 +++- .../neo4j/api/beta/util/EntityUtils.java | 90 +++++ .../neo4j/api/beta/util/NodeLabels.java | 65 --- .../neo4j/api/beta/util/NodeUtils.java | 30 ++ .../neo4j/api/beta/util/Predicates.java | 59 ++- .../neo4j/api/beta/util/Presentations.java | 6 +- .../api/beta/util/RelationshipTypes.java | 48 --- .../assertj/neo4j/api/beta/util/Utils.java | 83 ++++ .../org/assertj/neo4j/api/beta/util/Wip.java | 2 +- .../api/beta/AbstractEntitiesAssertTests.java | 298 +++++++++++--- .../api/beta/AbstractNodesAssertTests.java | 371 ++++++++++++++++++ .../api/beta/DriverNodesAssertTests.java | 134 ------- .../beta/DriverRelationshipsAssertTests.java | 107 +++-- .../error/ElementsShouldHaveLabelsTests.java | 101 ----- ...entsShouldHavePropertyInstanceOfTests.java | 45 --- .../ElementsShouldHavePropertyKeysTests.java | 197 ---------- ...entsShouldHavePropertyListOfTypeTests.java | 90 ----- ...ElementsShouldHavePropertyOfTypeTests.java | 115 ------ .../ElementsShouldHavePropertySizeTests.java | 16 - .../ElementsShouldHavePropertyValueTests.java | 71 ---- .../error/ElementsShouldHaveTypeTests.java | 99 ----- .../error/ShouldBeEmptyQueryResultTests.java | 88 +++++ .../beta/error/ShouldHaveNodeLabelsTests.java | 114 ++++++ .../ShouldHavePropertyInstanceOfTests.java | 118 ++++++ .../error/ShouldHavePropertyKeysTests.java | 118 ++++++ .../ShouldHavePropertyListOfTypeTests.java | 99 +++++ .../error/ShouldHavePropertySizeTests.java | 133 +++++++ .../error/ShouldHavePropertyValueTests.java | 117 ++++++ .../ShouldHavePropertyValueTypeTests.java | 121 ++++++ ...ldNodeHaveNoRelatedRelationshipsTests.java | 196 +++++++++ .../beta/error/ShouldPropertyMatchTests.java | 91 +++++ .../ShouldRelationshipHaveTypeTests.java | 106 +++++ .../integrations/ParisIntegrationTests.java | 2 +- .../SampleNodesIntegrationTests.java | 85 +++- .../SampleRelationshipsIntegrationTests.java | 12 +- .../SampleRequestIntegrationTests.java | 2 +- .../SampleResultIntegrationTests.java | 2 +- .../api/beta/integrations/TypesTests.java | 4 +- .../api/beta/testing/IntegrationTests.java | 2 +- .../neo4j/api/beta/testing/Loaders.java} | 22 +- .../neo4j/api/beta/testing/MockResult.java | 2 +- .../assertj/neo4j/api/beta/testing/Mocks.java | 18 +- .../neo4j/api/beta/testing/Neo4JDataSet.java | 2 +- .../neo4j/api/beta/testing/Randomize.java | 35 ++ .../neo4j/api/beta/testing/Samples.java | 39 ++ .../neo4j/api/beta/testing/TestTags.java | 2 +- .../testing/{ => builders}/NodeBuilder.java | 4 +- .../testing/{ => builders}/RecordBuilder.java | 7 +- .../{ => builders}/RelationshipBuilder.java | 4 +- .../builders/RelationshipsLoaderBuilder.java | 66 ++++ .../testing/{ => builders}/ResultBuilder.java | 5 +- .../neo4j/api/beta/type/DbEntityTests.java | 28 +- .../neo4j/api/beta/type/NodesTests.java | 54 +-- .../api/beta/type/RelationshipsTests.java | 25 +- .../neo4j/api/beta/util/ChecksTests.java | 14 +- .../neo4j/api/beta/util/EntityUtilsTests.java | 206 ++++++++++ .../neo4j/api/beta/util/NodeLabelsTests.java | 176 --------- .../neo4j/api/beta/util/PredicatesTests.java | 158 +++++++- .../api/beta/util/PresentationsTests.java | 2 +- .../api/beta/util/RelationshipTypesTests.java | 169 -------- .../neo4j/api/beta/util/UtilsTests.java | 75 ++++ src/test/resources/samples/language.cypher | 31 +- 121 files changed, 4802 insertions(+), 2395 deletions(-) create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/BasicEntityErrorMessageFactory.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/BasicGroupingEntityErrorFactory.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/DbEntitiesMessageFactory.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveLabels.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyInstanceOf.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyKeys.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyListOfType.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertySize.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValue.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValueType.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveType.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/EntityErrorMessageFactory.java rename src/main/java/org/assertj/neo4j/api/beta/error/{ShouldAllHaveLabel.java => GroupingEntityErrorFactory.java} (54%) delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/Missing.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldBeEmptyQueryResult.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveNodeLabels.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyInstanceOf.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyKeys.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyListOfType.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertySize.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValue.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueType.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyWithType.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldNodeHaveNoRelatedRelationships.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldPropertyMatch.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/error/ShouldRelationshipHaveType.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/type/LoaderFactory.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/type/LoaderFactoryGeneric.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/type/NodeLoader.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/type/Queries.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/type/RelationshipLoader.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/util/EntityUtils.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/util/NodeLabels.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/util/NodeUtils.java delete mode 100644 src/main/java/org/assertj/neo4j/api/beta/util/RelationshipTypes.java create mode 100644 src/main/java/org/assertj/neo4j/api/beta/util/Utils.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/AbstractNodesAssertTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/DriverNodesAssertTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveLabelsTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyInstanceOfTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyKeysTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyListOfTypeTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyOfTypeTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertySizeTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValueTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveTypeTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldBeEmptyQueryResultTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldHaveNodeLabelsTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyInstanceOfTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyKeysTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyListOfTypeTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertySizeTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueTypeTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldNodeHaveNoRelatedRelationshipsTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldPropertyMatchTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/error/ShouldRelationshipHaveTypeTests.java rename src/{main/java/org/assertj/neo4j/api/beta/error/ShouldAllHaveProperty.java => test/java/org/assertj/neo4j/api/beta/testing/Loaders.java} (54%) create mode 100644 src/test/java/org/assertj/neo4j/api/beta/testing/Randomize.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/testing/Samples.java rename src/test/java/org/assertj/neo4j/api/beta/testing/{ => builders}/NodeBuilder.java (94%) rename src/test/java/org/assertj/neo4j/api/beta/testing/{ => builders}/RecordBuilder.java (92%) rename src/test/java/org/assertj/neo4j/api/beta/testing/{ => builders}/RelationshipBuilder.java (94%) create mode 100644 src/test/java/org/assertj/neo4j/api/beta/testing/builders/RelationshipsLoaderBuilder.java rename src/test/java/org/assertj/neo4j/api/beta/testing/{ => builders}/ResultBuilder.java (89%) create mode 100644 src/test/java/org/assertj/neo4j/api/beta/util/EntityUtilsTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/util/NodeLabelsTests.java delete mode 100644 src/test/java/org/assertj/neo4j/api/beta/util/RelationshipTypesTests.java create mode 100644 src/test/java/org/assertj/neo4j/api/beta/util/UtilsTests.java diff --git a/TODOS.md b/TODOS.md index 02e02fa..e72363f 100644 --- a/TODOS.md +++ b/TODOS.md @@ -1,6 +1,5 @@ # TODOS - ## Features ### Nodes @@ -24,37 +23,60 @@ class SampleTests { ``` -* Provider assertions on the main "raw" Java Bold driver types (Records...) -* Provider assertions on query results - * Should support both String and Cypher-DSL constructs -* Provider higher level experience à la AssertJ-DB - * Entities (commons nodes & relationships) : - * [X] `ignoringIds`: Remove id to entities and create a new assertions - * [X] `havePropertyKeys`: Verify if property's entities have the expected keys - * [ ] `havePropertyType` : Verify if all property's entities have the expected type - * [ ] `havePropertyCount`: Verify if entities have the number of properties - * [ ] `haveProperty` : - * [ ] `haveProperty` : - * [ ] `haveProperty` : - * [ ] `haveProperties` : - * [X] `contains` : - * [ ] `filteredOn` - * [ ] `filteredOnPropertyExists` - * [ ] `filteredOnProperty` - * [ ] - * [ ] - * [ ] - * [ ] - * [ ] - * [ ] - * Nodes : - * [X] `haveLabels` +## Tasks + +### Goals + +* [ ] Provider assertions on the main "raw" Java Bold driver types (Records...) + * [ ] `haveColumnSize` + * [ ] `isNode` + * [ ] `isRelationships` + * [ ] `` +* [ ] Provider assertions on query results + * [ ] Should support both String + * [ ] Cypher-DSL constructs +* [ ] Provider higher level experience à la AssertJ-DB + * [ ] Entities (commons nodes & relationships) : + * [X] `toParentAssert` : Go to the parent assertion + * [X] `ignoringIds`: Create a new assertion that will not compare the entity with theirs ids + * [X] `havePropertyKeys`: Verify that all entities have the expected keys + * [X] `havePropertyOfType` : Verify that all entities have a property with a value matching the provided type + * [X] `havePropertySize`: Verify that all entities have the expected number of properties + * [X] `havePropertyValue` : Verify that all entities have the property value + * [X] `havePropertyValueMatching` : Verify that all entities have the property matching the provided predicate + * [X] `haveListPropertyOfType` : Verify that all entities have a list property with elements of the provided type + * [X] `contains` : Verify that there is an entity that is equal to the one provided + * [X] `filteredOn` : Filter entities on a predicate. Create a new assertion + * [X] `filteredOnPropertyExists` : Filter entities that have the provided property key + * [X] `filteredOnPropertyValue` : Filter entities that have the provided property key + * [ ] Add negative assertions + * [ ] Nodes : + * [ ] `toRootAssert` : Retrieve the root assertion + * [X] `haveLabels` : Verify that the nodes have the expected labels + * [X] `filteredOnLabels` : Filter on nodes having the labels * [X] `Drivers.node()....` - * [ ] `toParent` - * Relationships : + * [X] `incomingRelationships` + * [X] `outgoindRelationships` + * [X] `haveNoIncomingRelationships` + * [X] `haveNoOutgoingRelationships` + * [ ] Add negative assertions + * [ ] Relationships : + * [ ] `toRootAssert` : Retrieve the root assertion + * [X] `haveType` : Verify that a relationships if of the expected type * [X] `Drivers.relationship()....` - * [X] `haveType`: Really useful ? * [ ] `toParent` - * Request - * [ ] + * [ ] `startingNodes` + * [ ] `endingNodes` + * [ ] `haveNoStartingNodes` + * [ ] `haveNoEndingNodes` + * [ ] `` + * [ ] Add negative assertions + * [ ] Request : See bellow + * [ ] Changes : + * [ ] `` +### Others + +* [ ] Simplify error message factory +* [ ] +* [ ] Simplify assertions diff --git a/pom.xml b/pom.xml index 24a3747..c07662d 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,7 @@ 1.15.1 1.2.3 1.7.30 + 2020.1.6 @@ -61,6 +62,13 @@ ${neo4j-driver.version} provided + + + org.neo4j + neo4j-cypher-dsl + ${neo4j-cypher-dsl.version} + true + org.junit.jupiter diff --git a/src/main/java/org/assertj/neo4j/api/beta/AbstractEntitiesAssert.java b/src/main/java/org/assertj/neo4j/api/beta/AbstractEntitiesAssert.java index 727e405..125a83a 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/AbstractEntitiesAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/AbstractEntitiesAssert.java @@ -14,25 +14,33 @@ import org.assertj.core.api.AbstractAssert; import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.core.error.ShouldBeEmpty; +import org.assertj.core.internal.ComparisonStrategy; import org.assertj.core.internal.Iterables; import org.assertj.core.util.VisibleForTesting; -import org.assertj.neo4j.api.beta.error.ElementsShouldHavePropertyInstanceOf; -import org.assertj.neo4j.api.beta.error.ElementsShouldHavePropertyKeys; -import org.assertj.neo4j.api.beta.error.ElementsShouldHavePropertySize; -import org.assertj.neo4j.api.beta.error.ElementsShouldHavePropertyValue; -import org.assertj.neo4j.api.beta.error.ElementsShouldHavePropertyValueType; +import org.assertj.neo4j.api.beta.error.ShouldBeEmptyQueryResult; +import org.assertj.neo4j.api.beta.error.ShouldHavePropertyInstanceOf; +import org.assertj.neo4j.api.beta.error.ShouldHavePropertyListOfType; +import org.assertj.neo4j.api.beta.error.ShouldHavePropertySize; +import org.assertj.neo4j.api.beta.error.ShouldHavePropertyValue; +import org.assertj.neo4j.api.beta.error.ShouldHavePropertyValueType; +import org.assertj.neo4j.api.beta.error.ShouldHavePropertyKeys; +import org.assertj.neo4j.api.beta.error.ShouldPropertyMatch; import org.assertj.neo4j.api.beta.type.DataLoader; import org.assertj.neo4j.api.beta.type.DbEntity; import org.assertj.neo4j.api.beta.type.RecordType; import org.assertj.neo4j.api.beta.type.ValueType; import org.assertj.neo4j.api.beta.util.Checks; import org.assertj.neo4j.api.beta.util.Predicates; +import org.assertj.neo4j.api.beta.util.Presentations; +import org.assertj.neo4j.api.beta.util.Utils; import org.assertj.neo4j.api.beta.util.Wip; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -42,7 +50,7 @@ * @param the entity type * @param the parent assertions type * @param the root assertions type - * @author patouche - 24/11/2020 + * @author Patrick Allain - 24/11/2020 */ //@formatter:off public abstract class AbstractEntitiesAssert, @@ -62,7 +70,11 @@ public abstract class AbstractEntitiesAssert dataLoader; - /** True if comparison should be made ignoring ids */ + // /** Comparison strategy. */ + // protected final ComparisonStrategy comparisonStrategy; + + /** True if comparison should be made ignoring ids. */ + /** TODO: Check if it's possible to use a ComparisonStrategy instead. */ protected final boolean ignoreIds; /** Factory for creating new assertions on restricted list of entities. */ @@ -140,14 +152,26 @@ protected List entityIds() { */ protected SELF shouldAllVerify(final Predicate predicate, final ErrorMessageCallback callback) { - final List notSatisfies = actual.stream() - .filter(predicate.negate()).collect(Collectors.toList()); + final List notSatisfies = actual.stream().filter(predicate.negate()).collect(Collectors.toList()); if (!notSatisfies.isEmpty()) { throwAssertionError(callback.create(notSatisfies)); } return myself; } + public SELF isEmpty() { + return isEmpty( + (entities) -> ShouldBeEmptyQueryResult.elements(entities, dataLoader.query()).notSatisfies(entities) + ); + } + + protected SELF isEmpty(final ErrorMessageCallback callback) { + if (!actual.isEmpty()) { + throwAssertionError(callback.create(actual)); + } + return myself; + } + /** * Verifies that actual entities (nodes or relationships) retrieve have the expected size. *

@@ -216,7 +240,7 @@ public SELF filteredOn(final Predicate predicate) { } /** - * Filtered entities to create a new {@link SELF} assertions. + * Filtered entities having existing properties to create a new {@link SELF} assertions. *

* Example: *

 Nodes nodes = new Nodes(driver, "Person");
@@ -234,7 +258,7 @@ public SELF filteredOnPropertyExists(final String... keys) {
     }
 
     /**
-     * Filtered entities to create a new {@link SELF} assertions.
+     * Filtered entities having existing properties to create a new {@link SELF} assertions.
      * 

* Example: *

 Nodes nodes = new Nodes(driver, "Person");
@@ -248,10 +272,32 @@ public SELF filteredOnPropertyExists(final String... keys) {
      * @return a new assertion object
      */
     public SELF filteredOnPropertyExists(final Iterable keys) {
-        Checks.notNullOrEmpty(keys, "The iterable of property keys should not be empty");
+        Checks.nonNullElementsIn(keys, "The iterable of property keys should not be empty");
         return filteredOn(Predicates.propertyKeysExists(keys));
     }
 
+    /**
+     * Filtered entities on a property value to create a new {@link SELF} assertions.
+     * 

+ * Example: + *

 Nodes nodes = new Nodes(driver, "Person");
+     * assertThat(nodes)
+     *   .hasSize(10)
+     *   .filteredOnPropertyValue("name", "civility")
+     *   .hasSize(5)
+     * 
+ * + * @param key the property key that the filtered entities will have + * @param value the property value that the filtered entities will have + * @return a new assertion object + */ + public SELF filteredOnPropertyValue(final String key, final Object value) { + return filteredOn(Predicates.propertyValue( + Objects.requireNonNull(key, "The property key cannot be null"), + value + )); + } + /** * Provide a easy way to create new assertions on the current list of {@link ENTITY} without specifying the {@link * ENTITY#getId()} @@ -293,7 +339,7 @@ public SELF ignoringIds() { * @throws AssertionError if the actual value is not equal to the given one. */ public SELF havePropertyKeys(final String... expectedKeys) { - return havePropertyKeys(Checks.notNullOrEmpty(expectedKeys, "The property keys should not be null or empty")); + return havePropertyKeys(Utils.listOf(expectedKeys)); } /** @@ -313,10 +359,11 @@ public SELF havePropertyKeys(final String... expectedKeys) { * @throws AssertionError if the actual value is not equal to the given one. */ public SELF havePropertyKeys(final Iterable expectedKeys) { - final List keys = Checks.notNullOrEmpty(expectedKeys, "The property keys should not be null or empty"); + final List keys = Checks.nonNullElementsIn(expectedKeys, "The property keys should not be null or " + + "empty"); return shouldAllVerify( Predicates.propertyKeysExists(keys), - (notSatisfying) -> ElementsShouldHavePropertyKeys.create(recordType, actual, keys) + (notSatisfies) -> ShouldHavePropertyKeys.elements(actual, keys).notSatisfies(notSatisfies) ); } @@ -330,15 +377,15 @@ public SELF havePropertyKeys(final Iterable expectedKeys) { * .havePropertySize(8); *
* - * @param expectedSizeOfProperties the expected size of properties + * @param expectedSize the expected size of properties * @return {@code this} assertion object. * @throws AssertionError if one entities don't have the expected size of properties */ - public SELF havePropertySize(final int expectedSizeOfProperties) { - return shouldAllVerify(Predicates.propertySize(expectedSizeOfProperties), - (notSatifies) -> ElementsShouldHavePropertySize - .create(recordType, actual, notSatifies, expectedSizeOfProperties) - ); + public SELF havePropertySize(final int expectedSize) { + return shouldAllVerify( + Predicates.propertySize(expectedSize), + (notSatisfies) -> ShouldHavePropertySize.elements(actual, expectedSize).notSatisfies(notSatisfies) + ); } /** @@ -364,12 +411,11 @@ public SELF havePropertySize(final int expectedSizeOfProperties) { */ public SELF havePropertyOfType(final String key, final ValueType expectedType) { Objects.requireNonNull(key, "The property key shouldn't be null"); - Objects.requireNonNull(expectedType, "The expected value type shouldn't be null"); + final ValueType type = Objects.requireNonNull(expectedType, "The expected value type shouldn't be null"); havePropertyKeys(key); return shouldAllVerify( - Predicates.propertyValueType(key, expectedType), - (notSatisfies) -> ElementsShouldHavePropertyValueType - .create(recordType, actual, key, expectedType) + Predicates.propertyValueType(key, type), + (notSatisfies) -> ShouldHavePropertyValueType.elements(actual, key, type).notSatisfies(notSatisfies) ); } @@ -396,12 +442,11 @@ public SELF havePropertyOfType(final String key, final ValueType expectedType) { */ public SELF havePropertyInstanceOf(final String key, final Class expectedClass) { Objects.requireNonNull(key, "The property key shouldn't be null"); - Objects.requireNonNull(expectedClass, "The expected class shouldn't be null"); + final Class clazz = Objects.requireNonNull(expectedClass, "The expected class shouldn't be null"); havePropertyKeys(key); return shouldAllVerify( - Predicates.propertyValueInstanceOf(key, expectedClass), - (notSatisfies) -> ElementsShouldHavePropertyInstanceOf - .create(recordType, actual, key, expectedClass) + Predicates.propertyValueInstanceOf(key, clazz), + (notSatisfies) -> ShouldHavePropertyInstanceOf.elements(actual, key, clazz).notSatisfies(notSatisfies) ); } @@ -424,16 +469,29 @@ public SELF havePropertyInstanceOf(final String key, final Class expectedClas public SELF haveListPropertyOfType(final String key, final ValueType expectedType) { havePropertyKeys(key); havePropertyOfType(key, ValueType.LIST); + final ValueType type = Objects.requireNonNull(expectedType, "The expected value type shouldn't be null"); return shouldAllVerify( - Predicates.propertyListContainsValueType(key, expectedType), - (notSatisfies) -> ElementsShouldHavePropertyValueType - .create(recordType, actual, key, expectedType) + Predicates.propertyListContainsValueType(key, type), + (notSatisfies) -> ShouldHavePropertyListOfType.elements(actual, key, type).notSatisfies(notSatisfies) ); } public SELF havePropertyValueMatching(final String key, final Predicate predicate) { - Wip.TODO(this, "havePropertyMatching"); - return myself; + havePropertyKeys(key); + return shouldAllVerify( + Predicates.propertyValueMatch(key, predicate), + (notSatisfies) -> ShouldPropertyMatch.elements(actual, key).notSatisfies(notSatisfies) + ); + } + + public SELF havePropertyValueMatching(final String key, final Class expectedClass, + final Predicate predicate) { + havePropertyKeys(key); + havePropertyInstanceOf(key, expectedClass); + return shouldAllVerify( + Predicates.propertyValueMatch(key, predicate), + (notSatisfies) -> ShouldPropertyMatch.elements(actual, key).notSatisfies(notSatisfies) + ); } /** @@ -455,8 +513,9 @@ public SELF haveProperty(final String key, final Object expectedValue) { havePropertyKeys(key); return shouldAllVerify( Predicates.propertyValue(key, expectedValue), - (notSatisfies) -> ElementsShouldHavePropertyValue - .create(recordType, actual, notSatisfies, key, expectedValue) + (notSatisfies) -> ShouldHavePropertyValue + .elements(actual, key, expectedValue) + .notSatisfies(notSatisfies) ); } diff --git a/src/main/java/org/assertj/neo4j/api/beta/AbstractNodesAssert.java b/src/main/java/org/assertj/neo4j/api/beta/AbstractNodesAssert.java index ea7b7cf..6166fdc 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/AbstractNodesAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/AbstractNodesAssert.java @@ -12,19 +12,22 @@ */ package org.assertj.neo4j.api.beta; -import org.assertj.neo4j.api.beta.error.ElementsShouldHaveLabels; +import org.assertj.neo4j.api.beta.error.ShouldHaveNodeLabels; +import org.assertj.neo4j.api.beta.error.ShouldNodeHaveNoRelatedRelationships; import org.assertj.neo4j.api.beta.type.DataLoader; +import org.assertj.neo4j.api.beta.type.LoaderFactory; import org.assertj.neo4j.api.beta.type.Nodes; import org.assertj.neo4j.api.beta.type.RecordType; import org.assertj.neo4j.api.beta.type.Relationships; import org.assertj.neo4j.api.beta.util.Checks; -import org.assertj.neo4j.api.beta.util.NodeLabels; -import org.assertj.neo4j.api.beta.util.Wip; +import org.assertj.neo4j.api.beta.util.EntityUtils; +import org.assertj.neo4j.api.beta.util.NodeUtils; +import org.assertj.neo4j.api.beta.util.Predicates; import java.util.List; /** - * @author patouche - 08/11/2020 + * @author Patrick Allain - 08/11/2020 */ //@formatter:off public abstract class AbstractNodesAssert, @@ -84,34 +87,52 @@ public SELF haveLabels(final String... expectedLabels) { public SELF haveLabels(final Iterable expectedLabels) { final List labels = Checks .notNullOrEmpty(expectedLabels, "The iterable of values to look for should not be empty"); - if (NodeLabels.haveLabels(actual, expectedLabels)) { - throwAssertionError(ElementsShouldHaveLabels.create(actual, labels, NodeLabels.missing(actual, labels))); - } - return myself; + return shouldAllVerify( + Predicates.labelsExists(expectedLabels), + (notSatisfies) -> ShouldHaveNodeLabels.elements(actual, labels).notSatisfies(notSatisfies) + ); } /** * Create a new assertions on incoming relationships - * @param type the relation type + * + * @param types the relation types * @return a */ - public ChildrenDriverRelationshipsAssert incomingRelationships(final String type) { + public ChildrenDriverRelationshipsAssert incomingRelationships(final String... types) { final List nodeIds = entityIds(); - final Relationships relationships = new Relationships(this.dataLoader.getDriver(), type); - return new ChildrenDriverRelationshipsAssert<>(relationships.load(), relationships, false, myself, toRootAssert()) - .filteredOn(r -> nodeIds.contains(r.getId())) + final Relationships relationships = this.dataLoader.chain(LoaderFactory.relationships(types)); + return new ChildrenDriverRelationshipsAssert<>(relationships.load(), relationships, false, myself, + toRootAssert()) + .filteredOn(r -> nodeIds.contains(r.getEnd())) .withParent(myself); } - public ChildrenDriverRelationshipsAssert outgoingRelationships(String type) { - throw Wip.TODO(this); + public ChildrenDriverRelationshipsAssert outgoingRelationships(final String... types) { + final List nodeIds = entityIds(); + final Relationships relationships = this.dataLoader.chain(LoaderFactory.relationships(types)); + return new ChildrenDriverRelationshipsAssert<>(relationships.load(), relationships, false, myself, + toRootAssert()) + .filteredOn(r -> nodeIds.contains(r.getStart())) + .withParent(myself); } - public SELF haveNoIncomingRelationships(String ... types) { - throw Wip.TODO(this); + public SELF haveNoIncomingRelationships(String... types) { + return incomingRelationships(types) + .isEmpty((relationships) -> ShouldNodeHaveNoRelatedRelationships + .incomingElements(actual, relationships) + .notSatisfies(EntityUtils.havingIncomingRelationships(actual, relationships)) + ) + .toParentAssert(); } - public SELF haveNoOutgoingRelationships(String ... types) { - throw Wip.TODO(this); + public SELF haveNoOutgoingRelationships(String... types) { + return outgoingRelationships(types) + .isEmpty((relationships) -> ShouldNodeHaveNoRelatedRelationships + .outgoingElements(actual, relationships) + .notSatisfies(EntityUtils.havingOutgoingRelationships(actual, relationships)) + ) + .toParentAssert(); } + } diff --git a/src/main/java/org/assertj/neo4j/api/beta/AbstractRelationshipsAssert.java b/src/main/java/org/assertj/neo4j/api/beta/AbstractRelationshipsAssert.java index 7e230e7..7fc92bc 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/AbstractRelationshipsAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/AbstractRelationshipsAssert.java @@ -12,16 +12,16 @@ */ package org.assertj.neo4j.api.beta; -import org.assertj.neo4j.api.beta.error.ElementsShouldHaveType; +import org.assertj.neo4j.api.beta.error.ShouldRelationshipHaveType; import org.assertj.neo4j.api.beta.type.DataLoader; import org.assertj.neo4j.api.beta.type.RecordType; import org.assertj.neo4j.api.beta.type.Relationships; -import org.assertj.neo4j.api.beta.util.RelationshipTypes; +import org.assertj.neo4j.api.beta.util.Predicates; import java.util.List; /** - * @author patouche - 24/11/2020 + * @author Patrick Allain - 24/11/2020 */ //@formatter:off public abstract class AbstractRelationshipsAssert, @@ -49,10 +49,10 @@ protected AbstractRelationshipsAssert( * @return */ public SELF haveType(final String expectedType) { - if (!RelationshipTypes.are(expectedType, actual)) { - throwAssertionError(ElementsShouldHaveType.create(actual, expectedType)); - } - return myself; + return shouldAllVerify( + Predicates.isType(expectedType), + (notSatisfies -> ShouldRelationshipHaveType.elements(actual, expectedType).notSatisfies(notSatisfies)) + ); } diff --git a/src/main/java/org/assertj/neo4j/api/beta/Adoptable.java b/src/main/java/org/assertj/neo4j/api/beta/Adoptable.java index e2ab05b..e7f0aec 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/Adoptable.java +++ b/src/main/java/org/assertj/neo4j/api/beta/Adoptable.java @@ -15,7 +15,7 @@ /** * Children assertions can be adopt by another parent assertions after it has been properly created. * - * @author patouche - 27/01/2021 + * @author Patrick Allain - 27/01/2021 */ public interface Adoptable { diff --git a/src/main/java/org/assertj/neo4j/api/beta/ChildrenDriverRelationshipsAssert.java b/src/main/java/org/assertj/neo4j/api/beta/ChildrenDriverRelationshipsAssert.java index 91644ca..695c880 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/ChildrenDriverRelationshipsAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/ChildrenDriverRelationshipsAssert.java @@ -19,7 +19,7 @@ import java.util.Objects; /** - * @author patouche - 02/01/2021 + * @author Patrick Allain - 02/01/2021 */ //@formatter:off public class ChildrenDriverRelationshipsAssert @@ -72,7 +72,6 @@ public ChildrenDriverRelationshipsAssert withParent( /** {@inheritDoc} */ @Override public ROOT_ASSERT toRootAssert() { - return rootAssert() - .orElseThrow(() -> new IllegalArgumentException("Root assertion shouldn't be null !")); + return rootAssert().orElseThrow(() -> new IllegalArgumentException("Root assertion shouldn't be null !")); } } diff --git a/src/main/java/org/assertj/neo4j/api/beta/DriverAssertions.java b/src/main/java/org/assertj/neo4j/api/beta/DriverAssertions.java index 042a4c0..4b447af 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/DriverAssertions.java +++ b/src/main/java/org/assertj/neo4j/api/beta/DriverAssertions.java @@ -18,7 +18,7 @@ import org.neo4j.driver.Result; /** - * @author patouche - 5/26/20. + * @author Patrick Allain - 5/26/20. */ public class DriverAssertions { diff --git a/src/main/java/org/assertj/neo4j/api/beta/DriverNodesAssert.java b/src/main/java/org/assertj/neo4j/api/beta/DriverNodesAssert.java index c53001d..47706dd 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/DriverNodesAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/DriverNodesAssert.java @@ -19,7 +19,7 @@ import java.util.List; /** - * @author patouche - 08/11/2020 + * @author Patrick Allain - 08/11/2020 */ public final class DriverNodesAssert extends AbstractNodesAssert { @@ -33,6 +33,11 @@ public DriverNodesAssert(final Nodes nodes) { this(nodes.load(), nodes, false, null); } + /** + * FIXME : To be removed. + * + * @param entities + */ @VisibleForTesting protected DriverNodesAssert(final List entities) { this(entities, null, false, null); @@ -47,12 +52,13 @@ private DriverNodesAssert(final List entities, entities, nodes, ignoreIds, - DriverNodesAssert::new, parent, + DriverNodesAssert::new, + parent, Navigable.rootAssert(parent) ); } - /** {@inheritDoc}*/ + /** {@inheritDoc} */ @Override public DriverNodesAssert toRootAssert() { return rootAssert().orElse(this); diff --git a/src/main/java/org/assertj/neo4j/api/beta/DriverRelationshipsAssert.java b/src/main/java/org/assertj/neo4j/api/beta/DriverRelationshipsAssert.java index cfc3b7d..78416c0 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/DriverRelationshipsAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/DriverRelationshipsAssert.java @@ -19,7 +19,7 @@ import java.util.List; /** - * @author patouche - 24/11/2020 + * @author Patrick Allain - 24/11/2020 */ //@formatter:off public class DriverRelationshipsAssert @@ -37,6 +37,11 @@ public DriverRelationshipsAssert(final Relationships relationships) { this(relationships.load(), relationships, false, null); } + /** + * FIXME : To be removed. + * + * @param entities + */ @VisibleForTesting protected DriverRelationshipsAssert(final List entities) { this(entities, null, false, null); diff --git a/src/main/java/org/assertj/neo4j/api/beta/DriverRequestAssert.java b/src/main/java/org/assertj/neo4j/api/beta/DriverRequestAssert.java index c4354cf..55546f3 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/DriverRequestAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/DriverRequestAssert.java @@ -17,7 +17,7 @@ import org.assertj.neo4j.api.beta.util.Wip; /** - * @author patouche - 27/11/2020 + * @author Patrick Allain - 27/11/2020 */ public class DriverRequestAssert extends AbstractAssert { diff --git a/src/main/java/org/assertj/neo4j/api/beta/DriverResultAssert.java b/src/main/java/org/assertj/neo4j/api/beta/DriverResultAssert.java index 6478e41..39c1262 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/DriverResultAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/DriverResultAssert.java @@ -23,7 +23,7 @@ import java.util.Map; /** - * @author patouche - 26/01/2021 + * @author Patrick Allain - 26/01/2021 */ public class DriverResultAssert extends AbstractIterableAssert< DriverResultAssert, List>, Map, RecordMapAssert> { @@ -34,8 +34,6 @@ public DriverResultAssert(final Result result) { super(result.list(Record::asMap), DriverResultAssert.class); } - - public DriverResultAssert hasColumnNumber(int i) { return myself; } diff --git a/src/main/java/org/assertj/neo4j/api/beta/Navigable.java b/src/main/java/org/assertj/neo4j/api/beta/Navigable.java index dbc417d..6068223 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/Navigable.java +++ b/src/main/java/org/assertj/neo4j/api/beta/Navigable.java @@ -15,12 +15,12 @@ import java.util.Optional; /** - * @author patouche - 01/01/2021 + * Indicate that an assertion can be navigable. + * + * @author Patrick Allain - 01/01/2021 */ public interface Navigable { - - PARENT_ASSERT toParentAssert(); ROOT_ASSERT toRootAssert(); diff --git a/src/main/java/org/assertj/neo4j/api/beta/NavigableListAssert.java b/src/main/java/org/assertj/neo4j/api/beta/NavigableListAssert.java index d519483..8eb79b8 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/NavigableListAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/NavigableListAssert.java @@ -20,11 +20,11 @@ import java.util.List; /** - * @author patouche - 26/01/2021 + * @author Patrick Allain - 26/01/2021 */ //@formatter:off public class NavigableListAssert - extends AbstractListAssert , List, ACTUAL, ObjectAssert> + extends AbstractListAssert, List, ACTUAL, ObjectAssert> implements Navigable { //@formatter:on public NavigableListAssert(List< ACTUAL> actual) { diff --git a/src/main/java/org/assertj/neo4j/api/beta/RecordAssert.java b/src/main/java/org/assertj/neo4j/api/beta/RecordAssert.java index 8220f4b..8bdea39 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/RecordAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/RecordAssert.java @@ -16,7 +16,7 @@ import org.neo4j.driver.Record; /** - * @author patouche - 26/01/2021 + * @author Patrick Allain - 26/01/2021 */ public class RecordAssert extends AbstractAssert { public RecordAssert(Record record) { diff --git a/src/main/java/org/assertj/neo4j/api/beta/RecordMapAssert.java b/src/main/java/org/assertj/neo4j/api/beta/RecordMapAssert.java index 70d11e6..6554378 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/RecordMapAssert.java +++ b/src/main/java/org/assertj/neo4j/api/beta/RecordMapAssert.java @@ -19,7 +19,7 @@ import java.util.Map; /** - * @author patouche - 26/01/2021 + * @author Patrick Allain - 26/01/2021 */ public class RecordMapAssert extends AbstractAssert> { diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/BasicEntityErrorMessageFactory.java b/src/main/java/org/assertj/neo4j/api/beta/error/BasicEntityErrorMessageFactory.java new file mode 100644 index 0000000..ae8da7f --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/BasicEntityErrorMessageFactory.java @@ -0,0 +1,78 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.BasicErrorMessageFactory; +import org.assertj.neo4j.api.beta.type.DbEntity; +import org.assertj.neo4j.api.beta.util.Presentations; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Basic entity error message factory. + * + * @param the entity type + * @author Patrick Allain - 03/02/2021 + */ +class BasicEntityErrorMessageFactory> + extends BasicErrorMessageFactory + implements EntityErrorMessageFactory { + + private final ENTITY actual; + + private final List details; + + /** + * Creates a new {@link BasicErrorMessageFactory} for the {@code actual} {@link ENTITY}. + *

+ * + * @param format the format string. + * @param actual the actual entity involve. + * @param details details error that will be used as argument for formatting and preprocessing. + */ + protected BasicEntityErrorMessageFactory(final String format, final ENTITY actual, final ArgDetail... details) { + super(format, toArguments(actual, details)); + this.actual = actual; + this.details = Arrays.stream(details).filter(ArgDetail::isIncluded).collect(Collectors.toList()); + } + + /** + * Create the arguments for the message formatter. + * + * @param entity the entity. + * @param details the error details + * @return an array for the provided arguments + */ + protected static > Object[] toArguments(final E entity, final ArgDetail... details) { + return Stream + .concat( + Stream.of(unquotedString(Presentations.outputId(entity))), + Arrays.stream(details).map(ArgDetail::value) + ) + .toArray(); + } + + /** {@inheritDoc} */ + @Override + public ENTITY entity() { + return this.actual; + } + + @Override + public List details() { + return details; + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/BasicGroupingEntityErrorFactory.java b/src/main/java/org/assertj/neo4j/api/beta/error/BasicGroupingEntityErrorFactory.java new file mode 100644 index 0000000..6279905 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/BasicGroupingEntityErrorFactory.java @@ -0,0 +1,130 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.BasicErrorMessageFactory; +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.core.util.Strings; +import org.assertj.neo4j.api.beta.type.DbEntity; +import org.assertj.neo4j.api.beta.type.RecordType; +import org.assertj.neo4j.api.beta.util.Checks; +import org.assertj.neo4j.api.beta.util.EntityUtils; +import org.assertj.neo4j.api.beta.util.Presentations; +import org.assertj.neo4j.api.beta.util.Utils; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +/** + * Grouping entity error factory in design to create a new {@link ErrorMessageFactory} based on a list of failing + * entities provided in an {@link EntityErrorMessageFactory}. + * + * @author Patrick Allain - 05/02/2021 + */ +public class BasicGroupingEntityErrorFactory> + implements GroupingEntityErrorFactory { + + private final List actual; + private final Function> mapper; + private final String format; + private final Object[] arguments; + + /** + * Class constructor for generating a grouping error message. + *

+ * Arguments will be concatenate at first : + *

    + *
  1. {@code %1$s} : The representation of actual entities
  2. + *
  3. {@code %2$s} : The representation of not satisfying entities
  4. + *
  5. {@code %3$s} : The plural form of the entities
  6. + *
  7. {@code %x$s} : All remaining arguments
  8. + *
+ * + * @param actual the list of actual entities + * @param mapper the function to transform entities that don't satisfies the condition into a {@link + * EntityErrorMessageFactory} + * @param format the message format + * @param arguments any other remaining arguments + */ + public BasicGroupingEntityErrorFactory( + final List actual, + final Function> mapper, + final String format, + final Object... arguments) { + this.actual = Checks.notNullOrEmpty(actual, "The list of entities cannot be null"); + this.mapper = mapper; + this.format = format; + this.arguments = arguments; + } + + @Override + public ErrorMessageFactory notSatisfies(final List notSatisfies) { + final RecordType type = Checks.first(this.actual, "The entity list cannot be empty").getRecordType(); + final List sortedNotSatisfies = EntityUtils.sorted(notSatisfies); + return new GroupingEntityErrorMessageFactory<>( + this.format + "%n%n" + Strings.escapePercent(this.formatItems(sortedNotSatisfies)), + EntityUtils.sorted(this.actual), + sortedNotSatisfies, + type, + arguments + ); + } + + private String formatItems(final List notSatisfies) { + return IntStream.range(0, notSatisfies.size()) + .mapToObj(idx -> this.formatItem(idx, notSatisfies.get(idx))) + .collect(Collectors.joining(String.format("%n%n"))); + } + + private String formatItem(final int index, final ENTITY entity) { + final List details = this.mapper.apply(entity).details(); + return Stream + .concat( + Stream.of(String.format("%d) %s", index + 1, Presentations.outputId(entity))), + details.stream().map(i -> String.format(" - %s: %s", i.title(), i.value())) + ) + .map(i -> " " + i) + .collect(Collectors.joining(String.format("%n"))); + } + + private static class GroupingEntityErrorMessageFactory> + extends BasicErrorMessageFactory { + + public GroupingEntityErrorMessageFactory( + final String format, + final List actual, + final List notSatisfies, + final RecordType type, + Object... arguments) { + super(format, toArguments(actual, notSatisfies, type, arguments)); + } + + private static > Object[] toArguments( + final List actual, final List notSatisfies, final RecordType type, final Object[] arguments) { + return Stream + .concat( + Stream.of( + Presentations.outputIds(actual), + Presentations.outputIds(notSatisfies), + unquotedString(type.pluralForm()) + ), + Arrays.stream(arguments) + ).toArray(); + } + } + +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/DbEntitiesMessageFactory.java b/src/main/java/org/assertj/neo4j/api/beta/error/DbEntitiesMessageFactory.java deleted file mode 100644 index 42b4370..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/DbEntitiesMessageFactory.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.error.BasicErrorMessageFactory; -import org.assertj.core.util.Strings; -import org.assertj.neo4j.api.beta.type.DbEntity; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.assertj.neo4j.api.beta.util.Presentations; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * See how the - */ -public abstract class DbEntitiesMessageFactory, EXPECTED, ITEM> extends BasicErrorMessageFactory { - - /** - * Creates a new {@link BasicErrorMessageFactory}. - */ - protected DbEntitiesMessageFactory( - final RecordType recordType, - final String title, - final String but, - final List actual, final EXPECTED expected, - final List items, - final ItemMessageFactory factory) { - super( - "%nExpecting %s:%n" - + " %s%n" - + "%s:%n" - + " %s%n" - + "%s:%n%n" - + Strings.escapePercent(describeItems(expected, items, factory)), - unquotedString(recordType.pluralForm()), - Presentations.outputIds(actual), - unquotedString(title), - expected, - unquotedString(but) - ); - } - - private static String describeItems( - final EXPECTED expected, final List items, - final ItemMessageFactory factory) { - return items.stream() - .map(item -> factory.describeItem(expected, item)) - .collect(Collectors.joining(String.format("%n%n"))); - } - - @FunctionalInterface - interface ItemMessageFactory { - - String describeItem(EXPECTED expected, ITEM item); - - } - -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveLabels.java b/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveLabels.java deleted file mode 100644 index eb1a174..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveLabels.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.neo4j.api.beta.type.Nodes.DbNode; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.assertj.neo4j.api.beta.util.Presentations; - -import java.util.List; - -/** - * @author patouche - 29/09/2020 - */ -public class ElementsShouldHaveLabels extends DbEntitiesMessageFactory, Missing> { - - private ElementsShouldHaveLabels( - final List actual, final List expectedLabels, - final List> missingActual) { - super( - RecordType.NODE, - "to have all the following labels", - "but some labels were missing on", - actual, expectedLabels, missingActual, itemFactory() - ); - } - - private static ItemMessageFactory, Missing> itemFactory() { - return (expected, missing) -> String.format( - " - %s have missing labels: %s%n" - + " Expected: %s%n" - + " Actual : %s", - Presentations.outputId(missing.getEntity()), missing.getData(), expected, - missing.getEntity().getSortedLabels() - ); - } - - /** - * Create a new error when there is a missing labels on a {@link DbNode}. - * - * @param actual the database nodes which have missing labels - * @param expectedLabels all expected labels - * @param missingActual all missing labels - * @return a new instance of {@link ElementsShouldHaveLabels}. - */ - public static ElementsShouldHaveLabels create( - final List actual, final List expectedLabels, - final List> missingActual) { - return new ElementsShouldHaveLabels(actual, expectedLabels, missingActual); - } - -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyInstanceOf.java b/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyInstanceOf.java deleted file mode 100644 index 1e4d7a6..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyInstanceOf.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.error.ErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.DbEntity; -import org.assertj.neo4j.api.beta.type.RecordType; - -import java.util.List; - -/** - * @author patouche - 30/01/2021 - */ -public class ElementsShouldHavePropertyInstanceOf> - extends DbEntitiesMessageFactory, E> { - - protected ElementsShouldHavePropertyInstanceOf(RecordType recordType, List actual, - String key, Class expectedClass) { - super(recordType, "title", "but", actual, expectedClass, actual, (e, v) -> "TODO"); - } - - public static > ErrorMessageFactory create(RecordType recordType, List actual, - String key, Class expectedClass) { - return new ElementsShouldHavePropertyInstanceOf<>(recordType, actual, key, expectedClass); - } -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyKeys.java b/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyKeys.java deleted file mode 100644 index e0fbc61..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyKeys.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.util.Streams; -import org.assertj.neo4j.api.beta.type.DbEntity; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.assertj.neo4j.api.beta.util.Presentations; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * @author patouche - 26/11/2020 - */ -public class ElementsShouldHavePropertyKeys> - extends DbEntitiesMessageFactory, Missing> { - - private ElementsShouldHavePropertyKeys( - final RecordType recordType, final List actual, final List expectedKeys) { - super( - recordType, - "to have all the following property keys", - "but some property keys were missing on", - actual, - expectedKeys, - missingPropertyKeys(actual, expectedKeys), - itemFactory() - ); - } - - static > Missing missingPropertyKeys(final E entity, final Iterable keys) { - final List entityKeys = entity.getPropertyKeys(); - final List missingKeys = Streams.stream(keys) - .filter(expectedLabel -> !entityKeys.contains(expectedLabel)) - .collect(Collectors.toList()); - return new Missing<>(entity, missingKeys); - } - - static > List> missingPropertyKeys( - final List entities, final Iterable keys) { - return entities.stream() - .map(node -> missingPropertyKeys(node, keys)) - .filter(Missing::hasMissing) - .collect(Collectors.toList()); - } - - private static > ItemMessageFactory, Missing> itemFactory() { - return (expected, missing) -> String.format( - " - %s have missing property keys: %s%n" - + " Actual : <%s>%n" - + " Expected: <%s>", - Presentations.outputId(missing.getEntity()), - missing.getData(), - missing.getEntity().getPropertyKeys(), - expected - ); - } - - public static > ElementsShouldHavePropertyKeys create( - final RecordType recordType, final List actual, final List expectedKeys) { - return new ElementsShouldHavePropertyKeys<>(recordType, actual, expectedKeys); - } - -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyListOfType.java b/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyListOfType.java deleted file mode 100644 index 9322820..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyListOfType.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.error.ErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.DbEntity; -import org.assertj.neo4j.api.beta.type.DbValue; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.assertj.neo4j.api.beta.type.ValueType; -import org.assertj.neo4j.api.beta.util.Presentations; - -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class ElementsShouldHavePropertyListOfType> - extends DbEntitiesMessageFactory { - - private ElementsShouldHavePropertyListOfType(final RecordType recordType, final List actual, final String key, - final ValueType expectedType) { - super(recordType, - String.format("to have property list \"%s\" containing type", key), - String.format("but some %s have for the property list \"%s\" have other types", - recordType.pluralForm(), key), - actual, - expectedType, - actual.stream() - .filter(e -> otherTypeInList(e, key, expectedType)) - .collect(Collectors.toList()), - itemFactory(key) - ); - } - - // FIXME : Externalize ? - private static > Stream streamValues(E entity, String key) { - final Object value = entity.getPropertyValue(key); - if (!(value instanceof List)) { - throw new IllegalArgumentException("Should have a list value"); - } - return ((List) value).stream(); - } - - private static > boolean otherTypeInList(final E entity, final String key, - final ValueType expectedType) { - return !streamValues(entity, key).map(DbValue::getType).allMatch(t -> t == expectedType); - } - - private static > ItemMessageFactory itemFactory(final String key) { - return (expected, entity) -> String.format( - " - %s don't have property list \"%s\" containing type:%n" - + " Expected: %s%n" - + " Actual : %s%n" - + " Value : %s", - Presentations.outputId(entity), - key, - expected, - streamValues(entity, key).findFirst().map(DbValue::getType).orElse(null), - streamValues(entity, key).map(DbValue::getContent).collect(Collectors.toList()) - ); - } - - public static > ErrorMessageFactory create( - final RecordType recordType, final List actual, final String key, ValueType expectedType) { - return new ElementsShouldHavePropertyListOfType<>(recordType, actual, key, expectedType); - } -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertySize.java b/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertySize.java deleted file mode 100644 index 25ad446..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertySize.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.error.ErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.DbEntity; -import org.assertj.neo4j.api.beta.type.RecordType; - -import java.util.List; - -/** - * @author patouche - 01/02/2021 - */ -public class ElementsShouldHavePropertySize> - extends DbEntitiesMessageFactory { - - public ElementsShouldHavePropertySize(RecordType recordType, List actual, List notSatisfies, int size) { - super(recordType, "title", "but", actual, size, notSatisfies, (e, v) -> "todo"); - } - - public static > ErrorMessageFactory create( - RecordType recordType, List actual, List notSatisfies, int size) { - return new ElementsShouldHavePropertySize<>(recordType, actual, notSatisfies, size); - } -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValue.java b/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValue.java deleted file mode 100644 index e9a74d8..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValue.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.error.ErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.DbEntity; -import org.assertj.neo4j.api.beta.type.RecordType; - -import java.util.List; - -/** - * @author patouche - 31/01/2021 - */ -public class ElementsShouldHavePropertyValue> - extends DbEntitiesMessageFactory { - - private ElementsShouldHavePropertyValue(RecordType recordType, List actual, List notSatisfies, - String key, Object expectedValue) { - super( - recordType, - "", - "", - actual, - "notSatisfies", notSatisfies, (e, v) -> "todo"); - } - - public static > ErrorMessageFactory create( - final RecordType recordType, - final List actual, - final List notSatisfies, - final String key, - final Object expectedValue) { - return new ElementsShouldHavePropertyValue<>(recordType, - actual, - notSatisfies, - key, - expectedValue); - } -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValueType.java b/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValueType.java deleted file mode 100644 index adc5173..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValueType.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.error.ErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.DbEntity; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.assertj.neo4j.api.beta.type.ValueType; -import org.assertj.neo4j.api.beta.util.Presentations; - -import java.util.List; -import java.util.stream.Collectors; - -public class ElementsShouldHavePropertyValueType> - extends DbEntitiesMessageFactory { - - private ElementsShouldHavePropertyValueType(final RecordType recordType, final List actual, final String key, - final ValueType expectedType) { - super(recordType, - String.format("to have property \"%s\" with type", key), - String.format("but some %s have for the property \"%s\" another type", recordType.pluralForm(), key), - actual, - expectedType, - actual.stream().filter(e -> e.getPropertyType(key) != expectedType).collect(Collectors.toList()), - itemFactory(key) - ); - } - - private static > ItemMessageFactory itemFactory(final String key) { - return (expected, entity) -> String.format( - " - %s have property \"%s\" of type:%n" - + " Expected: %s%n" - + " Actual : %s%n" - + " Value : %s", - Presentations.outputId(entity), key, expected, entity.getPropertyType(key), entity.getPropertyValue(key) - ); - } - - public static > ErrorMessageFactory create( - final RecordType recordType, - final List actual, - final String key, - final ValueType expectedType) { - return new ElementsShouldHavePropertyValueType<>(recordType, actual, key, expectedType); - } -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveType.java b/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveType.java deleted file mode 100644 index 553bd85..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveType.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.error.BasicErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; -import org.assertj.neo4j.api.beta.util.Presentations; -import org.assertj.neo4j.api.beta.util.RelationshipTypes; - -import java.util.List; - -/** - * @author patouche - 25/11/2020 - */ -public class ElementsShouldHaveType extends DbEntitiesMessageFactory { - - /** - * Creates a new {@link BasicErrorMessageFactory}. - * - * @param actual the relationships - * @param expectedType the expected type - */ - public ElementsShouldHaveType(final List actual, final String expectedType) { - super( - RecordType.RELATIONSHIP, - "to be of type", - "but some relationships have an other type", - actual, - expectedType, - RelationshipTypes.others(expectedType, actual), - factory() - ); - } - - private static ItemMessageFactory factory() { - return (expected, relationship) -> String.format( - " - %s doesn't have the expected type:%n" - + " Actual : %s%n" - + " Expected: %s", - Presentations.outputId(relationship), relationship.getType(), expected - ); - } - - public static ElementsShouldHaveType create( - final List actual, final String expectedType) { - return new ElementsShouldHaveType(actual, expectedType); - } -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/EntityErrorMessageFactory.java b/src/main/java/org/assertj/neo4j/api/beta/error/EntityErrorMessageFactory.java new file mode 100644 index 0000000..2a3d669 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/EntityErrorMessageFactory.java @@ -0,0 +1,114 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.type.DbEntity; + +import java.util.List; +import java.util.Objects; + +/** + * Factory for entity error messages. + *

+ * This factory is intent to be attach to parent message factory to have a nice message with the list of all entities + * which didn't satisfies the condition. + * + * @author Patrick Allain - 03/02/2021 + */ +interface EntityErrorMessageFactory> extends ErrorMessageFactory { + + /** + * Retrieve the actual entity that will is related to the {@link ErrorMessageFactory}. + * + * @return the entity. + */ + ENTITY entity(); + + /** + * Provide details about the failing assertion. + *

+ * This method will be use to describe a list of entities that don't fill the assertion. + * + * @return the error details + */ + List details(); + + /** + * Argument details. Only the {@link ArgDetail} having a title will be included in the {@link #details()} list. + */ + class ArgDetail { + + private final String title; + private final Object value; + + private ArgDetail(final String title, final Object value) { + this.title = title; + this.value = value; + } + + /** + * Create a new {@link ArgDetail} for an {@link EntityErrorMessageFactory} that will be included in the result + * {@link #details()}. + * + * @param title the title of error detail. + * @param value the error detail value. + * @return a new {@link ArgDetail} + */ + static ArgDetail included(final String title, final Object value) { + return new ArgDetail(Objects.requireNonNull(title, "Title cannot be null for included argument@"), value); + } + + /** + * Create a new {@link ArgDetail} for an {@link EntityErrorMessageFactory} that will not be included in the + * result {@link #details()}. + * + * @param value the error detail value. + * @return a new {@link ArgDetail} + */ + static ArgDetail excluded(final Object value) { + return new ArgDetail(null, value); + } + + public boolean isIncluded() { + return this.title != null; + } + + public String title() { + return title; + } + + public Object value() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ArgDetail that = (ArgDetail) o; + return Objects.equals(title, that.title) + && Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(title, value); + } + + @Override + public String toString() { + return "ErrorDetail{title='" + title + "', value=" + value + '}'; + } + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldAllHaveLabel.java b/src/main/java/org/assertj/neo4j/api/beta/error/GroupingEntityErrorFactory.java similarity index 54% rename from src/main/java/org/assertj/neo4j/api/beta/error/ShouldAllHaveLabel.java rename to src/main/java/org/assertj/neo4j/api/beta/error/GroupingEntityErrorFactory.java index 826ec78..8acdc80 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldAllHaveLabel.java +++ b/src/main/java/org/assertj/neo4j/api/beta/error/GroupingEntityErrorFactory.java @@ -12,23 +12,22 @@ */ package org.assertj.neo4j.api.beta.error; -import org.assertj.core.error.BasicErrorMessageFactory; -import org.neo4j.driver.types.Node; +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.type.DbEntity; -import java.util.stream.Stream; +import java.util.List; /** - * @author patouche - 29/09/2020 + * @author Patrick Allain - 05/02/2021 */ -@Deprecated -public class ShouldAllHaveLabel extends BasicErrorMessageFactory { +public interface GroupingEntityErrorFactory> { - private ShouldAllHaveLabel(final String labelName, final Stream nodes) { - super("TODO"); - } - - public static ShouldAllHaveLabel create(final String labelName, final Stream nodes) { - return new ShouldAllHaveLabel(labelName, nodes); - } + /** + * Create a new {@link ErrorMessageFactory} for a group of entities. + * + * @param notSatisfies a list of entities that don't match the expected assertion condition. + * @return a new {@link ErrorMessageFactory} + */ + ErrorMessageFactory notSatisfies(final List notSatisfies); } diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/Missing.java b/src/main/java/org/assertj/neo4j/api/beta/error/Missing.java deleted file mode 100644 index c418f79..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/Missing.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.neo4j.api.beta.type.DbEntity; - -import java.util.List; -import java.util.Objects; - -/** - * Associate data list with a given entity. - * - * @author patouche - 14/11/2020 - */ -public class Missing, M> { - - /** The entity. */ - private final E entity; - - /** The missing data. */ - private final List data; - - public Missing(final E entity, final List data) { - this.entity = entity; - this.data = data; - } - - public E getEntity() { - return entity; - } - - public List getData() { - return data; - } - - public boolean hasMissing() { - return !data.isEmpty(); - } - - @Override - public String toString() { - return "Missing{entity=" + entity + ", data=" + data + '}'; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final Missing that = (Missing) o; - return Objects.equals(entity, that.entity) - && Objects.equals(data, that.data); - } - - @Override - public int hashCode() { - return Objects.hash(entity, data); - } -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldBeEmptyQueryResult.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldBeEmptyQueryResult.java new file mode 100644 index 0000000..7d0d101 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldBeEmptyQueryResult.java @@ -0,0 +1,53 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.neo4j.api.beta.type.DbEntity; +import org.neo4j.driver.Query; + +import java.util.List; + +/** + * @author patouche - 13/02/2021 + */ +public class ShouldBeEmptyQueryResult> + extends BasicEntityErrorMessageFactory { + + private ShouldBeEmptyQueryResult(final ENTITY actual, final Query query) { + super( + "%nExpecting query:%n" + + " <%2$s>%n" + + "to return a empty list but got:%n" + + " <%1$s>", + actual, + ArgDetail.excluded(query) + ); + } + + public static > ShouldBeEmptyQueryResult create(E actual, Query query) { + return new ShouldBeEmptyQueryResult<>(actual, query); + } + + public static > GroupingEntityErrorFactory elements(List actual, Query query) { + return new BasicGroupingEntityErrorFactory<>( + actual, + (e) -> create(e, query), + "%nExpecting query:%n" + + " <%4$s>%n" + + "to return no %3$s but got:%n" + + " <%1$s>", + query + ); + } + +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveNodeLabels.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveNodeLabels.java new file mode 100644 index 0000000..e20e89b --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveNodeLabels.java @@ -0,0 +1,60 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.assertj.neo4j.api.beta.util.Utils; + +import java.util.List; + +/** + * Creates an error message indicating that an assertion that verifies a node don't have the expected labels. + * + * @author Patrick Allain - 29/09/2020 + */ +public class ShouldHaveNodeLabels extends BasicEntityErrorMessageFactory { + + private ShouldHaveNodeLabels(final DbNode actual, final Iterable labels) { + super( + "%nExpecting %s which have labels:\n" + + " <[\"LBL_1\", \"LBL_4\"]>\n" + + "to have labels:\n" + + " <[\"LBL_1\", \"LBL_2\", \"LBL_3\", \"LBL_4\"]>\n" + + "but the following labels cannot be found:\n" + + " <[\"LBL_2\", \"LBL_3\"]>", + actual, + ArgDetail.included("Actual labels", Utils.sorted(actual.getLabels())), + ArgDetail.excluded(Utils.sorted(labels)), + ArgDetail.included("Missing Labels", Utils.missing(labels, actual.getLabels())) + ); + } + + public static ShouldHaveNodeLabels create(final DbNode node, final Iterable labels) { + return new ShouldHaveNodeLabels(node, labels); + } + + public static GroupingEntityErrorFactory elements(final List actual, + final Iterable labels) { + return new BasicGroupingEntityErrorFactory<>( + actual, + node -> create(node, labels), + "%nExpecting nodes:%n" + + " <%1$s>%n" + + "to have the labels:%n" + + " <%4$s>%n" + + "but some labels are missing for nodes:", + Utils.sorted(labels) + ); + } + +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyInstanceOf.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyInstanceOf.java new file mode 100644 index 0000000..f91f832 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyInstanceOf.java @@ -0,0 +1,65 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.neo4j.api.beta.type.DbEntity; + +import java.util.List; + +/** + * Creates an error message indicating that an assertion that verifies a {@link ENTITY} property value is not of the + * expected type. + * + * @param the entity type + * @author Patrick Allain - 30/01/2021 + */ +public class ShouldHavePropertyInstanceOf> + extends BasicEntityErrorMessageFactory { + + private ShouldHavePropertyInstanceOf(final ENTITY actual, final String key, final Class expectedClass) { + super( + "%nExpecting %s to have property value %s instance of:%n" + + " <%s>%n" + + "but the actual property value for this key is a :%n" + + " <%s>%n" + + "which is not an instance of the expected class.%n%n" + + "Actual value for this property is:%n" + + " <%s>", + actual, + ArgDetail.excluded(key), + ArgDetail.excluded(expectedClass), + ArgDetail.included("Actual value class", actual.getPropertyValue(key).getClass().getName()), + ArgDetail.included("Actual value", actual.getPropertyValue(key)) + ); + } + + public static > ShouldHavePropertyInstanceOf create( + final E actual, final String key, final Class expectedClass) { + return new ShouldHavePropertyInstanceOf<>(actual, key, expectedClass); + } + + public static > GroupingEntityErrorFactory elements( + final List actual, final String key, final Class expectedClass) { + return new BasicGroupingEntityErrorFactory<>( + actual, + (e) -> create(e, key, expectedClass), + "%nExpecting %3$s:%n" + + " <%1$s>%n" + + "to have property value %4$s instance of:%n" + + " <%5$s>%n" + + "but some %3$s have a property value which is not an instance of the expected class:", + key, + expectedClass + ); + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyKeys.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyKeys.java new file mode 100644 index 0000000..9e65e3d --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyKeys.java @@ -0,0 +1,63 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.neo4j.api.beta.type.DbEntity; +import org.assertj.neo4j.api.beta.util.Utils; + +import java.util.List; + +/** + * Creates an error message indicating that an assertion that verifies a {@link ENTITY} don't have the expected property + * keys. + * + * @param the entity type + * @author Patrick Allain - 29/09/2020 + */ +public class ShouldHavePropertyKeys> extends BasicEntityErrorMessageFactory { + + private ShouldHavePropertyKeys(final ENTITY actual, final Iterable keys) { + super( + "%nExpecting %s with property keys:%n" + + " <%s>%n" + + "to have property keys:%n" + + " <%s>%n" + + "but the following property keys cannot be found:%n" + + " <%s>", + actual, + ArgDetail.included("Actual property keys", actual.getPropertyKeys()), + ArgDetail.excluded(Utils.sorted(keys)), + ArgDetail.included("Missing property keys", Utils.missing(keys, actual.getPropertyKeys())) + ); + } + + public static > EntityErrorMessageFactory create( + final E actual, final Iterable keys) { + return new ShouldHavePropertyKeys<>(actual, keys); + } + + public static > GroupingEntityErrorFactory elements( + final List actual, final Iterable keys) { + return new BasicGroupingEntityErrorFactory<>( + actual, + (e) -> create(e, keys), + "%nExpecting %3$s:%n" + + " <%1$s>%n" + + "to have properties with keys:%n" + + " <%4$s>%n" + + "but some %3$s don't have this properties:", + Utils.sorted(keys) + ); + } + +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyListOfType.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyListOfType.java new file mode 100644 index 0000000..845a889 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyListOfType.java @@ -0,0 +1,72 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.neo4j.api.beta.type.DbEntity; +import org.assertj.neo4j.api.beta.type.DbValue; +import org.assertj.neo4j.api.beta.type.ValueType; + +import java.util.List; + +/** + * Creates an error message indicating that an assertion that verifies a {@link ENTITY} property list contains only + * value of the expected type. + * + * @param the entity type + * @author Patrick ALLAIN - 29/09/2020 + */ +public class ShouldHavePropertyListOfType> + extends BasicEntityErrorMessageFactory { + + private ShouldHavePropertyListOfType(final ENTITY actual, final String key, final ValueType type) { + super( + "%nExpected %s to have a composite property list named %s containing only type:%n" + + " <%s>%n" + + "but this composite property list contains type:%n" + + " <%s>%n" + + "with actual value:%n" + + " <%s>", + actual, + ArgDetail.excluded(key), + ArgDetail.excluded(type), + ArgDetail.included("Actual list value type", + actual.getPropertyList(key) + .stream() + .findFirst() + .map(DbValue::getType) + .orElse(null) + ), + ArgDetail.included("Actual value", actual.getPropertyListValues(key)) + ); + } + + public static > ShouldHavePropertyListOfType create( + final E node, final String key, final ValueType type) { + return new ShouldHavePropertyListOfType<>(node, key, type); + } + + public static > GroupingEntityErrorFactory elements( + final List actual, final String key, final ValueType type) { + return new BasicGroupingEntityErrorFactory<>( + actual, + (e) -> create(e, key, type), + "%nExpecting %3$s:%n" + + " <%1$s>%n" + + "to have a composite property list named %4$s containing only type:%n" + + " <%5$s>%n" + + "but some %3$s have a composite list containing others type:", + key, + type + ); + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertySize.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertySize.java new file mode 100644 index 0000000..67f865b --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertySize.java @@ -0,0 +1,59 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.neo4j.api.beta.type.DbEntity; + +import java.util.List; + +/** + * Creates an error message indicating that an assertion that verifies {@link ENTITY} properties don't have the expected + * size. + * + * @param the entity type + * @author Patrick Allain - 01/02/2021 + */ +public class ShouldHavePropertySize> extends BasicEntityErrorMessageFactory { + + private ShouldHavePropertySize(final ENTITY actual, final int size) { + super( + "%nExpecting %s to have property size:%n" + + " <%s>%n" + + "but actual property size is:%n" + + " <%s>%n" + + "containing the following property keys:%n" + + " <%s>", + actual, + ArgDetail.excluded(size), + ArgDetail.included("Actual property size", actual.getPropertyKeys().size()), + ArgDetail.included("Actual property keys", actual.getPropertyKeys()) + ); + } + + public static > ShouldHavePropertySize create(final E actual, final int size) { + return new ShouldHavePropertySize<>(actual, size); + } + + public static > GroupingEntityErrorFactory elements(final List actual, final int size) { + return new BasicGroupingEntityErrorFactory<>( + actual, + (e) -> create(e, size), + "%nExpecting %3$s:%n" + + " <%1$s>%n" + + "to have a property size:%n" + + " <%4$s>%n" + + "but some %3$s have another property size:", + size + ); + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValue.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValue.java new file mode 100644 index 0000000..ee1f635 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValue.java @@ -0,0 +1,64 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.neo4j.api.beta.type.DbEntity; + +import java.util.List; + +/** + * Creates an error message indicating that an assertion that verifies {@link ENTITY} don't have the expected property + * value. + * + * @param the entity type + * @author Patrick Allain - 31/01/2021 + */ +public class ShouldHavePropertyValue> + extends BasicEntityErrorMessageFactory { + + private ShouldHavePropertyValue(final ENTITY actual, final String key, final Object value) { + super( + "%nExpecting %s to have a property %s with value:%n" + + " <%s>%n" + + "but current value of this property is:%n" + + " <%s>", + actual, + ArgDetail.excluded(key), + ArgDetail.excluded(value), + ArgDetail.included("Actual value", actual.getPropertyValue(key)), + ArgDetail.included("Actual type", actual.getPropertyType(key)) + ); + } + + public static > ShouldHavePropertyValue create( + final E actual, final String key, final Object value) { + return new ShouldHavePropertyValue<>(actual, key, value); + } + + public static > GroupingEntityErrorFactory elements( + final List actual, + final String key, + final Object value) { + return new BasicGroupingEntityErrorFactory<>( + actual, + (e) -> create(e, key, value), + "%nExpecting %3$s:%n" + + " <%1$s>%n" + + "to have a property named %4$s with value:%n" + + " <%5$s>%n" + + "but some %3$s have a different value for this property:", + key, + value + ); + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueType.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueType.java new file mode 100644 index 0000000..f187807 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueType.java @@ -0,0 +1,65 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.neo4j.api.beta.type.DbEntity; +import org.assertj.neo4j.api.beta.type.ValueType; + +import java.util.List; + +/** + * Creates an error message indicating that an assertion that verifies {@link ENTITY} don't have the expected property + * value type. + * + * @param the entity type + * @author Patrick Allain - 31/01/2021 + */ +public class ShouldHavePropertyValueType> + extends BasicEntityErrorMessageFactory { + + private ShouldHavePropertyValueType(final ENTITY actual, final String key, final ValueType expectedType) { + super( + "%nExpecting %s to have property value type for key %s:%n" + + " <%s>%n" + + "but actual value type for this property key is:%n" + + " <%s>%n%n" + + "Actual property value:%n" + + " <%s>", + actual, + ArgDetail.excluded(key), + ArgDetail.excluded(expectedType), + ArgDetail.included("Actual value type", actual.getPropertyType(key)), + ArgDetail.included("Actual value", actual.getPropertyValue(key)) + ); + } + + public static > ShouldHavePropertyValueType create( + final E actual, final String key, final ValueType expectedType) { + return new ShouldHavePropertyValueType<>(actual, key, expectedType); + } + + public static > GroupingEntityErrorFactory elements( + final List actual, final String key, final ValueType expectedType) { + return new BasicGroupingEntityErrorFactory<>( + actual, + (e) -> create(e, key, expectedType), + "%nExpecting %3$s:%n" + + " <%1$s>%n" + + "to have a property %4$s with a value type:%n" + + " <%5$s>%n" + + "but some %3$s have a different property value type:", + key, + expectedType + ); + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyWithType.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyWithType.java deleted file mode 100644 index 9bbaf6d..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyWithType.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.error.BasicErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.DbEntity; -import org.assertj.neo4j.api.beta.type.ValueType; - -/** - * @author patouche - 29/01/2021 - */ -public class ShouldHavePropertyWithType> extends BasicErrorMessageFactory { - - public ShouldHavePropertyWithType(final ENTITY entity, final ValueType expectedType) { - super("", entity, expectedType); - } - - public static > ShouldHavePropertyWithType create( - final E entity, final ValueType expectedType) { - return new ShouldHavePropertyWithType<>(entity, expectedType); - } -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecord.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecord.java index fea057f..0856746 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecord.java +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecord.java @@ -16,7 +16,7 @@ import org.neo4j.driver.Query; /** - * @author patouche - 02/11/2020 + * @author Patrick Allain - 02/11/2020 */ @Deprecated public class ShouldHaveRecord extends BasicErrorMessageFactory { diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecordNumber.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecordNumber.java index a30d28c..3fd2a10 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecordNumber.java +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecordNumber.java @@ -16,7 +16,7 @@ import org.neo4j.driver.Query; /** - * @author patouche - 02/11/2020 + * @author Patrick Allain - 02/11/2020 */ @Deprecated public class ShouldHaveRecordNumber extends BasicErrorMessageFactory { diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecordType.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecordType.java index 7f03e42..01eed92 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecordType.java +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldHaveRecordType.java @@ -19,7 +19,7 @@ import java.util.List; /** - * @author patouche - 02/11/2020 + * @author Patrick Allain - 02/11/2020 */ @Deprecated public class ShouldHaveRecordType extends BasicErrorMessageFactory { diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldNodeHaveNoRelatedRelationships.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldNodeHaveNoRelatedRelationships.java new file mode 100644 index 0000000..5f510d7 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldNodeHaveNoRelatedRelationships.java @@ -0,0 +1,87 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; +import org.assertj.neo4j.api.beta.util.EntityUtils; +import org.assertj.neo4j.api.beta.util.Presentations; +import org.assertj.neo4j.api.beta.util.Utils; + +import java.util.List; +import java.util.function.Function; + +/** + * @author patouche - 13/02/2021 + */ +public class ShouldNodeHaveNoRelatedRelationships + extends BasicEntityErrorMessageFactory { + + protected ShouldNodeHaveNoRelatedRelationships( + final String direction, + final DbNode actual, + final List relationships) { + super( + "%nExpecting node:%n" + + " <%s>%n" + + "to have no " + direction + " relationships but found:%n" + + " <%s>", + actual, + ArgDetail.included(Utils.title(direction) + " relationships:", EntityUtils.sorted(relationships))); + } + + public static ShouldNodeHaveNoRelatedRelationships createIncoming(final DbNode actual, + final List relationships) { + return new ShouldNodeHaveNoRelatedRelationships("incoming", actual, relationships); + } + + public static ShouldNodeHaveNoRelatedRelationships createOutgoing(final DbNode actual, + final List relationships) { + return new ShouldNodeHaveNoRelatedRelationships("outgoing", actual, relationships); + } + + private static GroupingEntityErrorFactory elements( + final List actual, + final String direction, + final Function> mapper, + final List relationships) { + return new BasicGroupingEntityErrorFactory<>( + actual, + mapper, + "%nExpecting nodes:%n" + + " <%1$s>%n" + + "to have no " + direction + " relationships but found:%n" + + " <%4$s>%n" + + "which are " + direction + " relationships to nodes:", + Presentations.outputIds(relationships) + ); + } + + public static GroupingEntityErrorFactory incomingElements( + final List actual, final List relationships) { + return elements( + actual, "incoming", + (e) -> createIncoming(e, EntityUtils.areIncomingForNode(e, relationships)), + relationships + ); + } + + public static GroupingEntityErrorFactory outgoingElements( + final List actual, final List relationships) { + return elements( + actual, "outgoing", + (e) -> createOutgoing(e, EntityUtils.areOutgoingForNode(e, relationships)), + relationships + ); + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldPropertyMatch.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldPropertyMatch.java new file mode 100644 index 0000000..fa0f593 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldPropertyMatch.java @@ -0,0 +1,56 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.neo4j.api.beta.type.DbEntity; + +import java.util.List; + +/** + * @author Patrick Allain - 10/02/2021 + */ +public class ShouldPropertyMatch> + extends BasicEntityErrorMessageFactory { + + protected ShouldPropertyMatch(final ENTITY actual, final String key) { + super( + "%nExpecting %s to have property:%n" + + " <%s>%n" + + "matching the provided condition for its value:%n" + + " <%s>%n" + + "but this value of type %s did not", + actual, + ArgDetail.excluded(key), + ArgDetail.included("Actual property value", actual.getPropertyValue(key)), + ArgDetail.included("Actual property type", actual.getPropertyType(key)) + ); + } + + public static > ShouldPropertyMatch create(final E actual, final String key) { + return new ShouldPropertyMatch<>(actual, key); + } + + public static > GroupingEntityErrorFactory elements(final List actual, + final String key) { + return new BasicGroupingEntityErrorFactory<>( + actual, + (e) -> create(e, key), + "%nExpecting %3$s:%n" + + " <%1$s>%n" + + "to have a for the property %4$s matching the condition but %3$s:%n" + + " <%2$s>%n" + + "did not:", + key + ); + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldRelationshipHaveType.java b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldRelationshipHaveType.java new file mode 100644 index 0000000..57410ec --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/error/ShouldRelationshipHaveType.java @@ -0,0 +1,62 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.BasicErrorMessageFactory; +import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; + +import java.util.List; + +/** + * @author Patrick Allain - 25/11/2020 + */ +public class ShouldRelationshipHaveType extends BasicEntityErrorMessageFactory { + + /** + * Creates a new {@link BasicErrorMessageFactory}. + * + * @param actual the relationship + * @param expectedType the expected type + */ + public ShouldRelationshipHaveType(final DbRelationship actual, final String expectedType) { + super( + "%nExpecting relationship:%n" + + " <%s>%n" + + "to have type:%n" + + " <%s>%n" + + "but actual type is:%n" + + " <%s>", + actual, + ArgDetail.excluded(expectedType), + ArgDetail.included("Actual type", actual.getType()) + ); + } + + public static ShouldRelationshipHaveType create(final DbRelationship actual, final String expectedType) { + return new ShouldRelationshipHaveType(actual, expectedType); + } + + public static GroupingEntityErrorFactory elements( + final List actual, final String expectedType) { + return new BasicGroupingEntityErrorFactory<>( + actual, + (r) -> create(r, expectedType), + "%nExpecting relationships:%n" + + " <%1$s>%n" + + "to have type:%n" + + " <%4$s>%n" + + "but found other types for some relationships:", + expectedType + ); + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/AbstractDataLoader.java b/src/main/java/org/assertj/neo4j/api/beta/type/AbstractDataLoader.java index b7d8273..f44a3b1 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/type/AbstractDataLoader.java +++ b/src/main/java/org/assertj/neo4j/api/beta/type/AbstractDataLoader.java @@ -12,12 +12,22 @@ */ package org.assertj.neo4j.api.beta.type; +import org.assertj.core.util.Lists; import org.neo4j.driver.Driver; +import org.neo4j.driver.Query; +import org.neo4j.driver.Record; +import org.neo4j.driver.Session; +import org.neo4j.driver.TransactionConfig; +import org.neo4j.driver.Value; +import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; /** - * @author patouche - 09/11/2020 + * Abstract class for data loader. + * + * @author Patrick Allain - 09/11/2020 */ abstract class AbstractDataLoader implements DataLoader { @@ -27,18 +37,56 @@ abstract class AbstractDataLoader implements DataLoader { /** The type of record. */ protected final RecordType recordType; + /** The neo4j query. */ + protected final Query query; + /** * Class constructor. * - * @param driver the Neo4J database driver - * @param recordType the record type + * @param driver the Neo4J database driver + * @param recordType the record type */ - protected AbstractDataLoader(final Driver driver, final RecordType recordType) { + protected AbstractDataLoader(final Driver driver, final RecordType recordType, final Query query) { this.driver = driver; this.recordType = recordType; + this.query = query; + } + + /** + * Load {@link ENTITY} list from a list of {@link Record}. + * + * @param records the records to be transform + * @return a list of entities + */ + protected abstract List load(final List records); + + /** {@inheritDoc} */ + @Override + public List load() { + try (Session session = this.driver.session()) { + final List records = session.readTransaction( + (tx -> tx.run(query).list()), + TransactionConfig.builder().build() + ); + return load(records); + } + } + + /** {@inheritDoc} */ + @Override + public > D chain(final LoaderFactory factory) { + return factory.create(this.driver); + } + + /** {@inheritDoc} */ + @Override + public Query query() { + return query; } - public Driver getDriver() { - return this.driver; + /** {@inheritDoc} */ + @Override + public String toString() { + return "DataLoader:" + recordType + "{query=" + query + '}'; } } diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/DataLoader.java b/src/main/java/org/assertj/neo4j/api/beta/type/DataLoader.java index 52e1a54..8c190cf 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/type/DataLoader.java +++ b/src/main/java/org/assertj/neo4j/api/beta/type/DataLoader.java @@ -12,21 +12,23 @@ */ package org.assertj.neo4j.api.beta.type; -import org.neo4j.driver.Driver; +import org.neo4j.driver.Query; import java.util.List; /** - * @author patouche - 27/01/2021 + * Data loader. + * + * @author Patrick Allain - 27/01/2021 */ public interface DataLoader { /** - * Get the driver use to load the data. + * Get que the query use to load the entities * - * @return the neo4j driver. + * @return the query use to load the entities */ - Driver getDriver(); + Query query(); /** * Load a list of records. @@ -34,4 +36,17 @@ public interface DataLoader { * @return the list of records transform into a expected type */ List load(); + + /** + * Chain current assertion with the creation of an other {@link DataLoader}. + *

+ * A new query will be executed bellow which will load mode entities. + * + * @param factory the factory + * @param the entity type + * @param the data loader type + * @return the data loader + */ + > D chain(LoaderFactory factory); + } diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/DbEntity.java b/src/main/java/org/assertj/neo4j/api/beta/type/DbEntity.java index 6ff2520..65ee52a 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/type/DbEntity.java +++ b/src/main/java/org/assertj/neo4j/api/beta/type/DbEntity.java @@ -12,8 +12,6 @@ */ package org.assertj.neo4j.api.beta.type; -import org.assertj.neo4j.api.beta.util.Wip; - import java.util.List; import java.util.Map; import java.util.Objects; @@ -23,7 +21,7 @@ /** * Abstract class for any neo4j entity. * - * @author patouche - 09/11/2020 + * @author Patrick Allain - 09/11/2020 */ public abstract class DbEntity { @@ -64,7 +62,8 @@ public Object getPropertyValue(final String key) { } public List getPropertyList(final String key) { - final DbValue property = Objects.requireNonNull(properties.get(key), "Property key \"" + key + "\" doesn't exist"); + final DbValue property = Objects + .requireNonNull(properties.get(key), "Property key \"" + key + "\" doesn't exist"); final Object content = property.getContent(); if (property.getType() != ValueType.LIST || !(content instanceof List)) { throw new IllegalArgumentException("Property key \"" + key + "\" is not a list composite type"); @@ -72,10 +71,20 @@ public List getPropertyList(final String key) { return (List) content; } + public List getPropertyListValues(final String key) { + return getPropertyList(key).stream().map(DbValue::getContent).collect(Collectors.toList()); + } + public ValueType getPropertyType(final String key) { return Optional.ofNullable(properties.get(key)).map(DbValue::getType).orElse(null); } + /** + * Should not be use anymore ! + * + * @return + */ + @Deprecated public abstract T withoutId(); /** @@ -83,7 +92,7 @@ public ValueType getPropertyType(final String key) { */ protected String entityRepresentation(final String prefix) { if (id == null) { - return recordType + "{" + prefix + ", properties=" + properties + '}'; + return recordType + "{" + prefix + ", properties=" + properties + '}'; } return recordType + "{id=" + id + ", " + prefix + ", properties=" + properties + '}'; } diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/DbValue.java b/src/main/java/org/assertj/neo4j/api/beta/type/DbValue.java index 17cc2e7..f7ee7e5 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/type/DbValue.java +++ b/src/main/java/org/assertj/neo4j/api/beta/type/DbValue.java @@ -15,9 +15,9 @@ import java.util.Objects; /** - * DB Value wrap an object within its type. + * Wrap an object within its type. * - * @author patouche - 23/12/2020 + * @author Patrick Allain - 23/12/2020 */ public class DbValue { diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/Drivers.java b/src/main/java/org/assertj/neo4j/api/beta/type/Drivers.java index f503c13..e9a58df 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/type/Drivers.java +++ b/src/main/java/org/assertj/neo4j/api/beta/type/Drivers.java @@ -12,12 +12,10 @@ */ package org.assertj.neo4j.api.beta.type; -import org.neo4j.driver.TransactionWork; - /** * Create builder for generating object to compare * - * @author patouche - 27/11/2020 + * @author Patrick Allain - 27/11/2020 */ public final class Drivers { @@ -41,8 +39,8 @@ public static Relationships.DbRelationshipBuilder relation() { } /** - * Create a new {@link Relationships.DbRelationshipBuilder} with a specified type to compare with the - * relationships you have in the database. + * Create a new {@link Relationships.DbRelationshipBuilder} with a specified type to compare with the relationships + * you have in the database. * * @param type the relationships type * @return a new {@link Relationships.DbRelationshipBuilder} instance @@ -51,5 +49,4 @@ public static Relationships.DbRelationshipBuilder relation(final String type) { return relation().type(type); } - } diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/LoaderFactory.java b/src/main/java/org/assertj/neo4j/api/beta/type/LoaderFactory.java new file mode 100644 index 0000000..94730f3 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/type/LoaderFactory.java @@ -0,0 +1,44 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.type; + +import org.neo4j.driver.Driver; + +/** + * Factory for creating new instance of {@link DataLoader}. + *

+ * This interface prevent to expose internal constructor of {@link DataLoader} implementation. + * + * @author Patrick Allain - 10/02/2021 + */ +public interface LoaderFactory> { + + /** + * Create a new {@link DataLoader} from a neo4j {@link Driver}. + * + * @param driver the neo4j driver + * @return a new instance of {@link LOADER} + */ + LOADER create(Driver driver); + + /** + * Create a new {@link LoaderFactory} for {@link Relationships.DbRelationship}. + * + * @param types the type of relationships + * @return a new loader factory instance. + */ + static LoaderFactory relationships(String... types) { + return new LoaderFactoryGeneric<>(Queries.relationships(types), RelationshipLoader::new); + } + +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/LoaderFactoryGeneric.java b/src/main/java/org/assertj/neo4j/api/beta/type/LoaderFactoryGeneric.java new file mode 100644 index 0000000..7657a7d --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/type/LoaderFactoryGeneric.java @@ -0,0 +1,46 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.type; + +import org.neo4j.driver.Driver; +import org.neo4j.driver.Query; + +import java.util.function.BiFunction; + +/** + * Generic {@link LoaderFactory} that wrap a query to be executed on the provided driver. + * + * @author patouche - 12/02/2021 + */ +class LoaderFactoryGeneric> implements LoaderFactory { + + private final Query query; + private final BiFunction function; + + LoaderFactoryGeneric(final Query query, final BiFunction function) { + this.query = query; + this.function = function; + } + + /** {@inheritDoc} */ + @Override + public LOADER create(final Driver driver) { + return function.apply(driver, query); + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return "LoaderFactory{query=" + query + '}'; + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/NodeLoader.java b/src/main/java/org/assertj/neo4j/api/beta/type/NodeLoader.java new file mode 100644 index 0000000..d1c5dc4 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/type/NodeLoader.java @@ -0,0 +1,68 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.type; + +import org.assertj.core.util.Lists; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Query; +import org.neo4j.driver.Record; +import org.neo4j.driver.Session; +import org.neo4j.driver.TransactionConfig; +import org.neo4j.driver.Value; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Data loader for {@link DbNode}. + * + * @author Patrick Allain - 31/10/2020 + */ +class NodeLoader extends AbstractDataLoader implements Nodes { + + /** + * Class constructor for {@link NodeLoader}. + *

+ * This will allow you to write easy assertions on your database nodes. + * + * @param driver the neo4j driver + * @param labels the nodes labels to watch + */ + public NodeLoader(final Driver driver, final String... labels) { + this(driver, Queries.nodes(labels)); + } + + NodeLoader(final Driver driver, final Query query) { + super(driver, RecordType.NODE, query); + } + + /** {@inheritDoc} */ + @Override + protected List load(final List records) { + return records.stream() + .map(Record::values) + .flatMap(Collection::stream) + .map(Value::asNode) + .map(n -> new DbNode(n.id(), Lists.newArrayList(n.labels()), ValueType.convertMap(n.asMap()))) + .collect(Collectors.toList()); + } + +} + diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/Nodes.java b/src/main/java/org/assertj/neo4j/api/beta/type/Nodes.java index 08adc72..4620e6e 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/type/Nodes.java +++ b/src/main/java/org/assertj/neo4j/api/beta/type/Nodes.java @@ -12,17 +12,10 @@ */ package org.assertj.neo4j.api.beta.type; -import org.assertj.core.util.Lists; import org.neo4j.driver.Driver; -import org.neo4j.driver.Record; -import org.neo4j.driver.Result; -import org.neo4j.driver.Session; -import org.neo4j.driver.TransactionConfig; -import org.neo4j.driver.Value; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -30,48 +23,21 @@ import java.util.stream.Collectors; /** - * @author patouche - 31/10/2020 + * {@link Nodes.DbNode} entities loader definition. + * + * @author Patrick Allain - 31/10/2020 */ -public class Nodes extends AbstractDataLoader { - - /** The node labels. */ - private final List labels; - - /** - * Class constructor for {@link Nodes}. - *

- * This will allow you to write easy assertions on your database nodes. - * - * @param driver the neo4j driver - * @param labels the nodes labels to watch - */ - public Nodes(final Driver driver, final String... labels) { - super(driver, RecordType.NODE); - this.labels = Arrays.asList(labels); - } +public interface Nodes extends DataLoader { - /** {@inheritDoc} */ - @Override - public List load() { - try (Session session = this.driver.session()) { - final String queryLabels = labels.stream().map(i -> ":" + i).collect(Collectors.joining("")); - final String query = String.format("MATCH (n %s) RETURN n", queryLabels); - final Result result = session.run(query, TransactionConfig.builder().build()); - final List records = result.list(); - return records.stream() - .map(Record::values) - .flatMap(Collection::stream) - .map(Value::asNode) - .map(n -> new DbNode(n.id(), Lists.newArrayList(n.labels()), ValueType.convertMap(n.asMap()))) - .collect(Collectors.toList()); - } + static Nodes of(Driver driver, String... labels) { + return new NodeLoader(driver, labels); } /** - * TODO : Maybe extract method here in a interface to be able to decorate a Node from driver - * - This may have impact for comparing node. + * TODO : Maybe extract method here in a interface to be able to decorate a Node from driver - This may have impact + * for comparing node. */ - public static class DbNode extends DbEntity { + class DbNode extends DbEntity { protected List labels; @@ -121,7 +87,10 @@ public int hashCode() { } } - public static class DbNodeBuilder { + /** + * Builder for {@link DbNode}. + */ + class DbNodeBuilder { private Long id = null; @@ -151,6 +120,11 @@ public DbNodeBuilder label(final String label) { return this; } + public DbNodeBuilder labels(final String... labels) { + Arrays.stream(labels).forEach(this::label); + return this; + } + public DbNode build() { return new DbNode(id, labels, properties); } diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/Queries.java b/src/main/java/org/assertj/neo4j/api/beta/type/Queries.java new file mode 100644 index 0000000..89ccd13 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/type/Queries.java @@ -0,0 +1,37 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.type; + +import org.neo4j.driver.Query; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author Patrick Allain - 10/02/2021 + */ +public interface Queries { + + static Query relationships(final String... types) { + final String joined = Arrays.stream(types).filter(Objects::nonNull).sorted().collect(Collectors.joining("|")); + final String orTypes = joined.isEmpty() ? "" : " :" + joined; + return new Query(String.format("MATCH ()-[r%s]->() RETURN r", orTypes)); + } + + static Query nodes(final String... labels) { + final String queryLabels = Arrays.stream(labels).map(i -> ":" + i).collect(Collectors.joining("")); + return new Query(String.format("MATCH (n %s) RETURN n", queryLabels)); + } + +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/RecordType.java b/src/main/java/org/assertj/neo4j/api/beta/type/RecordType.java index 36d9cf4..421f663 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/type/RecordType.java +++ b/src/main/java/org/assertj/neo4j/api/beta/type/RecordType.java @@ -22,7 +22,7 @@ import java.util.stream.Collectors; /** - * @author patouche - 02/11/2020 + * @author Patrick Allain - 02/11/2020 */ public enum RecordType { diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/RelationshipLoader.java b/src/main/java/org/assertj/neo4j/api/beta/type/RelationshipLoader.java new file mode 100644 index 0000000..ec5f2d2 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/type/RelationshipLoader.java @@ -0,0 +1,60 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.type; + +import org.neo4j.driver.Driver; +import org.neo4j.driver.Query; +import org.neo4j.driver.Record; +import org.neo4j.driver.Session; +import org.neo4j.driver.TransactionConfig; +import org.neo4j.driver.Value; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Concrete implementation for loading {@link Relationships.DbRelationship} entities. + * + * @author Patrick Allain - 31/10/2020 + */ +class RelationshipLoader extends AbstractDataLoader implements Relationships { + + /** + * Create a new relationships for assertions. + * + * @param driver the neo4j driver + * @param type the relationships type. + */ + public RelationshipLoader(final Driver driver, final String type) { + this(driver, Queries.relationships(type)); + } + + RelationshipLoader(final Driver driver, final Query query) { + super(driver, RecordType.RELATIONSHIP, query); + } + + /** {@inheritDoc} */ + @Override + public List load(final List records) { + return records.stream() + .map(Record::values) + .flatMap(Collection::stream) + .map(Value::asRelationship) + .map(r -> new DbRelationship(r.id(), r.type(), r.startNodeId(), r.endNodeId(), + ValueType.convertMap(r.asMap()))) + .collect(Collectors.toList()); + + } + +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/Relationships.java b/src/main/java/org/assertj/neo4j/api/beta/type/Relationships.java index 1dbc601..582b374 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/type/Relationships.java +++ b/src/main/java/org/assertj/neo4j/api/beta/type/Relationships.java @@ -13,76 +13,40 @@ package org.assertj.neo4j.api.beta.type; import org.neo4j.driver.Driver; -import org.neo4j.driver.Record; -import org.neo4j.driver.Result; -import org.neo4j.driver.Session; -import org.neo4j.driver.TransactionConfig; -import org.neo4j.driver.Value; -import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** - * @author patouche - 31/10/2020 + * {@link Relationships.DbRelationship} entities loader definition. + * + * @author Patrick Allain - 31/10/2020 */ -public class Relationships extends AbstractDataLoader { - - /** The relationship type. */ - private final String type; +public interface Relationships extends DataLoader { - /** - * Create a new relationships for assertions. - * - * @param driver the neo4j driver - * @param type the relationships type. - */ - public Relationships(final Driver driver, final String type) { - super(driver, RecordType.RELATIONSHIP); - this.type = type; - } - - /** {@inheritDoc} */ - @Override - public List load() { - try (Session session = this.driver.session()) { - final String query = String.format("MATCH ()-[r:%s]->() RETURN r", type); - final Result result = session.run(query, TransactionConfig.builder().build()); - final List records = result.list(); - return records.stream() - .map(Record::values) - .flatMap(Collection::stream) - .map(Value::asRelationship) - .map(r -> new Relationships.DbRelationship(r.id(), r.type(), ValueType.convertMap(r.asMap()))) - .collect(Collectors.toList()); - } + static Relationships of(final Driver driver, final String type) { + return new RelationshipLoader(driver, type); } /** - * Create a new {@link DbRelationshipBuilder}. - * - * @return a new {@link DbRelationshipBuilder} with the same {@link #type} of the current relationships. + * TODO : Maybe extract method here in a interface to be able to decorate a Relationship from driver - This may have + * impact for comparing relationship. */ - public DbRelationshipBuilder create() { - return new DbRelationshipBuilder().type(type); - } - - /** - * TODO : Maybe extract method here in a interface to be able to decorate a Relationship from driver - * - This may have impact for comparing relationship. - */ - public static class DbRelationship extends DbEntity { + class DbRelationship extends DbEntity { + private final Long start; + private final Long end; private final String type; DbRelationship(final String type, final Map properties) { - this(null, type, properties); + this(null, type, null, null, properties); } - DbRelationship(final Long id, final String type, final Map properties) { + DbRelationship(final Long id, final String type, final Long start, final Long end, + final Map properties) { super(RecordType.RELATIONSHIP, id, properties); + this.start = start; + this.end = end; this.type = type; } @@ -90,23 +54,32 @@ public String getType() { return type; } + public Long getStart() { + return start; + } + + public Long getEnd() { + return end; + } + @Override public String toString() { - return entityRepresentation("type='" + type + "'"); + return entityRepresentation("type='" + type + "', start=" + start + ", end=" + end); } @Override public DbRelationship withoutId() { - return new DbRelationship(this.type, this.properties); + return new DbRelationship(null, this.type, this.start, this.end, this.properties); } } - public static class DbRelationshipBuilder { + class DbRelationshipBuilder { private Long id; - private String type; + private Long start; + private Long end; private final Map properties = new HashMap<>(); @@ -132,8 +105,26 @@ public DbRelationshipBuilder type(final String type) { return this; } + public DbRelationshipBuilder start(final int start) { + return start((long) start); + } + + public DbRelationshipBuilder start(final Long start) { + this.start = start; + return this; + } + + public DbRelationshipBuilder end(final int end) { + return end((long) end); + } + + public DbRelationshipBuilder end(final Long end) { + this.end = end; + return this; + } + public DbRelationship build() { - return new DbRelationship(id, type, properties); + return new DbRelationship(id, type, start, end, properties); } } diff --git a/src/main/java/org/assertj/neo4j/api/beta/type/ValueType.java b/src/main/java/org/assertj/neo4j/api/beta/type/ValueType.java index bf54024..14965f5 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/type/ValueType.java +++ b/src/main/java/org/assertj/neo4j/api/beta/type/ValueType.java @@ -44,7 +44,7 @@ * * * - * @author patouche - 27/11/2020 + * @author Patrick Allain - 27/11/2020 */ public enum ValueType { @@ -62,7 +62,8 @@ public enum ValueType { DATE(LocalDate.class, Function.identity()), - DATE_TIME(ZonedDateTime.class, Function.identity(), new Converter<>(OffsetDateTime.class, OffsetDateTime::toZonedDateTime)), + DATE_TIME(ZonedDateTime.class, Function.identity(), new Converter<>(OffsetDateTime.class, + OffsetDateTime::toZonedDateTime)), LOCAL_DATE_TIME(LocalDateTime.class, Function.identity()), @@ -86,17 +87,20 @@ public enum ValueType { /** * Enum constructor. * - * @param targetClass - * @param converters - * @param + * @param targetClass the target class + * @param objectFactory the object factory to create + * @param converters the converter that will convert from the provided input type into the target type. + * @param the target class type */ + @SafeVarargs ValueType(final Class targetClass, final Function objectFactory, final Converter... converters) { this.targetClass = targetClass; this.objectFactory = (Function) objectFactory; this.converters = converters(targetClass, converters); } - private static List> converters(final Class targetClass, Converter[] converters) { + private static List> converters(final Class targetClass, + final Converter[] converters) { return concat( Stream.of(new Converter<>(targetClass, Function.identity())), Arrays.stream(converters) @@ -146,18 +150,24 @@ static Map convertMap(final Map properties) { return result; } + /** + * Converter. + * + * @param the input type + * @param the output type + */ static class Converter { private final Class fromClass; private final Function function; - public Converter(final Class fromClass, final Function function) { + Converter(final Class fromClass, final Function function) { this.fromClass = fromClass; this.function = function; } @SuppressWarnings("unchecked") - public O convert(final Object input) { + O convert(final Object input) { if (!fromClass.isInstance(input)) { throw new UnsupportedOperationException("Cannot convert object " + input + " as it isn't a instance " + "of " + fromClass); diff --git a/src/main/java/org/assertj/neo4j/api/beta/util/Checks.java b/src/main/java/org/assertj/neo4j/api/beta/util/Checks.java index f8ff46c..4058ccb 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/util/Checks.java +++ b/src/main/java/org/assertj/neo4j/api/beta/util/Checks.java @@ -1,27 +1,91 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ package org.assertj.neo4j.api.beta.util; import org.assertj.core.util.Arrays; import org.assertj.core.util.IterableUtil; import org.assertj.core.util.Lists; +import org.assertj.core.util.Streams; import java.util.List; +import java.util.Objects; /** - * @author patouche - 28/01/2021 + * Extend the {@link org.assertj.core.util.Preconditions} which is a final class. + * + * @author Patrick Allain - 28/01/2021 */ public final class Checks { - public static List notNullOrEmpty(final T[] items, final String message) { - if (Arrays.isNullOrEmpty(items)) { + /** + * Check that an array is not null or empty. + * + * @param array the array to check + * @param message the exception message + * @param the type of elements + * @return a list containing all elements + */ + public static List notNullOrEmpty(final T[] array, final String message) { + if (Arrays.isNullOrEmpty(array)) { throw new IllegalArgumentException(message); } - return java.util.Arrays.asList(items); + return java.util.Arrays.asList(array); } - public static List notNullOrEmpty(final Iterable items, final String message) { - if (IterableUtil.isNullOrEmpty(items)) { + /** + * Check that an iterable is not null or empty. + * + * @param iterable the iterable to check + * @param message the exception message + * @param the type of elements + * @return a list containing all elements + */ + public static List notNullOrEmpty(final Iterable iterable, final String message) { + if (IterableUtil.isNullOrEmpty(iterable)) { throw new IllegalArgumentException(message); } - return Lists.newArrayList(items); + return Utils.listOf(iterable); + } + + /** + * Check that an array is not null or empty and check that it doesn't contains any null elements. + * + * @param array the array to check + * @param message the exception message + * @param the type of elements + * @return a list of all elements + */ + public static List nonNullElementsIn(final T[] array, final String message) { + return nonNullElementsIn(notNullOrEmpty(array, message), message); + } + + /** + * Check that an array is not null or empty and check that it doesn't contains any null elements. + * + * @param iterable the iterable to check + * @param message the exception message + * @param the type of elements + * @return a list of all elements + */ + public static List nonNullElementsIn(final Iterable iterable, final String message) { + final List list = notNullOrEmpty(iterable, message); + if (list.stream().anyMatch(Objects::isNull)) { + throw new IllegalArgumentException(message); + } + return list; + } + + public static T first(final Iterable items, final String message) { + return Streams.stream(items).findFirst().orElseThrow(() -> new IllegalArgumentException(message)); } } diff --git a/src/main/java/org/assertj/neo4j/api/beta/util/EntityUtils.java b/src/main/java/org/assertj/neo4j/api/beta/util/EntityUtils.java new file mode 100644 index 0000000..a9f4be0 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/util/EntityUtils.java @@ -0,0 +1,90 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.util; + +import org.assertj.core.util.IterableUtil; +import org.assertj.neo4j.api.beta.type.DbEntity; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; + +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author patouche - 13/02/2021 + */ +public class EntityUtils { + + public static final Comparator> ENTITY_COMPARATOR = Comparator + .comparing(DbEntity::getId, Comparator.nullsFirst(Comparator.naturalOrder())); + + @SuppressWarnings("unchecked") + public static > Comparator comparator() { + return (Comparator) ENTITY_COMPARATOR; + } + + public static > List sorted(final Iterable entities) { + return IterableUtil.toCollection(entities).stream().sorted(comparator()).collect(Collectors.toList()); + } + + public static List areIncomingForNode(DbNode node, List relationships) { + return relationships.stream() + .filter(r -> Objects.equals(r.getEnd(), node.getId())) + .sorted(comparator()) + .collect(Collectors.toList()); + } + + public static List areOutgoingForNode(DbNode node, List relationships) { + return relationships.stream() + .filter(r -> Objects.equals(r.getStart(), node.getId())) + .sorted(comparator()) + .collect(Collectors.toList()); + } + + public static List havingIncomingRelationships(final List nodes, + final List relationships) { + final List endNodeIds = EntityUtils.endNodeIds(relationships); + return nodes.stream() + .filter(n -> endNodeIds.contains(n.getId())) + .sorted(comparator()) + .collect(Collectors.toList()); + } + + public static List havingOutgoingRelationships(final List nodes, + final List relationships) { + final List startNodeIds = EntityUtils.startNodeIds(relationships); + return nodes.stream() + .filter(n -> startNodeIds.contains(n.getId())) + .sorted(comparator()) + .collect(Collectors.toList()); + } + + public static List startNodeIds(List relationships) { + return relationships.stream() + .map(DbRelationship::getStart) + .sorted() + .collect(Collectors.toList()); + } + + public static List endNodeIds(List relationships) { + return relationships.stream() + .map(DbRelationship::getEnd) + .sorted() + .collect(Collectors.toList()); + } + + private EntityUtils() { + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/util/NodeLabels.java b/src/main/java/org/assertj/neo4j/api/beta/util/NodeLabels.java deleted file mode 100644 index 833f4d7..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/util/NodeLabels.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.util; - -import org.assertj.core.util.Lists; -import org.assertj.core.util.Streams; -import org.assertj.neo4j.api.beta.error.Missing; -import org.assertj.neo4j.api.beta.type.Nodes; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * @author patouche - 14/11/2020 - */ -public final class NodeLabels { - - public static boolean hasLabels(final Nodes.DbNode node, final Iterable expectedLabels) { - return !node.getLabels().containsAll(Lists.newArrayList(expectedLabels)); - } - - /** - * Test if one of the provided nodes don't have onf of the expected labels. - * - * @param nodes the list of nodes - * @param expectedLabels the expected labels - * @return {@code true} if one of the nodes don't have a expected labels. {@code false} otherwise. - */ - public static boolean haveLabels(final List nodes, final Iterable expectedLabels) { - return nodes.stream().anyMatch(e -> hasLabels(e, expectedLabels)); - } - - /** - * Create a new - * - * @param node - * @param labels - * @return - */ - public static Missing missing(final Nodes.DbNode node, final Iterable labels) { - final List missingLabels = Streams.stream(labels) - .filter(expectedLabel -> !node.getLabels().contains(expectedLabel)) - .collect(Collectors.toList()); - return new Missing<>(node, missingLabels); - } - - public static List> missing(final List nodes, - final List labels) { - return nodes.stream() - .map(node -> NodeLabels.missing(node, labels)) - .filter(Missing::hasMissing) - .collect(Collectors.toList()); - } - -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/util/NodeUtils.java b/src/main/java/org/assertj/neo4j/api/beta/util/NodeUtils.java new file mode 100644 index 0000000..b837f34 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/util/NodeUtils.java @@ -0,0 +1,30 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.util; + +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author patouche - 13/02/2021 + */ +public final class NodeUtils { + + + + private NodeUtils() { + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/util/Predicates.java b/src/main/java/org/assertj/neo4j/api/beta/util/Predicates.java index c70aa99..b5dbe99 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/util/Predicates.java +++ b/src/main/java/org/assertj/neo4j/api/beta/util/Predicates.java @@ -1,15 +1,30 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ package org.assertj.neo4j.api.beta.util; import org.assertj.core.util.Streams; import org.assertj.neo4j.api.beta.type.DbEntity; import org.assertj.neo4j.api.beta.type.DbValue; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.assertj.neo4j.api.beta.type.Relationships; +import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; import org.assertj.neo4j.api.beta.type.ValueType; import java.util.Objects; import java.util.function.Predicate; /** - * @author patouche - 30/01/2021 + * @author Patrick Allain - 30/01/2021 */ public interface Predicates { @@ -45,7 +60,7 @@ static > Predicate propertyKeysExists(final Iterable the entity type */ - static > Predicate propertySize(final int size) { + static > Predicate propertySize(final int size) { return (e) -> e.getProperties().size() == size; } @@ -68,4 +83,44 @@ static > Predicate propertyValue(final String key, fina return (e) -> Objects.equals(e.getPropertyValue(key), value); } + + static , T> Predicate propertyValueMatch( + final String key, final Predicate predicate) { + return (e) -> predicate.test((T) e.getPropertyValue(key)); + } + + /** + * Predicate to check if a {@link DbNode} has the a {@code label}. + *

+ * This predicate will return {@code true} if the label exist. {@code false} otherwise. + * + * @return the predicate to test a node + */ + static Predicate labelExists(final String label) { + return (node) -> node.getLabels().contains(label); + } + + /** + * Predicate to check if a {@link DbNode} have all the {@code labels}. + *

+ * This predicate will return {@code true} if all the labels exist. {@code false} otherwise. + * + * @return the predicate to test a node + */ + static Predicate labelsExists(final Iterable labels) { + return Streams.stream(labels) + .map(Predicates::labelExists) + .reduce(x -> true, Predicate::and); + } + + /** + * Predicate to check if a {@link DbRelationship} is of the expected {@code type}. + *

+ * This predicate will return {@code true} if the relationship is the one we expected. {@code false} otherwise. + * + * @return the predicate to test a relationship + */ + static Predicate isType(final String type) { + return (r) -> Objects.equals(r.getType(), type); + } } diff --git a/src/main/java/org/assertj/neo4j/api/beta/util/Presentations.java b/src/main/java/org/assertj/neo4j/api/beta/util/Presentations.java index 26c5ba5..0bbd384 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/util/Presentations.java +++ b/src/main/java/org/assertj/neo4j/api/beta/util/Presentations.java @@ -15,13 +15,11 @@ import org.assertj.core.util.Streams; import org.assertj.neo4j.api.beta.type.DbEntity; -import java.util.Comparator; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; /** - * @author patouche - 25/11/2020 + * @author Patrick Allain - 25/11/2020 */ public final class Presentations { @@ -45,7 +43,7 @@ public static > String outputId(final E entity) { */ public static > List outputIds(final Iterable entities) { return Streams.stream(entities) - .sorted(Comparator.comparing(i -> Optional.ofNullable(i.getId()).orElse(Long.MIN_VALUE))) + .sorted(EntityUtils.comparator()) .map(Presentations::outputId) .collect(Collectors.toList()); } diff --git a/src/main/java/org/assertj/neo4j/api/beta/util/RelationshipTypes.java b/src/main/java/org/assertj/neo4j/api/beta/util/RelationshipTypes.java deleted file mode 100644 index 89d281b..0000000 --- a/src/main/java/org/assertj/neo4j/api/beta/util/RelationshipTypes.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.util; - -import org.assertj.core.util.Preconditions; -import org.assertj.neo4j.api.beta.type.Relationships; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * @author patouche - 25/11/2020 - */ -public final class RelationshipTypes { - - private static String validName(final String type) { - Preconditions.checkNotNullOrEmpty(type, "Type should not be null or empty"); - return type; - } - - public static boolean is(final String type, Relationships.DbRelationship relationships) { - return validName(type).equals(relationships.getType()); - } - - public static boolean isNot(final String type, Relationships.DbRelationship relationships) { - return !is(type, relationships); - } - - public static boolean are(final String type, List relationships) { - validName(type); - return relationships.stream().allMatch(r -> RelationshipTypes.is(type, r)); - } - - public static List others( - final String type, final List relationships) { - return relationships.stream().filter(i -> RelationshipTypes.isNot(type, i)).collect(Collectors.toList()); - } -} diff --git a/src/main/java/org/assertj/neo4j/api/beta/util/Utils.java b/src/main/java/org/assertj/neo4j/api/beta/util/Utils.java new file mode 100644 index 0000000..abdac12 --- /dev/null +++ b/src/main/java/org/assertj/neo4j/api/beta/util/Utils.java @@ -0,0 +1,83 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.util; + +import org.assertj.core.util.IterableUtil; +import org.assertj.core.util.Lists; +import org.assertj.core.util.Streams; +import org.assertj.neo4j.api.beta.type.DbEntity; +import org.assertj.neo4j.api.beta.type.Nodes; +import org.assertj.neo4j.api.beta.type.Relationships; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Patrick Allain - 03/02/2021 + */ +public final class Utils { + + /** + * Transform a iterable into a list. + * + * @param iterable the iterable to transform + * @param the type of elements return by the iterator + * @return a list of elements. + */ + public static List listOf(final Iterable iterable) { + if (iterable instanceof List) { + return (List) iterable; + } + return Lists.newArrayList(iterable); + } + + /** + * Transform a array into a list. + * + * @param array the array to transform + * @param the type of elements return by the iterator + * @return a list of elements. + */ + public static List listOf(final T[] array) { + return Arrays.asList(array); + } + + /** + * Return a list of {items} that don't belong to the {@code searched} list. + * + * @param searched the searched list + * @param items the items + * @return a list of items + */ + public static List missing(final Iterable searched, final Iterable items) { + final Collection collectionItems = IterableUtil.toCollection(items); + return Streams.stream(searched) + .filter(s -> !collectionItems.contains(s)) + .sorted() + .collect(Collectors.toList()); + } + + public static List sorted(final Iterable items) { + return Streams.stream(items).sorted().collect(Collectors.toList()); + } + + public static String title(final String str) { + return str.substring(0, 1).toUpperCase() + str.substring(1); + } + + private Utils() { + } +} diff --git a/src/main/java/org/assertj/neo4j/api/beta/util/Wip.java b/src/main/java/org/assertj/neo4j/api/beta/util/Wip.java index 42848e7..513d351 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/util/Wip.java +++ b/src/main/java/org/assertj/neo4j/api/beta/util/Wip.java @@ -17,7 +17,7 @@ * * TODO : SHOULD BE DELETED ! * - * @author patouche - 14/11/2020 + * @author Patrick Allain - 14/11/2020 */ public class Wip { diff --git a/src/test/java/org/assertj/neo4j/api/beta/AbstractEntitiesAssertTests.java b/src/test/java/org/assertj/neo4j/api/beta/AbstractEntitiesAssertTests.java index 87a26ff..522f032 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/AbstractEntitiesAssertTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/AbstractEntitiesAssertTests.java @@ -12,7 +12,6 @@ */ package org.assertj.neo4j.api.beta; -import org.assertj.core.api.Assertions; import org.assertj.neo4j.api.beta.type.DataLoader; import org.assertj.neo4j.api.beta.type.DbEntity; import org.assertj.neo4j.api.beta.type.Drivers; @@ -20,24 +19,28 @@ import org.assertj.neo4j.api.beta.type.RecordType; import org.assertj.neo4j.api.beta.type.ValueType; import org.assertj.neo4j.api.beta.util.Predicates; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.neo4j.driver.Query; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** - * @author patouche - 12/11/2020 + * @author Patrick Allain - 12/11/2020 */ class AbstractEntitiesAssertTests { @@ -45,8 +48,8 @@ private static class ConcreteEntitiesAssert extends AbstractEntitiesAssert { - protected ConcreteEntitiesAssert(List entities) { - this(entities, null, false, null); + protected ConcreteEntitiesAssert(List entities, DataLoader loader) { + this(entities, loader, false, null); } protected ConcreteEntitiesAssert(List entities, DataLoader loader, @@ -71,15 +74,28 @@ public ConcreteEntitiesAssert toRootAssert() { private static class BaseTests { + protected final Nodes dataLoader; + protected ConcreteEntitiesAssert assertions; protected BaseTests(Nodes.DbNodeBuilder... builders) { + this.dataLoader = Mockito.mock(Nodes.class); + testCase(builders); + } + + protected void testCase(Nodes.DbNodeBuilder... builders) { this.assertions = new ConcreteEntitiesAssert( IntStream.range(0, builders.length) .mapToObj(idx -> builders[idx].id(idx + 1).build()) - .collect(Collectors.toList()) + .collect(Collectors.toList()), + dataLoader ); } + + @AfterEach + void tearDown() { + Mockito.verifyNoMoreInteractions(dataLoader); + } } @Nested @@ -154,6 +170,77 @@ void should_be_navigable() { } + @Nested + @DisplayName("filteredOnPropertyExists") + class FilteredOnPropertyValueTests extends BaseTests { + + FilteredOnPropertyValueTests() { + super( + Drivers.node(), + Drivers.node().property("prop", "other-val-1"), + Drivers.node().property("prop", "val"), + Drivers.node().property("prop", "other-val-2") + ); + } + + @Test + void should_filter_entities_having_the_property() { + // WHEN + ConcreteEntitiesAssert result = assertions.filteredOnPropertyValue("prop", "val"); + + // THEN + assertThat(result).isNotSameAs(assertions); + assertThat(result.getActual()) + .hasSize(1) + .extracting(DbEntity::getId) + .contains(3L); + } + + @Test + void should_be_navigable() { + // WHEN + ConcreteEntitiesAssert result = assertions.filteredOnPropertyExists("prop"); + + // THEN + assertThat(result.toParentAssert()).as("parent").isSameAs(assertions); + assertThat(result.toRootAssert()).as("root").isSameAs(assertions); + } + + } + + @Nested + @DisplayName("isEmpty") + class IsEmptyTests extends BaseTests { + + @Test + void should_failed() { + // GIVEN + testCase(Drivers.node().id(1)); + when(dataLoader.query()).thenReturn(new Query("MATCH (n) RETURN n")); + + // WHEN + final Throwable result = catchThrowable(() ->assertions.isEmpty()); + + // THEN + verify(dataLoader).query(); + assertThat(result) + .isInstanceOf(AssertionError.class) + .hasMessageContainingAll( + "Expecting query:", + "to return no nodes but got:" + ); + } + + @Test + void should_pass() { + // WHEN + final ConcreteEntitiesAssert result = assertions.isEmpty(); + + // THEN + assertThat(result).isSameAs(assertions); + } + } + @Nested @DisplayName("haveListPropertyOfType") class HaveListPropertyOfTypeTest extends BaseTests { @@ -162,11 +249,16 @@ class HaveListPropertyOfTypeTest extends BaseTests { super( Drivers.node() .property("prop", Arrays.asList(1, 2)) - .property("mixed", 1), - Drivers.node().property("prop", Arrays.asList(1, 2, 3)) - .property("mixed", "val"), - Drivers.node().property("prop", Arrays.asList(1, 2, 3, 4)) + .property("mixed", 1) + .property("mixed-list", Arrays.asList(1.1, 1.2)), + Drivers.node() + .property("prop", Arrays.asList(1, 2, 3)) + .property("mixed", "val") + .property("mixed-list", Arrays.asList(true, false, true)), + Drivers.node() + .property("prop", Arrays.asList(1, 2, 3, 4)) .property("mixed", Arrays.asList(1, 2)) + .property("mixed-list", Arrays.asList(1, 2, 3, 4)) .property("missing", Arrays.asList(1, 2)) ); } @@ -182,13 +274,14 @@ void should_fail_when_property_is_missing() { assertThat(throwable) .isInstanceOf(AssertionError.class) .hasMessageContainingAll( - "to have all the following property keys:", - "but some property keys were missing on:" + "Expecting nodes:", + "to have properties with keys:", + "but some nodes don't have this properties:" ); } @Test - void should_fail_when_property_is_not_all_list_value() { + void should_fail_when_property_are_not_all_list_value() { // WHEN final Throwable throwable = catchThrowable( () -> assertions.haveListPropertyOfType("mixed", ValueType.STRING) @@ -198,17 +291,33 @@ void should_fail_when_property_is_not_all_list_value() { assertThat(throwable) .isInstanceOf(AssertionError.class) .hasMessageContainingAll( - "to have property \"mixed\" with type:", - "but some nodes have for the property \"mixed\" another type:" + "Expecting nodes:", + "to have a property \"mixed\" with a value type:", + "but some nodes have a different property value type:" ); } @Test - void should_pass() { + void should_fail_when_property_are_not_all_of_expected_type() { // WHEN - final ConcreteEntitiesAssert result = assertions.haveListPropertyOfType("prop", ValueType.STRING); + final Throwable throwable = catchThrowable( + () -> assertions.haveListPropertyOfType("mixed-list", ValueType.STRING) + ); + + // THEN + assertThat(throwable) + .isInstanceOf(AssertionError.class) + .hasMessageContainingAll( + "Expecting nodes:", + "to have a composite property list named \"mixed-list\" containing only type:", + "but some nodes have a composite list containing others type:" + ); + } - // FIXME: BAD ERROR MESSAGE + @Test + void should_pass() { + // WHEN + final ConcreteEntitiesAssert result = assertions.haveListPropertyOfType("prop", ValueType.INTEGER); // THEN assertThat(result).isSameAs(assertions); @@ -224,13 +333,13 @@ class HavePropertyTests extends BaseTests { super( Drivers.node() .property("prop", "val") - .property("inc", "val-1"), + .property("prop-1", "val-1"), Drivers.node() .property("prop", "val") - .property("inc", "val-1"), + .property("prop-1", "val-1"), Drivers.node() .property("prop", "val") - .property("inc", "val-1") + .property("prop-1", "val-1") .property("missing", "val") ); } @@ -244,20 +353,25 @@ void should_fail_when_property_is_missing() { assertThat(throwable) .isInstanceOf(AssertionError.class) .hasMessageContainingAll( - "to have all the following property keys:", - "but some property keys were missing on:" + "Expecting nodes:", + "to have properties with keys:", + "but some nodes don't have this properties:" ); } @Test void should_fail_when_property_dont_have_the_expected_value() { // WHEN - final Throwable throwable = catchThrowable(() -> assertions.haveProperty("inc", "val-0")); + final Throwable throwable = catchThrowable(() -> assertions.haveProperty("prop-1", "val-0")); // THEN assertThat(throwable) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("The property keys to look for should not be null or empty"); + .isInstanceOf(AssertionError.class) + .hasMessageContainingAll( + "Expecting nodes:", + "to have a property named \"prop-1\" with value:", + "but some nodes have a different value for this property:" + ); } @Test @@ -291,7 +405,11 @@ void should_fail() { // THEN assertThat(throwable) .isInstanceOf(AssertionError.class) - .hasMessageContaining("TODO"); + .hasMessageContainingAll( + "Expecting nodes:", + "to have a property size:", + "but some nodes have another property size:" + ); } @Test @@ -338,8 +456,9 @@ void should_fail_when_property_is_missing() { assertThat(throwable) .isInstanceOf(AssertionError.class) .hasMessageContainingAll( - "to have all the following property keys:", - "but some property keys were missing on:" + "Expecting nodes:", + "to have properties with keys:", + "but some nodes don't have this properties:" ); } @@ -354,8 +473,9 @@ void should_fail_when_property_dont_have_the_right_type() { assertThat(throwable) .isInstanceOf(AssertionError.class) .hasMessageContainingAll( - "to have all the following property keys:", - "but some property keys were missing on:" + "Expecting nodes:", + "to have property value \"mixed\" instance of:", + "but some nodes have a property value which is not an instance of the expected class:" ); } @@ -397,7 +517,11 @@ void should_fail_when_nodes_have_missing_values() { // THEN assertThat(throwable) .isInstanceOf(AssertionError.class) - .hasMessageContainingAll("Expecting nodes:", "but some property keys were missing on:"); + .hasMessageContainingAll( + "Expecting nodes:", + "to have properties with keys:", + "but some nodes don't have this properties:" + ); } @Test @@ -412,27 +536,105 @@ void should_pass() { } @Nested - @DisplayName("havePropertyValueMatching") + @DisplayName("havePropertyValueMatching(String, Predicate)") class HavePropertyValueMatchingTests extends BaseTests { HavePropertyValueMatchingTests() { - super(Drivers.node().property("prop", "val-1"), Drivers.node().property("prop", "val-2"), - Drivers.node().property("prop", "val-3")); + super( + Drivers.node().property("prop", "val").property("prop-inc", "val-1"), + Drivers.node().property("prop", "val").property("prop-inc", "val-2"), + Drivers.node().property("prop", "val").property("prop-inc", "val-3").property("missing", true) + ); } @Test void should_fail_when_property_is_missing() { // WHEN final Throwable throwable = catchThrowable( - () -> assertions.havePropertyValueMatching("prop-mixed", (o) -> true) + () -> assertions.havePropertyValueMatching("missing", (o) -> true) + ); + + // THEN + assertThat(throwable) + .isInstanceOf(AssertionError.class) + .hasMessageContainingAll( + "Expecting nodes:", + "to have properties with keys:", + "but some nodes don't have this properties:" + ); + } + + @Test + void should_fail_when_not_matching() { + // WHEN + final Throwable throwable = catchThrowable( + () -> assertions.havePropertyValueMatching("prop-inc", (o) -> Objects.equals("val", o)) + ); + + // THEN + assertThat(throwable) + .isInstanceOf(AssertionError.class) + .hasMessageContainingAll( + "Expecting nodes:", + "to have a for the property \"prop-inc\" matching the condition but nodes:", + "did not:" + ); + } + + @Test + void should_pass() { + // WHEN + final ConcreteEntitiesAssert result = assertions + .havePropertyValueMatching("prop", (o) -> Objects.equals("val", o)); + + // THEN + assertThat(result).isSameAs(assertions); + } + } + + @Nested + @DisplayName("havePropertyValueMatching(String, Class, Predicate)") + class HavePropertyValueMatchingTypedTests extends BaseTests { + + HavePropertyValueMatchingTypedTests() { + super( + Drivers.node().property("prop", 1).property("prop-mixed", true), + Drivers.node().property("prop", 2).property("prop-mixed", 3.14), + Drivers.node().property("prop", 3).property("prop-mixed", "val").property("missing", true) + ); + } + + @Test + void should_fail_when_property_is_missing() { + // WHEN + final Throwable throwable = catchThrowable( + () -> assertions.havePropertyValueMatching("missing", Boolean.class, (o) -> true) + ); + + // THEN + assertThat(throwable) + .isInstanceOf(AssertionError.class) + .hasMessageContainingAll( + "Expecting nodes:", + "to have properties with keys:", + "but some nodes don't have this properties:" + ); + } + + @Test + void should_fail_when_property_value_dont_have_the_correct_type() { + // WHEN + final Throwable throwable = catchThrowable( + () -> assertions.havePropertyValueMatching("prop-mixed", Boolean.class, (o) -> true) ); // THEN assertThat(throwable) .isInstanceOf(AssertionError.class) .hasMessageContainingAll( - "toto", - "" + "Expecting nodes:", + "to have property value \"prop-mixed\" instance of:", + "but some nodes have a property value which is not an instance of the expected class:" ); } @@ -440,22 +642,24 @@ void should_fail_when_property_is_missing() { void should_fail_when_not_matching() { // WHEN final Throwable throwable = catchThrowable( - () -> assertions.havePropertyValueMatching("prop-mixed", (o) -> false) + () -> assertions.havePropertyValueMatching("prop", Long.class, (i) -> i < 0) ); // THEN assertThat(throwable) .isInstanceOf(AssertionError.class) .hasMessageContainingAll( - "toto", - "" + "Expecting nodes:", + "to have a for the property \"prop\" matching the condition but nodes:", + "did not:" ); } @Test void should_pass() { // WHEN - final ConcreteEntitiesAssert result = assertions.havePropertyValueMatching("key", (o) -> true); + final ConcreteEntitiesAssert result = assertions + .havePropertyValueMatching("prop", Long.class, (i) -> i < 10); // THEN assertThat(result).isSameAs(assertions); @@ -492,8 +696,9 @@ void should_fail_when_property_is_missing() { assertThat(throwable) .isInstanceOf(AssertionError.class) .hasMessageContainingAll( - "to have all the following property keys:", - "but some property keys were missing on:" + "Expecting nodes:", + "to have properties with keys:", + "but some nodes don't have this properties:" ); } @@ -508,8 +713,9 @@ void should_fail_when_property_dont_have_the_right_type() { assertThat(throwable) .isInstanceOf(AssertionError.class) .hasMessageContainingAll( - "to have property \"mixed\" with type:", - "but some nodes have for the property \"mixed\" another type:" + "Expecting nodes:", + "to have a property \"mixed\" with a value type:", + "but some nodes have a different property value type:" ); } diff --git a/src/test/java/org/assertj/neo4j/api/beta/AbstractNodesAssertTests.java b/src/test/java/org/assertj/neo4j/api/beta/AbstractNodesAssertTests.java new file mode 100644 index 0000000..6c4af8e --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/AbstractNodesAssertTests.java @@ -0,0 +1,371 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta; + +import org.assertj.neo4j.api.beta.testing.Loaders; +import org.assertj.neo4j.api.beta.type.DataLoader; +import org.assertj.neo4j.api.beta.type.DbEntity; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.LoaderFactory; +import org.assertj.neo4j.api.beta.type.Nodes; +import org.assertj.neo4j.api.beta.type.Relationships; +import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Query; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchThrowable; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +/** + * @author Patrick Allain - 10/02/2021 + */ +class AbstractNodesAssertTests { + + private static class BaseNodesTests { + + protected final Nodes dataLoader; + + private final List nodes; + + protected DriverNodesAssert assertions; + + protected final Driver driver = Mockito.mock(Driver.class); + + protected BaseNodesTests(final Nodes.DbNodeBuilder... builders) { + this.dataLoader = Mockito.mock(Nodes.class); + this.nodes = IntStream.range(0, builders.length) + .mapToObj(idx -> builders[idx].id(idx + 1).build()) + .collect(Collectors.toList()); + } + + @BeforeEach + void setUp() { + testCase(this.nodes); + } + + protected void testCase(final List nodes) { + when(this.dataLoader.load()).thenReturn(nodes); + this.assertions = new DriverNodesAssert(dataLoader); + } + + protected LoaderFactory> argQuery(final String query) { + return argThat(d -> Objects.equals(d.create(this.driver).query(), new Query(query))); + } + + @AfterEach + void tearDown() { + verifyNoMoreInteractions(this.dataLoader); + } + } + + @Nested + @DisplayName("haveLabels") + class HaveLabelsTests extends BaseNodesTests { + + HaveLabelsTests() { + super( + Drivers.node().labels("all", "missing"), + Drivers.node().labels("all", "missing"), + Drivers.node().labels("all", "OTHER-LABEL"), + Drivers.node().labels("all", "missing"), + Drivers.node().labels("all", "missing") + ); + } + + @Test + void should_fail_when_no_labels_provided() { + // WHEN + final Throwable throwable = catchThrowable(assertions::haveLabels); + + // THEN + verify(dataLoader).load(); + assertThat(throwable) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("The labels to look for should not be null or empty"); + } + + @Test + void should_fail_when_iterable_is_empty() { + // WHEN + final Throwable throwable = catchThrowable(() -> assertions.haveLabels(Collections.emptyList())); + + // THEN + verify(dataLoader).load(); + assertThat(throwable) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("The iterable of values to look for should not be empty"); + } + + @Test + void should_fail_when_single_value() { + // WHEN + final Throwable throwable = catchThrowable(() -> assertions.haveLabels("missing")); + + // THEN + verify(dataLoader).load(); + assertThat(throwable) + .isInstanceOf(AssertionError.class) + .hasMessageContainingAll( + "Expecting nodes:", + "to have the labels:", + "but some labels are missing for nodes:" + ); + } + + @Test + void should_pass_when_single_value() { + // WHEN + final DriverNodesAssert result = assertions.haveLabels("all"); + + // THEN + verify(dataLoader).load(); + assertThat(result).isSameAs(assertions); + } + + } + + @Nested + @DisplayName("ignoringIds") + class IgnoringIdsTests extends BaseNodesTests { + + public IgnoringIdsTests() { + super( + Drivers.node().id(22).labels("lbl", "lbl-1"), + Drivers.node().id(56).labels("lbl", "lbl-2") + ); + } + + @Test + void should_return_a_list_of_nodes_without_ids() { + // WHEN + final DriverNodesAssert result = assertions.ignoringIds(); + + // THEN + assertThat(result.getActual()) + .extracting(DbEntity::getId) + .doesNotContainNull(); + Assertions.assertDoesNotThrow(() -> result + .contains(Drivers.node().label("lbl-1").build()) + .contains(Drivers.node().id(35).label("lbl-2").build()) + ); + } + } + + @Nested + @DisplayName("incomingRelationships") + class IncomingRelationshipsTests extends BaseNodesTests { + + IncomingRelationshipsTests() { + super( + Drivers.node().id(1).labels("LBL_1"), + Drivers.node().id(2).labels("LBL_2"), + Drivers.node().id(3).labels("LBL_3") + ); + } + + @Test + void should_pass() { + // GIVEN + final DbRelationship relationship1 = Drivers.relation("DISCOVER").id(11).start(1).end(4).build(); + final DbRelationship relationship2 = Drivers.relation("KNOWS").id(12).start(5).end(1).build(); + final DbRelationship relationship3 = Drivers.relation("KNOWS").id(23).start(6).end(3).build(); + final Relationships relationships = Loaders.relationships(relationship1, relationship2, relationship3); + when(dataLoader.chain(any())).thenReturn(relationships); + + // WHEN + final ChildrenDriverRelationshipsAssert result = + assertions.incomingRelationships("KNOWS", "DISCOVER"); + + // THEN + verify(dataLoader).load(); + verify(dataLoader).chain(argQuery("MATCH ()-[r :DISCOVER|KNOWS]->() RETURN r")); + + assertThat(result.getActual()) + .hasSize(2) + .contains(relationship2, relationship3); + } + + } + + @Nested + @DisplayName("outgoingRelationships") + class OutgoingRelationshipsTests extends BaseNodesTests { + + public OutgoingRelationshipsTests() { + super( + Drivers.node().id(1).labels("LBL_1"), + Drivers.node().id(2).labels("LBL_2"), + Drivers.node().id(3).labels("LBL_3") + ); + } + + @Test + void should_pass() { + // GIVEN + final DbRelationship relationship1 = Drivers.relation("DISCOVER").id(11).start(4).end(1).build(); + final DbRelationship relationship2 = Drivers.relation("KNOWS").id(12).start(1).end(5).build(); + final DbRelationship relationship3 = Drivers.relation("KNOWS").id(23).start(3).end(6).build(); + final Relationships relationships = Loaders.relationships(relationship1, relationship2, relationship3); + when(dataLoader.chain(any())).thenReturn(relationships); + + // WHEN + final ChildrenDriverRelationshipsAssert result = + assertions.outgoingRelationships("KNOWS", "DISCOVER"); + + // THEN + verify(dataLoader).load(); + verify(dataLoader).chain(argQuery("MATCH ()-[r :DISCOVER|KNOWS]->() RETURN r")); + + assertThat(result.getActual()) + .hasSize(2) + .contains(relationship2, relationship3); + } + } + + @Nested + @DisplayName("haveNoIncomingRelationships") + class HaveNoIncomingRelationshipsTests extends BaseNodesTests { + + HaveNoIncomingRelationshipsTests() { + super( + Drivers.node().id(1).labels("LBL_1"), + Drivers.node().id(2).labels("LBL_2"), + Drivers.node().id(3).labels("LBL_3") + ); + } + + @Test + void should_fail() { + // GIVEN + final DbRelationship relationship1 = Drivers.relation("DISCOVER").id(11).start(1).end(4).build(); + final DbRelationship relationship2 = Drivers.relation("KNOWS").id(12).start(5).end(1).build(); + final DbRelationship relationship3 = Drivers.relation("KNOWS").id(13).start(6).end(3).build(); + final Relationships relationships = Loaders.relationships(relationship1, relationship2, relationship3); + when(dataLoader.chain(any())).thenReturn(relationships); + + // WHEN + final Throwable throwable = catchThrowable(() -> assertions.haveNoIncomingRelationships()); + + // THEN + verify(dataLoader).load(); + verify(dataLoader).chain(argQuery("MATCH ()-[r]->() RETURN r")); + + assertThat(throwable) + .isInstanceOf(AssertionError.class) + .hasMessageContainingAll( + "Expecting nodes:", + "to have no incoming relationships but found:", + "which are incoming relationships to nodes:" + ); + } + + @Test + void should_pass() { + // GIVEN + final DbRelationship relationship1 = Drivers.relation("DISCOVER").id(11).start(1).end(4).build(); + final DbRelationship relationship2 = Drivers.relation("KNOWS").id(12).start(2).end(5).build(); + final DbRelationship relationship3 = Drivers.relation("KNOWS").id(13).start(3).end(6).build(); + final Relationships relationships = Loaders.relationships(relationship1, relationship2, relationship3); + when(dataLoader.chain(any())).thenReturn(relationships); + + // WHEN + + final DriverNodesAssert result = assertions.haveNoIncomingRelationships("KNOWS", "DISCOVER"); + + // THEN + verify(dataLoader).load(); + verify(dataLoader).chain(argQuery("MATCH ()-[r :DISCOVER|KNOWS]->() RETURN r")); + + assertThat(result).isSameAs(assertions); + } + + } + + @Nested + @DisplayName("haveNoOutgoingRelationships") + class HaveNoOutgoingRelationshipsTests extends BaseNodesTests { + + HaveNoOutgoingRelationshipsTests() { + super( + Drivers.node().id(1).labels("LBL_1"), + Drivers.node().id(2).labels("LBL_2"), + Drivers.node().id(3).labels("LBL_3") + ); + } + + @Test + void should_fail() { + // GIVEN + final DbRelationship relationship1 = Drivers.relation("DISCOVER").id(11).start(1).end(4).build(); + final DbRelationship relationship2 = Drivers.relation("DISCOVER").id(12).start(2).end(5).build(); + final DbRelationship relationship3 = Drivers.relation("KNOWS").id(13).start(6).end(3).build(); + final Relationships relationships = Loaders.relationships(relationship1, relationship2, relationship3); + when(dataLoader.chain(any())).thenReturn(relationships); + + // WHEN + final Throwable throwable = catchThrowable(() -> assertions.haveNoOutgoingRelationships()); + + // THEN + verify(dataLoader).load(); + verify(dataLoader).chain(argQuery("MATCH ()-[r]->() RETURN r")); + + assertThat(throwable) + .isInstanceOf(AssertionError.class) + .hasMessageContainingAll( + "Expecting nodes:", + "to have no outgoing relationships but found:", + "which are outgoing relationships to nodes:" + ); + } + + @Test + void should_pass() { + // GIVEN + final DbRelationship relationship1 = Drivers.relation("DISCOVER").id(11).start(4).end(1).build(); + final DbRelationship relationship2 = Drivers.relation("KNOWS").id(12).start(5).end(2).build(); + final DbRelationship relationship3 = Drivers.relation("KNOWS").id(13).start(6).end(3).build(); + final Relationships relationships = Loaders.relationships(relationship1, relationship2, relationship3); + when(dataLoader.chain(any())).thenReturn(relationships); + + // WHEN + + final DriverNodesAssert result = assertions.haveNoOutgoingRelationships("KNOWS", "DISCOVER"); + + // THEN + verify(dataLoader).load(); + verify(dataLoader).chain(argQuery("MATCH ()-[r :DISCOVER|KNOWS]->() RETURN r")); + + assertThat(result).isSameAs(assertions); + } + + } +} + diff --git a/src/test/java/org/assertj/neo4j/api/beta/DriverNodesAssertTests.java b/src/test/java/org/assertj/neo4j/api/beta/DriverNodesAssertTests.java deleted file mode 100644 index 7a864d5..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/DriverNodesAssertTests.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta; - -import org.assertj.neo4j.api.beta.type.DbEntity; -import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Nodes; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; - -/** - * @author patouche - 12/11/2020 - */ -public class DriverNodesAssertTests { - - @Nested - @DisplayName("ignoringIds") - class IgnoringIdsTests { - - @Test - void should_return_a_list_of_nodes_without_ids() { - // GIVEN - final List nodes = Arrays.asList( - Drivers.node().id(22).label("lbl-1").build(), - Drivers.node().id(56).label("lbl-2").build() - ); - final DriverNodesAssert nodesAssert = new DriverNodesAssert(nodes); - - // WHEN - final DriverNodesAssert result = nodesAssert.ignoringIds(); - - // THEN - assertThat(result.getActual()) - .extracting(DbEntity::getId) - .containsOnlyNulls(); - } - } - - @Nested - @DisplayName("haveLabels") - class HaveLabelsTests { - - @Test - void should_fail_when_no_labels_provided() { - // GIVEN - final DriverNodesAssert nodesAssert = new DriverNodesAssert(Collections.emptyList()); - - // WHEN - final Throwable throwable = catchThrowable(nodesAssert::haveLabels); - - // THEN - assertThat(throwable) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("The labels to look for should not be null or empty"); - } - - @Test - void should_fail_when_iterable_is_empty() { - // GIVEN - final DriverNodesAssert nodesAssert = new DriverNodesAssert(Collections.emptyList()); - - // WHEN - final Throwable throwable = catchThrowable(() -> nodesAssert.haveLabels(Collections.emptyList())); - - // THEN - assertThat(throwable) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("The iterable of values to look for should not be empty"); - } - - @Test - void should_fail_when_single_value() { - // GIVEN - final List nodes = Arrays.asList( - Drivers.node().label("Test").build(), - Drivers.node().label("Test").build(), - Drivers.node().label("OTHER-LABEL").build(), - Drivers.node().label("Test").build(), - Drivers.node().label("Test").build() - ); - final DriverNodesAssert nodesAssert = new DriverNodesAssert(nodes ); - - // WHEN - final Throwable throwable = catchThrowable(() -> nodesAssert.haveLabels("Test")); - - // THEN - assertThat(throwable) - .isInstanceOf(AssertionError.class) - .hasMessageContainingAll("Expecting nodes:", "to have all the following labels:"); - } - - @Test - void should_pass_when_single_value() { - - // GIVEN - final List nodes = Arrays.asList( - Drivers.node().label("Test").build(), - Drivers.node().label("Test").build(), - Drivers.node().label("Test").build(), - Drivers.node().label("Test").build(), - Drivers.node().label("Test").build() - ); - final DriverNodesAssert nodesAssert = new DriverNodesAssert(nodes ); - - // WHEN - final DriverNodesAssert result = nodesAssert.haveLabels("Test"); - - // THEN - assertThat(result).isSameAs(nodesAssert); - } - } - - - - -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/DriverRelationshipsAssertTests.java b/src/test/java/org/assertj/neo4j/api/beta/DriverRelationshipsAssertTests.java index 2f97d07..399a715 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/DriverRelationshipsAssertTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/DriverRelationshipsAssertTests.java @@ -12,24 +12,78 @@ */ package org.assertj.neo4j.api.beta; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.type.DataLoader; import org.assertj.neo4j.api.beta.type.DbEntity; import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.LoaderFactory; +import org.assertj.neo4j.api.beta.type.Nodes; import org.assertj.neo4j.api.beta.type.Relationships; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Query; import java.util.Arrays; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; /** - * @author patouche - 24/11/2020 + * @author Patrick Allain - 24/11/2020 */ class DriverRelationshipsAssertTests { + private static class BaseRelationshipsTests { + + protected final Relationships dataLoader; + + private final List relationships; + + protected DriverRelationshipsAssert assertions; + + protected final Driver driver = Mockito.mock(Driver.class); + + protected BaseRelationshipsTests(final Relationships.DbRelationshipBuilder... builders) { + this.dataLoader = Mockito.mock(Relationships.class); + this.relationships = IntStream.range(0, builders.length) + .mapToObj(idx -> builders[idx].id(idx + 1).build()) + .collect(Collectors.toList()); + } + + @BeforeEach + void setUp() { + testCase(this.relationships); + } + + protected void testCase(final List nodes) { + when(this.dataLoader.load()).thenReturn(nodes); + this.assertions = new DriverRelationshipsAssert(dataLoader); + } + + protected LoaderFactory> argQuery(final String query) { + return argThat(d -> Objects.equals(d.create(this.driver).query(), new Query(query))); + } + + @AfterEach + void tearDown() { + verifyNoMoreInteractions(this.dataLoader); + } + } + @Nested @DisplayName("ignoringIds") class IgnoringIdsTests { @@ -38,8 +92,8 @@ class IgnoringIdsTests { void should_return_a_list_of_nodes_without_ids() { // GIVEN final List relationships = Arrays.asList( - Drivers.relation("KNOWS").id(22).build(), - Drivers.relation("KNOWS").id(56).build() + Drivers.relation("KNOWS_1").id(22).build(), + Drivers.relation("KNOWS_2").id(56).build() ); final DriverRelationshipsAssert relationshipsAssert = new DriverRelationshipsAssert(relationships); @@ -49,47 +103,52 @@ void should_return_a_list_of_nodes_without_ids() { // THEN assertThat(result.getActual()) .extracting(DbEntity::getId) - .containsOnlyNulls(); + .doesNotContainNull(); + Assertions.assertDoesNotThrow(() -> result + .contains(Drivers.relation("KNOWS_1").build()) + .contains(Drivers.relation("KNOWS_2").id(29).build()) + ); } } @Nested - @DisplayName("ignoringIds") - class HaveTypeTests { + @DisplayName("haveType") + class HaveTypeTests extends BaseRelationshipsTests { + + HaveTypeTests() { + super( + Drivers.relation("KNOWS").id(22), + Drivers.relation("KNOWS").id(29), + Drivers.relation("KNOWS").id(35), + Drivers.relation("KNOWS").id(56) + ); + } @Test void should_pass() { - // GIVEN - final List relationships = Arrays.asList( - Drivers.relation("KNOWS").id(22).build(), - Drivers.relation("KNOWS").id(56).build() - ); - final DriverRelationshipsAssert relationshipsAssert = new DriverRelationshipsAssert(relationships); - // WHEN - final DriverRelationshipsAssert result = relationshipsAssert.haveType("KNOWS"); + final DriverRelationshipsAssert result = assertions.haveType("KNOWS"); // THEN - assertThat(result).isSameAs(relationshipsAssert); + verify(dataLoader).load(); + assertThat(result).isSameAs(assertions); } @Test void should_fail() { - // GIVEN - final List relationships = Arrays.asList( - Drivers.relation("KNOWS").id(22).build(), - Drivers.relation("KNOWS").id(56).build() - ); - final DriverRelationshipsAssert relationshipsAssert = new DriverRelationshipsAssert(relationships); - // WHEN - final Throwable throwable = catchThrowable(() -> relationshipsAssert.haveType("OTHER_TYPE")); + final Throwable throwable = catchThrowable(() -> assertions.haveType("OTHER_TYPE")); // THEN + verify(dataLoader).load(); assertThat(throwable) .isInstanceOf(AssertionError.class) - .hasMessageContainingAll("Expecting relationships:", "but some relationships have an other type:"); + .hasMessageContainingAll( + "Expecting relationships:", + "to have type:", + "but found other types for some relationships:" + ); } } diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveLabelsTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveLabelsTests.java deleted file mode 100644 index 93e1724..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveLabelsTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.api.Assertions; -import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Nodes; -import org.assertj.neo4j.api.beta.util.NodeLabels; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.List; - -/** - * @author patouche - 14/11/2020 - */ -public class ElementsShouldHaveLabelsTests { - - @Test - void create_singleNode() { - // GIVEN - final List expectedLabels = Arrays.asList("LBL_1", "LBL_2", "LBL_3"); - final List nodes = Arrays.asList( - Drivers.node().id(1).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(2).label("LBL_1").label("LBL_3").build(), - Drivers.node().id(3).label("LBL_1").label("LBL_2").label("LBL_3").build() - ); - final List> havingMissingLabels = NodeLabels.missing(nodes, expectedLabels); - - // WHEN - final ElementsShouldHaveLabels error = ElementsShouldHaveLabels - .create(nodes, expectedLabels, havingMissingLabels); - - // THEN - Assertions.assertThat(error.create()).isEqualToNormalizingNewlines( - "\nExpecting nodes:\n" - + " [\"NODE{id=1}\", \"NODE{id=2}\", \"NODE{id=3}\"]\n" - + "to have all the following labels:\n" - + " [\"LBL_1\", \"LBL_2\", \"LBL_3\"]\n" - + "but some labels were missing on:\n" - + "\n" - + " - NODE{id=2} have missing labels: [LBL_2]\n" - + " Actual : [LBL_1, LBL_3]\n" - + " Expected: [LBL_1, LBL_2, LBL_3]" - ); - - } - - @Test - void create_multiple_nodes() { - // GIVEN - final List expectedLabels = Arrays.asList("LBL_1", "LBL_2", "LBL_3"); - final List nodes = Arrays.asList( - Drivers.node().id(2).label("LBL_3").label("LBL_2").build(), - Drivers.node().id(3).label("LBL_3").label("LBL_1").build(), - Drivers.node().id(4).label("LBL_2").label("LBL_1").build(), - Drivers.node().id(5).label("LBL_1").build() - ); - final List> havingMissingLabels = NodeLabels.missing(nodes, expectedLabels); - - // WHEN - final ElementsShouldHaveLabels error = ElementsShouldHaveLabels - .create(nodes, expectedLabels, havingMissingLabels); - - // THEN - Assertions.assertThat(error.create()).isEqualToNormalizingNewlines( - "\nExpecting nodes:\n" - + " [\"NODE{id=2}\", \"NODE{id=3}\", \"NODE{id=4}\", \"NODE{id=5}\"]\n" - + "to have all the following labels:\n" - + " [\"LBL_1\", \"LBL_2\", \"LBL_3\"]\n" - + "but some labels were missing on:\n" - + "\n" - + " - NODE{id=2} have missing labels: [LBL_1]\n" - + " Actual : [LBL_2, LBL_3]\n" - + " Expected: [LBL_1, LBL_2, LBL_3]\n" - + "\n" - + " - NODE{id=3} have missing labels: [LBL_2]\n" - + " Actual : [LBL_1, LBL_3]\n" - + " Expected: [LBL_1, LBL_2, LBL_3]\n" - + "\n" - + " - NODE{id=4} have missing labels: [LBL_3]\n" - + " Actual : [LBL_1, LBL_2]\n" - + " Expected: [LBL_1, LBL_2, LBL_3]\n" - + "\n" - + " - NODE{id=5} have missing labels: [LBL_2, LBL_3]\n" - + " Actual : [LBL_1]\n" - + " Expected: [LBL_1, LBL_2, LBL_3]" - ); - - } -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyInstanceOfTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyInstanceOfTests.java deleted file mode 100644 index 3331103..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyInstanceOfTests.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.api.Assertions; -import org.assertj.core.error.ErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Nodes; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.assertj.neo4j.api.beta.type.ValueType; -import org.junit.jupiter.api.Test; -import org.neo4j.driver.Values; - -import java.time.LocalDateTime; -import java.time.ZonedDateTime; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * @author patouche - 31/01/2021 - */ -class ElementsShouldHavePropertyInstanceOfTests { - @Test - void single_entities_error() { - // GIVEN - final ValueType expectedType = ValueType.STRING; - final List actual = Arrays.asList( - Drivers.node().id(1).property("prop-key", "value-1").build(), - Drivers.node().id(2).property("prop-key", LocalDateTime.now()).build(), - Drivers.node().id(3).property("prop-key", "value-3").build(), - Drivers.node().id(4).property("prop-key", "value-4").build() - ); - - // WHEN - final ErrorMessageFactory result = ElementsShouldHavePropertyInstanceOf - .create(RecordType.NODE, actual, "toto", String.class); - - // THEN - Assertions.assertThat(result.create()).isEqualToNormalizingNewlines( - "todo" - ); - } - -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyKeysTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyKeysTests.java deleted file mode 100644 index 622ef6b..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyKeysTests.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.api.Assertions; -import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Nodes.DbNode; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author patouhe - 26/11/2020 - */ -class ElementsShouldHavePropertyKeysTests { - - @Nested - @DisplayName("missingPropertyKeys(Entity, List)") - class EntityMissingPropertyKeysTests { - - @Test - void should_return_a_missing_with_no_data() { - // GIVEN - final List keys = Arrays.asList("k-1", "k-2", "k-3"); - final DbNode entity = Drivers.node() - .property("k-1", "val-1") - .property("k-2", "val-2") - .property("k-3", "val-3") - .build(); - // WHEN - final Missing result = ElementsShouldHavePropertyKeys.missingPropertyKeys(entity, keys); - - // THEN - assertThat(result).isNotNull(); - assertThat(result.getEntity()).isSameAs(entity); - assertThat(result.getData()).isNotNull(); - assertThat(result.hasMissing()).isFalse(); - } - - @Test - void should_return_a_missing_with_data() { - // GIVEN - final List keys = Arrays.asList("k-1", "k-2", "k-3"); - final DbNode entity = Drivers.node().property("k-1", "val-1").build(); - - // WHEN - final Missing result = ElementsShouldHavePropertyKeys.missingPropertyKeys(entity, keys); - - // THEN - assertThat(result).isNotNull(); - assertThat(result.getEntity()).isSameAs(entity); - assertThat(result.getData()).isNotNull().containsExactly("k-2", "k-3"); - assertThat(result.hasMissing()).isTrue(); - } - - } - - @Nested - @DisplayName("missingPropertyKeys(List, List)") - class MissingPropertyKeysTests { - - @Test - void should_return_an_empty_list() { - // GIVEN - final List keys = Arrays.asList("k-1", "k-2", "k-3"); - final List entities = IntStream.range(0, 10) - .mapToObj(i -> Drivers.node() - .property("k-1", "val-1-" + i) - .property("k-2", "val-2-" + i) - .property("k-3", "val-3-" + i) - .build()) - .collect(Collectors.toList()); - - // WHEN - final List> result = ElementsShouldHavePropertyKeys.missingPropertyKeys(entities, keys); - - // THEN - assertThat(result).isNotNull().isEmpty(); - } - - @Test - void should_return_a_list_of_missing_nodes() { - // GIVEN - final List keys = Arrays.asList("k-1", "k-2", "k-3"); - final List entities = Arrays.asList( - Drivers.node().property("k-1", "val-1-1").property("k-2", "val-1-2").build(), - Drivers.node().property("k-1", "val-2-1").property("k-3", "val-2-3").build(), - Drivers.node().property("k-2", "val-3-2").property("k-3", "val-3-3").build(), - Drivers.node().property("k-1", "val-4-1").build() - ); - - // WHEN - final List> result = ElementsShouldHavePropertyKeys.missingPropertyKeys(entities, keys); - - // THEN - assertThat(result) - .hasSize(4) - .containsExactly( - new Missing<>(entities.get(0), Arrays.asList("k-3")), - new Missing<>(entities.get(1), Arrays.asList("k-2")), - new Missing<>(entities.get(2), Arrays.asList("k-1")), - new Missing<>(entities.get(3), Arrays.asList("k-2", "k-3")) - ); - } - } - - @Test - void create_single_node() { - // GIVEN - final List expectedKeys = Arrays.asList("k-1", "k-2", "k-3"); - final List nodes = Arrays.asList( - Drivers.node().id(1).property("k-1", "v-1").property("k-2", "v-2").property("k-3", "v-3").build(), - Drivers.node().id(2).property("k-1", "v-1").property("k-2", "v-2").build(), - Drivers.node().id(3).property("k-1", "v-1").property("k-2", "v-2").property("k-3", "v-3").build() - ); - - // WHEN - final ElementsShouldHavePropertyKeys error = ElementsShouldHavePropertyKeys.create( - RecordType.NODE, nodes, expectedKeys - ); - - // THEN - Assertions.assertThat(error.create()).isEqualToNormalizingNewlines( - "\nExpecting nodes:\n" - + " [\"NODE{id=1}\", \"NODE{id=2}\", \"NODE{id=3}\"]\n" - + "to have all the following property keys:\n" - + " [\"k-1\", \"k-2\", \"k-3\"]\n" - + "but some property keys were missing on:\n" - + "\n" - + " - NODE{id=2} have missing property keys: [k-3]\n" - + " Actual : <[k-1, k-2]>\n" - + " Expected: <[k-1, k-2, k-3]>" - ); - - } - - @Test - void create_multiple_nodes() { - // GIVEN - final List expectedKeys = Arrays.asList("k-1", "k-2", "k-3"); - final List nodes = Arrays.asList( - Drivers.node().id(1).property("k-3", "v-3").property("k-2", "v-2").build(), - Drivers.node().id(2).property("k-3", "v-3").property("k-1", "v-1").build(), - Drivers.node().id(3).property("k-2", "v-2").property("k-1", "v-1").build(), - Drivers.node().id(4).property("k-3", "v-3").build() - ); - - // WHEN - final ElementsShouldHavePropertyKeys error = ElementsShouldHavePropertyKeys.create( - RecordType.NODE, nodes, expectedKeys - ); - - // THEN - Assertions.assertThat(error.create()).isEqualToNormalizingNewlines( - "\nExpecting nodes:\n" - + " [\"NODE{id=1}\", \"NODE{id=2}\", \"NODE{id=3}\", \"NODE{id=4}\"]\n" - + "to have all the following property keys:\n" - + " [\"k-1\", \"k-2\", \"k-3\"]\n" - + "but some property keys were missing on:\n" - + "\n" - + " - NODE{id=1} have missing property keys: [k-1]\n" - + " Actual : <[k-2, k-3]>\n" - + " Expected: <[k-1, k-2, k-3]>\n" - + "\n" - + " - NODE{id=2} have missing property keys: [k-2]\n" - + " Actual : <[k-1, k-3]>\n" - + " Expected: <[k-1, k-2, k-3]>\n" - + "\n" - + " - NODE{id=3} have missing property keys: [k-3]\n" - + " Actual : <[k-1, k-2]>\n" - + " Expected: <[k-1, k-2, k-3]>\n" - + "\n" - + " - NODE{id=4} have missing property keys: [k-1, k-2]\n" - + " Actual : <[k-3]>\n" - + " Expected: <[k-1, k-2, k-3]>" - ); - - } -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyListOfTypeTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyListOfTypeTests.java deleted file mode 100644 index c8a1cef..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyListOfTypeTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.api.Assertions; -import org.assertj.core.error.ErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Nodes; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.assertj.neo4j.api.beta.type.ValueType; -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; - -/** - * @author patouche - 27/12/2020 - */ -class ElementsShouldHavePropertyListOfTypeTests { - - @Test - void create_single_node() { - // GIVEN - final List nodes = asList( - Drivers.node().id(1) - .property("key", emptyList()) - .build(), - Drivers.node().id(2) - .property("key", singletonList("v-2.1.1")) - .build(), - Drivers.node().id(3) - .property("key", asList(3.11, 3.12)) - .build() - ); - - // WHEN - final ErrorMessageFactory error = ElementsShouldHavePropertyListOfType.create( - RecordType.NODE, nodes, "key", ValueType.INTEGER - ); - - // THEN - Assertions.assertThat(error.create()).isEqualToNormalizingNewlines( - "TOTO" - ); - - } - - @Test - void create_multiple_nodes() { - // GIVEN - final List nodes = asList( - Drivers.node().id(1) - .property("key", emptyList()) - .build(), - Drivers.node().id(2) - .property("key", singletonList("v-2.1.1")) - .build(), - Drivers.node().id(3) - .property("key", asList(3.11, 3.12)) - .build(), - Drivers.node().id(4) - .property("key", asList(4.11, 4.12, 4.13)) - .build() - ); - - // WHEN - final ErrorMessageFactory error = ElementsShouldHavePropertyListOfType.create( - RecordType.NODE, nodes, "key", ValueType.STRING - ); - - // THEN - Assertions.assertThat(error.create()).isEqualToNormalizingNewlines( - "TODO" - ); - - } -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyOfTypeTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyOfTypeTests.java deleted file mode 100644 index e66e601..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyOfTypeTests.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.api.Assertions; -import org.assertj.core.error.ErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Nodes; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.assertj.neo4j.api.beta.type.ValueType; -import org.junit.jupiter.api.Test; -import org.neo4j.driver.Values; - -import java.time.LocalDateTime; -import java.time.ZonedDateTime; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -class ElementsShouldHavePropertyOfTypeTests { - - @Test - void single_entities_error() { - // GIVEN - final ValueType expectedType = ValueType.STRING; - final List actual = Arrays.asList( - Drivers.node().id(1).property("prop-key", "value-1").build(), - Drivers.node().id(2).property("prop-key", LocalDateTime.now()).build(), - Drivers.node().id(3).property("prop-key", "value-3").build(), - Drivers.node().id(4).property("prop-key", "value-4").build() - ); - - // WHEN - final ErrorMessageFactory result = ElementsShouldHavePropertyValueType - .create(RecordType.NODE, actual, "prop-key", expectedType); - - // THEN - Assertions.assertThat(result.create()).isEqualToNormalizingNewlines( - "\nExpecting nodes:\n" - + " [\"NODE{id=1}\", \"NODE{id=2}\", \"NODE{id=3}\", \"NODE{id=4}\"]\n" - + "to have property \"prop-key\" with type:\n" - + " STRING\n" - + "but some nodes have for the property \"prop-key\" another type:\n" - + "\n" - + " - NODE{id=2} have property \"prop-key\" of type:\n" - + " Actual : LOCAL_DATE_TIME\n" - + " Expected: STRING" - ); - } - - @Test - void multiple_entities_error() { - // GIVEN - final ValueType expectedType = ValueType.STRING; - final List actual = Arrays.asList( - Drivers.node().id(1).property("prop-key", "value-1").build(), - Drivers.node().id(2).property("prop-key", LocalDateTime.now()).build(), - Drivers.node().id(3).property("prop-key", 1).build(), - Drivers.node().id(4).property("prop-key", Values.point(1, 22.29, 56.35).asObject()).build(), - Drivers.node().id(4).property("prop-key", ZonedDateTime.now()).build(), - Drivers.node().id(4).property("prop-key", true).build() - ); - final List items = actual.stream() - .filter(e -> e.getPropertyType("prop-key") != expectedType) - .collect(Collectors.toList()); - - // WHEN - final ErrorMessageFactory result = ElementsShouldHavePropertyValueType - .create(RecordType.NODE, actual, "prop-key", expectedType); - - // THEN - Assertions.assertThat(result.create()).isEqualToNormalizingNewlines( - "\nExpecting nodes:\n" - + " [\"NODE{id=1}\",\n" - + " \"NODE{id=2}\",\n" - + " \"NODE{id=3}\",\n" - + " \"NODE{id=4}\",\n" - + " \"NODE{id=4}\",\n" - + " \"NODE{id=4}\"]\n" - + "to have property \"prop-key\" with type:\n" - + " STRING\n" - + "but some nodes have for the property \"prop-key\" another type:\n" - + "\n" - + " - NODE{id=2} have property \"prop-key\" of type:\n" - + " Actual : LOCAL_DATE_TIME\n" - + " Expected: STRING\n" - + "\n" - + " - NODE{id=3} have property \"prop-key\" of type:\n" - + " Actual : INTEGER\n" - + " Expected: STRING\n" - + "\n" - + " - NODE{id=4} have property \"prop-key\" of type:\n" - + " Actual : POINT\n" - + " Expected: STRING\n" - + "\n" - + " - NODE{id=4} have property \"prop-key\" of type:\n" - + " Actual : DATE_TIME\n" - + " Expected: STRING\n" - + "\n" - + " - NODE{id=4} have property \"prop-key\" of type:\n" - + " Actual : BOOLEAN\n" - + " Expected: STRING" - ); - } -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertySizeTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertySizeTests.java deleted file mode 100644 index 38147e2..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertySizeTests.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -/** - * @author patouche - 01/02/2021 - */ -class ElementsShouldHavePropertySizeTests { - - @Test - void create_single_node() { - Assertions.fail("TODO"); - } - -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValueTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValueTests.java deleted file mode 100644 index 6b7b68e..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHavePropertyValueTests.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.api.Assertions; -import org.assertj.core.error.ErrorMessageFactory; -import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Nodes; -import org.assertj.neo4j.api.beta.type.RecordType; -import org.assertj.neo4j.api.beta.type.ValueType; -import org.junit.jupiter.api.Test; -import org.neo4j.driver.Values; - -import java.time.LocalDateTime; -import java.time.ZonedDateTime; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * @author patouche - 31/01/2021 - */ -class ElementsShouldHavePropertyValueTests { - - @Test - void single_entities_error() { - // GIVEN - final ValueType expectedType = ValueType.STRING; - final List actual = Arrays.asList( - Drivers.node().id(1).property("prop-key", "value-1").build(), - Drivers.node().id(2).property("prop-key", LocalDateTime.now()).build(), - Drivers.node().id(3).property("prop-key", "value-3").build(), - Drivers.node().id(4).property("prop-key", "value-4").build() - ); - - // WHEN - final ErrorMessageFactory result = ElementsShouldHavePropertyValue - .create(RecordType.NODE, actual, actual, "toto", "toto"); - - // THEN - Assertions.assertThat(result.create()).isEqualToNormalizingNewlines( - "todo" - ); - } - - @Test - void multiple_entities_error() { - // GIVEN - final ValueType expectedType = ValueType.STRING; - final List actual = Arrays.asList( - Drivers.node().id(1).property("prop-key", "value-1").build(), - Drivers.node().id(2).property("prop-key", LocalDateTime.now()).build(), - Drivers.node().id(3).property("prop-key", 1).build(), - Drivers.node().id(4).property("prop-key", Values.point(1, 22.29, 56.35).asObject()).build(), - Drivers.node().id(4).property("prop-key", ZonedDateTime.now()).build(), - Drivers.node().id(4).property("prop-key", true).build() - ); - final List items = actual.stream() - .filter(e -> e.getPropertyType("prop-key") != expectedType) - .collect(Collectors.toList()); - - // WHEN - final ErrorMessageFactory result = ElementsShouldHavePropertyValue - .create(RecordType.NODE, actual, actual, "toto", "toto"); - - // THEN - Assertions.assertThat(result.create()).isEqualToNormalizingNewlines( - "todo" - ); - } -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveTypeTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveTypeTests.java deleted file mode 100644 index 617b06d..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/error/ElementsShouldHaveTypeTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.error; - -import org.assertj.core.api.Assertions; -import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Relationships; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.List; - -/** - * @author patouche - 25/11/2020 - */ -class ElementsShouldHaveTypeTests { - - @Test - void create_single_relationships() { - // GIVEN - final String expectedType = "TYPE"; - final List relationships = Arrays.asList( - Drivers.relation("TYPE").id(1).build(), - Drivers.relation("OTHER_TYPE").id(2).build(), - Drivers.relation("TYPE").id(3).build() - ); - - // WHEN - final ElementsShouldHaveType error = ElementsShouldHaveType.create(relationships, expectedType); - - // THEN - Assertions.assertThat(error.create()).isEqualToNormalizingNewlines( - "\nExpecting relationships:\n" - + " [\"RELATIONSHIP{id=1}\", \"RELATIONSHIP{id=2}\", \"RELATIONSHIP{id=3}\"]\n" - + "to be of type:\n" - + " \"TYPE\"\n" - + "but some relationships have an other type:\n" - + "\n" - + " - RELATIONSHIP{id=2} doesn't have the expected type:\n" - + " Actual : OTHER_TYPE\n" - + " Expected: TYPE" - ); - - } - - @Test - void create_multiple_relationships() { - // GIVEN - final String expectedType = "TYPE"; - final List relationships = Arrays.asList( - Drivers.relation("TYPE").id(1).build(), - Drivers.relation("OTHER_TYPE_2").id(2).build(), - Drivers.relation("TYPE").id(3).build(), - Drivers.relation("OTHER_TYPE_4").id(4).build(), - Drivers.relation("OTHER_TYPE_5").id(5).build(), - Drivers.relation("TYPE").id(6).build() - ); - - // WHEN - final ElementsShouldHaveType error = ElementsShouldHaveType.create(relationships, expectedType); - - // THEN - Assertions.assertThat(error.create()).isEqualToNormalizingNewlines( - "\nExpecting relationships:\n" - + " [\"RELATIONSHIP{id=1}\",\n" - + " \"RELATIONSHIP{id=2}\",\n" - + " \"RELATIONSHIP{id=3}\",\n" - + " \"RELATIONSHIP{id=4}\",\n" - + " \"RELATIONSHIP{id=5}\",\n" - + " \"RELATIONSHIP{id=6}\"]\n" - + "to be of type:\n" - + " \"TYPE\"\n" - + "but some relationships have an other type:\n" - + "\n" - + " - RELATIONSHIP{id=2} doesn't have the expected type:\n" - + " Actual : OTHER_TYPE_2\n" - + " Expected: TYPE\n" - + "\n" - + " - RELATIONSHIP{id=4} doesn't have the expected type:\n" - + " Actual : OTHER_TYPE_4\n" - + " Expected: TYPE\n" - + "\n" - + " - RELATIONSHIP{id=5} doesn't have the expected type:\n" - + " Actual : OTHER_TYPE_5\n" - + " Expected: TYPE" - ); - - } -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldBeEmptyQueryResultTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldBeEmptyQueryResultTests.java new file mode 100644 index 0000000..3815f5a --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldBeEmptyQueryResultTests.java @@ -0,0 +1,88 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Query; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author patouche - 13/02/2021 + */ +class ShouldBeEmptyQueryResultTests { + + @Nested + class CreateTests { + + @Test + void should_generate_error_message() { + // GIVEN + final Query query = new Query("MATCH (n) RETURN n"); + final DbNode actual = Drivers.node().id(42).build(); + + // WHEN + final ErrorMessageFactory error = ShouldBeEmptyQueryResult.create(actual, query); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting query:\n" + + " \n" + + "to return a empty list but got:\n" + + " " + ); + } + + } + + @Nested + class ElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final Query query = new Query("MATCH (n) RETURN n"); + final DbNode node1 = Drivers.node().id(22).build(); + final DbNode node2 = Drivers.node().id(49).build(); + final DbNode node3 = Drivers.node().id(35).build(); + final DbNode node4 = Drivers.node().id(42).build(); + final DbNode node5 = Drivers.node().id(56).build(); + final List actual = Randomize.listOf(node1, node2, node3, node4, node5); + + // WHEN + final ErrorMessageFactory error = ShouldBeEmptyQueryResult.elements(actual, query) + .notSatisfies(Randomize.listOf(node1, node2)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting query:\n" + + " \n" + + "to return no nodes but got:\n" + + " <[\"NODE{id=22}\", \"NODE{id=35}\", \"NODE{id=42}\", \"NODE{id=49}\", \"NODE{id=56}\"]>\n" + + "\n" + + " 1) NODE{id=22}\n" + + "\n" + + " 2) NODE{id=49}" + ); + } + } +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHaveNodeLabelsTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHaveNodeLabelsTests.java new file mode 100644 index 0000000..cb3f8e3 --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHaveNodeLabelsTests.java @@ -0,0 +1,114 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +/** + * @author Patrick Allain - 14/11/2020 + */ +public class ShouldHaveNodeLabelsTests { + + private static final List LABELS = Randomize.listOf("LBL_1", "LBL_2", "LBL_3", "LBL_4"); + + @Nested + class CreateTests { + + @Test + void should_generate_error_message() { + // GIVEN + final Nodes.DbNode entity = Drivers.node().id(42).labels("LBL_4", "LBL_1").build(); + + // WHEN + final ErrorMessageFactory error = ShouldHaveNodeLabels.create(entity, LABELS); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\nExpecting NODE{id=42} which have labels:\n" + + " <[\"LBL_1\", \"LBL_4\"]>\n" + + "to have labels:\n" + + " <[\"LBL_1\", \"LBL_2\", \"LBL_3\", \"LBL_4\"]>\n" + + "but the following labels cannot be found:\n" + + " <[\"LBL_2\", \"LBL_3\"]>" + ); + } + + } + + @Nested + class ElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final Nodes.DbNode node1 = Drivers.node().id(12).labels("LBL_1").build(); + final Nodes.DbNode node2 = Drivers.node().id(18).labels("LBL_2").build(); + final Nodes.DbNode node3 = Drivers.node().id(42).labels("LBL_3").build(); + final Nodes.DbNode node4 = Drivers.node().id(51).labels("LBL_4", "LBL_1").build(); + final Nodes.DbNode node5 = Drivers.node().id(69).labels("LBL_4", "LBL_2").build(); + final Nodes.DbNode node6 = Drivers.node().id(95).labels("LBL_1", "LBL_2", "LBL_3", "LBL_4").build(); + + final List nodes = Randomize.listOf(node1, node2, node3, node4, node5, node6); + final GroupingEntityErrorFactory elements = ShouldHaveNodeLabels.elements(nodes, LABELS); + + // WHEN + final ErrorMessageFactory error = elements + .notSatisfies(Randomize.listOf(node1, node2, node3, node4, node5)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting nodes:\n" + + " <[\"NODE{id=12}\",\n" + + " \"NODE{id=18}\",\n" + + " \"NODE{id=42}\",\n" + + " \"NODE{id=51}\",\n" + + " \"NODE{id=69}\",\n" + + " \"NODE{id=95}\"]>\n" + + "to have the labels:\n" + + " <[\"LBL_1\", \"LBL_2\", \"LBL_3\", \"LBL_4\"]>\n" + + "but some labels are missing for nodes:\n" + + "\n" + + " 1) NODE{id=12}\n" + + " - Actual labels: [LBL_1]\n" + + " - Missing Labels: [LBL_2, LBL_3, LBL_4]\n" + + "\n" + + " 2) NODE{id=18}\n" + + " - Actual labels: [LBL_2]\n" + + " - Missing Labels: [LBL_1, LBL_3, LBL_4]\n" + + "\n" + + " 3) NODE{id=42}\n" + + " - Actual labels: [LBL_3]\n" + + " - Missing Labels: [LBL_1, LBL_2, LBL_4]\n" + + "\n" + + " 4) NODE{id=51}\n" + + " - Actual labels: [LBL_1, LBL_4]\n" + + " - Missing Labels: [LBL_2, LBL_3]\n" + + "\n" + + " 5) NODE{id=69}\n" + + " - Actual labels: [LBL_2, LBL_4]\n" + + " - Missing Labels: [LBL_1, LBL_3]" + ); + } + } + +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyInstanceOfTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyInstanceOfTests.java new file mode 100644 index 0000000..c2f24d0 --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyInstanceOfTests.java @@ -0,0 +1,118 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.testing.Samples; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Patrick Allain - 31/01/2021 + */ +class ShouldHavePropertyInstanceOfTests { + + @Nested + class CreateTests { + + @Test + void should_generate_error_message() { + // GIVEN + final Nodes.DbNode actual = Drivers.node().id(1).property("key", "value-1").build(); + + // WHEN + final ErrorMessageFactory error = ShouldHavePropertyInstanceOf.create(actual, "key", Long.class); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting NODE{id=1} to have property value \"key\" instance of:\n" + + " \n" + + "but the actual property value for this key is a :\n" + + " <\"java.lang.String\">\n" + + "which is not an instance of the expected class.\n" + + "\n" + + "Actual value for this property is:\n" + + " <\"value-1\">" + ); + } + } + + @Nested + class ElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final Nodes.DbNode node1 = Drivers.node().id(1).property("key", "value-1").build(); + final Nodes.DbNode node2 = Drivers.node().id(2).property("key", Samples.LOCAL_DATE_TIME).build(); + final Nodes.DbNode node3 = Drivers.node().id(3).property("key", 3.14).build(); + final Nodes.DbNode node4 = Drivers.node().id(4).property("key", 4).build(); + final Nodes.DbNode node5 = Drivers.node().id(5).property("key", Samples.ZONED_DATE_TIME).build(); + final Nodes.DbNode node6 = Drivers.node().id(6).property("key", true).build(); + + final List actual = Randomize.listOf(node1, node2, node3, node4, node5, node6); + + // WHEN + final ErrorMessageFactory error = ShouldHavePropertyInstanceOf + .elements(actual, "key", Boolean.class) + .notSatisfies(Randomize.listOf(node1, node2, node3, node4, node5)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting nodes:\n" + + " <[\"NODE{id=1}\",\n" + + " \"NODE{id=2}\",\n" + + " \"NODE{id=3}\",\n" + + " \"NODE{id=4}\",\n" + + " \"NODE{id=5}\",\n" + + " \"NODE{id=6}\"]>\n" + + "to have property value \"key\" instance of:\n" + + " \n" + + "but some nodes have a property value which is not an instance of the expected class:\n" + + "\n" + + " 1) NODE{id=1}\n" + + " - Actual value class: java.lang.String\n" + + " - Actual value: value-1\n" + + "\n" + + " 2) NODE{id=2}\n" + + " - Actual value class: java.time.LocalDateTime\n" + + " - Actual value: 2020-02-03T04:05:06.000000007\n" + + "\n" + + " 3) NODE{id=3}\n" + + " - Actual value class: java.lang.Double\n" + + " - Actual value: 3.14\n" + + "\n" + + " 4) NODE{id=4}\n" + + " - Actual value class: java.lang.Long\n" + + " - Actual value: 4\n" + + "\n" + + " 5) NODE{id=5}\n" + + " - Actual value class: java.time.ZonedDateTime\n" + + " - Actual value: 2020-02-03T04:05:06.000000007+11:00[Australia/Sydney]" + ); + } + } + +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyKeysTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyKeysTests.java new file mode 100644 index 0000000..90d9660 --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyKeysTests.java @@ -0,0 +1,118 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author patouhe - 26/11/2020 + */ +class ShouldHavePropertyKeysTests { + + private static final List KEYS = Randomize.listOf("k-1", "k-2", "k-3"); + + @Nested + class CreateTests { + + @Test + void should_generate_error_message() { + // GIVEN + final DbNode entity = Drivers.node().id(42).property("k-1", 1).property("k-4", 4).build(); + + // WHEN + final ErrorMessageFactory error = ShouldHavePropertyKeys.create(entity, KEYS); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\nExpecting NODE{id=42} with property keys:\n" + + " <[\"k-1\", \"k-4\"]>\n" + + "to have property keys:\n" + + " <[\"k-1\", \"k-2\", \"k-3\"]>\n" + + "but the following property keys cannot be found:\n" + + " <[\"k-2\", \"k-3\"]>" + ); + } + + } + + @Nested + class ElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final List keys = Arrays.asList("k-1", "k-2", "k-3"); + final DbNode node1 = Drivers.node().id(12).property("k-1", 1).build(); + final DbNode node2 = Drivers.node().id(18).property("k-2", 2).build(); + final DbNode node3 = Drivers.node().id(42).property("k-3", 3).build(); + final DbNode node4 = Drivers.node().id(51).property("k-1", 1).property("k-3", 3).build(); + final DbNode node5 = Drivers.node().id(69).property("k-2", 2).property("k-3", 3).build(); + final DbNode node6 = Drivers.node().id(95).property("k-1", 1).property("k-2", 2).property("k-3", 4).build(); + + final List entities = Randomize.listOf(node1, node2, node3, node4, node5, node6); + final GroupingEntityErrorFactory elements = ShouldHavePropertyKeys.elements(entities, keys); + + // WHEN + final ErrorMessageFactory error = elements + .notSatisfies(Randomize.listOf(node1, node2, node3, node4, node5)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting nodes:\n" + + " <[\"NODE{id=12}\",\n" + + " \"NODE{id=18}\",\n" + + " \"NODE{id=42}\",\n" + + " \"NODE{id=51}\",\n" + + " \"NODE{id=69}\",\n" + + " \"NODE{id=95}\"]>\n" + + "to have properties with keys:\n" + + " <[\"k-1\", \"k-2\", \"k-3\"]>\n" + + "but some nodes don't have this properties:\n" + + "\n" + + " 1) NODE{id=12}\n" + + " - Actual property keys: [k-1]\n" + + " - Missing property keys: [k-2, k-3]\n" + + "\n" + + " 2) NODE{id=18}\n" + + " - Actual property keys: [k-2]\n" + + " - Missing property keys: [k-1, k-3]\n" + + "\n" + + " 3) NODE{id=42}\n" + + " - Actual property keys: [k-3]\n" + + " - Missing property keys: [k-1, k-2]\n" + + "\n" + + " 4) NODE{id=51}\n" + + " - Actual property keys: [k-1, k-3]\n" + + " - Missing property keys: [k-2]\n" + + "\n" + + " 5) NODE{id=69}\n" + + " - Actual property keys: [k-2, k-3]\n" + + " - Missing property keys: [k-1]" + ); + } + } + +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyListOfTypeTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyListOfTypeTests.java new file mode 100644 index 0000000..a09d54c --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyListOfTypeTests.java @@ -0,0 +1,99 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.assertj.neo4j.api.beta.type.ValueType; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Patrick Allain - 27/12/2020 + */ +class ShouldHavePropertyListOfTypeTests { + + @Nested + class CreateTests { + + @Test + void should_generate_error_message() { + // GIVEN + final DbNode node = Drivers.node().id(3).property("key", Arrays.asList(3.11, 3.12, 3.13)).build(); + + // WHEN + final ErrorMessageFactory error = ShouldHavePropertyListOfType.create(node, "key", ValueType.INTEGER); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expected NODE{id=3} to have a composite property list named \"key\" containing only type:\n" + + " \n" + + "but this composite property list contains type:\n" + + " \n" + + "with actual value:\n" + + " <[3.11, 3.12, 3.13]>" + ); + + } + } + + @Nested + class ElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final DbNode node1 = Drivers.node().id(1).property("key", emptyList()).build(); + final DbNode node2 = Drivers.node().id(2).property("key", singletonList("v-2.1.1")).build(); + final DbNode node3 = Drivers.node().id(3).property("key", asList(3.11, 3.12)).build(); + final DbNode node4 = Drivers.node().id(4).property("key", asList(4, 5, 6)).build(); + + final List actual = Randomize.listOf(node1, node2, node3, node4); + final GroupingEntityErrorFactory elements = ShouldHavePropertyListOfType + .elements(actual, "key", ValueType.STRING); + + // WHEN + final ErrorMessageFactory error = elements.notSatisfies(Randomize.listOf(node3, node4)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting nodes:\n" + + " <[\"NODE{id=1}\", \"NODE{id=2}\", \"NODE{id=3}\", \"NODE{id=4}\"]>\n" + + "to have a composite property list named \"key\" containing only type:\n" + + " \n" + + "but some nodes have a composite list containing others type:\n" + + "\n" + + " 1) NODE{id=3}\n" + + " - Actual list value type: FLOAT\n" + + " - Actual value: [3.11, 3.12]\n" + + "\n" + + " 2) NODE{id=4}\n" + + " - Actual list value type: INTEGER\n" + + " - Actual value: [4, 5, 6]" + ); + + } + } +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertySizeTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertySizeTests.java new file mode 100644 index 0000000..5523212 --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertySizeTests.java @@ -0,0 +1,133 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.testing.Samples; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Patrick Allain - 01/02/2021 + */ +class ShouldHavePropertySizeTests { + + @Nested + class CreateTests { + + @Test + void should_generate_error_message() { + // GIVEN + final DbNode actual = Drivers.node().id(42).property("k-2", 3.14).property("k-1", "v-1").build(); + + // WHEN + final ErrorMessageFactory error = ShouldHavePropertySize.create(actual, 3); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting NODE{id=42} to have property size:\n" + + " <3>\n" + + "but actual property size is:\n" + + " <2>\n" + + "containing the following property keys:\n" + + " <[\"k-1\", \"k-2\"]>" + ); + } + } + + @Nested + class ElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final DbNode node1 = Drivers.node().id(1).property("k-1", "v-1").build(); + final DbNode node2 = Drivers.node().id(2).property("k-1", "v-2").property("k-2", 3.14).build(); + final DbNode node3 = Drivers.node().id(3) + .property("k-1", "v-3") + .property("k-2", 6.12) + .property("k-3", false) + .property("k-4", "some-prop") + .build(); + final DbNode node4 = Drivers.node().id(4) + .property("k-1", "v-4") + .property("k-4", "some-other-prop") + .build(); + final DbNode node5 = Drivers.node().id(5) + .property("k-1", "v-5") + .property("k-2", 2.0) + .property("k-3", true) + .property("k-5", Samples.ZONED_DATE_TIME) + .build(); + final DbNode node6 = Drivers.node().id(6) + .property("k-1", "v-6") + .property("k-2", 8.5) + .property("k-3", true) + .build(); + + final List actual = Randomize.listOf(node1, node2, node3, node4, node5, node6); + final GroupingEntityErrorFactory elements = ShouldHavePropertySize.elements(actual, 3); + + // WHEN + final ErrorMessageFactory error = elements + .notSatisfies(Randomize.listOf(node1, node2, node3, node4, node5)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting nodes:\n" + + " <[\"NODE{id=1}\",\n" + + " \"NODE{id=2}\",\n" + + " \"NODE{id=3}\",\n" + + " \"NODE{id=4}\",\n" + + " \"NODE{id=5}\",\n" + + " \"NODE{id=6}\"]>\n" + + "to have a property size:\n" + + " <3>\n" + + "but some nodes have another property size:\n" + + "\n" + + " 1) NODE{id=1}\n" + + " - Actual property size: 1\n" + + " - Actual property keys: [k-1]\n" + + "\n" + + " 2) NODE{id=2}\n" + + " - Actual property size: 2\n" + + " - Actual property keys: [k-1, k-2]\n" + + "\n" + + " 3) NODE{id=3}\n" + + " - Actual property size: 4\n" + + " - Actual property keys: [k-1, k-2, k-3, k-4]\n" + + "\n" + + " 4) NODE{id=4}\n" + + " - Actual property size: 2\n" + + " - Actual property keys: [k-1, k-4]\n" + + "\n" + + " 5) NODE{id=5}\n" + + " - Actual property size: 4\n" + + " - Actual property keys: [k-1, k-2, k-3, k-5]" + ); + } + } + +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueTests.java new file mode 100644 index 0000000..69d8695 --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueTests.java @@ -0,0 +1,117 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.testing.Samples; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Values; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.neo4j.api.beta.type.Nodes.DbNode; + +/** + * @author Patrick Allain - 31/01/2021 + */ +class ShouldHavePropertyValueTests { + + @Nested + class CreateTests { + + @Test + void should_generate_error_message() { + // GIVEN + final DbNode actual = Drivers.node().id(1).property("key", "value").build(); + + // WHEN + final ErrorMessageFactory error = ShouldHavePropertyValue + .create(actual, "key", "other-value"); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting NODE{id=1} to have a property \"key\" with value:\n" + + " <\"other-value\">\n" + + "but current value of this property is:\n" + + " <\"value\">" + ); + } + + } + + @Nested + class ElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final DbNode node1 = Drivers.node().id(1).property("key", "value-1").build(); + final DbNode node2 = Drivers.node().id(2).property("key", Samples.LOCAL_DATE_TIME).build(); + final DbNode node3 = Drivers.node().id(3).property("key", 1).build(); + final DbNode node4 = Drivers.node().id(4).property("key", Values.point(1, 22.29, 56.35).asObject()).build(); + final DbNode node5 = Drivers.node().id(5).property("key", Samples.ZONED_DATE_TIME).build(); + final DbNode node6 = Drivers.node().id(6).property("key", true).build(); + + final List actual = Randomize.listOf(node1, node2, node3, node4, node5, node6); + final GroupingEntityErrorFactory elements = ShouldHavePropertyValue + .elements(actual, "key", true); + + // WHEN + final ErrorMessageFactory result = elements + .notSatisfies(Randomize.listOf(node1, node2, node3, node4, node5)); + + // THEN + assertThat(result.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting nodes:\n" + + " <[\"NODE{id=1}\",\n" + + " \"NODE{id=2}\",\n" + + " \"NODE{id=3}\",\n" + + " \"NODE{id=4}\",\n" + + " \"NODE{id=5}\",\n" + + " \"NODE{id=6}\"]>\n" + + "to have a property named \"key\" with value:\n" + + " \n" + + "but some nodes have a different value for this property:\n" + + "\n" + + " 1) NODE{id=1}\n" + + " - Actual value: value-1\n" + + " - Actual type: STRING\n" + + "\n" + + " 2) NODE{id=2}\n" + + " - Actual value: 2020-02-03T04:05:06.000000007\n" + + " - Actual type: LOCAL_DATE_TIME\n" + + "\n" + + " 3) NODE{id=3}\n" + + " - Actual value: 1\n" + + " - Actual type: INTEGER\n" + + "\n" + + " 4) NODE{id=4}\n" + + " - Actual value: Point{srid=1, x=22.29, y=56.35}\n" + + " - Actual type: POINT\n" + + "\n" + + " 5) NODE{id=5}\n" + + " - Actual value: 2020-02-03T04:05:06.000000007+11:00[Australia/Sydney]\n" + + " - Actual type: DATE_TIME" + ); + } + } +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueTypeTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueTypeTests.java new file mode 100644 index 0000000..9ebf03e --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldHavePropertyValueTypeTests.java @@ -0,0 +1,121 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.testing.Samples; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.assertj.neo4j.api.beta.type.ValueType; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Values; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Patrick Allain - 09/02/2021 + */ +class ShouldHavePropertyValueTypeTests { + + @Nested + class CreateTests { + + @Test + void should_generate_error_message() { + // GIVEN + final ValueType expectedType = ValueType.STRING; + final DbNode actual = Drivers.node().id(2).property("key", Samples.LOCAL_DATE_TIME).build(); + + // WHEN + final ErrorMessageFactory result = ShouldHavePropertyValueType.create(actual, "key", expectedType); + + // THEN + assertThat(result.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting NODE{id=2} to have property value type for key \"key\":\n" + + " \n" + + "but actual value type for this property key is:\n" + + " \n" + + "\n" + + "Actual property value:\n" + + " <2020-02-03T04:05:06.000000007 (java.time.LocalDateTime)>" + ); + } + } + + @Nested + class ElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final ValueType expectedType = ValueType.BOOLEAN; + final DbNode node1 = Drivers.node().id(1).property("key", "value-1").build(); + final DbNode node2 = Drivers.node().id(2).property("key", Samples.LOCAL_DATE_TIME).build(); + final DbNode node3 = Drivers.node().id(3).property("key", 1).build(); + final DbNode node4 = Drivers.node().id(4) + .property("key", Values.point(1, 22.29, 56.35).asObject()) + .build(); + final DbNode node5 = Drivers.node().id(5).property("key", Samples.ZONED_DATE_TIME).build(); + final DbNode node6 = Drivers.node().id(6).property("key", true).build(); + + final List actual = Randomize.listOf(node1, node2, node3, node4, node5, node6); + + // WHEN + final ErrorMessageFactory error = ShouldHavePropertyValueType + .elements(actual, "key", expectedType) + .notSatisfies(Randomize.listOf(node1, node2, node3, node4, node5)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting nodes:\n" + + " <[\"NODE{id=1}\",\n" + + " \"NODE{id=2}\",\n" + + " \"NODE{id=3}\",\n" + + " \"NODE{id=4}\",\n" + + " \"NODE{id=5}\",\n" + + " \"NODE{id=6}\"]>\n" + + "to have a property \"key\" with a value type:\n" + + " \n" + + "but some nodes have a different property value type:\n" + + "\n" + + " 1) NODE{id=1}\n" + + " - Actual value type: STRING\n" + + " - Actual value: value-1\n" + + "\n" + + " 2) NODE{id=2}\n" + + " - Actual value type: LOCAL_DATE_TIME\n" + + " - Actual value: 2020-02-03T04:05:06.000000007\n" + + "\n" + + " 3) NODE{id=3}\n" + + " - Actual value type: INTEGER\n" + + " - Actual value: 1\n" + + "\n" + + " 4) NODE{id=4}\n" + + " - Actual value type: POINT\n" + + " - Actual value: Point{srid=1, x=22.29, y=56.35}\n" + + "\n" + + " 5) NODE{id=5}\n" + + " - Actual value type: DATE_TIME\n" + + " - Actual value: 2020-02-03T04:05:06.000000007+11:00[Australia/Sydney]" + ); + } + + } + +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldNodeHaveNoRelatedRelationshipsTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldNodeHaveNoRelatedRelationshipsTests.java new file mode 100644 index 0000000..69197c4 --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldNodeHaveNoRelatedRelationshipsTests.java @@ -0,0 +1,196 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author patouche - 13/02/2021 + */ +class ShouldNodeHaveNoRelatedRelationshipsTests { + + @Nested + class CreateIncomingTests { + + @Test + void should_generate_error_message() { + // GIVEN + final DbRelationship relationship1 = Drivers.relation().id(1).end(42).build(); + final DbRelationship relationship2 = Drivers.relation().id(2).end(42).build(); + final DbRelationship relationship3 = Drivers.relation().id(3).end(42).build(); + final List relationships = Randomize.listOf(relationship1, relationship2, relationship3); + final DbNode actual = Drivers.node().id(42).build(); + + // WHEN + final ErrorMessageFactory error = ShouldNodeHaveNoRelatedRelationships.createIncoming(actual, + relationships); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting node:\n" + + " \n" + + "to have no incoming relationships but found:\n" + + " <[RELATIONSHIP{id=1, type='null', start=null, end=42, properties={}},\n" + + " RELATIONSHIP{id=2, type='null', start=null, end=42, properties={}},\n" + + " RELATIONSHIP{id=3, type='null', start=null, end=42, properties={}}]>" + ); + } + + } + + @Nested + class CreateOutgoingTests { + + @Test + void should_generate_error_message() { + // GIVEN + final DbRelationship relationship1 = Drivers.relation().id(1).start(42).build(); + final DbRelationship relationship2 = Drivers.relation().id(2).start(42).build(); + final DbRelationship relationship3 = Drivers.relation().id(3).start(42).build(); + final List relationships = Randomize.listOf(relationship1, relationship2, relationship3); + final DbNode actual = Drivers.node().id(42).build(); + + // WHEN + final ErrorMessageFactory error = ShouldNodeHaveNoRelatedRelationships.createOutgoing(actual, + relationships); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting node:\n" + + " \n" + + "to have no outgoing relationships but found:\n" + + " <[RELATIONSHIP{id=1, type='null', start=42, end=null, properties={}},\n" + + " RELATIONSHIP{id=2, type='null', start=42, end=null, properties={}},\n" + + " RELATIONSHIP{id=3, type='null', start=42, end=null, properties={}}]>" + ); + } + + } + + @Nested + class IncomingElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final DbRelationship relationship1 = Drivers.relation().id(1).end(22).build(); + final DbRelationship relationship2 = Drivers.relation().id(2).end(42).build(); + final DbRelationship relationship3 = Drivers.relation().id(3).end(69).build(); + final List relationships = Randomize.listOf(relationship1, relationship2, relationship3); + final DbNode node1 = Drivers.node().id(22).build(); + final DbNode node2 = Drivers.node().id(29).build(); + final DbNode node3 = Drivers.node().id(35).build(); + final DbNode node4 = Drivers.node().id(42).build(); + final DbNode node5 = Drivers.node().id(56).build(); + final DbNode node6 = Drivers.node().id(69).build(); + final List actual = Randomize.listOf(node1, node2, node3, node4, node5, node6); + + // WHEN + final ErrorMessageFactory error = ShouldNodeHaveNoRelatedRelationships + .incomingElements(actual, relationships) + .notSatisfies(Randomize.listOf(node1, node4, node6)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting nodes:\n" + + " <[\"NODE{id=22}\",\n" + + " \"NODE{id=29}\",\n" + + " \"NODE{id=35}\",\n" + + " \"NODE{id=42}\",\n" + + " \"NODE{id=56}\",\n" + + " \"NODE{id=69}\"]>\n" + + "to have no incoming relationships but found:\n" + + " <[\"RELATIONSHIP{id=1}\", \"RELATIONSHIP{id=2}\", \"RELATIONSHIP{id=3}\"]>\n" + + "which are incoming relationships to nodes:\n" + + "\n" + + " 1) NODE{id=22}\n" + + " - Incoming relationships:: [RELATIONSHIP{id=1, type='null', start=null, end=22, " + + "properties={}}]\n" + + "\n" + + " 2) NODE{id=42}\n" + + " - Incoming relationships:: [RELATIONSHIP{id=2, type='null', start=null, end=42, " + + "properties={}}]\n" + + "\n" + + " 3) NODE{id=69}\n" + + " - Incoming relationships:: [RELATIONSHIP{id=3, type='null', start=null, end=69, " + + "properties={}}]" + ); + } + } + + @Nested + class OutgoingElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final DbRelationship relationship1 = Drivers.relation().id(1).start(22).build(); + final DbRelationship relationship2 = Drivers.relation().id(2).start(42).build(); + final DbRelationship relationship3 = Drivers.relation().id(3).start(69).build(); + final List relationships = Randomize.listOf(relationship1, relationship2, relationship3); + final DbNode node1 = Drivers.node().id(22).build(); + final DbNode node2 = Drivers.node().id(29).build(); + final DbNode node3 = Drivers.node().id(35).build(); + final DbNode node4 = Drivers.node().id(42).build(); + final DbNode node5 = Drivers.node().id(56).build(); + final DbNode node6 = Drivers.node().id(69).build(); + final List actual = Randomize.listOf(node1, node2, node3, node4, node5, node6); + + // WHEN + final ErrorMessageFactory error = ShouldNodeHaveNoRelatedRelationships + .outgoingElements(actual, relationships) + .notSatisfies(Randomize.listOf(node1, node4, node6)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting nodes:\n" + + " <[\"NODE{id=22}\",\n" + + " \"NODE{id=29}\",\n" + + " \"NODE{id=35}\",\n" + + " \"NODE{id=42}\",\n" + + " \"NODE{id=56}\",\n" + + " \"NODE{id=69}\"]>\n" + + "to have no outgoing relationships but found:\n" + + " <[\"RELATIONSHIP{id=1}\", \"RELATIONSHIP{id=2}\", \"RELATIONSHIP{id=3}\"]>\n" + + "which are outgoing relationships to nodes:\n" + + "\n" + + " 1) NODE{id=22}\n" + + " - Outgoing relationships:: [RELATIONSHIP{id=1, type='null', start=22, end=null, " + + "properties={}}]\n" + + "\n" + + " 2) NODE{id=42}\n" + + " - Outgoing relationships:: [RELATIONSHIP{id=2, type='null', start=42, end=null, " + + "properties={}}]\n" + + "\n" + + " 3) NODE{id=69}\n" + + " - Outgoing relationships:: [RELATIONSHIP{id=3, type='null', start=69, end=null, " + + "properties={}}]" + ); + } + } + +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldPropertyMatchTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldPropertyMatchTests.java new file mode 100644 index 0000000..d34a81f --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldPropertyMatchTests.java @@ -0,0 +1,91 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.testing.Samples; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Patrick Allain - 10/02/2021 + */ +class ShouldPropertyMatchTests { + + @Nested + class CreateTests { + + @Test + void should_generate_error_message() { + // GIVEN + final Nodes.DbNode actual = Drivers.node().id(2).property("key", Samples.LOCAL_DATE_TIME).build(); + + // WHEN + final ErrorMessageFactory error = ShouldPropertyMatch.create(actual, "key"); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting NODE{id=2} to have property:\n" + + " <\"key\">\n" + + "matching the provided condition for its value:\n" + + " <2020-02-03T04:05:06.000000007 (java.time.LocalDateTime)>\n" + + "but this value of type LOCAL_DATE_TIME did not" + ); + } + } + + @Nested + class ElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final Nodes.DbNode node1 = Drivers.node().id(1).property("key", "value-1").build(); + final Nodes.DbNode node2 = Drivers.node().id(2).property("key", Samples.LOCAL_DATE_TIME).build(); + final Nodes.DbNode node3 = Drivers.node().id(3).property("key", 1).build(); + final List actual = Randomize.listOf(node1, node2, node3); + + // WHEN + final ErrorMessageFactory error = ShouldPropertyMatch + .elements(actual, "key") + .notSatisfies(Randomize.listOf(node1, node2)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting nodes:\n" + + " <[\"NODE{id=1}\", \"NODE{id=2}\", \"NODE{id=3}\"]>\n" + + "to have a for the property \"key\" matching the condition but nodes:\n" + + " <[\"NODE{id=1}\", \"NODE{id=2}\"]>\n" + + "did not:\n" + + "\n" + + " 1) NODE{id=1}\n" + + " - Actual property value: value-1\n" + + " - Actual property type: STRING\n" + + "\n" + + " 2) NODE{id=2}\n" + + " - Actual property value: 2020-02-03T04:05:06.000000007\n" + + " - Actual property type: LOCAL_DATE_TIME" + ); + } + + } +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/error/ShouldRelationshipHaveTypeTests.java b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldRelationshipHaveTypeTests.java new file mode 100644 index 0000000..9df521d --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/error/ShouldRelationshipHaveTypeTests.java @@ -0,0 +1,106 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.error; + +import org.assertj.core.error.ErrorMessageFactory; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Relationships; +import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Patrick Allain - 25/11/2020 + */ +class ShouldRelationshipHaveTypeTests { + + @Nested + class CreateTests { + + @Test + void should_generate_error_message() { + // GIVEN + final String expectedType = "TYPE"; + final DbRelationship relationship = Drivers.relation("BAD_TYPE").id(2).build(); + + // WHEN + final ShouldRelationshipHaveType error = ShouldRelationshipHaveType.create(relationship, expectedType); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting relationship:\n" + + " \n" + + "to have type:\n" + + " <\"TYPE\">\n" + + "but actual type is:\n" + + " <\"BAD_TYPE\">" + ); + + } + } + + @Nested + class ElementsTests { + + @Test + void should_generate_an_aggregate_error_message() { + // GIVEN + final String expectedType = "TYPE"; + final DbRelationship relationship1 = Drivers.relation("TYPE").id(1).build(); + final DbRelationship relationship2 = Drivers.relation("OTHER_TYPE_1").id(2).build(); + final DbRelationship relationship3 = Drivers.relation("TYPE").id(3).build(); + final DbRelationship relationship4 = Drivers.relation("OTHER_TYPE_2").id(4).build(); + final DbRelationship relationship5 = Drivers.relation("OTHER_TYPE_3").id(5).build(); + final DbRelationship relationship6 = Drivers.relation("TYPE").id(6).build(); + final List relationships = Randomize + .listOf(relationship1, relationship2, relationship3, relationship4, relationship5, relationship6); + + // WHEN + final ErrorMessageFactory error = ShouldRelationshipHaveType + .elements(relationships, expectedType) + .notSatisfies(Randomize.listOf(relationship2, relationship4, relationship5)); + + // THEN + assertThat(error.create()).isEqualToNormalizingNewlines( + "\n" + + "Expecting relationships:\n" + + " <[\"RELATIONSHIP{id=1}\",\n" + + " \"RELATIONSHIP{id=2}\",\n" + + " \"RELATIONSHIP{id=3}\",\n" + + " \"RELATIONSHIP{id=4}\",\n" + + " \"RELATIONSHIP{id=5}\",\n" + + " \"RELATIONSHIP{id=6}\"]>\n" + + "to have type:\n" + + " <\"TYPE\">\n" + + "but found other types for some relationships:\n" + + "\n" + + " 1) RELATIONSHIP{id=2}\n" + + " - Actual type: OTHER_TYPE_1\n" + + "\n" + + " 2) RELATIONSHIP{id=4}\n" + + " - Actual type: OTHER_TYPE_2\n" + + "\n" + + " 3) RELATIONSHIP{id=5}\n" + + " - Actual type: OTHER_TYPE_3" + ); + + } + } +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/integrations/ParisIntegrationTests.java b/src/test/java/org/assertj/neo4j/api/beta/integrations/ParisIntegrationTests.java index f21212f..4d6cb55 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/integrations/ParisIntegrationTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/integrations/ParisIntegrationTests.java @@ -27,7 +27,7 @@ /** * https://insights.stackoverflow.com/survey/2020#correlated-technologies * - * @author patouche - 5/26/20. + * @author Patrick Allain - 5/26/20. */ @Testcontainers @IntegrationTests.ToBeImplemented diff --git a/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleNodesIntegrationTests.java b/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleNodesIntegrationTests.java index c9b7f2a..fd9427a 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleNodesIntegrationTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleNodesIntegrationTests.java @@ -29,9 +29,7 @@ import java.util.Objects; /** - * https://insights.stackoverflow.com/survey/2020#correlated-technologies - * - * @author patouche - 5/26/20. + * @author Patrick Allain - 5/26/20. */ @Tag(TestTags.INTEGRATION) class SampleNodesIntegrationTests { @@ -46,7 +44,7 @@ public WithIdTests() { @Test public void contains() { - final Nodes nodes = new Nodes(driver, "Language"); + final Nodes nodes = Nodes.of(driver, "Language"); DriverAssertions.assertThat(nodes) .contains(Drivers.node().id(6).label("Language").property("name", "Scala").build()); } @@ -64,26 +62,26 @@ public ShouldFailedTests() { @Test void haveLabels() { - final Nodes nodes = new Nodes(driver, "Language"); + final Nodes nodes = Nodes.of(driver, "Language"); DriverAssertions.assertThat(nodes).haveLabels("OtherLabel", "AnotherLabel"); } @Test void haveSize() { - final Nodes nodes = new Nodes(driver, "Language"); + final Nodes nodes = Nodes.of(driver, "Language"); DriverAssertions.assertThat(nodes).hasSize(42); } @Test void havePropertyKeys() { - final Nodes nodes = new Nodes(driver, "Repo"); + final Nodes nodes = Nodes.of(driver, "Repo"); DriverAssertions.assertThat(nodes) .havePropertyKeys("prop_1", "prop_2", "prop_3", "prop_4"); } @Test void havePropertyOfType() { - final Nodes nodes = new Nodes(driver, "Repo"); + final Nodes nodes = Nodes.of(driver, "Repo"); DriverAssertions.assertThat(nodes) .havePropertyOfType("name", ValueType.DATE_TIME) .havePropertyOfType("creation_date", ValueType.DURATION) @@ -93,7 +91,7 @@ void havePropertyOfType() { @Test void haveProperty() { - final Nodes nodes = new Nodes(driver, "Repo"); + final Nodes nodes = Nodes.of(driver, "Repo"); DriverAssertions.assertThat(nodes) .haveProperty("name", "value"); } @@ -109,7 +107,7 @@ public ShouldSucceedTests() { @Test void full() { - final Nodes nodes = new Nodes(driver, "Repo"); + final Nodes nodes = Nodes.of(driver, "Repo"); //@formatter:off DriverAssertions.assertThat(nodes) .hasSize(12) @@ -134,7 +132,7 @@ void full() { @Test void ignoringIds() { - final Nodes nodes = new Nodes(driver, "Language"); + final Nodes nodes = Nodes.of(driver, "Language"); DriverAssertions.assertThat(nodes) .ignoringIds() .contains(Drivers.node().label("Language").property("name", "Scala").build()); @@ -142,20 +140,20 @@ void ignoringIds() { @Test void haveLabels() { - final Nodes nodes = new Nodes(driver, "Language"); + final Nodes nodes = Nodes.of(driver, "Language"); DriverAssertions.assertThat(nodes).haveLabels("Language"); } @Test void havePropertyKeys() { - final Nodes nodes = new Nodes(driver, "Repo"); + final Nodes nodes = Nodes.of(driver, "Repo"); DriverAssertions.assertThat(nodes) .havePropertyKeys("name", "owner", "url", "creation_date"); } @Test void havePropertyOfType() { - final Nodes nodes = new Nodes(driver, "Repo"); + final Nodes nodes = Nodes.of(driver, "Repo"); DriverAssertions.assertThat(nodes) .havePropertyOfType("name", ValueType.STRING) .havePropertyOfType("creation_date", ValueType.LOCAL_DATE_TIME) @@ -163,25 +161,74 @@ void havePropertyOfType() { } @Test - void haveListPropertyContainingType() { - final Nodes nodes = new Nodes(driver, "Repo"); + void haveListPropertyOfType() { + final Nodes nodes = Nodes.of(driver, "Repo"); DriverAssertions.assertThat(nodes) .haveListPropertyOfType("active_branches", ValueType.STRING); } @Test void haveProperty() { - final Nodes nodes = new Nodes(driver, "Repo"); + final Nodes nodes = Nodes.of(driver, "Repo"); DriverAssertions.assertThat(nodes) - .haveProperty("name", "value"); + .filteredOnPropertyValue("name", "ktor") + .haveProperty("owner", "ktorio"); } @Test void filteredOn() { - final Nodes nodes = new Nodes(driver, "Repo"); + final Nodes nodes = Nodes.of(driver, "Repo"); DriverAssertions.assertThat(nodes) .filteredOn(n -> Objects.equals(n.getPropertyValue("owner"), "pallets")) .hasSize(2); } + + @Test + void filteredOnPropertyExists() { + final Nodes nodes = Nodes.of(driver, "Repo"); + DriverAssertions.assertThat(nodes) + .hasSize(4) + .filteredOnPropertyExists("onboarding_duration") + .havePropertyOfType("onboarding_duration", ValueType.DURATION) + .hasSize(10); + } + + @Test + void filteredOnPropertyValue() { + final Nodes nodes = Nodes.of(driver, "Repo"); + DriverAssertions.assertThat(nodes) + .filteredOnPropertyValue("owner", "pallets") + .hasSize(2); + } + + @Test + void haveNoIncomingRelationships() { + final Nodes nodes = Nodes.of(driver, "Repo"); + DriverAssertions.assertThat(nodes) + .filteredOnPropertyValue("name", "neo4j") + .haveNoIncomingRelationships() + .hasSize(2); + } + + @Test + void incomingRelationships() { + final Nodes nodes = Nodes.of(driver, "Language"); + DriverAssertions.assertThat(nodes) + .filteredOnPropertyValue("name", "Java") + .incomingRelationships("KNOWS", "WRITTEN") + .hasSize(8) + .toParentAssert() + .incomingRelationships("WRITTEN") + .hasSize(3); + } + + @Test + void outgoingRelationships() { + final Nodes nodes = Nodes.of(driver, "Repo"); + DriverAssertions.assertThat(nodes) + .filteredOnPropertyValue("name", "neo4j") + .outgoingRelationships("WRITTEN") + .hasSize(2); + } } } diff --git a/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleRelationshipsIntegrationTests.java b/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleRelationshipsIntegrationTests.java index 95b0334..884d83a 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleRelationshipsIntegrationTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleRelationshipsIntegrationTests.java @@ -22,7 +22,7 @@ /** * https://insights.stackoverflow.com/survey/2020#correlated-technologies * - * @author patouche - 5/26/20. + * @author Patrick Allain - 5/26/20. */ class SampleRelationshipsIntegrationTests extends IntegrationTests.DatasetTests { @@ -32,7 +32,7 @@ public SampleRelationshipsIntegrationTests() { @Test public void full() { - final Relationships relationships = new Relationships(driver, "KNOWS"); + final Relationships relationships = Relationships.of(driver, "KNOWS"); DriverAssertions.assertThat(relationships) .hasSize(18) .haveType("KNOWS") @@ -43,21 +43,21 @@ public void full() { @Test public void ignoringIds() { - final Relationships relationships = new Relationships(driver, "KNOWS"); + final Relationships relationships = Relationships.of(driver, "KNOWS"); DriverAssertions.assertThat(relationships) .ignoringIds() - .contains(relationships.create().property("level", 5).build()); + .contains(Drivers.relation("KNOWS").property("level", 5).build()); } @Test public void haveType() { - final Relationships relationships = new Relationships(driver, "KNOWS"); + final Relationships relationships = Relationships.of(driver, "KNOWS"); DriverAssertions.assertThat(relationships).haveType("KNOWS"); } @Test public void havePropertyKeys() { - final Relationships relationships = new Relationships(driver, "KNOWS"); + final Relationships relationships = Relationships.of(driver, "KNOWS"); DriverAssertions.assertThat(relationships).havePropertyKeys("level"); } diff --git a/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleRequestIntegrationTests.java b/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleRequestIntegrationTests.java index bb08e45..da9d219 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleRequestIntegrationTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleRequestIntegrationTests.java @@ -24,7 +24,7 @@ /** * https://insights.stackoverflow.com/survey/2020#correlated-technologies * - * @author patouche - 5/26/20. + * @author Patrick Allain - 5/26/20. */ @Testcontainers @Disabled("TO BE IMPLEMENTED") diff --git a/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleResultIntegrationTests.java b/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleResultIntegrationTests.java index 19b8a60..ca286ca 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleResultIntegrationTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/integrations/SampleResultIntegrationTests.java @@ -28,7 +28,7 @@ import org.neo4j.driver.Values; /** - * @author patouche - 26/01/2021 + * @author Patrick Allain - 26/01/2021 */ class SampleResultIntegrationTests extends IntegrationTests.DatasetTests { diff --git a/src/test/java/org/assertj/neo4j/api/beta/integrations/TypesTests.java b/src/test/java/org/assertj/neo4j/api/beta/integrations/TypesTests.java index b64ef9a..41791a3 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/integrations/TypesTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/integrations/TypesTests.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test; /** - * @author patouche - 28/12/2020 + * @author Patrick Allain - 28/12/2020 */ @DisplayName("Neo4j Property Types") @Tag(TestTags.INTEGRATION) @@ -40,7 +40,7 @@ public PropertyTypeTests() { @Test void should_property_have_the_right_type() { - Nodes nodes = new Nodes(driver, "Types"); + Nodes nodes = Nodes.of(driver, "Types"); DriverAssertions.assertThat(nodes) // Simple property types .havePropertyOfType("type_boolean", ValueType.BOOLEAN) diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/IntegrationTests.java b/src/test/java/org/assertj/neo4j/api/beta/testing/IntegrationTests.java index 56c9d8a..f59847b 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/testing/IntegrationTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/IntegrationTests.java @@ -30,7 +30,7 @@ /** * Integration tests support. * - * @author patouche - 26/12/2020 + * @author Patrick Allain - 26/12/2020 */ public interface IntegrationTests { diff --git a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldAllHaveProperty.java b/src/test/java/org/assertj/neo4j/api/beta/testing/Loaders.java similarity index 54% rename from src/main/java/org/assertj/neo4j/api/beta/error/ShouldAllHaveProperty.java rename to src/test/java/org/assertj/neo4j/api/beta/testing/Loaders.java index 6ef5f59..153e1c9 100644 --- a/src/main/java/org/assertj/neo4j/api/beta/error/ShouldAllHaveProperty.java +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/Loaders.java @@ -10,25 +10,21 @@ * * Copyright 2013-2020 the original author or authors. */ -package org.assertj.neo4j.api.beta.error; +package org.assertj.neo4j.api.beta.testing; -import org.assertj.core.error.BasicErrorMessageFactory; -import org.neo4j.driver.types.Node; - -import java.util.stream.Stream; +import org.assertj.neo4j.api.beta.testing.builders.RelationshipsLoaderBuilder; +import org.assertj.neo4j.api.beta.type.Relationships; /** - * @author patouche - 29/09/2020 + * @author patouche - 12/02/2021 */ -@Deprecated -public class ShouldAllHaveProperty extends BasicErrorMessageFactory { +public interface Loaders { - private ShouldAllHaveProperty(final String key, final Stream nodes) { - super(""); + static RelationshipsLoaderBuilder relationships() { + return new RelationshipsLoaderBuilder(); } - public static ShouldAllHaveProperty create(final String key, final Stream nodes) { - return new ShouldAllHaveProperty(key, nodes); + static Relationships relationships(Relationships.DbRelationship... entities) { + return relationships().entities(entities).build(); } - } diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/MockResult.java b/src/test/java/org/assertj/neo4j/api/beta/testing/MockResult.java index 495fc76..88f4298 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/testing/MockResult.java +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/MockResult.java @@ -24,7 +24,7 @@ import java.util.stream.Stream; /** - * @author patouche - 11/11/2020 + * @author Patrick Allain - 11/11/2020 */ public class MockResult implements Result { diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/Mocks.java b/src/test/java/org/assertj/neo4j/api/beta/testing/Mocks.java index 8db486a..2bf9168 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/testing/Mocks.java +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/Mocks.java @@ -12,26 +12,30 @@ */ package org.assertj.neo4j.api.beta.testing; -import org.assertj.neo4j.api.beta.type.Relationships; +import org.assertj.neo4j.api.beta.testing.builders.NodeBuilder; +import org.assertj.neo4j.api.beta.testing.builders.RecordBuilder; +import org.assertj.neo4j.api.beta.testing.builders.RelationshipBuilder; +import org.assertj.neo4j.api.beta.testing.builders.ResultBuilder; /** - * @author patouche - 11/11/2020 + * @author Patrick Allain - 11/11/2020 */ -public final class Mocks { +public interface Mocks { - public static ResultBuilder result() { + static ResultBuilder result() { return new ResultBuilder(); } - public static RecordBuilder record() { + static RecordBuilder record() { return new RecordBuilder(); } - public static NodeBuilder node() { + static NodeBuilder node() { return new NodeBuilder(); } - public static RelationshipBuilder relation(final String type) { + static RelationshipBuilder relation(final String type) { return new RelationshipBuilder(type); } + } diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/Neo4JDataSet.java b/src/test/java/org/assertj/neo4j/api/beta/testing/Neo4JDataSet.java index 516ad32..b9e1957 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/testing/Neo4JDataSet.java +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/Neo4JDataSet.java @@ -33,7 +33,7 @@ /** * For org.assertj.neo4j.api.beta.testing purpose... * - * @author patouche + * @author Patrick Allain */ public final class Neo4JDataSet { diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/Randomize.java b/src/test/java/org/assertj/neo4j/api/beta/testing/Randomize.java new file mode 100644 index 0000000..1ba296c --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/Randomize.java @@ -0,0 +1,35 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.testing; + +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Patrick Allain - 07/02/2021 + */ +public class Randomize { + + public static final SecureRandom SECURE_RANDOM = new SecureRandom(new SecureRandom().generateSeed(128)); + + public static Comparator comparator() { + return (o1, o2) -> SECURE_RANDOM.nextInt(3) - 1; + } + + public static List listOf(T... items) { + return Arrays.stream(items).sorted(Randomize.comparator()).collect(Collectors.toList()); + } +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/Samples.java b/src/test/java/org/assertj/neo4j/api/beta/testing/Samples.java new file mode 100644 index 0000000..c0e4098 --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/Samples.java @@ -0,0 +1,39 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.testing; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.List; + +/** + * @author Patrick Allain - 10/02/2021 + */ +public interface Samples { + + ZonedDateTime ZONED_DATE_TIME = ZonedDateTime + .of(2020, 2, 3, 4, 5, 6, 7, ZoneId.of("Australia/Sydney")); + + LocalDateTime LOCAL_DATE_TIME = ZONED_DATE_TIME.toLocalDateTime(); + LocalDate LOCAL_DATE = ZONED_DATE_TIME.toLocalDate(); + OffsetTime TIME = ZONED_DATE_TIME.toLocalTime().atOffset(ZoneOffset.UTC); + LocalTime LOCAL_TIME = ZONED_DATE_TIME.toLocalTime(); + + List LABELS = Randomize.listOf("LBL_1", "LBL_2", "LBL_3", "LBL_4"); + +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/TestTags.java b/src/test/java/org/assertj/neo4j/api/beta/testing/TestTags.java index cfd50a0..b6ca74d 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/testing/TestTags.java +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/TestTags.java @@ -13,7 +13,7 @@ package org.assertj.neo4j.api.beta.testing; /** - * @author patouche - 28/12/2020 + * @author Patrick Allain - 28/12/2020 */ public interface TestTags { diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/NodeBuilder.java b/src/test/java/org/assertj/neo4j/api/beta/testing/builders/NodeBuilder.java similarity index 94% rename from src/test/java/org/assertj/neo4j/api/beta/testing/NodeBuilder.java rename to src/test/java/org/assertj/neo4j/api/beta/testing/builders/NodeBuilder.java index ba5f478..eb927af 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/testing/NodeBuilder.java +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/builders/NodeBuilder.java @@ -10,7 +10,7 @@ * * Copyright 2013-2020 the original author or authors. */ -package org.assertj.neo4j.api.beta.testing; +package org.assertj.neo4j.api.beta.testing.builders; import org.neo4j.driver.Value; import org.neo4j.driver.internal.InternalNode; @@ -22,7 +22,7 @@ import java.util.Map; /** - * @author patouche - 11/11/2020 + * @author Patrick Allain - 11/11/2020 */ public class NodeBuilder { diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/RecordBuilder.java b/src/test/java/org/assertj/neo4j/api/beta/testing/builders/RecordBuilder.java similarity index 92% rename from src/test/java/org/assertj/neo4j/api/beta/testing/RecordBuilder.java rename to src/test/java/org/assertj/neo4j/api/beta/testing/builders/RecordBuilder.java index 91f72b3..5d953d7 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/testing/RecordBuilder.java +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/builders/RecordBuilder.java @@ -10,7 +10,7 @@ * * Copyright 2013-2020 the original author or authors. */ -package org.assertj.neo4j.api.beta.testing; +package org.assertj.neo4j.api.beta.testing.builders; import org.neo4j.driver.Record; import org.neo4j.driver.Value; @@ -20,12 +20,11 @@ import org.neo4j.driver.types.Node; import org.neo4j.driver.types.Relationship; -import javax.management.relation.Relation; import java.util.ArrayList; import java.util.List; /** - * @author patouche - 11/11/2020 + * @author Patrick Allain - 11/11/2020 */ public class RecordBuilder { @@ -33,7 +32,7 @@ public class RecordBuilder { private final List values = new ArrayList<>(); - RecordBuilder() { + public RecordBuilder() { } public RecordBuilder key(String key) { diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/RelationshipBuilder.java b/src/test/java/org/assertj/neo4j/api/beta/testing/builders/RelationshipBuilder.java similarity index 94% rename from src/test/java/org/assertj/neo4j/api/beta/testing/RelationshipBuilder.java rename to src/test/java/org/assertj/neo4j/api/beta/testing/builders/RelationshipBuilder.java index 9599621..44578de 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/testing/RelationshipBuilder.java +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/builders/RelationshipBuilder.java @@ -10,7 +10,7 @@ * * Copyright 2013-2020 the original author or authors. */ -package org.assertj.neo4j.api.beta.testing; +package org.assertj.neo4j.api.beta.testing.builders; import org.neo4j.driver.Value; import org.neo4j.driver.internal.InternalRelationship; @@ -20,7 +20,7 @@ import java.util.Map; /** - * @author patouche - 05/12/2020 + * @author Patrick Allain - 05/12/2020 */ public class RelationshipBuilder { diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/builders/RelationshipsLoaderBuilder.java b/src/test/java/org/assertj/neo4j/api/beta/testing/builders/RelationshipsLoaderBuilder.java new file mode 100644 index 0000000..2cd9277 --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/builders/RelationshipsLoaderBuilder.java @@ -0,0 +1,66 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.testing.builders; + +import org.assertj.neo4j.api.beta.type.DataLoader; +import org.assertj.neo4j.api.beta.type.LoaderFactory; +import org.assertj.neo4j.api.beta.type.Relationships; +import org.neo4j.driver.Query; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author patouche - 12/02/2021 + */ +public class RelationshipsLoaderBuilder { + private DataLoader factoryResult; + private List entities = new ArrayList<>(); + private Query query; + + public RelationshipsLoaderBuilder factoryResult(DataLoader factoryResult) { + this.factoryResult = factoryResult; + return this; + } + + public RelationshipsLoaderBuilder entities(Relationships.DbRelationship... entities) { + this.entities = Arrays.asList(entities); + return this; + } + + public RelationshipsLoaderBuilder query(Query query) { + this.query = query; + return this; + } + + public Relationships build() { + return new Relationships() { + + @Override + public Query query() { + return query; + } + + @Override + public List load() { + return entities; + } + + @Override + public > D chain(final LoaderFactory factory) { + return (D) factory; + } + }; + } +} diff --git a/src/test/java/org/assertj/neo4j/api/beta/testing/ResultBuilder.java b/src/test/java/org/assertj/neo4j/api/beta/testing/builders/ResultBuilder.java similarity index 89% rename from src/test/java/org/assertj/neo4j/api/beta/testing/ResultBuilder.java rename to src/test/java/org/assertj/neo4j/api/beta/testing/builders/ResultBuilder.java index bfc3d93..3368c12 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/testing/ResultBuilder.java +++ b/src/test/java/org/assertj/neo4j/api/beta/testing/builders/ResultBuilder.java @@ -10,8 +10,9 @@ * * Copyright 2013-2020 the original author or authors. */ -package org.assertj.neo4j.api.beta.testing; +package org.assertj.neo4j.api.beta.testing.builders; +import org.assertj.neo4j.api.beta.testing.MockResult; import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.summary.ResultSummary; @@ -20,7 +21,7 @@ import java.util.List; /** - * @author patouche - 11/11/2020 + * @author Patrick Allain - 11/11/2020 */ public class ResultBuilder { diff --git a/src/test/java/org/assertj/neo4j/api/beta/type/DbEntityTests.java b/src/test/java/org/assertj/neo4j/api/beta/type/DbEntityTests.java index d13e112..574da4a 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/type/DbEntityTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/type/DbEntityTests.java @@ -15,6 +15,7 @@ import org.assertj.core.api.Assertions; import org.assertj.core.api.SoftAssertions; import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension; +import org.assertj.neo4j.api.beta.testing.Samples; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -33,23 +34,20 @@ import java.util.stream.IntStream; /** - * @author patouche - 27/12/2020 + * @author Patrick Allain - 27/12/2020 */ class DbEntityTests { - private static final ZonedDateTime SAMPLE_TIME = ZonedDateTime.of(2020, 2, 3, 4, 5, 6, 7, ZoneId.of("Australia" - + "/Sydney")); - public static final Nodes.DbNode SAMPLE_NODE = Drivers.node() .property("boolean", true) .property("string", "str-value") .property("long", 42) .property("double", 4.2) - .property("date", SAMPLE_TIME.toLocalDate()) - .property("datetime", SAMPLE_TIME) - .property("localdatetime", SAMPLE_TIME.toLocalDateTime()) - .property("time", SAMPLE_TIME.toLocalTime().atOffset(ZoneOffset.UTC)) - .property("localtime", SAMPLE_TIME.toLocalTime()) + .property("date", Samples.LOCAL_DATE) + .property("datetime", Samples.ZONED_DATE_TIME) + .property("localdatetime", Samples.LOCAL_DATE_TIME) + .property("time", Samples.TIME) + .property("localtime", Samples.LOCAL_TIME) .property("duration", Duration.ofDays(3)) .property("point_2d", Values.point(0, 42L, 12L).asObject()) .property("point_3d", Values.point(0, 42L, 12L, 69L).asObject()) @@ -75,7 +73,7 @@ private static List intList(final IntFunction func) { } private static List timeList(final Function func) { - return IntStream.range(0, 10).mapToObj(SAMPLE_TIME::plusHours).map(func).collect(Collectors.toList()); + return IntStream.range(0, 10).mapToObj(Samples.ZONED_DATE_TIME::plusHours).map(func).collect(Collectors.toList()); } @Nested @@ -118,11 +116,11 @@ void should_return_the_object_for_simple_type(final SoftAssertions softly) { softly.assertThat(SAMPLE_NODE.getPropertyValue("string")).isEqualTo("str-value"); softly.assertThat(SAMPLE_NODE.getPropertyValue("long")).isEqualTo(42L); softly.assertThat(SAMPLE_NODE.getPropertyValue("double")).isEqualTo(4.2); - softly.assertThat(SAMPLE_NODE.getPropertyValue("date")).isEqualTo(SAMPLE_TIME.toLocalDate()); - softly.assertThat(SAMPLE_NODE.getPropertyValue("datetime")).isEqualTo(SAMPLE_TIME); - softly.assertThat(SAMPLE_NODE.getPropertyValue("localdatetime")).isEqualTo(SAMPLE_TIME.toLocalDateTime()); - softly.assertThat(SAMPLE_NODE.getPropertyValue("time")).isEqualTo(SAMPLE_TIME.toLocalTime().atOffset(ZoneOffset.UTC)); - softly.assertThat(SAMPLE_NODE.getPropertyValue("localtime")).isEqualTo(SAMPLE_TIME.toLocalTime()); + softly.assertThat(SAMPLE_NODE.getPropertyValue("date")).isEqualTo(Samples.LOCAL_DATE); + softly.assertThat(SAMPLE_NODE.getPropertyValue("datetime")).isEqualTo(Samples.ZONED_DATE_TIME); + softly.assertThat(SAMPLE_NODE.getPropertyValue("localdatetime")).isEqualTo(Samples.LOCAL_DATE_TIME); + softly.assertThat(SAMPLE_NODE.getPropertyValue("time")).isEqualTo(Samples.TIME); + softly.assertThat(SAMPLE_NODE.getPropertyValue("localtime")).isEqualTo(Samples.LOCAL_TIME); softly.assertThat(SAMPLE_NODE.getPropertyValue("duration")).isEqualTo(Values.value(Duration.ofDays(3)).asObject()); softly.assertThat(SAMPLE_NODE.getPropertyValue("point_2d")).isEqualTo(Values.point(0, 42, 12).asPoint()); softly.assertThat(SAMPLE_NODE.getPropertyValue("point_3d")).isEqualTo(Values.point(0, 42, 12, 69).asPoint()); diff --git a/src/test/java/org/assertj/neo4j/api/beta/type/NodesTests.java b/src/test/java/org/assertj/neo4j/api/beta/type/NodesTests.java index 39ec7ad..f82804e 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/type/NodesTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/type/NodesTests.java @@ -19,11 +19,14 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.neo4j.driver.Driver; +import org.neo4j.driver.Query; +import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.Session; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.Values; +import java.util.Arrays; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -35,7 +38,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; /** - * @author patouche - 11/11/2020 + * @author Patrick Allain - 11/11/2020 */ @ExtendWith(MockitoExtension.class) class NodesTests { @@ -52,24 +55,22 @@ void tearDown() { } @Test - void load_whenNoLabels() { + void load_when_no_labels() { // GIVEN - final Nodes nodes = new Nodes(driver); - final Result result = Mocks.result() - .record(Mocks.record() + final Nodes nodes = Nodes.of(driver); + final List result = Arrays.asList( + Mocks.record() .key("key") .node(Mocks.node().labels("Sample").properties("prop-0", Values.value(true)).build()) - .build() - ) - .record(Mocks.record() + .build(), + Mocks.record() .key("key") .node(Mocks.node().id(1).labels("Sample").properties("prop-1", Values.value(false)).build()) .build() - ) - .build(); + ); doReturn(session).when(driver).session(); - doReturn(result).when(session).run(anyString(), any(TransactionConfig.class)); + doReturn(result).when(session).readTransaction(any(), any(TransactionConfig.class)); // WHEN final List dbNodes = nodes.load(); @@ -81,32 +82,32 @@ void load_whenNoLabels() { Drivers.node().id(0).label("Sample").property("prop-0", true).build(), Drivers.node().id(1).label("Sample").property("prop-1", false).build() ); + assertThat(nodes.query()).isEqualTo(new Query("MATCH (n ) RETURN n")); verify(driver).session(); - verify(session).run(eq("MATCH (n ) RETURN n"), any(TransactionConfig.class)); + verify(session).readTransaction(any(), any(TransactionConfig.class)); verify(session).close(); } @Test - void load_whenMultiLabels() { + void load_when_multi_labels() { // GIVEN - final Nodes nodes = new Nodes(driver, "Lbl1", "Lbl2"); - final Result result = Mocks.result() - .record(Mocks.record() + final Nodes nodes = Nodes.of(driver, "Lbl1", "Lbl2"); + final List result = Arrays.asList( + Mocks.record() .key("key") - .node(Mocks.node().id(0).labels("Lbl1").labels("Lbl2").properties("prop-0", Values.value(true)).build()) - .build() - ) - .record(Mocks.record() + .node(Mocks.node().id(0).labels("Lbl1").labels("Lbl2").properties("prop-0", + Values.value(true)).build()) + .build(), + Mocks.record() .key("key") .node(Mocks.node().id(1).labels("Lbl1").labels("Lbl2").properties("prop-1", Values.value(false)).build()) .build() - ) - .build(); + ); doReturn(session).when(driver).session(); - doReturn(result).when(session).run(anyString(), any(TransactionConfig.class)); + doReturn(result).when(session).readTransaction(any(), any(TransactionConfig.class)); // WHEN final List dbNodes = nodes.load(); @@ -115,12 +116,13 @@ void load_whenMultiLabels() { assertThat(dbNodes) .hasSize(2) .contains( - Drivers.node().id(0).label("Lbl1").label( "Lbl2").property("prop-0", true).build(), - Drivers.node().id(1).label("Lbl1").label( "Lbl2").property("prop-1", false).build() + Drivers.node().id(0).label("Lbl1").label("Lbl2").property("prop-0", true).build(), + Drivers.node().id(1).label("Lbl1").label("Lbl2").property("prop-1", false).build() ); + assertThat(nodes.query()).isEqualTo(new Query("MATCH (n :Lbl1:Lbl2) RETURN n")); verify(driver).session(); - verify(session).run(eq("MATCH (n :Lbl1:Lbl2) RETURN n"), any(TransactionConfig.class)); + verify(session).readTransaction(any(), any(TransactionConfig.class)); verify(session).close(); } diff --git a/src/test/java/org/assertj/neo4j/api/beta/type/RelationshipsTests.java b/src/test/java/org/assertj/neo4j/api/beta/type/RelationshipsTests.java index 5beb643..e4b1f2c 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/type/RelationshipsTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/type/RelationshipsTests.java @@ -19,11 +19,14 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.neo4j.driver.Driver; +import org.neo4j.driver.Query; +import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.Session; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.Values; +import java.util.Arrays; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -37,7 +40,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; /** - * @author patouche - 24/11/2020 + * @author Patrick Allain - 24/11/2020 */ @ExtendWith(MockitoExtension.class) class RelationshipsTests { @@ -56,19 +59,17 @@ void tearDown() { @Test void load() { // GIVEN - final Relationships relationships = new Relationships(driver, "KNOWS"); - final Result result; - result = Mocks.result() - .record(Mocks.record() + final Relationships relationships = Relationships.of(driver, "KNOWS"); + final List result = Arrays.asList( + Mocks.record() .key("key") .relation(Mocks.relation("SAMPLE") .id(1) .properties("prop-0", Values.value(true)) .build() ) - .build() - ) - .record(Mocks.record() + .build(), + Mocks.record() .key("key") .relation(Mocks.relation("SAMPLE") .id(2) @@ -76,11 +77,10 @@ void load() { .build() ) .build() - ) - .build(); + ); doReturn(session).when(driver).session(); - doReturn(result).when(session).run(anyString(), any(TransactionConfig.class)); + doReturn(result).when(session).readTransaction(any(), any(TransactionConfig.class)); // WHEN final List dbRelationships = relationships.load(); @@ -92,9 +92,10 @@ void load() { Drivers.relation("SAMPLE").id(1).property("prop-0", true).build(), Drivers.relation("SAMPLE").id(2).property("prop-1", false).build() ); + assertThat(relationships.query()).isEqualTo(new Query("MATCH ()-[r :KNOWS]->() RETURN r")); verify(driver).session(); - verify(session).run(eq("MATCH ()-[r:KNOWS]->() RETURN r"), any(TransactionConfig.class)); + verify(session).readTransaction(any(), any(TransactionConfig.class)); verify(session).close(); } diff --git a/src/test/java/org/assertj/neo4j/api/beta/util/ChecksTests.java b/src/test/java/org/assertj/neo4j/api/beta/util/ChecksTests.java index d3f7405..32ff3db 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/util/ChecksTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/util/ChecksTests.java @@ -1,3 +1,15 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ package org.assertj.neo4j.api.beta.util; import org.junit.jupiter.api.DisplayName; @@ -12,7 +24,7 @@ import static org.assertj.core.api.Assertions.catchThrowable; /** - * @author patouche - 28/01/2021 + * @author Patrick Allain - 28/01/2021 */ class ChecksTests { diff --git a/src/test/java/org/assertj/neo4j/api/beta/util/EntityUtilsTests.java b/src/test/java/org/assertj/neo4j/api/beta/util/EntityUtilsTests.java new file mode 100644 index 0000000..eab51a5 --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/util/EntityUtilsTests.java @@ -0,0 +1,206 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.util; + +import org.assertj.core.api.Assertions; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author patouche - 13/02/2021 + */ +class EntityUtilsTests { + + @Nested + class SortedTests { + + @Test + void should_sort_entities_by_ids() { + // GIVEN + final DbNode node1 = Drivers.node().id(11).build(); + final DbNode node2 = Drivers.node().id(16).build(); + final DbNode node3 = Drivers.node().id(42).build(); + final DbNode node4 = Drivers.node().id(64).build(); + final DbNode node5 = Drivers.node().id(69).build(); + final DbNode node6 = Drivers.node().id(98).build(); + final Iterable entities = Randomize.listOf(node1, node2, node3, node4, node5, node6); + + // WHEN + final List result = EntityUtils.sorted(entities); + + // THEN + assertThat(result).containsExactly(node1, node2, node3, node4, node5, node6); + } + + @Test + void should_support_null_ids() { + // GIVEN + final DbNode node1 = Drivers.node().id(11).build(); + final DbNode node2 = Drivers.node().build(); + final DbNode node3 = Drivers.node().id(42).build(); + final DbNode node4 = Drivers.node().build(); + final DbNode node5 = Drivers.node().id(69).build(); + final DbNode node6 = Drivers.node().id(98).build(); + final Iterable entities = Randomize.listOf(node1, node2, node3, node4, node5, node6); + + // WHEN + final List result = EntityUtils.sorted(entities); + + // THEN + assertThat(result) + .hasSize(6) + .containsSubsequence(node2, node1) + .containsSubsequence(node4, node1) + .containsSubsequence(node1, node3, node5, node6); + } + + } + + @Nested + class AreIncomingForNodeTests { + + @Test + void should_filter_only_incoming_relationships_of_node() { + // GIVEN + final DbNode node = Drivers.node().id(42).build(); + final DbRelationship relationship1 = Drivers.relation().id(1).end(22).build(); + final DbRelationship relationship2 = Drivers.relation().id(2).end(29).build(); + final DbRelationship relationship3 = Drivers.relation().id(3).end(35).build(); + final DbRelationship relationship4 = Drivers.relation().id(4).end(42).build(); + final DbRelationship relationship5 = Drivers.relation().id(5).end(56).build(); + final DbRelationship relationship6 = Drivers.relation().id(6).end(42).build(); + final List relationships = Randomize + .listOf(relationship1, relationship2, relationship3, relationship4, relationship5, relationship6); + + // WHEN + final List result = EntityUtils.areIncomingForNode(node, relationships); + + // THEN + assertThat(result).containsExactly(relationship4, relationship6); + } + } + + @Nested + class AreOutgoingForNodeTests { + + @Test + void should_filter_only_outgoing_relationships_of_node() { + // GIVEN + final DbNode node = Drivers.node().id(42).build(); + final DbRelationship relationship1 = Drivers.relation().id(1).start(22).build(); + final DbRelationship relationship2 = Drivers.relation().id(2).start(29).build(); + final DbRelationship relationship3 = Drivers.relation().id(3).start(35).build(); + final DbRelationship relationship4 = Drivers.relation().id(4).start(42).build(); + final DbRelationship relationship5 = Drivers.relation().id(5).start(56).build(); + final DbRelationship relationship6 = Drivers.relation().id(6).start(42).build(); + final List relationships = Randomize + .listOf(relationship1, relationship2, relationship3, relationship4, relationship5, relationship6); + + // WHEN + final List result = EntityUtils.areOutgoingForNode(node, relationships); + + // THEN + assertThat(result).containsExactly(relationship4, relationship6); + } + } + + @Nested + class HavingIncomingRelationshipsTests { + + @Test + void should_filter_only_node_with_incoming_relationships() { + // GIVEN + final DbNode node1 = Drivers.node().id(22).build(); + final DbNode node2 = Drivers.node().id(23).build(); + final DbNode node3 = Drivers.node().id(42).build(); + final DbNode node4 = Drivers.node().id(74).build(); + final DbNode node5 = Drivers.node().id(98).build(); + final List nodes = Randomize.listOf(node1, node2, node3, node4, node5); + + final DbRelationship relationship1 = Drivers.relation().id(1).end(22).build(); + final DbRelationship relationship2 = Drivers.relation().id(2).end(29).build(); + final DbRelationship relationship3 = Drivers.relation().id(3).end(35).build(); + final DbRelationship relationship4 = Drivers.relation().id(4).end(42).build(); + final DbRelationship relationship5 = Drivers.relation().id(5).end(56).build(); + final DbRelationship relationship6 = Drivers.relation().id(6).end(42).build(); + final List relationships = Randomize + .listOf(relationship1, relationship2, relationship3, relationship4, relationship5, relationship6); + + // WHEN + final List result = EntityUtils.havingIncomingRelationships(nodes, relationships); + + // THEN + assertThat(result).containsExactly(node1, node3); + } + } + + @Nested + class HavingOutgoingRelationshipsTests { + + @Test + void should_filter_only_node_with_outgoing_relationships() { + // GIVEN + final DbNode node1 = Drivers.node().id(22).build(); + final DbNode node2 = Drivers.node().id(23).build(); + final DbNode node3 = Drivers.node().id(42).build(); + final DbNode node4 = Drivers.node().id(74).build(); + final DbNode node5 = Drivers.node().id(98).build(); + final List nodes = Randomize.listOf(node1, node2, node3, node4, node5); + + final DbRelationship relationship1 = Drivers.relation().id(1).start(22).build(); + final DbRelationship relationship2 = Drivers.relation().id(2).start(29).build(); + final DbRelationship relationship3 = Drivers.relation().id(3).start(35).build(); + final DbRelationship relationship4 = Drivers.relation().id(4).start(42).build(); + final DbRelationship relationship5 = Drivers.relation().id(5).start(56).build(); + final DbRelationship relationship6 = Drivers.relation().id(6).start(42).build(); + final List relationships = Randomize + .listOf(relationship1, relationship2, relationship3, relationship4, relationship5, relationship6); + + // WHEN + final List result = EntityUtils.havingOutgoingRelationships(nodes, relationships); + + // THEN + assertThat(result).containsExactly(node1, node3); + } + } + + @Nested + class StartNodeIdsTests { + + @Test + void should_return_the_start_node_ids() { + + } + + } + + @Nested + class EndNodeIdsTests { + + @Test + void should_return_the_end_node_ids() { + + } + + } + +} + diff --git a/src/test/java/org/assertj/neo4j/api/beta/util/NodeLabelsTests.java b/src/test/java/org/assertj/neo4j/api/beta/util/NodeLabelsTests.java deleted file mode 100644 index 9f1035b..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/util/NodeLabelsTests.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.util; - -import org.assertj.neo4j.api.beta.error.Missing; -import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Nodes; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author patouche - 15/11/2020 - */ -class NodeLabelsTests { - - @Nested - @DisplayName("hasMissing") - class HasMissingTests { - - @Test - void should_return_false() { - // GIVEN - final List labels = Arrays.asList("LBL_1", "LBL_2", "LBL_3"); - final Nodes.DbNode entity = Drivers.node().id(1).label("LBL_1").label("LBL_2").label("LBL_3").build(); - - // WHEN - final boolean result = NodeLabels.hasLabels(entity, labels); - - // THEN - assertThat(result).isFalse(); - } - - @Test - void should_return_true() { - // GIVEN - final List labels = Arrays.asList("LBL_1", "LBL_2", "LBL_3"); - final Nodes.DbNode entity = Drivers.node().id(1).label("LBL_1").label("LBL_3").build(); - - // WHEN - final boolean result = NodeLabels.hasLabels(entity, labels); - - // THEN - assertThat(result).isTrue(); - } - - } - - @Nested - @DisplayName("haveMissing") - class HaveMissingTests { - - @Test - void should_return_false() { - // GIVEN - final List labels = Arrays.asList("LBL_1", "LBL_2", "LBL_3"); - final List entities = Arrays.asList( - Drivers.node().id(1).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(2).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(3).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(4).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(5).label("LBL_1").label("LBL_2").label("LBL_3").build() - ); - - // WHEN - final boolean result = NodeLabels.haveLabels(entities, labels); - - // THEN - assertThat(result).isFalse(); - } - - @Test - void should_return_true() { - // GIVEN - final List labels = Arrays.asList("LBL_1", "LBL_2", "LBL_3"); - final List entities = Arrays.asList( - Drivers.node().id(1).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(2).label("LBL_1").label("LBL_3").build(), - Drivers.node().id(3).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(4).label("LBL_1").label("LBL_2").build(), - Drivers.node().id(5).label("LBL_1").build() - ); - - // WHEN - final boolean result = NodeLabels.haveLabels(entities, labels); - - // THEN - assertThat(result).isTrue(); - } - - } - - @Nested - @DisplayName("missing(DbNode, Iterable)") - class NodeMissingTests { - - @Test - void should_return_a_new_instance() { - // GIVEN - final List labels = Arrays.asList("LBL_1", "LBL_2", "LBL_3", "LBL_4"); - final Nodes.DbNode node = Drivers.node().id(1).label("LBL_1").label("LBL_3").build(); - - // WHEN - final Missing result = NodeLabels.missing(node, labels); - - // THEN - assertThat(result) - .isNotNull() - .isEqualTo(new Missing<>(node, Arrays.asList("LBL_2", "LBL_4"))); - } - - } - - @Nested - @DisplayName("missing(List, Iterable)") - class ListMissingTests { - @Test - void should_return_an_empty_list() { - // GIVEN - final List labels = Arrays.asList("LBL_1", "LBL_2", "LBL_3"); - final List entities = Arrays.asList( - Drivers.node().id(1).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(2).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(3).label("LBL_1").label("LBL_2").label("LBL_3").build() - ); - - // WHEN - final List> result = NodeLabels.missing(entities, labels); - - // THEN - assertThat(result).isNotNull().isEmpty(); - } - - - @Test - void should_return_a_list_of_missing_nodes() { - // GIVEN - final List labels = Arrays.asList("LBL_1", "LBL_2", "LBL_3"); - final List entities = Arrays.asList( - Drivers.node().id(1).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(2).label("LBL_1").label("LBL_3").build(), - Drivers.node().id(3).label("LBL_1").label("LBL_2").label("LBL_3").build(), - Drivers.node().id(4).label("LBL_1").label("LBL_2").build(), - Drivers.node().id(5).label("LBL_1").build() - ); - // WHEN - final List> result = NodeLabels.missing(entities, labels); - - // THEN - assertThat(result) - .hasSize(3) - .contains( - new Missing<>(entities.get(1), Arrays.asList("LBL_2")), - new Missing<>(entities.get(3), Arrays.asList("LBL_3")), - new Missing<>(entities.get(4), Arrays.asList("LBL_2", "LBL_3")) - ); - } - - } - -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/util/PredicatesTests.java b/src/test/java/org/assertj/neo4j/api/beta/util/PredicatesTests.java index 6e99c19..a1fcd59 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/util/PredicatesTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/util/PredicatesTests.java @@ -1,8 +1,20 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ package org.assertj.neo4j.api.beta.util; -import org.assertj.core.api.Assertions; import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Nodes; +import org.assertj.neo4j.api.beta.type.Nodes.DbNode; +import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; import org.assertj.neo4j.api.beta.type.ValueType; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -24,12 +36,12 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * @author patouche - 30/01/2021 + * @author Patrick Allain - 30/01/2021 */ @DisplayName("Predicates") class PredicatesTests { - private static final Nodes.DbNode SAMPLE_ENTITY = Drivers.node() + private static final DbNode SAMPLE_ENTITY = Drivers.node() .id(42) .property("key-boolean", true) .property("key-long", 42L) @@ -43,6 +55,15 @@ class PredicatesTests { .property("key-list-long", IntStream.range(0, 42).boxed().collect(Collectors.toList())) .build(); + private static final DbNode SAMPLE_NODE = Drivers.node() + .id(69) + .labels("LABEL_1", "LABEL_2", "LABEL_3") + .build(); + + private static final DbRelationship SAMPLE_RELATIONSHIP = Drivers.relation("TYPE") + .id(42) + .build(); + @Nested class PropertyKeyExistsTests { @@ -50,8 +71,8 @@ class PropertyKeyExistsTests { void should_return_false() { // GIVEN final String key = "other-key"; - final Nodes.DbNode entity = Drivers.node().property("key", "value").build(); - final Predicate predicate = Predicates.propertyKeyExists(key); + final DbNode entity = Drivers.node().property("key", "value").build(); + final Predicate predicate = Predicates.propertyKeyExists(key); // WHEN final boolean result = predicate.test(entity); @@ -64,8 +85,8 @@ void should_return_false() { void should_return_true() { // GIVEN final String key = "key"; - final Nodes.DbNode entity = Drivers.node().property("key", "value").build(); - final Predicate predicate = Predicates.propertyKeyExists(key); + final DbNode entity = Drivers.node().property("key", "value").build(); + final Predicate predicate = Predicates.propertyKeyExists(key); // WHEN final boolean result = predicate.test(entity); @@ -82,7 +103,7 @@ class PropertyKeysExistsTests { void should_return_false() { // GIVEN final List keys = Arrays.asList("key-1", "key-2", "key-3", "other-key"); - final Predicate predicate = Predicates.propertyKeysExists(keys); + final Predicate predicate = Predicates.propertyKeysExists(keys); // WHEN final boolean result = predicate.test(SAMPLE_ENTITY); @@ -95,7 +116,7 @@ void should_return_false() { void should_return_true() { // GIVEN final List keys = Arrays.asList("key-boolean", "key-long", "key-list-long"); - final Predicate predicate = Predicates.propertyKeysExists(keys); + final Predicate predicate = Predicates.propertyKeysExists(keys); // WHEN final boolean result = predicate.test(SAMPLE_ENTITY); @@ -114,7 +135,7 @@ void should_return_false() { final List keys = Arrays.asList("key-1", "key-2", "key-3", "other-key"); // WHEN - final boolean result = Predicates.propertyKeysExists(keys).test(SAMPLE_ENTITY); + final boolean result = Predicates.propertyKeysExists(keys).test(SAMPLE_ENTITY); // THEN assertThat(result).isFalse(); @@ -123,7 +144,7 @@ void should_return_false() { @Test void should_return_true() { // GIVEN - final Predicate predicate = Predicates.propertyValueType("key-duration", ValueType.DURATION); + final Predicate predicate = Predicates.propertyValueType("key-duration", ValueType.DURATION); // WHEN final boolean result = predicate.test(SAMPLE_ENTITY); @@ -139,7 +160,7 @@ class PropertyValueInstanceOfTests { @Test void should_return_false() { // GIVEN - final Predicate predicate = Predicates + final Predicate predicate = Predicates .propertyValueInstanceOf("key-date-time", LocalDateTime.class); // WHEN @@ -152,7 +173,7 @@ void should_return_false() { @Test void should_return_true() { // GIVEN - final Predicate predicate = Predicates + final Predicate predicate = Predicates .propertyValueInstanceOf("key-date-time", ZonedDateTime.class); // WHEN @@ -170,7 +191,7 @@ class PropertyValueTests { @Test void should_return_false() { // GIVEN - final Predicate predicate = Predicates.propertyValue("key-string", "bad-value"); + final Predicate predicate = Predicates.propertyValue("key-string", "bad-value"); // WHEN final boolean result = predicate.test(SAMPLE_ENTITY); @@ -182,7 +203,7 @@ void should_return_false() { @Test void should_return_true() { // GIVEN - final Predicate predicate = Predicates.propertyValue("key-string", "value-42"); + final Predicate predicate = Predicates.propertyValue("key-string", "value-42"); // WHEN final boolean result = predicate.test(SAMPLE_ENTITY); @@ -199,7 +220,7 @@ class PropertyListContainsValueTypeTests { @Test void should_return_false() { // GIVEN - final Predicate predicate = Predicates + final Predicate predicate = Predicates .propertyListContainsValueType("key-list-long", ValueType.STRING); // WHEN @@ -212,7 +233,7 @@ void should_return_false() { @Test void should_return_true() { // GIVEN - final Predicate predicate = Predicates + final Predicate predicate = Predicates .propertyListContainsValueType("key-list-long", ValueType.INTEGER); // WHEN @@ -223,23 +244,120 @@ void should_return_true() { } } + @Nested + class LabelExistsTests { + + @Test + void should_return_true() { + // GIVEN + final Predicate predicate = Predicates.labelExists("LABEL_1"); + + // WHEN + final boolean result = predicate.test(SAMPLE_NODE); + + // THEN + assertThat(result).isTrue(); + } + + @Test + void should_return_false() { + // GIVEN + final Predicate predicate = Predicates.labelExists("LABEL_MISSING"); + + // WHEN + final boolean result = predicate.test(SAMPLE_NODE); + + // THEN + assertThat(result).isFalse(); + } + + } + + @Nested + class LabelsExistsTests { + + @Test + void should_return_true() { + // GIVEN + final List labels = Arrays.asList("LABEL_1", "LABEL_2", "LABEL_3"); + final Predicate predicate = Predicates.labelsExists(labels); + + // WHEN + final boolean result = predicate.test(SAMPLE_NODE); + + // THEN + assertThat(result).isTrue(); + } + + @Test + void should_return_false() { + // GIVEN + final List labels = Arrays.asList("LABEL_1", "LABEL_2", "LABEL_MISSING"); + final Predicate predicate = Predicates.labelsExists(labels); + + // WHEN + final boolean result = predicate.test(SAMPLE_NODE); + + // THEN + assertThat(result).isFalse(); + } + + } + + @Nested + class IsTypeTests { + + @Test + void should_return_true() { + // GIVEN + final Predicate predicate = Predicates.isType("TYPE"); + + // WHEN + final boolean result = predicate.test(SAMPLE_RELATIONSHIP); + + // THEN + assertThat(result).isTrue(); + } + + @Test + void should_return_false() { + // GIVEN + final Predicate predicate = Predicates.isType("OTHER_TYPE"); + + // WHEN + final boolean result = predicate.test(SAMPLE_RELATIONSHIP); + + // THEN + assertThat(result).isFalse(); + } + + } + @Nested class XxxTests { @Test void should_return_true() { // GIVEN + final Predicate predicate = (x) -> true; + // WHEN + final boolean result = predicate.test(SAMPLE_NODE); + // THEN - Assertions.fail("TODO"); + assertThat(result).isTrue(); } @Test void should_return_false() { // GIVEN + final Predicate predicate = (x) -> false; + // WHEN + final boolean result = predicate.test(SAMPLE_NODE); + // THEN - Assertions.fail("TODO"); + assertThat(result).isFalse(); } } diff --git a/src/test/java/org/assertj/neo4j/api/beta/util/PresentationsTests.java b/src/test/java/org/assertj/neo4j/api/beta/util/PresentationsTests.java index 41863b2..7634b5c 100644 --- a/src/test/java/org/assertj/neo4j/api/beta/util/PresentationsTests.java +++ b/src/test/java/org/assertj/neo4j/api/beta/util/PresentationsTests.java @@ -30,7 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * @author patouche - 25/11/2020 + * @author Patrick Allain - 25/11/2020 */ class PresentationsTests { diff --git a/src/test/java/org/assertj/neo4j/api/beta/util/RelationshipTypesTests.java b/src/test/java/org/assertj/neo4j/api/beta/util/RelationshipTypesTests.java deleted file mode 100644 index 77c3ba4..0000000 --- a/src/test/java/org/assertj/neo4j/api/beta/util/RelationshipTypesTests.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2013-2020 the original author or authors. - */ -package org.assertj.neo4j.api.beta.util; - -import org.assertj.core.api.Assertions; -import org.assertj.neo4j.api.beta.type.Drivers; -import org.assertj.neo4j.api.beta.type.Relationships.DbRelationship; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author patouche - 25/11/2020 - */ -class RelationshipTypesTests { - - private static final String SAMPLE_TYPE = "TYPE"; - - private static final DbRelationship SAMPLE_TYPE_RELATIONSHIP = Drivers.relation(SAMPLE_TYPE).build(); - - private static final DbRelationship SAMPLE_OTHER_RELATIONSHIP = Drivers.relation("OTHER").build(); - - @Nested - class IsTests { - - @Test - void should_fail_with_NullPointerException() { - // WHEN - final Throwable throwable = Assertions.catchThrowable(() -> RelationshipTypes.is(null, - SAMPLE_TYPE_RELATIONSHIP)); - - // THEN - assertThat(throwable) - .isInstanceOf(NullPointerException.class) - .hasMessage("Type should not be null or empty"); - } - - @Test - void should_fail_with_IllegalArgumentException() { - // WHEN - final Throwable throwable = Assertions.catchThrowable(() -> RelationshipTypes.is("", - SAMPLE_TYPE_RELATIONSHIP)); - - // THEN - assertThat(throwable) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Type should not be null or empty"); - } - - @Test - void should_return_true() { - // WHEN - final boolean result = RelationshipTypes.is(SAMPLE_TYPE, SAMPLE_TYPE_RELATIONSHIP); - - // THEN - assertThat(result).isTrue(); - } - - @Test - void should_return_false() { - // WHEN - final boolean result = RelationshipTypes.is(SAMPLE_TYPE, SAMPLE_OTHER_RELATIONSHIP); - - // THEN - assertThat(result).isFalse(); - } - } - - @Nested - class IsNotTests { - - @Test - void should_return_true() { - // WHEN - final boolean result = RelationshipTypes.isNot(SAMPLE_TYPE, SAMPLE_OTHER_RELATIONSHIP); - - // THEN - assertThat(result).isTrue(); - } - - @Test - void should_return_false() { - // WHEN - final boolean result = RelationshipTypes.isNot(SAMPLE_TYPE, SAMPLE_TYPE_RELATIONSHIP); - - // THEN - assertThat(result).isFalse(); - } - } - - @Nested - class AreTests { - - @Test - void should_return_true() { - // GIVEN - final List relationships = Arrays.asList( - Drivers.relation("TYPE").build(), - Drivers.relation("TYPE").build(), - Drivers.relation("TYPE").build(), - Drivers.relation("TYPE").build() - ); - - // WHEN - final boolean result = RelationshipTypes.are("TYPE", relationships); - - // THEN - assertThat(result).isTrue(); - } - - @Test - void should_return_false() { - // GIVEN - final List relationships = Arrays.asList( - Drivers.relation("TYPE").build(), - Drivers.relation("TYPE").build(), - Drivers.relation("OTHER_TYPE").build(), - Drivers.relation("TYPE").build() - ); - - // WHEN - final boolean result = RelationshipTypes.are("TYPE", relationships); - - // THEN - assertThat(result).isFalse(); - } - } - - @Nested - class OthersTests { - - @Test - void should_return_all_relationships_having_an_other_type() { - // GIVEN - final List relationships = Arrays.asList( - Drivers.relation("TYPE").id(1).build(), - Drivers.relation("OTHER").id(2).build(), - Drivers.relation("TYPE").id(3).build(), - Drivers.relation("OTHER_2").id(4).build() - ); - - // WHEN - final List result = RelationshipTypes.others("TYPE", relationships); - - // THEN - assertThat(result) - .hasSize(2) - .contains( - Drivers.relation("OTHER").id(2).build(), - Drivers.relation("OTHER_2").id(4).build() - ); - } - } - -} diff --git a/src/test/java/org/assertj/neo4j/api/beta/util/UtilsTests.java b/src/test/java/org/assertj/neo4j/api/beta/util/UtilsTests.java new file mode 100644 index 0000000..7f16fc6 --- /dev/null +++ b/src/test/java/org/assertj/neo4j/api/beta/util/UtilsTests.java @@ -0,0 +1,75 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2013-2020 the original author or authors. + */ +package org.assertj.neo4j.api.beta.util; + +import org.assertj.core.api.Assertions; +import org.assertj.neo4j.api.beta.testing.Randomize; +import org.assertj.neo4j.api.beta.type.Drivers; +import org.assertj.neo4j.api.beta.type.Nodes; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Patrick Allain - 05/02/2021 + */ +class UtilsTests { + + @Nested + class MissingTests { + + @Test + void should_return_an_empty_list() { + // GIVEN + final Iterable searched = Randomize.listOf("str-3", "str-5", "str-7", "str-9"); + final Iterable items = IntStream.rangeClosed(1, 10) + .mapToObj(i -> "str-" + i) + .sorted(Randomize.comparator()) + .collect(Collectors.toList()); + + // WHEN + final List result = Utils.missing(searched, items); + + // THEN + assertThat(result).isEmpty(); + } + + @Test + void should_return_the_missing_items() { + // GIVEN + final Iterable searched = Randomize.listOf("str-3", "str-15", "str-17", "str-29"); + final Iterable items = IntStream.rangeClosed(1, 10) + .mapToObj(i -> "str-" + i) + .sorted(Randomize.comparator()) + .collect(Collectors.toList()); + + // WHEN + final List result = Utils.missing(searched, items); + + // THEN + assertThat(result).containsExactly("str-15", "str-17", "str-29"); + } + } + + + + + + + +} diff --git a/src/test/resources/samples/language.cypher b/src/test/resources/samples/language.cypher index e276e5b..fbe7b37 100644 --- a/src/test/resources/samples/language.cypher +++ b/src/test/resources/samples/language.cypher @@ -2,6 +2,9 @@ // ALL OF VALUES DESCRIBE BELLOW IS NOT REAL AND HAVE BEEN DEFINE ONLY TO HAVE // A DATASET TO RUN SOME INTEGRATION TESTS +// The original idea came just after the publication of Stack Overflow survey +// https://insights.stackoverflow.com/survey/2020#correlated-technologies + // Nodes CREATE @@ -123,7 +126,6 @@ CREATE owner: 'grafana', url: 'https://github.com/grafana/tempo', creation_date: localdatetime('2020-01-24T18:05:02'), - onboarding_duration: duration({ minutes: 25 }), active_branches: ['main'], stats_items: ['branches', 'tags', 'stars', 'fork'], stats_values: [17, 42, 3450, 345] @@ -133,7 +135,6 @@ CREATE owner: 'prometheus', url: 'https://github.com/prometheus/prometheus', creation_date: localdatetime('2012-11-24T11:14:12'), - onboarding_duration: duration({ minutes: 25 }), active_branches: ['master'], stats_items: ['branches', 'tags', 'stars', 'fork'], stats_values: [17, 42, 3450, 345] @@ -191,16 +192,16 @@ CREATE (KTurner)-[:KNOWS {level: 1}]->(Java) CREATE - (Assertj_AssertjCore)-[:IS {percent: ['99.7']}]->(Java), - (Assertj_AssertjCore)-[:IS {percent: ['0.3']}]->(Shell), - (Neo4j_Neo4j)-[:IS {percent: ['76.8']}]->(Java), - (Neo4j_Neo4j)-[:IS {percent: ['0.2']}]->(Shell), - (JunitTeam_Junit5)-[:IS {percent: ['97.5']}]->(Java), - (JunitTeam_Junit5)-[:IS {percent: ['2.1']}]->(Kotlin), - (Urfave_Cli)-[:IS {percent: ['99.8']}]->(Go), - (Urfave_Cli)-[:IS {percent: ['0.2']}]->(Shell), - (Ktorio_Ktor)-[:IS {percent: ['0.2']}]->(Shell), - (Kubernetes_Kubernetes)-[:IS {percent: ['90.3']}]->(Go), - (Kubernetes_Kubernetes)-[:IS {percent: ['2.8']}]->(Shell), - (Pallets_Click)-[:IS {percent: ['100']}]->(Python), - (Pallets_Flask)-[:IS {percent: ['99.9']}]->(Python) + (Assertj_AssertjCore)-[:WRITTEN {percent: ['99.7']}]->(Java), + (Assertj_AssertjCore)-[:WRITTEN {percent: ['0.3']}]->(Shell), + (Neo4j_Neo4j)-[:WRITTEN {percent: ['76.8']}]->(Java), + (Neo4j_Neo4j)-[:WRITTEN {percent: ['0.2']}]->(Shell), + (JunitTeam_Junit5)-[:WRITTEN {percent: ['97.5']}]->(Java), + (JunitTeam_Junit5)-[:WRITTEN {percent: ['2.1']}]->(Kotlin), + (Urfave_Cli)-[:WRITTEN {percent: ['99.8']}]->(Go), + (Urfave_Cli)-[:WRITTEN {percent: ['0.2']}]->(Shell), + (Ktorio_Ktor)-[:WRITTEN {percent: ['0.2']}]->(Shell), + (Kubernetes_Kubernetes)-[:WRITTEN {percent: ['90.3']}]->(Go), + (Kubernetes_Kubernetes)-[:WRITTEN {percent: ['2.8']}]->(Shell), + (Pallets_Click)-[:WRITTEN {percent: ['100']}]->(Python), + (Pallets_Flask)-[:WRITTEN {percent: ['99.9']}]->(Python)