/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.cdi.tck.tests.lookup.typesafe.resolution.parameterized;
import static org.jboss.cdi.tck.cdi.Sections.ASSIGNABLE_PARAMETERS;
import static org.jboss.cdi.tck.cdi.Sections.LEGAL_BEAN_TYPES;
import static org.jboss.cdi.tck.cdi.Sections.LEGAL_INJECTION_POINT_TYPES;
import static org.jboss.cdi.tck.cdi.Sections.PERFORMING_TYPESAFE_RESOLUTION;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.util.TypeLiteral;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.cdi.tck.AbstractTest;
import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.test.audit.annotations.SpecAssertion;
import org.jboss.test.audit.annotations.SpecAssertions;
import org.jboss.test.audit.annotations.SpecVersion;
import org.testng.annotations.Test;
/**
*
* @author Martin Kouba
* @author Matus Abaffy
*/
@SuppressWarnings("serial")
@SpecVersion(spec = "cdi", version = "2.0-PFD")
public class AssignabilityOfRawAndParameterizedTypesTest extends AbstractTest {
private static final Class<?>[] RESULT_TYPES = new Class<?>[] { ResultImpl.class, Result.class, Object.class };
private static final Class<?>[] DAO_TYPES = new Class<?>[] { Dao.class, Object.class };
private static final Class<?>[] BOX_TYPES = new Class<?>[] { BoxBarBazFooImpl.class, Box.class, Object.class };
@Deployment
public static WebArchive createTestArchive() {
return new WebArchiveBuilder().withTestClassPackage(AssignabilityOfRawAndParameterizedTypesTest.class).build();
}
@Test
@SpecAssertions({ @SpecAssertion(section = PERFORMING_TYPESAFE_RESOLUTION, id = "kb"), @SpecAssertion(section = LEGAL_BEAN_TYPES, id = "f"),
@SpecAssertion(section = LEGAL_BEAN_TYPES, id = "g"), @SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "a") })
public void testAssignabilityToRawType() {
// Dao, DaoProducer.getDao(), DaoProducer.getRawDao and ObjectDao
// IntegerDao is not assignable to the raw required type Dao
assertEquals(getBeans(Dao.class).size(), 4);
}
@Test
@SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "ba")
public void testAssignabilityOfParameterizedTypeWithActualTypesToParameterizedTypeWithActualTypes() {
assert getBeans(new TypeLiteral<Map<Integer, Integer>>() {
}).size() == 2;
assert getBeans(new TypeLiteral<HashMap<Integer, Integer>>() {
}).iterator().next().getTypes().contains(IntegerHashMap.class);
}
@Test
@SpecAssertions({ @SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "c") })
public void testAssignabilityOfParameterizedTypeWithActualTypesToParameterizedTypeWithWildcards() {
assert getBeans(new TypeLiteral<HashMap<? extends Number, ? super Integer>>() {
}).size() == 1;
assert getBeans(new TypeLiteral<HashMap<? extends Number, ? super Integer>>() {
}).iterator().next().getTypes().contains(IntegerHashMap.class);
}
@Test
@SpecAssertions({ @SpecAssertion(section = LEGAL_INJECTION_POINT_TYPES, id = "b") })
public void testAssignabilityOfParameterizedTypeWithActualTypesToParameterizedTypeWithWildcardsAtInjectionPoint() {
assert getContextualReference(InjectedBean.class).getMap() instanceof IntegerHashMap;
}
@Test
@SpecAssertions({ @SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "da"),
@SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "dc") })
public void testAssignabilityOfParameterizedTypeWithTypeVariablesToParameterizedTypeWithWildcards() {
Set<Bean<Result<? extends Throwable, ? super Exception>>> beans = getBeans(new TypeLiteral<Result<? extends Throwable, ? super Exception>>() {
});
assert beans.size() == 1;
assert rawTypeSetMatches(beans.iterator().next().getTypes(), RESULT_TYPES);
}
@Test
@SpecAssertions({ @SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "db"),
@SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "dc") })
public void testAssignabilityOfParameterizedTypeWithTypeVariablesToParameterizedTypeWithWildcards2() {
Set<Bean<Result<? extends RuntimeException, ? super RuntimeException>>> beans = getBeans(new TypeLiteral<Result<? extends RuntimeException, ? super RuntimeException>>() {
});
assert beans.size() == 1;
assert rawTypeSetMatches(beans.iterator().next().getTypes(), RESULT_TYPES);
}
@Test
@SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "dc")
public <T1 extends SubBar & SubBaz & Foo,
T2 extends BarBazImpl & Foo,
T3 extends SubBar & SubBaz & SuperFoo,
T4 extends SubBar & SubBaz,
T5 extends BarBazSuperFooImpl,
T6 extends BarBazSuperFooImpl & SuperBarFooCloneable> void testAssignabilityOfParameterizedTypeWithTypeVariablesToParameterizedTypeWithWildcardWithLowerBound() {
Set<Bean<Result<? extends Exception, ? super Throwable>>> beans = getBeans(new TypeLiteral<Result<? extends Exception, ? super Throwable>>() {
});
assertEquals(beans.size(), 0);
Set<Bean<Box<? super T1>>> beans1 = getBeans(new TypeLiteral<Box<? super T1>>() {
});
assertEquals(beans1.size(), 1);
assertTrue(rawTypeSetMatches(beans1.iterator().next().getTypes(), BOX_TYPES));
Set<Bean<Box<? super T2>>> beans2 = getBeans(new TypeLiteral<Box<? super T2>>() {
});
assertEquals(beans2.size(), 1);
assertTrue(rawTypeSetMatches(beans2.iterator().next().getTypes(), BOX_TYPES));
// SuperFoo does not extend Foo
Set<Bean<Box<? super T3>>> noBeans3 = getBeans(new TypeLiteral<Box<? super T3>>() {
});
assertEquals(noBeans3.size(), 0);
// does not extend Foo
Set<Bean<Box<? super T4>>> noBeans4 = getBeans(new TypeLiteral<Box<? super T4>>() {
});
assertEquals(noBeans4.size(), 0);
// SuperFoo does not extend Foo
Set<Bean<Box<? super T5>>> noBeans5 = getBeans(new TypeLiteral<Box<? super T5>>() {
});
assertEquals(noBeans5.size(), 0);
Set<Bean<Box<? super T6>>> beans6 = getBeans(new TypeLiteral<Box<? super T6>>() {
});
assertEquals(beans6.size(), 1);
assertTrue(rawTypeSetMatches(beans6.iterator().next().getTypes(), BOX_TYPES));
}
@Test
@SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "e")
public void testAssignabilityOfParameterizedTypeWithTypeVariablesToParameterizedTypeWithActualTypes() {
Set<Bean<Result<RuntimeException, IllegalStateException>>> beans = getBeans(new TypeLiteral<Result<RuntimeException, IllegalStateException>>() {
});
assert beans.size() == 1;
assert rawTypeSetMatches(beans.iterator().next().getTypes(), RESULT_TYPES);
Set<Bean<Result<RuntimeException, Throwable>>> noBeans = getBeans(new TypeLiteral<Result<RuntimeException, Throwable>>() {
});
assertEquals(noBeans.size(), 0);
}
@Test
@SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "e")
public void testAssignabilityOfParameterizedTypeWithTypeVariablesWithMultipleBoundsToParameterizedTypeWithActualTypes() {
Set<Bean<Box<BarSubBazFooImpl>>> beans = getBeans(new TypeLiteral<Box<BarSubBazFooImpl>>() {
});
assertEquals(beans.size(), 1);
assertTrue(rawTypeSetMatches(beans.iterator().next().getTypes(), BOX_TYPES));
// SuperFoo is not inside BoxBarBazFooImpl's bounds
Set<Bean<Box<BarBazSuperFooImpl>>> noBeans1 = getBeans(new TypeLiteral<Box<BarBazSuperFooImpl>>() {
});
assertEquals(noBeans1.size(), 0);
// BarBazImpl does not extend Baz, which is required by BoxBarBazFooImpl's bounds
Set<Bean<Box<BarBazImpl>>> noBeans2 = getBeans(new TypeLiteral<Box<BarBazImpl>>() {
});
assertEquals(noBeans2.size(), 0);
}
@Test
@SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "f")
public <T1 extends RuntimeException, T2 extends T1, T3> void testAssignabilityOfParameterizedTypeWithTypeVariablesToParameterizedTypeWithTypeVariable() {
Set<Bean<Result<T1, T2>>> beans = getBeans(new TypeLiteral<Result<T1, T2>>() {
});
assert beans.size() == 1;
assert rawTypeSetMatches(beans.iterator().next().getTypes(), RESULT_TYPES);
Set<Bean<Result<T1, T3>>> noBeans = getBeans(new TypeLiteral<Result<T1, T3>>() {
});
assertEquals(noBeans.size(), 0);
Set<Bean<Dao<T1, T3>>> daoBeans = getBeans(new TypeLiteral<Dao<T1, T3>>() {
});
assertEquals(daoBeans.size(), 1);
assertTrue(rawTypeSetMatches(daoBeans.iterator().next().getTypes(), DAO_TYPES));
}
@Test
@SpecAssertion(section = ASSIGNABLE_PARAMETERS, id = "f")
public <T1 extends SubBar & SubBaz & Foo,
T2 extends BarBazImpl & Foo,
T3 extends SubBar & SubBaz & SuperFoo,
T4 extends SubBar & SubBaz,
T5 extends BarBazSuperFooImpl,
T6 extends BarBazSuperFooImpl & SuperBarFooCloneable> void testAssignabilityOfParameterizedTypeWithTypeVariableWithMultipleBoundsToParameterizedTypeWithTypeVariable() {
Set<Bean<Box<T1>>> beans1 = getBeans(new TypeLiteral<Box<T1>>() {
});
assertEquals(beans1.size(), 1);
assertTrue(rawTypeSetMatches(beans1.iterator().next().getTypes(), BOX_TYPES));
Set<Bean<Box<T2>>> beans2 = getBeans(new TypeLiteral<Box<T2>>() {
});
assertEquals(beans2.size(), 1);
assertTrue(rawTypeSetMatches(beans2.iterator().next().getTypes(), BOX_TYPES));
// SuperFoo does not extend Foo
Set<Bean<Box<T3>>> noBeans3 = getBeans(new TypeLiteral<Box<T3>>() {
});
assertEquals(noBeans3.size(), 0);
// does not extend Foo
Set<Bean<Box<T4>>> noBeans4 = getBeans(new TypeLiteral<Box<T4>>() {
});
assertEquals(noBeans4.size(), 0);
// SuperFoo does not extend Foo
Set<Bean<Box<T5>>> noBeans5 = getBeans(new TypeLiteral<Box<T5>>() {
});
assertEquals(noBeans5.size(), 0);
Set<Bean<Box<T6>>> beans6 = getBeans(new TypeLiteral<Box<T6>>() {
});
assertEquals(beans6.size(), 1);
assertTrue(rawTypeSetMatches(beans6.iterator().next().getTypes(), BOX_TYPES));
}
}