/*
* Copyright (c) 2012, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.util.service;
import com.twelvemonkeys.util.CollectionUtil;
import org.junit.Test;
import java.util.*;
import static org.junit.Assert.*;
/**
* ServiceRegistryTest
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: ServiceRegistryTest.java,v 1.0 25.01.12 16:16 haraldk Exp$
*/
public class ServiceRegistryTest {
private final TestRegistry registry = new TestRegistry();
@Test(expected = IllegalArgumentException.class)
public void testCreateNull() {
new ServiceRegistry(null);
}
@Test
public void testCreateEmptyIterator() {
// A completely useless registry...
ServiceRegistry registry = new ServiceRegistry(Collections.<Class<?>>emptyList().iterator());
registry.registerApplicationClasspathSPIs();
while (registry.categories().hasNext()) {
fail("No categories");
}
}
@Test(expected = ServiceConfigurationError.class)
public void testCreateBadConfig() {
@SuppressWarnings("unchecked")
ServiceRegistry registry = new ServiceRegistry(Arrays.asList(BadSPI.class).iterator());
registry.registerApplicationClasspathSPIs();
// DONE: Test non-class
// TODO: Test class not implementing SPI category
// TODO: Test class that throws exception in constructor
// TODO: Test class that has no public no-args constructor
// TODO: Test IOException
// Some of these can be tested using stubs, via the package protected registerSPIs method
}
@Test
public void testCategories() {
// Categories
Iterator<Class<?>> categories = registry.categories();
assertTrue(categories.hasNext());
Class<?> category = categories.next();
assertEquals(DummySPI.class, category);
assertFalse(categories.hasNext());
}
@Test
public void testProviders() {
// Providers
Iterator<DummySPI> providers = registry.providers(DummySPI.class);
List<DummySPI> providerList = new ArrayList<DummySPI>();
CollectionUtil.addAll(providerList, providers);
assertEquals(2, providerList.size());
// Order should be as in configuration file
assertNotNull(providerList.get(0));
assertEquals(DummySPIImpl.class, providerList.get(0).getClass());
assertNotNull(providerList.get(1));
assertEquals(DummySPIToo.class, providerList.get(1).getClass());
}
@Test
public void testCompatibleCategoriesNull() {
// Compatible categories
Iterator<Class<?>> categories = registry.compatibleCategories(null);
assertFalse(categories.hasNext());
}
@Test
public void testCompatibleCategoriesImpl() {
Iterator<Class<?>> categories = registry.compatibleCategories(new DummySPIImpl());
assertTrue(categories.hasNext());
assertEquals(DummySPI.class, categories.next());
assertFalse(categories.hasNext());
}
@Test
public void testCompatibleCategoriesToo() {
Iterator<Class<?>> categories = registry.compatibleCategories(new DummySPIToo());
assertTrue(categories.hasNext());
assertEquals(DummySPI.class, categories.next());
assertFalse(categories.hasNext());
}
@Test
public void testCompatibleCategoriesNonRegistered() {
Iterator<Class<?>> categories = registry.compatibleCategories(new DummySPI() {});
assertTrue(categories.hasNext());
assertEquals(DummySPI.class, categories.next());
assertFalse(categories.hasNext());
}
@Test
public void testCompatibleCategoriesUnknownType() {
Iterator<Class<?>> categories = registry.compatibleCategories(new Object());
assertFalse(categories.hasNext());
}
@Test
public void testContainingCategoriesNull() {
// Containing categories
Iterator<Class<?>> categories = registry.containingCategories(null);
assertFalse(categories.hasNext());
}
@Test
public void testContainingCategoriesKnownInstanceImpl() {
Iterator<DummySPI> providers = registry.providers(DummySPI.class);
assertTrue(providers.hasNext()); // Sanity check
Iterator<Class<?>> categories = registry.containingCategories(providers.next());
assertTrue(categories.hasNext());
assertEquals(DummySPI.class, categories.next());
assertFalse(categories.hasNext());
}
@Test
public void testContainingCategoriesKnownInstanceToo() {
Iterator<DummySPI> providers = registry.providers(DummySPI.class);
providers.next();
assertTrue(providers.hasNext()); // Sanity check
Iterator<Class<?>> categories = registry.containingCategories(providers.next());
assertTrue(categories.hasNext());
assertEquals(DummySPI.class, categories.next());
assertFalse(categories.hasNext());
}
@Test
public void testContainingCategoriesNewInstanceRegisteredImpl() {
// NOTE: Currently we match based on type, rather than instance, but it does make sense...
Iterator<Class<?>> categories = registry.containingCategories(new DummySPIImpl());
assertTrue(categories.hasNext());
assertEquals(DummySPI.class, categories.next());
assertFalse(categories.hasNext());
}
@Test
public void testContainingCategoriesNewInstanceRegisteredToo() {
// NOTE: Currently we match based on type, rather than instance, but it does make sense...
Iterator<Class<?>> categories = registry.containingCategories(new DummySPIToo());
assertTrue(categories.hasNext());
assertEquals(DummySPI.class, categories.next());
assertFalse(categories.hasNext());
}
@Test
public void testContainingCategoriesCompatibleNonRegisteredType() {
Iterator<Class<?>> categories = registry.containingCategories(new DummySPI() {});
assertFalse(categories.hasNext());
}
@Test
public void testContainingCategoriesUnknownType() {
Iterator<Class<?>> categories = registry.containingCategories(new Object());
assertFalse(categories.hasNext());
}
@Test
public void testRegister() {
// Register
DummySPI dummy = new DummySPI() {};
assertTrue(registry.register(dummy));
// Should now have category
Iterator<Class<?>> categories = registry.containingCategories(dummy);
assertTrue(categories.hasNext());
assertEquals(DummySPI.class, categories.next());
assertFalse(categories.hasNext());
// Should now be in providers
Iterator<DummySPI> providers = registry.providers(DummySPI.class);
List<DummySPI> providerList = new ArrayList<DummySPI>();
CollectionUtil.addAll(providerList, providers);
assertEquals(3, providerList.size());
assertNotNull(providerList.get(1));
assertSame(dummy, providerList.get(2));
}
@Test
public void testRegisterAlreadyRegistered() {
Iterator<DummySPI> providers = registry.providers(DummySPI.class);
assertTrue(providers.hasNext()); // Sanity check
assertFalse(registry.register(providers.next()));
}
@Test
public void testRegisterNull() {
assertFalse(registry.register(null));
}
@Test
public void testRegisterIncompatible() {
assertFalse(registry.register(new Object()));
}
@Test
public void testDeregisterNull() {
assertFalse(registry.deregister(null));
}
@Test
public void testDeregisterIncompatible() {
assertFalse(registry.deregister(new Object()));
}
@Test
public void testDeregisterCompatibleNonRegistered() {
DummySPI dummy = new DummySPI() {};
assertFalse(registry.deregister(dummy));
}
@Test
public void testDeregister() {
Iterator<DummySPI> providers = registry.providers(DummySPI.class);
assertTrue(providers.hasNext()); // Sanity check
DummySPI instance = providers.next();
assertTrue(registry.deregister(instance));
// Test no longer in registry
providers = registry.providers(DummySPI.class);
int count = 0;
while (providers.hasNext()) {
DummySPI next = providers.next();
assertNotSame(instance, next);
count++;
}
assertEquals(1, count);
}
// TODO: Test register with category
// TODO: Test register with unknown category
// TODO: Test register with null category
// TODO: Test de-register with category
// TODO: Test de-register with unknown category
// TODO: Test de-register with null category
private static class TestRegistry extends ServiceRegistry {
@SuppressWarnings("unchecked")
public TestRegistry() {
super(Arrays.asList(DummySPI.class).iterator());
registerApplicationClasspathSPIs();
}
}
public static class BadSPI {}
}