package io.github.lukehutch.fastclasspathscanner.metaannotation;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.StrictAssertions.assertThat;
import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.junit.Test;

public class MetaAnnotationTest {
    FastClasspathScanner scanner = new FastClasspathScanner(getClass().getPackage().getName()).scan();

    private static <T extends Comparable<T>> ArrayList<T> sort(List<T> list) {
        ArrayList<T> sorted = new ArrayList<>(list);
        Collections.sort(sorted);
        return sorted;
    }

    @Test
    public void metaAnnotationsByClass() {
        assertThat(scanner.getNamesOfClassesWithAnnotation(MetaAnnotatedAnnotation.class)).containsExactly(
                MetaAnnotatedClass.class.getName());

        assertThat(sort(scanner.getNamesOfClassesWithMetaAnnotation(MetaAnnotation.class))).containsExactly(
                MetaAndNonMetaAnnotatedClass.class.getName(), MetaAnnotatedClass.class.getName());

        assertThat(sort(scanner.getNamesOfClassesWithMetaAnnotation(MetaAnnotatedAnnotation.class)))
                .containsExactly(MetaAnnotatedClass.class.getName(), MetaMetaAnnotatedClass.class.getName());
    }

    @Test
    public void metaAnnotationsByName() {
        assertThat(scanner.getNamesOfClassesWithAnnotation(MetaAnnotatedAnnotation.class.getName()))
                .containsExactly(MetaAnnotatedClass.class.getName());

        assertThat(sort(scanner.getNamesOfClassesWithMetaAnnotation(MetaAnnotation.class.getName())))
                .containsExactly(MetaAndNonMetaAnnotatedClass.class.getName(), MetaAnnotatedClass.class.getName());

        assertThat(sort(scanner.getNamesOfClassesWithMetaAnnotation(MetaAnnotatedAnnotation.class.getName())))
                .containsExactly(MetaAnnotatedClass.class.getName(), MetaMetaAnnotatedClass.class.getName());
    }

    @Test
    public void nonMeta() {
        assertThat(sort(scanner.getNamesOfClassesWithMetaAnnotation(NonMetaAnnotation.class))).containsExactly(
                MetaAndNonMetaAnnotatedClass.class.getName(), NonMetaClass.class.getName());
    }

    @Test
    public void varArgsByClass() {
        assertThat(
                sort(scanner.getNamesOfClassesWithMetaAnnotationsAnyOf(MetaAnnotation.class,
                        NonMetaAnnotation.class))) //
                .containsExactly(MetaAndNonMetaAnnotatedClass.class.getName(), MetaAnnotatedClass.class.getName(),
                        NonMetaClass.class.getName());
    }

    @Test
    public void varArgsByName() {
        assertThat(
                sort(scanner.getNamesOfClassesWithMetaAnnotationsAnyOf(MetaAnnotation.class.getName(),
                        NonMetaAnnotation.class.getName()))) //
                .containsExactly(MetaAndNonMetaAnnotatedClass.class.getName(), MetaAnnotatedClass.class.getName(),
                        NonMetaClass.class.getName());
    }

    @Test
    public void nonMetaAnnotation() {
        assertThat(NonMetaClass.class.getAnnotation(NonMetaAnnotation.class)).isNotNull();
        assertThat(NonMetaClass.class.getAnnotation(MetaAnnotation.class)).isNull();
    }

    @Test
    public void nonClassTargetDoesntWork() {
        assertThat(NonClassTarget.class.getAnnotationsByType(MetaAnnotatedAnnotation.class)).isEmpty();
        assertThat(NonClassTarget.class.getAnnotationsByType(MetaAnnotation.class)).isEmpty();
    }

    @Test
    public void metaMeta() {
        assertThat(MetaMetaAnnotatedClass.class.getAnnotation(MetaAnnotatedAnnotation.class)).isNull();
        assertThat(MetaMetaAnnotatedClass.class.getAnnotation(MetaAnnotation.class)).isNull();
    }
}

@@ -2288,16 +2288,21 @@
  varArgs
+AnyOf
 ByClass(
@@ -2297,32 +2297,32 @@
 nyOfByClass() %7B%0A
-
         assertTh
@@ -2682,16 +2682,21 @@
  varArgs
+AnyOf
 ByName()
@@ -2992,32 +2992,32 @@
 lass.getName(),%0A
-
                 
@@ -3054,32 +3054,606 @@
 Name());%0A    %7D%0A%0A
+    @Test%0A    public void varArgsAllOfByClass() %7B%0A        assertThat(scanner.getNamesOfClassesWithMetaAnnotationsAllOf(MetaAnnotation.class, NonMetaAnnotation.class)) //%0A                .containsExactly(MetaAndNonMetaAnnotatedClass.class.getName());%0A    %7D%0A%0A    @Test%0A    public void varArgsAllOfByName() %7B%0A        assertThat(%0A                scanner.getNamesOfClassesWithMetaAnnotationsAllOf(MetaAnnotation.class.getName(),%0A                        NonMetaAnnotation.class.getName())) //%0A                .containsExactly(MetaAndNonMetaAnnotatedClass.class.getName());%0A    %7D%0A%0A
     @Test%0A    pu

Add a test