Skip to content

Commit

Permalink
new class ContractVerifier created that can verify a given class
Browse files Browse the repository at this point in the history
  • Loading branch information
astrapi69 committed May 6, 2019
1 parent df52edb commit b355591
Show file tree
Hide file tree
Showing 13 changed files with 213 additions and 54 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
Version 3.1-SNAPSHOT
-------------

ADDED:

- new class ContractVerifier created that can verify a given class the contracts of the methods equals, hashcode and toString

CHANGED:

- update of dependency jobject-clone version to 3
Expand Down
21 changes: 17 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,22 @@

<artifactId>jobj-contract-verifier</artifactId>
<version>3.1-SNAPSHOT</version>

<name>${project.artifactId}</name>

<description>Verify if java objects fulfill the contracts of equals, hashcode and toString</description>

<url>https://github.com/astrapi69/${project.artifactId}</url>

<properties>
<!-- JOBJECT-CLONE versions -->
<!-- JOBJECT-CLONE versions -->
<jobject-clone.version>3</jobject-clone.version>
<!-- TEST-OBJECTS version -->
<test-objects.version>5.1</test-objects.version>
<!-- EXTERNAL LIBRARIES versions -->
<commons-beanutils.version>1.9.3</commons-beanutils.version>
<!-- RANDOMIZER-CORE version -->
<randomizer-core.version>5.8</randomizer-core.version>
</properties>

<licenses>
Expand Down Expand Up @@ -80,6 +82,12 @@
<artifactId>test-objects</artifactId>
<version>${test-objects.version}</version>
</dependency>
<!-- RANDOMIZER DEPENDENCY -->
<dependency>
<groupId>de.alpharogroup</groupId>
<artifactId>randomizer-core</artifactId>
<version>${randomizer-core.version}</version>
</dependency>

</dependencies>

Expand All @@ -96,7 +104,12 @@
<groupId>io.github.benas</groupId>
<artifactId>random-beans</artifactId>
</dependency>

<!-- RANDOMIZER DEPENDENCY -->
<dependency>
<groupId>de.alpharogroup</groupId>
<artifactId>randomizer-core</artifactId>
</dependency>

<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
Expand All @@ -115,5 +128,5 @@
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import de.alpharogroup.evaluate.object.api.ContractViolation;
import de.alpharogroup.evaluate.object.enums.EqualsHashcodeContractViolation;
import de.alpharogroup.evaluate.object.enums.ToStringContractViolation;
import de.alpharogroup.random.RandomObjectFactory;
import io.github.benas.randombeans.EnhancedRandomBuilder;
import lombok.experimental.UtilityClass;

