1 /* 2 * Copyright (C) 2014 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.inject.jdk8; 18 19 import com.google.inject.AbstractModule; 20 import com.google.inject.CreationException; 21 import com.google.inject.Guice; 22 import com.google.inject.Inject; 23 import com.google.inject.Injector; 24 import com.google.inject.Key; 25 import com.google.inject.Provider; 26 import com.google.inject.Provides; 27 import com.google.inject.ProvisionException; 28 import com.google.inject.TypeLiteral; 29 import java.util.Collections; 30 import java.util.UUID; 31 import java.util.concurrent.Callable; 32 import java.util.concurrent.atomic.AtomicInteger; 33 import java.util.function.Predicate; 34 import junit.framework.TestCase; 35 36 /** 37 * Test bindings to lambdas, method references, etc. 38 * 39 * @author cgdecker@google.com (Colin Decker) 40 */ 41 public class Java8LanguageFeatureBindingTest extends TestCase { 42 43 // Some of these tests are kind of weird. 44 // See https://github.com/google/guice/issues/757 for more on why they exist. 45 testBinding_lambdaToInterface()46 public void testBinding_lambdaToInterface() { 47 Injector injector = 48 Guice.createInjector( 49 new AbstractModule() { 50 @Override 51 protected void configure() { 52 bind(new TypeLiteral<Predicate<Object>>() {}).toInstance(o -> o != null); 53 } 54 }); 55 56 Predicate<Object> predicate = injector.getInstance(new Key<Predicate<Object>>() {}); 57 assertTrue(predicate.test(new Object())); 58 assertFalse(predicate.test(null)); 59 } 60 testProviderMethod_returningLambda()61 public void testProviderMethod_returningLambda() throws Exception { 62 Injector injector = 63 Guice.createInjector( 64 new AbstractModule() { 65 66 @Provides 67 public Callable<String> provideCallable() { 68 return () -> "foo"; 69 } 70 }); 71 72 Callable<String> callable = injector.getInstance(new Key<Callable<String>>() {}); 73 assertEquals("foo", callable.call()); 74 } 75 testProviderMethod_containingLambda_throwingException()76 public void testProviderMethod_containingLambda_throwingException() throws Exception { 77 Injector injector = 78 Guice.createInjector( 79 new AbstractModule() { 80 81 @Provides 82 public Callable<String> provideCallable() { 83 if (Boolean.parseBoolean("false")) { // avoid dead code warnings 84 return () -> "foo"; 85 } else { 86 throw new RuntimeException("foo"); 87 } 88 } 89 }); 90 91 try { 92 injector.getInstance(new Key<Callable<String>>() {}); 93 } catch (ProvisionException expected) { 94 assertTrue(expected.getCause() instanceof RuntimeException); 95 assertEquals("foo", expected.getCause().getMessage()); 96 } 97 } 98 testProvider_usingJdk8Features()99 public void testProvider_usingJdk8Features() { 100 try { 101 Guice.createInjector( 102 new AbstractModule() { 103 @Override 104 protected void configure() { 105 bind(String.class).toProvider(StringProvider.class); 106 } 107 }); 108 109 fail(); 110 } catch (CreationException expected) { 111 } 112 113 UUID uuid = UUID.randomUUID(); 114 Injector injector = 115 Guice.createInjector( 116 new AbstractModule() { 117 @Override 118 protected void configure() { 119 bind(UUID.class).toInstance(uuid); 120 bind(String.class).toProvider(StringProvider.class); 121 } 122 }); 123 124 assertEquals(uuid.toString(), injector.getInstance(String.class)); 125 } 126 127 private static final class StringProvider implements Provider<String> { 128 private final UUID uuid; 129 130 @Inject StringProvider(UUID uuid)131 StringProvider(UUID uuid) { 132 this.uuid = uuid; 133 } 134 135 @Override get()136 public String get() { 137 return Collections.singleton(uuid).stream().map(UUID::toString).findFirst().get(); 138 } 139 } 140 testBinding_toProvider_lambda()141 public void testBinding_toProvider_lambda() { 142 Injector injector = 143 Guice.createInjector( 144 new AbstractModule() { 145 @Override 146 protected void configure() { 147 AtomicInteger i = new AtomicInteger(); 148 bind(String.class).toProvider(() -> "Hello" + i.incrementAndGet()); 149 } 150 }); 151 152 assertEquals("Hello1", injector.getInstance(String.class)); 153 assertEquals("Hello2", injector.getInstance(String.class)); 154 } 155 testBinding_toProvider_methodReference()156 public void testBinding_toProvider_methodReference() { 157 Injector injector = 158 Guice.createInjector( 159 new AbstractModule() { 160 @Override 161 protected void configure() { 162 bind(String.class).toProvider(Java8LanguageFeatureBindingTest.this::provideString); 163 } 164 }); 165 166 Provider<String> provider = injector.getProvider(String.class); 167 assertEquals("Hello", provider.get()); 168 } 169 provideString()170 private String provideString() { 171 return "Hello"; 172 } 173 } 174