1e18906acc38e436613d01b0b96cf5c09623ec987sameb/**
2e18906acc38e436613d01b0b96cf5c09623ec987sameb * Copyright (C) 2015 Google Inc.
3e18906acc38e436613d01b0b96cf5c09623ec987sameb *
4e18906acc38e436613d01b0b96cf5c09623ec987sameb * Licensed under the Apache License, Version 2.0 (the "License");
5e18906acc38e436613d01b0b96cf5c09623ec987sameb * you may not use this file except in compliance with the License.
6e18906acc38e436613d01b0b96cf5c09623ec987sameb * You may obtain a copy of the License at
7e18906acc38e436613d01b0b96cf5c09623ec987sameb *
8e18906acc38e436613d01b0b96cf5c09623ec987sameb * http://www.apache.org/licenses/LICENSE-2.0
9e18906acc38e436613d01b0b96cf5c09623ec987sameb *
10e18906acc38e436613d01b0b96cf5c09623ec987sameb * Unless required by applicable law or agreed to in writing, software
11e18906acc38e436613d01b0b96cf5c09623ec987sameb * distributed under the License is distributed on an "AS IS" BASIS,
12e18906acc38e436613d01b0b96cf5c09623ec987sameb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e18906acc38e436613d01b0b96cf5c09623ec987sameb * See the License for the specific language governing permissions and
14e18906acc38e436613d01b0b96cf5c09623ec987sameb * limitations under the License.
15e18906acc38e436613d01b0b96cf5c09623ec987sameb */
16e18906acc38e436613d01b0b96cf5c09623ec987sameb
17e18906acc38e436613d01b0b96cf5c09623ec987samebpackage com.google.inject.spi;
18e18906acc38e436613d01b0b96cf5c09623ec987sameb
19e18906acc38e436613d01b0b96cf5c09623ec987samebimport static com.google.inject.Asserts.assertContains;
20e18906acc38e436613d01b0b96cf5c09623ec987samebimport static com.google.inject.name.Names.named;
21e18906acc38e436613d01b0b96cf5c09623ec987samebimport static java.lang.annotation.ElementType.METHOD;
22e18906acc38e436613d01b0b96cf5c09623ec987samebimport static java.lang.annotation.RetentionPolicy.RUNTIME;
23e18906acc38e436613d01b0b96cf5c09623ec987sameb
24e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.common.collect.ImmutableSet;
2554da0e3ca924a5040e88a1c067f9f6760a14b20bsamebimport com.google.common.collect.Iterables;
26e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.AbstractModule;
27e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.Binder;
28e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.Binding;
29e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.CreationException;
3054da0e3ca924a5040e88a1c067f9f6760a14b20bsamebimport com.google.inject.Exposed;
31e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.Guice;
32e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.Injector;
33e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.Key;
34e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.Module;
3554da0e3ca924a5040e88a1c067f9f6760a14b20bsamebimport com.google.inject.PrivateModule;
36e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.internal.util.StackTraceElements;
37e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.name.Named;
38e18906acc38e436613d01b0b96cf5c09623ec987samebimport com.google.inject.name.Names;
39e18906acc38e436613d01b0b96cf5c09623ec987sameb
40e18906acc38e436613d01b0b96cf5c09623ec987samebimport junit.framework.TestCase;
41e18906acc38e436613d01b0b96cf5c09623ec987sameb
42e18906acc38e436613d01b0b96cf5c09623ec987samebimport java.lang.annotation.Annotation;
43e18906acc38e436613d01b0b96cf5c09623ec987samebimport java.lang.annotation.Documented;
44e18906acc38e436613d01b0b96cf5c09623ec987samebimport java.lang.annotation.Retention;
45e18906acc38e436613d01b0b96cf5c09623ec987samebimport java.lang.annotation.Target;
46e18906acc38e436613d01b0b96cf5c09623ec987samebimport java.util.Set;
47e18906acc38e436613d01b0b96cf5c09623ec987sameb
48e18906acc38e436613d01b0b96cf5c09623ec987sameb/** Tests for {@link ModuleAnnotatedMethodScanner} usage. */
49e18906acc38e436613d01b0b96cf5c09623ec987samebpublic class ModuleAnnotatedMethodScannerTest extends TestCase {
5054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
51e18906acc38e436613d01b0b96cf5c09623ec987sameb  public void testScanning() throws Exception {
52e18906acc38e436613d01b0b96cf5c09623ec987sameb    Module module = new AbstractModule() {
5354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Override protected void configure() {}
5454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
55e18906acc38e436613d01b0b96cf5c09623ec987sameb      @TestProvides @Named("foo") String foo() {
56e18906acc38e436613d01b0b96cf5c09623ec987sameb        return "foo";
57e18906acc38e436613d01b0b96cf5c09623ec987sameb      }
5854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
59e18906acc38e436613d01b0b96cf5c09623ec987sameb      @TestProvides @Named("foo2") String foo2() {
60e18906acc38e436613d01b0b96cf5c09623ec987sameb        return "foo2";
61e18906acc38e436613d01b0b96cf5c09623ec987sameb      }
62e18906acc38e436613d01b0b96cf5c09623ec987sameb    };
6354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Injector injector = Guice.createInjector(module, NamedMunger.module());
64e18906acc38e436613d01b0b96cf5c09623ec987sameb
65e18906acc38e436613d01b0b96cf5c09623ec987sameb    // assert no bindings named "foo" or "foo2" exist -- they were munged.
6654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertMungedBinding(injector, String.class, "foo", "foo");
6754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertMungedBinding(injector, String.class, "foo2", "foo2");
68e18906acc38e436613d01b0b96cf5c09623ec987sameb
69e18906acc38e436613d01b0b96cf5c09623ec987sameb    Binding<String> fooBinding = injector.getBinding(Key.get(String.class, named("foo-munged")));
70e18906acc38e436613d01b0b96cf5c09623ec987sameb    Binding<String> foo2Binding = injector.getBinding(Key.get(String.class, named("foo2-munged")));
71e18906acc38e436613d01b0b96cf5c09623ec987sameb    // Validate the provider has a sane toString
72e18906acc38e436613d01b0b96cf5c09623ec987sameb    assertEquals(methodName(TestProvides.class, "foo", module),
73e18906acc38e436613d01b0b96cf5c09623ec987sameb        fooBinding.getProvider().toString());
74e18906acc38e436613d01b0b96cf5c09623ec987sameb    assertEquals(methodName(TestProvides.class, "foo2", module),
75e18906acc38e436613d01b0b96cf5c09623ec987sameb        foo2Binding.getProvider().toString());
76e18906acc38e436613d01b0b96cf5c09623ec987sameb  }
77e18906acc38e436613d01b0b96cf5c09623ec987sameb
7802c489e4fbddf702c7932b55caab83e6d8cba9cesameb  public void testSkipSources() throws Exception {
7902c489e4fbddf702c7932b55caab83e6d8cba9cesameb    Module module = new AbstractModule() {
8002c489e4fbddf702c7932b55caab83e6d8cba9cesameb      @Override protected void configure() {
8102c489e4fbddf702c7932b55caab83e6d8cba9cesameb        binder().skipSources(getClass()).install(new AbstractModule() {
8202c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Override protected void configure() {}
8302c489e4fbddf702c7932b55caab83e6d8cba9cesameb
8402c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @TestProvides @Named("foo") String foo() { return "foo"; }
8502c489e4fbddf702c7932b55caab83e6d8cba9cesameb        });
8602c489e4fbddf702c7932b55caab83e6d8cba9cesameb      }
8702c489e4fbddf702c7932b55caab83e6d8cba9cesameb    };
8802c489e4fbddf702c7932b55caab83e6d8cba9cesameb    Injector injector = Guice.createInjector(module, NamedMunger.module());
8902c489e4fbddf702c7932b55caab83e6d8cba9cesameb    assertMungedBinding(injector, String.class, "foo", "foo");
9002c489e4fbddf702c7932b55caab83e6d8cba9cesameb  }
9102c489e4fbddf702c7932b55caab83e6d8cba9cesameb
9202c489e4fbddf702c7932b55caab83e6d8cba9cesameb  public void testWithSource() throws Exception {
9302c489e4fbddf702c7932b55caab83e6d8cba9cesameb    Module module = new AbstractModule() {
9402c489e4fbddf702c7932b55caab83e6d8cba9cesameb      @Override protected void configure() {
9502c489e4fbddf702c7932b55caab83e6d8cba9cesameb        binder().withSource("source").install(new AbstractModule() {
9602c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Override protected void configure() {}
9702c489e4fbddf702c7932b55caab83e6d8cba9cesameb
9802c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @TestProvides @Named("foo") String foo() { return "foo"; }
9902c489e4fbddf702c7932b55caab83e6d8cba9cesameb        });
10002c489e4fbddf702c7932b55caab83e6d8cba9cesameb      }
10102c489e4fbddf702c7932b55caab83e6d8cba9cesameb    };
10202c489e4fbddf702c7932b55caab83e6d8cba9cesameb    Injector injector = Guice.createInjector(module, NamedMunger.module());
10302c489e4fbddf702c7932b55caab83e6d8cba9cesameb    assertMungedBinding(injector, String.class, "foo", "foo");
10402c489e4fbddf702c7932b55caab83e6d8cba9cesameb  }
10502c489e4fbddf702c7932b55caab83e6d8cba9cesameb
106e18906acc38e436613d01b0b96cf5c09623ec987sameb  public void testMoreThanOneClaimedAnnotationFails() throws Exception {
107e18906acc38e436613d01b0b96cf5c09623ec987sameb    Module module = new AbstractModule() {
10854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Override protected void configure() {}
10954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
110e18906acc38e436613d01b0b96cf5c09623ec987sameb      @TestProvides @TestProvides2 String foo() {
111e18906acc38e436613d01b0b96cf5c09623ec987sameb        return "foo";
112e18906acc38e436613d01b0b96cf5c09623ec987sameb      }
113e18906acc38e436613d01b0b96cf5c09623ec987sameb    };
114e18906acc38e436613d01b0b96cf5c09623ec987sameb    try {
11554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      Guice.createInjector(module, NamedMunger.module());
116e18906acc38e436613d01b0b96cf5c09623ec987sameb      fail();
117e18906acc38e436613d01b0b96cf5c09623ec987sameb    } catch(CreationException expected) {
118e18906acc38e436613d01b0b96cf5c09623ec987sameb      assertEquals(1, expected.getErrorMessages().size());
119e18906acc38e436613d01b0b96cf5c09623ec987sameb      assertContains(expected.getMessage(),
12054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          "More than one annotation claimed by NamedMunger on method "
121e18906acc38e436613d01b0b96cf5c09623ec987sameb              + module.getClass().getName() + ".foo(). Methods can only have "
122e18906acc38e436613d01b0b96cf5c09623ec987sameb              + "one annotation claimed per scanner.");
123e18906acc38e436613d01b0b96cf5c09623ec987sameb    }
124e18906acc38e436613d01b0b96cf5c09623ec987sameb  }
12554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
126e18906acc38e436613d01b0b96cf5c09623ec987sameb  private String methodName(Class<? extends Annotation> annotation, String method, Object container)
127e18906acc38e436613d01b0b96cf5c09623ec987sameb      throws Exception {
128e18906acc38e436613d01b0b96cf5c09623ec987sameb    return "@" + annotation.getName() + " "
129e18906acc38e436613d01b0b96cf5c09623ec987sameb        + StackTraceElements.forMember(container.getClass().getDeclaredMethod(method));
130e18906acc38e436613d01b0b96cf5c09623ec987sameb  }
13154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
132e18906acc38e436613d01b0b96cf5c09623ec987sameb  @Documented @Target(METHOD) @Retention(RUNTIME)
133e18906acc38e436613d01b0b96cf5c09623ec987sameb  private @interface TestProvides {}
134e18906acc38e436613d01b0b96cf5c09623ec987sameb
135e18906acc38e436613d01b0b96cf5c09623ec987sameb  @Documented @Target(METHOD) @Retention(RUNTIME)
136e18906acc38e436613d01b0b96cf5c09623ec987sameb  private @interface TestProvides2 {}
13754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
138e18906acc38e436613d01b0b96cf5c09623ec987sameb  private static class NamedMunger extends ModuleAnnotatedMethodScanner {
13954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    static Module module() {
14054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      return new AbstractModule() {
14154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        @Override protected void configure() {
14254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          binder().scanModulesForAnnotatedMethods(new NamedMunger());
14354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        }
14454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      };
14554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    }
14654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
14754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    @Override
14854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    public String toString() {
14954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      return "NamedMunger";
15054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    }
15154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
152e18906acc38e436613d01b0b96cf5c09623ec987sameb    @Override
153e18906acc38e436613d01b0b96cf5c09623ec987sameb    public Set<? extends Class<? extends Annotation>> annotationClasses() {
154e18906acc38e436613d01b0b96cf5c09623ec987sameb      return ImmutableSet.of(TestProvides.class, TestProvides2.class);
155e18906acc38e436613d01b0b96cf5c09623ec987sameb    }
156e18906acc38e436613d01b0b96cf5c09623ec987sameb
157e18906acc38e436613d01b0b96cf5c09623ec987sameb    @Override
158e18906acc38e436613d01b0b96cf5c09623ec987sameb    public <T> Key<T> prepareMethod(Binder binder, Annotation annotation, Key<T> key,
159e18906acc38e436613d01b0b96cf5c09623ec987sameb        InjectionPoint injectionPoint) {
160e18906acc38e436613d01b0b96cf5c09623ec987sameb      return Key.get(key.getTypeLiteral(),
161e18906acc38e436613d01b0b96cf5c09623ec987sameb          Names.named(((Named) key.getAnnotation()).value() + "-munged"));
162e18906acc38e436613d01b0b96cf5c09623ec987sameb    }
163e18906acc38e436613d01b0b96cf5c09623ec987sameb  }
1647445e44ba8acbbfc09116fec71d59066cdae8721sameb
16554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  private void assertMungedBinding(Injector injector, Class<?> clazz, String originalName,
16654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      Object expectedValue) {
16754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertNull(injector.getExistingBinding(Key.get(clazz, named(originalName))));
16854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Binding<?> fooBinding = injector.getBinding(Key.get(clazz, named(originalName + "-munged")));
16954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertEquals(expectedValue, fooBinding.getProvider().get());
17054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  }
17154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
17254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  public void testFailingScanner() {
1737445e44ba8acbbfc09116fec71d59066cdae8721sameb    try {
17454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      Guice.createInjector(new SomeModule(), FailingScanner.module());
1757445e44ba8acbbfc09116fec71d59066cdae8721sameb      fail();
1767445e44ba8acbbfc09116fec71d59066cdae8721sameb    } catch (CreationException expected) {
1777445e44ba8acbbfc09116fec71d59066cdae8721sameb      Message m = Iterables.getOnlyElement(expected.getErrorMessages());
1787445e44ba8acbbfc09116fec71d59066cdae8721sameb      assertEquals(
1797445e44ba8acbbfc09116fec71d59066cdae8721sameb          "An exception was caught and reported. Message: Failing in the scanner.",
1807445e44ba8acbbfc09116fec71d59066cdae8721sameb          m.getMessage());
1817445e44ba8acbbfc09116fec71d59066cdae8721sameb      assertEquals(IllegalStateException.class, m.getCause().getClass());
1827445e44ba8acbbfc09116fec71d59066cdae8721sameb      ElementSource source = (ElementSource) Iterables.getOnlyElement(m.getSources());
1837445e44ba8acbbfc09116fec71d59066cdae8721sameb      assertEquals(SomeModule.class.getName(),
1847445e44ba8acbbfc09116fec71d59066cdae8721sameb          Iterables.getOnlyElement(source.getModuleClassNames()));
1857445e44ba8acbbfc09116fec71d59066cdae8721sameb      assertEquals(String.class.getName() + " " + SomeModule.class.getName() + ".aString()",
1867445e44ba8acbbfc09116fec71d59066cdae8721sameb          source.toString());
1877445e44ba8acbbfc09116fec71d59066cdae8721sameb    }
1887445e44ba8acbbfc09116fec71d59066cdae8721sameb  }
1897445e44ba8acbbfc09116fec71d59066cdae8721sameb
19054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  public static class FailingScanner extends ModuleAnnotatedMethodScanner {
19154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    static Module module() {
19254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      return new AbstractModule() {
19354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        @Override protected void configure() {
19454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          binder().scanModulesForAnnotatedMethods(new FailingScanner());
19554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        }
19654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      };
1977445e44ba8acbbfc09116fec71d59066cdae8721sameb    }
1987445e44ba8acbbfc09116fec71d59066cdae8721sameb
1997445e44ba8acbbfc09116fec71d59066cdae8721sameb    @Override public Set<? extends Class<? extends Annotation>> annotationClasses() {
2007445e44ba8acbbfc09116fec71d59066cdae8721sameb      return ImmutableSet.of(TestProvides.class);
2017445e44ba8acbbfc09116fec71d59066cdae8721sameb    }
2027445e44ba8acbbfc09116fec71d59066cdae8721sameb
2037445e44ba8acbbfc09116fec71d59066cdae8721sameb    @Override public <T> Key<T> prepareMethod(
2047445e44ba8acbbfc09116fec71d59066cdae8721sameb        Binder binder, Annotation rawAnnotation, Key<T> key, InjectionPoint injectionPoint) {
2057445e44ba8acbbfc09116fec71d59066cdae8721sameb      throw new IllegalStateException("Failing in the scanner.");
2067445e44ba8acbbfc09116fec71d59066cdae8721sameb    }
2077445e44ba8acbbfc09116fec71d59066cdae8721sameb  }
2087445e44ba8acbbfc09116fec71d59066cdae8721sameb
2097445e44ba8acbbfc09116fec71d59066cdae8721sameb  static class SomeModule extends AbstractModule {
2107445e44ba8acbbfc09116fec71d59066cdae8721sameb    @TestProvides String aString() {
2117445e44ba8acbbfc09116fec71d59066cdae8721sameb      return "Foo";
2127445e44ba8acbbfc09116fec71d59066cdae8721sameb    }
2137445e44ba8acbbfc09116fec71d59066cdae8721sameb
2147445e44ba8acbbfc09116fec71d59066cdae8721sameb    @Override protected void configure() {}
2157445e44ba8acbbfc09116fec71d59066cdae8721sameb  }
21654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
21754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  public void testChildInjectorInheritsScanner() {
21854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Injector parent = Guice.createInjector(NamedMunger.module());
21954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Injector child = parent.createChildInjector(new AbstractModule() {
22054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Override protected void configure() {}
22154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
22254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @TestProvides @Named("foo") String foo() {
22354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        return "foo";
22454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      }
22554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    });
22654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertMungedBinding(child, String.class, "foo", "foo");
22754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  }
22854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
22954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  public void testChildInjectorScannersDontImpactSiblings() {
23054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Module module = new AbstractModule() {
23154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Override
23254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      protected void configure() {}
23354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
23454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @TestProvides @Named("foo") String foo() {
23554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        return "foo";
23654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      }
23754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    };
23854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Injector parent = Guice.createInjector();
23954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Injector child = parent.createChildInjector(NamedMunger.module(), module);
24054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertMungedBinding(child, String.class, "foo", "foo");
24154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
24254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    // no foo nor foo-munged in sibling, since scanner never saw it.
24354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Injector sibling = parent.createChildInjector(module);
24454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertNull(sibling.getExistingBinding(Key.get(String.class, named("foo"))));
24554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertNull(sibling.getExistingBinding(Key.get(String.class, named("foo-munged"))));
24654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  }
24754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
24854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  public void testPrivateModuleInheritScanner_usingPrivateModule() {
24954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Injector injector = Guice.createInjector(NamedMunger.module(), new PrivateModule() {
25054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Override protected void configure() {}
25154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
25254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Exposed @TestProvides @Named("foo") String foo() {
25354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        return "foo";
25454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      }
25554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    });
25654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertMungedBinding(injector, String.class, "foo", "foo");
25754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  }
25854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
25902c489e4fbddf702c7932b55caab83e6d8cba9cesameb  public void testPrivateModule_skipSourcesWithinPrivateModule() {
26002c489e4fbddf702c7932b55caab83e6d8cba9cesameb    Injector injector = Guice.createInjector(NamedMunger.module(), new PrivateModule() {
26102c489e4fbddf702c7932b55caab83e6d8cba9cesameb      @Override protected void configure() {
26202c489e4fbddf702c7932b55caab83e6d8cba9cesameb        binder().skipSources(getClass()).install(new AbstractModule() {
26302c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Override protected void configure() {}
26402c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Exposed @TestProvides @Named("foo") String foo() {
26502c489e4fbddf702c7932b55caab83e6d8cba9cesameb            return "foo";
26602c489e4fbddf702c7932b55caab83e6d8cba9cesameb          }
26702c489e4fbddf702c7932b55caab83e6d8cba9cesameb        });
26802c489e4fbddf702c7932b55caab83e6d8cba9cesameb      }
26902c489e4fbddf702c7932b55caab83e6d8cba9cesameb    });
27002c489e4fbddf702c7932b55caab83e6d8cba9cesameb    assertMungedBinding(injector, String.class, "foo", "foo");
27102c489e4fbddf702c7932b55caab83e6d8cba9cesameb  }
27202c489e4fbddf702c7932b55caab83e6d8cba9cesameb
27302c489e4fbddf702c7932b55caab83e6d8cba9cesameb  public void testPrivateModule_skipSourcesForPrivateModule() {
27402c489e4fbddf702c7932b55caab83e6d8cba9cesameb    Injector injector = Guice.createInjector(NamedMunger.module(), new AbstractModule() {
27502c489e4fbddf702c7932b55caab83e6d8cba9cesameb      @Override protected void configure() {
27602c489e4fbddf702c7932b55caab83e6d8cba9cesameb        binder().skipSources(getClass()).install(new PrivateModule() {
27702c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Override protected void configure() {}
27802c489e4fbddf702c7932b55caab83e6d8cba9cesameb
27902c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Exposed @TestProvides @Named("foo") String foo() {
28002c489e4fbddf702c7932b55caab83e6d8cba9cesameb            return "foo";
28102c489e4fbddf702c7932b55caab83e6d8cba9cesameb          }
28202c489e4fbddf702c7932b55caab83e6d8cba9cesameb        });
28302c489e4fbddf702c7932b55caab83e6d8cba9cesameb      }});
28402c489e4fbddf702c7932b55caab83e6d8cba9cesameb    assertMungedBinding(injector, String.class, "foo", "foo");
28502c489e4fbddf702c7932b55caab83e6d8cba9cesameb  }
28602c489e4fbddf702c7932b55caab83e6d8cba9cesameb
28754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  public void testPrivateModuleInheritScanner_usingPrivateBinder() {
28854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Injector injector = Guice.createInjector(NamedMunger.module(), new AbstractModule() {
28954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Override protected void configure() {
29054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        binder().newPrivateBinder().install(new AbstractModule() {
29154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          @Override protected void configure() {}
29254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
29354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          @Exposed @TestProvides @Named("foo") String foo() {
29454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb            return "foo";
29554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          }
29654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        });
29754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      }
29854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    });
29954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertMungedBinding(injector, String.class, "foo", "foo");
30054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  }
30154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
30202c489e4fbddf702c7932b55caab83e6d8cba9cesameb  public void testPrivateModuleInheritScanner_skipSourcesFromPrivateBinder() {
30302c489e4fbddf702c7932b55caab83e6d8cba9cesameb    Injector injector = Guice.createInjector(NamedMunger.module(), new AbstractModule() {
30402c489e4fbddf702c7932b55caab83e6d8cba9cesameb      @Override protected void configure() {
30502c489e4fbddf702c7932b55caab83e6d8cba9cesameb        binder().newPrivateBinder().skipSources(getClass()).install(new AbstractModule() {
30602c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Override protected void configure() {}
30702c489e4fbddf702c7932b55caab83e6d8cba9cesameb
30802c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Exposed @TestProvides @Named("foo") String foo() {
30902c489e4fbddf702c7932b55caab83e6d8cba9cesameb            return "foo";
31002c489e4fbddf702c7932b55caab83e6d8cba9cesameb          }
31102c489e4fbddf702c7932b55caab83e6d8cba9cesameb        });
31202c489e4fbddf702c7932b55caab83e6d8cba9cesameb      }
31302c489e4fbddf702c7932b55caab83e6d8cba9cesameb    });
31402c489e4fbddf702c7932b55caab83e6d8cba9cesameb    assertMungedBinding(injector, String.class, "foo", "foo");
31502c489e4fbddf702c7932b55caab83e6d8cba9cesameb  }
31602c489e4fbddf702c7932b55caab83e6d8cba9cesameb
31702c489e4fbddf702c7932b55caab83e6d8cba9cesameb  public void testPrivateModuleInheritScanner_skipSourcesFromPrivateBinder2() {
31802c489e4fbddf702c7932b55caab83e6d8cba9cesameb    Injector injector = Guice.createInjector(NamedMunger.module(), new AbstractModule() {
31902c489e4fbddf702c7932b55caab83e6d8cba9cesameb      @Override protected void configure() {
32002c489e4fbddf702c7932b55caab83e6d8cba9cesameb        binder().skipSources(getClass()).newPrivateBinder().install(new AbstractModule() {
32102c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Override protected void configure() {}
32202c489e4fbddf702c7932b55caab83e6d8cba9cesameb
32302c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Exposed @TestProvides @Named("foo") String foo() {
32402c489e4fbddf702c7932b55caab83e6d8cba9cesameb            return "foo";
32502c489e4fbddf702c7932b55caab83e6d8cba9cesameb          }
32602c489e4fbddf702c7932b55caab83e6d8cba9cesameb        });
32702c489e4fbddf702c7932b55caab83e6d8cba9cesameb      }
32802c489e4fbddf702c7932b55caab83e6d8cba9cesameb    });
32902c489e4fbddf702c7932b55caab83e6d8cba9cesameb    assertMungedBinding(injector, String.class, "foo", "foo");
33002c489e4fbddf702c7932b55caab83e6d8cba9cesameb  }
33102c489e4fbddf702c7932b55caab83e6d8cba9cesameb
33254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  public void testPrivateModuleScannersDontImpactSiblings_usingPrivateModule() {
33354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Injector injector = Guice.createInjector(new PrivateModule() {
33454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Override protected void configure() {
33554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        install(NamedMunger.module());
33654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      }
33754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
33854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Exposed @TestProvides @Named("foo") String foo() {
33954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        return "foo";
34054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      }
34154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    }, new PrivateModule() {
34254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Override protected void configure() {}
34354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
34454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      // ignored! (because the scanner doesn't run over this module)
34554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Exposed @TestProvides @Named("foo") String foo() {
34654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        return "foo";
34754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      }
34854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    });
34954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertMungedBinding(injector, String.class, "foo", "foo");
35054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  }
35154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
35254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  public void testPrivateModuleScannersDontImpactSiblings_usingPrivateBinder() {
35354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    Injector injector = Guice.createInjector(new AbstractModule() {
35454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Override protected void configure() {
35554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        binder().newPrivateBinder().install(new AbstractModule() {
35654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          @Override protected void configure() {
35754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb            install(NamedMunger.module());
35854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          }
35954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
36054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          @Exposed @TestProvides @Named("foo") String foo() {
36154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb            return "foo";
36254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          }
36354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        });
36454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      }
36554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    }, new AbstractModule() {
36654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      @Override protected void configure() {
36754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        binder().newPrivateBinder().install(new AbstractModule() {
36854da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          @Override protected void configure() {}
36954da0e3ca924a5040e88a1c067f9f6760a14b20bsameb
37054da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          // ignored! (because the scanner doesn't run over this module)
37154da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          @Exposed @TestProvides @Named("foo") String foo() {
37254da0e3ca924a5040e88a1c067f9f6760a14b20bsameb            return "foo";
37354da0e3ca924a5040e88a1c067f9f6760a14b20bsameb          }
37454da0e3ca924a5040e88a1c067f9f6760a14b20bsameb        });
37554da0e3ca924a5040e88a1c067f9f6760a14b20bsameb      }});
37654da0e3ca924a5040e88a1c067f9f6760a14b20bsameb    assertMungedBinding(injector, String.class, "foo", "foo");
37754da0e3ca924a5040e88a1c067f9f6760a14b20bsameb  }
37802c489e4fbddf702c7932b55caab83e6d8cba9cesameb
37902c489e4fbddf702c7932b55caab83e6d8cba9cesameb  public void testPrivateModuleWithinPrivateModule() {
38002c489e4fbddf702c7932b55caab83e6d8cba9cesameb    Injector injector = Guice.createInjector(NamedMunger.module(), new PrivateModule() {
38102c489e4fbddf702c7932b55caab83e6d8cba9cesameb      @Override protected void configure() {
38202c489e4fbddf702c7932b55caab83e6d8cba9cesameb        expose(Key.get(String.class, named("foo-munged")));
38302c489e4fbddf702c7932b55caab83e6d8cba9cesameb        install(new PrivateModule() {
38402c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Override protected void configure() {}
38502c489e4fbddf702c7932b55caab83e6d8cba9cesameb
38602c489e4fbddf702c7932b55caab83e6d8cba9cesameb          @Exposed @TestProvides @Named("foo") String foo() {
38702c489e4fbddf702c7932b55caab83e6d8cba9cesameb            return "foo";
38802c489e4fbddf702c7932b55caab83e6d8cba9cesameb          }
38902c489e4fbddf702c7932b55caab83e6d8cba9cesameb        });
39002c489e4fbddf702c7932b55caab83e6d8cba9cesameb      }
39102c489e4fbddf702c7932b55caab83e6d8cba9cesameb    });
39202c489e4fbddf702c7932b55caab83e6d8cba9cesameb    assertMungedBinding(injector, String.class, "foo", "foo");
39302c489e4fbddf702c7932b55caab83e6d8cba9cesameb  }
394e18906acc38e436613d01b0b96cf5c09623ec987sameb}
395