home | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (DuplicateBindingsTest.java)

This example Java source code file (DuplicateBindingsTest.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

abstractmodule, annotation, class, constructor, foo, fooimpl, foomodule, hashequalstester, log, logging, override, provider, reflection, runtimeexception, simplemodule, string, throwingmodule, util

The DuplicateBindingsTest.java Java example source code

/**
 * Copyright (C) 2010 Google Inc.
 *
 * Licensed 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 com.google.inject;

import static com.google.inject.Asserts.*;
import static com.google.inject.name.Names.named;

import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.inject.name.Named;
import com.google.inject.spi.Element;
import com.google.inject.spi.Elements;
import com.google.inject.util.Providers;

import junit.framework.TestCase;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.logging.Logger;

/**
 * A suite of tests for duplicate bindings.
 * 
 * @author sameb@google.com (Sam Berlin)
 */
public class DuplicateBindingsTest extends TestCase {
  
  private FooImpl foo = new FooImpl();
  private Provider<Foo> pFoo = Providers.of(new FooImpl());
  private Class<? extends Provider pclFoo = FooProvider.class;
  private Class<? extends Foo> clFoo = FooImpl.class;
  private Constructor<FooImpl> cFoo = FooImpl.cxtor();

  public void testDuplicateBindingsAreIgnored() {
    Injector injector = Guice.createInjector(
        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
    );
    List<Key bindings = Lists.newArrayList(injector.getAllBindings().keySet());
    removeBasicBindings(bindings);
    
    // Ensure only one binding existed for each type.
    assertTrue(bindings.remove(Key.get(Foo.class, named("instance"))));
    assertTrue(bindings.remove(Key.get(Foo.class, named("pInstance"))));
    assertTrue(bindings.remove(Key.get(Foo.class, named("pKey"))));
    assertTrue(bindings.remove(Key.get(Foo.class, named("linkedKey"))));
    assertTrue(bindings.remove(Key.get(FooImpl.class)));
    assertTrue(bindings.remove(Key.get(Foo.class, named("constructor"))));
    assertTrue(bindings.remove(Key.get(FooProvider.class))); // JIT binding
    assertTrue(bindings.remove(Key.get(Foo.class, named("providerMethod"))));
    
    assertEquals(bindings.toString(), 0, bindings.size());
  }
  
  public void testElementsDeduplicate() {
    List<Element> elements = Elements.getElements(
        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
    );
    assertEquals(14, elements.size());
    assertEquals(7, new LinkedHashSet<Element>(elements).size());
  }
  
  public void testProviderMethodsFailIfInstancesDiffer() {
    try {
      Guice.createInjector(new FailingProviderModule(), new FailingProviderModule());
      fail("should have failed");
    } catch(CreationException ce) {
      assertContains(ce.getMessage(),
          "A binding to " + Foo.class.getName() + " was already configured " +
          "at " + FailingProviderModule.class.getName(),
          "at " + FailingProviderModule.class.getName()
          );
    }
  }
  
  public void testSameScopeInstanceIgnored() {
    Guice.createInjector(
        new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo),
        new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo)
    );
    
    Guice.createInjector(
        new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo),
        new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo)
    );
  }
  
  public void testSameScopeAnnotationIgnored() {
    Guice.createInjector(
        new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo),
        new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo)
    );
  }
  
  public void testMixedAnnotationAndScopeForSingletonIgnored() {
    Guice.createInjector(
        new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo),
        new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo)
    );
  }
  
  public void testMixedScopeAndUnscopedIgnored() {
    Guice.createInjector(
        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
        new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo)
    );
  }

  public void testMixedScopeFails() {
    try {
      Guice.createInjector(
          new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
          new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo)
      );
      fail("expected exception");
    } catch(CreationException ce) {
      String segment1 = "A binding to " + Foo.class.getName() + " annotated with "
          + named("pInstance") + " was already configured at " + SimpleModule.class.getName();
      String segment2 = "A binding to " + Foo.class.getName() + " annotated with " + named("pKey")
          + " was already configured at " + SimpleModule.class.getName();
      String segment3 = "A binding to " + Foo.class.getName() + " annotated with " 
          + named("constructor") + " was already configured at " + SimpleModule.class.getName();
      String segment4 = "A binding to " + FooImpl.class.getName() + " was already configured at "
          + SimpleModule.class.getName();
      String atSegment = "at " + ScopedModule.class.getName();
      if (isIncludeStackTraceOff()) {
        assertContains(ce.getMessage(), segment1 , atSegment, segment2, atSegment, segment3,
            atSegment, segment4, atSegment);
      } else {
        assertContains(ce.getMessage(), segment1 , atSegment, segment2, atSegment, segment4,
            atSegment, segment3, atSegment);
      }
    }
  }

  @SuppressWarnings("unchecked")
  public void testMixedTargetsFails() {
    try {
      Guice.createInjector(
          new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
          new SimpleModule(new FooImpl(), Providers.<Foo>of(new FooImpl()), 
              (Class)BarProvider.class, (Class)Bar.class, (Constructor)Bar.cxtor())
      );
      fail("expected exception");
    } catch(CreationException ce) {
      assertContains(ce.getMessage(), 
          "A binding to " + Foo.class.getName() + " annotated with " + named("pInstance") + " was already configured at " + SimpleModule.class.getName(),
          "at " + SimpleModule.class.getName(), 
          "A binding to " + Foo.class.getName() + " annotated with " + named("pKey") + " was already configured at " + SimpleModule.class.getName(),
          "at " + SimpleModule.class.getName(), 
          "A binding to " + Foo.class.getName() + " annotated with " + named("linkedKey") + " was already configured at " + SimpleModule.class.getName(),
          "at " + SimpleModule.class.getName(),
          "A binding to " + Foo.class.getName() + " annotated with " + named("constructor") + " was already configured at " + SimpleModule.class.getName(),
          "at " + SimpleModule.class.getName());
    }
  }
  
  public void testExceptionInEqualsThrowsCreationException() {
    try {
      Guice.createInjector(new ThrowingModule(), new ThrowingModule());
      fail("expected exception");
    } catch(CreationException ce) {
      assertContains(ce.getMessage(),
          "A binding to " + Foo.class.getName() + " was already configured at " + ThrowingModule.class.getName(),
          "and an error was thrown while checking duplicate bindings.  Error: java.lang.RuntimeException: Boo!",
          "at " + ThrowingModule.class.getName());
    }
  }
  
  public void testChildInjectorDuplicateParentFail() {
    Injector injector = Guice.createInjector(
        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
    );
    
    try {
      injector.createChildInjector(
          new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
      );
      fail("expected exception");
    } catch(CreationException ce) {
      assertContains(ce.getMessage(), 
          "A binding to " + Foo.class.getName() + " annotated with " + named("pInstance") + " was already configured at " + SimpleModule.class.getName(),
          "at " + SimpleModule.class.getName(), 
          "A binding to " + Foo.class.getName() + " annotated with " + named("pKey") + " was already configured at " + SimpleModule.class.getName(),
          "at " + SimpleModule.class.getName(), 
          "A binding to " + Foo.class.getName() + " annotated with " + named("linkedKey") + " was already configured at " + SimpleModule.class.getName(),
          "at " + SimpleModule.class.getName(),
          "A binding to " + Foo.class.getName() + " annotated with " + named("constructor") + " was already configured at " + SimpleModule.class.getName(),
          "at " + SimpleModule.class.getName(),
          "A binding to " + Foo.class.getName() + " annotated with " + named("providerMethod") + " was already configured at " + SimpleProviderModule.class.getName(),
          "at " + SimpleProviderModule.class.getName()
          );
    } 
    
    
  }
  
  public void testDuplicatesSolelyInChildIgnored() {
    Injector injector = Guice.createInjector();
    injector.createChildInjector(
        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
        new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
    );
  }
  
  public void testDifferentBindingTypesFail() {
    List<Element> elements = Elements.getElements(
        new FailedModule(foo, pFoo, pclFoo, clFoo, cFoo)
    );
    
    // Make sure every combination of the elements with another element fails.
    // This ensures that duplication checks the kind of binding also.
    for(Element e1 : elements) {
      for(Element e2: elements) {
        // if they're the same, this shouldn't fail.
        try {
          Guice.createInjector(Elements.getModule(Arrays.asList(e1, e2)));
          if(e1 != e2) {
            fail("must fail!");
          }
        } catch(CreationException expected) {
          if(e1 != e2) {
            assertContains(expected.getMessage(),
                "A binding to " + Foo.class.getName() + " was already configured at " + FailedModule.class.getName(),
                "at " + FailedModule.class.getName());
          } else {
            throw expected;
          }
        }
      }
    }
  }
  
  public void testJitBindingsAreCheckedAfterConversions() {
    Guice.createInjector(new AbstractModule() {
      @Override
      protected void configure() {
       bind(A.class);
       bind(A.class).to(RealA.class);
      }
    });
  }
  
  public void testEqualsNotCalledByDefaultOnInstance() {
    final HashEqualsTester a = new HashEqualsTester();
    a.throwOnEquals = true;
    Guice.createInjector(new AbstractModule() {
      @Override
      protected void configure() {
       bind(String.class);
       bind(HashEqualsTester.class).toInstance(a);
      }
    });
  }
  
  public void testEqualsNotCalledByDefaultOnProvider() {
    final HashEqualsTester a = new HashEqualsTester();
    a.throwOnEquals = true;
    Guice.createInjector(new AbstractModule() {
      @Override
      protected void configure() {
       bind(String.class);
       bind(Object.class).toProvider(a);
      }
    });
  }
  
  public void testHashcodeNeverCalledOnInstance() {
    final HashEqualsTester a = new HashEqualsTester();
    a.throwOnHashcode = true;
    a.equality = "test";
    
    final HashEqualsTester b = new HashEqualsTester();
    b.throwOnHashcode = true;
    b.equality = "test";
    Guice.createInjector(new AbstractModule() {
      @Override
      protected void configure() {
       bind(String.class);
       bind(HashEqualsTester.class).toInstance(a);
       bind(HashEqualsTester.class).toInstance(b);
      }
    });
  }
  
  public void testHashcodeNeverCalledOnProviderInstance() {
    final HashEqualsTester a = new HashEqualsTester();
    a.throwOnHashcode = true;
    a.equality = "test";
    
    final HashEqualsTester b = new HashEqualsTester();
    b.throwOnHashcode = true;
    b.equality = "test";
    Guice.createInjector(new AbstractModule() {
      @Override
      protected void configure() {
       bind(String.class);
       bind(Object.class).toProvider(a);
       bind(Object.class).toProvider(b);
      }
    });
  }

  private static class RealA extends A {}
  @ImplementedBy(RealA.class) private static class A {}
  
  private void removeBasicBindings(Collection<Key bindings) {
    bindings.remove(Key.get(Injector.class));
    bindings.remove(Key.get(Logger.class));
    bindings.remove(Key.get(Stage.class));
  }
  
  private static class ThrowingModule extends AbstractModule {
    @Override
    protected void configure() {
      bind(Foo.class).toInstance(new Foo() {
        @Override
        public boolean equals(Object obj) {
          throw new RuntimeException("Boo!");
        }
      });
    }
  }
  
  private static abstract class FooModule extends AbstractModule {
    protected final FooImpl foo;
    protected final Provider<Foo> pFoo;
    protected final Class<? extends Provider pclFoo;
    protected final Class<? extends Foo> clFoo;
    protected final Constructor<FooImpl> cFoo;
    
    FooModule(FooImpl foo, Provider<Foo> pFoo, Class> pclFoo,
        Class<? extends Foo> clFoo, Constructor cFoo) {
      this.foo = foo;
      this.pFoo = pFoo;
      this.pclFoo = pclFoo;
      this.clFoo = clFoo;
      this.cFoo = cFoo;
    }    
  }
  
  private static class FailedModule extends FooModule {
    FailedModule(FooImpl foo, Provider<Foo> pFoo, Class> pclFoo,
        Class<? extends Foo> clFoo, Constructor cFoo) {
      super(foo, pFoo, pclFoo, clFoo, cFoo);
    }
    
    protected void configure() {
      // InstanceBinding
      bind(Foo.class).toInstance(foo);
      
      // ProviderInstanceBinding
      bind(Foo.class).toProvider(pFoo);
      
      // ProviderKeyBinding
      bind(Foo.class).toProvider(pclFoo);
      
      // LinkedKeyBinding
      bind(Foo.class).to(clFoo);
      
      // ConstructorBinding
      bind(Foo.class).toConstructor(cFoo);
    }
    
    @Provides Foo foo() {
      return null;
    }
  }
  
  private static class FailingProviderModule extends AbstractModule {
    @Override protected void configure() {}

    @Provides Foo foo() {
      return null;
    }
  }

  private static class SimpleProviderModule extends AbstractModule {
    @Override protected void configure() {}

    @Provides @Named("providerMethod") Foo foo() {
      return null;
    }

    @Override
    public boolean equals(Object obj) {
      return obj.getClass() == getClass();
    }
  }  
  
  private static class SimpleModule extends FooModule {
    SimpleModule(FooImpl foo, Provider<Foo> pFoo, Class> pclFoo,
        Class<? extends Foo> clFoo, Constructor cFoo) {
      super(foo, pFoo, pclFoo, clFoo, cFoo);
    }
    
    protected void configure() {
      // InstanceBinding
      bind(Foo.class).annotatedWith(named("instance")).toInstance(foo);
      
      // ProviderInstanceBinding
      bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo);
      
      // ProviderKeyBinding
      bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo);
      
      // LinkedKeyBinding
      bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo);
      
      // UntargettedBinding / ConstructorBinding
      bind(FooImpl.class);
      
      // ConstructorBinding
      bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo);

      // ProviderMethod
      // (reconstructed from an Element to ensure it doesn't get filtered out
      //  by deduplicating Modules)
      install(Elements.getModule(Elements.getElements(new SimpleProviderModule())));
    }
  }
  
  private static class ScopedModule extends FooModule {
    private final Scope scope;

    ScopedModule(Scope scope, FooImpl foo, Provider<Foo> pFoo,
        Class<? extends Provider pclFoo, Class clFoo,
        Constructor<FooImpl> cFoo) {
      super(foo, pFoo, pclFoo, clFoo, cFoo);
      this.scope = scope;
    }
    
    protected void configure() {
      // ProviderInstanceBinding
      bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo).in(scope);
      
      // ProviderKeyBinding
      bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo).in(scope);
      
      // LinkedKeyBinding
      bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo).in(scope);
      
      // UntargettedBinding / ConstructorBinding
      bind(FooImpl.class).in(scope);
      
      // ConstructorBinding
      bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo).in(scope);
    }
  }
  
  private static class AnnotatedScopeModule extends FooModule {
    private final Class<? extends Annotation> scope;

    AnnotatedScopeModule(Class<? extends Annotation> scope, FooImpl foo, Provider pFoo,
        Class<? extends Provider pclFoo, Class clFoo,
        Constructor<FooImpl> cFoo) {
      super(foo, pFoo, pclFoo, clFoo, cFoo);
      this.scope = scope;
    }
    
    
    protected void configure() {
      // ProviderInstanceBinding
      bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo).in(scope);
      
      // ProviderKeyBinding
      bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo).in(scope);
      
      // LinkedKeyBinding
      bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo).in(scope);
      
      // UntargettedBinding / ConstructorBinding
      bind(FooImpl.class).in(scope);
      
      // ConstructorBinding
      bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo).in(scope);
    }
  }  
  
  private static interface Foo {}
  private static class FooImpl implements Foo {
    @Inject public FooImpl() {}
    
    private static Constructor<FooImpl> cxtor() {
      try {
        return FooImpl.class.getConstructor();
      } catch (SecurityException e) {
        throw new RuntimeException(e);
      } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
      }
    }
  }  
  private static class FooProvider implements Provider<Foo> {
    public Foo get() {
      return new FooImpl();
    }
  }
  
  private static class Bar implements Foo {
    @Inject public Bar() {}
    
    private static Constructor<Bar> cxtor() {
      try {
        return Bar.class.getConstructor();
      } catch (SecurityException e) {
        throw new RuntimeException(e);
      } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
      }
    }
  }  
  private static class BarProvider implements Provider<Foo> {
    public Foo get() {
      return new Bar();
    }
  }
  
  private static class HashEqualsTester implements Provider<Object> {
    private String equality;
    private boolean throwOnEquals;
    private boolean throwOnHashcode;
    
    @Override
    public boolean equals(Object obj) {
      if (throwOnEquals) {
        throw new RuntimeException();
      } else if (obj instanceof HashEqualsTester) {
        HashEqualsTester o = (HashEqualsTester)obj;
        if(o.throwOnEquals) {
          throw new RuntimeException();
        }
        if(equality == null && o.equality == null) {
          return this == o;
        } else {
          return Objects.equal(equality, o.equality);
        }
      } else {
        return false;
      }
    }
    
    @Override
    public int hashCode() {
      if(throwOnHashcode) {
        throw new RuntimeException();
      } else {
        return super.hashCode();
      }
    }
    
    public Object get() {
      return new Object();
    }
  }
  
}

Other Java examples (source code examples)

Here is a short list of links related to this Java DuplicateBindingsTest.java source code file:



my book on functional programming

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.