You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2020/04/29 09:54:42 UTC
[sling-org-apache-sling-testing-sling-mock] branch master updated:
SLING-9407 sling-mock: Add mock for ResourceBundleProvider and
ResourceBundle (i18n)
This is an automated email from the ASF dual-hosted git repository.
sseifert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-sling-mock.git
The following commit(s) were added to refs/heads/master by this push:
new 461ac0e SLING-9407 sling-mock: Add mock for ResourceBundleProvider and ResourceBundle (i18n)
461ac0e is described below
commit 461ac0e0373d0741467d0329c10e29fb2d242464
Author: sseifert <ss...@pro-vision.de>
AuthorDate: Wed Apr 29 11:53:02 2020 +0200
SLING-9407 sling-mock: Add mock for ResourceBundleProvider and ResourceBundle (i18n)
---
.../testing/mock/sling/MockResourceBundle.java | 95 ++++++++++++++++
.../mock/sling/MockResourceBundleProvider.java | 126 +++++++++++++++++++++
.../mock/sling/context/SlingContextImpl.java | 2 +
.../sling/testing/mock/sling/package-info.java | 2 +-
.../mock/sling/MockResourceBundleProviderTest.java | 82 ++++++++++++++
.../testing/mock/sling/MockResourceBundleTest.java | 65 +++++++++++
6 files changed, 371 insertions(+), 1 deletion(-)
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/MockResourceBundle.java b/core/src/main/java/org/apache/sling/testing/mock/sling/MockResourceBundle.java
new file mode 100644
index 0000000..8d01887
--- /dev/null
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/MockResourceBundle.java
@@ -0,0 +1,95 @@
+/*
+ * 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.testing.mock.sling;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Mock implementation of an i18n {@link ResourceBundle}.
+ * Contains no translations by default and returns the key itself.
+ * But you can add your own mappings.
+ */
+public final class MockResourceBundle extends ResourceBundle {
+
+ private final String baseName;
+ private final Locale locale;
+ private final Map<String, String> mappings = new HashMap<>();
+
+ /**
+ * @param baseName Base name
+ * @param locale Locale
+ */
+ public MockResourceBundle(String baseName, Locale locale) {
+ this.baseName = baseName;
+ this.locale = locale;
+ }
+
+ @Override
+ public Locale getLocale() {
+ return locale;
+ }
+
+ @Override
+ protected Object handleGetObject(String key) {
+ return mappings.getOrDefault(key, key);
+ }
+
+ @Override
+ public Set<String> keySet() {
+ return mappings.keySet();
+ }
+
+ @Override
+ public Enumeration<String> getKeys() {
+ return Collections.enumeration(mappings.keySet());
+ }
+
+ /**
+ * @return Base name
+ */
+ public String getBaseName() {
+ return baseName;
+ }
+
+ /**
+ * Add translation.
+ * @param key Key
+ * @param value Value
+ */
+ public void put(@NotNull String key, @NotNull String value) {
+ mappings.put(key, value);
+ }
+
+ /**
+ * Add translations.
+ * @param map Translation map
+ */
+ public void putAll(@NotNull Map<? extends String, ? extends String> map) {
+ mappings.putAll(map);
+ }
+
+}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/MockResourceBundleProvider.java b/core/src/main/java/org/apache/sling/testing/mock/sling/MockResourceBundleProvider.java
new file mode 100644
index 0000000..8e6418e
--- /dev/null
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/MockResourceBundleProvider.java
@@ -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.testing.mock.sling;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.sling.i18n.ResourceBundleProvider;
+import org.osgi.service.component.annotations.Component;
+
+/**
+ * Mock implementation of @link {@link ResourceBundleProvider} then ensures
+ * resolving i18n keys does not lead to exceptions. By default it contains no
+ * translations, but it's possible to add you own mapping in unit tests.
+ */
+@Component(service = ResourceBundleProvider.class)
+public final class MockResourceBundleProvider implements ResourceBundleProvider {
+
+ private final ConcurrentHashMap<Key, MockResourceBundle> resourceBundleCache = new ConcurrentHashMap<>();
+ private Locale defaultLocale = Locale.US;
+
+ @Override
+ public Locale getDefaultLocale() {
+ return defaultLocale;
+ }
+
+ @Override
+ public ResourceBundle getResourceBundle(final Locale locale) {
+ return getResourceBundle(null, locale);
+ }
+
+ @Override
+ public ResourceBundle getResourceBundle(final String baseName, final Locale locale) {
+ Locale bundleLocale = locale != null ? locale : defaultLocale;
+ Key key = new Key(baseName, bundleLocale);
+ return resourceBundleCache.computeIfAbsent(key, k -> new MockResourceBundle(k.baseName, k.locale));
+ }
+
+ /**
+ * Sets the default locale.
+ * @param defaultLocale Default locale
+ */
+ public void setDefaultLocale(Locale defaultLocale) {
+ this.defaultLocale = defaultLocale;
+ }
+
+ /**
+ * The <code>Key</code> class encapsulates the base name and Locale in a
+ * single object that can be used as the key in a <code>HashMap</code>.
+ */
+ private static final class Key {
+ final String baseName;
+ final Locale locale;
+
+ // precomputed hash code, because this will always be used due to
+ // this instance being used as a key in a HashMap.
+ private final int hashCode;
+
+ Key(final String baseName, final Locale locale) {
+
+ int hc = 0;
+ if (baseName != null) {
+ hc += 17 * baseName.hashCode();
+ }
+ if (locale != null) {
+ hc += 13 * locale.hashCode();
+ }
+
+ this.baseName = baseName;
+ this.locale = locale;
+ this.hashCode = hc;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ } else if (obj instanceof Key) {
+ Key other = (Key) obj;
+ return equals(this.baseName, other.baseName)
+ && equals(this.locale, other.locale);
+ }
+
+ return false;
+ }
+
+ private static boolean equals(Object o1, Object o2) {
+ if (o1 == null) {
+ if (o2 != null) {
+ return false;
+ }
+ } else if (!o1.equals(o2)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "Key(" + baseName + ", " + locale + ")";
+ }
+ }
+
+}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/context/SlingContextImpl.java b/core/src/main/java/org/apache/sling/testing/mock/sling/context/SlingContextImpl.java
index b6e7ca3..5a90f46 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/context/SlingContextImpl.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/context/SlingContextImpl.java
@@ -47,6 +47,7 @@ import org.apache.sling.scripting.core.impl.BindingsValuesProvidersByContextImpl
import org.apache.sling.settings.SlingSettingsService;
import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.apache.sling.testing.mock.osgi.context.OsgiContextImpl;
+import org.apache.sling.testing.mock.sling.MockResourceBundleProvider;
import org.apache.sling.testing.mock.sling.MockSling;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.builder.ContentBuilder;
@@ -179,6 +180,7 @@ public class SlingContextImpl extends OsgiContextImpl {
registerService(MimeTypeService.class, new MockMimeTypeService());
registerInjectActivateService(new ResourceBuilderFactoryService());
registerInjectActivateService(new JcrObjectsBindingsValuesProvider());
+ registerInjectActivateService(new MockResourceBundleProvider());
// scan for models defined via bundle headers in classpath
if (registerSlingModelsFromClassPath) {
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java b/core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java
index 507d918..b5f88a2 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/package-info.java
@@ -19,5 +19,5 @@
/**
* Mock implementation of selected Sling APIs.
*/
-@org.osgi.annotation.versioning.Version("3.1.1")
+@org.osgi.annotation.versioning.Version("3.2.0")
package org.apache.sling.testing.mock.sling;
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/MockResourceBundleProviderTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/MockResourceBundleProviderTest.java
new file mode 100644
index 0000000..c83efba
--- /dev/null
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/MockResourceBundleProviderTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.testing.mock.sling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import org.apache.sling.i18n.ResourceBundleProvider;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class MockResourceBundleProviderTest {
+
+ private static final String MY_NAME = "my-name";
+
+ @Rule
+ public SlingContext context = new SlingContext();
+
+ @Test
+ public void testGetResourceBundleFromRequest() {
+ ResourceBundle bundle = context.request().getResourceBundle(Locale.CANADA_FRENCH);
+ assertEquals(Locale.CANADA_FRENCH, bundle.getLocale());
+ assertNull(((MockResourceBundle)bundle).getBaseName());
+ }
+
+ @Test
+ public void testGetResourceBundleFromRequestWithBaseName() {
+ ResourceBundle bundle = context.request().getResourceBundle(MY_NAME, Locale.CANADA_FRENCH);
+ assertEquals(Locale.CANADA_FRENCH, bundle.getLocale());
+ assertEquals(MY_NAME, ((MockResourceBundle)bundle).getBaseName());
+ }
+
+ @Test
+ public void testDefaultLocale() {
+ MockResourceBundleProvider bundleProvider = (MockResourceBundleProvider)context.getService(ResourceBundleProvider.class);
+ assertNotNull(bundleProvider);
+ bundleProvider.setDefaultLocale(Locale.KOREA);
+
+ ResourceBundle bundle = context.request().getResourceBundle(null);
+ assertEquals(Locale.KOREA, bundle.getLocale());
+ assertNull(((MockResourceBundle)bundle).getBaseName());
+ }
+
+ @Test
+ public void testCaching() {
+ ResourceBundle bundle = context.request().getResourceBundle(Locale.GERMAN);
+
+ ((MockResourceBundle)bundle).put("key1", "value1");
+ assertEquals("value1", bundle.getString("key1"));
+
+ ResourceBundle bundle_cached = context.request().getResourceBundle(Locale.GERMAN);
+ assertEquals("value1", bundle_cached.getString("key1"));
+
+ ResourceBundle bundle_otherlocale = context.request().getResourceBundle(Locale.FRANCE);
+ assertEquals("key1", bundle_otherlocale.getString("key1"));
+
+ ResourceBundle bundle_otherbasename = context.request().getResourceBundle(MY_NAME, Locale.GERMAN);
+ assertEquals("key1", bundle_otherbasename.getString("key1"));
+ }
+
+}
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/MockResourceBundleTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/MockResourceBundleTest.java
new file mode 100644
index 0000000..8ebd22d
--- /dev/null
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/MockResourceBundleTest.java
@@ -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.testing.mock.sling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Locale;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+public class MockResourceBundleTest {
+
+ private static final String MY_NAME = "my-name";
+ private MockResourceBundle underTest;
+
+ @Before
+ public void setUp() {
+ underTest = new MockResourceBundle(MY_NAME, Locale.US);
+ assertEquals(MY_NAME, underTest.getBaseName());
+ assertEquals(Locale.US, underTest.getLocale());
+ }
+
+ @Test
+ public void testEmpty() {
+ assertEquals("unknown", underTest.getString("unknown"));
+ assertEquals(ImmutableSet.of(), underTest.keySet());
+ assertFalse(underTest.getKeys().hasMoreElements());
+ }
+
+ @Test
+ public void testWithMappings() {
+ underTest.put("key1", "value1");
+ underTest.putAll(ImmutableMap.of("key2", "value2", "key3" ,"value3"));
+
+ assertEquals("value1", underTest.getString("key1"));
+ assertEquals("value2", underTest.getString("key2"));
+ assertEquals("value3", underTest.getString("key3"));
+
+ assertEquals(ImmutableSet.of("key1", "key2", "key3"), underTest.keySet());
+ assertTrue(underTest.getKeys().hasMoreElements());
+ }
+
+}