From 5a08861fcb8c5bc5831a6b99c192aba0a7933952 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 4 Oct 2014 11:46:20 -0400 Subject: test: New sangria-test project. --- sangria-test/pom.xml | 51 ++++++++++++ .../com/tavianator/sangria/test/AtomicMatcher.java | 38 +++++++++ .../sangria/test/BestPracticesMatcher.java | 42 ++++++++++ .../tavianator/sangria/test/SangriaMatchers.java | 31 ++++++++ .../com/tavianator/sangria/test/package-info.java | 25 ++++++ .../sangria/test/SangriaMatchersTest.java | 91 ++++++++++++++++++++++ 6 files changed, 278 insertions(+) create mode 100644 sangria-test/pom.xml create mode 100644 sangria-test/src/main/java/com/tavianator/sangria/test/AtomicMatcher.java create mode 100644 sangria-test/src/main/java/com/tavianator/sangria/test/BestPracticesMatcher.java create mode 100644 sangria-test/src/main/java/com/tavianator/sangria/test/SangriaMatchers.java create mode 100644 sangria-test/src/main/java/com/tavianator/sangria/test/package-info.java create mode 100644 sangria-test/src/test/java/com/tavianator/sangria/test/SangriaMatchersTest.java (limited to 'sangria-test') diff --git a/sangria-test/pom.xml b/sangria-test/pom.xml new file mode 100644 index 0000000..cdb835d --- /dev/null +++ b/sangria-test/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + + com.tavianator.sangria + sangria + 1.2-SNAPSHOT + + + sangria-test + jar + Sangria Test + Utilities for testing with Guice + + + + com.google.inject + guice + + + + com.google.guava + guava + + + + com.google.code.findbugs + jsr305 + true + + + + junit + junit + + + + org.hamcrest + hamcrest-integration + + + + org.mockito + mockito-core + test + + + diff --git a/sangria-test/src/main/java/com/tavianator/sangria/test/AtomicMatcher.java b/sangria-test/src/main/java/com/tavianator/sangria/test/AtomicMatcher.java new file mode 100644 index 0000000..03c897e --- /dev/null +++ b/sangria-test/src/main/java/com/tavianator/sangria/test/AtomicMatcher.java @@ -0,0 +1,38 @@ +package com.tavianator.sangria.test; + +import com.google.inject.CreationException; +import com.google.inject.Guice; +import com.google.inject.Module; +import com.google.inject.spi.Elements; +import org.hamcrest.Description; +import org.hamcrest.TypeSafeDiagnosingMatcher; + +/** + * Matcher that checks whether a {@link Module} can be installed multiple times. + * + * @author Tavian Barnes (tavianator@tavianator.com) + * @version 1.2 + * @since 1.2 + */ +final class AtomicMatcher extends TypeSafeDiagnosingMatcher { + @Override + protected boolean matchesSafely(Module item, Description mismatchDescription) { + // Pass through the SPI to make sure the Module is atomic regardless of its equals() implementation + // This ensures atomicity even through Modules.override(), for example + Module copy1 = Elements.getModule(Elements.getElements(item)); + Module copy2 = Elements.getModule(Elements.getElements(item)); + + try { + Guice.createInjector(copy1, copy2); + return true; + } catch (CreationException e) { + mismatchDescription.appendValue(e); + return false; + } + } + + @Override + public void describeTo(Description description) { + description.appendText("an atomic Module"); + } +} diff --git a/sangria-test/src/main/java/com/tavianator/sangria/test/BestPracticesMatcher.java b/sangria-test/src/main/java/com/tavianator/sangria/test/BestPracticesMatcher.java new file mode 100644 index 0000000..36eea97 --- /dev/null +++ b/sangria-test/src/main/java/com/tavianator/sangria/test/BestPracticesMatcher.java @@ -0,0 +1,42 @@ +package com.tavianator.sangria.test; + +import com.google.inject.AbstractModule; +import com.google.inject.CreationException; +import com.google.inject.Guice; +import com.google.inject.Module; +import org.hamcrest.Description; +import org.hamcrest.TypeSafeDiagnosingMatcher; + +/** + * Matcher that checks whether a {@link Module} follows Guice best practices. + * + * @author Tavian Barnes (tavianator@tavianator.com) + * @version 1.2 + * @since 1.2 + */ +final class BestPracticesMatcher extends TypeSafeDiagnosingMatcher { + private static final class EnforcerModule extends AbstractModule { + @Override + protected void configure() { + binder().requireAtInjectOnConstructors(); + binder().requireExactBindingAnnotations(); + binder().requireExplicitBindings(); + } + } + + @Override + protected boolean matchesSafely(Module item, Description mismatchDescription) { + try { + Guice.createInjector(item, new EnforcerModule()); + return true; + } catch (CreationException e) { + mismatchDescription.appendValue(e); + return false; + } + } + + @Override + public void describeTo(Description description) { + description.appendText("a Module following Guice best practices"); + } +} diff --git a/sangria-test/src/main/java/com/tavianator/sangria/test/SangriaMatchers.java b/sangria-test/src/main/java/com/tavianator/sangria/test/SangriaMatchers.java new file mode 100644 index 0000000..da8dd74 --- /dev/null +++ b/sangria-test/src/main/java/com/tavianator/sangria/test/SangriaMatchers.java @@ -0,0 +1,31 @@ +package com.tavianator.sangria.test; + +import com.google.inject.Module; +import org.hamcrest.Matcher; + +/** + * Guice-related Hamcrest matchers. + * + * @author Tavian Barnes (tavianator@tavianator.com) + * @version 1.2 + * @since 1.2 + */ +public final class SangriaMatchers { + private SangriaMatchers() { + // Not for instantiating + } + + /** + * @return A {@link Matcher} that checks whether a {@link Module}'s bindings can be de-duplicated successfully. + */ + public static Matcher atomic() { + return new AtomicMatcher(); + } + + /** + * @return A {@link Matcher} that checks whether a {@link Module} follows Guice best practices. + */ + public static Matcher followsBestPractices() { + return new BestPracticesMatcher(); + } +} diff --git a/sangria-test/src/main/java/com/tavianator/sangria/test/package-info.java b/sangria-test/src/main/java/com/tavianator/sangria/test/package-info.java new file mode 100644 index 0000000..0375640 --- /dev/null +++ b/sangria-test/src/main/java/com/tavianator/sangria/test/package-info.java @@ -0,0 +1,25 @@ +/**************************************************************************** + * Sangria * + * Copyright (C) 2014 Tavian Barnes * + * * + * 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. * + ****************************************************************************/ + +/** + * {@code sangria-test}: Utilities for testing with Guice. + * + * @author Tavian Barnes (tavianator@tavianator.com) + * @version 1.2 + * @since 1.2 + */ +package com.tavianator.sangria.test; diff --git a/sangria-test/src/test/java/com/tavianator/sangria/test/SangriaMatchersTest.java b/sangria-test/src/test/java/com/tavianator/sangria/test/SangriaMatchersTest.java new file mode 100644 index 0000000..06fb45e --- /dev/null +++ b/sangria-test/src/test/java/com/tavianator/sangria/test/SangriaMatchersTest.java @@ -0,0 +1,91 @@ +package com.tavianator.sangria.test; + +import javax.inject.Inject; +import javax.inject.Named; + +import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import org.junit.Test; + +import static com.tavianator.sangria.test.SangriaMatchers.*; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +/** + * Tests for {@link SangriaMatchers}. + * + * @author Tavian Barnes (tavianator@tavianator.com) + * @version 1.2 + * @since 1.2 + */ +public class SangriaMatchersTest { + private static class AtomicModule extends AbstractModule { + private static final Object INSTANCE = new Object(); + + @Override + protected void configure() { + bind(Object.class) + .toInstance(INSTANCE); + } + } + + private static class NonAtomicModule extends AbstractModule { + @Override + protected void configure() { + bind(Object.class) + .toInstance(new Object()); + } + } + + @Test + public void testAtomic() { + assertThat(new AtomicModule(), is(atomic())); + assertThat(new NonAtomicModule(), is(not(atomic()))); + } + + private static class NoAtInjectModule extends AbstractModule { + @Override + protected void configure() { + bind(String.class); + } + } + + private static class InexactBindingAnnotationModule extends AbstractModule { + @Override + protected void configure() { + bind(String.class) + .annotatedWith(Named.class) + .toInstance("test"); + } + + @Provides + String getString(@Named("test") String test) { + return test; + } + } + + private static class Injectable { + @Inject + Injectable() { + } + } + + private static class JustInTimeModule extends AbstractModule { + @Override + protected void configure() { + } + + @Provides + String getString(Injectable injectable) { + return "test"; + } + } + + @Test + public void testFollowsBestPractices() { + assertThat(new AtomicModule(), followsBestPractices()); + assertThat(new NoAtInjectModule(), not(followsBestPractices())); + assertThat(new InexactBindingAnnotationModule(), not(followsBestPractices())); + assertThat(new JustInTimeModule(), not(followsBestPractices())); + } +} -- cgit v1.2.3