Author: bdelacretaz Date: Wed Nov 4 23:50:31 2009 New Revision: 832916 URL: http://svn.apache.org/viewvc?rev=832916&view=rev Log: SLING-1166 - Provide helper class for simpler unit testing of sling code. Contributed by Alex Klimetschek, thanks!
Added: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/ sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/ sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/AdapterManagerTestHelper.java (with props) sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockAdapterFactory.java (with props) sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockBundleContext.java (with props) sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockComponentContext.java (with props) sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockServiceReference.java (with props) sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/commons/testing/SlingTestHelper.java (with props) Modified: sling/trunk/bundles/commons/testing/pom.xml Modified: sling/trunk/bundles/commons/testing/pom.xml URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/testing/pom.xml?rev=832916&r1=832915&r2=832916&view=diff ============================================================================== --- sling/trunk/bundles/commons/testing/pom.xml (original) +++ sling/trunk/bundles/commons/testing/pom.xml Wed Nov 4 23:50:31 2009 @@ -91,6 +91,18 @@ <scope>compile</scope> </dependency> <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.adapter</artifactId> + <version>2.0.4</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.jcr.resource</artifactId> + <version>2.0.6</version> + <scope>compile</scope> + </dependency> + <dependency> <groupId>rhino</groupId> <artifactId>js</artifactId> <version>1.6R6</version> Added: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/AdapterManagerTestHelper.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/AdapterManagerTestHelper.java?rev=832916&view=auto ============================================================================== --- sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/AdapterManagerTestHelper.java (added) +++ sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/AdapterManagerTestHelper.java Wed Nov 4 23:50:31 2009 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.adapter.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.sling.api.adapter.AdapterFactory; +import org.apache.sling.commons.testing.osgi.MockBundle; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceReference; + + +/** + * Sets up an {...@link AdapterManagerImpl} in a junit testing environment. This + * class is in the same package as the {...@link AdapterManagerImpl} in order to + * access the protected activate method. + * + */ +public class AdapterManagerTestHelper { + + private static AdapterManagerImpl adapterMgr; + + private static MockComponentContext mockContext; + + private static List<ServiceReference> registeredFactories = new ArrayList<ServiceReference>(); + + private static void initAdapterManager() { + if (adapterMgr == null) { + adapterMgr = new AdapterManagerImpl(); + + mockContext = new MockComponentContext(); + adapterMgr.activate(mockContext); + } + } + + public static void registerAdapterFactory(AdapterFactory adapterFactory, + String[] adaptableClasses, String[] adapterClasses) { + initAdapterManager(); + + Bundle bundle = new MockBundle(1L); + MockServiceReference ref = new MockServiceReference(bundle); + mockContext.addService(ref, adapterFactory); + ref.setProperty(Constants.SERVICE_ID, 1L); + ref.setProperty(AdapterFactory.ADAPTABLE_CLASSES, adaptableClasses); + ref.setProperty(AdapterFactory.ADAPTER_CLASSES, adapterClasses); + adapterMgr.bindAdapterFactory(ref); + + registeredFactories.add(ref); + } + + public static void resetAdapterFactories() { + if (adapterMgr != null) { + for (ServiceReference ref : registeredFactories) { + adapterMgr.unbindAdapterFactory(ref); + } + } + } +} Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/AdapterManagerTestHelper.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/AdapterManagerTestHelper.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev URL Added: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockAdapterFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockAdapterFactory.java?rev=832916&view=auto ============================================================================== --- sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockAdapterFactory.java (added) +++ sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockAdapterFactory.java Wed Nov 4 23:50:31 2009 @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.adapter.internal; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import org.apache.sling.api.adapter.AdapterFactory; + +public class MockAdapterFactory implements AdapterFactory { + + private static final InvocationHandler NOP_INVOCATION_HANDLER = new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + return null; + } + }; + + @SuppressWarnings("unchecked") + public <AdapterType> AdapterType getAdapter(Object adaptable, + Class<AdapterType> type) { + + try { + if (type.isInterface()) { + return (AdapterType) Proxy.newProxyInstance(type.getClassLoader(), + new Class[] { type }, NOP_INVOCATION_HANDLER); + } + + return type.newInstance(); + } catch (Exception e) { + // ignore + } + + return null; + } +} Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockAdapterFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockAdapterFactory.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev URL Added: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockBundleContext.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockBundleContext.java?rev=832916&view=auto ============================================================================== --- sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockBundleContext.java (added) +++ sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockBundleContext.java Wed Nov 4 23:50:31 2009 @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.adapter.internal; + +import java.io.File; +import java.io.InputStream; +import java.util.Dictionary; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.BundleListener; +import org.osgi.framework.Filter; +import org.osgi.framework.FrameworkListener; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceListener; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; + +public class MockBundleContext implements BundleContext { + + public void addBundleListener(BundleListener listener) { + // TODO Auto-generated method stub + + } + + public void addFrameworkListener(FrameworkListener listener) { + // TODO Auto-generated method stub + + } + + public void addServiceListener(ServiceListener listener, String filter) + throws InvalidSyntaxException { + // TODO Auto-generated method stub + + } + + public void addServiceListener(ServiceListener listener) { + // TODO Auto-generated method stub + + } + + public Filter createFilter(String filter) throws InvalidSyntaxException { + // TODO Auto-generated method stub + return null; + } + + public ServiceReference[] getAllServiceReferences(String clazz, + String filter) throws InvalidSyntaxException { + // TODO Auto-generated method stub + return null; + } + + public Bundle getBundle() { + // TODO Auto-generated method stub + return null; + } + + public Bundle getBundle(long id) { + // TODO Auto-generated method stub + return null; + } + + public Bundle[] getBundles() { + // TODO Auto-generated method stub + return null; + } + + public File getDataFile(String filename) { + // TODO Auto-generated method stub + return null; + } + + public String getProperty(String key) { + // TODO Auto-generated method stub + return null; + } + + public Object getService(ServiceReference reference) { + // TODO Auto-generated method stub + return null; + } + + public ServiceReference getServiceReference(String clazz) { + // TODO Auto-generated method stub + return null; + } + + public ServiceReference[] getServiceReferences(String clazz, String filter) + throws InvalidSyntaxException { + // TODO Auto-generated method stub + return null; + } + + public Bundle installBundle(String location, InputStream input) + throws BundleException { + // TODO Auto-generated method stub + return null; + } + + public Bundle installBundle(String location) throws BundleException { + // TODO Auto-generated method stub + return null; + } + + public ServiceRegistration registerService(String clazz, Object service, + Dictionary properties) { + // TODO Auto-generated method stub + return null; + } + + public ServiceRegistration registerService(String[] clazzes, + Object service, Dictionary properties) { + // TODO Auto-generated method stub + return null; + } + + public void removeBundleListener(BundleListener listener) { + // TODO Auto-generated method stub + + } + + public void removeFrameworkListener(FrameworkListener listener) { + // TODO Auto-generated method stub + + } + + public void removeServiceListener(ServiceListener listener) { + // TODO Auto-generated method stub + + } + + public boolean ungetService(ServiceReference reference) { + // TODO Auto-generated method stub + return false; + } + +} Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockBundleContext.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockBundleContext.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev URL Added: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockComponentContext.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockComponentContext.java?rev=832916&view=auto ============================================================================== --- sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockComponentContext.java (added) +++ sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockComponentContext.java Wed Nov 4 23:50:31 2009 @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.adapter.internal; + +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Map; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.ComponentInstance; + +public class MockComponentContext implements ComponentContext { + + private Map<ServiceReference, Object> services = new HashMap<ServiceReference, Object>(); + + public void addService(ServiceReference reference, Object service) { + services.put(reference, service); + } + + public Object locateService(String name, ServiceReference reference) { + return services.get(reference); + } + + public Object locateService(String name) { + return null; + } + + public Object[] locateServices(String name) { + return null; + } + + public void disableComponent(String name) { + } + + public void enableComponent(String name) { + } + + public BundleContext getBundleContext() { + return new MockBundleContext(); + } + + public ComponentInstance getComponentInstance() { + return null; + } + + public Dictionary<?, ?> getProperties() { + return null; + } + + public ServiceReference getServiceReference() { + return null; + } + + public Bundle getUsingBundle() { + return null; + } + +} Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockComponentContext.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockComponentContext.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev URL Added: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockServiceReference.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockServiceReference.java?rev=832916&view=auto ============================================================================== --- sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockServiceReference.java (added) +++ sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockServiceReference.java Wed Nov 4 23:50:31 2009 @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.adapter.internal; + +import java.util.Collections; +import java.util.Dictionary; +import java.util.Hashtable; + +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; + +public class MockServiceReference implements ServiceReference { + + private Bundle bundle; + private Dictionary<String, Object> props; + + public MockServiceReference(Bundle bundle) { + this.bundle = bundle; + this.props = new Hashtable<String, Object>(); + } + + public Bundle getBundle() { + return bundle; + } + + public void setProperty(String key, Object value) { + props.put(key, value); + } + + public Object getProperty(String key) { + return props.get(key); + } + + public String[] getPropertyKeys() { + return Collections.list(props.keys()).toArray(new String[props.size()]); + } + + public Bundle[] getUsingBundles() { + return null; + } + + public boolean isAssignableTo(Bundle bundle, String className) { + return false; + } + + public int compareTo(Object reference) { + return 0; + } +} Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockServiceReference.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/adapter/internal/MockServiceReference.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev URL Added: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/commons/testing/SlingTestHelper.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/commons/testing/SlingTestHelper.java?rev=832916&view=auto ============================================================================== --- sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/commons/testing/SlingTestHelper.java (added) +++ sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/commons/testing/SlingTestHelper.java Wed Nov 4 23:50:31 2009 @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.sling.commons.testing; + +import java.io.IOException; +import java.lang.reflect.Field; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.sling.adapter.internal.AdapterManagerTestHelper; +import org.apache.sling.api.adapter.AdapterFactory; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.jcr.api.SlingRepository; +import org.apache.sling.jcr.resource.JcrResourceResolverFactory; +import org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl; +import org.apache.sling.jcr.resource.internal.helper.Mapping; + +/** + * <code>SlingTestHelper</code> provides various helper methods for accessing + * standard sling features in a test environment without the OSGi service framework + * available. This includes: + * + * - access to a {...@link JcrResourceResolverFactory} and a jcr-based {...@link ResourceResolver} + * - register standard sling node types + * - simple adaptable manager implementation (requires {...@link AdapterManagerTestHelper}) + */ +public class SlingTestHelper { + + public static JcrResourceResolverFactory + getJcrResourceResolverFactory(SlingRepository repository) throws Exception { + + JcrResourceResolverFactoryImpl resFac = new JcrResourceResolverFactoryImpl(); + + // set all fields that are normally resolved by OSGi SCR via reflection + + Field repoField = resFac.getClass().getDeclaredField("repository"); + repoField.setAccessible(true); + repoField.set(resFac, repository); + + Field mappingsField = resFac.getClass().getDeclaredField("mappings"); + mappingsField.setAccessible(true); + mappingsField.set(resFac, new Mapping[] { Mapping.DIRECT }); + + Field searchPathField = resFac.getClass().getDeclaredField("searchPath"); + searchPathField.setAccessible(true); + searchPathField.set(resFac, new String[] { "/apps", "/libs" }); + + return resFac; + } + + public static ResourceResolver getResourceResolver(SlingRepository repository, Session session) throws Exception { + JcrResourceResolverFactory factory = getJcrResourceResolverFactory(repository); + return factory.getResourceResolver(session); + } + + public static void registerSlingNodeTypes(Session adminSession) throws IOException, RepositoryException { + Class<SlingTestHelper> clazz = SlingTestHelper.class; + org.apache.sling.commons.testing.jcr.RepositoryUtil.registerNodeType(adminSession, + clazz.getResourceAsStream("/SLING-INF/nodetypes/folder.cnd")); + org.apache.sling.commons.testing.jcr.RepositoryUtil.registerNodeType(adminSession, + clazz.getResourceAsStream("/SLING-INF/nodetypes/resource.cnd")); + org.apache.sling.commons.testing.jcr.RepositoryUtil.registerNodeType(adminSession, + clazz.getResourceAsStream("/SLING-INF/nodetypes/vanitypath.cnd")); + } + + public static void registerAdapterFactory(AdapterFactory adapterFactory, + String[] adaptableClasses, String[] adapterClasses) { + AdapterManagerTestHelper.registerAdapterFactory(adapterFactory, adaptableClasses, adapterClasses); + } + + public static void resetAdapterFactories() { + AdapterManagerTestHelper.resetAdapterFactories(); + } + + public static void printJCR(Session session) throws RepositoryException { + printJCR(session.getRootNode(), new String[] {}); + } + + public static void printJCR(Node node) throws RepositoryException { + printJCR(node, new String[] {}); + } + + public static void printJCR(Session session, String path, String... props) throws RepositoryException { + printJCR((Node) session.getItem(path), props); + } + + public static void printJCR(Node node, String... props) throws RepositoryException { + System.out.println(node.getPath()); + if (props != null) { + for (String prop: props) { + if (node.hasProperty(prop)) { + Property property = node.getProperty(prop); + System.out.println(property.getPath() + " = " + property.getString()); + } + } + } + NodeIterator nodes = node.getNodes(); + while (nodes.hasNext()) { + Node child = nodes.nextNode(); + if (!child.getName().equals("jcr:system")) { + printJCR(child, props); + } + } + } + +} Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/commons/testing/SlingTestHelper.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/commons/testing/SlingTestHelper.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev URL