Full test coverage for errors...

git-svn-id: https://google-guice.googlecode.com/svn/trunk@593 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/internal/Errors.java b/src/com/google/inject/internal/Errors.java
index 9656d3e..f94a2ff 100644
--- a/src/com/google/inject/internal/Errors.java
+++ b/src/com/google/inject/internal/Errors.java
@@ -281,10 +281,6 @@
     }
   }
 
-  public Errors cannotInjectNull(Object source) {
-    return addMessage("null returned by binding at %s", source);
-  }
-
   public Errors cannotInjectRawProvider() {
     return addMessage("Cannot inject a Provider that has no type parameter");
   }
@@ -369,13 +365,6 @@
     return String.format(messageFormat, arguments);
   }
 
-  /**
-   * Returns a mutable copy.
-   */
-  public Errors copy() {
-    return new Errors().merge(this);
-  }
-
   public List<Message> getMessages() {
     List<Message> result = Lists.newArrayList(errors);
 
diff --git a/test/com/google/inject/BinderTest.java b/test/com/google/inject/BinderTest.java
index 89c30c0..3010333 100644
--- a/test/com/google/inject/BinderTest.java
+++ b/test/com/google/inject/BinderTest.java
@@ -133,6 +133,21 @@
     }
   }
 
+  public void testRecursiveBinding() {
+    try {
+      Guice.createInjector(new AbstractModule() {
+        @Override public void configure() {
+          bind(Runnable.class).to(Runnable.class);
+        }
+      });
+      fail();
+    } catch (CreationException expected) {
+      assertContains(expected.getMessage(),
+          "1) Error at " + getClass().getName(), ".configure(BinderTest.java:",
+          "Binding points to itself.");
+    }
+  }
+
   public void testToStringOnBinderApi() {
     try {
       Guice.createInjector(new AbstractModule() {
@@ -393,4 +408,15 @@
 //  }
 
   enum Roshambo { ROCK, SCISSORS, PAPER }
+
+  public void testInjectRawProvider() {
+    try {
+      Guice.createInjector().getInstance(Provider.class);
+      fail();
+    } catch (ProvisionException expected) {
+      Asserts.assertContains(expected.getMessage(),
+          "1) Error at " + Provider.class.getName(),
+          "Cannot inject a Provider that has no type parameter");
+    }
+  }
 }
diff --git a/test/com/google/inject/BindingTest.java b/test/com/google/inject/BindingTest.java
index b716c50..124bb6b 100644
--- a/test/com/google/inject/BindingTest.java
+++ b/test/com/google/inject/BindingTest.java
@@ -302,4 +302,21 @@
           "Could not find a suitable constructor in " + PrivateNoArg.class.getName());
     }
   }
+
+  public void testTooManyConstructors() {
+    try {
+      Guice.createInjector().getInstance(TooManyConstructors.class);
+      fail();
+    } catch (ProvisionException expected) {
+      assertContains(expected.getMessage(),
+          "Error at " + TooManyConstructors.class.getName() + ".class(BindingTest.java:",
+          TooManyConstructors.class.getName() + " has more than one constructor annotated with " 
+              + "@Inject. Classes must have either one (and only one) constructor");
+    }
+  }
+
+  static class TooManyConstructors {
+    @Inject TooManyConstructors(Injector i) {}
+    @Inject TooManyConstructors() {}
+  }
 }
diff --git a/test/com/google/inject/CircularDependencyTest.java b/test/com/google/inject/CircularDependencyTest.java
index 018be1d..2832441 100644
--- a/test/com/google/inject/CircularDependencyTest.java
+++ b/test/com/google/inject/CircularDependencyTest.java
@@ -65,4 +65,22 @@
     }
   }
 
+  public void testUnresolvableCircularDependency() {
+    try {
+      Guice.createInjector().getInstance(C.class);
+      fail();
+    } catch (ProvisionException expected) {
+      Asserts.assertContains(expected.getMessage(),
+          "Tried proxying " + C.class.getName() + " to support a circular dependency, ",
+          "but it is not an interface.");
+    }
+  }
+
+  static class C {
+    @Inject C(D d) {}
+  }
+
+  static class D {
+    @Inject D(C c) {}
+  }
 }
diff --git a/test/com/google/inject/ScopesTest.java b/test/com/google/inject/ScopesTest.java
index 784b224..1a9b7a1 100644
--- a/test/com/google/inject/ScopesTest.java
+++ b/test/com/google/inject/ScopesTest.java
@@ -249,6 +249,49 @@
     }
   }
 
+  public void testBindScopeToAnnotationWithoutScopeAnnotation() {
+    try {
+      Guice.createInjector(new AbstractModule() {
+        protected void configure() {
+          bindScope(Deprecated.class, Scopes.NO_SCOPE);
+        }
+      });
+      fail();
+    } catch (CreationException expected) {
+      assertContains(expected.getMessage(),
+          "1) Error at " + Deprecated.class.getName() + ".class(",
+          "Please annotate with @ScopeAnnotation.");
+    }
+  }
+
+  public void testBindScopeTooManyTimes() {
+    try {
+      Guice.createInjector(new AbstractModule() {
+        protected void configure() {
+          bindScope(CustomScoped.class, Scopes.NO_SCOPE);
+          bindScope(CustomScoped.class, Scopes.SINGLETON);
+        }
+      });
+      fail();
+    } catch (CreationException expected) {
+      assertContains(expected.getMessage(),
+          "1) Error at " + ScopesTest.class.getName(), ".configure(ScopesTest.java:",
+          "Scope Scopes.NO_SCOPE is already bound to " + CustomScoped.class.getName(), 
+          "Cannot bind Scopes.SINGLETON.\n\n" + "1 error[s]");
+    }
+  }
+
+  public void testDuplicateScopeAnnotations() {
+    try {
+      Guice.createInjector().getInstance(SingletonAndCustomScoped.class);
+      fail();
+    } catch (ProvisionException expected) {
+      assertContains(expected.getMessage(),
+          "1) Error at " + SingletonAndCustomScoped.class.getName(), ".class(ScopesTest.java:",
+          "More than one scope annotation was found: ");
+    }
+  }
+
   class RememberProviderScope implements Scope {
     final Map<Key<?>, Provider<?>> providers = Maps.newHashMap();
     public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
@@ -304,4 +347,7 @@
     static int nextInstanceId;
     final int instanceId = nextInstanceId++;
   }
+
+  @Singleton @CustomScoped
+  static class SingletonAndCustomScoped {}
 }