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

Java example source code file (ElementsTest.java)

This example Java source code file (ElementsTest.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, atomicreference, failingbindingscopingvisitor, failingelementvisitor, failingtargetvisitor, instancebinding, key, override, provider, providerinstancebinding, reflection, string, typeliteral, util, void

The ElementsTest.java Java example source code

/**
 * Copyright (C) 2008 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.spi;

import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.inject.Asserts.assertContains;
import static com.google.inject.Asserts.getDeclaringSourcePart;
import static com.google.inject.Asserts.isIncludeStackTraceComplete;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
import com.google.inject.Binding;
import com.google.inject.BindingAnnotation;
import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.MembersInjector;
import com.google.inject.Module;
import com.google.inject.PrivateBinder;
import com.google.inject.Provider;
import com.google.inject.Scope;
import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.AnnotatedBindingBuilder;
import com.google.inject.binder.AnnotatedConstantBindingBuilder;
import com.google.inject.binder.ConstantBindingBuilder;
import com.google.inject.binder.ScopedBindingBuilder;
import com.google.inject.matcher.Matcher;
import com.google.inject.matcher.Matchers;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import com.google.inject.util.Providers;

import junit.framework.TestCase;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author jessewilson@google.com (Jesse Wilson)
 */
public class ElementsTest extends TestCase {

  // Binder fidelity tests

  public void testAddMessageErrorCommand() {
    checkModule(
        new AbstractModule() {
          @Override protected void configure() {
            addError("Message %s %d %s", "A", 5, "C");
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Message A 5 C", command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSources().toString(),
                ElementsTest.class.getName(),
                getDeclaringSourcePart(ElementsTest.class));
            assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
            return null;
          }
        }
    );
  }

  public void testAddThrowableErrorCommand() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            addError(new Exception("A"));
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("A", command.getCause().getMessage());
            assertEquals(command.getMessage(),
                "An exception was caught and reported. Message: A");
            assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
            return null;
          }
        }
    );
  }

  public void testErrorsAddedWhenExceptionsAreThrown() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            install(new AbstractModule() {
              protected void configure() {
                throw new RuntimeException("Throwing RuntimeException in AbstractModule.configure().");
              }
            });

            addError("Code after the exception still gets executed");
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Throwing RuntimeException in AbstractModule.configure().",
                command.getCause().getMessage());
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Code after the exception still gets executed",
                command.getMessage());
            return null;
          }
        }
    );
  }

  private <T> T getInstance(Binding binding) {
    return binding.acceptTargetVisitor(Elements.<T>getInstanceVisitor());
  }

  public void testBindConstantAnnotations() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bindConstant().annotatedWith(SampleAnnotation.class).to("A");
            bindConstant().annotatedWith(Names.named("Bee")).to("B");
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(String.class, SampleAnnotation.class), command.getKey());
            assertEquals("A", getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(String.class, Names.named("Bee")), command.getKey());
            assertEquals("B", getInstance(command));
            return null;
          }
        }
    );
  }

  public void testBindConstantTypes() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bindConstant().annotatedWith(Names.named("String")).to("A");
            bindConstant().annotatedWith(Names.named("int")).to(2);
            bindConstant().annotatedWith(Names.named("long")).to(3L);
            bindConstant().annotatedWith(Names.named("boolean")).to(false);
            bindConstant().annotatedWith(Names.named("double")).to(5.0d);
            bindConstant().annotatedWith(Names.named("float")).to(6.0f);
            bindConstant().annotatedWith(Names.named("short")).to((short) 7);
            bindConstant().annotatedWith(Names.named("char")).to('h');
            bindConstant().annotatedWith(Names.named("byte")).to((byte) 8);
            bindConstant().annotatedWith(Names.named("Class")).to(Iterator.class);
            bindConstant().annotatedWith(Names.named("Enum")).to(CoinSide.TAILS);
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(String.class, Names.named("String")), command.getKey());
            assertEquals("A", getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Integer.class, Names.named("int")), command.getKey());
            assertEquals(2, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Long.class, Names.named("long")), command.getKey());
            assertEquals(3L, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Boolean.class, Names.named("boolean")), command.getKey());
            assertEquals(false, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Double.class, Names.named("double")), command.getKey());
            assertEquals(5.0d, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Float.class, Names.named("float")), command.getKey());
            assertEquals(6.0f, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Short.class, Names.named("short")), command.getKey());
            assertEquals((short) 7, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Character.class, Names.named("char")), command.getKey());
            assertEquals('h', getInstance(command));
            return null;
          }
        },
        
        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Byte.class, Names.named("byte")), command.getKey());
            assertEquals((byte) 8, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Class.class, Names.named("Class")), command.getKey());
            assertEquals(Iterator.class, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(CoinSide.class, Names.named("Enum")), command.getKey());
            assertEquals(CoinSide.TAILS, getInstance(command));
            return null;
          }
        }
    );
  }

  public void testBindKeysNoAnnotations() {
    FailingElementVisitor keyChecker = new FailingElementVisitor() {
      @Override public <T> Void visit(Binding command) {
        assertEquals(Key.get(String.class), command.getKey());
        return null;
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).toInstance("A");
            bind(new TypeLiteral<String>() {}).toInstance("B");
            bind(Key.get(String.class)).toInstance("C");
          }
        },
        keyChecker,
        keyChecker,
        keyChecker
    );
  }

  public void testBindKeysWithAnnotationType() {
    FailingElementVisitor annotationChecker = new FailingElementVisitor() {
      @Override public <T> Void visit(Binding command) {
        assertEquals(Key.get(String.class, SampleAnnotation.class), command.getKey());
        return null;
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).annotatedWith(SampleAnnotation.class).toInstance("A");
            bind(new TypeLiteral<String>() {}).annotatedWith(SampleAnnotation.class).toInstance("B");
          }
        },
        annotationChecker,
        annotationChecker
    );
  }

  public void testBindKeysWithAnnotationInstance() {
    FailingElementVisitor annotationChecker = new FailingElementVisitor() {
      @Override public <T> Void visit(Binding command) {
        assertEquals(Key.get(String.class, Names.named("a")), command.getKey());
        return null;
      }
    };


    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).annotatedWith(Names.named("a")).toInstance("B");
            bind(new TypeLiteral<String>() {}).annotatedWith(Names.named("a")).toInstance("C");
          }
        },
        annotationChecker,
        annotationChecker
    );
  }

  public void testBindToProvider() {
    final Provider<String> aProvider = new Provider() {
      public String get() {
        return "A";
      }
    };
    
    final javax.inject.Provider<Integer> intJavaxProvider = new javax.inject.Provider() {
      public Integer get() {
        return 42;
      }
    };
    
    final javax.inject.Provider<Double> doubleJavaxProvider = new javax.inject.Provider() {
      @javax.inject.Inject String string;
      
      public Double get() {
        return 42.42;
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).toProvider(aProvider);
            bind(Integer.class).toProvider(intJavaxProvider);
            bind(Double.class).toProvider(doubleJavaxProvider);
            bind(List.class).toProvider(ListProvider.class);
            bind(Collection.class).toProvider(Key.get(ListProvider.class));
            bind(Iterable.class).toProvider(new TypeLiteral<TProvider() {});
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof ProviderInstanceBinding);
            assertEquals(Key.get(String.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(
                  ProviderInstanceBinding<? extends T> binding) {
                assertSame(aProvider, binding.getUserSuppliedProvider());
                assertSame(aProvider, binding.getProviderInstance());
                return null;
              }
            });
            return null;
          }
        },
        
        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof ProviderInstanceBinding);
            assertEquals(Key.get(Integer.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(
                  ProviderInstanceBinding<? extends T> binding) {
                assertSame(intJavaxProvider, binding.getUserSuppliedProvider());
                assertEquals(42, binding.getProviderInstance().get());
                // we don't wrap this w/ dependencies if there were none.
                assertFalse(binding.getProviderInstance() instanceof HasDependencies);
                return null;
              }
            });
            return null;
          }
        },        
        
        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof ProviderInstanceBinding);
            assertEquals(Key.get(Double.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(
                  ProviderInstanceBinding<? extends T> binding) {
                assertSame(doubleJavaxProvider, binding.getUserSuppliedProvider());
                assertEquals(42.42, binding.getProviderInstance().get());
                // we do wrap it with dependencies if there were some.
                assertTrue(binding.getProviderInstance() instanceof HasDependencies);
                Set<Dependency deps =
                    ((HasDependencies) binding.getProviderInstance()).getDependencies();
                assertEquals(1, deps.size());
                assertEquals(String.class,
                    deps.iterator().next().getKey().getTypeLiteral().getRawType());
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof ProviderKeyBinding);
            assertEquals(Key.get(List.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(ProviderKeyBinding<? extends T> binding) {
                assertEquals(Key.get(ListProvider.class), binding.getProviderKey());
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof ProviderKeyBinding);
            assertEquals(Key.get(Collection.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(ProviderKeyBinding<? extends T> binding) {
                assertEquals(Key.get(ListProvider.class), binding.getProviderKey());
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof ProviderKeyBinding);
            assertEquals(Key.get(Iterable.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(ProviderKeyBinding<? extends T> binding) {
                assertEquals(new Key<TProvider() {}, binding.getProviderKey());
                return null;
              }
            });
            return null;
          }
        }
    );
  }

  public void testBindToLinkedBinding() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(List.class).to(ArrayList.class);
            bind(Map.class).to(new TypeLiteral<HashMap() {});
            bind(Set.class).to(Key.get(TreeSet.class, SampleAnnotation.class));
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof LinkedKeyBinding);
            assertEquals(Key.get(List.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(LinkedKeyBinding<? extends T> binding) {
                assertEquals(Key.get(ArrayList.class), binding.getLinkedKey());
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof LinkedKeyBinding);
            assertEquals(Key.get(Map.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(LinkedKeyBinding<? extends T> binding) {
                assertEquals(Key.get(new TypeLiteral<HashMap() {}),
                    binding.getLinkedKey());
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof LinkedKeyBinding);
            assertEquals(Key.get(Set.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(LinkedKeyBinding<? extends T> binding) {
                assertEquals(Key.get(TreeSet.class, SampleAnnotation.class),
                    binding.getLinkedKey());
                return null;
              }
            });
            return null;
          }
        }
    );
  }

  public void testBindToInstance() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).toInstance("A");
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(String.class), command.getKey());
            assertEquals("A", getInstance(command));
            return null;
          }
        }
    );
  }

  public void testBindInScopes() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class);
            bind(List.class).to(ArrayList.class).in(Scopes.SINGLETON);
            bind(Map.class).to(HashMap.class).in(Singleton.class);
            bind(Set.class).to(TreeSet.class).asEagerSingleton();
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertEquals(Key.get(String.class), command.getKey());
            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              @Override public Void visitNoScoping() {
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertEquals(Key.get(List.class), command.getKey());
            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              @Override public Void visitScope(Scope scope) {
                assertEquals(Scopes.SINGLETON, scope);
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertEquals(Key.get(Map.class), command.getKey());
            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              @Override public Void visitScopeAnnotation(Class<? extends Annotation> annotation) {
                assertEquals(Singleton.class, annotation);
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            assertEquals(Key.get(Set.class), command.getKey());
            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              public Void visitEagerSingleton() {
                return null;
              }
            });
            return null;
          }
        }
    );
  }

  public void testBindToInstanceInScope() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            AnnotatedBindingBuilder<String> b = bind(String.class);
            b.toInstance("A");
            b.in(Singleton.class);
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Setting the scope is not permitted when binding to a single instance.",
                command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
            return null;
          }
        }
      );
  }

  public void testBindToInstanceScope() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).toInstance("A");
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding binding) {
            assertEquals(Key.get(String.class), binding.getKey());
            binding.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              public Void visitEagerSingleton() {
                return null;
              }
            });
            return null;
          }
        }
      );
  }

  /*if[AOP]*/
  public void testBindIntercepor() {
    final Matcher<Class> classMatcher = Matchers.subclassesOf(List.class);
    final Matcher<Object> methodMatcher = Matchers.any();
    final org.aopalliance.intercept.MethodInterceptor methodInterceptor
        = new org.aopalliance.intercept.MethodInterceptor() {
      public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) {
        return null;
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bindInterceptor(classMatcher, methodMatcher, methodInterceptor);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(InterceptorBinding command) {
            assertSame(classMatcher, command.getClassMatcher());
            assertSame(methodMatcher, command.getMethodMatcher());
            assertEquals(Arrays.asList(methodInterceptor), command.getInterceptors());
            return null;
          }
        }
    );
  }
  /*end[AOP]*/

  public void testBindScope() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bindScope(SampleAnnotation.class, Scopes.NO_SCOPE);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(ScopeBinding command) {
            assertSame(SampleAnnotation.class, command.getAnnotationType());
            assertSame(Scopes.NO_SCOPE, command.getScope());
            return null;
          }
        }
    );
  }

  public void testBindListener() {
    final Matcher<Object> typeMatcher = Matchers.only(TypeLiteral.get(String.class));
    final TypeListener listener = new TypeListener() {
      public <I> void hear(TypeLiteral type, TypeEncounter encounter) {
        throw new UnsupportedOperationException();
      }
    };
    
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bindListener(typeMatcher, listener);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(TypeListenerBinding binding) {
            assertSame(typeMatcher, binding.getTypeMatcher());
            assertSame(listener, binding.getListener());
            return null;
          }
        }
    );
  }

  public void testConvertToTypes() {
    final TypeConverter typeConverter = new TypeConverter() {
      public Object convert(String value, TypeLiteral<?> toType) {
        return value;
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            convertToTypes(Matchers.any(), typeConverter);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(TypeConverterBinding command) {
            assertSame(typeConverter, command.getTypeConverter());
            assertSame(Matchers.any(), command.getTypeMatcher());
            return null;
          }
        }
    );
  }

  public void testGetProvider() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            Provider<String> keyGetProvider
                = getProvider(Key.get(String.class, SampleAnnotation.class));
            try {
              keyGetProvider.get();
            } catch (IllegalStateException e) {
              assertEquals("This Provider cannot be used until the Injector has been created.",
                  e.getMessage());
            }

            Provider<String> typeGetProvider = getProvider(String.class);
            try {
              typeGetProvider.get();
            } catch (IllegalStateException e) {
              assertEquals("This Provider cannot be used until the Injector has been created.",
                  e.getMessage());
            }
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(ProviderLookup command) {
            assertEquals(Key.get(String.class, SampleAnnotation.class), command.getKey());
            assertNull(command.getDelegate());
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(ProviderLookup command) {
            assertEquals(Key.get(String.class), command.getKey());
            assertNull(command.getDelegate());
            return null;
          }
        }
    );
  }
  
  public void testElementInitialization() {
    final AtomicReference<Provider providerFromBinder
        = new AtomicReference<Provider();
    final AtomicReference<MembersInjector membersInjectorFromBinder
        = new AtomicReference<MembersInjector();

    final AtomicReference<String> lastInjected = new AtomicReference();
    final MembersInjector<String> stringInjector = new MembersInjector() {
      public void injectMembers(String instance) {
        lastInjected.set(instance);
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            providerFromBinder.set(getProvider(String.class));
            membersInjectorFromBinder.set(getMembersInjector(String.class));
          }
        },

        new FailingElementVisitor() {
          public <T> Void visit(ProviderLookup providerLookup) {
            @SuppressWarnings("unchecked") // we know that T is a String here
            ProviderLookup<String> stringLookup = (ProviderLookup) providerLookup;
            stringLookup.initializeDelegate(Providers.of("out"));

            assertEquals("out", providerFromBinder.get().get());
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(MembersInjectorLookup lookup) {
            @SuppressWarnings("unchecked") // we know that T is a String here
            MembersInjectorLookup<String> stringLookup = (MembersInjectorLookup) lookup;
            stringLookup.initializeDelegate(stringInjector);

            membersInjectorFromBinder.get().injectMembers("in");
            assertEquals("in", lastInjected.get());
            return null;
          }
        });
  }

  public void testGetMembersInjector() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            MembersInjector<A typeMembersInjector
                = getMembersInjector(new TypeLiteral<A() {});
            try {
              typeMembersInjector.injectMembers(new A<String>());
            } catch (IllegalStateException e) {
              assertEquals(
                  "This MembersInjector cannot be used until the Injector has been created.",
                  e.getMessage());
            }

            MembersInjector<String> classMembersInjector = getMembersInjector(String.class);
            try {
              classMembersInjector.injectMembers("hello");
            } catch (IllegalStateException e) {
              assertEquals(
                  "This MembersInjector cannot be used until the Injector has been created.",
                  e.getMessage());
            }
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(MembersInjectorLookup command) {
            assertEquals(new TypeLiteral<A() {}, command.getType());
            assertNull(command.getDelegate());
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(MembersInjectorLookup command) {
            assertEquals(TypeLiteral.get(String.class), command.getType());
            assertNull(command.getDelegate());
            return null;
          }
        }
    );
  }

  public void testRequestInjection() {
    final Object firstObject = new Object();
    final Object secondObject = new Object();

    checkModule(
        new AbstractModule() {
          protected void configure() {
            requestInjection(firstObject);
            requestInjection(secondObject);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(InjectionRequest<?> command) {
            assertEquals(firstObject, command.getInstance());
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(InjectionRequest<?> command) {
            assertEquals(secondObject, command.getInstance());
            return null;
          }
        }
    );
  }

  public void testRequestStaticInjection() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            requestStaticInjection(ArrayList.class);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(StaticInjectionRequest command) {
            assertEquals(ArrayList.class, command.getType());
            return null;
          }
        }
    );
  }

  public void testNewPrivateBinder() {
    final Key<Collection> collection = Key.get(Collection.class, SampleAnnotation.class);
    final Key<ArrayList> arrayList = Key.get(ArrayList.class);
    final ImmutableSet<Key collections = ImmutableSet.>of(arrayList, collection);

    final Key<?> a = Key.get(String.class, Names.named("a"));
    final Key<?> b = Key.get(String.class, Names.named("b"));
    final ImmutableSet<Key ab = ImmutableSet.of(a, b);

    checkModule(
        new AbstractModule() {
          protected void configure() {
            PrivateBinder one = binder().newPrivateBinder();
            one.expose(ArrayList.class);
            one.expose(Collection.class).annotatedWith(SampleAnnotation.class);
            one.bind(List.class).to(ArrayList.class);

            PrivateBinder two = binder().withSource("1 FooBar")
                .newPrivateBinder().withSource("2 FooBar");
            two.expose(String.class).annotatedWith(Names.named("a"));
            two.expose(b);
            two.bind(List.class).to(ArrayList.class);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(PrivateElements one) {
            assertEquals(collections, one.getExposedKeys());
            checkElements(one.getElements(),
                new FailingElementVisitor() {
                  @Override public <T> Void visit(Binding binding) {
                    assertEquals(Key.get(List.class), binding.getKey());
                    return null;
                  }
                }
            );
            return null;
          }
        },

        new ExternalFailureVisitor() {
          @Override public Void visit(PrivateElements two) {
            assertEquals(ab, two.getExposedKeys());
            assertEquals("1 FooBar", two.getSource().toString());
            checkElements(two.getElements(),
                new ExternalFailureVisitor() {
                  @Override public <T> Void visit(Binding binding) {
                    assertEquals("2 FooBar", binding.getSource().toString());
                    assertEquals(Key.get(List.class), binding.getKey());
                    return null;
                  }
                }
            );
            return null;
          }
        }
    );
  }

  public void testBindWithMultipleAnnotationsAddsError() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            AnnotatedBindingBuilder<String> abb = bind(String.class);
            abb.annotatedWith(SampleAnnotation.class);
            abb.annotatedWith(Names.named("A"));
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("More than one annotation is specified for this binding.",
                command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
            return null;
          }
        }
    );
  }

  public void testBindWithMultipleTargetsAddsError() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            AnnotatedBindingBuilder<String> abb = bind(String.class);
            abb.toInstance("A");
            abb.toInstance("B");
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Implementation is set more than once.", command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
            return null;
          }
        }
    );
  }

  public void testBindWithMultipleScopesAddsError() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            ScopedBindingBuilder sbb = bind(List.class).to(ArrayList.class);
            sbb.in(Scopes.NO_SCOPE);
            sbb.asEagerSingleton();
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Scope is set more than once.", command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
            return null;
          }
        }
    );
  }

  public void testBindConstantWithMultipleAnnotationsAddsError() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            AnnotatedConstantBindingBuilder cbb = bindConstant();
            cbb.annotatedWith(SampleAnnotation.class).to("A");
            cbb.annotatedWith(Names.named("A"));
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("More than one annotation is specified for this binding.",
                command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSource(), getDeclaringSourcePart(ElementsTest.class));
            return null;
          }
        }
    );
  }

  public void testBindConstantWithMultipleTargetsAddsError() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            ConstantBindingBuilder cbb = bindConstant().annotatedWith(SampleAnnotation.class);
            cbb.to("A");
            cbb.to("B");
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message message) {
            assertEquals("Constant value is set more than once.", message.getMessage());
            assertNull(message.getCause());
            assertContains(message.getSource(), getDeclaringSourcePart(ElementsTest.class));
            return null;
          }
        }
    );
  }

  public void testBindToConstructor() throws NoSuchMethodException, NoSuchFieldException {
    final Constructor<A> aConstructor = A.class.getDeclaredConstructor();
    final Constructor<B> bConstructor = B.class.getDeclaredConstructor(Object.class);
    final Field field = B.class.getDeclaredField("stage");

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(A.class).toConstructor(aConstructor);
            bind(B.class).toConstructor(bConstructor, new TypeLiteral<B() {})
                .in(Singleton.class);
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding binding) {
            assertEquals(new Key<A>() {}, binding.getKey());

            return binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(ConstructorBinding<? extends T> constructorBinding) {
                InjectionPoint injectionPoint = constructorBinding.getConstructor();
                assertEquals(aConstructor, injectionPoint.getMember());
                assertEquals(new TypeLiteral<A>() {}, injectionPoint.getDeclaringType());
                return null;
              }
            });
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding binding) {
            assertEquals(new Key<B>() {}, binding.getKey());
            binding.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              @Override public Void visitScopeAnnotation(Class<? extends Annotation> annotation) {
                assertEquals(Singleton.class, annotation);
                return null;
              }
            });

            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(ConstructorBinding<? extends T> constructorBinding) {
                assertEquals(bConstructor, constructorBinding.getConstructor().getMember());
                assertEquals(Key.get(Integer.class),
                    getOnlyElement(constructorBinding.getConstructor().getDependencies()).getKey());
                assertEquals(field,
                    getOnlyElement(constructorBinding.getInjectableMembers()).getMember());
                assertEquals(2, constructorBinding.getDependencies().size());
/*if[AOP]*/
                assertEquals(ImmutableMap.of(), constructorBinding.getMethodInterceptors());
/*end[AOP]*/
                return null;
              }
            });
            return null;
          }
        }
    );
  }

  public void testBindToMalformedConstructor() throws NoSuchMethodException, NoSuchFieldException {
    final Constructor<C> constructor = C.class.getDeclaredConstructor(Integer.class);

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(C.class).toConstructor(constructor);
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding binding) {
            assertEquals(Key.get(C.class), binding.getKey());
            assertTrue(binding instanceof UntargettedBinding);
            return null;
          }
        },

        new ExternalFailureVisitor() {
          @Override public Void visit(Message message) {
            assertContains(message.getMessage(),
                C.class.getName() + ".a has more than one annotation ",
                Named.class.getName(), SampleAnnotation.class.getName());
            return null;
          }
        },

        new ExternalFailureVisitor() {
          @Override public Void visit(Message message) {
            assertContains(message.getMessage(),
                C.class.getName() + ".<init>() has more than one annotation ",
                Named.class.getName(), SampleAnnotation.class.getName());
            return null;
          }
        }
    );
  }

  // Business logic tests

  public void testModulesAreInstalledAtMostOnce() {
    final AtomicInteger aConfigureCount = new AtomicInteger(0);
    final Module a = new AbstractModule() {
      public void configure() {
        aConfigureCount.incrementAndGet();
      }
    };

    Elements.getElements(a, a);
    assertEquals(1, aConfigureCount.get());

    aConfigureCount.set(0);
    Module b = new AbstractModule() {
      protected void configure() {
        install(a);
        install(a);
      }
    };

    Elements.getElements(b);
    assertEquals(1, aConfigureCount.get());
  }

  /**
   * Ensures the module performs the commands consistent with {@code visitors}.
   */
  protected void checkModule(Module module, ElementVisitor<?>... visitors) {
    List<Element> elements = Elements.getElements(module);
    assertEquals(elements.size(), visitors.length);
    checkElements(elements, visitors);
  }

  protected void checkElements(List<Element> elements, ElementVisitor... visitors) {
    for (int i = 0; i < visitors.length; i++) {
      ElementVisitor<?> visitor = visitors[i];
      Element element = elements.get(i);
      if (!(element instanceof Message)) {
          ElementSource source = (ElementSource) element.getSource();
          assertFalse(source.getModuleClassNames().isEmpty());
          if (isIncludeStackTraceComplete()) {
            assertTrue(source.getStackTrace().length > 0);
          } else {
            assertEquals(0, source.getStackTrace().length);
          }
      }
      if (!(visitor instanceof ExternalFailureVisitor)) {
        assertContains(element.getSource().toString(), getDeclaringSourcePart(ElementsTest.class));
      }
      element.acceptVisitor(visitor);
    }
  }

  private static class ListProvider implements Provider<List> {
    public List get() {
      return new ArrayList();
    }
  }

  private static class TProvider<T> implements Provider {
    public T get() {
      return null;
    }
  }

  /**
   * By extending this interface rather than FailingElementVisitor, the source of the error doesn't
   * need to contain the string {@code ElementsTest.java}.
   */
  abstract class ExternalFailureVisitor extends FailingElementVisitor {}

  @Retention(RUNTIME)
  @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
  @BindingAnnotation
  public @interface SampleAnnotation { }

  public enum CoinSide { HEADS, TAILS }

  static class A<T> {
    @Inject Stage stage;
  }

  static class B<T> {
    @Inject Stage stage;
    B(T t) {}
  }

  static class C {
    @Inject @Named("foo") @SampleAnnotation String a;
    C(@Named("bar") @SampleAnnotation Integer b) {}
  }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java ElementsTest.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.