Repository: weld/weld-junit (java)

Issue:
@Any qualifier not added automatically by mock bean builder
A bean created with the following code:
```java
MockBean.builder()
        .scope(ApplicationScoped)
        .types(new TypeLiteral<ParameterConverter<Object, Object>>() { }.type)
        .qualifiers(new ParameterType.Literal('foo'))
        .creating(fooParameterConverter)
        .build();
```
will not be injected into an injection point that uses the `@Any` qualifier like
```java
@Inject
@Any
private Instance<ParameterConverter<?, ?>> parameterConverters;
```

I just had a hard time understanding why this is the case.
Shouldn't the `@Any` qualifier always be added implicitly to a bean like the CDI spec defines?

Work-around is to manually add the `@Any` qualifier like `.qualifiers(Any.Literal.INSTANCE, new ParameterType.Literal('foo'))`

Pull request:
MockBean should add @Any qualifier by default.
Fixes #97 

Patch:
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/MockBean.java b/junit-common/src/main/java/org/jboss/weld/junit/MockBean.java
index 24a0e68..df3ce1c 100644
--- a/junit-common/src/main/java/org/jboss/weld/junit/MockBean.java
+++ b/junit-common/src/main/java/org/jboss/weld/junit/MockBean.java
@@ -46,6 +46,7 @@ import javax.inject.Scope;
 
 import org.jboss.weld.environment.se.Weld;
 import org.jboss.weld.environment.se.WeldContainer;
+import org.jboss.weld.util.collections.ImmutableSet;
 import org.jboss.weld.util.reflection.HierarchyDiscovery;
 
 /**
@@ -608,27 +609,28 @@ public class MockBean<T> implements Bean<T>, PassivationCapable {
             if (createCallback == null) {
                 throw new IllegalStateException("Create callback must not be null");
             }
-            if (qualifiers.size() == 1) {
-                Annotation qualifier = qualifiers.iterator().next();
-                if (qualifier.annotationType().equals(Named.class) || qualifier.equals(AnyLiteral.INSTANCE)) {
-                    // Single qualifier - @Named or @Any
-                    qualifiers.add(DefaultLiteral.INSTANCE);
-                }
-            } else if (qualifiers.size() == 2 && qualifiers.contains(AnyLiteral.INSTANCE)) {
-                for (Annotation qualifier : qualifiers) {
-                    if (qualifier.annotationType().equals(Named.class)) {
-                        // Two qualifiers - @Named and @Any
-                        qualifiers.add(DefaultLiteral.INSTANCE);
-                        break;
-                    }
+            Set<Annotation> normalizedQualfiers = new HashSet<Annotation>(qualifiers);
+            normalizedQualfiers.remove(Any.Literal.INSTANCE);
+            normalizedQualfiers.remove(Default.Literal.INSTANCE);
+            if (normalizedQualfiers.isEmpty()) {
+                normalizedQualfiers.add(Default.Literal.INSTANCE);
+                normalizedQualfiers.add(Any.Literal.INSTANCE);
+            } else {
+                ImmutableSet.Builder<Annotation> builder = ImmutableSet.builder();
+                if (normalizedQualfiers.size() == 1
+                        && normalizedQualfiers.iterator().next().annotationType().equals(Named.class)) {
+                    builder.add(Default.Literal.INSTANCE);
                 }
+                builder.add(Any.Literal.INSTANCE);
+                builder.addAll(qualifiers);
+                normalizedQualfiers = builder.build();
             }
             // if given any priority, we will instead initialize MockBeanWithPriority
             if (priority != null) {
-                return new MockBeanWithPriority<>(beanClass, stereotypes, alternative, selectForSyntheticBeanArchive, priority, name, qualifiers, types, scope, createCallback,
+                return new MockBeanWithPriority<>(beanClass, stereotypes, alternative, selectForSyntheticBeanArchive, priority, name, normalizedQualfiers, types, scope, createCallback,
                         destroyCallback);
             } else {
-                return new MockBean<>(beanClass, stereotypes, alternative, selectForSyntheticBeanArchive, name, qualifiers, types, scope, createCallback,
+                return new MockBean<>(beanClass, stereotypes, alternative, selectForSyntheticBeanArchive, name, normalizedQualfiers, types, scope, createCallback,
                         destroyCallback);
             }
         }


Test patch:
diff --git a/junit4/src/test/java/org/jboss/weld/junit4/bean/MockBeanWithQualifiersTest.java b/junit4/src/test/java/org/jboss/weld/junit4/bean/MockBeanWithQualifiersTest.java
new file mode 100644
index 0000000..73e9492
--- /dev/null
+++ b/junit4/src/test/java/org/jboss/weld/junit4/bean/MockBeanWithQualifiersTest.java
@@ -0,0 +1,25 @@
+package org.jboss.weld.junit4.bean;
+
+import org.jboss.weld.junit.MockBean;
+import org.jboss.weld.junit4.WeldInitiator;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+
+import javax.enterprise.inject.Any;
+
+/**
+ * Tests that {@link MockBean} with custom qualifiers has {@link Any} qualifier automatically added.
+ */
+public class MockBeanWithQualifiersTest {
+
+    @Rule
+    public WeldInitiator weld = WeldInitiator.from(MockBeanWithQualifiersTest.class)
+            .addBeans(MockBean.builder().types(String.class).qualifiers(Meaty.Literal.INSTANCE).create(c -> "foo").build())
+            .build();
+
+    @Test
+    public void testBeanHasDefaultQualifiersAdded() {
+        Assert.assertEquals("foo", weld.select(String.class, Any.Literal.INSTANCE).get());
+    }
+}
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/bean/MockBeanWithQualifiersTest.java b/junit5/src/test/java/org/jboss/weld/junit5/bean/MockBeanWithQualifiersTest.java
new file mode 100644
index 0000000..2da7c3b
--- /dev/null
+++ b/junit5/src/test/java/org/jboss/weld/junit5/bean/MockBeanWithQualifiersTest.java
@@ -0,0 +1,27 @@
+package org.jboss.weld.junit5.bean;
+
+import org.jboss.weld.junit.MockBean;
+import org.jboss.weld.junit5.EnableWeld;
+import org.jboss.weld.junit5.WeldInitiator;
+import org.jboss.weld.junit5.WeldSetup;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import javax.enterprise.inject.Any;
+
+/**
+ * Tests that {@link MockBean} with custom qualifiers has {@link Any} qualifier automatically added.
+ */
+@EnableWeld
+public class MockBeanWithQualifiersTest {
+
+    @WeldSetup
+    public WeldInitiator weld = WeldInitiator.from(AlternativeMockBeanTest.SimpleService.class)
+            .addBeans(MockBean.builder().types(String.class).qualifiers(Meaty.Literal.INSTANCE).create(c -> "foo").build())
+            .build();
+
+    @Test
+    public void testBeanHasDefaultQualifiersAdded() {
+        Assertions.assertEquals("foo", weld.select(String.class, Any.Literal.INSTANCE).get());
+    }
+}