package com.google.sitebricks; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.inject.AbstractModule; import com.google.inject.CreationException; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Provider; import com.google.inject.name.Named; import com.google.sitebricks.i18n.Message; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; /** * Unit test for the i18n binder utility. */ public class LocalizationTest { private static final String HELLO = "hello"; private HttpServletRequest requestMock; @BeforeMethod public final void setup() { requestMock = createNiceMock(HttpServletRequest.class); expect(requestMock.getLocale()).andReturn(Locale.ENGLISH); replay(requestMock); } @Test public final void simpleLocalize() { final Map<String, String> resourceBundle = Maps.newHashMap(); resourceBundle.put(HELLO, "hello there!"); String msg = Guice.createInjector(new AbstractModule() { @Override protected void configure() { Set<Localizer.Localization> locs = Sets.newHashSet(); locs.add(new Localizer.Localization(Localized.class, Locale.ENGLISH, resourceBundle)); Localizer.localizeAll(binder(), locs); bind(HttpServletRequest.class).toInstance(requestMock); } }).getInstance(Localized.class) .hello(); assert resourceBundle.get(HELLO).equals(msg); } @Test(expectedExceptions = CreationException.class) public final void simpleLocalizeMissingEntry() { final Map<String, String> resourceBundle = Maps.newHashMap(); Guice.createInjector(new AbstractModule() { @Override protected void configure() { Set<Localizer.Localization> locs = Sets.newHashSet(); locs.add(new Localizer.Localization(Localized.class, Locale.ENGLISH, resourceBundle)); Localizer.localizeAll(binder(), locs); bind(HttpServletRequest.class).toInstance(requestMock); } }); } @Test(expectedExceptions = CreationException.class) public final void simpleLocalizeMissingAnnotation() { final Map<String, String> resourceBundle = Maps.newHashMap(); resourceBundle.put(LocalizationTest.HELLO, "stuff"); Guice.createInjector(new AbstractModule() { @Override protected void configure() { Set<Localizer.Localization> locs = Sets.newHashSet(); locs.add(new Localizer.Localization(LocalizedMissingAnnotation.class, Locale.ENGLISH, resourceBundle)); Localizer.localizeAll(binder(), locs); bind(HttpServletRequest.class).toInstance(requestMock); } }).getInstance(LocalizedMissingAnnotation.class); } @Test(expectedExceptions = CreationException.class) public final void simpleLocalizeWrongReturnType() { final Map<String, String> resourceBundle = Maps.newHashMap(); resourceBundle.put(LocalizationTest.HELLO, "stuff"); Guice.createInjector(new AbstractModule() { @Override protected void configure() { Set<Localizer.Localization> locs = Sets.newHashSet(); locs.add(new Localizer.Localization(LocalizedWrongReturnType.class, Locale.ENGLISH, resourceBundle)); Localizer.localizeAll(binder(), locs); bind(HttpServletRequest.class).toInstance(requestMock); } }).getInstance(LocalizedWrongReturnType.class); } @Test(expectedExceptions = CreationException.class) public final void parameterizedLocalizeWrongArgAnnotation() { final Map<String, String> resourceBundle = Maps.newHashMap(); resourceBundle.put(LocalizationTest.HELLO, "stuff"); Guice.createInjector(new AbstractModule() { @Override protected void configure() { Set<Localizer.Localization> locs = Sets.newHashSet(); locs.add(new Localizer.Localization(LocalizedWrongArgAnnotation.class, Locale.ENGLISH, resourceBundle)); Localizer.localizeAll(binder(), locs); bind(HttpServletRequest.class).toInstance(requestMock); } }).getInstance(LocalizedWrongArgAnnotation.class); } @Test(expectedExceptions = CreationException.class) public final void parameterizedLocalizeBrokenTemplate() { final Map<String, String> resourceBundle = Maps.newHashMap(); resourceBundle.put(LocalizationTest.HELLO, "stuff"); Guice.createInjector(new AbstractModule() { @Override protected void configure() { Set<Localizer.Localization> locs = Sets.newHashSet(); locs.add(new Localizer.Localization(LocalizedBrokenTemplate.class, Locale.ENGLISH, resourceBundle)); Localizer.localizeAll(binder(), locs); bind(HttpServletRequest.class).toInstance(requestMock); } }).getInstance(LocalizedBrokenTemplate.class); } @Test public final void parameterizedLocalizeTemplate() { final Map<String, String> resourceBundle = Maps.newHashMap(); resourceBundle.put(LocalizationTest.HELLO, "hello ${name}"); String msg = Guice.createInjector(new AbstractModule() { @Override protected void configure() { Set<Localizer.Localization> locs = Sets.newHashSet(); locs.add(new Localizer.Localization(LocalizedTemplate.class, Locale.ENGLISH, resourceBundle)); Localizer.localizeAll(binder(), locs); bind(HttpServletRequest.class).toInstance(requestMock); } }).getInstance(LocalizedTemplate.class) .hello("Dude"); assert "hello Dude".equals(msg); } @Test public final void parameterizedLocalizeTemplateMultipleLocales() { Locale.setDefault(Locale.ENGLISH); final Map<String, String> resourceBundle = Maps.newHashMap(); resourceBundle.put(LocalizationTest.HELLO, "hello ${name}"); final HashMap<String, String> japaneseBundle = Maps.newHashMap(); japaneseBundle.put(LocalizationTest.HELLO, "konichiwa ${name}"); // Simulate an Accept-Language of Japanese HttpServletRequest japaneseRequest = createNiceMock(HttpServletRequest.class); expect(japaneseRequest.getLocale()).andReturn(Locale.JAPANESE); replay(japaneseRequest); final AtomicReference<HttpServletRequest> mockToUse = new AtomicReference<HttpServletRequest>(japaneseRequest); Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { Set<Localizer.Localization> locs = Sets.newHashSet(); locs.add(new Localizer.Localization(LocalizedTemplate.class, Locale.ENGLISH, resourceBundle)); locs.add(new Localizer.Localization(LocalizedTemplate.class, Locale.JAPANESE, japaneseBundle)); Localizer.localizeAll(binder(), locs); bind(HttpServletRequest.class).toProvider(new Provider<HttpServletRequest>() { public HttpServletRequest get() { return mockToUse.get(); } }); } }); String msg = injector.getInstance(LocalizedTemplate.class).hello("Dude"); assert "konichiwa Dude".equals(msg) : msg; verify(japaneseRequest); // Now let's simulate english. mockToUse.set(requestMock); msg = injector.getInstance(LocalizedTemplate.class).hello("Dude"); assert "hello Dude".equals(msg); // Now let's simulate a totally different locale (should default to english). // Simulate an Accept-Language of French HttpServletRequest frenchRequest = createNiceMock(HttpServletRequest.class); expect(frenchRequest.getLocale()).andReturn(Locale.FRENCH); replay(frenchRequest); mockToUse.set(frenchRequest); // Assert that it uses the english locale (set as default above) msg = injector.getInstance(LocalizedTemplate.class).hello("Dude"); assert "hello Dude".equals(msg); verify(frenchRequest, requestMock); } @Test public final void parameterizedWithNoExternalBundle() { String msg = Guice.createInjector(new AbstractModule() { @Override protected void configure() { Set<Localizer.Localization> locs = Sets.newHashSet(); locs.add(Localizer.defaultLocalizationFor(LocalizedTemplate.class)); Localizer.localizeAll(binder(), locs); bind(HttpServletRequest.class).toInstance(requestMock); } }).getInstance(LocalizedTemplate.class) .hello("Dudette"); assert "hello Dudette!".equals(msg); } public static interface Localized { @Message(message = "hello world!") String hello(); } public static interface LocalizedMissingAnnotation { String hello(); } public static interface LocalizedWrongReturnType { @Message(message = "hello world!") void hello(); } public static interface LocalizedWrongArgAnnotation { @Message(message = "hello world!") String hello(String val); } public static interface LocalizedBrokenTemplate { @Message(message = "hello ${named}!") String hello(@Named("name") String val); } public static interface LocalizedTemplate { @Message(message = "hello ${name}!") String hello(@Named("name") String val); } }