[
  {
    "path": ".gitignore",
    "content": "gwt-unitCache\nwww-test\ntarget\n.project\n*.iml\n.settings\n.idea\n.classpath\n.gwt\nbin\nMETA-INF\n.checkstyle\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n"
  },
  {
    "path": "LICENSE.md",
    "content": "# License\n\nJukito is freely distributable under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html).\n"
  },
  {
    "path": "README.md",
    "content": "![Jukito](http://i.imgur.com/rSeHAEc.png \"Jukito\")\n\n### The combined power of JUnit, Guice and Mockito. Plus it sounds like a cool martial art.\n\n-----\n\nSo you started using dependency injection because somebody told you it would make your tests simpler? But as you gaze at your deep hierarchy of test classes, \"simple\" is not exactly the word you think of. Plus, creating a new mock whenever you add a parameter to an injected constructor gets old very quickly.\n\nYou are not alone! And Jukito was created specifically for people like you. Read on, or [get started](https://github.com/ArcBees/Jukito/wiki) right away!\n\nIf you use [Google Guice](http://code.google.com/p/google-guice/), or if your GWT application uses [Gin](http://code.google.com/p/google-gin/), then Jukito is the perfect antidote to your unit testing headaches. Now you can write tests like this:\n\n```java\n@RunWith(JukitoRunner.class)\npublic class EmailSystemTest {\n\n  @Inject EmailSystemImpl emailSystem;\n  Email dummyEmail;\n\n  @Before\n  public void setupMocks(\n      IncomingEmails incomingEmails,\n      EmailFactory factory) {\n    dummyEmail = factory.createDummy();\n    when(incomingEmails.count()).thenReturn(1);\n    when(incomingEmails.get(0)).thenReturn(dummyEmail);\n  }\n\n  @Test\n  public void shouldFetchEmailWhenStarting(\n      EmailView emailView) {\n    // WHEN\n    emailSystem.start();\n\n    // THEN\n    verify(emailView).addEmail(dummyEmail);\n  }\n}\n```\n\nThat's right, Jukito lets you `@Inject` fields exactly as if your test class was injected with Guice. You can also inject parameters into your `@Test`, `@Before` and `@After` methods. Guice's just-in-time binding automatically instantiate your concrete classes, like `EmailFactory`. What about interfaces like `IncomingEmails` or `EmailView`? Jukito mocks them out automatically for you using [mockito](https://code.google.com/p/mockito/)!\n\nLet's look at another example:\n\n```java\n@RunWith(JukitoRunner.class)\npublic class CalculatorTest {\n\n  public static class Module extends JukitoModule {\n    protected void configureTest() {\n      bindMany(Calculator.class,\n          ScientificCalculator.class,\n          BusinessCalculator.class);\n\n      bindManyInstances(AdditionExample.class, \n          new AdditionExample(1, 1, 2),\n          new AdditionExample(10, 10, 20),\n          new AdditionExample(18, 24, 42));\n    }\n  }\n\n  @Test\n  public void testAdd(@All Calculator calculator, @All AdditionExample example) {\n    // WHEN\n    int result = calculator.add(example.a, example.b);\n\n    // THEN\n    assertEquals(example.expected, result);\n  }\n}\n```\n\nAs you see here, Jukito lets you define your very own test module, where you can bind classes just like a regular Guice module. It doesn't stop there, however. The `bindMany` methods let you bind different classes or instances to the same interface. Combined with the powerful `@All` annotation this lets you easily run a single test on a whole suite of test examples. The code above will run a total of six tests!\n\n## Getting Started\n[Read the wiki](https://github.com/ArcBees/Jukito/wiki) to find out everything Jukito has to offer, and [join the discussion](http://groups.google.com/group/jukito)!\n\n## Latest Release\n* 1.5\n\n## Links\n* [Jukito Custom Google Search](http://www.google.com/cse/home?cx=011138278718949652927:turyqq9pl64) - Search GWTP documentation, wiki and thread collections.\n* [Jukito WebSite Source](https://github.com/ArcBees/jukito-website) - Jukito website source.\n* [Jukito Google Group](https://groups.google.com/forum/?fromgroups#!forum/jukito) - Find help here.\n* [Jukito Previous Repo](https://code.google.com/p/jukito/) - Previous home of Jukito.\n* [GWTP](https://github.com/ArcBees/GWTP) - Find out more about GWT-Platform.\n\n## Thanks to\n[![Arcbees.com](http://i.imgur.com/HDf1qfq.png)](http://arcbees.com)\n\n[![Atlassian](http://i.imgur.com/BKkj8Rg.png)](https://www.atlassian.com/)\n\n[![IntelliJ](https://lh6.googleusercontent.com/--QIIJfKrjSk/UJJ6X-UohII/AAAAAAAAAVM/cOW7EjnH778/s800/banner_IDEA.png)](http://www.jetbrains.com/idea/index.html)\n"
  },
  {
    "path": "codequality/checkstyle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE module PUBLIC \"-//Puppy Crawl//DTD Check Configuration 1.3//EN\"\n        \"http://users.tpg.com.au/ojburn/dtds/configuration_1_3.dtd\">\n\n<module name=\"Checker\">\n    <property name=\"severity\" value=\"error\"/>\n    <property name=\"localeCountry\" value=\"CA\"/>\n    <property name=\"localeLanguage\" value=\"en\"/>\n\n    <module name=\"LineLength\">\n        <property name=\"fileExtensions\" value=\"java\"/>\n        <property name=\"max\" value=\"120\"/>\n        <property name=\"ignorePattern\" value=\"^(import( static)?|package) [^ ]+$\"/>\n    </module>\n\n    <module name=\"TreeWalker\">\n        <module name=\"DeclarationOrder\"/>\n        <module name=\"EqualsHashCode\"/>\n        <module name=\"ExplicitInitialization\"/>\n        <module name=\"GenericWhitespace\"/>\n        <module name=\"MethodParamPad\"/>\n        <module name=\"MissingOverride\"/>\n        <module name=\"ModifiedControlVariable\"/>\n        <module name=\"ParameterAssignment\"/>\n        <module name=\"ParenPad\"/>\n        <module name=\"SimplifyBooleanExpression\"/>\n        <module name=\"SimplifyBooleanReturn\"/>\n        <module name=\"StringLiteralEquality\"/>\n        <module name=\"UnnecessaryParentheses\"/>\n        <module name=\"Indentation\">\n            <property name=\"basicOffset\" value=\"4\" />\n            <property name=\"throwsIndent\" value=\"8\"/>\n            <property name=\"arrayInitIndent\" value=\"8\"/>\n            <property name=\"lineWrappingIndentation\" value=\"8\"/>\n        </module>\n        <module name=\"InterfaceIsType\"/>\n        <module name=\"RedundantImport\"/>\n        <module name=\"UnusedImports\">\n            <property name=\"processJavadoc\" value=\"true\"/>\n        </module>\n        <module name=\"IllegalImport\"/>\n        <module name=\"AvoidStarImport\"/>\n        <module name=\"ImportOrder\">\n            <property name=\"option\" value=\"bottom\"/>\n            <property name=\"ordered\" value=\"true\"/>\n            <property name=\"separated\" value=\"true\"/>\n            <property name=\"groups\" value=\"java,javax,org,com\"/>\n        </module>\n        <module name=\"JavadocStyle\">\n            <property name=\"checkHtml\" value=\"false\"/>\n            <property name=\"tokens\" value=\"CLASS_DEF,CTOR_DEF,INTERFACE_DEF,METHOD_DEF,VARIABLE_DEF\"/>\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"Well formed java docs\"/>\n        </module>\n        <module name=\"ParameterName\"/>\n        <module name=\"LocalFinalVariableName\">\n            <property name=\"format\" value=\"^(\\$|\\$?[a-z][a-zA-Z0-9]*)$\"/>\n        </module>\n        <module name=\"LocalVariableName\">\n            <property name=\"tokens\" value=\"VARIABLE_DEF\"/>\n            <property name=\"format\" value=\"^(\\$|\\$?[a-z][a-zA-Z0-9]*)$\"/>\n        </module>\n        <module name=\"LeftCurly\"/>\n        <module name=\"RightCurly\"/>\n        <module name=\"NeedBraces\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"make sure if has braces\"/>\n        </module>\n        <module name=\"CovariantEquals\"/>\n        <module name=\"IllegalInstantiation\">\n            <property name=\"classes\" value=\"java.lang.Boolean\"/>\n        </module>\n        <module name=\"UpperEll\">\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"checking for 4l rather than 4L\"/>\n        </module>\n        <module name=\"DefaultComesLast\"/>\n        <module name=\"MultipleStringLiterals\">\n            <property name=\"ignoreStringsRegexp\" value=\".{0,3}\"/>\n        </module>\n        <module name=\"IllegalInstantiation\">\n            <property name=\"classes\" value=\"Boolean\"/>\n        </module>\n        <module name=\"Regexp\">\n            <property name=\"format\" value=\"[\\r]?[\\n][ \\t]*[\\r]?[\\n][ \\t]*[\\r]?[\\n][ \\t]*\"/>\n            <property name=\"message\" value=\"more than one blank line\"/>\n            <property name=\"illegalPattern\" value=\"true\"/>\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"more than one blank line\"/>\n        </module>\n        <module name=\"Regexp\">\n            <property name=\"format\" value=\"[\\r]?[\\n][ \\t]*[\\r]?[\\n][ \\t]+[}][ ]*[\\n]\"/>\n            <property name=\"message\" value=\"newline before }\"/>\n            <property name=\"illegalPattern\" value=\"true\"/>\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"newline before }\"/>\n        </module>\n        <module name=\"Regexp\">\n            <property name=\"format\" value=\"[^*][ \\t]+[\\r]?[\\n]\"/>\n            <property name=\"message\" value=\"trailing whitespace\"/>\n            <property name=\"illegalPattern\" value=\"true\"/>\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"trailing whitespace\"/>\n        </module>\n        <module name=\"RedundantModifier\"/>\n        <module name=\"ModifierOrder\"/>\n        <module name=\"EmptyStatement\"/>\n        <module name=\"MethodName\"/>\n        <module name=\"MemberName\">\n            <property name=\"format\" value=\"[a-z]|[a-z][a-z_0-9][A-Za-z0-9_]*|[a-z](?&lt;!f)[A-Z0-9]*\"/>\n        </module>\n        <module name=\"NoWhitespaceBefore\">\n            <property name=\"allowLineBreaks\" value=\"true\"/>\n            <property name=\"tokens\" value=\"DOT\"/>\n        </module>\n        <module name=\"NoWhitespaceAfter\">\n            <property name=\"allowLineBreaks\" value=\"false\"/>\n            <property name=\"tokens\" value=\"BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS\"/>\n        </module>\n        <module name=\"WhitespaceAround\">\n            <property name=\"tokens\"\n                      value=\"COLON,NOT_EQUAL,QUESTION,DIV,DIV_ASSIGN,BXOR,BXOR_ASSIGN,MINUS,LCURLY,STAR,STAR_ASSIGN,TYPE_EXTENSION_AND,BAND,LAND,BAND_ASSIGN,MOD,MOD_ASSIGN,PLUS,PLUS_ASSIGN,LT,SL,SL_ASSIGN,LE,ASSIGN,MINUS_ASSIGN,EQUAL,GT,GE,SR,SR_ASSIGN,BSR,BSR_ASSIGN,BOR,BOR_ASSIGN,LOR,LITERAL_ASSERT,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,SLIST,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE\"/>\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"Must have spaces\"/>\n        </module>\n        <module name=\"WhitespaceAfter\">\n            <property name=\"tokens\" value=\"TYPECAST\"/>\n        </module>\n        <module name=\"TypecastParenPad\">\n            <property name=\"tokens\" value=\"RPAREN,TYPECAST\"/>\n        </module>\n        <module name=\"SuppressionCommentFilter\">\n            <property name=\"offCommentFormat\" value=\"CHECKSTYLE_OFF\"/>\n            <property name=\"onCommentFormat\" value=\"CHECKSTYLE_ON\"/>\n        </module>\n        <module name=\"SuppressionCommentFilter\">\n            <property name=\"offCommentFormat\" value=\"CHECKSTYLE_NAMING_OFF\"/>\n            <property name=\"onCommentFormat\" value=\"CHECKSTYLE_NAMING_ON\"/>\n            <property name=\"checkFormat\" value=\".*Name.*\"/>\n            <property name=\"messageFormat\" value=\".*name.*\"/>\n            <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"Avoid name checking\"/>\n        </module>\n    </module>\n\n    <module name=\"Translation\"/>\n    <module name=\"NewlineAtEndOfFile\">\n        <property name=\"lineSeparator\" value=\"lf\"/>\n    </module>\n    <module name=\"FileTabCharacter\">\n        <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"no tabs\"/>\n    </module>\n    <module name=\"RegexpSingleline\">\n        <property name=\"format\" value=\"  [/][/][A-z]\"/>\n        <property name=\"message\" value=\"// comments must be followed by a space and be on their own line\"/>\n        <metadata name=\"com.atlassw.tools.eclipse.checkstyle.comment\" value=\"bad // comment\"/>\n    </module>\n    <module name=\"RegexpHeader\">\n        <property name=\"fileExtensions\" value=\"java\"/>\n        <property name=\"headerFile\" value=\"codequality/opensource.java.header\"/>\n    </module>\n</module>\n"
  },
  {
    "path": "codequality/opensource.java.header",
    "content": "/\\*\\*?\n \\* Copyright \\d{4} ArcBees Inc\\.\n \\*\n \\* Licensed under the Apache License, Version 2\\.0 \\(the \"License\"\\); you may not\n \\* use this file except in compliance with the License\\. You may obtain a copy of\n \\* the License at\n \\*\n \\* http://www\\.apache\\.org/licenses/LICENSE-2\\.0\n \\*\n \\* Unless required by applicable law or agreed to in writing, software\n \\* distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n \\* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\\. See the\n \\* License for the specific language governing permissions and limitations under\n \\* the License\\.\n \\*/\n"
  },
  {
    "path": "codequality/suppressions.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE suppressions PUBLIC\n        \"-//Puppy Crawl//DTD Suppressions 1.1//EN\"\n        \"http://users.tpg.com.au/ojburn/dtds/suppressions_1_1.dtd\">\n\n<suppressions>\n    <!-- Suppress files under target -->\n    <suppress checks=\".*\" files=\".*[/\\\\]target[/\\\\].*\"/>\n\n    <!-- Suppress method naming under test -->\n    <suppress checks=\"MethodName\" files=\".*[/\\\\]test[/\\\\].*\"/>\n\n    <!-- Suppress files under com/google -->\n    <suppress checks=\".*\" files=\"com[/\\\\]google[/\\\\]\"/>\n</suppressions>\n"
  },
  {
    "path": "jukito/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.jukito</groupId>\n        <artifactId>jukito-parent</artifactId>\n        <version>1.6-SNAPSHOT</version>\n    </parent>\n\n    <artifactId>jukito</artifactId>\n    <packaging>jar</packaging>\n    <name>jukito</name>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n            </plugin>\n\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n            </plugin>\n\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-deploy-plugin</artifactId>\n            </plugin>\n\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-source-plugin</artifactId>\n            </plugin>\n\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-release-plugin</artifactId>\n            </plugin>\n\n            <plugin>\n                <groupId>org.codehaus.mojo</groupId>\n                <artifactId>animal-sniffer-maven-plugin</artifactId>\n            </plugin>\n\n            <!-- run 'mvn javadoc:aggregate' to generate -->\n            <!-- run 'mvn javadoc:aggregate -X' to debug -->\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-javadoc-plugin</artifactId>\n            </plugin>\n\n            <!-- run 'mvn site' to upload -->\n            <!-- run 'mvn site -X' to debug and upload. -->\n            <plugin>\n                <groupId>com.github.github</groupId>\n                <artifactId>site-maven-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.mockito</groupId>\n            <artifactId>mockito-core</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>junit</groupId>\n            <artifactId>junit</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>com.google.inject</groupId>\n            <artifactId>guice</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>com.google.inject.extensions</groupId>\n            <artifactId>guice-assistedinject</artifactId>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/All.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport com.google.inject.BindingAnnotation;\n\n/**\n * This annotation can be used on one or more parameter of a test function.\n * The test function will be executed multiple times, one for each value bound\n * to the parameter type.\n * <p/>\n * If more than one parameter is annotated with {@literal @}{@link All} then\n * all combinations will be used. Therefore, be careful when using it on more than\n * two or three parameters as it can result in a combinatorial explosion.\n * <p/>\n * Using the additional parameter {@link #value()} a subset of all bound values\n * can be specified to be run in the test function.\n *\n * @see {@link TestModule#bindMany}\n * @see {@link TestModule#bindManyInstances}\n * @see {@link TestModule#bindManyNamed}\n * @see {@link TestModule#bindManyNamedInstances}\n */\n@BindingAnnotation\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.PARAMETER)\npublic @interface All {\n    String DEFAULT = \"__ALL__\";\n\n    /**\n     * Used in conjunction with {@link org.jukito.JukitoModule#bindManyNamed(Class, String, Class[])} and related\n     * methods to retrieve all objects binded with the given name.\n     */\n    String value() default DEFAULT;\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/BindingsCollector.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.Annotation;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\n\nimport com.google.inject.AbstractModule;\nimport com.google.inject.Binding;\nimport com.google.inject.Key;\nimport com.google.inject.Scope;\nimport com.google.inject.spi.ConstructorBinding;\nimport com.google.inject.spi.ConvertedConstantBinding;\nimport com.google.inject.spi.DefaultBindingScopingVisitor;\nimport com.google.inject.spi.DefaultBindingTargetVisitor;\nimport com.google.inject.spi.DefaultElementVisitor;\nimport com.google.inject.spi.Dependency;\nimport com.google.inject.spi.Element;\nimport com.google.inject.spi.Elements;\nimport com.google.inject.spi.InjectionPoint;\nimport com.google.inject.spi.InstanceBinding;\nimport com.google.inject.spi.LinkedKeyBinding;\nimport com.google.inject.spi.Message;\nimport com.google.inject.spi.PrivateElements;\nimport com.google.inject.spi.ProviderBinding;\nimport com.google.inject.spi.ProviderInstanceBinding;\nimport com.google.inject.spi.ProviderKeyBinding;\nimport com.google.inject.spi.StaticInjectionRequest;\nimport com.google.inject.spi.UntargettedBinding;\n\n/**\n * Collects all the bindings from a Guice module, so that Jukito can identify missing\n * bindings and bind them to mock or instances.\n */\npublic class BindingsCollector {\n\n    /**\n     * Information on a binding, used by Jukito to identify provided keys and needed keys.\n     */\n    public static class BindingInfo {\n\n        public Object boundInstance;\n        Key<?> key;\n        Key<?> boundKey;\n        String scope;\n\n        public static BindingInfo create(Binding<?> binding, Key<?> boundKey,\n                Object instance) {\n            BindingInfo bindingInfo = new BindingInfo();\n            bindingInfo.key = binding.getKey();\n            bindingInfo.boundKey = boundKey;\n            bindingInfo.boundInstance = instance;\n            bindingInfo.scope = binding.acceptScopingVisitor(new GuiceScopingVisitor());\n            return bindingInfo;\n        }\n\n        public static BindingInfo create(Key<?> boundKey) {\n            BindingInfo bindingInfo = new BindingInfo();\n            bindingInfo.boundKey = boundKey;\n\n            return bindingInfo;\n        }\n    }\n\n    private final AbstractModule module;\n    private final List<BindingInfo> bindingsObserved = new ArrayList<>();\n    private final List<Message> messages = new ArrayList<>();\n\n    BindingsCollector(AbstractModule module) {\n        this.module = module;\n    }\n\n    public void collectBindings() {\n        GuiceElementVisitor visitor = new GuiceElementVisitor();\n        visitor.visitElements(Elements.getElements(module));\n\n        // TODO report errors?\n    }\n\n    public List<BindingInfo> getBindingsObserved() {\n        return bindingsObserved;\n    }\n\n    /**\n     * This visitor collects all information on various guice elements.\n     */\n    public class GuiceElementVisitor extends DefaultElementVisitor<Void> {\n\n        private void visitElements(List<Element> elements) {\n            for (Element element : elements) {\n                element.acceptVisitor(this);\n            }\n        }\n\n        @Override\n        public <T> Void visit(com.google.inject.Binding<T> command) {\n            GuiceBindingVisitor<T> bindingVisitor = new GuiceBindingVisitor<>();\n            command.acceptTargetVisitor(bindingVisitor);\n            return null;\n        }\n\n        @SuppressWarnings(\"unchecked\")\n        @Override\n        public Void visit(PrivateElements privateElements) {\n            Set<Key<?>> exposedKeys = privateElements.getExposedKeys();\n            for (Element element : privateElements.getElements()) {\n                if (element instanceof Binding<?>) {\n                    Binding<?> bindingElement = (Binding<?>) element;\n                    if (exposedKeys.contains(bindingElement.getKey())) {\n                        @SuppressWarnings(\"rawtypes\")\n                        GuicePrivateBindingVisitor bindingVisitor = new GuicePrivateBindingVisitor();\n                        bindingElement.acceptTargetVisitor(bindingVisitor);\n                    }\n                }\n            }\n            return null;\n        }\n\n        @Override\n        public Void visit(StaticInjectionRequest staticInjectionRequest) {\n            for (InjectionPoint injectionPoint : staticInjectionRequest.getInjectionPoints()) {\n                addInjectionPointDependencies(injectionPoint);\n            }\n\n            return super.visit(staticInjectionRequest);\n        }\n\n        @Override\n        public Void visit(Message message) {\n            messages.add(message);\n            return null;\n        }\n\n        private void addInjectionPointDependencies(InjectionPoint injectionPoint) {\n            // Do not consider dependencies coming from optional injections.\n            if (injectionPoint.isOptional()) {\n                return;\n            }\n\n            for (Dependency<?> dependency : injectionPoint.getDependencies()) {\n                Key<?> key = dependency.getKey();\n\n                bindingsObserved.add(BindingInfo.create(key));\n            }\n        }\n    }\n\n    /**\n     * This visitor collects all information on guice bindings.\n     */\n    public class GuiceBindingVisitor<T> extends DefaultBindingTargetVisitor<T, Void> {\n\n        protected Void addBindingInfo(Binding<? extends T> binding, Key<?> boundKey, Object instance) {\n            bindingsObserved.add(BindingInfo.create(binding, boundKey, instance));\n            return null;\n        }\n\n        private Void addBinding(Binding<? extends T> binding) {\n            return addBindingInfo(binding, binding.getKey(), null);\n        }\n\n        private Void addBindingKey(Binding<? extends T> binding, Key<?> boundKey) {\n            return addBindingInfo(binding, boundKey, null);\n        }\n\n        private Void addBindingInstance(Binding<? extends T> binding, Object instance) {\n            return addBindingInfo(binding, null, instance);\n        }\n\n        @Override\n        public Void visit(ProviderBinding<? extends T> providerBinding) {\n            return addBindingKey(providerBinding, providerBinding.getProvidedKey());\n        }\n\n        @Override\n        public Void visit(ProviderKeyBinding<? extends T> providerKeyBinding) {\n            return addBindingKey(providerKeyBinding, providerKeyBinding.getProviderKey());\n        }\n\n        @Override\n        public Void visit(ProviderInstanceBinding<? extends T> providerInstanceBinding) {\n            return addBindingInstance(providerInstanceBinding,\n                    providerInstanceBinding.getProviderInstance());\n        }\n\n        @Override\n        public Void visit(InstanceBinding<? extends T> instanceBinding) {\n            return addBindingInstance(instanceBinding, instanceBinding.getInstance());\n        }\n\n        @Override\n        public Void visit(ConvertedConstantBinding<? extends T> constantBinding) {\n            return addBindingInstance(constantBinding, constantBinding.getValue());\n        }\n\n        @Override\n        public Void visit(UntargettedBinding<? extends T> untargettedBinding) {\n            return addBinding(untargettedBinding);\n        }\n\n        @Override\n        public Void visit(LinkedKeyBinding<? extends T> linkedKeyBinding) {\n            return addBindingKey(linkedKeyBinding, linkedKeyBinding.getLinkedKey());\n        }\n\n        @Override\n        public Void visit(ConstructorBinding<? extends T> constructorBinding) {\n            return addBinding(constructorBinding);\n        }\n    }\n\n    /**\n     * This visitor collects the bindings for PrivateModules. Because the child\n     * elements are private, the bound keys are not recorded.\n     */\n    public class GuicePrivateBindingVisitor<T> extends GuiceBindingVisitor<T> {\n\n        @Override\n        public Void visit(LinkedKeyBinding<? extends T> linkedKeyBinding) {\n            return addBindingInfo(linkedKeyBinding, null, null);\n        }\n    }\n\n    /**\n     * This visitor collects all information on guice scopes associated to the bindings.\n     */\n    public static class GuiceScopingVisitor extends DefaultBindingScopingVisitor<String> {\n\n        @Override\n        public String visitEagerSingleton() {\n            return \"EagerSingleton\";\n        }\n\n        @Override\n        public String visitScope(Scope scope) {\n            return scope.toString();\n        }\n\n        @Override\n        public String visitScopeAnnotation(Class<? extends Annotation> scopeAnnotation) {\n            return scopeAnnotation.getCanonicalName();\n        }\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/Description.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Annotation can be used for better test description (instead of camel case test method).\n */\n@Target({ElementType.METHOD})\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Description {\n    String value();\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/EnvironmentDependentModules.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport com.google.inject.Module;\n\n/**\n * Annotation used for declaration of modules which are installed\n * and used separately in different applications\n * but test for it collaborators are the same and thus\n * run for against Environment Dependent Modules.\n */\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface EnvironmentDependentModules {\n    Class<? extends Module>[] value();\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/GuiceUtils.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.List;\n\nimport com.google.inject.ConfigurationException;\nimport com.google.inject.Key;\nimport com.google.inject.Provider;\nimport com.google.inject.TypeLiteral;\nimport com.google.inject.internal.Annotations;\nimport com.google.inject.internal.Errors;\nimport com.google.inject.internal.ErrorsException;\n\n/**\n * A number of useful static methods to manipulate Guice object. Most are\n * taken from the source code of Guice, but cannot be accessed in there.\n */\npublic class GuiceUtils {\n\n    public static boolean isProvider(Key<?> key) {\n        return key.getTypeLiteral().getRawType().equals(Provider.class);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public static <T> TypeLiteral<T> getProvidedType(\n            TypeLiteral<? extends Provider<? extends T>> initialProviderTypeLiteral,\n            Errors errors) throws ErrorsException {\n\n        TypeLiteral<? extends Provider<? extends T>> providerTypeLiteral = initialProviderTypeLiteral;\n        while (providerTypeLiteral.getRawType() != Provider.class) {\n            providerTypeLiteral = (TypeLiteral<? extends Provider<? extends T>>)\n                    providerTypeLiteral.getSupertype(Provider.class);\n        }\n\n        Type providerType = providerTypeLiteral.getType();\n\n        // If the Provider has no type parameter (raw Provider)...\n        if (!(providerType instanceof ParameterizedType)) {\n            throw errors.cannotInjectRawProvider().toException();\n        }\n\n        Type entryType = ((ParameterizedType) providerType).getActualTypeArguments()[0];\n        return (TypeLiteral<T>) TypeLiteral.get(entryType);\n    }\n\n    public static <T> Key<T> getProvidedKey(Key<Provider<T>> key,\n            Errors errors) throws ErrorsException {\n        TypeLiteral<T> providedType = getProvidedType(key.getTypeLiteral(), errors);\n\n        Key<T> providedKey;\n        if (key.getAnnotation() == null) {\n            providedKey = (Key<T>) Key.get(providedType);\n        } else {\n            providedKey = (Key<T>) Key.get(providedType, key.getAnnotation());\n        }\n        return providedKey;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public static <T> Key<T> ensureProvidedKey(Key<T> key, Errors errors) {\n        try {\n            return isProvider(key) ? getProvidedKey((Key<Provider<T>>) key, errors) : key;\n        } catch (ConfigurationException e) {\n            errors.merge(e.getErrorMessages());\n        } catch (ErrorsException e) {\n            errors.merge(e.getErrors());\n        }\n        return null;\n    }\n\n    public static List<Key<?>> getMethodKeys(Method method, Errors errors) {\n        Annotation allParameterAnnotations[][] = method.getParameterAnnotations();\n        List<Key<?>> result = new ArrayList<Key<?>>(allParameterAnnotations.length);\n        Iterator<Annotation[]> annotationsIterator = Arrays.asList(allParameterAnnotations).iterator();\n        TypeLiteral<?> type = TypeLiteral.get(method.getDeclaringClass());\n        for (TypeLiteral<?> parameterType : type.getParameterTypes(method)) {\n            try {\n                Annotation[] parameterAnnotations = annotationsIterator.next();\n                result.add(Annotations.getKey(parameterType, method, parameterAnnotations, errors));\n            } catch (ConfigurationException e) {\n                errors.merge(e.getErrorMessages());\n            } catch (ErrorsException e) {\n                errors.merge(e.getErrors());\n            }\n        }\n        return result;\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/InjectedAfterStatements.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.junit.internal.runners.model.MultipleFailureException;\nimport org.junit.runners.model.FrameworkMethod;\nimport org.junit.runners.model.Statement;\n\nimport com.google.inject.Injector;\n\n/**\n * A {@link Statement} invoking a list of methods with parameters by filling-in\n * these parameters with injected instances. The methods are called after the\n * provided {@code prev} {@link Statement}.\n */\npublic class InjectedAfterStatements extends Statement {\n\n    private final Statement prev;\n    private final List<Statement> afters;\n\n    public InjectedAfterStatements(Statement prev, List<FrameworkMethod> afters,\n            Object target, Injector injector) {\n        this.prev = prev;\n        this.afters = new ArrayList<Statement>(afters.size());\n        for (FrameworkMethod method : afters) {\n            this.afters.add(new InjectedStatement(method, target, injector));\n        }\n    }\n\n    @Override\n    public void evaluate() throws Throwable {\n        List<Throwable> errors = new ArrayList<Throwable>();\n        errors.clear();\n        try {\n            prev.evaluate();\n        } catch (Throwable e) {\n            errors.add(e);\n        } finally {\n            for (Statement after : afters) {\n                try {\n                    after.evaluate();\n                } catch (Throwable e) {\n                    errors.add(e);\n                }\n            }\n        }\n        if (!errors.isEmpty()) {\n            throw new MultipleFailureException(errors);\n        }\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/InjectedBeforeStatements.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.junit.runners.model.FrameworkMethod;\nimport org.junit.runners.model.Statement;\n\nimport com.google.inject.Injector;\n\n/**\n * A {@link Statement} invoking a list of methods with parameters by filling-in\n * these parameters with injected instances. The methods are called before the\n * provided {@code next} {@link Statement}.\n */\npublic class InjectedBeforeStatements extends Statement {\n\n    private final Statement next;\n    private final List<Statement> befores;\n\n    public InjectedBeforeStatements(Statement next, List<FrameworkMethod> befores,\n            Object target, Injector injector) {\n        this.next = next;\n        this.befores = new ArrayList<Statement>(befores.size());\n        for (FrameworkMethod method : befores) {\n            this.befores.add(new InjectedStatement(method, target, injector));\n        }\n    }\n\n    @Override\n    public void evaluate() throws Throwable {\n        for (Statement before : befores) {\n            before.evaluate();\n        }\n        next.evaluate();\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/InjectedFrameworkMethod.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.reflect.Method;\nimport java.util.List;\n\nimport org.junit.runners.model.FrameworkMethod;\n\nimport com.google.inject.Binding;\n\n/**\n * This class is an extension of {@link FrameworkMethod} that makes it possible to specify\n * which {@link Binding} to use for parameters marked with {@literal @}{@link All}.\n */\npublic class InjectedFrameworkMethod extends FrameworkMethod {\n\n    private final List<Binding<?>> bindingsToUseForParameters;\n\n    public InjectedFrameworkMethod(Method method) {\n        super(method);\n        bindingsToUseForParameters = null;\n    }\n\n    public InjectedFrameworkMethod(Method method, List<Binding<?>> bindingsToUseForParameters) {\n        super(method);\n        this.bindingsToUseForParameters = bindingsToUseForParameters;\n    }\n\n    public List<Binding<?>> getBindingsToUseForParameters() {\n        return bindingsToUseForParameters;\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/InjectedStatement.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\nimport org.junit.runners.model.FrameworkMethod;\nimport org.junit.runners.model.Statement;\n\nimport com.google.inject.Binding;\nimport com.google.inject.Guice;\nimport com.google.inject.Injector;\nimport com.google.inject.Key;\nimport com.google.inject.Module;\nimport com.google.inject.internal.Errors;\n\n/**\n * A {@link Statement} invoking a method with parameters by filling-in these\n * parameters with injected instances.\n */\nclass InjectedStatement extends Statement {\n\n    private final FrameworkMethod method;\n    private final Object test;\n    private final Injector injector;\n\n    InjectedStatement(FrameworkMethod method, Object test, Injector injector) {\n        this.method = method;\n        this.test = test;\n        this.injector = injector;\n    }\n\n    @Override\n    public void evaluate() throws Throwable {\n        Method javaMethod = method.getMethod();\n        Injector methodInjector = injector;\n\n        UseModules useModules = javaMethod.getAnnotation(UseModules.class);\n        if (useModules != null) {\n            Class<? extends Module>[] moduleClasses = useModules.value();\n            final Module[] modules = new Module[moduleClasses.length];\n            for (int i = 0; i < modules.length; i++) {\n                modules[i] = moduleClasses[i].newInstance();\n            }\n            TestModule jukitoModule;\n            if (useModules.autoBindMocks()) {\n                jukitoModule = new JukitoModule() {\n                    @Override\n                    protected void configureTest() {\n                        for (Module m : modules) {\n                            install(m);\n                        }\n                    }\n                };\n            } else {\n                jukitoModule = new TestModule() {\n                    @Override\n                    protected void configureTest() {\n                        for (Module m : modules) {\n                            install(m);\n                        }\n                    }\n                };\n            }\n            methodInjector = Guice.createInjector(jukitoModule);\n        }\n\n        Errors errors = new Errors(javaMethod);\n        List<Key<?>> keys = GuiceUtils.getMethodKeys(javaMethod, errors);\n        errors.throwConfigurationExceptionIfErrorsExist();\n\n        Iterator<Binding<?>> bindingIter;\n        if (InjectedFrameworkMethod.class.isAssignableFrom(method.getClass())) {\n            bindingIter = ((InjectedFrameworkMethod) method).getBindingsToUseForParameters().iterator();\n        } else {\n            bindingIter = new ArrayList<Binding<?>>().iterator();\n        }\n\n        List<Object> injectedParameters = new ArrayList<Object>();\n        for (Key<?> key : keys) {\n            if (!All.class.equals(key.getAnnotationType())) {\n                injectedParameters.add(methodInjector.getInstance(key));\n            } else {\n                if (!bindingIter.hasNext()) {\n                    throw new AssertionError(\"Expected more bindings to fill @All parameters.\");\n                }\n                injectedParameters.add(methodInjector.getInstance(bindingIter.next().getKey()));\n            }\n        }\n\n        method.invokeExplosively(test, injectedParameters.toArray());\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/JukitoInternal.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport com.google.inject.BindingAnnotation;\n\n/**\n * An internal binding annotation used when binding {@link SpyProvider}.\n * See {@link TestModule#bindSpy(Class)}.\n */\n@BindingAnnotation\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})\n@interface JukitoInternal {\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/JukitoModule.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.io.IOException;\nimport java.io.Writer;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.logging.Logger;\n\nimport org.jukito.BindingsCollector.BindingInfo;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport com.google.inject.ConfigurationException;\nimport com.google.inject.Injector;\nimport com.google.inject.Key;\nimport com.google.inject.MembersInjector;\nimport com.google.inject.Provider;\nimport com.google.inject.Singleton;\nimport com.google.inject.Stage;\nimport com.google.inject.TypeLiteral;\nimport com.google.inject.assistedinject.Assisted;\nimport com.google.inject.internal.Errors;\nimport com.google.inject.internal.ProviderMethod;\nimport com.google.inject.internal.ProviderMethodsModule;\nimport com.google.inject.spi.Dependency;\nimport com.google.inject.spi.HasDependencies;\nimport com.google.inject.spi.InjectionPoint;\n\n/**\n * A guice {@link com.google.inject.Module Module} with a bit of syntactic sugar\n * to bind within typical test scopes. Depends on mockito. This module\n * automatically mocks any interface or abstract class dependency for which a\n * binding is not explicitly provided. Any concrete class for which a binding is\n * not explicitly provided is bound as a {@link TestScope#SINGLETON}.\n * <p/>\n * Depends on Mockito.\n */\npublic abstract class JukitoModule extends TestModule {\n\n    protected List<BindingInfo> bindingsObserved = Collections.emptyList();\n\n    private final Set<Class<?>> forceMock = new HashSet<>();\n    private final Set<Class<?>> dontForceMock = new HashSet<>();\n    private final List<Key<?>> keysNeedingTransitiveDependencies = new ArrayList<>();\n    private final Map<Class<?>, Object> primitiveTypes = new HashMap<>();\n\n    public JukitoModule() {\n        primitiveTypes.put(String.class, \"\");\n        primitiveTypes.put(Integer.class, 0);\n        primitiveTypes.put(Long.class, 0L);\n        primitiveTypes.put(Boolean.class, false);\n        primitiveTypes.put(Double.class, 0.0);\n        primitiveTypes.put(Float.class, 0.0f);\n        primitiveTypes.put(Short.class, (short) 0);\n        primitiveTypes.put(Character.class, '\\0');\n        primitiveTypes.put(Byte.class, (byte) 0);\n        primitiveTypes.put(Class.class, Object.class);\n    }\n\n    /**\n     * Attach this {@link JukitoModule} to a list of the bindings that were\n     * observed by a preliminary run of {@link BindingsCollector}.\n     *\n     * @param bindingsObserved The observed bindings.\n     */\n    public void setBindingsObserved(List<BindingInfo> bindingsObserved) {\n        this.bindingsObserved = bindingsObserved;\n    }\n\n    /**\n     * By default, only abstract classes, interfaces and classes annotated with\n     * {@link TestMockSingleton} are automatically mocked. Use {@link #forceMock}\n     * to indicate that all concrete classes derived from the a specific type\n     * will be mocked in {@link TestMockSingleton} scope.\n     *\n     * @param klass The {@link Class} or interface for which all subclasses will be mocked.\n     */\n    protected void forceMock(Class<?> klass) {\n        forceMock.add(klass);\n    }\n\n    @Override\n    @SuppressWarnings({\"unchecked\", \"rawtypes\"})\n    public final void configure() {\n        bindScopes();\n        configureTest();\n\n        Set<Key<?>> keysObserved = new HashSet<>(bindingsObserved.size());\n        Set<Key<?>> keysNeeded = new HashSet<>(bindingsObserved.size());\n\n        for (BindingInfo bindingInfo : bindingsObserved) {\n            if (bindingInfo.key != null) {\n                keysObserved.add(bindingInfo.key);\n            }\n            if (bindingInfo.boundKey != null) {\n                keysNeeded.add(bindingInfo.boundKey);\n            }\n            if (bindingInfo.boundInstance != null &&\n                    bindingInfo.boundInstance instanceof HasDependencies) {\n                HasDependencies hasDependencies = (HasDependencies) bindingInfo.boundInstance;\n                for (Dependency<?> dependency : hasDependencies.getDependencies()) {\n                    keysNeeded.add(dependency.getKey());\n                }\n            }\n        }\n\n        // registering keys build via @Provides methods in this module in the keysObserved set.\n        ProviderMethodsModule providerMethodsModule = (ProviderMethodsModule)\n                ProviderMethodsModule.forModule(this);\n\n        List<ProviderMethod<?>> providerMethodList = providerMethodsModule.getProviderMethods(binder());\n        for (ProviderMethod<?> providerMethod : providerMethodList) {\n            keysObserved.add(providerMethod.getKey());\n        }\n\n        // Make sure needed keys from Guice bindings are bound as mock or to instances\n        // (but not as test singletons)\n        for (Key<?> keyNeeded : keysNeeded) {\n            addNeededKey(keysObserved, keysNeeded, keyNeeded, false);\n            keysNeedingTransitiveDependencies.add(keyNeeded);\n        }\n\n        // Preempt JIT binding by looking through the test class and any parent class\n        // looking for methods annotated with @Test, @Before, or @After.\n        // Concrete classes bound in this way are bound in @TestSingleton.\n        Class<?> currentClass = testClass;\n        while (currentClass != null) {\n            for (Method method : currentClass.getDeclaredMethods()) {\n                if (method.isAnnotationPresent(Test.class)\n                        || method.isAnnotationPresent(Before.class)\n                        || method.isAnnotationPresent(After.class)) {\n\n                    Errors errors = new Errors(method);\n                    List<Key<?>> keys = GuiceUtils.getMethodKeys(method, errors);\n\n                    for (Key<?> key : keys) {\n                        // Skip keys annotated with @All\n                        if (!All.class.equals(key.getAnnotationType())) {\n                            Key<?> keyNeeded = GuiceUtils.ensureProvidedKey(key, errors);\n                            addNeededKey(keysObserved, keysNeeded, keyNeeded, true);\n                        }\n                    }\n                    errors.throwConfigurationExceptionIfErrorsExist();\n                }\n            }\n            currentClass = currentClass.getSuperclass();\n        }\n\n        // Preempt JIT binding by looking through the test class looking for\n        // fields and methods annotated with @Inject.\n        // Concrete classes bound in this way are bound in @TestSingleton.\n        if (testClass != null) {\n            Set<InjectionPoint> injectionPoints = InjectionPoint.forInstanceMethodsAndFields(testClass);\n\n            for (InjectionPoint injectionPoint : injectionPoints) {\n                Errors errors = new Errors(injectionPoint);\n                List<Dependency<?>> dependencies = injectionPoint.getDependencies();\n                for (Dependency<?> dependency : dependencies) {\n                    Key<?> keyNeeded = GuiceUtils.ensureProvidedKey(dependency.getKey(),\n                            errors);\n                    addNeededKey(keysObserved, keysNeeded, keyNeeded, true);\n                }\n                errors.throwConfigurationExceptionIfErrorsExist();\n            }\n        }\n\n        // Recursively add the dependencies of all the bindings observed. Warning, we can't use for each here\n        // since it would result into concurrency issues.\n        for (int i = 0; i < keysNeedingTransitiveDependencies.size(); ++i) {\n            addDependencies(keysNeedingTransitiveDependencies.get(i), keysObserved, keysNeeded);\n        }\n\n        // Bind all keys needed but not observed as mocks.\n        for (Key<?> key : keysNeeded) {\n            Class<?> rawType = key.getTypeLiteral().getRawType();\n            if (!keysObserved.contains(key) && !isCoreGuiceType(rawType)\n                    && !isAssistedInjection(key)) {\n                Object primitiveInstance = getDummyInstanceOfPrimitiveType(rawType);\n                if (primitiveInstance == null) {\n                    if (rawType != Provider.class && !isInnerClass(rawType)) {\n                        bind(key).toProvider(new MockProvider(rawType)).in(TestScope.SINGLETON);\n                    }\n                } else {\n                    bindKeyToInstance(key, primitiveInstance);\n                }\n            }\n        }\n    }\n\n    private boolean isInnerClass(Class<?> rawType) {\n        return rawType.isMemberClass() && !Modifier.isStatic(rawType.getModifiers());\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private <T> void bindKeyToInstance(Key<T> key, Object primitiveInstance) {\n        bind(key).toInstance((T) primitiveInstance);\n    }\n\n    private void addNeededKey(Set<Key<?>> keysObserved, Set<Key<?>> keysNeeded,\n            Key<?> keyNeeded, boolean asTestSingleton) {\n        keysNeeded.add(keyNeeded);\n        bindIfConcrete(keysObserved, keyNeeded, asTestSingleton);\n    }\n\n    private <T> void bindIfConcrete(Set<Key<?>> keysObserved,\n            Key<T> key, boolean asTestSingleton) {\n        TypeLiteral<?> typeToBind = key.getTypeLiteral();\n        Class<?> rawType = typeToBind.getRawType();\n        if (!keysObserved.contains(key) && canBeInjected(typeToBind)\n                && !shouldForceMock(rawType) && !isAssistedInjection(key)) {\n\n            // If an @Singleton annotation is present, force the bind as TestSingleton\n            if (asTestSingleton ||\n                    rawType.getAnnotation(Singleton.class) != null) {\n                bind(key).in(TestScope.SINGLETON);\n            } else {\n                bind(key);\n            }\n            keysObserved.add(key);\n            keysNeedingTransitiveDependencies.add(key);\n        }\n    }\n\n    private boolean canBeInjected(TypeLiteral<?> type) {\n        Class<?> rawType = type.getRawType();\n        if (isPrimitive(rawType) || isCoreGuiceType(rawType) || !isInstantiable(rawType)) {\n            return false;\n        }\n        try {\n            InjectionPoint.forConstructorOf(type);\n            return true;\n        } catch (ConfigurationException e) {\n            return false;\n        }\n    }\n\n    private boolean isAssistedInjection(Key<?> key) {\n        return key.getAnnotationType() != null\n                && Assisted.class.isAssignableFrom(key.getAnnotationType());\n    }\n\n    private boolean shouldForceMock(Class<?> klass) {\n        if (dontForceMock.contains(klass)) {\n            return false;\n        }\n        if (forceMock.contains(klass)) {\n            return true;\n        }\n        // The forceMock set contains all the base classes the user wants\n        // to force mock, check id the specified klass is a subclass of one of\n        // these.\n        // Update forceMock or dontForceMock based on the result to speed-up\n        // future look-ups.\n        boolean result = false;\n        for (Class<?> classToMock : forceMock) {\n            if (classToMock.isAssignableFrom(klass)) {\n                result = true;\n                break;\n            }\n        }\n\n        if (result) {\n            forceMock.add(klass);\n        } else {\n            dontForceMock.add(klass);\n        }\n\n        return result;\n    }\n\n    private boolean isInstantiable(Class<?> klass) {\n        return !klass.isInterface() && !Modifier.isAbstract(klass.getModifiers());\n    }\n\n    private boolean isPrimitive(Class<?> klass) {\n        return getDummyInstanceOfPrimitiveType(klass) != null;\n    }\n\n    private Object getDummyInstanceOfPrimitiveType(Class<?> klass) {\n        Object instance = primitiveTypes.get(klass);\n        if (instance == null && Enum.class.isAssignableFrom(klass)) {\n            // Safe to ignore exception, Guice will fail with a reasonable error\n            // if the Enum is empty.\n            try {\n                instance = ((Object[]) klass.getMethod(\"values\").invoke(null))[0];\n            } catch (Exception ignored) {\n            }\n        }\n        return instance;\n    }\n\n    private boolean isCoreGuiceType(Class<?> klass) {\n        return TypeLiteral.class.isAssignableFrom(klass)\n                || Injector.class.isAssignableFrom(klass)\n                || Logger.class.isAssignableFrom(klass)\n                || Stage.class.isAssignableFrom(klass)\n                || MembersInjector.class.isAssignableFrom(klass);\n    }\n\n    private <T> void addDependencies(Key<T> key, Set<Key<?>> keysObserved,\n            Set<Key<?>> keysNeeded) {\n        TypeLiteral<T> type = key.getTypeLiteral();\n        if (!canBeInjected(type)) {\n            return;\n        }\n        addInjectionPointDependencies(InjectionPoint.forConstructorOf(type),\n                keysObserved, keysNeeded);\n        Set<InjectionPoint> methodsAndFieldsInjectionPoints =\n                InjectionPoint.forInstanceMethodsAndFields(type);\n        for (InjectionPoint injectionPoint : methodsAndFieldsInjectionPoints) {\n            addInjectionPointDependencies(injectionPoint, keysObserved, keysNeeded);\n        }\n    }\n\n    private void addInjectionPointDependencies(InjectionPoint injectionPoint,\n            Set<Key<?>> keysObserved, Set<Key<?>> keysNeeded) {\n        // Do not consider dependencies coming from optional injections\n        if (injectionPoint.isOptional()) {\n            return;\n        }\n        for (Dependency<?> dependency : injectionPoint.getDependencies()) {\n            Key<?> key = dependency.getKey();\n            addKeyDependency(key, keysObserved, keysNeeded);\n        }\n    }\n\n    private void addKeyDependency(Key<?> key, Set<Key<?>> keysObserved,\n            Set<Key<?>> keysNeeded) {\n        Key<?> newKey = key;\n        if (Provider.class.equals(key.getTypeLiteral().getRawType())) {\n            Type providedType = (\n                    (ParameterizedType) key.getTypeLiteral().getType()).getActualTypeArguments()[0];\n            if (key.getAnnotation() != null) {\n                newKey = Key.get(providedType, key.getAnnotation());\n            } else if (key.getAnnotationType() != null) {\n                newKey = Key.get(providedType, key.getAnnotationType());\n            } else {\n                newKey = Key.get(providedType);\n            }\n        }\n        addNeededKey(keysObserved, keysNeeded, newKey, true);\n    }\n\n    /**\n     * Override and return the {@link Writer} you want to use to report the tree of test objects,and whether they\n     * were mocked, spied, automatically instantiated, or explicitly bound. Mostly useful for\n     * debugging.\n     *\n     * @return The {@link Writer}, if {@code null} no report will be output.\n     */\n    public Writer getReportWriter() {\n        return null;\n    }\n\n    /**\n     * Outputs the report, see {@link #setReportWriter(Writer)}. Will not output anything if the\n     * {@code reportWriter} is {@code null}. Do not call directly, it will be called by\n     * {@link JukitoRunner}. To obtain a report, override {@link #getReportWriter()}.\n     */\n    public void printReport(List<BindingInfo> allBindings) {\n        Writer reportWriter = getReportWriter();\n        if (reportWriter == null) {\n            return;\n        }\n\n        try {\n            reportWriter.append(\"*** EXPLICIT BINDINGS ***\\n\");\n            Set<Key<?>> reportedKeys = outputBindings(reportWriter, bindingsObserved,\n                    Collections.<Key<?>>emptySet());\n            reportWriter.append('\\n');\n            reportWriter.append(\"*** AUTOMATIC BINDINGS ***\\n\");\n            outputBindings(reportWriter, allBindings, reportedKeys);\n            reportWriter.append('\\n');\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    /**\n     * @param reportWriter The {@link Writer} to use to output the report.\n     * @param bindings     The bindings to report.\n     * @param keysToSkip   The keys that should not be reported.\n     * @return All the keys that were reported.\n     * @throws IOException If something goes wrong when writing.\n     */\n    private Set<Key<?>> outputBindings(Writer reportWriter, List<BindingInfo> bindings,\n            Set<Key<?>> keysToSkip) throws IOException {\n\n        Set<Key<?>> reportedKeys = new HashSet<>(bindings.size());\n        for (BindingInfo bindingInfo : bindings) {\n            if (keysToSkip.contains(bindingInfo.key)) {\n                continue;\n            }\n            reportedKeys.add(bindingInfo.key);\n            reportWriter.append(\"  \");\n            reportWriter.append(bindingInfo.key.toString());\n            reportWriter.append(\" --> \");\n            if (bindingInfo.boundKey != null) {\n                if (bindingInfo.key == bindingInfo.boundKey) {\n                    reportWriter.append(\"Bound directly\");\n                } else {\n                    reportWriter.append(bindingInfo.boundKey.toString());\n                }\n            } else if (bindingInfo.boundInstance != null) {\n                reportWriter.append(\"Instance of \").append(bindingInfo.boundInstance.getClass().getCanonicalName());\n            } else {\n                reportWriter.append(\"NOTHING!?\");\n            }\n            reportWriter.append(\" ### \");\n            if (bindingInfo.scope == null) {\n                reportWriter.append(\"No scope\");\n            } else {\n                reportWriter.append(\"In scope \");\n                reportWriter.append(bindingInfo.scope);\n            }\n            reportWriter.append('\\n');\n        }\n        return reportedKeys;\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/JukitoRunner.java",
    "content": "/*\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.notification.RunNotifier;\nimport org.junit.runners.BlockJUnit4ClassRunner;\nimport org.junit.runners.model.FrameworkMethod;\nimport org.junit.runners.model.InitializationError;\nimport org.junit.runners.model.Statement;\n\nimport com.google.inject.Binding;\nimport com.google.inject.Guice;\nimport com.google.inject.Injector;\nimport com.google.inject.Key;\nimport com.google.inject.Module;\nimport com.google.inject.Scope;\nimport com.google.inject.TypeLiteral;\nimport com.google.inject.internal.Errors;\nimport com.google.inject.spi.DefaultBindingScopingVisitor;\n\n/*\n * This class implements the mockito runner but allows Guice dependency\n * injection. To setup the guice environment, the test class can have an inner\n * static class deriving from {@link TestModule}. This last class will let you bind\n * {@link TestSingleton} and {@link TestEagerSingleton} and the runner will make sure these\n * singletons are reset at every invocation of a test case.\n *\n *\n * Most of the code here is inspired from: <a href=\n * \"http://cowwoc.blogspot.com/2008/10/integrating-google-guice-into-junit4.html\"\n * > http://cowwoc.blogspot.com/2008/10/integrating-google-guice-into-junit4.\n * html</a>\n *\n * Depends on Mockito.\n */\npublic class JukitoRunner extends BlockJUnit4ClassRunner {\n\n    private Injector injector;\n\n    public JukitoRunner(Class<?> klass) throws InitializationError,\n            InvocationTargetException, InstantiationException, IllegalAccessException {\n        super(klass);\n        ensureInjector();\n    }\n\n    public JukitoRunner(Class<?> klass, Injector injector) throws InitializationError,\n            InvocationTargetException, InstantiationException, IllegalAccessException {\n        // refactor needed here cos ensureInjector is run without reason here.\n        super(klass);\n        this.injector = injector;\n    }\n\n    /**\n     * Creates an injector from a test module.\n     * Override this to use something like Netflix Governator.\n     *\n     * @param testModule the test module\n     * @return a newly created injector\n     */\n    protected Injector createInjector(TestModule testModule) {\n        return Guice.createInjector(testModule);\n    }\n\n    private void ensureInjector()\n            throws InstantiationException, IllegalAccessException {\n        if (injector != null) {\n            return;\n        }\n        Class<?> testClass = getTestClass().getJavaClass();\n        TestModule testModule = getTestModule(testClass);\n        testModule.setTestClass(testClass);\n\n        JukitoModule jukitoModule = null; // Only non-null if it's a JukitoModule\n        if (testModule instanceof JukitoModule) {\n            jukitoModule = (JukitoModule) testModule;\n\n            // Create a module just for the purpose of collecting bindings\n            TestModule testModuleForCollection = getTestModule(testClass);\n            BindingsCollector collector = new BindingsCollector(testModuleForCollection);\n            collector.collectBindings();\n            jukitoModule.setBindingsObserved(collector.getBindingsObserved());\n        }\n        injector = this.createInjector(testModule);\n        if (jukitoModule != null && jukitoModule.getReportWriter() != null) {\n            // An output report is desired\n            BindingsCollector collector = new BindingsCollector(jukitoModule);\n            collector.collectBindings();\n            jukitoModule.printReport(collector.getBindingsObserved());\n        }\n    }\n\n    private TestModule getTestModule(Class<?> testClass) throws InstantiationException, IllegalAccessException {\n        Set<Class<? extends Module>> useModuleClasses = getUseModuleClasses(testClass);\n        boolean autoBindMocks = getAutoBindMocksValue(testClass);\n        if (!useModuleClasses.isEmpty()) {\n            return createJukitoModule(useModuleClasses, autoBindMocks);\n        }\n\n        TestModule testModule = getInnerClassModule(testClass);\n        if (testModule != null) {\n            return testModule;\n        }\n\n        if (autoBindMocks) {\n            return new JukitoModule() {\n                @Override\n                protected void configureTest() {\n                }\n            };\n        } else {\n            return new TestModule() {\n                @Override\n                protected void configureTest() {\n                }\n            };\n        }\n    }\n\n    /**\n     * Gets Guice modules registered with {@link UseModules} from test class and all super classes.\n     *\n     * @param testClass the test class running\n     * @return set of Guice modules\n     */\n    private Set<Class<? extends Module>> getUseModuleClasses(Class<?> testClass) {\n        Class<?> currentClass = testClass;\n        Set<Class<? extends Module>> modules = new HashSet<>();\n        while (currentClass != null) {\n            UseModules useModules = currentClass.getAnnotation(UseModules.class);\n            if (useModules != null) {\n                Collections.addAll(modules, useModules.value());\n            }\n            currentClass = currentClass.getSuperclass();\n        }\n        return modules;\n    }\n\n    private TestModule getInnerClassModule(Class<?> testClass)\n            throws InstantiationException, IllegalAccessException {\n        Class<?> currentClass = testClass;\n        while (currentClass != null) {\n            for (Class<?> innerClass : currentClass.getDeclaredClasses()) {\n                if (TestModule.class.isAssignableFrom(innerClass)) {\n                    return (TestModule) innerClass.newInstance();\n                }\n            }\n            currentClass = currentClass.getSuperclass();\n        }\n        return null;\n    }\n\n    private boolean getAutoBindMocksValue(Class<?> testClass) {\n        boolean autoBindMocks = true;\n        Class<?> currentClass = testClass;\n        while (currentClass != null) {\n            UseModules useModules = currentClass.getAnnotation(UseModules.class);\n            if (useModules != null) {\n                autoBindMocks = useModules.autoBindMocks();\n                break;\n            }\n            currentClass = currentClass.getSuperclass();\n        }\n        return autoBindMocks;\n    }\n\n    private TestModule createJukitoModule(final Iterable<Class<? extends Module>> moduleClasses,\n            boolean autoBindMocks) {\n        if (autoBindMocks) {\n            return new JukitoModule() {\n                @Override\n                protected void configureTest() {\n                    for (Class<? extends Module> mClass : moduleClasses) {\n                        try {\n                            install(mClass.newInstance());\n                        } catch (Exception e) {\n                            throw new RuntimeException(e);\n                        }\n                    }\n                }\n            };\n        } else {\n            return new TestModule() {\n                @Override\n                protected void configureTest() {\n                    for (Class<? extends Module> mClass : moduleClasses) {\n                        try {\n                            install(mClass.newInstance());\n                        } catch (Exception e) {\n                            throw new RuntimeException(e);\n                        }\n                    }\n                }\n            };\n        }\n    }\n\n    @Override\n    public void run(RunNotifier notifier) {\n        // add listener that validates framework usage at the end of each test\n        notifier.addListener(new MockitoUsageValidator(notifier));\n        super.run(notifier);\n    }\n\n    @Override\n    protected Object createTest() throws Exception {\n        TestScope.clear();\n        instantiateEagerTestSingletons();\n        return injector.getInstance(getTestClass().getJavaClass());\n    }\n\n    @Override\n    protected Statement methodInvoker(FrameworkMethod method, Object test) {\n        return new InjectedStatement(method, test, injector);\n    }\n\n    @Override\n    protected Statement withBefores(FrameworkMethod method, Object target,\n            Statement statement) {\n        try {\n            ensureInjector();\n        } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n        List<FrameworkMethod> befores = getTestClass().getAnnotatedMethods(\n                Before.class);\n        return befores.isEmpty() ? statement : new InjectedBeforeStatements(statement,\n                befores, target, injector);\n    }\n\n    @Override\n    protected Statement withAfters(FrameworkMethod method, Object target,\n            Statement statement) {\n        try {\n            ensureInjector();\n        } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n        List<FrameworkMethod> afters = getTestClass().getAnnotatedMethods(\n                After.class);\n        return afters.isEmpty() ? statement : new InjectedAfterStatements(statement,\n                afters, target, injector);\n    }\n\n    @Override\n    protected List<FrameworkMethod> computeTestMethods() {\n        try {\n            ensureInjector();\n        } catch (Exception e) {\n            throw new RuntimeException(e);\n        }\n        List<FrameworkMethod> testMethods = getTestClass().getAnnotatedMethods(Test.class);\n        List<FrameworkMethod> result = new ArrayList<>(testMethods.size());\n        for (FrameworkMethod method : testMethods) {\n            Method javaMethod = method.getMethod();\n            Errors errors = new Errors(javaMethod);\n            List<Key<?>> keys = GuiceUtils.getMethodKeys(javaMethod, errors);\n            errors.throwConfigurationExceptionIfErrorsExist();\n\n            List<List<Binding<?>>> bindingsToUseForParameters = new ArrayList<>();\n            for (Key<?> key : keys) {\n                if (All.class.equals(key.getAnnotationType())) {\n                    All allAnnotation = (All) key.getAnnotation();\n                    TypeLiteral<?> typeLiteral = key.getTypeLiteral();\n                    List<Binding<?>> bindings = getBindingsForParameterWithAllAnnotation(allAnnotation, typeLiteral);\n                    bindingsToUseForParameters.add(bindings);\n                }\n            }\n            // Add an injected method for every combination of binding\n            addAllBindingAssignations(bindingsToUseForParameters, 0,\n                    new ArrayList<Binding<?>>(bindingsToUseForParameters.size()),\n                    javaMethod, result);\n        }\n        return result;\n    }\n\n    @Override\n    protected String testName(FrameworkMethod method) {\n        org.jukito.Description annotation = method.getMethod().getAnnotation(org.jukito.Description.class);\n        if (annotation != null) {\n            return annotation.value();\n        } else {\n            return super.testName(method);\n        }\n    }\n\n    /**\n     * Computes a list of all bindings which match a {@link All} annotation.\n     *\n     * @param allAnnotation the annotation to match\n     * @param typeLiteral   the type of the bindings.\n     * @return the computed list.\n     */\n    private List<Binding<?>> getBindingsForParameterWithAllAnnotation(All allAnnotation, TypeLiteral<?> typeLiteral) {\n        List<Binding<?>> result = new ArrayList<>();\n        String bindingName = allAnnotation.value();\n        if (All.DEFAULT.equals(bindingName)) {\n            // If the annotation is with the default name bind all bindings\n            result.addAll(injector.findBindingsByType(typeLiteral));\n        } else {\n            // Else bind only those bindings which have a key with the same name\n            for (Binding<?> binding : injector.findBindingsByType(typeLiteral)) {\n                if (NamedUniqueAnnotations.matches(bindingName, binding.getKey().getAnnotation())) {\n                    result.add(binding);\n                }\n            }\n        }\n        return result;\n    }\n\n    /**\n     * This method looks at all possible way to assign the bindings in\n     * {@code bindingsToUseForParameters}, starting at index {@code index}.\n     * If {@code index} is larger than the number of elements in {@code bindingsToUseForParameters}\n     * then the {@code currentAssignation} with {@javaMethod} is added to {@code result}.\n     *\n     * @param result\n     * @param javaMethod\n     * @param bindingsToUseForParameters\n     * @param index\n     * @param currentAssignation\n     */\n    private void addAllBindingAssignations(\n            List<List<Binding<?>>> bindingsToUseForParameters, int index,\n            List<Binding<?>> currentAssignation,\n            Method javaMethod, List<FrameworkMethod> result) {\n\n        if (index >= bindingsToUseForParameters.size()) {\n            List<Binding<?>> assignation = new ArrayList<>(currentAssignation.size());\n            assignation.addAll(currentAssignation);\n            result.add(new InjectedFrameworkMethod(javaMethod, assignation));\n            return;\n        }\n\n        for (Binding<?> binding : bindingsToUseForParameters.get(index)) {\n            if (binding.getKey().getAnnotation() == null) {\n                // As TestModule.bindMany() annotates the bindings, the un-annotated bindings are typically unwanted\n                // mocks automatically bound by Jukito.\n                continue;\n            }\n\n            currentAssignation.add(binding);\n            if (currentAssignation.size() != index + 1) {\n                throw new AssertionError(\"Size of currentAssignation list is wrong.\");\n            }\n            addAllBindingAssignations(bindingsToUseForParameters, index + 1,\n                    currentAssignation,\n                    javaMethod, result);\n            currentAssignation.remove(index);\n        }\n    }\n\n    private void instantiateEagerTestSingletons() {\n        DefaultBindingScopingVisitor<Boolean> isEagerTestScopeSingleton =\n                new DefaultBindingScopingVisitor<Boolean>() {\n                    public Boolean visitScope(Scope scope) {\n                        return scope == TestScope.EAGER_SINGLETON;\n                    }\n                };\n        for (Binding<?> binding : injector.getBindings().values()) {\n            boolean instantiate = false;\n            if (binding != null) {\n                Boolean result = binding.acceptScopingVisitor(isEagerTestScopeSingleton);\n                if (result != null && result) {\n                    instantiate = true;\n                }\n            }\n            if (instantiate) {\n                binding.getProvider().get();\n            }\n        }\n    }\n\n    /**\n     * Adds to {@code errors} for each method annotated with {@code @Test},\n     * {@code @Before}, or {@code @After} that is not a public, void instance\n     * method with no arguments.\n     */\n    @Override\n    protected void validateInstanceMethods(List<Throwable> errors) {\n        validatePublicVoidMethods(After.class, false, errors);\n        validatePublicVoidMethods(Before.class, false, errors);\n        validateTestMethods(errors);\n\n        if (computeTestMethods().size() == 0) {\n            errors.add(new Exception(\"No runnable methods\"));\n        }\n    }\n\n    /**\n     * Adds to {@code errors} for each method annotated with {@code @Test}that\n     * is not a public, void instance method with no arguments.\n     */\n    @Override\n    protected void validateTestMethods(List<Throwable> errors) {\n        validatePublicVoidMethods(Test.class, false, errors);\n    }\n\n    /**\n     * Adds to {@code errors} if any method in this class is annotated with\n     * the provided {@code annotation}, but:\n     * <ul>\n     * <li>is not public, or\n     * <li>returns something other than void, or\n     * <li>is static (given {@code isStatic is false}), or\n     * <li>is not static (given {@code isStatic is true}).\n     */\n    private void validatePublicVoidMethods(Class<? extends Annotation> annotation,\n            boolean isStatic, List<Throwable> errors) {\n        List<FrameworkMethod> methods = getTestClass().getAnnotatedMethods(annotation);\n\n        for (FrameworkMethod eachTestMethod : methods) {\n            eachTestMethod.validatePublicVoid(isStatic, errors);\n        }\n    }\n\n    /**\n     * Access the Guice injector.\n     *\n     * @return The Guice {@link Injector}.\n     */\n    protected Injector getInjector() {\n        return injector;\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/MockProvider.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport com.google.inject.Provider;\n\nimport static org.mockito.Mockito.mock;\n\n/**\n * For use in test cases where an {@link Provider} is required to provide an\n * object and the test case needs to provide a mock of the object.\n * <p/>\n * A new object is returned each the the provider is invoked, unless the object\n * is bound as a {@link TestScope#SINGLETON} or {@link TestScope#EAGER_SINGLETON}.\n * <p/>\n * Depends on Mockito.\n *\n * @param <T> The class to provide.\n */\npublic class MockProvider<T> implements Provider<T> {\n\n    private final Class<T> classToProvide;\n\n    /**\n     * Construct a {@link Provider} that will return mocked objects of the specified types.\n     *\n     * @param classToProvide The {@link Class} of the mock object to provide.\n     */\n    public MockProvider(Class<T> classToProvide) {\n        this.classToProvide = classToProvide;\n    }\n\n    @Override\n    public T get() {\n        return mock(classToProvide);\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/MockitoUsageValidator.java",
    "content": "/*\n * Copyright 2017 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.runner.notification.Failure;\nimport org.junit.runner.notification.RunListener;\nimport org.junit.runner.notification.RunNotifier;\nimport org.mockito.Mockito;\n\npublic class MockitoUsageValidator extends RunListener {\n    private final RunNotifier notifier;\n\n    public MockitoUsageValidator(RunNotifier notifier) {\n        this.notifier = notifier;\n    }\n\n    @Override\n    public void testFinished(org.junit.runner.Description description) throws Exception {\n        super.testFinished(description);\n\n        try {\n            Mockito.validateMockitoUsage();\n        } catch (Throwable t) {\n            notifier.fireTestFailure(new Failure(description, t));\n        }\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/NamedUniqueAnnotations.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.annotation.Retention;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport com.google.inject.BindingAnnotation;\n\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\n/**\n * Factory for unique annotations with a name. Based on {@link com.google.inject.internal.UniqueAnnotations}.\n */\nclass NamedUniqueAnnotations {\n    private static final AtomicInteger nextUniqueValue = new AtomicInteger(1);\n\n    /**\n     * Returns if a NamedUniqueAnnotations matches a binding name.\n     *\n     * @param bindingName the name to match.\n     * @param annotation  the annotation to match the name to.\n     * @return if the annotation matches the bindingName.\n     */\n    public static boolean matches(String bindingName, java.lang.annotation.Annotation annotation) {\n        if (annotation instanceof Internal) {\n            return ((Internal) annotation).name().equals(bindingName);\n        }\n        return false;\n    }\n\n    /**\n     * Returns an annotation instance that is not equal to any other annotation\n     * instances, for use in creating distinct {@link com.google.inject.Key}s.\n     *\n     * @param name name to group multiple annotations. Each annotation is still unique even if it belongs to a group.\n     */\n    public static Annotation create(String name) {\n        int unique = nextUniqueValue.getAndIncrement();\n        String nonNullName = name == null ? All.DEFAULT : name;\n        return new InternalImpl(unique, nonNullName);\n    }\n\n    @Retention(RUNTIME)\n    @BindingAnnotation\n    private @interface Internal {\n        String name();\n\n        int value();\n    }\n\n    private static class InternalImpl implements Internal {\n        private final int value;\n        private final String name;\n\n        InternalImpl(int value, String name) {\n            this.value = value;\n            this.name = name;\n        }\n\n        public int value() {\n            return value;\n        }\n\n        public String name() {\n            return name;\n        }\n\n        public Class<? extends Annotation> annotationType() {\n            return Internal.class;\n        }\n\n        @Override\n        public String toString() {\n            return \"@\" + Internal.class.getName() + \"(name=\" + name + \", value=\" + value + \")\";\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) {\n                return true;\n            }\n            if (o instanceof Internal) {\n                Internal other = (Internal) o;\n                return value() == other.value() && name().equals(other.name());\n            }\n            return false;\n        }\n\n        @Override\n        public int hashCode() {\n            return (127 * name.hashCode()) ^ value;\n        }\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/SpyImmutableInstanceProvider.java",
    "content": "/**\n * Copyright 2014 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.mockito.Mockito;\n\nimport com.google.inject.Provider;\n\n/**\n * For use in classes where you want to create a spied instance, as in\n * {@link com.google.inject.binder.LinkedBindingBuilder#toInstance(T))},\n * except the instance is a spy.\n * <p/>\n * A new spy is returned each time this {@link Provider} is invoked, wrapping the\n * exact same instance class.\n * <p/>\n * <b>Important:</b> Spied object needs to be Immutable\n */\nclass SpyImmutableInstanceProvider<T> implements Provider<T> {\n    private final T instance;\n\n    /**\n     * Create a new {@link Provider} instance for use in creating spies of\n     * concrete instances.\n     * <p/>\n     * This instance should be immutable; if it is not, you risk polluting your tests as the underlying instance is the\n     * same (even though it uses a different spy wrapper).\n     *\n     * @param instance The instance to be returned.\n     */\n    SpyImmutableInstanceProvider(T instance) {\n        this.instance = instance;\n    }\n\n    /**\n     * Create a new spy of your bound instance.\n     */\n    @Override\n    public T get() {\n        return Mockito.spy(instance);\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/SpyProvider.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.util.Collections;\nimport java.util.Set;\n\nimport com.google.inject.Key;\nimport com.google.inject.Provider;\nimport com.google.inject.spi.Dependency;\nimport com.google.inject.spi.HasDependencies;\n\nimport static org.mockito.Mockito.spy;\n\n/**\n * For use in test cases where an {@link Provider} is required to provide an\n * object and the test case needs to provide a spy of the object.\n * <p/>\n * A new object is returned each the the provider is invoked, unless the object\n * is bound as a {@link TestScope#SINGLETON} or {@link TestScope#EAGER_SINGLETON}.\n * <p/>\n * Depends on Mockito.\n *\n * @param <T> The class to provide.\n */\nclass SpyProvider<T> implements Provider<T>, HasDependencies {\n\n    private final Provider<T> rawProvider;\n    private final Set<Dependency<?>> dependencies;\n\n    /**\n     * Construct a {@link Provider} that will return spied instances of objects\n     * of the specified types. You should not call this directly, instead use\n     * {@link TestModule#bindSpy(Class)} or {@link TestModule#bindSpy(com.google.inject.TypeLiteral)}.\n     *\n     * @param rawProvider The test class, running with {@link JukitoRunner}.\n     * @param relayingKey The key of the binding used to relay to the real class. This should usually be the key of a\n     *                    {code toConstructor} binding. Internally, Jukito uses the {@link JukitoInternal} annotation to\n     *                    distinguish this binding.\n     */\n    SpyProvider(Provider<T> rawProvider, Key<T> relayingKey) {\n        this.rawProvider = rawProvider;\n        dependencies = Collections.<Dependency<?>>singleton(Dependency.get(relayingKey));\n    }\n\n    @Override\n    public T get() {\n        return spy(rawProvider.get());\n    }\n\n    @Override\n    public Set<Dependency<?>> getDependencies() {\n        return dependencies;\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/TestEagerSingleton.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport com.google.inject.ScopeAnnotation;\n\n/**\n * This annotation can be used on any classes that should be bound\n * within the {@link TestScope#EAGER_SINGLETON} scope. It is meant to be\n * used on inner static classes of the test class or its parents\n * and shouldn't be used on top-level classes.\n */\n@ScopeAnnotation\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.TYPE, ElementType.METHOD})\npublic @interface TestEagerSingleton {\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/TestMockSingleton.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * This annotation can be used on any classes that should be bound as\n * a mock within the {@link TestScope#SINGLETON} scope. It is meant to be\n * used on inner static classes of the test class or its parents\n * and shouldn't be used on top-level classes.\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.TYPE)\npublic @interface TestMockSingleton {\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/TestModule.java",
    "content": "/**\n * Copyright 2014 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.reflect.Constructor;\n\nimport com.google.inject.AbstractModule;\nimport com.google.inject.Key;\nimport com.google.inject.TypeLiteral;\nimport com.google.inject.binder.LinkedBindingBuilder;\nimport com.google.inject.binder.ScopedBindingBuilder;\nimport com.google.inject.name.Names;\nimport com.google.inject.spi.InjectionPoint;\n\n/**\n * A guice {@link com.google.inject.Module Module} with a bit of syntactic sugar to bind within\n * typical test scopes. Depends on mockito.\n * <p/>\n * Depends on Mockito.\n */\npublic abstract class TestModule extends AbstractModule {\n\n    protected Class<?> testClass;\n\n    /**\n     * Attach the {@link TestModule} to a given test class.\n     *\n     * @param testClass The test class to attach to this {@link TestModule}.\n     */\n    public void setTestClass(Class<?> testClass) {\n        this.testClass = testClass;\n    }\n\n    @Override\n    public void configure() {\n        bindScopes();\n        configureTest();\n    }\n\n    protected void bindScopes() {\n        bindScope(TestSingleton.class, TestScope.SINGLETON);\n        bindScope(TestEagerSingleton.class, TestScope.EAGER_SINGLETON);\n    }\n\n    /**\n     * Configures a test {@link com.google.inject.Module Module} via the exposed methods.\n     */\n    protected abstract void configureTest();\n\n    /**\n     * Binds an interface to a mocked version of itself. You will usually want to bind this in the\n     * {@link TestSingleton} scope.\n     *\n     * @param <T>   The type of the interface to bind\n     * @param klass The class to bind\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindMock(Class<T> klass) {\n        return bindNewMockProvider(Key.get(klass));\n    }\n\n    /**\n     * Binds an interface annotated with a {@link com.google.inject.name.Named @Named} to a\n     * mocked version of itself. You will usually want to bind this in the\n     * {@link TestSingleton} scope.\n     *\n     * @param <T>         The type of the interface to bind, a parameterized type\n     * @param typeLiteral The {@link TypeLiteral} corresponding to the parameterized type to bind.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindMock(\n            TypeLiteral<T> typeLiteral) {\n        return bindNewMockProvider(Key.get(typeLiteral));\n    }\n\n    /**\n     * Binds a concrete object type so that spies of instances are returned\n     * instead of instances themselves. You will usually want to bind this in the\n     * {@link TestSingleton} scope.\n     *\n     * @param <T>   The type of the interface to bind\n     * @param klass The class to bind\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindSpy(Class<T> klass) {\n        return bindNewSpyProvider(Key.get(klass));\n    }\n\n    /**\n     * Binds a concrete object type so that spies of instances are returned\n     * instead of instances themselves. You will usually want to bind this in the\n     * {@link TestSingleton} scope.\n     *\n     * @param <T>         The type of the interface to bind, a parameterized type\n     * @param typeLiteral The {@link TypeLiteral} corresponding to the parameterized type to bind.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindSpy(\n            TypeLiteral<T> typeLiteral) {\n        return bindNewSpyProvider(Key.get(typeLiteral));\n    }\n\n    /**\n     * Binds a concrete instance so that spies of this instance are returned\n     * instead of the object itself. Each spy is an independent spy but the\n     * underlying instance will be the same, so if the object is mutable,\n     * your tests can be polluted!\n     * <p/>\n     * You will usually want to bind this in the {@link TestSingleton} scope.\n     *\n     * @param <T>      The type of the interface to bind\n     * @param klass    The class to bind\n     * @param instance The instance to bind this class to.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindSpy(Class<T> klass, T instance) {\n        return bindNewSpyImmutableInstanceProvider(Key.get(klass), instance);\n    }\n\n    /**\n     * Binds a concrete instance so that spies of this instance are returned\n     * instead of the object itself. Each spy is an independent spy but the\n     * underlying instance will be the same, so if the object is mutable,\n     * your tests can be polluted!\n     * <p/>\n     * You will usually want to bind this in the\n     * {@link TestSingleton} scope.\n     *\n     * @param <T>         The type of the interface to bind, a parameterized type\n     * @param typeLiteral The {@link TypeLiteral} corresponding to the parameterized type to bind.\n     * @param instance    The instance to bind this class to.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindSpy(\n            TypeLiteral<T> typeLiteral, T instance) {\n        return bindNewSpyImmutableInstanceProvider(Key.get(typeLiteral), instance);\n    }\n\n    /**\n     * Binds an interface annotated with a {@link com.google.inject.name.Named @Named} to a\n     * mocked version of itself. You will usually want to bind this in the\n     * {@link TestSingleton} scope.\n     *\n     * @param <T>   The type of the interface to bind\n     * @param klass The class to bind\n     * @param name  The name used with the {@link com.google.inject.name.Named @Named} annotation.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindNamedMock(Class<T> klass, String name) {\n        return bindNewMockProvider(Key.get(klass, Names.named(name)));\n    }\n\n    /**\n     * Binds an interface annotated with a {@link com.google.inject.name.Named @Named} to a\n     * mocked version of itself. You will usually want to bind this in the\n     * {@link TestSingleton} scope.\n     *\n     * @param <T>         The type of the interface to bind\n     * @param typeLiteral The {@link TypeLiteral} corresponding to the parameterized type to bind.\n     * @param name        The name used with the {@link com.google.inject.name.Named @Named} annotation.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindNamedMock(TypeLiteral<T> typeLiteral,\n            String name) {\n        return bindNewMockProvider(Key.get(typeLiteral, Names.named(name)));\n    }\n\n    /**\n     * Binds a concrete object type annotated with a\n     * {@link com.google.inject.name.Named @Named} so that spies of instances are returned\n     * instead of instances themselves. You will usually want to bind this in the\n     * {@link TestSingleton} scope.\n     *\n     * @param <T>   The type of the interface to bind\n     * @param klass The class to bind\n     * @param name  The name used with the {@link com.google.inject.name.Named @Named} annotation.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindNamedSpy(Class<T> klass, String name) {\n        return bindNewSpyProvider(Key.get(klass, Names.named(name)));\n    }\n\n    /**\n     * Binds  a concrete object type annotated with a\n     * {@link com.google.inject.name.Named @Named} so that spies of instances are returned\n     * instead of instances themselves. You will usually want to bind this in the\n     * {@link TestSingleton} scope.\n     *\n     * @param <T>         The type of the interface to bind\n     * @param typeLiteral The {@link TypeLiteral} corresponding to the parameterized type to bind.\n     * @param name        The name used with the {@link com.google.inject.name.Named @Named} annotation.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindNamedSpy(TypeLiteral<T> typeLiteral,\n            String name) {\n        return bindNewSpyProvider(Key.get(typeLiteral, Names.named(name)));\n    }\n\n    /**\n     * Binds a concrete instance annotated with {@link com.google.inject.name.Named @Named} so that spies of this\n     * instance are returned instead of the object itself. Each spy is an independent spy but the underlying instance\n     * will be the same, so if the object is mutable, your tests can be polluted!\n     * <p/>\n     * You will usually want to bind this in the {@link TestSingleton} scope.\n     *\n     * @param <T>      The type of the interface to bind\n     * @param klass    The class to bind\n     * @param instance The instance to bind this class to.\n     * @param name     The name used with the {@link com.google.inject.name.Named @Named} annotation.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindNamedSpy(Class<T> klass, T instance,\n            String name) {\n        return bindNewSpyImmutableInstanceProvider(Key.get(klass, Names.named(name)), instance);\n    }\n\n    /**\n     * Binds a concrete instance annotated with {@link com.google.inject.name.Named @Named} so that spies of this\n     * instance are returned instead of the object itself. Each spy is an independent spy but the underlying instance\n     * will be the same, so if the object is mutable, your tests can be polluted!\n     * <p/>\n     * You will usually want to bind this in the {@link TestSingleton} scope.\n     *\n     * @param <T>         The type of the interface to bind\n     * @param typeLiteral The {@link TypeLiteral} corresponding to the parameterized type to bind.\n     * @param instance    The instance to bind this class to.\n     * @param name        The name used with the {@link com.google.inject.name.Named @Named} annotation.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> ScopedBindingBuilder bindNamedSpy(TypeLiteral<T> typeLiteral,\n            T instance, String name) {\n        return bindNewSpyImmutableInstanceProvider(Key.get(typeLiteral, Names.named(name)), instance);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private <T> ScopedBindingBuilder bindNewMockProvider(Key<T> key) {\n        return bind(key).toProvider(\n                new MockProvider<T>((Class<T>) key.getTypeLiteral().getRawType()));\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private <T> ScopedBindingBuilder bindNewSpyProvider(Key<T> key) {\n        TypeLiteral<T> type = key.getTypeLiteral();\n        InjectionPoint constructorInjectionPoint = InjectionPoint.forConstructorOf(type);\n        Key<T> relayingKey = Key.get(type, JukitoInternal.class);\n        bind(relayingKey).toConstructor((Constructor<T>) constructorInjectionPoint.getMember());\n        return bind(key).toProvider(new SpyProvider<T>(getProvider(relayingKey), relayingKey));\n    }\n\n    private <T> ScopedBindingBuilder bindNewSpyImmutableInstanceProvider(Key<T> key, T instance) {\n        return bind(key).toProvider(new SpyImmutableInstanceProvider<T>(instance));\n    }\n\n    /**\n     * This method binds many different instances to the same class or interface. Use this only\n     * if the instances are totally stateless. That is, they are immutable and have\n     * no mutable dependencies (e.g. a {@link String} or a simple POJO). For more\n     * complex classes use {@link #bindMany}.\n     * <p/>\n     * The specified {@link Class} will be bound to all the different instances, each\n     * binding using a different unique annotation.\n     * <p/>\n     * This method is useful when combined with the {@literal @}{@link All} annotation.\n     *\n     * @param clazz     The {@link Class} to which the instances will be bound.\n     * @param instances All the instances to bind.\n     * @see {@link All}\n     */\n    protected <T, V extends T> void bindManyInstances(Class<T> clazz, V... instances) {\n        bindManyNamedInstances(clazz, All.DEFAULT, instances);\n    }\n\n    /**\n     * This method binds many different instances to the same class or interface. Use this only\n     * if the instances are totally stateless. That is, they are immutable and have\n     * no mutable dependencies (e.g. a {@link String} or a simple POJO). For more\n     * complex classes use {@link #bindMany}.\n     * <p/>\n     * The specified {@link Class} will be bound to all the different instances, each\n     * binding using a different unique but named annotation.\n     * <p/>\n     * This method is useful when combined with the {@literal @}{@link All} annotation with\n     * a name parameter.\n     *\n     * @param clazz     The {@link Class} to which the instances will be bound.\n     * @param name      The name to which to bind the instances.\n     * @param instances All the instances to bind.\n     * @see {@link All}\n     */\n    protected <T, V extends T> void bindManyNamedInstances(Class<T> clazz, String name, V... instances) {\n        for (V instance : instances) {\n            bind(clazz).annotatedWith(NamedUniqueAnnotations.create(name)).toInstance(instance);\n        }\n    }\n\n    /**\n     * This method binds many different instances to the same type literal. Use this only\n     * if the instances are totally stateless. That is, they are immutable and have\n     * no mutable dependencies (e.g. a {@link String} or a simple POJO). For more\n     * complex classes use {@link #bindMany}.\n     * <p/>\n     * The specified {@link TypeLiteral} will be bound to all the different instances, each\n     * binding using a different unique annotation.\n     * <p/>\n     * This method is useful when combined with the {@literal @}{@link All} annotation.\n     *\n     * @param type      The {@link TypeLiteral} to which the instances will be bound.\n     * @param instances All the instances to bind.\n     * @see {@link All}\n     */\n    protected <T, V extends T> void bindManyInstances(TypeLiteral<T> type, V... instances) {\n        bindManyNamedInstances(type, All.DEFAULT, instances);\n    }\n\n    /**\n     * This method binds many different instances to the same class or interface. Use this only\n     * if the instances are totally stateless. That is, they are immutable and have\n     * no mutable dependencies (e.g. a {@link String} or a simple POJO). For more\n     * complex classes use {@link #bindMany}.\n     * <p/>\n     * The specified {@link Class} will be bound to all the different instances, each\n     * binding using a different unique but named annotation.\n     * <p/>\n     * This method is useful when combined with the {@literal @}{@link All} annotation with\n     * a name.\n     *\n     * @param type      The {@link Class} to which the instances will be bound.\n     * @param name      The name to which to bind the instances.\n     * @param instances All the instances to bind.\n     * @see {@link All}\n     */\n    protected <T, V extends T> void bindManyNamedInstances(TypeLiteral<T> type, String name, V... instances) {\n        for (V instance : instances) {\n            bind(type).annotatedWith(NamedUniqueAnnotations.create(name)).toInstance(instance);\n        }\n    }\n\n    /**\n     * This method binds many different classes to the same interface. All the\n     * classes will be bound within the {@link TestScope#SINGLETON} scope.\n     * <p/>\n     * This method is useful when combined with the {@literal @}{@link All} annotation.\n     *\n     * @param clazz        The {@link Class} to which the instances will be bound.\n     * @param boundClasses All the classes to bind.\n     * @see {@link All}\n     */\n    protected <T> void bindMany(Class<T> clazz, Class<? extends T>... boundClasses) {\n        bindManyNamed(clazz, All.DEFAULT, boundClasses);\n    }\n\n    /**\n     * This method binds many different type literals to the same type literal. All the\n     * classes will be bound within the {@link TestScope#SINGLETON} scope.\n     * <p/>\n     * This method is useful when combined with the {@literal @}{@link All} annotation with\n     * a name.\n     *\n     * @param clazz        The {@link Class} to which the instances will be bound.\n     * @param name         The name to which to bind the instances.\n     * @param boundClasses All the types to bind.\n     * @see {@link All}\n     */\n    protected <T> void bindManyNamed(Class<T> clazz, String name, Class<? extends T>... boundClasses) {\n        for (Class<? extends T> boundClass : boundClasses) {\n            bind(clazz).annotatedWith(NamedUniqueAnnotations.create(name)).to(boundClass).in(TestScope.SINGLETON);\n        }\n    }\n\n    /**\n     * This method binds many different type literals to the same type literal. All the\n     * classes will be bound within the {@link TestScope#SINGLETON} scope.\n     * <p/>\n     * This method is useful when combined with the {@literal @}{@link All} annotation.\n     *\n     * @param type       The {@link Class} to which the instances will be bound.\n     * @param boundTypes All the types to bind.\n     * @see {@link All}\n     */\n    protected <T> void bindMany(TypeLiteral<T> type, TypeLiteral<? extends T>... boundTypes) {\n        bindManyNamed(type, All.DEFAULT, boundTypes);\n    }\n\n    /**\n     * This method binds many different type literals to the same type literal. All the\n     * classes will be bound within the {@link TestScope#SINGLETON} scope.\n     * <p/>\n     * This method is useful when combined with the {@literal @}{@link All} annotation with\n     * a name.\n     *\n     * @param type       The {@link Class} to which the instances will be bound.\n     * @param name       The name to which to bind the instances.\n     * @param boundTypes All the types to bind.\n     * @see {@link All}\n     */\n    protected <T> void bindManyNamed(TypeLiteral<T> type, String name,\n            TypeLiteral<? extends T>... boundTypes) {\n        for (TypeLiteral<? extends T> boundType : boundTypes) {\n            bind(type).annotatedWith(NamedUniqueAnnotations.create(name)).to(boundType).in(TestScope.SINGLETON);\n        }\n    }\n\n    /**\n     * Binds an interface annotated with a {@link com.google.inject.name.Named @Named}.\n     *\n     * @param <T>   The type of the interface to bind\n     * @param klass The class to bind\n     * @param name  The name used with the {@link com.google.inject.name.Named @Named} annotation.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> LinkedBindingBuilder<T> bindNamed(Class<T> klass, String name) {\n        return bind(klass).annotatedWith(Names.named(name));\n    }\n\n    /**\n     * Binds an interface annotated with a {@link com.google.inject.name.Named @Named}.\n     *\n     * @param <T>         The type of the interface to bind\n     * @param typeLiteral The {@link TypeLiteral} corresponding to the parameterized type to bind.\n     * @param name        The name used with the {@link com.google.inject.name.Named @Named} annotation.\n     * @return A {@link ScopedBindingBuilder}.\n     */\n    protected <T> LinkedBindingBuilder<T> bindNamed(TypeLiteral<T> typeLiteral,\n            String name) {\n        return bind(typeLiteral).annotatedWith(Names.named(name));\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/TestScope.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.google.inject.Key;\nimport com.google.inject.Provider;\nimport com.google.inject.Scope;\n\n/**\n * Container of the {@link #SINGLETON} and {@link #EAGER_SINGLETON} scopes for\n * test cases running with the {@link JukitoRunner}. Depends on mockito.\n * <p/>\n * Depends on Mockito.\n */\npublic class TestScope {\n\n    private static class Singleton implements Scope {\n        private final String simpleName;\n\n        private final Map<Key<?>, Object> backingMap = new HashMap<Key<?>, Object>();\n\n        private Singleton(String simpleName) {\n            this.simpleName = simpleName;\n        }\n\n        public void clear() {\n            backingMap.clear();\n        }\n\n        @Override\n        public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {\n            return new Provider<T>() {\n                @SuppressWarnings(\"unchecked\")\n                public T get() {\n\n                    Object o = backingMap.get(key);\n\n                    if (o == null) {\n                        o = unscoped.get();\n                        backingMap.put(key, o);\n                    }\n                    return (T) o;\n                }\n            };\n        }\n\n        public String toString() {\n            return simpleName;\n        }\n    }\n\n    /**\n     * Test-scoped singletons are typically used in test cases for objects that\n     * correspond to singletons in the application. Your JUnit test case must use\n     * {@link JukitoRunner} on its {@code @RunWith} annotation so that\n     * test-scoped singletons are reset before every test case.\n     * <p/>\n     * If you want your singleton to be instantiated automatically with each new\n     * test, use {@link #EAGER_SINGLETON}.\n     */\n    public static final Singleton SINGLETON = new Singleton(\"TestSingleton\");\n\n    /**\n     * Eager test-scoped singleton are similar to test-scoped {@link #SINGLETON}\n     * but they get instantiated automatically with each new test.\n     */\n    public static final Singleton EAGER_SINGLETON = new Singleton(\"EagerTestSingleton\");\n\n    /**\n     * Clears all the instances of test-scoped singletons. After this method is\n     * called, any \"singleton\" bound to this scope that had already been created\n     * will be created again next time it gets injected.\n     */\n    public static void clear() {\n        SINGLETON.clear();\n        EAGER_SINGLETON.clear();\n    }\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/TestSingleton.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport com.google.inject.ScopeAnnotation;\n\n/**\n * This annotation can be used on any classes that should be bound\n * within the {@link TestScope#SINGLETON} scope. It is meant to be\n * used on inner static classes ofx the test class or its parents\n * and shouldn't be used on top-level classes.\n */\n@ScopeAnnotation\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.TYPE, ElementType.METHOD})\npublic @interface TestSingleton {\n}\n"
  },
  {
    "path": "jukito/src/main/java/org/jukito/UseModules.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport com.google.inject.Module;\n\n/**\n * This annotation can be used on a test class together with\n * {@code @RunWith(JukitoRunner.class)} to use the bindings contained\n * in the specified modules for the test.\n * <p/>\n * Example:\n * <pre>\n * {@literal @}RunWith(JukitoRunner.class)\n * {@literal @}UseModules({ FooModule.class, BarModule.class}\n * public class MyTest {\n *   {@literal @}Test\n *   public void someTest(TypeBoundInFooModule a, TypeBoundInBarModule b) {\n *   }\n * }</pre>\n *\n * The example is equivalent to the following <i>inner static module</i>\n * approach.\n * <pre>\n * {@literal @}RunWith(JukitoRunner.class)\n * public class MyTest {\n *   static class Module extends JukitoModule {\n *     {@literal @}Override\n *     protected void configureTest() {\n *       install(new FooModule());\n *       install(new BarModule());\n *     }\n *   }\n *   // Test methods\n * }</pre>\n */\n@Target({ElementType.TYPE, ElementType.METHOD})\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface UseModules {\n\n    Class<? extends Module>[] value();\n\n    boolean autoBindMocks() default true;\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/AllAnnotationTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.junit.AfterClass;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mockito;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\n/**\n * Test that methods with some parameters annotated with {@literal @}{@link org.jukito.All} behave correctly.\n */\n@RunWith(JukitoRunner.class)\npublic class AllAnnotationTest {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @SuppressWarnings(\"unchecked\")\n        @Override\n        protected void configureTest() {\n            bindManyInstances(String.class, \"A\", \"B\");\n            bindManyInstances(TestDataInstance.class, new TestDataInstance(\"A\"),\n                    new TestDataInstance(\"B\"));\n            bindMany(TestData.class, TestDataA.class, TestDataB.class);\n            bindMany(Node.class, NodeA.class);\n        }\n    }\n\n    interface TestData {\n        String getData();\n    }\n\n    static class TestDataA implements TestData {\n        public String getData() {\n            return \"A\";\n        }\n    }\n\n    static class TestDataB implements TestData {\n        public String getData() {\n            return \"B\";\n        }\n    }\n\n    static class TestDataInstance {\n        private final String data;\n\n        TestDataInstance(String data) {\n            this.data = data;\n        }\n\n        public String getData() {\n            return data;\n        }\n    }\n\n    interface Node {\n    }\n\n    static class NodeA implements Node {\n    }\n\n    /**\n     * This class keeps track of what happens in all the tests run in this\n     * class. It's used to make sure all expected tests are called.\n     */\n    private static class Bookkeeper {\n        static List<String> stringsProcessed = new ArrayList<String>();\n        static List<String> dataProcessed = new ArrayList<String>();\n        static List<String> dataInstanceProcessed = new ArrayList<String>();\n    }\n\n    @Test\n    public void testAllWithInstance(@All String string1, @All String string2) {\n        Bookkeeper.stringsProcessed.add(string1 + string2);\n    }\n\n    @Test\n    public void testAllWithClass(@All TestData data1, @All TestData data2) {\n        Bookkeeper.dataProcessed.add(data1.getData() + data2.getData());\n    }\n\n    @Test\n    public void testAllWithClassInstance(@All TestDataInstance data1, @All TestDataInstance data2) {\n        Bookkeeper.dataInstanceProcessed.add(data1.getData() + data2.getData());\n    }\n\n    @AfterClass\n    public static void checkBookkeeper() {\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"AA\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"AB\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"BA\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"BB\"));\n        assertEquals(4, Bookkeeper.stringsProcessed.size());\n\n        assertTrue(Bookkeeper.dataProcessed.contains(\"AA\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"AB\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"BA\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"BB\"));\n        assertEquals(4, Bookkeeper.dataProcessed.size());\n\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"AA\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"AB\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"BA\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"BB\"));\n        assertEquals(4, Bookkeeper.dataInstanceProcessed.size());\n    }\n\n    @Test\n    public void testAllDoesNotIncludeMock(@All Node node, Node neighbour) {\n        assertFalse(Mockito.mockingDetails(node).isMock());\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/AllNamedAnnotationTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.junit.AfterClass;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\n\n/**\n * Test that methods with some parameters annotated with {@literal @}{@link All} behave correctly.\n */\n@RunWith(JukitoRunner.class)\npublic class AllNamedAnnotationTest {\n\n    public static final String FIRST = \"first\";\n    public static final String SECOND = \"second\";\n\n    static class Module extends JukitoModule {\n        @SuppressWarnings(\"unchecked\")\n        @Override\n        protected void configureTest() {\n            bindManyNamedInstances(String.class, FIRST, \"A\", \"B\");\n            bindManyNamedInstances(String.class, SECOND, \"C\", \"D\");\n            bindManyNamedInstances(TestDataInstance.class, FIRST, new TestDataInstance(\"A\"),\n                    new TestDataInstance(\"B\"));\n            bindManyNamedInstances(TestDataInstance.class, SECOND, new TestDataInstance(\"C\"),\n                    new TestDataInstance(\"D\"));\n            bindManyNamed(TestData.class, FIRST, TestDataA.class, TestDataB.class);\n            bindManyNamed(TestData.class, SECOND, TestDataC.class, TestDataD.class);\n\n            bindManyNamedInstances(Integer.class, null, 1, 2, 3, 5);\n        }\n    }\n\n    interface TestData {\n        String getData();\n    }\n\n    static class TestDataA implements TestData {\n        public String getData() {\n            return \"A\";\n        }\n    }\n\n    static class TestDataB implements TestData {\n        public String getData() {\n            return \"B\";\n        }\n    }\n\n    static class TestDataC implements TestData {\n        public String getData() {\n            return \"C\";\n        }\n    }\n\n    static class TestDataD implements TestData {\n        public String getData() {\n            return \"D\";\n        }\n    }\n\n    static class TestDataInstance {\n        private final String data;\n\n        TestDataInstance(String data) {\n            this.data = data;\n        }\n\n        public String getData() {\n            return data;\n        }\n    }\n\n    /**\n     * This class keeps track of what happens in all the tests run in this\n     * class. It's used to make sure all expected tests are called.\n     */\n    private static class Bookkeeper {\n        static List<String> namedStringsProcessed = new ArrayList<String>();\n        static List<String> namedDataProcessed = new ArrayList<String>();\n        static List<String> namedDataInstanceProcessed = new ArrayList<String>();\n\n        static List<String> stringsProcessed = new ArrayList<String>();\n        static List<String> dataProcessed = new ArrayList<String>();\n        static List<String> dataInstanceProcessed = new ArrayList<String>();\n\n        static List<Integer> integerProcessed = new ArrayList<Integer>();\n    }\n\n    @Test\n    public void testAllWithNamedInstance(@All(FIRST) String string1, @All(SECOND) String string2) {\n        Bookkeeper.namedStringsProcessed.add(string1 + string2);\n    }\n\n    @Test\n    public void testAllWithNamedClass(@All(FIRST) TestData data1, @All(SECOND) TestData data2) {\n        Bookkeeper.namedDataProcessed.add(data1.getData() + data2.getData());\n    }\n\n    @Test\n    public void testAllWithNamedClassInstance(\n            @All(FIRST) TestDataInstance data1, @All(SECOND) TestDataInstance data2) {\n        Bookkeeper.namedDataInstanceProcessed.add(data1.getData() + data2.getData());\n    }\n\n    @Test\n    public void testAllWithInstance(@All String string1, @All String string2) {\n        Bookkeeper.stringsProcessed.add(string1 + string2);\n    }\n\n    @Test\n    public void testAllWithClass(@All TestData data1, @All TestData data2) {\n        Bookkeeper.dataProcessed.add(data1.getData() + data2.getData());\n    }\n\n    @Test\n    public void testAllWithClassInstance(@All TestDataInstance data1, @All TestDataInstance data2) {\n        Bookkeeper.dataInstanceProcessed.add(data1.getData() + data2.getData());\n    }\n\n    @Test\n    public void testAllWithNullAsName(@All Integer i) {\n        Bookkeeper.integerProcessed.add(i);\n    }\n\n    @AfterClass\n    public static void checkBookkeeper() {\n        assertTrue(Bookkeeper.namedStringsProcessed.contains(\"AC\"));\n        assertTrue(Bookkeeper.namedStringsProcessed.contains(\"AD\"));\n        assertTrue(Bookkeeper.namedStringsProcessed.contains(\"BC\"));\n        assertTrue(Bookkeeper.namedStringsProcessed.contains(\"BD\"));\n        assertEquals(4, Bookkeeper.namedStringsProcessed.size());\n\n        assertTrue(Bookkeeper.namedDataProcessed.contains(\"AC\"));\n        assertTrue(Bookkeeper.namedDataProcessed.contains(\"AD\"));\n        assertTrue(Bookkeeper.namedDataProcessed.contains(\"BC\"));\n        assertTrue(Bookkeeper.namedDataProcessed.contains(\"BD\"));\n        assertEquals(4, Bookkeeper.namedDataProcessed.size());\n\n        assertTrue(Bookkeeper.namedDataInstanceProcessed.contains(\"AC\"));\n        assertTrue(Bookkeeper.namedDataInstanceProcessed.contains(\"AD\"));\n        assertTrue(Bookkeeper.namedDataInstanceProcessed.contains(\"BC\"));\n        assertTrue(Bookkeeper.namedDataInstanceProcessed.contains(\"BD\"));\n        assertEquals(4, Bookkeeper.namedDataInstanceProcessed.size());\n\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"AA\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"AB\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"AC\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"AD\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"BA\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"BB\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"BC\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"BD\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"CA\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"CB\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"CC\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"CD\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"DA\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"DB\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"DC\"));\n        assertTrue(Bookkeeper.stringsProcessed.contains(\"DD\"));\n        assertEquals(16, Bookkeeper.stringsProcessed.size());\n\n        assertTrue(Bookkeeper.dataProcessed.contains(\"AA\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"AB\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"AC\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"AD\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"BA\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"BB\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"BC\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"BD\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"CA\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"CB\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"CC\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"CD\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"DA\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"DB\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"DC\"));\n        assertTrue(Bookkeeper.dataProcessed.contains(\"DD\"));\n        assertEquals(16, Bookkeeper.dataProcessed.size());\n\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"AA\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"AB\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"AC\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"AD\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"BA\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"BB\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"BC\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"BD\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"CA\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"CB\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"CC\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"CD\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"DA\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"DB\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"DC\"));\n        assertTrue(Bookkeeper.dataInstanceProcessed.contains(\"DD\"));\n        assertEquals(16, Bookkeeper.dataInstanceProcessed.size());\n\n        assertTrue(Bookkeeper.integerProcessed.contains(1));\n        assertTrue(Bookkeeper.integerProcessed.contains(2));\n        assertTrue(Bookkeeper.integerProcessed.contains(3));\n        assertTrue(Bookkeeper.integerProcessed.contains(5));\n        assertEquals(4, Bookkeeper.integerProcessed.size());\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/AssistedInjectTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.text.SimpleDateFormat;\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.Locale;\nimport java.util.TimeZone;\n\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Inject;\nimport com.google.inject.assistedinject.Assisted;\nimport com.google.inject.assistedinject.FactoryModuleBuilder;\nimport com.google.inject.name.Named;\nimport com.google.inject.name.Names;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.when;\n\n/**\n * Tests that new Guice 3.0 assisted injection works in Jukito.\n */\n@RunWith(JukitoRunner.class)\npublic class AssistedInjectTest {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bindConstant().annotatedWith(Names.named(\"G\")).to(6.673E-11);\n            install(new FactoryModuleBuilder().implement(Payment.class, RealPayment.class)\n                    .build(PaymentFactory.class));\n            install(new FactoryModuleBuilder().implement(Star.class, StarImpl.class)\n                    .build(StarFactory.class));\n        }\n    }\n\n    interface PaymentFactory {\n        Payment create(Date startDate, int amount);\n    }\n\n    interface Payment {\n        String format();\n    }\n\n    static class RealPayment implements Payment {\n        private final Date date;\n        private final int amount;\n        private final LocaleInfo localeInfo;\n\n        @Inject\n        RealPayment(@Assisted Date date, @Assisted int amount, LocaleInfo localeInfo) {\n            this.date = date;\n            this.amount = amount;\n            this.localeInfo = localeInfo;\n        }\n\n        @Override\n        public String format() {\n            String result = \"Paid \" + Integer.toString(amount);\n            if (localeInfo.isMoneySignBefore()) {\n                result = localeInfo.getMoneySign() + result;\n            } else {\n                result += localeInfo.getMoneySign();\n            }\n            SimpleDateFormat formatter = new SimpleDateFormat(\"MM/dd/yyyy\", Locale.US);\n            formatter.setTimeZone(TimeZone.getTimeZone(\"GMT\"));\n            result += \" on \" + formatter.format(date);\n\n            return result;\n        }\n    }\n\n    interface LocaleInfo {\n        String getMoneySign();\n\n        boolean isMoneySignBefore();\n    }\n\n    interface StarFactory {\n        Star create(String name, double mass);\n    }\n\n    interface Star {\n        double getGravitationalConstant();\n\n        double getMass();\n\n        String getName();\n    }\n\n    static class StarImpl implements Star {\n        private final double gravitationalConstant;\n        private final double mass;\n        private final String name;\n\n        @Inject\n        StarImpl(@Named(\"G\") Double gravitationalConstant, @Assisted double mass,\n                @Assisted String name) {\n            this.gravitationalConstant = gravitationalConstant;\n            this.mass = mass;\n            this.name = name;\n        }\n\n        @Override\n        public double getGravitationalConstant() {\n            return gravitationalConstant;\n        }\n\n        @Override\n        public double getMass() {\n            return mass;\n        }\n\n        @Override\n        public String getName() {\n            return name;\n        }\n    }\n\n    @Inject\n    StarFactory starFactory;\n\n    @Before\n    public void setup(LocaleInfo localeInfo) {\n        when(localeInfo.getMoneySign()).thenReturn(\"$\");\n        when(localeInfo.isMoneySignBefore()).thenReturn(false);\n    }\n\n    @Test\n    public void testFactory(PaymentFactory factory) {\n        // GIVEN\n        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(\"GMT\"), Locale.US);\n        calendar.set(2011, 4, 24); // Month is 0-based\n\n        // WHEN\n        Payment payment = factory.create(calendar.getTime(), 50);\n\n        // THEN\n        assertEquals(\"Paid 50$ on 05/24/2011\", payment.format());\n    }\n\n    @Test\n    public void testFactoryWithInjectedConstant() {\n        // WHEN\n        Star star = starFactory.create(\"Sun\", 1.99E30);\n\n        // THEN\n        assertEquals(\"Sun\", star.getName());\n        assertEquals(1.99E30, star.getMass(), 0.000001);\n        assertEquals(6.673E-11, star.getGravitationalConstant(), 0.000001);\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/AutoBindMocksDisabledTest.java",
    "content": "/*\n * Copyright 2017 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Assert;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mockito;\n\nimport com.google.inject.PrivateModule;\n\nimport jakarta.inject.Inject;\n\n/**\n * Tests behavior of autoBindMocks property on UseModules annotation.\n * NOTE: If autoBindMocks is true, this test will fail because SomeInterface will be auto bound\n * to a mock and the binding will conflict with private module's binding\n */\n@RunWith(JukitoRunner.class)\n@UseModules(value = AutoBindMocksDisabledTest.MyModule.class, autoBindMocks = false)\npublic class AutoBindMocksDisabledTest {\n\n    /**\n     * Guice PrivateModule for testing.\n     */\n    public static final class MyModule extends PrivateModule {\n\n        @Override\n        protected void configure() {\n            bind(ExposedClass.class);\n            bind(SomeInterface.class).to(NotAMock.class);\n            expose(ExposedClass.class);\n        }\n    }\n\n    /**\n     * Test Interface that will be auto mocked if autoBindMocks is set to true.\n     */\n    public interface SomeInterface {\n        void doSomething();\n    }\n\n    /**\n     * When autoBindMocks is false, an instance of this type will be bound\n     * to SomeInterface from the PrivateModule.\n     */\n    public static final class NotAMock implements SomeInterface {\n\n        @Override\n        public void doSomething() {\n        }\n    }\n\n    /**\n     * Class which injects either the automock or the concrete instance\n     * depending on the autoBindMocks property.\n     */\n    public static final class ExposedClass {\n\n        private SomeInterface instance;\n\n        @Inject\n        ExposedClass(final SomeInterface instance) {\n            this.instance = instance;\n        }\n\n        SomeInterface getInstance() {\n            return instance;\n        }\n    }\n\n    @Test\n    public void testSomething(final ExposedClass clazz) throws Exception {\n        Assert.assertFalse(Mockito.mockingDetails(clazz).isMock());\n        Assert.assertFalse(Mockito.mockingDetails(clazz.getInstance()).isMock());\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/BindAnnotatedConcreteClassesTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.name.Named;\n\nimport static org.junit.Assert.assertNotSame;\nimport static org.junit.Assert.assertSame;\n\n/**\n * Test that annotated concrete classes can be correctly bound.\n * See http://code.google.com/p/jukito/issues/detail?id=12\n */\n@RunWith(JukitoRunner.class)\npublic class BindAnnotatedConcreteClassesTest {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bindNamed(ConcreteClass.class, \"a\").to(ConcreteClass.class).in(TestSingleton.class);\n            bindNamed(ConcreteClass.class, \"b\").to(ConcreteClass.class).in(TestSingleton.class);\n            bindNamed(ConcreteClass.class, \"c\").to(SubConcreteClass.class);\n            bindNamed(ConcreteClass.class, \"d\").to(SubConcreteClass.class);\n            bind(SubConcreteClass.class).in(TestSingleton.class);\n            bind(SubSubConcreteClass.class);\n        }\n    }\n\n    static class ConcreteClass {\n    }\n\n    static class SubConcreteClass extends ConcreteClass {\n    }\n\n    static class SubSubConcreteClass extends ConcreteClass {\n    }\n\n    @Test\n    public void testConcreteClassBoundToDifferentSingletons(@Named(\"a\") ConcreteClass a,\n            @Named(\"b\") ConcreteClass b) {\n        // THEN\n        assertNotSame(a, b);\n    }\n\n    @Test\n    public void testConcreteClassBoundToSameSingleton(@Named(\"c\") ConcreteClass c,\n            @Named(\"d\") ConcreteClass d) {\n        // THEN\n        assertSame(c, d);\n    }\n\n    @Test\n    public void testConcreteClassNoBoundAsSingleton(SubSubConcreteClass instance1,\n            SubSubConcreteClass instance2) {\n        // THEN\n        assertNotSame(instance1, instance2);\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/BindSpyInstanceTest.java",
    "content": "/**\n * Copyright 2014 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Bind spy instance test.\n */\n@RunWith(JukitoRunner.class)\npublic class BindSpyInstanceTest {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bindSpy(SimpleClass.class, new SimpleClass(\"foo\")).in(TestScope.SINGLETON);\n        }\n    }\n\n    static class SimpleClass {\n        private String arg0;\n\n        @SuppressWarnings(\"unused\")\n        SimpleClass() {\n            this(\"default\");\n        }\n\n        SimpleClass(String arg0) {\n            this.arg0 = arg0;\n        }\n\n        String getVal() {\n            return arg0;\n        }\n    }\n\n    @Test\n    public void testOneInvocation(SimpleClass simple) {\n        String value = simple.getVal();\n\n        assertEquals(\"foo\", value);\n\n        verify(simple).getVal();\n    }\n\n    @Test\n    public void testNeverInvoked(SimpleClass simple) {\n        verify(simple, never()).getVal();\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/BindSpyTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Inject;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.doReturn;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test that binding spy works correctly.\n */\n@RunWith(JukitoRunner.class)\npublic class BindSpyTest {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bindSpy(SimpleClass.class).in(TestScope.SINGLETON);\n        }\n    }\n\n    interface CompositionMockA {\n        String test();\n    }\n\n    interface CompositionMockB {\n        String test();\n    }\n\n    static class SimpleClass {\n        @Inject\n        CompositionMockB mockB;\n\n        private CompositionMockA mockA;\n\n        @Inject\n        SimpleClass(CompositionMockA mockA) {\n            this.mockA = mockA;\n        }\n\n        String callTestMethodOnMock() {\n            mockA.test();\n            mockB.test();\n            return \"Default string\";\n        }\n    }\n\n    @Inject\n    CompositionMockA mockA;\n    @Inject\n    CompositionMockA mockB;\n\n    @Test\n    public void testStubbingSpiedInstance(SimpleClass simpleClass) {\n        // GIVEN\n        doReturn(\"Mocked string\").when(simpleClass).callTestMethodOnMock();\n\n        // WHEN\n        String result = simpleClass.callTestMethodOnMock();\n\n        // THEN\n        assertEquals(\"Mocked string\", result);\n        verify(mockA, never()).test();\n        verify(mockB, never()).test();\n    }\n\n    @Test\n    public void testNotStubbingSpiedInstance(SimpleClass simpleClass) {\n        // WHEN\n        String result = simpleClass.callTestMethodOnMock();\n\n        // THEN\n        verify(mockA).test();\n        verify(mockB).test();\n        assertEquals(\"Default string\", result);\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/BindingToProviderTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Provides;\n\nimport jakarta.inject.Provider;\n\nimport static org.junit.Assert.assertEquals;\n\n/**\n * A test to make sure injecting a Provider in a @Provides method.\n * See https://github.com/ArcBees/Jukito/issues/34\n */\n@RunWith(JukitoRunner.class)\npublic class BindingToProviderTest {\n\n    /**\n     * Guice test module.\n     */\n    public static class MyModule extends JukitoModule {\n        @Provides\n        public final MyClass getObject(Provider<String> provider) {\n            return new MyClass(\"abc\" + provider.get());\n        }\n\n        @Override\n        protected void configureTest() {\n            bind(String.class).toInstance(\"def\");\n        }\n    }\n\n    static class MyClass {\n        private final String string;\n\n        MyClass(String string) {\n            this.string = string;\n        }\n\n        String getString() {\n            return string;\n        }\n    }\n\n    @Test\n    public void foo(MyClass obj) {\n        assertEquals(\"abcdef\", obj.getString());\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/EDRunner.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.junit.runner.Description;\nimport org.junit.runner.Runner;\nimport org.junit.runner.notification.RunNotifier;\nimport org.junit.runners.ParentRunner;\n\nimport com.google.inject.AbstractModule;\nimport com.google.inject.Guice;\nimport com.google.inject.Injector;\nimport com.google.inject.Module;\n\n/**\n * Runner allows to run the all test methods in environment build upon different implementations\n * via dedicated Injectors per test run.\n */\npublic class EDRunner extends ParentRunner {\n    private List<Runner> runnersList;\n\n    public EDRunner(Class<?> testClass) throws Exception {\n        super(testClass);\n        runnersList = createJukitoRunners(testClass);\n    }\n\n    public List<Runner> createJukitoRunners(Class<?> testClass) throws Exception {\n        List<Runner> result = new ArrayList<Runner>();\n\n        for (Injector injector : calculateInjectors(testClass)) {\n            JukitoRunner jukitoRunner = new JukitoRunner(testClass, injector);\n            result.add(jukitoRunner);\n        }\n\n        return result;\n    }\n\n    protected List<Injector> calculateInjectors(Class<?> testClass)\n            throws IllegalAccessException, InstantiationException {\n        List<Injector> result = new ArrayList<Injector>();\n\n        EnvironmentDependentModules environmentDependentModules\n                = testClass.getAnnotation(EnvironmentDependentModules.class);\n\n        if (environmentDependentModules == null) {\n            throw new RuntimeException(EnvironmentDependentModules.class + \" not found on test class\");\n        }\n\n        for (Class edModuleClass : environmentDependentModules.value()) {\n            Injector i = buildInjector(edModuleClass, testClass);\n            result.add(i);\n        }\n\n        return result;\n    }\n\n    @Override\n    protected List getChildren() {\n        return runnersList;\n    }\n\n    @Override\n    protected Description describeChild(Object child) {\n        return ((JukitoRunner) child).getDescription();\n    }\n\n    @Override\n    protected void runChild(Object child, RunNotifier notifier) {\n        ((JukitoRunner) child).run(notifier);\n    }\n\n    private Injector buildInjector(Class<? extends Module> edModuleClazz, final Class<?> testClass)\n            throws InstantiationException, IllegalAccessException {\n\n        final Module environmentDependentModule = edModuleClazz.newInstance();\n\n        final AbstractModule testModule = new AbstractModule() {\n            @Override\n            protected void configure() {\n                for (Module declaredModule : getDeclaredModulesForTest(testClass)) {\n                    install(declaredModule);\n                }\n                install(environmentDependentModule);\n            }\n        };\n\n        JukitoModule finalModule = new JukitoModule() {\n            @Override\n            protected void configureTest() {\n                install(testModule);\n            }\n        };\n\n        BindingsCollector collector = new BindingsCollector(finalModule);\n        collector.collectBindings();\n        finalModule.setBindingsObserved(collector.getBindingsObserved());\n\n        return Guice.createInjector(finalModule);\n    }\n\n    // TODO refactor to common user module discovery method (JukitoRunner uses similar code now)\n    private Module[] getDeclaredModulesForTest(Class<?> testClass) {\n        UseModules useModules = testClass.getAnnotation(UseModules.class);\n        Class<? extends Module>[] moduleClasses = useModules.value();\n        final Module[] modules = new Module[moduleClasses.length];\n        for (int i = 0; i < modules.length; i++) {\n            try {\n                modules[i] = moduleClasses[i].newInstance();\n            } catch (Exception e) {\n                throw new RuntimeException(e);\n            }\n        }\n        return modules;\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/EnvironmentDependentComponent.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\n/**\n * Sample interface which have implementations bound in different guice context (Injectors).\n */\npublic interface EnvironmentDependentComponent {\n    void hello();\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/ExternalSingleton.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport com.google.inject.Singleton;\n\n/**\n * A class annotated with @Singleton not defined within test class.\n */\n@Singleton\npublic class ExternalSingleton {\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/ForceMockTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test that the {@link org.jukito.JukitoModule#forceMock} method works as expected.\n */\n@RunWith(JukitoRunner.class)\npublic class ForceMockTest {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            forceMock(Base1.class);\n            forceMock(Child21.class);\n            forceMock(Child311.class);\n        }\n    }\n\n    interface Base1 {\n        int t1();\n    }\n\n    static class Child11 implements Base1 {\n        public int t1() {\n            return 11;\n        }\n    }\n\n    static class Child111 extends Child11 {\n        public int t1() {\n            return 111;\n        }\n    }\n\n    static class Child12 implements Base1 {\n        public int t1() {\n            return 12;\n        }\n    }\n\n    interface Base2 {\n        int t2();\n    }\n\n    static class Child21 implements Base2 {\n        public int t2() {\n            return 21;\n        }\n    }\n\n    static class Child211 extends Child21 {\n        public int t2() {\n            return 211;\n        }\n    }\n\n    static class Child22 implements Base2 {\n        public int t2() {\n            return 22;\n        }\n    }\n\n    interface Base3 {\n        int t3();\n    }\n\n    static class Child31 implements Base3 {\n        public int t3() {\n            return 31;\n        }\n    }\n\n    static class Child311 extends Child31 {\n        public int t3() {\n            return 311;\n        }\n    }\n\n    @Test\n    public void injectForceMock(\n            Base1 base1,\n            Child11 child11,\n            Child111 child111,\n            Child12 child12,\n            Base2 base2,\n            Child21 child21,\n            Child211 child211,\n            Child22 child22,\n            Base3 base3,\n            Child31 child31,\n            Child311 child311) {\n        verify(base1, never()).t1();\n        verify(child11, never()).t1();\n        verify(child111, never()).t1();\n        verify(child12, never()).t1();\n\n        verify(base2, never()).t2();\n        verify(child21, never()).t2();\n        verify(child211, never()).t2();\n        assertEquals(22, child22.t2());\n\n        verify(base3, never()).t3();\n        assertEquals(31, child31.t3());\n        verify(child311, never()).t3();\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/GeneralTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.util.logging.Logger;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Inject;\nimport com.google.inject.Injector;\nimport com.google.inject.Key;\nimport com.google.inject.MembersInjector;\nimport com.google.inject.Stage;\nimport com.google.inject.TypeLiteral;\nimport com.google.inject.name.Named;\nimport com.google.inject.name.Names;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test various general behaviors.\n */\n@RunWith(JukitoRunner.class)\npublic class GeneralTest {\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bindConstant().annotatedWith(OneHundred.class).to(100);\n            bindConstant().annotatedWith(Names.named(\"200\")).to(200);\n            bindConstant().annotatedWith(Names.named(\"HelloWorld\")).to(\"Hello World!\");\n            bindConstant().annotatedWith(Names.named(\"500L\")).to(500L);\n            bindConstant().annotatedWith(Names.named(\"true\")).to(true);\n            bindConstant().annotatedWith(Names.named(\"3.1415\")).to(3.1415);\n            bindConstant().annotatedWith(Names.named(\"2.718f\")).to(2.718f);\n            bindConstant().annotatedWith(Names.named(\"short8\")).to((short) 8);\n            bindConstant().annotatedWith(Names.named(\"'a'\")).to('a');\n            bindConstant().annotatedWith(Names.named(\"IntegerClass\")).to(Integer.class);\n            bindConstant().annotatedWith(Names.named(\"VALUE1\")).to(MyEnum.VALUE1);\n            bindConstant().annotatedWith(Names.named(\"VALUE2\")).to(MyEnum.VALUE2);\n            bind(MyInteger.class).annotatedWith(OneHundred.class).toInstance(new MyIntegerImpl(100));\n            bind(MyInteger.class).annotatedWith(Names.named(\"200\")).toInstance(new MyIntegerImpl(200));\n            bind(Key.get(TestClass.class, Value3.class)).toInstance(new TestClass(MyEnum.VALUE3));\n            bind(Key.get(TestClass.class, Names.named(\"VALUE2\"))).to(TestClass.class).in(\n                    TestSingleton.class);\n            bind(new TypeLiteral<ParameterizedTestClass<Integer>>() {\n            }).in(TestScope.SINGLETON);\n            bind(new TypeLiteral<ParameterizedTestClass<Double>>() {\n            }).to(\n                    ParameterizedTestClassDouble.class).in(TestScope.SINGLETON);\n            bindNamedMock(ClassWithUninstanciableDependency3.class, \"UninstanciableDependency3a\");\n            bind(ClassWithUninstanciableDependency3.class).annotatedWith(\n                    Names.named(\"UninstanciableDependency3b\")).toProvider(MyMockProvider3b.class);\n            bind(ClassWithUninstanciableDependency3.class).annotatedWith(\n                    Names.named(\"UninstanciableDependency3c\")).toProvider(Key.get(MyMockProvider3c.class));\n            try {\n                bind(ParameterizedTestClassString.class).toConstructor(\n                        ParameterizedTestClassString.class.getConstructor(String.class));\n            } catch (SecurityException e) {\n                e.printStackTrace();\n            } catch (NoSuchMethodException e) {\n                e.printStackTrace();\n            }\n            // TODO: Try to bind a mock logger once Issue 9 is solved.\n            // bindMock(Logger.class);\n        }\n    }\n\n    interface MyInteger {\n        int getValue();\n    }\n\n    static class MyIntegerImpl implements MyInteger {\n        private final int value;\n\n        MyIntegerImpl(int value) {\n            this.value = value;\n        }\n\n        @Override\n        public int getValue() {\n            return value;\n        }\n    }\n\n    enum MyEnum {\n        VALUE1,\n        VALUE2,\n        VALUE3\n    }\n\n    static class TestClass {\n        private final MyEnum value;\n\n        @Inject\n        TestClass(@Named(\"VALUE2\") MyEnum value) {\n            this.value = value;\n        }\n    }\n\n    static class ParameterizedTestClass<T> {\n        final T value;\n\n        @Inject\n        ParameterizedTestClass(@Named(\"200\") T value) {\n            this.value = value;\n        }\n    }\n\n    static class ParameterizedTestClassDouble extends ParameterizedTestClass<Double> {\n        @Inject\n        ParameterizedTestClassDouble() {\n            super(10.0);\n        }\n    }\n\n    public static class ParameterizedTestClassString extends ParameterizedTestClass<String> {\n        ParameterizedTestClassString() {\n            super(\"default constructor\");\n        }\n\n        public ParameterizedTestClassString(@Named(\"HelloWorld\") String value) {\n            super(value);\n        }\n    }\n\n    static class TestClassWithMethodInjection {\n        private int value;\n\n        @Inject\n        TestClassWithMethodInjection(@OneHundred Integer value) {\n            this.value = value;\n        }\n\n        @Inject\n        public void setValue(@Named(\"200\") Integer value) {\n            this.value = value;\n        }\n    }\n\n    interface NonBoundInterface {\n        int getValue();\n    }\n\n    static class TestClassWithOptionalInjection {\n        private int value;\n\n        @Inject\n        TestClassWithOptionalInjection(@OneHundred Integer value) {\n            this.value = value;\n        }\n\n        @Inject(optional = true)\n        public void setValue(NonBoundInterface obj) {\n            value = obj.getValue(); // Should never be called, NonBoundInterface should not be mocked\n        }\n    }\n\n    // This class will cause an error if bound\n    static class UninstanciableClass {\n        private UninstanciableClass() {\n        }\n\n        public int getValue() {\n            return 360;\n        }\n    }\n\n    @TestMockSingleton\n    static class ClassWithUninstanciableDependency1 {\n        private final UninstanciableClass dependency;\n\n        @Inject\n        ClassWithUninstanciableDependency1(UninstanciableClass dependency) {\n            this.dependency = dependency;\n        }\n\n        public int getValue() {\n            return 42;\n        }\n\n        public UninstanciableClass getDependency() {\n            return dependency;\n        }\n    }\n\n    abstract static class ClassWithUninstanciableDependency2 {\n        @Inject\n        ClassWithUninstanciableDependency2(UninstanciableClass dependency) {\n        }\n\n        public int getValue() {\n            return 42;\n        }\n    }\n\n    static class ClassWithUninstanciableDependency3 {\n        @Inject\n        ClassWithUninstanciableDependency3(UninstanciableClass dependency) {\n        }\n\n        public int getValue() {\n            return 42;\n        }\n    }\n\n    static class MyMockProvider3b extends MockProvider<ClassWithUninstanciableDependency3> {\n        @Inject\n        MyMockProvider3b() {\n            super(ClassWithUninstanciableDependency3.class);\n        }\n    }\n\n    static class MyMockProvider3c extends MockProvider<ClassWithUninstanciableDependency3> {\n        @Inject\n        MyMockProvider3c() {\n            super(ClassWithUninstanciableDependency3.class);\n        }\n    }\n\n    static class TestGenericClassInjectedWithTypeLiteral<U> {\n        private final Class<? super U> injectedType;\n\n        @Inject\n        TestGenericClassInjectedWithTypeLiteral(TypeLiteral<U> typeLiteral) {\n            injectedType = typeLiteral.getRawType();\n        }\n\n        public Class<? super U> getInjectedType() {\n            return injectedType;\n        }\n    }\n\n    @Test\n    public void testConstantInjection(\n            @OneHundred Integer oneHundred,\n            @Named(\"200\") Integer twoHundred,\n            @Named(\"HelloWorld\") String helloWorld,\n            @Named(\"500L\") long fiveHundred,\n            @Named(\"3.1415\") double pi,\n            @Named(\"2.718f\") float e,\n            @Named(\"short8\") short eight,\n            @Named(\"'a'\") char a,\n            @SuppressWarnings(\"rawtypes\")\n            @Named(\"IntegerClass\") Class integerClass,\n            @Named(\"VALUE1\") MyEnum value1) {\n        assertEquals(100, (int) oneHundred);\n        assertEquals(200, (int) twoHundred);\n        assertEquals(\"Hello World!\", helloWorld);\n        assertEquals(500L, fiveHundred);\n        assertEquals(3.1415, pi, 0.0000001);\n        assertEquals(2.718f, e, 0.00001);\n        assertEquals(8, eight);\n        assertEquals('a', a);\n        assertEquals(Integer.class, integerClass);\n        assertEquals(MyEnum.VALUE1, value1);\n    }\n\n    @Test\n    public void testInjectBoundWithKeys(\n            @Value3 TestClass testClassValue3,\n            @Named(\"VALUE2\") TestClass testClassValue2,\n            @OneHundred MyInteger testMyInteger100,\n            @Named(\"200\") MyInteger testMyInteger200) {\n        assertEquals(MyEnum.VALUE3, testClassValue3.value);\n        assertEquals(MyEnum.VALUE2, testClassValue2.value);\n        assertEquals(100, testMyInteger100.getValue());\n        assertEquals(200, testMyInteger200.getValue());\n    }\n\n    @Test\n    public void testParameterizedInjection1(\n            ParameterizedTestClass<Integer> testClass) {\n        assertEquals(200, (int) testClass.value);\n    }\n\n    @Test\n    public void testParameterizedInjection2(\n            ParameterizedTestClass<Double> testClass) {\n        assertEquals(10.0, (double) testClass.value, 0.0000001);\n    }\n\n    @Test\n    public void testMethodInjection(\n            TestClassWithMethodInjection testClass) {\n        assertEquals(200, testClass.value);\n    }\n\n    @Test\n    public void testOptionalInjection(\n            TestClassWithOptionalInjection testClass) {\n        assertEquals(100, testClass.value);\n    }\n\n    @Test\n    public void testInjectingMockShouldNotInstantiateDependencies1(\n            ClassWithUninstanciableDependency1 testClass) {\n        assertEquals(42, testClass.getValue());\n        verify(testClass.getDependency(), never()).getValue();\n    }\n\n    @Test\n    public void testInjectingMockShouldNotInstantiateDependencies2(\n            ClassWithUninstanciableDependency2 testClass) {\n        verify(testClass, never()).getValue();\n    }\n\n    @Test\n    public void testInjectingMockShouldNotInstantiateDependencies3a(\n            @Named(\"UninstanciableDependency3a\") ClassWithUninstanciableDependency3 testClass) {\n        verify(testClass, never()).getValue();\n    }\n\n    @Test\n    public void testInjectingMockShouldNotInstantiateDependencies3b(\n            @Named(\"UninstanciableDependency3b\") ClassWithUninstanciableDependency3 testClass) {\n        verify(testClass, never()).getValue();\n    }\n\n    @Test\n    public void testInjectingMockShouldNotInstantiateDependencies3c(\n            @Named(\"UninstanciableDependency3c\") ClassWithUninstanciableDependency3 testClass) {\n        verify(testClass, never()).getValue();\n    }\n\n    @Test\n    public void testInjectingClassInjectedWithTypeLiteralShouldWork(\n            TestGenericClassInjectedWithTypeLiteral<String> testClass) {\n        assertEquals(String.class, testClass.getInjectedType());\n    }\n\n    @Test\n    public void testInjectingTypeLiteralShouldWork(\n            TypeLiteral<Integer> typeLiteral) {\n        assertEquals(Integer.class, typeLiteral.getRawType());\n    }\n\n    @Test\n    public void testInjectingInjectorShouldWork(\n            Injector injector) {\n    }\n\n    @Test\n    public void testInjectingLoggerShouldWork(\n            Logger logger) {\n    }\n\n    @Test\n    public void testInjectingStageShouldWork(\n            Stage stage) {\n    }\n\n    @Test\n    public void testInjectingMembersInjectorShouldWork(\n            MembersInjector<TestClass> memberInjector) {\n    }\n\n    @Test\n    public void toConstructorInjectionShouldWork(ParameterizedTestClassString object) {\n        assertEquals(\"Hello World!\", object.value);\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/InnerClassTest.java",
    "content": "/**\n * Copyright 2014 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.ConfigurationException;\nimport com.google.inject.Inject;\n\nimport static org.junit.Assert.assertEquals;\n\n/**\n * Test to ensure that injecting inner classes throw a ConfigurationException, instead\n * of simply injecting a mock. Additionally, test that injecting static inner classes\n * still work properly.\n */\n@RunWith(JukitoRunner.class)\npublic class InnerClassTest {\n    /**\n     * Test module, just bind anything to make sure regular injections still work properly.\n     */\n    public static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bind(String.class).toInstance(\"hello world!\");\n        }\n    }\n\n    /**\n     * Dummy inner class with a single inject.\n     */\n    class InnerClass {\n        @Inject\n        String test;\n\n        public String toString() {\n            return test;\n        }\n    }\n\n    /**\n     * Dummy static inner class with a single inject.\n     */\n    static class StaticInnerClass {\n        @Inject\n        String test;\n\n        public String toString() {\n            return test;\n        }\n    }\n\n    /**\n     * Verify that when you try to inject an inner class, a ConfigurationException is thrown.\n     *\n     * @param klass\n     */\n    @Test(expected = ConfigurationException.class)\n    public void testInnerClass(InnerClass klass) {\n        assertEquals(\"hello world!\", klass.toString());\n    }\n\n    /**\n     * Verify that when you try to inject a static inner class, everything works properly.\n     *\n     * @param klass\n     */\n    @Test\n    public void testStaticInnerClass(StaticInnerClass klass) {\n        assertEquals(\"hello world!\", klass.toString());\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/InstallTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.AbstractModule;\nimport com.google.inject.Inject;\nimport com.google.inject.Provider;\nimport com.google.inject.name.Named;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.when;\n\n/**\n * Test exercising Guice's install() mechanism.\n */\n@RunWith(JukitoRunner.class)\npublic class InstallTest {\n\n    /**\n     * Guice test module, containing two submodules.\n     */\n    static class Module extends JukitoModule {\n\n        public class FooModule extends AbstractModule {\n\n            @Override\n            protected void configure() {\n                bind(Foo.class).to(FooImpl.class);\n            }\n        }\n\n        public class BarModule extends AbstractModule {\n\n            @Override\n            protected void configure() {\n                bind(Bar.class).to(BarImpl.class);\n            }\n        }\n\n        @Override\n        protected void configureTest() {\n            install(new FooModule());\n            install(new BarModule());\n            bindNamedMock(Foo.class, \"ten\").in(TestSingleton.class);\n        }\n    }\n\n    interface Foo {\n        int calc();\n    }\n\n    static class FooImpl implements Foo {\n\n        private final Provider<Bar> barProvider;\n        private final Foo ten;\n\n        @Inject\n        FooImpl(Provider<Bar> barProvider, @Named(\"10\") Foo ten) {\n            this.barProvider = barProvider;\n            this.ten = ten;\n        }\n\n        @Override\n        public int calc() {\n            return this.barProvider.get().calc() + ten.calc();\n        }\n    }\n\n    interface Bar {\n        int calc();\n    }\n\n    static class BarImpl implements Bar {\n        @Override\n        public int calc() {\n            return 5;\n        }\n    }\n\n    @Inject\n    Foo foo;\n\n    @Before\n    public void setup(@Named(\"10\") Foo ten) {\n        when(ten.calc()).thenReturn(10);\n    }\n\n    @Test\n    public void installingModuleWorks(Bar bar) {\n        assertEquals(15, foo.calc());\n        assertEquals(5, bar.calc());\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/ModuleWithProvidesMethods.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\npackage org.jukito;\n\nimport com.google.inject.AbstractModule;\nimport com.google.inject.Provides;\n\nimport static org.mockito.Mockito.mock;\n\n/**\n * Simple module with factory method.\n */\npublic class ModuleWithProvidesMethods extends AbstractModule {\n\n    @Provides\n    @TestSingleton\n    SomeTestClass create() {\n        SomeTestClass mock = mock(SomeTestClass.class);\n        mock.someInitMethod();\n        return mock;\n    }\n\n    @Override\n    protected void configure() {\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/NoModuleTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.assertSame;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test to ensure injection works well without a module.\n */\n@RunWith(JukitoRunner.class)\npublic class NoModuleTest {\n\n    interface MyMockSingleton {\n        int dummy();\n    }\n\n    @TestMockSingleton\n    interface MyAnnotatedMockSingleton {\n        int dummy();\n    }\n\n    static class MySingleton {\n    }\n\n    @TestSingleton\n    static class MyAnnotatedSingleton {\n    }\n\n    @TestEagerSingleton\n    static class MyAnnotatedEagerSingleton {\n    }\n\n    @Test\n    public void testMockSingleton(MyMockSingleton a, MyMockSingleton b) {\n        assertSame(a, b);\n        a.dummy();\n        verify(a).dummy();\n        verify(b).dummy();\n    }\n\n    @Test\n    public void testAnnotatedMockSingleton(MyAnnotatedMockSingleton a,\n            MyAnnotatedMockSingleton b) {\n        assertSame(a, b);\n        a.dummy();\n        verify(a).dummy();\n        verify(b).dummy();\n    }\n\n    @Test\n    public void testSingleton(MySingleton a, MySingleton b) {\n        assertSame(a, b);\n    }\n\n    @Test\n    public void testAnnotatedSingleton(MyAnnotatedSingleton a, MyAnnotatedSingleton b) {\n        assertSame(a, b);\n    }\n\n    @Test\n    public void testAnnotatedEagerSingleton(MyAnnotatedEagerSingleton a,\n            MyAnnotatedEagerSingleton b) {\n        assertSame(a, b);\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/OldStyleAssistedInjectTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Inject;\nimport com.google.inject.assistedinject.Assisted;\nimport com.google.inject.assistedinject.FactoryProvider;\nimport com.google.inject.name.Named;\nimport com.google.inject.name.Names;\n\nimport static org.junit.Assert.assertEquals;\n\n/**\n * Test that make sure old-style Guice 2.0 assisted injection is supported.\n */\n@SuppressWarnings(\"deprecation\")\n@RunWith(JukitoRunner.class)\npublic class OldStyleAssistedInjectTest {\n    /**\n     * Guice test module.\n     */\n    public static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bindConstant().annotatedWith(Names.named(\"moneySymbol\")).to(\"$\");\n            bindNamed(PaymentFactory.class, \"factory1\").toProvider(\n                    FactoryProvider.newFactory(PaymentFactory.class, RealPayment1.class));\n            bindNamed(PaymentFactory.class, \"factory2\").toProvider(\n                    FactoryProvider.newFactory(PaymentFactory.class, RealPayment2.class));\n            bind(PaymentAmountFactory.class).toProvider(\n                    FactoryProvider.newFactory(PaymentAmountFactory.class, RealPaymentAmount.class));\n            bind(Amount.class).toInstance(new Amount() {\n                public String toString() {\n                    return \"An amount of 10.00 \";\n                }\n            });\n        }\n    }\n\n    interface PaymentFactory {\n        Payment create(int amount);\n    }\n\n    interface PaymentAmountFactory {\n        Payment create(Amount amount);\n    }\n\n    interface Payment {\n        String getPayment();\n    }\n\n    static class RealPayment1 implements Payment {\n        private final String moneySymbol;\n        private final int amount;\n\n        @Inject\n        RealPayment1(@Named(\"moneySymbol\") String moneySymbol, @Assisted int amount) {\n            this.moneySymbol = moneySymbol;\n            this.amount = amount;\n        }\n\n        @Override\n        public String getPayment() {\n            return Integer.toString(amount) + \".00\" + moneySymbol;\n        }\n    }\n\n    static class RealPayment2 implements Payment {\n        private final int amount;\n\n        @Inject\n        RealPayment2(@Assisted int amount) {\n            this.amount = amount;\n        }\n\n        @Override\n        public String getPayment() {\n            return Integer.toString(amount) + \" dollars\";\n        }\n    }\n\n    interface Amount {\n        String toString();\n    }\n\n    // Interface Configuration should be mocked because it is a dependency\n    // of RealPaymentAmout. The mocked version of {@ocde shouldAlwaysHideAmounts()}\n    // will always return {@code false}.\n    interface Configuration {\n        boolean shouldAlwaysHideAmounts();\n    }\n\n    // Class InjectedClass should be bound automatically\n    // because it is a dependency of RealPaymentAmount\n    static class InjectedClass {\n        @Inject\n        @Named(\"moneySymbol\")\n        String moneySymbol;\n    }\n\n    static class RealPaymentAmount implements Payment {\n        private final Configuration configuration;\n        private final InjectedClass injectedClass;\n        private final Amount amount;\n\n        @Inject\n        RealPaymentAmount(Configuration configuration,\n                InjectedClass injectedClass,\n                @Assisted Amount amount) {\n            this.configuration = configuration;\n            this.injectedClass = injectedClass;\n            this.amount = amount;\n        }\n\n        @Override\n        public String getPayment() {\n            if (configuration.shouldAlwaysHideAmounts()) {\n                return \"xxxxxxx \" + injectedClass.moneySymbol;\n            }\n            return amount.toString() + injectedClass.moneySymbol;\n        }\n    }\n\n    @Inject\n    @Named(\"factory1\")\n    PaymentFactory factory1;\n\n    @Test\n    public void shouldInjectFactoryInClass() {\n        // WHEN\n        Payment payment = factory1.create(20);\n\n        // THEN\n        assertEquals(\"20.00$\", payment.getPayment());\n    }\n\n    @Test\n    public void shouldInjectFactoryAsParameter(@Named(\"factory2\") PaymentFactory factory2) {\n        // WHEN\n        Payment payment = factory2.create(30);\n\n        // THEN\n        assertEquals(\"30 dollars\", payment.getPayment());\n    }\n\n    @Test\n    public void shouldInjectFactoryWithInterfacesAsParameter(\n            PaymentAmountFactory factoryString,\n            Amount amount) {\n        // WHEN\n        Payment payment = factoryString.create(amount);\n\n        // THEN\n        assertEquals(\"An amount of 10.00 $\", payment.getPayment());\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/OneHundred.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\nimport com.google.inject.BindingAnnotation;\n\n/**\n * An annotation used in a test class.\n */\n@BindingAnnotation\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface OneHundred {\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/ParentClassInnerClassModuleDiscoveryTest.java",
    "content": "/*\n * Copyright 2017 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.junit.AfterClass;\nimport org.junit.Assert;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Test which ensures that nested TestModules in parent classes are discovered by the JukitoRunner.\n */\n@RunWith(JukitoRunner.class)\npublic class ParentClassInnerClassModuleDiscoveryTest extends SampleParentTestClassWithInnerTestModule {\n\n    private static final AtomicInteger numberOfTestRuns = new AtomicInteger(0);\n\n    @AfterClass\n    public static void afterClass() throws Exception {\n        Assert.assertEquals(2, numberOfTestRuns.get());\n    }\n\n    @Test\n    public void testSomething(@All final String bindingsFromParent) throws Exception {\n        numberOfTestRuns.incrementAndGet();\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/ParentTestClassBase.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Ignore;\nimport org.junit.Test;\n\nimport com.google.inject.Inject;\nimport com.google.inject.Provider;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertSame;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\n\n/**\n * This parent test class is used by {@link ParentTestClassTest}.\n */\n@Ignore(\"Tests in this base class are not meant to be run independantly.\")\npublic class ParentTestClassBase {\n\n    /**\n     * This should be automatically injected in the child class.\n     */\n    @TestSingleton\n    static class SingletonDefinedInParent {\n        private String value = \"SingletonDefinedInParentValue\";\n\n        public String getValue() {\n            return value;\n        }\n    }\n\n    /**\n     * This should be automatically injected in the child class.\n     */\n    @TestMockSingleton\n    interface MockSingletonDefinedInParent {\n        void mockSingletonMethod();\n    }\n\n    interface DummyInterface {\n        String getDummyValue();\n    }\n\n    interface DummyInterfaceUsedOnlyInParent1 {\n        String getDummyValue();\n    }\n\n    interface DummyInterfaceUsedOnlyInParent2 {\n        String getDummyValue();\n    }\n\n    interface DummyInterfaceUsedOnlyInParent3 {\n        String getDummyValue();\n    }\n\n    static class DummyClassUsedOnlyInParent1 {\n    }\n\n    static class DummyClassUsedOnlyInParent2 {\n    }\n\n    static class DummyClassUsedOnlyInParent3 {\n    }\n\n    @Inject\n    protected Provider<DummyInterface> dummyProvider;\n    @Inject\n    protected MockSingletonDefinedInParent mockSingletonDefinedInParent;\n\n    /**\n     * This class keeps track of what happens in all the tests run in this\n     * class and its child. It's used to make sure all expected tests are called.\n     */\n    protected static class Bookkeeper {\n        static boolean parentTestShouldRunExecuted;\n    }\n\n    @Test\n    public void parentTestShouldRun() {\n        Bookkeeper.parentTestShouldRunExecuted = true;\n    }\n\n    @Test\n    public void interfaceBoundInChildIsInjectedInParent() {\n        assertEquals(\"DummyValue\", dummyProvider.get().getDummyValue());\n    }\n\n    @Test\n    public void interfaceBoundInChildIsInjectedInParentTestMethod(\n            DummyInterface dummyInterface) {\n        assertEquals(\"DummyValue\", dummyInterface.getDummyValue());\n    }\n\n    @Test\n    public void interfaceUsedInParentTestMethodShouldBeMockedAsTestSingleton(\n            Provider<DummyInterfaceUsedOnlyInParent1> provider) {\n        // Following should not crash\n        verify(provider.get(), never()).getDummyValue();\n\n        assertSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void concreteClassUsedInParentTestMethodShouldBeBoundAsTestSingleton(\n            Provider<DummyClassUsedOnlyInParent1> provider) {\n        assertSame(provider.get(), provider.get());\n    }\n\n    @Before\n    public void interfaceUsedInParentBeforeMethodShouldBeMockedAsTestSingleton(\n            Provider<DummyInterfaceUsedOnlyInParent2> provider) {\n        // Following should not crash\n        verify(provider.get(), never()).getDummyValue();\n\n        assertSame(provider.get(), provider.get());\n    }\n\n    @Before\n    public void concreteClassUsedInParentBeforeMethodShouldBeBoundAsTestSingleton(\n            Provider<DummyClassUsedOnlyInParent2> provider) {\n        assertSame(provider.get(), provider.get());\n    }\n\n    @After\n    public void interfaceUsedInParentAfterMethodShouldBeMockedAsTestSingleton(\n            Provider<DummyInterfaceUsedOnlyInParent3> provider) {\n        // Following should not crash\n        verify(provider.get(), never()).getDummyValue();\n\n        assertSame(provider.get(), provider.get());\n    }\n\n    @After\n    public void concreteClassUsedInParentAfterMethodShouldBeBoundAsTestSingleton(\n            Provider<DummyClassUsedOnlyInParent3> provider) {\n        assertSame(provider.get(), provider.get());\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/ParentTestClassTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.AfterClass;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test that inheritance of test classes works correctly.\n */\n@RunWith(JukitoRunner.class)\npublic class ParentTestClassTest extends ParentTestClassBase {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bind(DummyInterface.class).to(MyDummyClass.class).in(TestScope.SINGLETON);\n        }\n    }\n\n    /**\n     * This class should be injected in parent tests.\n     */\n    static class MyDummyClass implements DummyInterface {\n        @Override\n        public String getDummyValue() {\n            return \"DummyValue\";\n        }\n    }\n\n    @Test\n    public void mockSingletonDefinedInParentShouldBeBoundAsAMock() {\n        verify(mockSingletonDefinedInParent, never()).mockSingletonMethod();\n    }\n\n    @Test\n    public void singletonDefinedInParentShouldBeBound(\n            SingletonDefinedInParent singletonDefinedInParent) {\n        assertEquals(\"SingletonDefinedInParentValue\", singletonDefinedInParent.getValue());\n    }\n\n    @AfterClass\n    public static void checkBookkeeper() {\n        assertTrue(Bookkeeper.parentTestShouldRunExecuted);\n    }\n}\n\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/ProviderBindingTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mockito;\n\nimport com.google.inject.Inject;\nimport com.google.inject.Provider;\n\nimport static junit.framework.Assert.assertNotNull;\n\n/**\n * Test which ensures that a class which is a provider may also be binded independently.\n */\n@RunWith(JukitoRunner.class)\npublic class ProviderBindingTest {\n\n    /**\n     * Guice test module.\n     */\n    public static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bind(ServiceAndProvider.class);\n            bind(MyService.class).toProvider(ServiceAndProvider.class);\n        }\n    }\n\n    @Test\n    public void shouldBeExecuted(OtherService service, MyService myService) {\n        assertNotNull(service);\n        assertNotNull(myService);\n    }\n\n    interface MyService {\n    }\n\n    static class ServiceAndProvider implements Provider<MyService> {\n        @Override\n        public MyService get() {\n            return Mockito.mock(MyService.class);\n        }\n\n        public void doSomethingVeryImportant() {\n            // nop\n        }\n    }\n\n    static class OtherService {\n        @Inject\n        public ServiceAndProvider service;\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/ProviderTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Inject;\nimport com.google.inject.Key;\nimport com.google.inject.Provider;\nimport com.google.inject.Provides;\nimport com.google.inject.name.Named;\nimport com.google.inject.name.Names;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNotSame;\nimport static org.junit.Assert.assertSame;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test that providers injected by the tester module behaves correctly.\n */\n@RunWith(JukitoRunner.class)\npublic class ProviderTest {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bindNamedMock(Mock.class, \"singleton\").in(TestScope.SINGLETON);\n            bindNamedMock(Mock.class, \"nonsingleton\");\n            bindNamed(Instance.class, \"singleton\").to(Instance.class).in(TestSingleton.class);\n            bindNamed(Instance.class, \"nonsingleton\").to(Instance.class);\n            bindNamed(Parent.class, \"providerInstance\").toProvider(new ParentProviderA()).in(\n                    TestSingleton.class);\n            bindNamed(Parent.class, \"providerClass\").toProvider(ParentProviderB.class).in(\n                    TestSingleton.class);\n            bindNamed(Parent.class, \"providerKey\").toProvider(Key.get(ParentProviderA.class)).in(\n                    TestSingleton.class);\n            bindNamedMock(UninstanciableClass.class, \"cannotInstantiate1\").in(TestScope.SINGLETON);\n            bind(UninstanciableClass.class).annotatedWith(Names.named(\"cannotInstantiate2\")).toProvider(\n                    MyMockProvider2.class);\n            bind(UninstanciableClass.class).annotatedWith(Names.named(\"cannotInstantiate3\")).toProvider(\n                    Key.get(MyMockProvider3.class));\n            bind(ClassWithMockedDependency1.class).annotatedWith(\n                    Names.named(\"MockedDependency1\")).toProvider(MyProvider1.class);\n            bind(ClassWithMockedDependency2.class).annotatedWith(\n                    Names.named(\"MockedDependency2\")).toProvider(Key.get(MyProvider2.class));\n        }\n\n        @Provides\n        ProvidedViaMethod getProvidedViaMethod() {\n            return new ProvidedViaMethod(\"good\");\n        }\n    }\n\n    interface Mock {\n    }\n\n    static class Instance {\n        @Inject\n        Instance() {\n        }\n    }\n\n    interface Parent {\n        String getValue();\n    }\n\n    static class ChildA implements Parent {\n        public String getValue() {\n            return \"childA\";\n        }\n    }\n\n    interface MockInChildB {\n    }\n\n    interface MockInProviderB {\n        void test();\n    }\n\n    static class ChildB implements Parent {\n        @Inject\n        MockInChildB mockB;\n\n        public String getValue() {\n            return \"childB\";\n        }\n    }\n\n    abstract static class ParentProviderABase implements Provider<Parent> {\n    }\n\n    static class ParentProviderA extends ParentProviderABase {\n        @Override\n        public Parent get() {\n            return new ChildA();\n        }\n    }\n\n    static class ParentProviderB implements Provider<Parent> {\n        private final Provider<ChildB> childBProvider;\n\n        @Inject\n        ParentProviderB(Provider<ChildB> childBProvider, Provider<MockInProviderB> myMock) {\n            this.childBProvider = childBProvider;\n\n            // These calls should succeed\n            myMock.get().test();\n            verify(myMock.get()).test();\n        }\n\n        @Override\n        public Parent get() {\n            return childBProvider.get();\n        }\n    }\n\n    static class UninstanciableClass {\n        private UninstanciableClass() {\n        }\n\n        public int getValue() {\n            return 42;\n        }\n    }\n\n    static class MyMockProvider2 extends MockProvider<UninstanciableClass> {\n        @Inject\n        MyMockProvider2() {\n            super(UninstanciableClass.class);\n        }\n    }\n\n    static class MyMockProvider3 extends MockProvider<UninstanciableClass> {\n        @Inject\n        MyMockProvider3() {\n            super(UninstanciableClass.class);\n        }\n    }\n\n    interface DependencyShouldBeMocked1 {\n        int getValue();\n    }\n\n    static class ClassWithMockedDependency1 {\n        private final DependencyShouldBeMocked1 dependency;\n\n        @Inject\n        ClassWithMockedDependency1(DependencyShouldBeMocked1 dependency) {\n            this.dependency = dependency;\n        }\n\n        public DependencyShouldBeMocked1 getDependency() {\n            return dependency;\n        }\n    }\n\n    static class MyProvider1 implements Provider<ClassWithMockedDependency1> {\n        final Provider<ClassWithMockedDependency1> provider;\n\n        @Inject\n        MyProvider1(Provider<ClassWithMockedDependency1> provider) {\n            this.provider = provider;\n        }\n\n        @Override\n        public ClassWithMockedDependency1 get() {\n            return provider.get();\n        }\n    }\n\n    interface DependencyShouldBeMocked2 {\n        int getValue();\n    }\n\n    static class ClassWithMockedDependency2 {\n        private final DependencyShouldBeMocked2 dependency;\n\n        @Inject\n        ClassWithMockedDependency2(DependencyShouldBeMocked2 dependency) {\n            this.dependency = dependency;\n        }\n\n        public DependencyShouldBeMocked2 getDependency() {\n            return dependency;\n        }\n    }\n\n    static class MyProvider2 implements Provider<ClassWithMockedDependency2> {\n        final Provider<ClassWithMockedDependency2> provider;\n\n        @Inject\n        MyProvider2(Provider<ClassWithMockedDependency2> provider) {\n            this.provider = provider;\n        }\n\n        @Override\n        public ClassWithMockedDependency2 get() {\n            return provider.get();\n        }\n    }\n\n    static class ProvidedViaMethod {\n        final String value;\n\n        ProvidedViaMethod(String value) {\n            this.value = value;\n        }\n    }\n\n    @Test\n    public void mockSingletonProviderShouldReturnTheSameInstance(\n            @Named(\"singleton\") Provider<Mock> provider) {\n        assertSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void mockNonSingletonProviderShouldNotReturnTheSameInstance(\n            @Named(\"nonsingleton\") Provider<Mock> provider) {\n        assertNotSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void singletonProvidedClassShouldReturnTheSameInstance(\n            @Named(\"singleton\") Provider<Instance> provider) {\n        assertSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void singletonClassShouldNotReturnTheSameInstance(\n            @Named(\"singleton\") Instance obj1, @Named(\"singleton\") Instance obj2) {\n        assertSame(obj1, obj2);\n    }\n\n    @Test\n    public void nonSingletonProvidedClassShouldNotReturnTheSameInstance(\n            @Named(\"nonsingleton\") Provider<Instance> provider) {\n        assertNotSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void nonSingletonClassShouldNotReturnTheSameInstance(\n            @Named(\"nonsingleton\") Instance obj1, @Named(\"nonsingleton\") Instance obj2) {\n        assertNotSame(obj1, obj2);\n    }\n\n    @Test\n    public void bindingToProviderInstanceShouldWorkAndInject(\n            @Named(\"nonsingleton\") Provider<Mock> provider) {\n        assertNotSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void shouldInjectProviderBoundWithInstance(\n            @Named(\"providerInstance\") Parent parentProvidedFromProviderInstance) {\n        assertEquals(parentProvidedFromProviderInstance.getClass(), ChildA.class);\n    }\n\n    @Test\n    public void shouldInjectProviderBoundWithClass(\n            @Named(\"providerClass\") Parent parentProvidedFromProviderClass) {\n        assertEquals(parentProvidedFromProviderClass.getClass(), ChildB.class);\n    }\n\n    @Test\n    public void shouldInjectProviderBoundWithKey(\n            @Named(\"providerKey\") Parent parentProvidedFromProviderKey) {\n        assertEquals(parentProvidedFromProviderKey.getClass(), ChildA.class);\n    }\n\n    @Test\n    public void shouldInjectProviderOfClassWithPrivateConstructor1(\n            @Named(\"cannotInstantiate1\") UninstanciableClass classWithPrivateConstructor) {\n        verify(classWithPrivateConstructor, never()).getValue();\n    }\n\n    @Test\n    public void shouldInjectProviderOfClassWithPrivateConstructor2(\n            @Named(\"cannotInstantiate2\") UninstanciableClass classWithPrivateConstructor) {\n        verify(classWithPrivateConstructor, never()).getValue();\n    }\n\n    @Test\n    public void shouldInjectProviderOfClassWithPrivateConstructor3(\n            @Named(\"cannotInstantiate3\") UninstanciableClass classWithPrivateConstructor) {\n        verify(classWithPrivateConstructor, never()).getValue();\n    }\n\n    @Test\n    public void testInjectingProviderShouldInstantiateDependencies1(\n            @Named(\"MockedDependency1\") ClassWithMockedDependency1 testClass) {\n        verify(testClass.getDependency(), never()).getValue();\n    }\n\n    @Test\n    public void testInjectingProviderShouldInstantiateDependencies2(\n            @Named(\"MockedDependency2\") ClassWithMockedDependency2 testClass) {\n        verify(testClass.getDependency(), never()).getValue();\n    }\n\n    @Test\n    public void providesMethodShouldWork(ProvidedViaMethod providedViaMethod) {\n        assertEquals(\"good\", providedViaMethod.value);\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/ProvidesMethodTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Inject;\nimport com.google.inject.Provider;\nimport com.google.inject.Provides;\nimport com.google.inject.name.Named;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNotSame;\nimport static org.junit.Assert.assertSame;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test that @Provides methods in the tester module behave correctly.\n */\n@RunWith(JukitoRunner.class)\npublic class ProvidesMethodTest {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bindNamedMock(Mock.class, \"singleton\").in(TestScope.SINGLETON);\n            bindNamedMock(Mock.class, \"nonsingleton\");\n            bindNamed(Instance.class, \"singleton\").to(Instance.class).in(TestSingleton.class);\n            bindNamed(Instance.class, \"nonsingleton\").to(Instance.class);\n            bindNamedMock(UninstanciableClass.class, \"cannotInstantiate1\").in(TestScope.SINGLETON);\n        }\n\n        @Provides\n        @TestSingleton\n        @Named(\"providerInstance\")\n        protected Parent providesParent1() {\n            return new ChildA();\n        }\n\n        @Provides\n        @TestSingleton\n        @Named(\"providerClass\")\n        protected Parent providesParent2(ChildB childB, MockInProviderB myMock) {\n            // These calls should succeed\n            myMock.test();\n            verify(myMock).test();\n            return childB;\n        }\n\n        @Provides\n        @TestSingleton\n        @Named(\"providerKey\")\n        protected Parent providesParent3() {\n            return new ChildA();\n        }\n\n        @Provides\n        @TestSingleton\n        @Named(\"cannotInstantiate2\")\n        protected UninstanciableClass providesUninstanciableClass2() {\n            return mock(UninstanciableClass.class);\n        }\n\n        @Provides\n        @TestSingleton\n        @Named(\"cannotInstantiate3\")\n        protected UninstanciableClass providesUninstanciableClass3() {\n            return mock(UninstanciableClass.class);\n        }\n\n        @Provides\n        @TestSingleton\n        @Named(\"MockedDependency1\")\n        protected ClassWithMockedDependency1 providesClassWithMockedDependency1(ClassWithMockedDependency1 x) {\n            return x;\n        }\n\n        @Provides\n        @TestSingleton\n        @Named(\"MockedDependency2\")\n        protected ClassWithMockedDependency2 providesClassWithMockedDependency2(ClassWithMockedDependency2 x) {\n            return x;\n        }\n\n        @Provides\n        public Value aValue() {\n            return VALUE;\n        }\n\n        @Provides\n        public Integer anInteger(Value value) {\n            return 3;\n        }\n    }\n\n    interface Mock {\n    }\n\n    static class Instance {\n        @Inject\n        Instance() {\n        }\n    }\n\n    interface Parent {\n        String getValue();\n    }\n\n    static class ChildA implements Parent {\n        public String getValue() {\n            return \"childA\";\n        }\n    }\n\n    interface MockInChildB {\n    }\n\n    interface MockInProviderB {\n        void test();\n    }\n\n    static class ChildB implements Parent {\n        @Inject\n        MockInChildB mockB;\n\n        public String getValue() {\n            return \"childB\";\n        }\n    }\n\n    static class UninstanciableClass {\n        private UninstanciableClass() {\n        }\n\n        public int getValue() {\n            return 42;\n        }\n    }\n\n    interface DependencyShouldBeMocked1 {\n        int getValue();\n    }\n\n    static class ClassWithMockedDependency1 {\n        private final DependencyShouldBeMocked1 dependency;\n\n        @Inject\n        ClassWithMockedDependency1(DependencyShouldBeMocked1 dependency) {\n            this.dependency = dependency;\n        }\n\n        public DependencyShouldBeMocked1 getDependency() {\n            return dependency;\n        }\n    }\n\n    interface DependencyShouldBeMocked2 {\n        int getValue();\n    }\n\n    static class ClassWithMockedDependency2 {\n        private final DependencyShouldBeMocked2 dependency;\n\n        @Inject\n        ClassWithMockedDependency2(DependencyShouldBeMocked2 dependency) {\n            this.dependency = dependency;\n        }\n\n        public DependencyShouldBeMocked2 getDependency() {\n            return dependency;\n        }\n    }\n\n    static class Value {\n        public final String string;\n\n        Value(String string) {\n            this.string = string;\n        }\n    }\n\n    private static final Value VALUE = new Value(\"ok\");\n\n    @Test\n    public void mockSingletonProviderShouldReturnTheSameInstance(\n            @Named(\"singleton\") Provider<Mock> provider) {\n        assertSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void mockNonSingletonProviderShouldNotReturnTheSameInstance(\n            @Named(\"nonsingleton\") Provider<Mock> provider) {\n        assertNotSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void singletonProvidedClassShouldReturnTheSameInstance(\n            @Named(\"singleton\") Provider<Instance> provider) {\n        assertSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void singletonClassShouldNotReturnTheSameInstance(\n            @Named(\"singleton\") Instance obj1, @Named(\"singleton\") Instance obj2) {\n        assertSame(obj1, obj2);\n    }\n\n    @Test\n    public void nonSingletonProvidedClassShouldNotReturnTheSameInstance(\n            @Named(\"nonsingleton\") Provider<Instance> provider) {\n        assertNotSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void nonSingletonClassShouldNotReturnTheSameInstance(\n            @Named(\"nonsingleton\") Instance obj1, @Named(\"nonsingleton\") Instance obj2) {\n        assertNotSame(obj1, obj2);\n    }\n\n    @Test\n    public void bindingToProviderInstanceShouldWorkAndInject(\n            @Named(\"nonsingleton\") Provider<Mock> provider) {\n        assertNotSame(provider.get(), provider.get());\n    }\n\n    @Test\n    public void shouldInjectProviderBoundWithInstance(\n            @Named(\"providerInstance\") Parent parentProvidedFromProviderInstance) {\n        assertEquals(parentProvidedFromProviderInstance.getClass(), ChildA.class);\n    }\n\n    @Test\n    public void shouldInjectProviderBoundWithClass(\n            @Named(\"providerClass\") Parent parentProvidedFromProviderClass) {\n        assertEquals(parentProvidedFromProviderClass.getClass(), ChildB.class);\n    }\n\n    @Test\n    public void shouldInjectProviderBoundWithKey(\n            @Named(\"providerKey\") Parent parentProvidedFromProviderKey) {\n        assertEquals(parentProvidedFromProviderKey.getClass(), ChildA.class);\n    }\n\n    @Test\n    public void shouldInjectProviderOfClassWithPrivateConstructor1(\n            @Named(\"cannotInstantiate1\") UninstanciableClass classWithPrivateConstructor) {\n        verify(classWithPrivateConstructor, never()).getValue();\n    }\n\n    @Test\n    public void shouldInjectProviderOfClassWithPrivateConstructor2(\n            @Named(\"cannotInstantiate2\") UninstanciableClass classWithPrivateConstructor) {\n        verify(classWithPrivateConstructor, never()).getValue();\n    }\n\n    @Test\n    public void shouldInjectProviderOfClassWithPrivateConstructor3(\n            @Named(\"cannotInstantiate3\") UninstanciableClass classWithPrivateConstructor) {\n        verify(classWithPrivateConstructor, never()).getValue();\n    }\n\n    @Test\n    public void testInjectingProviderShouldInstantiateDependencies1(\n            @Named(\"MockedDependency1\") ClassWithMockedDependency1 testClass) {\n        verify(testClass.getDependency(), never()).getValue();\n    }\n\n    @Test\n    public void testInjectingProviderShouldInstantiateDependencies2(\n            @Named(\"MockedDependency2\") ClassWithMockedDependency2 testClass) {\n        verify(testClass.getDependency(), never()).getValue();\n    }\n\n    @Test\n    public void testProvidingConstants(Value value, Integer integer) {\n        assertEquals(\"ok\", value.string);\n        assertEquals(3, (int) integer);\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/ReportWriterTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.io.StringWriter;\nimport java.io.Writer;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Set;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Inject;\n\nimport jakarta.inject.Singleton;\n\nimport static org.junit.Assert.assertEquals;\n\n/**\n * Tests that new Guice 3.0 assisted injection works in Jukito.\n */\n@RunWith(JukitoRunner.class)\npublic class ReportWriterTest {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        final Writer reportWriter = new StringWriter();\n\n        // Overriding this method will cause a report to be generated.\n        @Override\n        public Writer getReportWriter() {\n            return reportWriter;\n        }\n\n        @Override\n        protected void configureTest() {\n            bind(Writer.class).toInstance(reportWriter);\n            bindNamedSpy(Resource4.class, \"Spy\").in(TestSingleton.class);\n            forceMock(Resource6.class);\n        }\n    }\n\n    @Singleton\n    static class Resource1 {\n    }\n\n    interface Resource2 {\n    }\n\n    static class Resource3 {\n        @Inject\n        @OneHundred\n        Resource5 resource5;\n\n        @Inject\n        Resource3(Resource4 resource4) {\n        }\n\n        @Inject\n        void setResource6(Resource6 resource6) {\n        }\n    }\n\n    static class Resource4 {\n    }\n\n    interface Resource5 {\n    }\n\n    static class Resource6 {\n    }\n\n    @Inject\n    Resource2 resource2;\n    @Inject\n    Resource3 resource3;\n\n    @Test\n    public void ensureReport(Writer reportWriter, Resource1 resource1) {\n        Set<String> explicitBindings = findBlock(\"*** EXPLICIT BINDINGS ***\", reportWriter.toString());\n        Set<String> automaticBindings = findBlock(\"*** AUTOMATIC BINDINGS ***\",\n                reportWriter.toString());\n\n        Set<String> e = new HashSet<String>();\n        e.add(\"  Key[type=java.io.Writer, annotation=[none]] --> Instance of java.io.StringWriter ### In scope \" +\n                \"EagerSingleton\");\n        e.add(\"  Key[type=org.jukito.ReportWriterTest$Resource4, annotation=@org.jukito.JukitoInternal] --> Bound \" +\n                \"directly ### No scope\");\n        e.add(\"  Key[type=org.jukito.ReportWriterTest$Resource4, annotation=@com.google.inject.name.Named(\\\"Spy\\\")]\" +\n                \" \" +\n                \"--> Instance of org.jukito.SpyProvider ### In scope org.jukito.TestSingleton\");\n\n        Set<String> a = new HashSet<String>();\n        a.add(\"  Key[type=org.jukito.ReportWriterTest$Resource1, annotation=[none]] --> Bound directly ### In scope \" +\n                \"TestSingleton\");\n        a.add(\"  Key[type=org.jukito.ReportWriterTest$Resource2, annotation=[none]] --> Instance of \" +\n                \"org.jukito.MockProvider ### In scope TestSingleton\");\n        a.add(\"  Key[type=org.jukito.ReportWriterTest$Resource3, annotation=[none]] --> Bound directly ### In scope \" +\n                \"TestSingleton\");\n        a.add(\"  Key[type=org.jukito.ReportWriterTest$Resource4, annotation=[none]] --> Bound directly ### In scope \" +\n                \"TestSingleton\");\n        a.add(\"  Key[type=org.jukito.ReportWriterTest$Resource5, annotation=@org.jukito.OneHundred] --> Instance of \" +\n                \"org.jukito.MockProvider ### In scope TestSingleton\");\n        a.add(\"  Key[type=org.jukito.ReportWriterTest$Resource6, annotation=[none]] --> Instance of \" +\n                \"org.jukito.MockProvider ### In scope TestSingleton\");\n\n        assertEquals(e, explicitBindings);\n        assertEquals(a, automaticBindings);\n    }\n\n    private Set<String> findBlock(String header, String text) {\n        int start = text.indexOf(header) + header.length();\n        int end = text.indexOf(\"\\n\\n\", start);\n        String block = text.substring(start + 1, end);\n        String[] lines = block.split(\"\\n\");\n        Set<String> result = new HashSet<String>(lines.length);\n        result.addAll(Arrays.asList(lines));\n        return result;\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/RequestInjectionTest.java",
    "content": "/**\n * Copyright 2014 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport jakarta.inject.Inject;\n\nimport static org.junit.Assert.assertTrue;\nimport static org.mockito.Mockito.mockingDetails;\n\n/**\n * Test class for request injection.\n */\n@RunWith(JukitoRunner.class)\npublic class RequestInjectionTest {\n    interface Dummy {\n    }\n\n    static class RequestInjection {\n        @Inject\n        Dummy dummy;\n\n        public Dummy getDummy() {\n            return dummy;\n        }\n    }\n\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            requestInjection(RequestInjection.class);\n        }\n    }\n\n    // SUT\n    @Inject\n    RequestInjection requestInjection;\n\n    @Test\n    public void dummyShouldBeMocked() {\n        Dummy dummy = requestInjection.getDummy();\n\n        assertTrue(mockingDetails(dummy).isMock());\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/RequestStaticInjectionTest.java",
    "content": "/**\n * Copyright 2014 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Provides;\n\nimport jakarta.inject.Inject;\nimport jakarta.inject.Named;\n\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\nimport static org.mockito.Mockito.mockingDetails;\n\n/**\n * Test class for request static injection.\n */\n@RunWith(JukitoRunner.class)\npublic class RequestStaticInjectionTest {\n    interface Dummy {\n    }\n\n    static class RequestStaticInjectionA {\n        @Inject\n        @Named(\"a\")\n        static Dummy DUMMY;\n    }\n\n    static class RequestStaticInjectionB {\n        @Inject\n        static Dummy DUMMY;\n    }\n\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            requestStaticInjection(RequestStaticInjectionA.class);\n            requestStaticInjection(RequestStaticInjectionB.class);\n        }\n\n        @Provides\n        @Named(\"a\")\n        Dummy createDummy() {\n            return new Dummy() {\n            };\n        }\n    }\n\n    @Test\n    public void dummyShouldNotBeMocked() {\n        Dummy dummy = RequestStaticInjectionA.DUMMY;\n\n        assertFalse(mockingDetails(dummy).isMock());\n\n        assertNotNull(dummy);\n    }\n\n    @Test\n    public void dummyShouldBeMocked() {\n        Dummy dummy = RequestStaticInjectionB.DUMMY;\n\n        assertTrue(mockingDetails(dummy).isMock());\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/RespectProvidesAnnotationInModuleTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test proving that factory methods are called when defined in external module\n * and installed in JukitoModule.\n */\n@RunWith(JukitoRunner.class)\npublic class RespectProvidesAnnotationInModuleTest {\n    @Test\n    public void shouldRespectProvidesAnnotationUsedInModule(SomeTestClass someTestClass) throws Exception {\n        //-------------------- GIVEN -------------------------------------------------------------------\n\n        //-------------------- WHEN --------------------------------------------------------------------\n\n        //-------------------- THEN --------------------------------------------------------------------\n        // injected object should be created by factory method\n        // defined in  custom module  ModuleWithProvidesMethods.\n        // Init method should be called from factory method\n        verify(someTestClass).someInitMethod();\n    }\n\n    /**\n     * Guice test module.\n     */\n    public static class A extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            install(new ModuleWithProvidesMethods());\n        }\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/RespectTestScopeWhenUsingAbstractModuleTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\npackage org.jukito;\n\nimport org.junit.FixMethodOrder;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.MethodSorters;\n\nimport com.google.inject.Inject;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.times;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test for respecting {@literal @}{@link org.jukito.TestSingleton}\n * when user modules subclass AbstractModule.\n */\n@RunWith(JukitoRunner.class)\n@FixMethodOrder(MethodSorters.NAME_ASCENDING)\npublic class RespectTestScopeWhenUsingAbstractModuleTest {\n\n    @Inject\n    SomeTestClass someTestClassOne;\n\n    @Inject\n    SomeTestClass someTestClassTwo;\n\n    @Test\n    public void shouldRespectTestSingletonAnnotationA() throws Exception {\n        //-------------------- GIVEN -------------------------------------------------------------------\n\n        //-------------------- WHEN --------------------------------------------------------------------\n        // calls for purpose of test shouldRespectTestSingletonsB\n        someTestClassOne.crazyMethod();\n        someTestClassOne.crazyMethod();\n        someTestClassOne.crazyMethod();\n\n        //-------------------- THEN --------------------------------------------------------------------\n        assertEquals(someTestClassOne, someTestClassTwo);\n    }\n\n    @Test\n    public void shouldRespectTestSingletonsB() throws Exception {\n        //-------------------- GIVEN -------------------------------------------------------------------\n\n        //-------------------- WHEN --------------------------------------------------------------------\n        someTestClassOne.crazyMethod();\n\n        //-------------------- THEN --------------------------------------------------------------------\n        // verify if mock has been reset and thus only one call is registered\n        verify(someTestClassOne, times(1)).crazyMethod();\n    }\n\n    @Test\n    public void shouldRespectTestSingletonsC() throws Exception {\n        //-------------------- GIVEN -------------------------------------------------------------------\n\n        //-------------------- WHEN --------------------------------------------------------------------\n        someTestClassOne.crazyMethod();\n        someTestClassTwo.crazyMethod();\n\n        //-------------------- THEN --------------------------------------------------------------------\n        verify(someTestClassOne, times(2)).crazyMethod();\n    }\n\n    /**\n     * Guice test module.\n     */\n    public static class A extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            install(new ModuleWithProvidesMethods());\n        }\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/SampleParentTestClassWithInnerTestModule.java",
    "content": "/*\n * Copyright 2017 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\n/**\n * Sample Parent Test Class which binds 2 string instances for use by\n * the {@link ParentClassInnerClassModuleDiscoveryTest}.\n */\npublic class SampleParentTestClassWithInnerTestModule {\n\n    /**\n     * Sample JukitoModule which binds 2 String instances.\n     * The Instances will be injected to an {@code @All} test and counted to verify that\n     * this module is discovered by the JukitoRunner.\n     */\n    public static final class MyModule extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bindManyInstances(String.class, \"Hello\", \"World\");\n        }\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/SingletonTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.junit.AfterClass;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Inject;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNotSame;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test that the various flavours of singletons work correctly.\n */\n@RunWith(JukitoRunner.class)\npublic class SingletonTest {\n\n    /**\n     * Guice test module.\n     */\n    static class Module extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bind(MyEagerSingleton.class).asEagerSingleton();\n            bindMock(MyTestMockSingletonBoundNonMock.class);\n            bind(MyTestEagerSingleton.class);\n        }\n    }\n\n    @TestSingleton\n    static class Registry {\n        public Map<Class<?>, Integer> registrationCount = new HashMap<Class<?>, Integer>();\n\n        public void register(Class<?> clazz) {\n            registrationCount.put(clazz, getCount(clazz) + 1);\n        }\n\n        public int getCount(Class<?> clazz) {\n            Integer value = registrationCount.get(clazz);\n            if (value == null) {\n                return 0;\n            }\n            return value;\n        }\n    }\n\n    /**\n     * This class keeps track of what happens in all the tests run in this\n     * class. It's used to make sure all expected tests are called.\n     */\n    private static class Bookkeeper {\n        static int numberOfTimesTestEagerSingletonIsInstantiated;\n        static int numberOfTimesTestSingletonIsInstantiated;\n        static int numberOfTimesEagerSingletonIsInstantiated;\n        static ExternalSingleton singleton1;\n        static ExternalSingleton singleton2;\n    }\n\n    /**\n     * This should be instantiated once for the entire test class.\n     */\n    static class MyEagerSingleton {\n        @Inject\n        MyEagerSingleton(Registry registry) {\n            registry.register(getClass());\n            Bookkeeper.numberOfTimesEagerSingletonIsInstantiated++;\n        }\n    }\n\n    /**\n     * This should automatically register before each test.\n     */\n    @TestEagerSingleton\n    static class MyTestEagerSingleton {\n        @Inject\n        MyTestEagerSingleton(Registry registry) {\n            registry.register(getClass());\n            Bookkeeper.numberOfTimesTestEagerSingletonIsInstantiated++;\n        }\n    }\n\n    /**\n     * This should register only in tests where it is injected.\n     */\n    @TestSingleton\n    static class MyTestSingleton {\n        @Inject\n        MyTestSingleton(Registry registry) {\n            registry.register(getClass());\n            Bookkeeper.numberOfTimesTestSingletonIsInstantiated++;\n        }\n    }\n\n    /**\n     * This should be different from one test to the next.\n     */\n    @TestMockSingleton\n    interface MyTestMockSingleton {\n        void dummy();\n    }\n\n    /**\n     * This should be bound as non-mock even though there is an annotation,\n     * because the module explicitely binds it.\n     */\n    @TestMockSingleton\n    interface MyTestMockSingletonBoundNonMock {\n        void dummy();\n    }\n\n    @Inject\n    Registry registry;\n\n    @Test\n    public void onlyEagerSingletonShouldBeRegistered() {\n        assertEquals(1, registry.getCount(MyTestEagerSingleton.class));\n    }\n\n    @Test\n    public void bothSingletonsShouldBeRegistered(MyTestSingleton myTestSingleton) {\n        assertEquals(1, registry.getCount(MyTestEagerSingleton.class));\n        assertEquals(1, registry.getCount(MyTestSingleton.class));\n    }\n\n    @Test\n    public void injectionOfMockShouldBeADifferentObject1(MyTestMockSingleton myTestMockSingleton) {\n        myTestMockSingleton.dummy();\n        verify(myTestMockSingleton).dummy();\n    }\n\n    @Test\n    public void injectionOfMockShouldBeADifferentObject2(MyTestMockSingleton myTestMockSingleton) {\n        myTestMockSingleton.dummy();\n        verify(myTestMockSingleton).dummy();\n    }\n\n    @Test\n    public void injectionOfSingletonMockExplicitelyBoundAsNonSingleton(\n            MyTestMockSingletonBoundNonMock a,\n            MyTestMockSingletonBoundNonMock b) {\n        verify(a, never()).dummy();\n        verify(b, never()).dummy();\n        assertNotSame(a, b);\n    }\n\n    @Test\n    public void firstInjectionOfSingleton(ExternalSingleton obj) {\n        Bookkeeper.singleton1 = obj;\n    }\n\n    @Test\n    public void secondInjectionOfSingleton(ExternalSingleton obj) {\n        Bookkeeper.singleton2 = obj;\n    }\n\n    @AfterClass\n    public static void verifyNumberOfInstantiations() {\n        assertEquals(7, Bookkeeper.numberOfTimesTestEagerSingletonIsInstantiated);\n        assertEquals(1, Bookkeeper.numberOfTimesTestSingletonIsInstantiated);\n        assertEquals(1, Bookkeeper.numberOfTimesEagerSingletonIsInstantiated);\n        assertNotSame(Bookkeeper.singleton1, Bookkeeper.singleton2);\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/SomeCoreComponent.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\n/**\n * Sample core component under test in different environments.\n */\npublic class SomeCoreComponent {\n    private EnvironmentDependentComponent someComponent;\n\n    public SomeCoreComponent(EnvironmentDependentComponent someComponent) {\n        this.someComponent = someComponent;\n    }\n\n    public void run() {\n        someComponent.hello();\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/SomeTestClass.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\n/**\n * Sample class doing totally nothing.\n */\npublic class SomeTestClass {\n    public void someInitMethod() {\n        // nothing\n    }\n\n    public void crazyMethod() {\n        // nothing special here\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/TestTestDescriptions.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Simple test with @Description in place.\n */\n@RunWith(JukitoRunner.class)\npublic class TestTestDescriptions {\n    @Test\n    @Description(\"some nice test description\")\n    public void testA() throws Exception {\n        // Given\n\n        // When\n\n        // Then\n    }\n\n    @Test\n    @Description(\"some nice ultra long test description, some nice ultra long test description,\" +\n            \"some nice ultra long test description, some nice ultra long test description\")\n    public void testB() throws Exception {\n        // Given\n\n        // When\n\n        // Then\n    }\n\n    @Test\n    public void testWithoutDescription() throws Exception {\n        // Given\n\n        // When\n\n        // Then\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/TransitiveDependencyTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.Inject;\nimport com.google.inject.name.Named;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNotNull;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.verify;\n\n/**\n * Test that various form of automatic discovery of transitive dependencies work.\n */\n@RunWith(JukitoRunner.class)\npublic class TransitiveDependencyTest {\n\n    static class MyModule extends JukitoModule {\n        @Override\n        protected void configureTest() {\n            bind(MyInterface.class).to(MyInterfaceImpl.class).in(TestSingleton.class);\n            bind(MyInterfaceImpl.class);\n        }\n    }\n\n    interface SubCollaborator {\n        void subCollaborate();\n    }\n\n    @TestEagerSingleton\n    static class Collaborator {\n        private final SubCollaborator subCollaborator;\n\n        @Inject\n        Collaborator(SubCollaborator subCollaborator) {\n            this.subCollaborator = subCollaborator;\n        }\n    }\n\n    @TestEagerSingleton\n    static class Leader {\n        private final Collaborator collaborator;\n\n        @Inject\n        Leader(Collaborator collaborator) {\n            this.collaborator = collaborator;\n        }\n    }\n\n    interface MyInterface {\n        int getValue();\n    }\n\n    static class MyDependency {\n        public int getValue() {\n            return 10;\n        }\n    }\n\n    interface MyDependentInterface {\n    }\n\n    static class MyInterfaceImpl implements MyInterface {\n        private final MyDependency myDependency;\n\n        @Inject\n        MyInterfaceImpl(MyDependency myDependency,\n                MyDependentInterface myDependentInterface) {\n            this.myDependency = myDependency;\n        }\n\n        @Override\n        public int getValue() {\n            return myDependency.getValue();\n        }\n    }\n\n    enum MyEnum {\n        OPTION_1, OPTION_2\n    }\n\n    static class MyClassInjectedWithUnboundConstants {\n        @Inject\n        @Named(\"version\")\n        Integer version;\n        @Inject\n        @Named(\"someClass\")\n        Class<? extends MyClassInjectedWithUnboundConstants> someClass;\n        @Inject\n        @Named(\"timestamp\")\n        Long timestamp;\n        @Inject\n        @Named(\"option\")\n        MyEnum option;\n\n        @Inject\n        MyClassInjectedWithUnboundConstants(\n                @Named(\"pi\") double pi,\n                @Named(\"salt\") String salt,\n                @Named(\"small\") short small,\n                @Named(\"tiny\") byte tiny,\n                @Named(\"letter\") Character letter) {\n        }\n\n        @Inject\n        void setAutoinit(@Named(\"autoinit\") boolean autoinit) {\n        }\n\n        @Inject\n        void setSensitivity(@Named(\"sensitivity\") float sensitivity) {\n        }\n    }\n\n    @Test\n    public void testDoubleDependency(Leader leader) {\n        verify(leader.collaborator.subCollaborator, never()).subCollaborate();\n    }\n\n    @Test\n    public void testDependencyFromInterface(MyInterface myInterface) {\n        assertEquals(10, myInterface.getValue());\n    }\n\n    @Test\n    public void testDependencyOnUnboundConstants(MyClassInjectedWithUnboundConstants object) {\n        assertNotNull(object);\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/UseModulesTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport org.jukito.UseModulesTest.Abc;\nimport org.jukito.UseModulesTest.AbcImpl;\nimport org.jukito.UseModulesTest.Def;\nimport org.jukito.UseModulesTest.DefImpl;\nimport org.jukito.UseModulesTest.Klm;\nimport org.jukito.UseModulesTest.KlmImpl;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.mockito.Mockito;\n\nimport com.google.inject.AbstractModule;\n\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\n\n/**\n * Test to check that method injection works fine with external modules.\n */\n@RunWith(JukitoRunner.class)\n@UseModules({AbcModule.class, DefModule.class})\npublic class UseModulesTest extends UseModulesTestBase {\n    interface Abc {\n    }\n\n    interface Def {\n    }\n\n    interface Ghj {\n    }\n\n    interface Klm {\n    }\n\n    static class AbcImpl implements Abc {\n    }\n\n    static class DefImpl implements Def {\n    }\n\n    static class AbcImpl2 implements Abc {\n    }\n\n    static class DefImpl2 implements Def {\n    }\n\n    static class KlmImpl implements Klm {\n    }\n\n    @Test\n    @UseModules(XyzModule.class)\n    public void testInjectionUsingMethodModules(Abc abc, Def def) {\n        assertTrue(abc instanceof AbcImpl2);\n        assertTrue(def instanceof DefImpl2);\n    }\n\n    @Test\n    public void testInjectionWithExternalModules(Abc abc, Def def, Klm klm) {\n        assertTrue(abc instanceof AbcImpl);\n        assertTrue(def instanceof DefImpl);\n        assertTrue(klm instanceof KlmImpl);\n    }\n\n    @Test\n    public void testAutoMockingForMissingBindings(Ghj ghj) {\n        assertNotNull(ghj);\n        assertTrue(Mockito.mockingDetails(ghj).isMock());\n    }\n}\n\nclass XyzModule extends AbstractModule {\n    @Override\n    protected void configure() {\n        bind(Abc.class).to(UseModulesTest.AbcImpl2.class);\n        bind(Def.class).to(UseModulesTest.DefImpl2.class);\n    }\n}\n\n@UseModules({DefModule.class, KlmModule.class})\nabstract class UseModulesTestBase {\n    // KlmModule should get installed\n    // DefModule should be ignored because subClass has it\n}\n\nclass AbcModule extends AbstractModule {\n    @Override\n    protected void configure() {\n        bind(Abc.class).to(AbcImpl.class);\n    }\n}\n\nclass DefModule extends AbstractModule {\n    @Override\n    protected void configure() {\n        bind(Def.class).to(DefImpl.class);\n    }\n}\n\nclass KlmModule extends AbstractModule {\n    @Override\n    protected void configure() {\n        bind(Klm.class).to(KlmImpl.class);\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/Value3.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\nimport com.google.inject.BindingAnnotation;\n\n/**\n * An annotation used in a test class.\n */\n@BindingAnnotation\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Value3 {\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/environmentdependent/DesktopModule.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.environmentdependent;\n\nimport org.jukito.EnvironmentDependentComponent;\n\nimport com.google.inject.AbstractModule;\n\n/**\n * Sample Environment Dependent Module.\n */\npublic class DesktopModule extends AbstractModule {\n    @Override\n    protected void configure() {\n        bind(EnvironmentDependentComponent.class).toInstance(new EnvironmentDependentComponent() {\n            @Override\n            public void hello() {\n                System.err.println(\"DesktopModule\");\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/environmentdependent/EnvironmentDependentModulesTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.environmentdependent;\n\nimport org.jukito.EDRunner;\nimport org.jukito.EnvironmentDependentComponent;\nimport org.jukito.EnvironmentDependentModules;\nimport org.jukito.SomeCoreComponent;\nimport org.jukito.UseModules;\nimport org.jukito.environmentdependent.EnvironmentDependentModulesTest.SomeCoreModule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport com.google.inject.AbstractModule;\nimport com.google.inject.Provides;\n\n/**\n * This test is run as many times as many Environment Dependent Modules you declare.\n * Every Environment Dependent Module is installed in separated Injector\n * with default core modules you declare in @UseModules.\n */\n@EnvironmentDependentModules({MobileModule.class, DesktopModule.class, TabletModule.class})\n@UseModules(SomeCoreModule.class)\n@RunWith(EDRunner.class)\npublic class EnvironmentDependentModulesTest {\n    @Test\n    public void shouldRunAsManyTimesAsManyInjectorsWereCreated(SomeCoreComponent coreComponent) throws Exception {\n        coreComponent.run();\n    }\n\n    /**\n     * SomeCoreModule.\n     */\n    public static class SomeCoreModule extends AbstractModule {\n        @Provides\n        SomeCoreComponent createCalculator(EnvironmentDependentComponent dependentComponent) {\n            return new SomeCoreComponent(dependentComponent);\n        }\n\n        @Override\n        protected void configure() {\n        }\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/environmentdependent/MobileModule.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.environmentdependent;\n\nimport org.jukito.EnvironmentDependentComponent;\n\nimport com.google.inject.AbstractModule;\n\n/**\n * Sample Environment Dependent Module.\n */\npublic class MobileModule extends AbstractModule {\n    @Override\n    protected void configure() {\n        bind(EnvironmentDependentComponent.class).toInstance(new EnvironmentDependentComponent() {\n            @Override\n            public void hello() {\n                System.err.println(\"MobileModule\");\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "jukito/src/test/java/org/jukito/environmentdependent/TabletModule.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.environmentdependent;\n\nimport org.jukito.EnvironmentDependentComponent;\n\nimport com.google.inject.AbstractModule;\n\n/**\n * Sample Environment Dependent Module.\n */\npublic class TabletModule extends AbstractModule {\n    @Override\n    protected void configure() {\n        bind(EnvironmentDependentComponent.class).toInstance(new EnvironmentDependentComponent() {\n            @Override\n            public void hello() {\n                System.err.println(\"TabletModule\");\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "jukito-samples/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.jukito</groupId>\n        <artifactId>jukito-parent</artifactId>\n        <version>1.6-SNAPSHOT</version>\n    </parent>\n\n    <artifactId>jukito-samples</artifactId>\n    <name>Jukito Samples</name>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-checkstyle-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n    <dependencies>\n        <dependency>\n            <groupId>com.google.inject</groupId>\n            <artifactId>guice</artifactId>\n        </dependency>\n\n        <!-- Test dependencies -->\n        <dependency>\n            <groupId>org.jukito</groupId>\n            <artifactId>jukito</artifactId>\n            <version>${project.version}</version>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "jukito-samples/src/main/java/org/jukito/samples/Car.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.samples;\n\npublic abstract class Car {\n    private Engine engine;\n\n    public Car(Engine engine) {\n        this.engine = engine;\n    }\n\n    public void startEngine() {\n        engine.initiateIgnition();\n    }\n\n    public Engine getEngine() {\n        return engine;\n    }\n}\n"
  },
  {
    "path": "jukito-samples/src/main/java/org/jukito/samples/DieselEngine.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.samples;\n\npublic class DieselEngine implements Engine {\n    @Override\n    public void initiateIgnition() {\n    }\n}\n"
  },
  {
    "path": "jukito-samples/src/main/java/org/jukito/samples/Engine.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.samples;\n\npublic interface Engine {\n    void initiateIgnition();\n}\n"
  },
  {
    "path": "jukito-samples/src/main/java/org/jukito/samples/FordMustang.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.samples;\n\nimport jakarta.inject.Inject;\n\npublic class FordMustang extends Car {\n    @Inject\n    public FordMustang(Engine engine) {\n        super(engine);\n    }\n}\n"
  },
  {
    "path": "jukito-samples/src/main/java/org/jukito/samples/PetrolEngine.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.samples;\n\npublic class PetrolEngine implements Engine {\n    @Override\n    public void initiateIgnition() {\n    }\n}\n"
  },
  {
    "path": "jukito-samples/src/main/java/org/jukito/samples/modules/DieselLineModule.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.samples.modules;\n\nimport org.jukito.samples.DieselEngine;\nimport org.jukito.samples.Engine;\n\nimport com.google.inject.AbstractModule;\n\npublic class DieselLineModule extends AbstractModule {\n    @Override\n    protected void configure() {\n        bind(Engine.class).to(DieselEngine.class);\n    }\n}\n"
  },
  {
    "path": "jukito-samples/src/main/java/org/jukito/samples/modules/PetrolLineModule.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.samples.modules;\n\nimport org.jukito.samples.Engine;\nimport org.jukito.samples.PetrolEngine;\n\nimport com.google.inject.AbstractModule;\n\npublic class PetrolLineModule extends AbstractModule {\n    @Override\n    protected void configure() {\n        bind(Engine.class).to(PetrolEngine.class);\n    }\n}\n"
  },
  {
    "path": "jukito-samples/src/test/java/org/jukito/samples/FordMustangTest.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.samples;\n\nimport org.jukito.JukitoRunner;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport jakarta.inject.Inject;\n\nimport static org.mockito.Mockito.verify;\n\n/**\n * A simple test with one mock (engine) and one real object (FordMustang).\n */\n@RunWith(JukitoRunner.class)\npublic class FordMustangTest {\n    @Inject\n    FordMustang sut;\n\n    @Test\n    public void shouldInitiateIgnitionWhenCarStart() throws Exception {\n        // Given\n\n        // When\n        sut.startEngine();\n\n        // Then\n        verify(sut.getEngine()).initiateIgnition();\n    }\n}\n"
  },
  {
    "path": "jukito-samples/src/test/java/org/jukito/samples/FordMustangTest2.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.samples;\n\nimport org.jukito.JukitoModule;\nimport org.jukito.JukitoRunner;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport jakarta.inject.Inject;\n\nimport static org.mockito.Mockito.verify;\n\n/**\n * A simple test with one real DOC (binding in test).\n */\n@RunWith(JukitoRunner.class)\npublic class FordMustangTest2 {\n    @Inject\n    FordMustang sut;\n\n    @Test\n    public void shouldInitiateIgnitionWhenCarStart() throws Exception {\n        // Given\n\n        // Then\n        sut.startEngine();\n\n        // Then\n        verify(sut.getEngine()).initiateIgnition();\n    }\n\n    public static class A extends JukitoModule {\n        @Override\n        protected void configureTest() {\n\n            // Diesel in Mustang, yeaah I know :)\n            bind(Engine.class).to(DieselEngine.class);\n\n            // necessary if you want to verify interaction on real object\n            bindSpy(DieselEngine.class);\n        }\n    }\n}\n"
  },
  {
    "path": "jukito-samples/src/test/java/org/jukito/samples/FordMustangTest3.java",
    "content": "/**\n * Copyright 2013 ArcBees Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\npackage org.jukito.samples;\n\nimport org.jukito.JukitoModule;\nimport org.jukito.JukitoRunner;\nimport org.jukito.samples.modules.DieselLineModule;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport jakarta.inject.Inject;\n\nimport static org.mockito.Mockito.verify;\n\n/**\n * A simple test with one real DOC (binding via module installation).\n */\n@RunWith(JukitoRunner.class)\npublic class FordMustangTest3 {\n    @Inject\n    FordMustang sut;\n\n    @Test\n    public void shouldInitiateIgnitionWhenCarStart() throws Exception {\n        // Given\n\n        // When\n        sut.startEngine();\n\n        // Then\n        verify(sut.getEngine()).initiateIgnition();\n    }\n\n    /**\n     * JukitoModule.\n     */\n    public static class A extends JukitoModule {\n        @Override\n        protected void configureTest() {\n\n            // install yours module as you wish\n            install(new DieselLineModule());\n\n            // necessary if you want to verify interaction on real object\n            bindSpy(DieselEngine.class);\n        }\n    }\n}\n"
  },
  {
    "path": "pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>org.sonatype.oss</groupId>\n        <artifactId>oss-parent</artifactId>\n        <version>9</version>\n    </parent>\n\n    <groupId>org.jukito</groupId>\n    <artifactId>jukito-parent</artifactId>\n    <version>1.6-SNAPSHOT</version>\n    <packaging>pom</packaging>\n    <name>Jukito</name>\n    <inceptionYear>2010</inceptionYear>\n    <description>A testing framework with automocking base on JUnit, Guice and Mokito.</description>\n    <url>http://jukito.org</url>\n\n    <licenses>\n        <license>\n            <name>Apache 2</name>\n            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n            <distribution>repo</distribution>\n            <comments>A business-friendly OSS license</comments>\n        </license>\n    </licenses>\n\n    <organization>\n        <name>ArcBees Inc.</name>\n        <url>http://arcbees.com</url>\n    </organization>\n\n    <developers>\n        <developer>\n            <name>Philippe Beaudoin</name>\n            <email>philippe.beaudoin@gmail.com</email>\n            <url>http://www.google.com/profiles/philippe.beaudoin</url>\n            <organization>ArcBees</organization>\n            <organizationUrl>http://arcbees.com</organizationUrl>\n            <roles>\n                <role>architect</role>\n                <role>lead developer</role>\n            </roles>\n            <timezone>-8</timezone>\n            <properties>\n                <picUrl>http://goo.gl/xV2K8</picUrl>\n            </properties>\n        </developer>\n        <developer>\n            <name>Christian Goudreau</name>\n            <email>goudreau.christian@gmail.com</email>\n            <organization>ArcBees</organization>\n            <organizationUrl>http://arcbees.com</organizationUrl>\n            <roles>\n                <role>developer</role>\n            </roles>\n            <timezone>-5</timezone>\n        </developer>\n    </developers>\n\n    <contributors>\n        <contributor>\n            <name>Brandon Donnelson</name>\n        </contributor>\n        <contributor>\n            <name>Przemek Galazka</name>\n        </contributor>\n        <contributor>\n            <name>Simon-Pierre Gingras</name>\n        </contributor>\n        <contributor>\n            <name>Maxime Meriouma-Caron</name>\n        </contributor>\n        <contributor>\n            <name>Alden Quimby</name>\n        </contributor>\n        <contributor>\n            <name>olafleur</name>\n        </contributor>\n        <contributor>\n            <name>Julian Lettner</name>\n        </contributor>\n        <contributor>\n            <name>Adam Piper</name>\n        </contributor>\n        <contributor>\n            <name>Mike Mansell</name>\n        </contributor>\n        <contributor>\n            <name>jclariviere</name>\n        </contributor>\n        <contributor>\n            <name>Christopher Viel</name>\n        </contributor>\n        <contributor>\n            <name>Jared Martin</name>\n        </contributor>\n    </contributors>\n\n    <scm>\n        <connection>scm:git:git@github.com:ArcBees/Jukito.git/</connection>\n        <developerConnection>scm:git:git@github.com:ArcBees/Jukito.git</developerConnection>\n        <url>https://github.com/ArcBees/Jukito</url>\n    </scm>\n\n    <issueManagement>\n        <system>GitHub Issues</system>\n        <url>https://github.com/ArcBees/Jukito/issues</url>\n    </issueManagement>\n\n    <ciManagement>\n        <system>Team City</system>\n        <url>http://teamcity.gonevertical.org</url>\n    </ciManagement>\n\n    <mailingLists>\n        <mailingList>\n            <name>Development</name>\n            <subscribe>jukito+subscribe@googlegroups.com</subscribe>\n            <unsubscribe>jukito+unsubscribe@googlegroups.com</unsubscribe>\n            <post>jukito@googlegroups.com</post>\n            <archive>http://groups.google.com/group/jukito</archive>\n        </mailingList>\n    </mailingLists>\n\n    <properties>\n        <target.jdk>11</target.jdk>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n\n        <guice.version>7.0.0</guice.version>\n        <junit.version>4.13.2</junit.version>\n        <mockito.version>4.11.0</mockito.version>\n\n        <maven-checkstyle-plugin.version>3.6.0</maven-checkstyle-plugin.version>\n        <checkstyle.version>10.20.1</checkstyle.version>\n        <maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>\n        <maven-deploy-plugin.version>3.1.3</maven-deploy-plugin.version>\n        <maven-eclipse-plugin.version>2.9</maven-eclipse-plugin.version>\n        <maven-javadoc-plugin.version>3.11.1</maven-javadoc-plugin.version>\n        <maven-source-plugin.version>3.3.1</maven-source-plugin.version>\n        <maven-surefire-plugin.version>3.5.2</maven-surefire-plugin.version>\n        <animal-sniffer-maven-plugin.version>1.24</animal-sniffer-maven-plugin.version>\n        <github.version>0.12</github.version>\n    </properties>\n\n    <modules>\n        <module>jukito</module>\n        <module>jukito-samples</module>\n    </modules>\n\n    <build>\n        <pluginManagement>\n            <plugins>\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-compiler-plugin</artifactId>\n                    <version>${maven-compiler-plugin.version}</version>\n                    <configuration>\n                        <source>${target.jdk}</source>\n                        <target>${target.jdk}</target>\n                        <encoding>${project.build.sourceEncoding}</encoding>\n                    </configuration>\n                </plugin>\n\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-surefire-plugin</artifactId>\n                    <version>${maven-surefire-plugin.version}</version>\n                    <configuration>\n                        <includes>\n                            <include>**/*Test.java</include>\n                            <include>**/*TestCase.java</include>\n                        </includes>\n                    </configuration>\n                </plugin>\n\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-deploy-plugin</artifactId>\n                    <version>${maven-deploy-plugin.version}</version>\n                </plugin>\n\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-checkstyle-plugin</artifactId>\n                    <version>${maven-checkstyle-plugin.version}</version>\n                    <configuration>\n                        <configLocation>/codequality/checkstyle.xml</configLocation>\n                        <suppressionsLocation>/codequality/suppressions.xml</suppressionsLocation>\n                        <propertyExpansion>basedir=${basedir}</propertyExpansion>\n                        <consoleOutput>true</consoleOutput>\n                        <failsOnError>true</failsOnError>\n                        <linkXRef>false</linkXRef>\n                        <includeTestSourceDirectory>true</includeTestSourceDirectory>\n                    </configuration>\n                    <executions>\n                        <execution>\n                            <id>validate</id>\n                            <phase>validate</phase>\n                            <goals>\n                                <goal>checkstyle</goal>\n                            </goals>\n                        </execution>\n                    </executions>\n                    <dependencies>\n                        <dependency>\n                            <groupId>com.puppycrawl.tools</groupId>\n                            <artifactId>checkstyle</artifactId>\n                            <version>${checkstyle.version}</version>\n                        </dependency>\n                    </dependencies>\n                </plugin>\n\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-source-plugin</artifactId>\n                    <version>${maven-source-plugin.version}</version>\n                    <executions>\n                        <execution>\n                            <goals>\n                                <goal>jar</goal>\n                            </goals>\n                        </execution>\n                    </executions>\n                </plugin>\n\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-release-plugin</artifactId>\n                    <configuration>\n                        <autoVersionSubmodules>true</autoVersionSubmodules>\n                        <useReleaseProfile>false</useReleaseProfile>\n                        <releaseProfiles>release</releaseProfiles>\n                        <arguments>-Psonatype-oss-release -Prelease -Dgpg.passphrase=${gpg.passphrase}</arguments>\n                    </configuration>\n                </plugin>\n\n                <plugin>\n                    <groupId>org.codehaus.mojo</groupId>\n                    <artifactId>animal-sniffer-maven-plugin</artifactId>\n                    <version>${animal-sniffer-maven-plugin.version}</version>\n                    <configuration>\n                        <signature>\n                            <groupId>org.codehaus.mojo.signature</groupId>\n                            <artifactId>java15</artifactId>\n                            <version>1.0</version>\n                        </signature>\n                    </configuration>\n                    <executions>\n                        <execution>\n                            <phase>process-classes</phase>\n                            <goals>\n                                <goal>check</goal>\n                            </goals>\n                        </execution>\n                    </executions>\n                </plugin>\n\n                <!-- run 'mvn javadoc:aggregate' to generate -->\n                <!-- run 'mvn javadoc:aggregate -X' to debug -->\n                <plugin>\n                    <groupId>org.apache.maven.plugins</groupId>\n                    <artifactId>maven-javadoc-plugin</artifactId>\n                    <version>${maven-javadoc-plugin.version}</version>\n                    <configuration>\n                        <maxmemory>2048</maxmemory>\n                        <failOnError>true</failOnError>\n                        <doctitle>Jukito Javadocs</doctitle>\n                        <additionalparam>-Xdoclint:none</additionalparam>\n                        <links>\n                            <link>http://download.oracle.com/javase/6/docs/api/</link>\n                            <link>http://google-web-toolkit.googlecode.com/svn/javadoc/latest/</link>\n                            <link>http://google-gin.googlecode.com/svn/trunk/javadoc/</link>\n                            <link>http://google-guice.googlecode.com/svn/trunk/javadoc/</link>\n                            <link>http://aopalliance.sourceforge.net/doc/</link>\n                            <link>https://developers.google.com/appengine/docs/java/javadoc/</link>\n                            <link>http://docs.guava-libraries.googlecode.com/git/javadoc/</link>\n                        </links>\n                        <outputDirectory>${project.build.directory}/javadoc</outputDirectory>\n                        <reportOutputDirectory>${project.reporting.outputDirectory}/javadoc</reportOutputDirectory>\n                        <excludes>\n                            <exclude>**/*.txt</exclude>\n                        </excludes>\n                        <header>\n                            <![CDATA[\n                            <a href=\"https://github.com/ArcBees/Jukito\" target=\"_blank\">Back to Jukito Home</a>\n                        ]]>\n                        </header>\n                    </configuration>\n                </plugin>\n\n                <!-- run 'mvn site' to upload -->\n                <!-- run 'mvn site -X' to debug and upload. -->\n                <plugin>\n                    <groupId>com.github.github</groupId>\n                    <artifactId>site-maven-plugin</artifactId>\n                    <version>${github.version}</version>\n                    <configuration>\n                        <!-- <dryRun>true</dryRun> -->\n                        <message>Creating site for ${project.version}</message>\n                        <!-- github > sets the ~/.m2/setting.xml server id profile -->\n                        <server>github</server>\n                        <excludes>\n                            <exclude>*.DS_Store</exclude>\n                            <exclude>*.sh</exclude>\n                            <exclude>options</exclude>\n                            <exclude>packages</exclude>\n                        </excludes>\n                        <force>true</force>\n                        <merge>true</merge>\n                    </configuration>\n                    <executions>\n                        <execution>\n                            <phase>site</phase>\n                            <goals>\n                                <goal>site</goal>\n                            </goals>\n                        </execution>\n                    </executions>\n                </plugin>\n            </plugins>\n        </pluginManagement>\n    </build>\n\n    <dependencyManagement>\n        <dependencies>\n            <dependency>\n                <groupId>org.mockito</groupId>\n                <artifactId>mockito-core</artifactId>\n                <version>${mockito.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>junit</groupId>\n                <artifactId>junit</artifactId>\n                <version>${junit.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>com.google.inject</groupId>\n                <artifactId>guice</artifactId>\n                <version>${guice.version}</version>\n            </dependency>\n\n            <dependency>\n                <groupId>com.google.inject.extensions</groupId>\n                <artifactId>guice-assistedinject</artifactId>\n                <version>${guice.version}</version>\n            </dependency>\n        </dependencies>\n    </dependencyManagement>\n</project>\n"
  }
]