package org.kohsuke.github;

import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.domain.properties.HasAnnotations;
import com.tngtech.archunit.core.domain.properties.HasName.AndFullName;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.core.importer.ImportOption;
import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ArchRule;
import com.tngtech.archunit.lang.ConditionEvents;
import com.tngtech.archunit.lang.SimpleConditionEvent;
import org.junit.Test;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;

public class ArchTests {

    private final JavaClasses classFiles = new ClassFileImporter()
            .withImportOption(new ImportOption.DoNotIncludeTests())
            .withImportOption(new ImportOption.DoNotIncludeJars())
            .importPackages("org.kohsuke.github");

    @Test
    public void testPreviewsAreFlaggedAsDeprecated() {

        String description = "annotate all preview APIs as @Deprecated until they are promoted to stable";

        ArchRule rule = classes().should(new ArchCondition<JavaClass>(description) {

            @Override
            public void check(final JavaClass targetClazz, final ConditionEvents events) {
                checkForPreviewAnnotation(targetClazz, events);
                targetClazz.getAllMethods().forEach(method -> {
                    checkForPreviewAnnotation(method, events);
                });
            }

            <T extends HasAnnotations<T> & AndFullName> void checkForPreviewAnnotation(T codeTarget,
                    ConditionEvents events) {

                if (codeTarget.tryGetAnnotationOfType(Preview.class).isPresent()
                        && !codeTarget.tryGetAnnotationOfType(Deprecated.class).isPresent()) {

                    String message = codeTarget.getFullName()
                            + " uses a preview API and is missing the '@Deprecated' annotation.";

                    events.add(new SimpleConditionEvent(codeTarget, false, message));
                }
            }
        });

        rule.check(classFiles);

    }
}

package org.kohsuke.github;

import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.core.importer.ImportOption;
import com.tngtech.archunit.lang.ArchRule;
import org.junit.BeforeClass;
import org.junit.Test;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.fields;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods;
import static org.junit.Assert.assertTrue;

public class ArchTests {

    private static final JavaClasses classFiles = new ClassFileImporter()
            .withImportOption(new ImportOption.DoNotIncludeTests())
            .withImportOption(new ImportOption.DoNotIncludeJars())
            .importPackages("org.kohsuke.github");

    @BeforeClass
    public static void beforeClass() {
        assertTrue(classFiles.size() > 0);
    }

    @Test
    public void testPreviewsAreFlaggedAsDeprecated() {

        String reason = "all preview APIs must be annotated as @Deprecated until they are promoted to stable";

        ArchRule classRule = classes().that()
                .areAnnotatedWith(Preview.class)
                .should()
                .beAnnotatedWith(Deprecated.class)
                .because(reason);

        ArchRule methodRule = methods().that()
                .areAnnotatedWith(Preview.class)
                .should()
                .beAnnotatedWith(Deprecated.class)
                .because(reason);

        ArchRule enumFieldsRule = fields().that()
                .areDeclaredInClassesThat()
                .areEnums()
                .and()
                .areAnnotatedWith(Preview.class)
                .should()
                .beAnnotatedWith(Deprecated.class)
                .because(reason);

        classRule.check(classFiles);
        enumFieldsRule.check(classFiles);
        methodRule.check(classFiles);

    }
}

update arch tests to add enum checks