Expand Down Expand Up @@ -244,10 +245,12 @@ public static <T> Optional<ContractViolation> equalsAndHashcodeUnequality(final
* Signals that an I/O exception has occurred
* @throws ClassNotFoundException
* occurs if a given class cannot be located by the specified class loader
* @throws NoSuchFieldException
* is thrown if no such field exists
*/
public static <T> Optional<ContractViolation> equalsHashcodeAndToString(Class<T> cls)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
InstantiationException, IOException, ClassNotFoundException
InstantiationException, IOException, ClassNotFoundException, NoSuchFieldException
{
Function<Class<T>, T> function = new EnhancedRandomBuilder().build()::nextObject;
return equalsHashcodeAndToString(cls, function);
Expand Down Expand Up @@ -278,11 +281,14 @@ public static <T> Optional<ContractViolation> equalsHashcodeAndToString(Class<T>
* Signals that an I/O exception has occurred
* @throws ClassNotFoundException
* occurs if a given class cannot be located by the specified class loader
* @throws NoSuchFieldException
* is thrown if no such field exists
*/
@SuppressWarnings("unchecked")
public static <T> Optional<ContractViolation> equalsHashcodeAndToString(Class<T> cls,
Function<Class<T>, T> function) throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException, InstantiationException, IOException, ClassNotFoundException
Function<Class<T>, T> function)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
InstantiationException, IOException, ClassNotFoundException, NoSuchFieldException
{
if (cls == null)
{
Expand All @@ -292,12 +298,16 @@ public static <T> Optional<ContractViolation> equalsHashcodeAndToString(Class<T>
T second = null;
do
{
if(second != null) {

if (second == null)
{
second = function.apply(cls);
}
else
{
second = RandomObjectFactory.newRandomObject(cls);
}
second = function.apply(cls);
}
while(second.equals(first));
while (second.equals(first));

final T third = (T)CloneObjectExtensions.cloneObject(first);
final T fourth = (T)CloneObjectExtensions.cloneObject(third);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
/**
* The MIT License
*
* Copyright (C) 2015 Asterios Raptis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package de.alpharogroup.evaluate.object.enums;

/**
* The class {@link VerificationConfiguration} holds the data how to verify of an object
* The class {@link VerificationType} holds the data how to verify of an object
*/
public enum VerificationType
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,12 @@ public static <T> boolean evaluateEqualsAndHashcodeUnequality(final T object,
* Signals that an I/O exception has occurred.
* @throws ClassNotFoundException
* occurs if a given class cannot be located by the specified class loader
* @throws NoSuchFieldException
* is thrown if no such field exists
*/
public static <T> boolean evaluateEqualsHashcodeAndToString(Class<T> cls)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
InstantiationException, IOException, ClassNotFoundException
InstantiationException, IOException, ClassNotFoundException, NoSuchFieldException
{
return !EqualsHashCodeAndToStringCheck.equalsHashcodeAndToString(cls).isPresent();
}
Expand Down Expand Up @@ -203,10 +205,13 @@ public static <T> boolean evaluateEqualsHashcodeAndToString(Class<T> cls)
* Signals that an I/O exception has occurred.
* @throws ClassNotFoundException
* occurs if a given class cannot be located by the specified class loader
* @throws NoSuchFieldException
* is thrown if no such field exists
*/
public static <T> boolean evaluateEqualsHashcodeAndToString(Class<T> cls,
Function<Class<T>, T> function) throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException, InstantiationException, IOException, ClassNotFoundException
Function<Class<T>, T> function)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
InstantiationException, IOException, ClassNotFoundException, NoSuchFieldException
{
return !EqualsHashCodeAndToStringCheck.equalsHashcodeAndToString(cls, function).isPresent();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
/**
* The MIT License
*
* Copyright (C) 2015 Asterios Raptis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package de.alpharogroup.evaluate.object.verifier;

import java.io.IOException;
Expand All @@ -22,33 +42,61 @@
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public final class ContractVerifier<T>
{

/**
* Factory method for create a new {@link ContractVerifier} object from the given class
*
* @param <T>
* the generic type
* @param type
* the class
* @return the contract verifier
*/
public static <T> ContractVerifier<T> of(final @NonNull Class<T> type)
{
return new ContractVerifier<>(type);
}

/** The cls. */
Class<T> cls;

/** The factory function. */
@NonFinal
Function<Class<T>, T> factoryFunction;

/** The verification type. */
@NonFinal
VerificationType verificationType = VerificationType.EQUALS_HASHCODE_AND_TO_STRING;

ContractVerifier(final @NonNull Class<T> cls)
/**
* Private constructor
*
* @param cls
* the class
*/
private ContractVerifier(final @NonNull Class<T> cls)
{
this.cls = cls;
}

/**
* Verify the given class and returns an {@link Optional} that is empty if the verification was
* successful
*
* @return an empty {@link Optional} object if the verification was successful
*/
public Optional<ContractViolation> verify()
{
Optional<ContractViolation> verificationResult = Optional.empty();
try
{
if (factoryFunction != null)
{
verificationResult = EqualsHashCodeAndToStringCheck.equalsHashcodeAndToString(cls, factoryFunction);
} else {
verificationResult = EqualsHashCodeAndToStringCheck.equalsHashcodeAndToString(cls,
factoryFunction);
}
else
{
verificationResult = EqualsHashCodeAndToStringCheck.equalsHashcodeAndToString(cls);
}
}
Expand Down Expand Up @@ -76,16 +124,34 @@ public Optional<ContractViolation> verify()
{
throw new AssertionError(e.getMessage(), e);
}
catch (NoSuchFieldException e)
{
throw new AssertionError(e.getMessage(), e);
}
return verificationResult;
}

/**
* Builder method that sets the verification type
* {@link VerificationType#EQUALS_HASHCODE_AND_TO_STRING}
*
* @return this {@link ContractVerifier}
*/
public ContractVerifier<T> withEqualsHashcodeAndToString()
{
verificationType = VerificationType.EQUALS_HASHCODE_AND_TO_STRING;
verificationType = VerificationType.EQUALS_HASHCODE_AND_TO_STRING;
return this;
}

public ContractVerifier<T> withFactoryFunction(final @NonNull Function<Class<T>, T> factoryFunction)
/**
* Builder method that sets the factory function
*
* @param factoryFunction
* the factory function
* @return this {@link ContractVerifier}
*/
public ContractVerifier<T> withFactoryFunction(
final @NonNull Function<Class<T>, T> factoryFunction)
{
this.factoryFunction = factoryFunction;
return this;
Expand Down
18 changes: 18 additions & 0 deletions src/main/resources/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
The MIT License

Copyright (C) ${year} ${owner}

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
/**
* The MIT License
*
* Copyright (C) 2015 Asterios Raptis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package de.alpharogroup.evaluate.object;

import io.github.benas.randombeans.EnhancedRandomBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,13 @@ public void testEqualsHashcodeAndToString()
* Signals that an I/O exception has occurred
* @throws ClassNotFoundException
* occurs if a given class cannot be located by the specified class loader
* @throws NoSuchFieldException
* is thrown if no such field exists
*/
@Test(enabled = true)
public void testEqualsHashcodeAndToStringClass()
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
InstantiationException, IOException, ClassNotFoundException
InstantiationException, IOException, ClassNotFoundException, NoSuchFieldException
{
actual = EqualsHashCodeAndToStringCheck.equalsHashcodeAndToString(null);
expected = Optional.of(ToStringContractViolation.CLASS_NULL_ARGUMENT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.testng.annotations.Test;

/**
* The unit test class for the class {@link ComparableEvaluator}.
* The unit test class for the class {@link ComparableEvaluator}
*/
public class ComparableEvaluatorTest
{
Expand Down

0 comments on commit b355591

Please sign in to comment.