package hudson;
import org.jvnet.hudson.test.HudsonTestCase;
import hudson.model.Descriptor;
import hudson.model.Describable;
import hudson.model.Hudson;
import hudson.util.DescriptorList;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.Collection;
/**
* @author Kohsuke Kawaguchi
*/
public class ExtensionListTest extends HudsonTestCase {
//
//
// non-Descriptor extension point
//
//
public interface Animal extends ExtensionPoint {
}
@Extension
public static class Dog implements Animal {
}
@Extension
public static class Cat implements Animal {
}
public void testAutoDiscovery() throws Exception {
ExtensionList<Animal> list = hudson.getExtensionList(Animal.class);
assertEquals(2,list.size());
assertNotNull(list.get(Dog.class));
assertNotNull(list.get(Cat.class));
}
public void testExtensionListView() throws Exception {
// this is how legacy list like UserNameResolver.LIST gets created.
List<Animal> LIST = ExtensionListView.createList(Animal.class);
// we should see auto-registered instances here
assertEquals(2,LIST.size());
assertTrue(hasInstanceOf(LIST,Dog.class));
assertTrue(hasInstanceOf(LIST,Cat.class));
Animal lion = new Animal() {};
LIST.add(lion);
assertEquals(3,LIST.size());
assertTrue(LIST.contains(lion));
}
private boolean hasInstanceOf(Collection c, Class type) {
for (Object o : c)
if(o.getClass()==type)
return true;
return false;
}
//
//
// Descriptor extension point
//
//
public static abstract class FishDescriptor extends Descriptor<Fish> {
public String getDisplayName() {
return clazz.getName();
}
}
public static abstract class Fish implements Describable<Fish> {
public Descriptor<Fish> getDescriptor() {
return Hudson.getInstance().getDescriptor(getClass());
}
}
public static class Tai extends Fish {
@Extension
public static final class DescriptorImpl extends FishDescriptor {}
}
public static class Saba extends Fish {
@Extension
public static final class DescriptorImpl extends FishDescriptor {}
}
public static class Sishamo extends Fish {
public static final class DescriptorImpl extends FishDescriptor {}
}
/**
* Verifies that the automated {@link Descriptor} lookup works.
*/
public void testDescriptorLookup() throws Exception {
Descriptor<Fish> d = new Sishamo().getDescriptor();
DescriptorExtensionList<Fish,Descriptor<Fish>> list = hudson.<Fish,Descriptor<Fish>>getDescriptorList(Fish.class);
assertSame(d,list.get(Sishamo.DescriptorImpl.class));
assertSame(d,hudson.getDescriptor(Sishamo.class));
}
public void testFishDiscovery() throws Exception {
// imagine that this is a static instance, like it is in many LIST static field in Hudson.
DescriptorList<Fish> LIST = new DescriptorList<Fish>(Fish.class);
DescriptorExtensionList<Fish,Descriptor<Fish>> list = hudson.<Fish,Descriptor<Fish>>getDescriptorList(Fish.class);
assertEquals(2,list.size());
assertNotNull(list.get(Tai.DescriptorImpl.class));
assertNotNull(list.get(Saba.DescriptorImpl.class));
// registration can happen later, and it should be still visible
LIST.add(new Sishamo.DescriptorImpl());
assertEquals(3,list.size());
assertNotNull(list.get(Sishamo.DescriptorImpl.class));
// all 3 should be visisble from LIST, too
assertEquals(3,LIST.size());
assertNotNull(LIST.findByName(Tai.class.getName()));
assertNotNull(LIST.findByName(Sishamo.class.getName()));
assertNotNull(LIST.findByName(Saba.class.getName()));
// DescriptorList can be gone and new one created but it should still have the same list
LIST = new DescriptorList<Fish>(Fish.class);
assertEquals(3,LIST.size());
assertNotNull(LIST.findByName(Tai.class.getName()));
assertNotNull(LIST.findByName(Sishamo.class.getName()));
assertNotNull(LIST.findByName(Saba.class.getName()));
}
public void testLegacyDescriptorList() throws Exception {
// created in a legacy fashion without any tie to ExtensionList
DescriptorList<Fish> LIST = new DescriptorList<Fish>();
// we won't auto-discover anything
assertEquals(0,LIST.size());
// registration can happen later, and it should be still visible
LIST.add(new Sishamo.DescriptorImpl());
assertEquals(1,LIST.size());
assertNotNull(LIST.findByName(Sishamo.class.getName()));
// create a new list and it forgets everything.
LIST = new DescriptorList<Fish>();
assertEquals(0,LIST.size());
}
public static class Car implements ExtensionPoint {
final String name;
public Car(String name) {
this.name = name;
}
}
@Extension(ordinal=1)
public static class Toyota extends Car {
public Toyota() {
super("toyota");
}
}
@Extension(ordinal=3)
public static Car honda() { return new Car("honda"); }
@Extension(ordinal=2)
public static final Car mazda = new Car("mazda");
/**
* Makes sure sorting of the components work as expected.
*/
public void testOrdinals() {
ExtensionList<Car> list = hudson.getExtensionList(Car.class);
assertEquals("honda",list.get(0).name);
assertEquals("mazda",list.get(1).name);
assertEquals("toyota",list.get(2).name);
}
}