Skip to content

Instantly share code, notes, and snippets.

@ibaca
Created January 14, 2019 21:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ibaca/48500098d932bdb5829aeb2504d6bbe6 to your computer and use it in GitHub Desktop.
Save ibaca/48500098d932bdb5829aeb2504d6bbe6 to your computer and use it in GitHub Desktop.
JsInterop-DTO-strategy checks
package com.intendia.igestion.shared;
import static com.tngtech.archunit.core.domain.JavaModifier.FINAL;
import static com.tngtech.archunit.core.domain.JavaModifier.PUBLIC;
import static com.tngtech.archunit.core.domain.JavaModifier.STATIC;
import static com.tngtech.archunit.lang.SimpleConditionEvent.violated;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static java.lang.String.format;
import static jsinterop.annotations.JsPackage.GLOBAL;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaField;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ConditionEvents;
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
import jsinterop.annotations.JsOverlay;
import jsinterop.annotations.JsType;
import org.junit.Test;
public class DtoArchTest {
@Test public void check_dto_name_convention() {
ArchRuleDefinition.classes().that(areDto)
.should(onlyHaveNonFinalPublicInstanceFields)
.andShould(onlyHaveJsOverlayStaticFields)
.check(new ClassFileImporter().importPackages("com.intendia.igestion.shared"));
}
public static final DescribedPredicate<JavaClass> areDto = new DescribedPredicate<JavaClass>("are a DTO") {
@Override public boolean apply(JavaClass input) {
return input.tryGetAnnotationOfType(JsType.class).transform(this::isDto).or(FALSE);
}
private boolean isDto(JsType a) {
return GLOBAL.equals(a.namespace()) && "Object".equals(a.name()) && TRUE.equals(a.isNative());
}
};
public static final ArchCondition<JavaClass> onlyHaveNonFinalPublicInstanceFields = new ArchCondition<JavaClass>(
"only have non-final public instance fields") {
@Override public void check(JavaClass item, ConditionEvents events) {
for (JavaField f : item.getFields()) {
//TODO gather all errors and report it, otherwise the user need to fix one by one
if (f.getModifiers().contains(STATIC)) continue; // skip static fields
if (!f.getModifiers().contains(PUBLIC) || f.getModifiers().contains(FINAL)) {
events.add(violated(f, format("Instance field %s is not public and non final", f.getFullName())));
}
}
}
};
public static final ArchCondition<JavaClass> onlyHaveJsOverlayStaticFields = new ArchCondition<JavaClass>(
"only have @JsOverlay annotated static fields") {
@Override public void check(JavaClass item, ConditionEvents events) {
for (JavaField f : item.getFields()) {
//TODO gather all errors and report it, otherwise the user need to fix one by one
if (!f.getModifiers().contains(STATIC) || f.reflect().isSynthetic()) continue; // skip instance fields
if (!f.isAnnotatedWith(JsOverlay.class)) {
events.add(violated(f, format("Static field %s is not annotated with @JsOverlay", f.getFullName())));
}
}
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment