/* * 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)); } }