diff --git a/pom.xml b/pom.xml index 311d2ff..55c4bf4 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,13 @@ Vincent Fuchs vincent.fuchs@gmail.com + + + FanJups + Fanon Jupkwo + jupsfan@gmail.com + + @@ -256,6 +263,8 @@ coveralls-maven-plugin 4.3.0 + + diff --git a/src/main/java/com/societegenerale/commons/plugin/rules/NoJavaUtilDateRuleTest.java b/src/main/java/com/societegenerale/commons/plugin/rules/NoJavaUtilDateRuleTest.java new file mode 100644 index 0000000..14bb47b --- /dev/null +++ b/src/main/java/com/societegenerale/commons/plugin/rules/NoJavaUtilDateRuleTest.java @@ -0,0 +1,62 @@ +package com.societegenerale.commons.plugin.rules; + +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes; + +import com.societegenerale.commons.plugin.utils.ArchUtils; +import com.tngtech.archunit.core.domain.JavaClass; +import com.tngtech.archunit.core.domain.JavaField; +import com.tngtech.archunit.lang.ArchCondition; +import com.tngtech.archunit.lang.ConditionEvents; +import com.tngtech.archunit.lang.SimpleConditionEvent; + +/** + * java.util.Date is deprecated but a lot of people still use it out of years of + * habit. This rule will catch such instances and remind developers they should + * use alternatives (java.time, java.util.GregorianCalendar , + * java.text.DateFormat (and its subclasses) to parse and format dates) because + * they support internationalization better + * + * + * + * @see java.util.Date + * is deprecated : developers can use other libraries : java.time, + * java.util.GregorianCalendar ; java.text.DateFormat ; ... + * + * @see Java + * 8 Time Oracle + */ + +public class NoJavaUtilDateRuleTest implements ArchRuleTest { + + private static final String JAVA_UTIL_DATE_PACKAGE_PREFIX = "java.util.Date"; + + protected static final String NO_JAVA_UTIL_DATE_VIOLATION_MESSAGE = "Use Java8 java.time or java.util.GregorianCalendar or java.text.DateFormat to parse and format dates instead of java.util.Date library because they support internationalization better"; + + @Override + public void execute(String path) { + classes().should(notUseJavaUtilDate()).check(ArchUtils.importAllClassesInPackage(path, SRC_CLASSES_FOLDER)); + } + + protected static ArchCondition notUseJavaUtilDate() { + + return new ArchCondition("not use Java Util Date ") { + @Override + public void check(JavaClass item, ConditionEvents events) { + + item.getAllFields().stream().filter(field -> isJavaUtilDateField(field)).forEach(field -> { + events.add(SimpleConditionEvent.violated(field, + NO_JAVA_UTIL_DATE_VIOLATION_MESSAGE + " - class: " + field.getOwner().getName())); + }); + + } + + private boolean isJavaUtilDateField(JavaField field) { + return field.getRawType().getName().startsWith(JAVA_UTIL_DATE_PACKAGE_PREFIX); + } + + }; + } + +} diff --git a/src/test/java/com/societegenerale/commons/plugin/rules/ArchUtilsTest.java b/src/test/java/com/societegenerale/commons/plugin/rules/ArchUtilsTest.java index 7a95441..4d628d1 100644 --- a/src/test/java/com/societegenerale/commons/plugin/rules/ArchUtilsTest.java +++ b/src/test/java/com/societegenerale/commons/plugin/rules/ArchUtilsTest.java @@ -1,54 +1,55 @@ package com.societegenerale.commons.plugin.rules; -import com.societegenerale.commons.plugin.utils.ArchUtils; -import com.tngtech.archunit.core.domain.JavaClass; -import com.tngtech.archunit.core.domain.JavaClasses; -import org.junit.Assert; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Assert; +import org.junit.Test; -public class ArchUtilsTest { +import com.societegenerale.commons.plugin.utils.ArchUtils; +import com.tngtech.archunit.core.domain.JavaClass; +import com.tngtech.archunit.core.domain.JavaClasses; +public class ArchUtilsTest { - @Test - public void constructorInvocationTest() { - try { - final Constructor c = ArchUtils.class.getDeclaredConstructor(); - c.setAccessible(true); - final ArchUtils newInstance = c.newInstance(); - Assert.assertNull(newInstance); - } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException - | InvocationTargetException e) { - assertThat(e).hasCauseExactlyInstanceOf(UnsupportedOperationException.class); - } - } - - @Test - public void testNumberOfRulesAvailable() { - JavaClasses classes = ArchUtils.importAllClassesInPackage("./target/classes/com/societegenerale/commons/plugin/", "rules"); - int noOfClasses = 0; - for (JavaClass javaClass : classes) { - if(! javaClass.getName().contains("$") && !javaClass.isInterface()) { - noOfClasses++; - } - } - assertThat(noOfClasses).isEqualTo(9); - } - - @Test - public void totalClassesInPathWhenPackageFolderDoesNotExists() { - JavaClasses classes = ArchUtils.importAllClassesInPackage("./target/classes", "classFolder"); - int noOfClasses = 0; - for (JavaClass javaClass : classes) { - if(!javaClass.getName().contains("$")) { - noOfClasses++; - } - } - assertThat(noOfClasses).isEqualTo(16); - } + @Test + public void constructorInvocationTest() { + try { + final Constructor c = ArchUtils.class.getDeclaredConstructor(); + c.setAccessible(true); + final ArchUtils newInstance = c.newInstance(); + Assert.assertNull(newInstance); + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + assertThat(e).hasCauseExactlyInstanceOf(UnsupportedOperationException.class); + } + } + + @Test + public void testNumberOfRulesAvailable() { + JavaClasses classes = ArchUtils + .importAllClassesInPackage("./target/classes/com/societegenerale/commons/plugin/", "rules"); + int noOfClasses = 0; + for (JavaClass javaClass : classes) { + if (!javaClass.getName().contains("$") && !javaClass.isInterface()) { + noOfClasses++; + } + } + assertThat(noOfClasses).isEqualTo(10); + } + + @Test + public void totalClassesInPathWhenPackageFolderDoesNotExists() { + JavaClasses classes = ArchUtils.importAllClassesInPackage("./target/classes", "classFolder"); + int noOfClasses = 0; + for (JavaClass javaClass : classes) { + if (!javaClass.getName().contains("$")) { + noOfClasses++; + } + } + assertThat(noOfClasses).isEqualTo(17); + } } diff --git a/src/test/java/com/societegenerale/commons/plugin/rules/NoJavaUtilDateRuleTestTest.java b/src/test/java/com/societegenerale/commons/plugin/rules/NoJavaUtilDateRuleTestTest.java new file mode 100644 index 0000000..542707f --- /dev/null +++ b/src/test/java/com/societegenerale/commons/plugin/rules/NoJavaUtilDateRuleTestTest.java @@ -0,0 +1,57 @@ +package com.societegenerale.commons.plugin.rules; + +import static com.societegenerale.commons.plugin.rules.NoJavaUtilDateRuleTest.NO_JAVA_UTIL_DATE_VIOLATION_MESSAGE; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.Test; + +import com.societegenerale.commons.plugin.rules.classesForTests.ObjectWithAdateField; +import com.societegenerale.commons.plugin.rules.classesForTests.ObjectWithJava8TimeLib; +import com.societegenerale.commons.plugin.rules.classesForTests.ObjectWithJavaTextDateFormat; +import com.societegenerale.commons.plugin.rules.classesForTests.ObjectWithJavaUtilGregorianCalendar; +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.core.importer.ClassFileImporter; + +public class NoJavaUtilDateRuleTestTest { + + @Test + public void shouldThrowViolations() { + + assertExceptionIsThrownFor(ObjectWithAdateField.class); + + } + + @Test + public void shouldNotThrowAnyViolation() { + + assertNoExceptionIsThrownFor(ObjectWithJava8TimeLib.class); + + assertNoExceptionIsThrownFor(ObjectWithJavaTextDateFormat.class); + + assertNoExceptionIsThrownFor(ObjectWithJavaUtilGregorianCalendar.class); + + } + + private void assertExceptionIsThrownFor(Class clazz) { + + JavaClasses classToTest = new ClassFileImporter().importClasses(clazz); + + assertThatThrownBy(() -> { + classes().should(NoJavaUtilDateRuleTest.notUseJavaUtilDate()).check(classToTest); + }).hasMessageContaining(ObjectWithAdateField.class.getName()) + .hasMessageContaining(NO_JAVA_UTIL_DATE_VIOLATION_MESSAGE); + + } + + private void assertNoExceptionIsThrownFor(Class clazz) { + + JavaClasses classToTest = new ClassFileImporter().importClasses(clazz); + + assertThatCode(() -> classes().should(NoJavaUtilDateRuleTest.notUseJavaUtilDate()).check(classToTest)) + .doesNotThrowAnyException(); + + } + +} diff --git a/src/test/java/com/societegenerale/commons/plugin/rules/classesForTests/ObjectWithAdateField.java b/src/test/java/com/societegenerale/commons/plugin/rules/classesForTests/ObjectWithAdateField.java new file mode 100644 index 0000000..c68f1f9 --- /dev/null +++ b/src/test/java/com/societegenerale/commons/plugin/rules/classesForTests/ObjectWithAdateField.java @@ -0,0 +1,9 @@ +package com.societegenerale.commons.plugin.rules.classesForTests; + +import java.util.Date; + +public class ObjectWithAdateField { + + private Date date = new Date(0, 0, 0); + +} diff --git a/src/test/java/com/societegenerale/commons/plugin/rules/classesForTests/ObjectWithJavaTextDateFormat.java b/src/test/java/com/societegenerale/commons/plugin/rules/classesForTests/ObjectWithJavaTextDateFormat.java new file mode 100644 index 0000000..ad36e77 --- /dev/null +++ b/src/test/java/com/societegenerale/commons/plugin/rules/classesForTests/ObjectWithJavaTextDateFormat.java @@ -0,0 +1,9 @@ +package com.societegenerale.commons.plugin.rules.classesForTests; + +import java.text.DateFormat; + +public class ObjectWithJavaTextDateFormat { + + private DateFormat dateFormat; + +} diff --git a/src/test/java/com/societegenerale/commons/plugin/rules/classesForTests/ObjectWithJavaUtilGregorianCalendar.java b/src/test/java/com/societegenerale/commons/plugin/rules/classesForTests/ObjectWithJavaUtilGregorianCalendar.java new file mode 100644 index 0000000..18889ff --- /dev/null +++ b/src/test/java/com/societegenerale/commons/plugin/rules/classesForTests/ObjectWithJavaUtilGregorianCalendar.java @@ -0,0 +1,9 @@ +package com.societegenerale.commons.plugin.rules.classesForTests; + +import java.util.GregorianCalendar; + +public class ObjectWithJavaUtilGregorianCalendar { + + private GregorianCalendar cal; + +}