Home | History | Annotate | Download | only in jdk8
      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 
     30 import junit.framework.TestCase;
     31 
     32 import java.util.Collections;
     33 import java.util.UUID;
     34 import java.util.concurrent.Callable;
     35 import java.util.concurrent.atomic.AtomicInteger;
     36 import java.util.function.Predicate;
     37 
     38 /**
     39  * Test bindings to lambdas, method references, etc.
     40  *
     41  * @author cgdecker (at) google.com (Colin Decker)
     42  */
     43 public class Java8LanguageFeatureBindingTest extends TestCase {
     44 
     45   // Some of these tests are kind of weird.
     46   // See https://github.com/google/guice/issues/757 for more on why they exist.
     47 
     48   public void testBinding_lambdaToInterface() {
     49     Injector injector = Guice.createInjector(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 
     61   public void testProviderMethod_returningLambda() throws Exception {
     62     Injector injector = Guice.createInjector(new AbstractModule() {
     63       @Override
     64       protected void configure() {}
     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 
     76   public void testProviderMethod_containingLambda_throwingException() throws Exception {
     77     Injector injector = Guice.createInjector(new AbstractModule() {
     78       @Override
     79       protected void configure() {}
     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 
     99   public void testProvider_usingJdk8Features() {
    100     try {
    101       Guice.createInjector(new AbstractModule() {
    102         @Override
    103         protected void configure() {
    104           bind(String.class).toProvider(StringProvider.class);
    105         }
    106       });
    107 
    108       fail();
    109     } catch (CreationException expected) {
    110     }
    111 
    112     UUID uuid = UUID.randomUUID();
    113     Injector injector = Guice.createInjector(new AbstractModule() {
    114       @Override
    115       protected void configure() {
    116         bind(UUID.class).toInstance(uuid);
    117         bind(String.class).toProvider(StringProvider.class);
    118       }
    119     });
    120 
    121     assertEquals(uuid.toString(), injector.getInstance(String.class));
    122   }
    123 
    124   private static final class StringProvider implements Provider<String> {
    125     private final UUID uuid;
    126 
    127     @Inject
    128     StringProvider(UUID uuid) {
    129       this.uuid = uuid;
    130     }
    131 
    132     @Override
    133     public String get() {
    134       return Collections.singleton(uuid).stream()
    135           .map(UUID::toString)
    136           .findFirst().get();
    137     }
    138   }
    139 
    140   public void testBinding_toProvider_lambda() {
    141     Injector injector = Guice.createInjector(new AbstractModule() {
    142       @Override
    143       protected void configure() {
    144         AtomicInteger i = new AtomicInteger();
    145         bind(String.class).toProvider(() -> "Hello" + i.incrementAndGet());
    146       }
    147     });
    148 
    149     assertEquals("Hello1", injector.getInstance(String.class));
    150     assertEquals("Hello2", injector.getInstance(String.class));
    151   }
    152 
    153   public void testBinding_toProvider_methodReference() {
    154     Injector injector = Guice.createInjector(new AbstractModule() {
    155       @Override
    156       protected void configure() {
    157         bind(String.class).toProvider(Java8LanguageFeatureBindingTest.this::provideString);
    158       }
    159     });
    160 
    161     Provider<String> provider = injector.getProvider(String.class);
    162     assertEquals("Hello", provider.get());
    163   }
    164 
    165   private String provideString() {
    166     return "Hello";
    167   }
    168 }
    169