/*******************************************************************************
* Copyright (c) 2013, 2014 David Green and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* David Green - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.wikitext.core.osgi;
import static java.text.MessageFormat.format;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.eclipse.mylyn.wikitext.parser.markup.MarkupLanguage;
import org.eclipse.mylyn.wikitext.util.ServiceLocator;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import com.google.common.base.Throwables;
public class OsgiServiceLocatorTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void create() {
assertNotNull(new OsgiServiceLocator());
}
@Test
public void getAllMarkupLanguages() {
OsgiServiceLocator serviceLocator = createOsgiServiceLocator(
createBundleWithLanguage(MockMarkupLanguage.class));
Set<MarkupLanguage> languages = serviceLocator.getAllMarkupLanguages();
assertNotNull(languages);
assertTrue(!languages.isEmpty());
assertMarkupLanguagePresent("MockMarkupLanguage", languages);
}
@Test
public void getApplicableInstance() {
assertNotNull(OsgiServiceLocator.getApplicableInstance());
}
@Test
public void installAsDefaultImplementation() {
ServiceLocator.setImplementation(OsgiServiceLocator.class);
ServiceLocator instance = ServiceLocator.getInstance();
assertNotNull(instance);
assertEquals(OsgiServiceLocator.class, instance.getClass());
}
@Test
public void installAsDefaultImplementationWithClassLoader() {
ServiceLocator.setImplementation(OsgiServiceLocator.class);
ServiceLocator instance = ServiceLocator.getInstance(OsgiServiceLocatorTest.class.getClassLoader());
assertNotNull(instance);
assertEquals(OsgiServiceLocator.class, instance.getClass());
}
@Test
public void loadsViaMetaInfServices() {
assertLoadsMarkupLanguageFromServicesPath("META-INF/services");
}
@Test
public void loadsViaRootFolder() {
assertLoadsMarkupLanguageFromServicesPath("services");
}
@Test
public void loadsViaBinFolder() {
assertLoadsMarkupLanguageFromServicesPath("bin/services");
}
void assertLoadsMarkupLanguageFromServicesPath(String servicesFolder) {
OsgiServiceLocator serviceLocator = createOsgiServiceLocator(
createBundleWithLanguage(servicesFolder, MockMarkupLanguage.class));
MarkupLanguage markupLanguage = serviceLocator.getMarkupLanguage(MockMarkupLanguage.class.getSimpleName());
assertNotNull(markupLanguage);
}
private Bundle createBundleWithLanguage(Class<? extends MarkupLanguage> markupLanguage) {
return createBundleWithLanguage("META-INF/services", markupLanguage);
}
private Bundle createBundleWithLanguage(String servicesFolder, Class<? extends MarkupLanguage> markupLanguage) {
Bundle bundle = mock(Bundle.class);
try {
URL url = new URL("file:" + markupLanguage.getName());
List<URL> resources = Collections.singletonList(url);
doReturn(Collections.enumeration(resources)).when(bundle).findEntries(eq(servicesFolder),
eq(MarkupLanguage.class.getName()), eq(false));
doReturn(1234L).when(bundle).getBundleId();
doReturn(markupLanguage).when(bundle).loadClass(eq(markupLanguage.getName()));
} catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
return bundle;
}
private OsgiServiceLocator createOsgiServiceLocator(Bundle... bundles) {
final BundleContext context = mock(BundleContext.class);
doReturn(bundles).when(context).getBundles();
return new OsgiServiceLocator() {
@Override
BundleContext getContext() {
return context;
}
@Override
protected List<String> readServiceClassNames(URL url) {
List<String> names = new ArrayList<>();
names.add(url.getPath());
return names;
}
};
}
private void assertMarkupLanguagePresent(String name, Set<MarkupLanguage> languages) {
for (MarkupLanguage language : languages) {
if (language.getName().equals(name)) {
return;
}
}
fail(format("Language {0} expected but not found in {1}", name, languages));
}
}